Skip to content

Commit 2db56e2

Browse files
committed
Merge branch 'leo.romanovsky/flagging-sdk-long-running-openfeature-2' into ffe-openfeature
2 parents eb171ad + 862769f commit 2db56e2

33 files changed

+397
-184
lines changed

.gitlab-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
variables:
2-
CURRENT_STAGING: staging-21
2+
CURRENT_STAGING: staging-22
33
APP: 'browser-sdk'
44
CURRENT_CI_IMAGE: 79
55
BUILD_STABLE_REGISTRY: 'registry.ddbuild.io'

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,26 @@
1818
1919
---
2020

21+
## v6.8.0
22+
23+
**Public Changes:**
24+
25+
-[RUM-10010] Send the user, account and session using the trace baggage header ([#3547](https://github.com/DataDog/browser-sdk/pull/3547)) [FLAGGING] [LOGS] [RUM] [RUM-REACT] [RUM-SLIM] [WORKER]
26+
- 🐛 [RUM-10101] Persist session cookie to one year when opt-in anonymous user tracking ([#3559](https://github.com/DataDog/browser-sdk/pull/3559)) [FLAGGING] [LOGS] [RUM] [RUM-REACT] [RUM-SLIM] [WORKER]
27+
- 🐛 [devext] synchronize network rules on extension start ([#3560](https://github.com/DataDog/browser-sdk/pull/3560))
28+
- ⚡️ [RUM-10104] avoid polling the cookie for `ciVisibilityContext` ([#3561](https://github.com/DataDog/browser-sdk/pull/3561)) [FLAGGING] [LOGS] [RUM] [RUM-REACT] [RUM-SLIM] [WORKER]
29+
30+
**Internal Changes:**
31+
32+
- 👷 [FFL-23] Create datadog-flagging package ([#3553](https://github.com/DataDog/browser-sdk/pull/3553)) [FLAGGING]
33+
- 👷️ [RUM-9996] fix internal source maps upload for root upload type ([#3544](https://github.com/DataDog/browser-sdk/pull/3544))
34+
- 👷 Update all non-major dependencies ([#3539](https://github.com/DataDog/browser-sdk/pull/3539)) [RUM-REACT]
35+
- 🔧 add flagging path to tsconfig ([#3566](https://github.com/DataDog/browser-sdk/pull/3566))
36+
- 🔧 apply sourcemaps to unit tests common chunk ([#3545](https://github.com/DataDog/browser-sdk/pull/3545))
37+
- Add Workflow: Changelog To Confluence ([#3546](https://github.com/DataDog/browser-sdk/pull/3546))
38+
- ♻️ [RUM-9990] Use hooks for Logs SDK to decouple rumInternalContext ([#3537](https://github.com/DataDog/browser-sdk/pull/3537)) [FLAGGING] [LOGS] [RUM] [RUM-REACT] [RUM-SLIM] [WORKER]
39+
-[RUM-7213] DOM mutation ignoring ([#3276](https://github.com/DataDog/browser-sdk/pull/3276)) [FLAGGING] [LOGS] [RUM] [RUM-REACT] [RUM-SLIM] [WORKER]
40+
2141
## v6.7.0
2242

2343
**Public Changes:**

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@ Datadog provides one CDN bundle per [site][70]:
3131

3232
| Site | logs | rum | rum-slim |
3333
| ------- | -------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------ |
34-
| US1 | https://www.datadoghq-browser-agent.com/us1/v5/datadog-logs.js | https://www.datadoghq-browser-agent.com/us1/v5/datadog-rum.js | https://www.datadoghq-browser-agent.com/us1/v5/datadog-rum-slim.js |
35-
| US3 | https://www.datadoghq-browser-agent.com/us3/v5/datadog-logs.js | https://www.datadoghq-browser-agent.com/us3/v5/datadog-rum.js | https://www.datadoghq-browser-agent.com/us3/v5/datadog-rum-slim.js |
36-
| US5 | https://www.datadoghq-browser-agent.com/us5/v5/datadog-logs.js | https://www.datadoghq-browser-agent.com/us5/v5/datadog-rum.js | https://www.datadoghq-browser-agent.com/us5/v5/datadog-rum-slim.js |
37-
| EU1 | https://www.datadoghq-browser-agent.com/eu1/v5/datadog-logs.js | https://www.datadoghq-browser-agent.com/eu1/v5/datadog-rum.js | https://www.datadoghq-browser-agent.com/eu1/v5/datadog-rum-slim.js |
38-
| US1-FED | https://www.datadoghq-browser-agent.com/datadog-logs-v5.js | https://www.datadoghq-browser-agent.com/datadog-rum-v5.js | https://www.datadoghq-browser-agent.com/datadog-rum-slim-v5.js |
34+
| US1 | https://www.datadoghq-browser-agent.com/us1/v6/datadog-logs.js | https://www.datadoghq-browser-agent.com/us1/v6/datadog-rum.js | https://www.datadoghq-browser-agent.com/us1/v6/datadog-rum-slim.js |
35+
| US3 | https://www.datadoghq-browser-agent.com/us3/v6/datadog-logs.js | https://www.datadoghq-browser-agent.com/us3/v6/datadog-rum.js | https://www.datadoghq-browser-agent.com/us3/v6/datadog-rum-slim.js |
36+
| US5 | https://www.datadoghq-browser-agent.com/us5/v6/datadog-logs.js | https://www.datadoghq-browser-agent.com/us5/v6/datadog-rum.js | https://www.datadoghq-browser-agent.com/us5/v6/datadog-rum-slim.js |
37+
| EU1 | https://www.datadoghq-browser-agent.com/eu1/v6/datadog-logs.js | https://www.datadoghq-browser-agent.com/eu1/v6/datadog-rum.js | https://www.datadoghq-browser-agent.com/eu1/v6/datadog-rum-slim.js |
38+
| AP1 | https://www.datadoghq-browser-agent.com/ap1/v6/datadog-logs.js | https://www.datadoghq-browser-agent.com/ap1/v6/datadog-rum.js | https://www.datadoghq-browser-agent.com/ap1/v6/datadog-rum-slim.js |
39+
| US1-FED | https://www.datadoghq-browser-agent.com/datadog-logs-v6.js | https://www.datadoghq-browser-agent.com/datadog-rum-v6.js | https://www.datadoghq-browser-agent.com/datadog-rum-slim-v6.js |
3940

4041
[1]: https://github.githubassets.com/favicons/favicon.png
4142
[2]: https://imgix.datadoghq.com/img/favicons/favicon-32x32.png

developer-extension/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@datadog/browser-sdk-developer-extension",
3-
"version": "6.7.0",
3+
"version": "6.8.0",
44
"private": true,
55
"scripts": {
66
"build": "rm -rf dist && webpack --mode production",

lerna.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
"npmClient": "yarn",
3-
"version": "6.7.0"
3+
"version": "6.8.0"
44
}

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@datadog/browser-core",
3-
"version": "6.7.0",
3+
"version": "6.8.0",
44
"license": "Apache-2.0",
55
"main": "cjs/index.js",
66
"module": "esm/index.js",

packages/core/src/browser/addEventListener.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ describe('addEventListener', () => {
7676
const customEventTarget = {
7777
addEventListener: jasmine.createSpy(),
7878
removeEventListener: jasmine.createSpy(),
79-
} as unknown as EventTarget
79+
} as unknown as HTMLElement
8080

8181
const { stop } = addEventListener({ allowUntrustedEvents: false }, customEventTarget, 'change', listener)
8282
stop()

packages/core/src/browser/browser.types.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,9 @@ export interface WeakRefConstructor {
5353

5454
// Those are native API types that are not official supported by TypeScript yet
5555

56-
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
57-
export interface CookieStore extends EventTarget {}
56+
export interface CookieStore extends EventTarget {
57+
get(name: string): Promise<unknown>
58+
}
5859

5960
export interface CookieStoreEventMap {
6061
change: CookieChangeEvent

packages/core/src/domain/session/storeStrategies/sessionInCookie.spec.ts

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import { resetExperimentalFeatures } from '../../../tools/experimentalFeatures'
21
import { mockClock, getSessionState } from '../../../../test'
32
import { setCookie, deleteCookie, getCookie, getCurrentSite } from '../../../browser/cookie'
43
import type { SessionState } from '../sessionState'
54
import type { Configuration } from '../../configuration'
6-
import { SESSION_TIME_OUT_DELAY } from '../sessionConstants'
5+
import { SESSION_COOKIE_EXPIRATION_DELAY, SESSION_EXPIRATION_DELAY, SESSION_TIME_OUT_DELAY } from '../sessionConstants'
76
import { buildCookieOptions, selectCookieStrategy, initCookieStrategy } from './sessionInCookie'
87
import type { SessionStoreStrategy } from './sessionStoreStrategy'
98
import { SESSION_STORE_KEY } from './sessionStoreStrategy'
@@ -103,6 +102,56 @@ describe('session in cookie strategy', () => {
103102
})
104103
})
105104
})
105+
106+
describe('session in cookie strategy when opt-in anonymous user tracking', () => {
107+
const anonymousId = 'device-123'
108+
const sessionState: SessionState = { id: '123', created: '0' }
109+
let cookieStorageStrategy: SessionStoreStrategy
110+
beforeEach(() => {
111+
cookieStorageStrategy = initCookieStrategy(
112+
{ ...DEFAULT_INIT_CONFIGURATION, trackAnonymousUser: true } as Configuration,
113+
{}
114+
)
115+
})
116+
117+
afterEach(() => {
118+
deleteCookie(SESSION_STORE_KEY)
119+
})
120+
it('should persist with anonymous id', () => {
121+
cookieStorageStrategy.persistSession({ ...sessionState, anonymousId })
122+
const session = cookieStorageStrategy.retrieveSession()
123+
expect(session).toEqual({ ...sessionState, anonymousId })
124+
expect(getCookie(SESSION_STORE_KEY)).toBe('id=123&created=0&aid=device-123')
125+
})
126+
127+
it('should expire with anonymous id', () => {
128+
cookieStorageStrategy.expireSession({ ...sessionState, anonymousId })
129+
const session = cookieStorageStrategy.retrieveSession()
130+
expect(session).toEqual({ isExpired: '1', anonymousId })
131+
expect(getCookie(SESSION_STORE_KEY)).toBe('isExpired=1&aid=device-123')
132+
})
133+
134+
it('should persist for one year when opt-in', () => {
135+
const cookieSetSpy = spyOnProperty(document, 'cookie', 'set')
136+
const clock = mockClock()
137+
cookieStorageStrategy.persistSession({ ...sessionState, anonymousId })
138+
expect(cookieSetSpy.calls.argsFor(0)[0]).toContain(
139+
new Date(clock.timeStamp(SESSION_COOKIE_EXPIRATION_DELAY)).toUTCString()
140+
)
141+
clock.cleanup()
142+
})
143+
144+
it('should expire in one year when opt-in', () => {
145+
const cookieSetSpy = spyOnProperty(document, 'cookie', 'set')
146+
const clock = mockClock()
147+
cookieStorageStrategy.expireSession({ ...sessionState, anonymousId })
148+
expect(cookieSetSpy.calls.argsFor(0)[0]).toContain(
149+
new Date(clock.timeStamp(SESSION_COOKIE_EXPIRATION_DELAY)).toUTCString()
150+
)
151+
clock.cleanup()
152+
})
153+
})
154+
106155
describe('session in cookie strategy when opt-out anonymous user tracking', () => {
107156
const anonymousId = 'device-123'
108157
const sessionState: SessionState = { id: '123', created: '0' }
@@ -113,7 +162,6 @@ describe('session in cookie strategy when opt-out anonymous user tracking', () =
113162
})
114163

115164
afterEach(() => {
116-
resetExperimentalFeatures()
117165
deleteCookie(SESSION_STORE_KEY)
118166
})
119167

@@ -125,6 +173,12 @@ describe('session in cookie strategy when opt-out anonymous user tracking', () =
125173
clock.cleanup()
126174
})
127175

176+
it('should not persist with one year when opt-out', () => {
177+
const cookieSetSpy = spyOnProperty(document, 'cookie', 'set')
178+
cookieStorageStrategy.persistSession({ ...sessionState, anonymousId })
179+
expect(cookieSetSpy.calls.argsFor(0)[0]).toContain(new Date(Date.now() + SESSION_EXPIRATION_DELAY).toUTCString())
180+
})
181+
128182
it('should not persist or expire a session with anonymous id when opt-out', () => {
129183
cookieStorageStrategy.persistSession({ ...sessionState, anonymousId })
130184
cookieStorageStrategy.expireSession({ ...sessionState, anonymousId })

packages/core/src/domain/session/storeStrategies/sessionInCookie.ts

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,29 +26,33 @@ export function initCookieStrategy(configuration: Configuration, cookieOptions:
2626
* This issue concerns only chromium browsers and enabling this on firefox increases cookie write failures.
2727
*/
2828
isLockEnabled: isChromium(),
29-
persistSession: persistSessionCookie(cookieOptions),
29+
persistSession: (sessionState: SessionState) =>
30+
storeSessionCookie(cookieOptions, configuration, sessionState, SESSION_EXPIRATION_DELAY),
3031
retrieveSession: retrieveSessionCookie,
31-
expireSession: (sessionState: SessionState) => expireSessionCookie(cookieOptions, sessionState, configuration),
32+
expireSession: (sessionState: SessionState) =>
33+
storeSessionCookie(
34+
cookieOptions,
35+
configuration,
36+
getExpiredSessionState(sessionState, configuration),
37+
SESSION_TIME_OUT_DELAY
38+
),
3239
}
3340

3441
tryOldCookiesMigration(cookieStore)
3542

3643
return cookieStore
3744
}
3845

39-
function persistSessionCookie(options: CookieOptions) {
40-
return (session: SessionState) => {
41-
setCookie(SESSION_STORE_KEY, toSessionString(session), SESSION_EXPIRATION_DELAY, options)
42-
}
43-
}
44-
45-
function expireSessionCookie(options: CookieOptions, sessionState: SessionState, configuration: Configuration) {
46-
const expiredSessionState = getExpiredSessionState(sessionState, configuration)
47-
// we do not extend cookie expiration date
46+
function storeSessionCookie(
47+
options: CookieOptions,
48+
configuration: Configuration,
49+
sessionState: SessionState,
50+
defaultTimeout: number
51+
) {
4852
setCookie(
4953
SESSION_STORE_KEY,
50-
toSessionString(expiredSessionState),
51-
configuration.trackAnonymousUser ? SESSION_COOKIE_EXPIRATION_DELAY : SESSION_TIME_OUT_DELAY,
54+
toSessionString(sessionState),
55+
configuration.trackAnonymousUser ? SESSION_COOKIE_EXPIRATION_DELAY : defaultTimeout,
5256
options
5357
)
5458
}

packages/flagging/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@datadog/browser-flagging",
3-
"version": "6.7.0",
3+
"version": "6.8.0",
44
"license": "Apache-2.0",
55
"private": true,
66
"main": "cjs/entries/main.js",
@@ -15,10 +15,10 @@
1515
"replace-build-env": "node ../../scripts/build/replace-build-env.js"
1616
},
1717
"dependencies": {
18-
"@datadog/browser-core": "6.7.0"
18+
"@datadog/browser-core": "6.8.0"
1919
},
2020
"peerDependencies": {
21-
"@datadog/browser-rum": "6.7.0",
21+
"@datadog/browser-rum": "6.8.0",
2222
"@openfeature/web-sdk": "^1.5.0"
2323
},
2424
"peerDependenciesMeta": {

packages/flagging/src/openfeature/provider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import type {
2-
Provider,
32
EvaluationContext,
43
JsonValue,
54
Logger,
65
Paradigm,
6+
Provider,
77
ProviderMetadata,
88
ResolutionDetails,
99
} from '@openfeature/web-sdk'

packages/logs/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@datadog/browser-logs",
3-
"version": "6.7.0",
3+
"version": "6.8.0",
44
"license": "Apache-2.0",
55
"main": "cjs/entries/main.js",
66
"module": "esm/entries/main.js",
@@ -14,10 +14,10 @@
1414
"replace-build-env": "node ../../scripts/build/replace-build-env.js"
1515
},
1616
"dependencies": {
17-
"@datadog/browser-core": "6.7.0"
17+
"@datadog/browser-core": "6.8.0"
1818
},
1919
"peerDependencies": {
20-
"@datadog/browser-rum": "6.7.0"
20+
"@datadog/browser-rum": "6.8.0"
2121
},
2222
"peerDependenciesMeta": {
2323
"@datadog/browser-rum": {

packages/rum-core/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@datadog/browser-rum-core",
3-
"version": "6.7.0",
3+
"version": "6.8.0",
44
"license": "Apache-2.0",
55
"main": "cjs/index.js",
66
"module": "esm/index.js",
@@ -13,7 +13,7 @@
1313
"replace-build-env": "node ../../scripts/build/replace-build-env.js"
1414
},
1515
"dependencies": {
16-
"@datadog/browser-core": "6.7.0"
16+
"@datadog/browser-core": "6.8.0"
1717
},
1818
"devDependencies": {
1919
"ajv": "8.17.1"

packages/rum-core/src/boot/startRum.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ export function startRumEventCollection(
266266
)
267267

268268
const displayContext = startDisplayContext(hooks, configuration)
269-
const ciVisibilityContext = startCiVisibilityContext(hooks)
269+
const ciVisibilityContext = startCiVisibilityContext(configuration, hooks)
270270
startSyntheticsContext(hooks)
271271

272272
startRumAssembly(configuration, lifeCycle, hooks, reportError)

packages/rum-core/src/browser/cookieObservable.spec.ts

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import type { Subscription } from '@datadog/browser-core'
22
import { ONE_MINUTE, deleteCookie, setCookie } from '@datadog/browser-core'
33
import type { Clock } from '@datadog/browser-core/test'
44
import { mockClock } from '@datadog/browser-core/test'
5+
import { mockRumConfiguration } from '../../test'
6+
import type { CookieStoreWindow } from './cookieObservable'
57
import { WATCH_COOKIE_INTERVAL_DELAY, createCookieObservable } from './cookieObservable'
68

79
const COOKIE_NAME = 'cookie_name'
@@ -25,20 +27,47 @@ describe('cookieObservable', () => {
2527
clock.cleanup()
2628
})
2729

28-
it('should notify observers on cookie change', (done) => {
29-
const observable = createCookieObservable(COOKIE_NAME)
30+
it('should notify observers on cookie change', async () => {
31+
const observable = createCookieObservable(mockRumConfiguration(), COOKIE_NAME)
3032

31-
subscription = observable.subscribe((cookieChange) => {
32-
expect(cookieChange).toEqual('foo')
33-
34-
done()
33+
const cookieChangePromise = new Promise((resolve) => {
34+
subscription = observable.subscribe(resolve)
3535
})
36+
37+
// When writing a cookie just after subscribing to the cookieStore 'change' event, the 'change'
38+
// event is sometimes not triggered, making this test case flaky.
39+
// To work around this, we get some random cookie from the cookieStore. This adds enough delay
40+
// to ensure that the 'change' event is triggered when we write our cookie.
41+
// This was reported here: https://issues.chromium.org/issues/420405275
42+
const cookieStore = (window as CookieStoreWindow).cookieStore
43+
if (cookieStore) {
44+
// Wait for the cookieStore to be ready
45+
await cookieStore.get('some_cookie_name')
46+
}
47+
48+
setCookie(COOKIE_NAME, 'foo', COOKIE_DURATION)
49+
clock.tick(WATCH_COOKIE_INTERVAL_DELAY)
50+
51+
const cookieChange = await cookieChangePromise
52+
expect(cookieChange).toEqual('foo')
53+
})
54+
55+
it('should notify observers on cookie change when cookieStore is not supported', () => {
56+
Object.defineProperty(window, 'cookieStore', { get: () => undefined, configurable: true })
57+
const observable = createCookieObservable(mockRumConfiguration(), COOKIE_NAME)
58+
59+
let cookieChange: string | undefined
60+
subscription = observable.subscribe((change) => (cookieChange = change))
61+
3662
setCookie(COOKIE_NAME, 'foo', COOKIE_DURATION)
3763
clock.tick(WATCH_COOKIE_INTERVAL_DELAY)
64+
65+
expect(cookieChange).toEqual('foo')
3866
})
3967

40-
it('should not notify observers on cookie change when the cookie value has not changed', () => {
41-
const observable = createCookieObservable(COOKIE_NAME)
68+
it('should not notify observers on cookie change when the cookie value as not changed when cookieStore is not supported', () => {
69+
Object.defineProperty(window, 'cookieStore', { get: () => undefined, configurable: true })
70+
const observable = createCookieObservable(mockRumConfiguration(), COOKIE_NAME)
4271

4372
setCookie(COOKIE_NAME, 'foo', COOKIE_DURATION)
4473

0 commit comments

Comments
 (0)