-
Notifications
You must be signed in to change notification settings - Fork 190
Expand file tree
/
Copy pathcookieObservable.ts
More file actions
69 lines (60 loc) · 2.41 KB
/
Copy pathcookieObservable.ts
File metadata and controls
69 lines (60 loc) · 2.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import type { Configuration, CookieStore } from '@datadog/browser-core'
import {
setInterval,
clearInterval,
Observable,
addEventListener,
ONE_SECOND,
DOM_EVENT,
getCookie,
} from '@datadog/browser-core'
export interface CookieStoreWindow {
cookieStore?: CookieStore
}
export type CookieObservable = ReturnType<typeof createCookieObservable>
export function createCookieObservable(configuration: Configuration, cookieName: string) {
const detectCookieChangeStrategy = (window as CookieStoreWindow).cookieStore
? listenToCookieStoreChange(configuration)
: watchCookieFallback
return new Observable<string | undefined>((observable) =>
detectCookieChangeStrategy(cookieName, (event) => observable.notify(event))
)
}
function listenToCookieStoreChange(configuration: Configuration) {
return (cookieName: string, callback: (event: string | undefined) => void) => {
// Lightning Web Security does not support the change event of CookieStore objects. https://developer.salesforce.com/tools/lws-distortion-viewer
const cookieStore = (window as CookieStoreWindow).cookieStore
if (!cookieStore) {
return watchCookieFallback(cookieName, callback)
}
try {
const listener = addEventListener(configuration, cookieStore, DOM_EVENT.CHANGE, (event) => {
// Based on our experimentation, we're assuming that entries for the same cookie cannot be in both the 'changed' and 'deleted' arrays.
// However, due to ambiguity in the specification, we asked for clarification: https://github.com/WICG/cookie-store/issues/226
const changeEvent =
event.changed.find((event) => event.name === cookieName) ||
event.deleted.find((event) => event.name === cookieName)
if (changeEvent) {
callback(changeEvent.value)
}
})
return listener.stop
} catch {
return watchCookieFallback(cookieName, callback)
}
}
}
export const WATCH_COOKIE_INTERVAL_DELAY = ONE_SECOND
function watchCookieFallback(cookieName: string, callback: (event: string | undefined) => void) {
let previousCookieValue = getCookie(cookieName)
const watchCookieIntervalId = setInterval(() => {
const cookieValue = getCookie(cookieName)
if (cookieValue !== previousCookieValue) {
previousCookieValue = cookieValue
callback(cookieValue)
}
}, WATCH_COOKIE_INTERVAL_DELAY)
return () => {
clearInterval(watchCookieIntervalId)
}
}