Skip to content

Commit 61208b1

Browse files
committed
πŸ› address Codex review feedback
1 parent 8640c84 commit 61208b1

5 files changed

Lines changed: 34 additions & 24 deletions

File tree

β€Žpackages/browser-core/src/domain/remoteConfiguration/remoteConfigurationFetch.tsβ€Ž

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { buildEndpointUrl } from '@datadog/js-core/transport'
2+
import { globalObject } from '@datadog/js-core/util'
23
import { fetch } from '../../browser/fetch'
34
import type { RumSdkConfig } from './remoteConfiguration.types'
45

@@ -15,6 +16,22 @@ export interface RemoteConfigurationEndpointOptions {
1516

1617
export type FetchRemoteConfigurationResult = { ok: true; value: RemoteConfiguration } | { ok: false; error: Error }
1718

19+
// Typed interface for the global inflight fetch registry so deduplication
20+
// works across separate SDK bundles (e.g. RUM and Logs loaded as separate CDN
21+
// scripts on the same page) and in service-worker environments where `window`
22+
// is not available.
23+
interface GlobalWithInflightFetches {
24+
__ddRcInflight?: Map<string, Promise<FetchRemoteConfigurationResult>>
25+
}
26+
27+
function getInflightFetches(): Map<string, Promise<FetchRemoteConfigurationResult>> {
28+
const global = globalObject as GlobalWithInflightFetches
29+
if (!global.__ddRcInflight) {
30+
global.__ddRcInflight = new Map()
31+
}
32+
return global.__ddRcInflight
33+
}
34+
1835
export function getRemoteConfigurationId(options: RemoteConfigurationEndpointOptions): string | undefined {
1936
return options.remoteConfiguration?.id ?? options.remoteConfigurationId
2037
}
@@ -31,30 +48,17 @@ export function buildEndpoint(options: RemoteConfigurationEndpointOptions): stri
3148
})
3249
}
3350

34-
// Use a window-level registry so deduplication works across separate SDK bundles
35-
// (e.g. RUM and Logs loaded as separate CDN scripts on the same page).
36-
const INFLIGHT_FETCHES_KEY = '__ddRcInflight'
37-
38-
function getInflightFetches(): Map<string, Promise<FetchRemoteConfigurationResult>> {
39-
const win = window as unknown as Record<string, unknown>
40-
if (!win[INFLIGHT_FETCHES_KEY]) {
41-
win[INFLIGHT_FETCHES_KEY] = new Map<string, Promise<FetchRemoteConfigurationResult>>()
42-
}
43-
return win[INFLIGHT_FETCHES_KEY] as Map<string, Promise<FetchRemoteConfigurationResult>>
44-
}
45-
4651
export function fetchRemoteConfiguration(
4752
options: RemoteConfigurationEndpointOptions
4853
): Promise<FetchRemoteConfigurationResult> {
4954
const endpoint = buildEndpoint(options)
5055
const inflightFetches = getInflightFetches()
5156

5257
if (!inflightFetches.has(endpoint)) {
53-
const win = window as unknown as Record<string, unknown>
5458
const promise = doFetchRemoteConfiguration(endpoint).finally(() => {
5559
inflightFetches.delete(endpoint)
5660
if (inflightFetches.size === 0) {
57-
delete win[INFLIGHT_FETCHES_KEY]
61+
delete (globalObject as GlobalWithInflightFetches).__ddRcInflight
5862
}
5963
})
6064
inflightFetches.set(endpoint, promise)

β€Žpackages/browser-logs/src/boot/preStartLogs.spec.tsβ€Ž

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
replaceMockable,
1010
replaceMockableWithSpy,
1111
createStartSessionManagerMock,
12+
registerCleanupTask,
1213
} from '@datadog/browser-core/test'
1314
import type { TrackingConsentState } from '@datadog/browser-core'
1415
import {
@@ -258,10 +259,6 @@ describe('preStartLogs', () => {
258259
describe('remote configuration', () => {
259260
const RC_ID = 'test-rc-id'
260261

261-
afterEach(() => {
262-
localStorage.removeItem(buildCacheKey(RC_ID))
263-
})
264-
265262
it('applies cached remote config overrides before starting', async () => {
266263
localStorage.setItem(
267264
buildCacheKey(RC_ID),
@@ -271,6 +268,7 @@ describe('preStartLogs', () => {
271268
fetchedAt: Date.now(),
272269
})
273270
)
271+
registerCleanupTask(() => localStorage.removeItem(buildCacheKey(RC_ID)))
274272

275273
const { strategy, doStartLogsSpy } = createPreStartStrategyWithDefaults()
276274
strategy.init({ clientToken: 'xxx', remoteConfiguration: { id: RC_ID } })

β€Žpackages/browser-logs/src/domain/configuration.tsβ€Ž

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,18 @@ export interface LogsInitConfiguration extends InitConfiguration {
7474
forwardReports?: RawReportType[] | 'all' | undefined
7575

7676
/**
77-
* The ID of the remote configuration to apply. Use this for the non-blocking cache-and-reload path.
77+
* The ID of the remote configuration to apply. Triggers synchronous loading β€” the SDK waits for
78+
* the fetch to complete before starting. Use `remoteConfiguration: { id }` for the non-blocking
79+
* cache-and-reload path instead.
7880
*
7981
* @category Remote Configuration
8082
*/
8183
remoteConfigurationId?: string | undefined
8284

8385
/**
84-
* Remote configuration options.
86+
* Remote configuration options. Use `{ id }` for the non-blocking cache-and-reload path (the SDK
87+
* starts immediately using a cached value and refreshes in the background). Use `{ id, sync: true }`
88+
* to block startup on a live fetch.
8589
*
8690
* @category Remote Configuration
8791
*/

β€Žpackages/browser-logs/src/domain/remoteConfiguration.spec.tsβ€Ž

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { CACHE_VERSION, buildCacheKey, display } from '@datadog/browser-core'
2-
import { interceptRequests } from '@datadog/browser-core/test'
2+
import { interceptRequests, registerCleanupTask } from '@datadog/browser-core/test'
33
import type { LogsInitConfiguration } from './configuration'
44
import {
55
applyLogsRemoteConfiguration,
@@ -62,8 +62,9 @@ describe('getLogsRemoteConfiguration', () => {
6262
remoteConfiguration: { id: RC_ID },
6363
}
6464

65-
afterEach(() => {
66-
localStorage.removeItem(buildCacheKey(RC_ID))
65+
beforeEach(() => {
66+
// Prevent background sync from firing real network requests
67+
interceptRequests()
6768
})
6869

6970
it('returns the initConfiguration with remote overrides applied on cache hit', () => {
@@ -75,6 +76,7 @@ describe('getLogsRemoteConfiguration', () => {
7576
fetchedAt: Date.now(),
7677
})
7778
)
79+
registerCleanupTask(() => localStorage.removeItem(buildCacheKey(RC_ID)))
7880

7981
const result = getLogsRemoteConfiguration(initConfiguration)
8082
expect(result!.forwardErrorsToLogs).toBeFalse()

β€Žpackages/browser-logs/src/domain/remoteConfiguration.tsβ€Ž

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ export function getLogsRemoteConfiguration(
4343
// Background sync β€” update the cache for the next page load
4444
fetchRemoteConfiguration(initConfiguration)
4545
.then((fetchResult) => {
46-
if (fetchResult.ok) {
46+
if (!fetchResult.ok) {
47+
display.error(fetchResult.error)
48+
} else {
4749
cache.write(fetchResult.value)
4850
}
4951
})

0 commit comments

Comments
Β (0)