Skip to content

Commit 769624f

Browse files
committed
Cleanup unsubscribes
1 parent a727dce commit 769624f

File tree

1 file changed

+32
-42
lines changed

1 file changed

+32
-42
lines changed

packages/auth/src/platform_browser/persistence/cookie_storage.ts

Lines changed: 32 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,15 @@ const getDocumentCookie = (name: string): string | null => {
3333
return document.cookie.match(matcher)?.[1] ?? null;
3434
};
3535

36+
const getCookieName = (key:string): string => key;
37+
3638
export class CookiePersistence implements PersistenceInternal {
3739
static type: 'COOKIE' = 'COOKIE';
3840
readonly type = PersistenceType.COOKIE;
39-
cookieStoreListeners: Map<
40-
StorageEventListener,
41-
(event: CookieChangeEvent) => void
42-
> = new Map();
43-
cookiePollingIntervals: Map<StorageEventListener, NodeJS.Timeout> = new Map();
41+
listenerUnsubscribes: Map<StorageEventListener, () => void> = new Map();
4442

4543
async _isAvailable(): Promise<boolean> {
44+
// TODO isSecureContext
4645
if (typeof navigator === 'undefined' || typeof document === 'undefined') {
4746
return false;
4847
}
@@ -57,27 +56,28 @@ export class CookiePersistence implements PersistenceInternal {
5756
if (!this._isAvailable()) {
5857
return null;
5958
}
59+
const name = getCookieName(key);
6060
if (window.cookieStore) {
61-
const cookie = await window.cookieStore.get(key);
61+
const cookie = await window.cookieStore.get(name);
6262
return cookie?.value as T;
63-
} else {
64-
return getDocumentCookie(key) as T;
6563
}
64+
return getDocumentCookie(name) as T;
6665
}
6766

6867
async _remove(key: string): Promise<void> {
6968
if (!this._isAvailable()) {
7069
return;
7170
}
71+
const name = getCookieName(key);
7272
if (window.cookieStore) {
73-
const cookie = await window.cookieStore.get(key);
73+
const cookie = await window.cookieStore.get(name);
7474
if (!cookie) {
7575
return;
7676
}
7777
await window.cookieStore.delete(cookie);
7878
} else {
7979
// TODO how do I get the cookie properties?
80-
document.cookie = `${key}=;Max-Age=34560000;Partitioned;Secure;SameSite=Strict;Path=/`;
80+
document.cookie = `${name}=;Max-Age=34560000;Partitioned;Secure;SameSite=Strict;Path=/`;
8181
}
8282
await fetch(`/__cookies__`, { method: 'DELETE' }).catch(() => undefined);
8383
}
@@ -86,52 +86,42 @@ export class CookiePersistence implements PersistenceInternal {
8686
if (!this._isAvailable()) {
8787
return;
8888
}
89+
const name = getCookieName(key);
8990
if (window.cookieStore) {
90-
const cb = (event: CookieChangeEvent): void => {
91-
const changedCookie = event.changed.find(change => change.name === key);
91+
const cb = ((event: CookieChangeEvent): void => {
92+
const changedCookie = event.changed.find(change => change.name === name);
9293
if (changedCookie) {
9394
listener(changedCookie.value as PersistenceValue);
9495
}
95-
const deletedCookie = event.deleted.find(change => change.name === key);
96+
const deletedCookie = event.deleted.find(change => change.name === name);
9697
if (deletedCookie) {
9798
listener(null);
9899
}
99-
};
100-
this.cookieStoreListeners.set(listener, cb);
101-
window.cookieStore.addEventListener('change', cb as EventListener);
102-
} else {
103-
let lastValue = getDocumentCookie(key);
104-
const interval = setInterval(() => {
105-
const currentValue = getDocumentCookie(key);
106-
if (currentValue !== lastValue) {
107-
listener(currentValue as PersistenceValue | null);
108-
lastValue = currentValue;
109-
}
110-
}, POLLING_INTERVAL_MS);
111-
this.cookiePollingIntervals.set(listener, interval);
100+
}) as EventListener;
101+
const unsubscribe = () => window.cookieStore.removeEventListener('change', cb);
102+
this.listenerUnsubscribes.set(listener, unsubscribe);
103+
return window.cookieStore.addEventListener('change', cb as EventListener);
112104
}
105+
let lastValue = getDocumentCookie(name);
106+
const interval = setInterval(() => {
107+
const currentValue = getDocumentCookie(name);
108+
if (currentValue !== lastValue) {
109+
listener(currentValue as PersistenceValue | null);
110+
lastValue = currentValue;
111+
}
112+
}, POLLING_INTERVAL_MS);
113+
const unsubscribe = () => clearInterval(interval);
114+
this.listenerUnsubscribes.set(listener, unsubscribe);
113115
}
114116

115117
// TODO can we tidy this logic up into a single unsubscribe function? () => void;
116118
_removeListener(_key: string, listener: StorageEventListener): void {
117-
if (!this._isAvailable()) {
119+
const unsubscribe = this.listenerUnsubscribes.get(listener);
120+
if (!unsubscribe) {
118121
return;
119122
}
120-
if (window.cookieStore) {
121-
const cb = this.cookieStoreListeners.get(listener);
122-
if (!cb) {
123-
return;
124-
}
125-
window.cookieStore.removeEventListener('change', cb as EventListener);
126-
this.cookieStoreListeners.delete(listener);
127-
} else {
128-
const interval = this.cookiePollingIntervals.get(listener);
129-
if (!interval) {
130-
return;
131-
}
132-
clearInterval(interval);
133-
this.cookiePollingIntervals.delete(listener);
134-
}
123+
unsubscribe();
124+
this.listenerUnsubscribes.delete(listener);
135125
}
136126
}
137127

0 commit comments

Comments
 (0)