diff --git a/packages/clarity-js/src/data/metadata.ts b/packages/clarity-js/src/data/metadata.ts index 0b4bd1db..da45c684 100644 --- a/packages/clarity-js/src/data/metadata.ts +++ b/packages/clarity-js/src/data/metadata.ts @@ -94,18 +94,22 @@ function userAgentData(): void { export function stop(): void { rootDomain = null; data = null; + callbacks.forEach(cb => { cb.called = false; }); } -export function metadata(cb: MetadataCallback, wait: boolean = true): void { +export function metadata(cb: MetadataCallback, wait: boolean = true, recall: boolean = false): void { let upgraded = config.lean ? BooleanFlag.False : BooleanFlag.True; + let called = false; // if caller hasn't specified that they want to skip waiting for upgrade but we've already upgraded, we need to - // directly execute the callback rather than adding to our list as we only process callbacks at the moment + // directly execute the callback in addition to adding to our list as we only process callbacks at the moment // we go through the upgrading flow. if (data && (upgraded || wait === false)) { // Immediately invoke the callback if the caller explicitly doesn't want to wait for the upgrade confirmation cb(data, !config.lean); - } else { - callbacks.push({ callback: cb, wait: wait }); + called = true; + } + if (recall || !called) { + callbacks.push({ callback: cb, wait, recall, called }); } } @@ -154,9 +158,17 @@ export function save(): void { function processCallback(upgrade: BooleanFlag) { if (callbacks.length > 0) { - callbacks.forEach(x => { - if (x.callback && (!x.wait || upgrade)) { x.callback(data, !config.lean); } - }) + for (let i = 0; i < callbacks.length; i++) { + const cb = callbacks[i]; + if (cb.callback && !cb.called && (!cb.wait || upgrade)) { + cb.callback(data, !config.lean); + cb.called = true; + if (!cb.recall) { + callbacks.splice(i, 1); + i--; + } + } + } } } @@ -257,11 +269,11 @@ function getCookie(key: string): string { // * Cookie was previously not encoded by Clarity and browser encoded it once or more // * Cookie was previously encoded by Clarity and browser did not encode it let [isEncoded, decodedValue] = decodeCookieValue(pair[1]); - + while (isEncoded) { [isEncoded, decodedValue] = decodeCookieValue(decodedValue); } - + return decodedValue; } } diff --git a/packages/clarity-js/types/data.d.ts b/packages/clarity-js/types/data.d.ts index caf370dd..44119f61 100644 --- a/packages/clarity-js/types/data.d.ts +++ b/packages/clarity-js/types/data.d.ts @@ -6,7 +6,9 @@ export type DecodedToken = (any | any[]); export type MetadataCallback = (data: Metadata, playback: boolean) => void; export interface MetadataCallbackOptions { callback: MetadataCallback, - wait: boolean + wait: boolean, + recall: boolean, + called: boolean } export type SignalCallback = (data: ClaritySignal) => void