diff --git a/examples/cstg/html/index.html b/examples/cstg/html/index.html index 6b0bd16a..b04c95e9 100644 --- a/examples/cstg/html/index.html +++ b/examples/cstg/html/index.html @@ -133,7 +133,7 @@

UID2 Publisher Client-Side Integration Example using UID2 JavaScript SDK

>
diff --git a/src/euidSdk.ts b/src/euidSdk.ts index 3011a033..ec9c028f 100644 --- a/src/euidSdk.ts +++ b/src/euidSdk.ts @@ -60,6 +60,11 @@ export function assertEUID(sdk: typeof window.__euid): asserts sdk is EUID { } export function __euidInternalHandleScriptLoad() { + if (window.__euid && 'init' in window.__euid) { + // This has already been run + return; + } + const callbacks = window?.__euid?.callbacks || []; const callbackContainer: CallbackContainer = {}; window.__euid = new EUID(callbacks, callbackContainer); diff --git a/src/integrationTests/basic.test.ts b/src/integrationTests/basic.test.ts index 8dabb956..6f743efb 100644 --- a/src/integrationTests/basic.test.ts +++ b/src/integrationTests/basic.test.ts @@ -1,8 +1,8 @@ import { afterEach, beforeEach, describe, expect, jest, test } from '@jest/globals'; import * as mocks from '../mocks'; -import { sdkWindow, UID2 } from '../uid2Sdk'; -import { EventType } from '../callbackManager'; +import { __uid2InternalHandleScriptLoad, sdkWindow, UID2 } from '../uid2Sdk'; +import { CallbackHandler, EventType } from '../callbackManager'; let callback: any; let uid2: UID2; @@ -1014,3 +1014,50 @@ testCookieAndLocalStorage(() => { }); }); }); + +describe('Include sdk script multiple times', () => { + const makeIdentity = mocks.makeIdentityV2; + let asyncCallback: jest.Mock; + const debugOutput = false; + + asyncCallback = jest.fn((event, payload) => { + if (debugOutput) { + console.log('Async Callback Event:', event); + console.log('Payload:', payload); + } + }); + + beforeEach(() => { + sdkWindow.__uid2 = new UID2(); + }); + + afterEach(() => { + sdkWindow.__uid2 = undefined; + }); + + test('call init after script inclusion', async () => { + const identity = { ...makeIdentity(), refresh_from: Date.now() + 100 }; + + __uid2InternalHandleScriptLoad(); + __uid2InternalHandleScriptLoad(); + __uid2InternalHandleScriptLoad(); + + (sdkWindow.__uid2 as UID2).init({ identity }); + + sdkWindow.__uid2!.callbacks!.push(asyncCallback); + expect(asyncCallback).toBeCalledWith(EventType.SdkLoaded, expect.anything()); + }); + + test('call init prior to script inclusion', async () => { + const identity = { ...makeIdentity(), refresh_from: Date.now() + 100 }; + + (sdkWindow.__uid2 as UID2).init({ identity }); + + __uid2InternalHandleScriptLoad(); + __uid2InternalHandleScriptLoad(); + __uid2InternalHandleScriptLoad(); + + sdkWindow.__uid2!.callbacks!.push(asyncCallback); + expect(asyncCallback).toBeCalledWith(EventType.SdkLoaded, expect.anything()); + }); +}); diff --git a/src/sdkBase.ts b/src/sdkBase.ts index f2cee4e4..e7b100d9 100644 --- a/src/sdkBase.ts +++ b/src/sdkBase.ts @@ -127,6 +127,10 @@ export abstract class SdkBase { return this._tokenPromiseHandler.createMaybeDeferredPromise(token ?? null); } + public initComplete(): boolean { + return this._initComplete; + } + /** * Deprecated */ diff --git a/src/uid2Sdk.ts b/src/uid2Sdk.ts index de5e4fac..77cc05c9 100644 --- a/src/uid2Sdk.ts +++ b/src/uid2Sdk.ts @@ -110,6 +110,11 @@ export function assertUID2(sdk: typeof window.__uid2): asserts sdk is UID2 { } export function __uid2InternalHandleScriptLoad() { + if (window.__uid2 && 'init' in window.__uid2) { + // This has already been run + return; + } + const callbacks = window?.__uid2?.callbacks || []; const callbackContainer: CallbackContainer = {}; window.__uid2 = new UID2(callbacks, callbackContainer);