@adhese/sdk 1.4.1 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/cjs/consent/consent.cjs.map +1 -1
  3. package/dist/cjs/findDomSlots/findDomSlots.cjs.map +1 -1
  4. package/dist/cjs/hooks.cjs.map +1 -1
  5. package/dist/cjs/logger/logger.cjs.map +1 -1
  6. package/dist/cjs/main.cjs.map +1 -1
  7. package/dist/cjs/main.composables.cjs.map +1 -1
  8. package/dist/cjs/main.utils.cjs.map +1 -1
  9. package/dist/cjs/package.json.cjs +1 -1
  10. package/dist/cjs/queryDetector/queryDetector.cjs.map +1 -1
  11. package/dist/cjs/requestAds/requestAds.cjs.map +1 -1
  12. package/dist/cjs/requestAds/requestAds.preview.cjs.map +1 -1
  13. package/dist/cjs/requestAds/requestAds.schema.cjs.map +1 -1
  14. package/dist/cjs/requestAds/requestAds.utils.cjs.map +1 -1
  15. package/dist/cjs/slot/slot.cjs +12 -7
  16. package/dist/cjs/slot/slot.cjs.map +1 -1
  17. package/dist/cjs/slot/slot.composables.cjs.map +1 -1
  18. package/dist/cjs/slotManager/slotManager.cjs.map +1 -1
  19. package/dist/consent/consent.js.map +1 -1
  20. package/dist/findDomSlots/findDomSlots.js.map +1 -1
  21. package/dist/hooks.js.map +1 -1
  22. package/dist/main.composables.js.map +1 -1
  23. package/dist/main.js.map +1 -1
  24. package/dist/main.utils.js.map +1 -1
  25. package/dist/package.json.js +1 -1
  26. package/dist/queryDetector/queryDetector.js.map +1 -1
  27. package/dist/requestAds/requestAds.js.map +1 -1
  28. package/dist/requestAds/requestAds.preview.js.map +1 -1
  29. package/dist/requestAds/requestAds.schema.js.map +1 -1
  30. package/dist/requestAds/requestAds.utils.js.map +1 -1
  31. package/dist/slot/slot.composables.js.map +1 -1
  32. package/dist/slot/slot.js +13 -8
  33. package/dist/slot/slot.js.map +1 -1
  34. package/dist/slotManager/slotManager.js.map +1 -1
  35. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @adhese/sdk
2
2
 
3
+ ## 1.4.2
4
+
5
+ ### Patch Changes
6
+
7
+ - b178b64: Fix eager rendering not doing anything
8
+
3
9
  ## 1.4.1
4
10
 
5
11
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"consent.cjs","sources":["../../../src/consent/consent.ts"],"sourcesContent":["import type { AdheseContext } from '@adhese/sdk';\nimport type { ConsentData } from '../types';\nimport { computed, type ComputedRef, type Ref, ref, watch } from '@adhese/sdk-shared';\n\nexport function useConsent(context: AdheseContext): [\n value: Ref<string>,\n type: ComputedRef<'binary' | 'tcf'>,\n] {\n const consent = ref('none');\n const consentType = computed(() => (consent.value === 'none' || consent.value === 'all') ? 'binary' : 'tcf');\n\n function onTcfConsentChange(data: ConsentData): void {\n if (data.tcString)\n consent.value = data.tcString;\n }\n\n context.hooks.onInit(() => {\n window.__tcfapi?.('addEventListener', 2, onTcfConsentChange);\n });\n\n context.hooks.onDispose(() => {\n window.__tcfapi?.('removeEventListener', 2, onTcfConsentChange);\n });\n\n watch(() => context.consent, (newConsent) => {\n consent.value = newConsent ? 'all' : 'none';\n }, { immediate: true });\n\n watch([consent, consentType], ([newConsent, newConsentType]) => {\n if (newConsentType === 'binary') {\n context.parameters.set('tl', newConsent);\n context.parameters.delete('xt');\n }\n else {\n context.parameters.set('xt', newConsent);\n context.parameters.delete('tl');\n }\n }, { immediate: true });\n\n watch(consent, (newConsent) => {\n context.consentString = newConsent;\n }, { immediate: true });\n\n return [consent, consentType];\n}\n"],"names":["ref","computed","watch"],"mappings":";;;AAIO,SAAS,WAAW,SAGzB;AACM,QAAA,UAAUA,cAAI,MAAM;AACpB,QAAA,cAAcC,UAAAA,SAAS,MAAO,QAAQ,UAAU,UAAU,QAAQ,UAAU,QAAS,WAAW,KAAK;AAE3G,WAAS,mBAAmB,MAAyB;AACnD,QAAI,KAAK;AACP,cAAQ,QAAQ,KAAK;AAAA,EACzB;AAEQ,UAAA,MAAM,OAAO,MAAM;;AAClB,iBAAA,aAAA,gCAAW,oBAAoB,GAAG;AAAA,EAAkB,CAC5D;AAEO,UAAA,MAAM,UAAU,MAAM;;AACrB,iBAAA,aAAA,gCAAW,uBAAuB,GAAG;AAAA,EAAkB,CAC/D;AAEDC,YAAAA,MAAM,MAAM,QAAQ,SAAS,CAAC,eAAe;AACnC,YAAA,QAAQ,aAAa,QAAQ;AAAA,EAAA,GACpC,EAAE,WAAW,KAAA,CAAM;AAEhBA,YAAA,MAAA,CAAC,SAAS,WAAW,GAAG,CAAC,CAAC,YAAY,cAAc,MAAM;AAC9D,QAAI,mBAAmB,UAAU;AACvB,cAAA,WAAW,IAAI,MAAM,UAAU;AAC/B,cAAA,WAAW,OAAO,IAAI;AAAA,IAAA,OAE3B;AACK,cAAA,WAAW,IAAI,MAAM,UAAU;AAC/B,cAAA,WAAW,OAAO,IAAI;AAAA,IAChC;AAAA,EAAA,GACC,EAAE,WAAW,KAAA,CAAM;AAEhBA,kBAAA,SAAS,CAAC,eAAe;AAC7B,YAAQ,gBAAgB;AAAA,EAAA,GACvB,EAAE,WAAW,KAAA,CAAM;AAEf,SAAA,CAAC,SAAS,WAAW;AAC9B;;"}
1
+ {"version":3,"file":"consent.cjs","sources":["../../../src/consent/consent.ts"],"sourcesContent":["import type { AdheseContext } from '@adhese/sdk';\nimport type { ConsentData } from '../types';\nimport { computed, type ComputedRef, type Ref, ref, watch } from '@adhese/sdk-shared';\n\nexport function useConsent(context: AdheseContext): [\n value: Ref<string>,\n type: ComputedRef<'binary' | 'tcf'>,\n] {\n const consent = ref('none');\n const consentType = computed(() => (consent.value === 'none' || consent.value === 'all') ? 'binary' : 'tcf');\n\n function onTcfConsentChange(data: ConsentData): void {\n if (data.tcString)\n consent.value = data.tcString;\n }\n\n context.hooks.onInit(() => {\n window.__tcfapi?.('addEventListener', 2, onTcfConsentChange);\n });\n\n context.hooks.onDispose(() => {\n window.__tcfapi?.('removeEventListener', 2, onTcfConsentChange);\n });\n\n watch(() => context.consent, (newConsent) => {\n consent.value = newConsent ? 'all' : 'none';\n }, { immediate: true });\n\n watch([consent, consentType], ([newConsent, newConsentType]) => {\n if (newConsentType === 'binary') {\n context.parameters.set('tl', newConsent);\n context.parameters.delete('xt');\n }\n else {\n context.parameters.set('xt', newConsent);\n context.parameters.delete('tl');\n }\n }, { immediate: true });\n\n watch(consent, (newConsent) => {\n context.consentString = newConsent;\n }, { immediate: true });\n\n return [consent, consentType];\n}\n"],"names":["ref","computed","watch"],"mappings":";;;AAIO,SAAS,WAAW,SAGzB;AACM,QAAA,UAAUA,cAAI,MAAM;AACpB,QAAA,cAAcC,UAAAA,SAAS,MAAO,QAAQ,UAAU,UAAU,QAAQ,UAAU,QAAS,WAAW,KAAK;AAE3G,WAAS,mBAAmB,MAAyB;AACnD,QAAI,KAAK;AACP,cAAQ,QAAQ,KAAK;AAAA,EAAA;AAGjB,UAAA,MAAM,OAAO,MAAM;;AAClB,iBAAA,aAAA,gCAAW,oBAAoB,GAAG;AAAA,EAAkB,CAC5D;AAEO,UAAA,MAAM,UAAU,MAAM;;AACrB,iBAAA,aAAA,gCAAW,uBAAuB,GAAG;AAAA,EAAkB,CAC/D;AAEDC,YAAAA,MAAM,MAAM,QAAQ,SAAS,CAAC,eAAe;AACnC,YAAA,QAAQ,aAAa,QAAQ;AAAA,EAAA,GACpC,EAAE,WAAW,MAAM;AAEhBA,YAAA,MAAA,CAAC,SAAS,WAAW,GAAG,CAAC,CAAC,YAAY,cAAc,MAAM;AAC9D,QAAI,mBAAmB,UAAU;AACvB,cAAA,WAAW,IAAI,MAAM,UAAU;AAC/B,cAAA,WAAW,OAAO,IAAI;AAAA,IAAA,OAE3B;AACK,cAAA,WAAW,IAAI,MAAM,UAAU;AAC/B,cAAA,WAAW,OAAO,IAAI;AAAA,IAAA;AAAA,EAChC,GACC,EAAE,WAAW,MAAM;AAEhBA,kBAAA,SAAS,CAAC,eAAe;AAC7B,YAAQ,gBAAgB;AAAA,EAAA,GACvB,EAAE,WAAW,MAAM;AAEf,SAAA,CAAC,SAAS,WAAW;AAC9B;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"findDomSlots.cjs","sources":["../../../src/findDomSlots/findDomSlots.ts"],"sourcesContent":["import type { AdheseContext, AdheseSlot } from '@adhese/sdk';\nimport { generateName, waitForDomLoad } from '@adhese/sdk-shared';\nimport { createSlot } from '../slot/slot';\n\n/**\n * Find all slots in the DOM and render them. Ignore slots that are already active.\n */\nexport async function findDomSlots(\n context: AdheseContext,\n): Promise<ReadonlyArray<AdheseSlot>> {\n await waitForDomLoad();\n\n return Array.from(document.querySelectorAll<HTMLElement>('.adunit'))\n .filter((element) => {\n if (!element.dataset.format)\n return false;\n\n const name = generateName(\n context.location,\n element.dataset.format,\n element.dataset.slot,\n );\n\n return !context.getAll?.().some(activeSlot => activeSlot.name === name);\n })\n .map(element => createSlot({\n format: element.dataset.format as string,\n containingElement: element,\n slot: element.dataset.slot,\n context,\n }))\n .filter(slot => !context.getAll?.().some(activeSlot => activeSlot.name === slot.name));\n}\n"],"names":["waitForDomLoad","generateName","createSlot","slot"],"mappings":";;;;AAOA,eAAsB,aACpB,SACoC;AACpC,QAAMA,UAAe,eAAA;AAEd,SAAA,MAAM,KAAK,SAAS,iBAA8B,SAAS,CAAC,EAChE,OAAO,CAAC,YAAY;;AACf,QAAA,CAAC,QAAQ,QAAQ;AACZ,aAAA;AAET,UAAM,OAAOC,UAAA;AAAA,MACX,QAAQ;AAAA,MACR,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,IAAA;AAGX,WAAA,GAAC,aAAQ,WAAR,iCAAmB,KAAK,CAAc,eAAA,WAAW,SAAS;AAAA,EACnE,CAAA,EACA,IAAI,CAAA,YAAWC,gBAAW;AAAA,IACzB,QAAQ,QAAQ,QAAQ;AAAA,IACxB,mBAAmB;AAAA,IACnB,MAAM,QAAQ,QAAQ;AAAA,IACtB;AAAA,EAAA,CACD,CAAC,EACD,OAAO;;AAAQ,cAAC,aAAQ,WAAR,iCAAmB,KAAK,CAAc,eAAA,WAAW,SAASC,MAAK;AAAA,GAAK;AACzF;;"}
1
+ {"version":3,"file":"findDomSlots.cjs","sources":["../../../src/findDomSlots/findDomSlots.ts"],"sourcesContent":["import type { AdheseContext, AdheseSlot } from '@adhese/sdk';\nimport { generateName, waitForDomLoad } from '@adhese/sdk-shared';\nimport { createSlot } from '../slot/slot';\n\n/**\n * Find all slots in the DOM and render them. Ignore slots that are already active.\n */\nexport async function findDomSlots(\n context: AdheseContext,\n): Promise<ReadonlyArray<AdheseSlot>> {\n await waitForDomLoad();\n\n return Array.from(document.querySelectorAll<HTMLElement>('.adunit'))\n .filter((element) => {\n if (!element.dataset.format)\n return false;\n\n const name = generateName(\n context.location,\n element.dataset.format,\n element.dataset.slot,\n );\n\n return !context.getAll?.().some(activeSlot => activeSlot.name === name);\n })\n .map(element => createSlot({\n format: element.dataset.format as string,\n containingElement: element,\n slot: element.dataset.slot,\n context,\n }))\n .filter(slot => !context.getAll?.().some(activeSlot => activeSlot.name === slot.name));\n}\n"],"names":["waitForDomLoad","generateName","createSlot","slot"],"mappings":";;;;AAOA,eAAsB,aACpB,SACoC;AACpC,QAAMA,yBAAe;AAEd,SAAA,MAAM,KAAK,SAAS,iBAA8B,SAAS,CAAC,EAChE,OAAO,CAAC,YAAY;;AACf,QAAA,CAAC,QAAQ,QAAQ;AACZ,aAAA;AAET,UAAM,OAAOC,UAAA;AAAA,MACX,QAAQ;AAAA,MACR,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,IAClB;AAEO,WAAA,GAAC,aAAQ,WAAR,iCAAmB,KAAK,CAAc,eAAA,WAAW,SAAS;AAAA,EACnE,CAAA,EACA,IAAI,CAAA,YAAWC,gBAAW;AAAA,IACzB,QAAQ,QAAQ,QAAQ;AAAA,IACxB,mBAAmB;AAAA,IACnB,MAAM,QAAQ,QAAQ;AAAA,IACtB;AAAA,EACD,CAAA,CAAC,EACD,OAAO,WAAQ;;AAAA,cAAC,aAAQ,WAAR,iCAAmB,KAAK,CAAc,eAAA,WAAW,SAASC,MAAK;AAAA,GAAK;AACzF;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.cjs","sources":["../../src/hooks.ts"],"sourcesContent":["import type { AdheseAd, AdheseSlotOptions } from './adheseSdk';\nimport type { AdMultiRequestOptions } from './requestAds/requestAds';\nimport { createAsyncHook, createSyncHook } from '@adhese/sdk-shared';\n\n// eslint-disable-next-line ts/explicit-function-return-type,ts/explicit-module-boundary-types\nexport function createGlobalHooks() {\n const disposeFunctions = new Set<() => void>();\n\n let isInit = false;\n const [runOnInit, onInit, disposeOnInit] = createSyncHook({\n onRun(callbacks) {\n isInit = true;\n callbacks?.clear();\n },\n onAdd() {\n if (isInit)\n runOnInit();\n },\n });\n disposeFunctions.add(disposeOnInit);\n\n let isDisposed = false;\n const [runOnDispose, onDispose, disposeOnDispose] = createSyncHook({\n onRun(callbacks) {\n isDisposed = true;\n callbacks?.clear();\n },\n onAdd() {\n if (isDisposed)\n runOnDispose();\n },\n });\n disposeFunctions.add(disposeOnDispose);\n\n const [runOnRequest, onRequest, disposeOnRequest] = createAsyncHook<AdMultiRequestOptions>();\n disposeFunctions.add(disposeOnRequest);\n\n const [runOnResponse, onResponse, disposeOnResponse] = createAsyncHook<ReadonlyArray<AdheseAd>>();\n disposeFunctions.add(disposeOnResponse);\n\n const [runOnSlotCreate, onSlotCreate, disposeOnSlotCreate] = createSyncHook<AdheseSlotOptions>();\n disposeFunctions.add(disposeOnSlotCreate);\n\n function clearAll(): void {\n for (const disposeFunction of disposeFunctions)\n disposeFunction();\n }\n\n return {\n runOnInit,\n onInit,\n runOnDispose,\n onDispose,\n runOnRequest,\n onRequest,\n runOnResponse,\n onResponse,\n runOnSlotCreate,\n onSlotCreate,\n clearAll,\n };\n}\n"],"names":["createSyncHook","createAsyncHook"],"mappings":";;;AAKO,SAAS,oBAAoB;AAC5B,QAAA,uCAAuB;AAE7B,MAAI,SAAS;AACb,QAAM,CAAC,WAAW,QAAQ,aAAa,IAAIA,UAAAA,eAAe;AAAA,IACxD,MAAM,WAAW;AACN,eAAA;AACT,6CAAW;AAAA,IACb;AAAA,IACA,QAAQ;AACF,UAAA;AACQ;IACd;AAAA,EAAA,CACD;AACD,mBAAiB,IAAI,aAAa;AAElC,MAAI,aAAa;AACjB,QAAM,CAAC,cAAc,WAAW,gBAAgB,IAAIA,UAAAA,eAAe;AAAA,IACjE,MAAM,WAAW;AACF,mBAAA;AACb,6CAAW;AAAA,IACb;AAAA,IACA,QAAQ;AACF,UAAA;AACW;IACjB;AAAA,EAAA,CACD;AACD,mBAAiB,IAAI,gBAAgB;AAErC,QAAM,CAAC,cAAc,WAAW,gBAAgB,IAAIC,UAAuC,gBAAA;AAC3F,mBAAiB,IAAI,gBAAgB;AAErC,QAAM,CAAC,eAAe,YAAY,iBAAiB,IAAIA,UAAyC,gBAAA;AAChG,mBAAiB,IAAI,iBAAiB;AAEtC,QAAM,CAAC,iBAAiB,cAAc,mBAAmB,IAAID,UAAkC,eAAA;AAC/F,mBAAiB,IAAI,mBAAmB;AAExC,WAAS,WAAiB;AACxB,eAAW,mBAAmB;AACZ;EACpB;AAEO,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;;"}
1
+ {"version":3,"file":"hooks.cjs","sources":["../../src/hooks.ts"],"sourcesContent":["import type { AdheseAd, AdheseSlotOptions } from './adheseSdk';\nimport type { AdMultiRequestOptions } from './requestAds/requestAds';\nimport { createAsyncHook, createSyncHook } from '@adhese/sdk-shared';\n\n// eslint-disable-next-line ts/explicit-function-return-type,ts/explicit-module-boundary-types\nexport function createGlobalHooks() {\n const disposeFunctions = new Set<() => void>();\n\n let isInit = false;\n const [runOnInit, onInit, disposeOnInit] = createSyncHook({\n onRun(callbacks) {\n isInit = true;\n callbacks?.clear();\n },\n onAdd() {\n if (isInit)\n runOnInit();\n },\n });\n disposeFunctions.add(disposeOnInit);\n\n let isDisposed = false;\n const [runOnDispose, onDispose, disposeOnDispose] = createSyncHook({\n onRun(callbacks) {\n isDisposed = true;\n callbacks?.clear();\n },\n onAdd() {\n if (isDisposed)\n runOnDispose();\n },\n });\n disposeFunctions.add(disposeOnDispose);\n\n const [runOnRequest, onRequest, disposeOnRequest] = createAsyncHook<AdMultiRequestOptions>();\n disposeFunctions.add(disposeOnRequest);\n\n const [runOnResponse, onResponse, disposeOnResponse] = createAsyncHook<ReadonlyArray<AdheseAd>>();\n disposeFunctions.add(disposeOnResponse);\n\n const [runOnSlotCreate, onSlotCreate, disposeOnSlotCreate] = createSyncHook<AdheseSlotOptions>();\n disposeFunctions.add(disposeOnSlotCreate);\n\n function clearAll(): void {\n for (const disposeFunction of disposeFunctions)\n disposeFunction();\n }\n\n return {\n runOnInit,\n onInit,\n runOnDispose,\n onDispose,\n runOnRequest,\n onRequest,\n runOnResponse,\n onResponse,\n runOnSlotCreate,\n onSlotCreate,\n clearAll,\n };\n}\n"],"names":["createSyncHook","createAsyncHook"],"mappings":";;;AAKO,SAAS,oBAAoB;AAC5B,QAAA,uCAAuB,IAAgB;AAE7C,MAAI,SAAS;AACb,QAAM,CAAC,WAAW,QAAQ,aAAa,IAAIA,UAAAA,eAAe;AAAA,IACxD,MAAM,WAAW;AACN,eAAA;AACT,6CAAW;AAAA,IACb;AAAA,IACA,QAAQ;AACF,UAAA;AACQ,kBAAA;AAAA,IAAA;AAAA,EACd,CACD;AACD,mBAAiB,IAAI,aAAa;AAElC,MAAI,aAAa;AACjB,QAAM,CAAC,cAAc,WAAW,gBAAgB,IAAIA,UAAAA,eAAe;AAAA,IACjE,MAAM,WAAW;AACF,mBAAA;AACb,6CAAW;AAAA,IACb;AAAA,IACA,QAAQ;AACF,UAAA;AACW,qBAAA;AAAA,IAAA;AAAA,EACjB,CACD;AACD,mBAAiB,IAAI,gBAAgB;AAErC,QAAM,CAAC,cAAc,WAAW,gBAAgB,IAAIC,UAAAA,gBAAuC;AAC3F,mBAAiB,IAAI,gBAAgB;AAErC,QAAM,CAAC,eAAe,YAAY,iBAAiB,IAAIA,UAAAA,gBAAyC;AAChG,mBAAiB,IAAI,iBAAiB;AAEtC,QAAM,CAAC,iBAAiB,cAAc,mBAAmB,IAAID,UAAAA,eAAkC;AAC/F,mBAAiB,IAAI,mBAAmB;AAExC,WAAS,WAAiB;AACxB,eAAW,mBAAmB;AACZ,sBAAA;AAAA,EAAA;AAGb,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"logger.cjs","sources":["../../../src/logger/logger.ts"],"sourcesContent":["import { createLogger } from '@adhese/sdk-shared';\nimport { name, version } from '../../package.json';\n\nexport const logger = createLogger({\n scope: `${name}@${version}`,\n});\n"],"names":["createLogger","name","version"],"mappings":";;;;AAGO,MAAM,SAASA,UAAAA,aAAa;AAAA,EACjC,OAAO,GAAGC,SAAAA,IAAI,IAAIC,SAAO,OAAA;AAC3B,CAAC;;"}
1
+ {"version":3,"file":"logger.cjs","sources":["../../../src/logger/logger.ts"],"sourcesContent":["import { createLogger } from '@adhese/sdk-shared';\nimport { name, version } from '../../package.json';\n\nexport const logger = createLogger({\n scope: `${name}@${version}`,\n});\n"],"names":["createLogger","name","version"],"mappings":";;;;AAGO,MAAM,SAASA,UAAAA,aAAa;AAAA,EACjC,OAAO,GAAGC,aAAI,IAAIC,SAAAA,OAAO;AAC3B,CAAC;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"main.cjs","sources":["../../src/main.ts"],"sourcesContent":["import type {\n Adhese,\n AdheseContextStateWithPlugins,\n AdheseOptions,\n AdhesePlugin,\n MergedOptions,\n} from './main.types';\nimport type { AdheseSlot, AdheseSlotOptions } from './slot/slot.types';\nimport { awaitTimeout, createEventManager, effectScope, omit, reactive, watch } from '@adhese/sdk-shared';\nimport { version } from '../package.json';\nimport { useConsent } from './consent/consent';\nimport { createGlobalHooks } from './hooks';\nimport { logger } from './logger/logger';\nimport { useMainDebugMode, useMainParameters, useMainQueryDetector } from './main.composables';\nimport { fetchAllUnrenderedSlots } from './main.utils';\n\nimport { createSlotManager } from './slotManager/slotManager';\n\n/**\n * Creates an Adhese instance. This instance is your main entry point to the Adhese API.\n *\n * @param options {AdheseOptions} The options to create the Adhese instance with. See the {@link AdheseOptions} type for more information.\n *\n * @return Adhese The Adhese instance.\n */\nexport function createAdhese<T extends ReadonlyArray<AdhesePlugin>>(options: AdheseOptions<T>): Adhese<T> {\n const scope = effectScope();\n\n return scope.run(() => {\n const mergedOptions: MergedOptions = {\n host: `https://ads-${options.account}.adhese.com`,\n poolHost: `https://pool-${options.account}.adhese.com`,\n location: 'homepage',\n requestType: 'POST',\n debug: false,\n initialSlots: [],\n findDomSlotsOnLoad: false,\n consent: false,\n logReferrer: true,\n logUrl: true,\n eagerRendering: false,\n viewabilityTracking: true,\n ...options,\n };\n\n import('./requestAds/requestAds.schema').catch(logger.error);\n\n const hooks = createGlobalHooks();\n\n const context = reactive<AdheseContextStateWithPlugins<T>>({\n location: mergedOptions.location,\n consent: mergedOptions.consent,\n debug: mergedOptions.debug,\n options: mergedOptions,\n logger,\n isDisposed: false,\n parameters: new Map(),\n events: createEventManager(),\n slots: new Map(),\n device: 'unknown',\n hooks,\n plugins: {},\n dispose,\n findDomSlots,\n getAll,\n get,\n addSlot,\n });\n\n for (const [index, plugin] of options.plugins?.entries() ?? []) {\n const data = plugin(context, {\n index,\n version,\n hooks,\n });\n\n const name = data.name as keyof typeof context.plugins;\n context.plugins[name] = omit(data, ['name']) as typeof context.plugins[typeof name];\n }\n\n watch(() => context.location, (newLocation) => {\n context.events?.locationChange.dispatch(newLocation);\n });\n\n useMainParameters(context, mergedOptions);\n\n const slotManager = createSlotManager({\n initialSlots: mergedOptions.initialSlots,\n context,\n });\n\n function getAll(): ReadonlyArray<AdheseSlot> {\n return slotManager.getAll() ?? [];\n }\n context.getAll = getAll;\n\n function get(name: string): AdheseSlot | undefined {\n return slotManager.get(name);\n }\n context.get = get;\n\n function addSlot(slotOptions: AdheseSlotOptions): Readonly<AdheseSlot> {\n return slotManager.add(slotOptions);\n }\n context.addSlot = addSlot;\n\n async function findDomSlots(): Promise<ReadonlyArray<AdheseSlot>> {\n const domSlots = (await slotManager.findDomSlots() ?? []).filter(slot => !slot.lazyLoading);\n\n if (domSlots.length <= 0)\n return [];\n\n await fetchAllUnrenderedSlots(context.getAll());\n\n return domSlots;\n }\n context.findDomSlots = findDomSlots;\n\n useMainDebugMode(context);\n\n useMainQueryDetector(mergedOptions, context);\n\n useConsent(context);\n\n function dispose(): void {\n context.isDisposed = true;\n\n slotManager.dispose();\n context.parameters?.clear();\n context.events?.dispose();\n\n hooks.runOnDispose();\n hooks.clearAll();\n\n scope.stop();\n }\n context.dispose = dispose;\n\n hooks.onInit(async () => {\n await awaitTimeout(0);\n\n if ((slotManager.getAll().length ?? 0) > 0)\n await fetchAllUnrenderedSlots(context.getAll()).catch(logger.error);\n\n if (mergedOptions.findDomSlotsOnLoad)\n await context?.findDomSlots();\n\n logger.debug('Created Adhese SDK instance', {\n mergedOptions,\n });\n\n if (!scope.active)\n dispose();\n });\n\n hooks.runOnInit();\n\n return context as Adhese<T>;\n })!;\n}\n"],"names":["effectScope","logger","hooks","createGlobalHooks","reactive","createEventManager","version","omit","watch","_a","useMainParameters","slotManager","createSlotManager","fetchAllUnrenderedSlots","useMainDebugMode","useMainQueryDetector","useConsent","awaitTimeout"],"mappings":"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"}
1
+ {"version":3,"file":"main.cjs","sources":["../../src/main.ts"],"sourcesContent":["import type {\n Adhese,\n AdheseContextStateWithPlugins,\n AdheseOptions,\n AdhesePlugin,\n MergedOptions,\n} from './main.types';\nimport type { AdheseSlot, AdheseSlotOptions } from './slot/slot.types';\nimport { awaitTimeout, createEventManager, effectScope, omit, reactive, watch } from '@adhese/sdk-shared';\nimport { version } from '../package.json';\nimport { useConsent } from './consent/consent';\nimport { createGlobalHooks } from './hooks';\nimport { logger } from './logger/logger';\nimport { useMainDebugMode, useMainParameters, useMainQueryDetector } from './main.composables';\nimport { fetchAllUnrenderedSlots } from './main.utils';\n\nimport { createSlotManager } from './slotManager/slotManager';\n\n/**\n * Creates an Adhese instance. This instance is your main entry point to the Adhese API.\n *\n * @param options {AdheseOptions} The options to create the Adhese instance with. See the {@link AdheseOptions} type for more information.\n *\n * @return Adhese The Adhese instance.\n */\nexport function createAdhese<T extends ReadonlyArray<AdhesePlugin>>(options: AdheseOptions<T>): Adhese<T> {\n const scope = effectScope();\n\n return scope.run(() => {\n const mergedOptions: MergedOptions = {\n host: `https://ads-${options.account}.adhese.com`,\n poolHost: `https://pool-${options.account}.adhese.com`,\n location: 'homepage',\n requestType: 'POST',\n debug: false,\n initialSlots: [],\n findDomSlotsOnLoad: false,\n consent: false,\n logReferrer: true,\n logUrl: true,\n eagerRendering: false,\n viewabilityTracking: true,\n ...options,\n };\n\n import('./requestAds/requestAds.schema').catch(logger.error);\n\n const hooks = createGlobalHooks();\n\n const context = reactive<AdheseContextStateWithPlugins<T>>({\n location: mergedOptions.location,\n consent: mergedOptions.consent,\n debug: mergedOptions.debug,\n options: mergedOptions,\n logger,\n isDisposed: false,\n parameters: new Map(),\n events: createEventManager(),\n slots: new Map(),\n device: 'unknown',\n hooks,\n plugins: {},\n dispose,\n findDomSlots,\n getAll,\n get,\n addSlot,\n });\n\n for (const [index, plugin] of options.plugins?.entries() ?? []) {\n const data = plugin(context, {\n index,\n version,\n hooks,\n });\n\n const name = data.name as keyof typeof context.plugins;\n context.plugins[name] = omit(data, ['name']) as typeof context.plugins[typeof name];\n }\n\n watch(() => context.location, (newLocation) => {\n context.events?.locationChange.dispatch(newLocation);\n });\n\n useMainParameters(context, mergedOptions);\n\n const slotManager = createSlotManager({\n initialSlots: mergedOptions.initialSlots,\n context,\n });\n\n function getAll(): ReadonlyArray<AdheseSlot> {\n return slotManager.getAll() ?? [];\n }\n context.getAll = getAll;\n\n function get(name: string): AdheseSlot | undefined {\n return slotManager.get(name);\n }\n context.get = get;\n\n function addSlot(slotOptions: AdheseSlotOptions): Readonly<AdheseSlot> {\n return slotManager.add(slotOptions);\n }\n context.addSlot = addSlot;\n\n async function findDomSlots(): Promise<ReadonlyArray<AdheseSlot>> {\n const domSlots = (await slotManager.findDomSlots() ?? []).filter(slot => !slot.lazyLoading);\n\n if (domSlots.length <= 0)\n return [];\n\n await fetchAllUnrenderedSlots(context.getAll());\n\n return domSlots;\n }\n context.findDomSlots = findDomSlots;\n\n useMainDebugMode(context);\n\n useMainQueryDetector(mergedOptions, context);\n\n useConsent(context);\n\n function dispose(): void {\n context.isDisposed = true;\n\n slotManager.dispose();\n context.parameters?.clear();\n context.events?.dispose();\n\n hooks.runOnDispose();\n hooks.clearAll();\n\n scope.stop();\n }\n context.dispose = dispose;\n\n hooks.onInit(async () => {\n await awaitTimeout(0);\n\n if ((slotManager.getAll().length ?? 0) > 0)\n await fetchAllUnrenderedSlots(context.getAll()).catch(logger.error);\n\n if (mergedOptions.findDomSlotsOnLoad)\n await context?.findDomSlots();\n\n logger.debug('Created Adhese SDK instance', {\n mergedOptions,\n });\n\n if (!scope.active)\n dispose();\n });\n\n hooks.runOnInit();\n\n return context as Adhese<T>;\n })!;\n}\n"],"names":["effectScope","logger","hooks","createGlobalHooks","reactive","createEventManager","version","omit","watch","_a","useMainParameters","slotManager","createSlotManager","fetchAllUnrenderedSlots","useMainDebugMode","useMainQueryDetector","useConsent","awaitTimeout"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"main.composables.cjs","sources":["../../src/main.composables.ts"],"sourcesContent":["import type { AdheseContextState, MergedOptions } from './main.types';\nimport { watch } from '@adhese/sdk-shared';\nimport { isPreviewMode } from './main.utils';\nimport { useQueryDetector } from './queryDetector/queryDetector';\n\nexport function useMainQueryDetector(mergedOptions: MergedOptions, context: AdheseContextState): void {\n const [device] = useQueryDetector(context, mergedOptions.queries);\n watch(device, async (newDevice) => {\n context.device = newDevice;\n\n context.parameters?.set('dt', newDevice);\n context.parameters?.set('br', newDevice);\n\n await Promise.allSettled(context.getAll().map(async slot => slot.request()));\n }, { immediate: true });\n}\n\nexport function useMainDebugMode(context: AdheseContextState): void {\n if (window.location.search.includes('adhese_debug=true') || isPreviewMode()) {\n context.debug = true;\n }\n\n watch(() => context.debug, async (newDebug) => {\n if (newDebug) {\n context.logger.setMinLogLevelThreshold('debug');\n context.logger.debug('Debug mode enabled');\n context.events?.debugChange.dispatch(true);\n }\n else {\n context.logger.debug('Debug mode disabled');\n context.logger.setMinLogLevelThreshold('info');\n context.events?.debugChange.dispatch(false);\n }\n }, {\n immediate: true,\n });\n\n context.hooks.onDispose(() => {\n context.logger.resetLogs();\n context.logger.debug('Adhese instance disposed');\n });\n}\n\nexport function useMainParameters(context: AdheseContextState, options: MergedOptions): void {\n const parameters = new Map<string, string | ReadonlyArray<string>>();\n\n if (options.logReferrer)\n parameters.set('re', btoa(document.referrer));\n\n if (options.logUrl)\n parameters.set('ur', btoa(window.location.href));\n\n for (const [key, value] of Object.entries({\n ...options.parameters ?? {},\n rn: Math.round(Math.random() * 10_000).toString(),\n }))\n parameters.set(key, value);\n\n context.parameters = parameters;\n\n watch(\n () => context.parameters,\n (newParameters) => {\n context.events?.parametersChange.dispatch(newParameters);\n },\n {\n deep: true,\n },\n );\n}\n"],"names":["useQueryDetector","watch","isPreviewMode"],"mappings":";;;;;AAKgB,SAAA,qBAAqB,eAA8B,SAAmC;AACpG,QAAM,CAAC,MAAM,IAAIA,cAAAA,iBAAiB,SAAS,cAAc,OAAO;AAC1DC,kBAAA,QAAQ,OAAO,cAAc;;AACjC,YAAQ,SAAS;AAET,kBAAA,eAAA,mBAAY,IAAI,MAAM;AACtB,kBAAA,eAAA,mBAAY,IAAI,MAAM;AAExB,UAAA,QAAQ,WAAW,QAAQ,OAAO,EAAE,IAAI,OAAM,SAAQ,KAAK,QAAQ,CAAC,CAAC;AAAA,EAAA,GAC1E,EAAE,WAAW,KAAA,CAAM;AACxB;AAEO,SAAS,iBAAiB,SAAmC;AAClE,MAAI,OAAO,SAAS,OAAO,SAAS,mBAAmB,KAAKC,WAAAA,iBAAiB;AAC3E,YAAQ,QAAQ;AAAA,EAClB;AAEAD,YAAAA,MAAM,MAAM,QAAQ,OAAO,OAAO,aAAa;;AAC7C,QAAI,UAAU;AACJ,cAAA,OAAO,wBAAwB,OAAO;AACtC,cAAA,OAAO,MAAM,oBAAoB;AACjC,oBAAA,WAAA,mBAAQ,YAAY,SAAS;AAAA,IAAI,OAEtC;AACK,cAAA,OAAO,MAAM,qBAAqB;AAClC,cAAA,OAAO,wBAAwB,MAAM;AACrC,oBAAA,WAAA,mBAAQ,YAAY,SAAS;AAAA,IACvC;AAAA,EAAA,GACC;AAAA,IACD,WAAW;AAAA,EAAA,CACZ;AAEO,UAAA,MAAM,UAAU,MAAM;AAC5B,YAAQ,OAAO;AACP,YAAA,OAAO,MAAM,0BAA0B;AAAA,EAAA,CAChD;AACH;AAEgB,SAAA,kBAAkB,SAA6B,SAA8B;AACrF,QAAA,iCAAiB;AAEvB,MAAI,QAAQ;AACV,eAAW,IAAI,MAAM,KAAK,SAAS,QAAQ,CAAC;AAE9C,MAAI,QAAQ;AACV,eAAW,IAAI,MAAM,KAAK,OAAO,SAAS,IAAI,CAAC;AAEjD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ;AAAA,IACxC,GAAG,QAAQ,cAAc,CAAC;AAAA,IAC1B,IAAI,KAAK,MAAM,KAAK,WAAW,GAAM,EAAE,SAAS;AAAA,EAAA,CACjD;AACY,eAAA,IAAI,KAAK,KAAK;AAE3B,UAAQ,aAAa;AAErBA,YAAA;AAAA,IACE,MAAM,QAAQ;AAAA,IACd,CAAC,kBAAkB;;AACT,oBAAA,WAAA,mBAAQ,iBAAiB,SAAS;AAAA,IAC5C;AAAA,IACA;AAAA,MACE,MAAM;AAAA,IACR;AAAA,EAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"main.composables.cjs","sources":["../../src/main.composables.ts"],"sourcesContent":["import type { AdheseContextState, MergedOptions } from './main.types';\nimport { watch } from '@adhese/sdk-shared';\nimport { isPreviewMode } from './main.utils';\nimport { useQueryDetector } from './queryDetector/queryDetector';\n\nexport function useMainQueryDetector(mergedOptions: MergedOptions, context: AdheseContextState): void {\n const [device] = useQueryDetector(context, mergedOptions.queries);\n watch(device, async (newDevice) => {\n context.device = newDevice;\n\n context.parameters?.set('dt', newDevice);\n context.parameters?.set('br', newDevice);\n\n await Promise.allSettled(context.getAll().map(async slot => slot.request()));\n }, { immediate: true });\n}\n\nexport function useMainDebugMode(context: AdheseContextState): void {\n if (window.location.search.includes('adhese_debug=true') || isPreviewMode()) {\n context.debug = true;\n }\n\n watch(() => context.debug, async (newDebug) => {\n if (newDebug) {\n context.logger.setMinLogLevelThreshold('debug');\n context.logger.debug('Debug mode enabled');\n context.events?.debugChange.dispatch(true);\n }\n else {\n context.logger.debug('Debug mode disabled');\n context.logger.setMinLogLevelThreshold('info');\n context.events?.debugChange.dispatch(false);\n }\n }, {\n immediate: true,\n });\n\n context.hooks.onDispose(() => {\n context.logger.resetLogs();\n context.logger.debug('Adhese instance disposed');\n });\n}\n\nexport function useMainParameters(context: AdheseContextState, options: MergedOptions): void {\n const parameters = new Map<string, string | ReadonlyArray<string>>();\n\n if (options.logReferrer)\n parameters.set('re', btoa(document.referrer));\n\n if (options.logUrl)\n parameters.set('ur', btoa(window.location.href));\n\n for (const [key, value] of Object.entries({\n ...options.parameters ?? {},\n rn: Math.round(Math.random() * 10_000).toString(),\n }))\n parameters.set(key, value);\n\n context.parameters = parameters;\n\n watch(\n () => context.parameters,\n (newParameters) => {\n context.events?.parametersChange.dispatch(newParameters);\n },\n {\n deep: true,\n },\n );\n}\n"],"names":["useQueryDetector","watch","isPreviewMode"],"mappings":";;;;;AAKgB,SAAA,qBAAqB,eAA8B,SAAmC;AACpG,QAAM,CAAC,MAAM,IAAIA,cAAAA,iBAAiB,SAAS,cAAc,OAAO;AAC1DC,kBAAA,QAAQ,OAAO,cAAc;;AACjC,YAAQ,SAAS;AAET,kBAAA,eAAA,mBAAY,IAAI,MAAM;AACtB,kBAAA,eAAA,mBAAY,IAAI,MAAM;AAExB,UAAA,QAAQ,WAAW,QAAQ,OAAO,EAAE,IAAI,OAAM,SAAQ,KAAK,QAAQ,CAAC,CAAC;AAAA,EAAA,GAC1E,EAAE,WAAW,MAAM;AACxB;AAEO,SAAS,iBAAiB,SAAmC;AAClE,MAAI,OAAO,SAAS,OAAO,SAAS,mBAAmB,KAAKC,WAAAA,iBAAiB;AAC3E,YAAQ,QAAQ;AAAA,EAAA;AAGlBD,YAAAA,MAAM,MAAM,QAAQ,OAAO,OAAO,aAAa;;AAC7C,QAAI,UAAU;AACJ,cAAA,OAAO,wBAAwB,OAAO;AACtC,cAAA,OAAO,MAAM,oBAAoB;AACjC,oBAAA,WAAA,mBAAQ,YAAY,SAAS;AAAA,IAAI,OAEtC;AACK,cAAA,OAAO,MAAM,qBAAqB;AAClC,cAAA,OAAO,wBAAwB,MAAM;AACrC,oBAAA,WAAA,mBAAQ,YAAY,SAAS;AAAA,IAAK;AAAA,EAC5C,GACC;AAAA,IACD,WAAW;AAAA,EAAA,CACZ;AAEO,UAAA,MAAM,UAAU,MAAM;AAC5B,YAAQ,OAAO,UAAU;AACjB,YAAA,OAAO,MAAM,0BAA0B;AAAA,EAAA,CAChD;AACH;AAEgB,SAAA,kBAAkB,SAA6B,SAA8B;AACrF,QAAA,iCAAiB,IAA4C;AAEnE,MAAI,QAAQ;AACV,eAAW,IAAI,MAAM,KAAK,SAAS,QAAQ,CAAC;AAE9C,MAAI,QAAQ;AACV,eAAW,IAAI,MAAM,KAAK,OAAO,SAAS,IAAI,CAAC;AAEjD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ;AAAA,IACxC,GAAG,QAAQ,cAAc,CAAC;AAAA,IAC1B,IAAI,KAAK,MAAM,KAAK,OAAW,IAAA,GAAM,EAAE,SAAS;AAAA,EAAA,CACjD;AACY,eAAA,IAAI,KAAK,KAAK;AAE3B,UAAQ,aAAa;AAErBA,YAAA;AAAA,IACE,MAAM,QAAQ;AAAA,IACd,CAAC,kBAAkB;;AACT,oBAAA,WAAA,mBAAQ,iBAAiB,SAAS;AAAA,IAC5C;AAAA,IACA;AAAA,MACE,MAAM;AAAA,IAAA;AAAA,EAEV;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"main.utils.cjs","sources":["../../src/main.utils.ts"],"sourcesContent":["import type { AdheseSlot } from './slot/slot.types';\nimport { logger } from './logger/logger';\n\n/**\n * Checks if the current page is in preview mode.\n */\nexport function isPreviewMode(): boolean {\n return window.location.search.includes('adhesePreviewCreativeId');\n}\n\nexport async function fetchAllUnrenderedSlots(slots: ReadonlyArray<AdheseSlot>): Promise<void> {\n const filteredSlots = slots.filter(slot => !slot.lazyLoading && !slot.data);\n\n if (filteredSlots.length === 0)\n return;\n\n const results = await Promise.allSettled(filteredSlots.map(slot => slot.request));\n\n for (const [index, result] of results.entries()) {\n if (result.status === 'rejected') {\n logger.error(`Failed to fetch slot data for slot ${filteredSlots[index].name}`, result.reason);\n }\n }\n}\n"],"names":["logger"],"mappings":";;;AAMO,SAAS,gBAAyB;AACvC,SAAO,OAAO,SAAS,OAAO,SAAS,yBAAyB;AAClE;AAEA,eAAsB,wBAAwB,OAAiD;AACvF,QAAA,gBAAgB,MAAM,OAAO,CAAA,SAAQ,CAAC,KAAK,eAAe,CAAC,KAAK,IAAI;AAE1E,MAAI,cAAc,WAAW;AAC3B;AAEI,QAAA,UAAU,MAAM,QAAQ,WAAW,cAAc,IAAI,CAAA,SAAQ,KAAK,OAAO,CAAC;AAEhF,aAAW,CAAC,OAAO,MAAM,KAAK,QAAQ,WAAW;AAC3C,QAAA,OAAO,WAAW,YAAY;AACzBA,aAAAA,OAAA,MAAM,sCAAsC,cAAc,KAAK,EAAE,IAAI,IAAI,OAAO,MAAM;AAAA,IAC/F;AAAA,EACF;AACF;;;"}
1
+ {"version":3,"file":"main.utils.cjs","sources":["../../src/main.utils.ts"],"sourcesContent":["import type { AdheseSlot } from './slot/slot.types';\nimport { logger } from './logger/logger';\n\n/**\n * Checks if the current page is in preview mode.\n */\nexport function isPreviewMode(): boolean {\n return window.location.search.includes('adhesePreviewCreativeId');\n}\n\nexport async function fetchAllUnrenderedSlots(slots: ReadonlyArray<AdheseSlot>): Promise<void> {\n const filteredSlots = slots.filter(slot => !slot.lazyLoading && !slot.data);\n\n if (filteredSlots.length === 0)\n return;\n\n const results = await Promise.allSettled(filteredSlots.map(slot => slot.request));\n\n for (const [index, result] of results.entries()) {\n if (result.status === 'rejected') {\n logger.error(`Failed to fetch slot data for slot ${filteredSlots[index].name}`, result.reason);\n }\n }\n}\n"],"names":["logger"],"mappings":";;;AAMO,SAAS,gBAAyB;AACvC,SAAO,OAAO,SAAS,OAAO,SAAS,yBAAyB;AAClE;AAEA,eAAsB,wBAAwB,OAAiD;AACvF,QAAA,gBAAgB,MAAM,OAAO,CAAA,SAAQ,CAAC,KAAK,eAAe,CAAC,KAAK,IAAI;AAE1E,MAAI,cAAc,WAAW;AAC3B;AAEI,QAAA,UAAU,MAAM,QAAQ,WAAW,cAAc,IAAI,CAAA,SAAQ,KAAK,OAAO,CAAC;AAEhF,aAAW,CAAC,OAAO,MAAM,KAAK,QAAQ,WAAW;AAC3C,QAAA,OAAO,WAAW,YAAY;AACzBA,oBAAA,MAAM,sCAAsC,cAAc,KAAK,EAAE,IAAI,IAAI,OAAO,MAAM;AAAA,IAAA;AAAA,EAC/F;AAEJ;;;"}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const name = "@adhese/sdk";
4
- const version = "1.4.1";
4
+ const version = "1.4.2";
5
5
  exports.name = name;
6
6
  exports.version = version;
7
7
  //# sourceMappingURL=package.json.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"queryDetector.cjs","sources":["../../../src/queryDetector/queryDetector.ts"],"sourcesContent":["import type { AdheseContext } from '@adhese/sdk';\nimport { computed, type ComputedRef, debounce, ref } from '@adhese/sdk-shared';\n\n/**\n * Create a query detector that will match a list of media queries and keeps track of the current matching query\n */\nexport function useQueryDetector(context: AdheseContext, queries: Record<string, string> = {\n phone: '(max-width: 768px)',\n tablet: '(min-width: 769px) and (max-width: 1024px)',\n desktop: '(min-width: 1025px)',\n}): [ComputedRef<string>, () => void] {\n const entries = Object.entries(queries);\n\n const active = ref(getQuery(entries));\n const queryList = entries.map(([, query]) => window.matchMedia(query));\n\n const handleOnChange = debounce((): void => {\n active.value = getQuery(entries);\n }, {\n waitMs: 50,\n });\n\n context.hooks.onInit(() => {\n for (const query of queryList)\n query.addEventListener('change', handleOnChange.call);\n\n handleOnChange.call();\n });\n\n function dispose(): void {\n for (const query of queryList)\n query.removeEventListener('change', handleOnChange.call);\n }\n\n context.hooks.onDispose(dispose);\n\n return [computed(() => active.value), dispose];\n}\n\nfunction getQuery(entries: ReadonlyArray<[string, string]>): string {\n for (const [device, query] of entries) {\n if (window.matchMedia(query).matches)\n return device;\n }\n\n return 'unknown';\n}\n"],"names":["ref","debounce","computed"],"mappings":";;;AAMgB,SAAA,iBAAiB,SAAwB,UAAkC;AAAA,EACzF,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AACX,GAAsC;AAC9B,QAAA,UAAU,OAAO,QAAQ,OAAO;AAEtC,QAAM,SAASA,UAAA,IAAI,SAAS,OAAO,CAAC;AAC9B,QAAA,YAAY,QAAQ,IAAI,CAAC,CAAA,EAAG,KAAK,MAAM,OAAO,WAAW,KAAK,CAAC;AAE/D,QAAA,iBAAiBC,UAAAA,SAAS,MAAY;AACnC,WAAA,QAAQ,SAAS,OAAO;AAAA,EAAA,GAC9B;AAAA,IACD,QAAQ;AAAA,EAAA,CACT;AAEO,UAAA,MAAM,OAAO,MAAM;AACzB,eAAW,SAAS;AACZ,YAAA,iBAAiB,UAAU,eAAe,IAAI;AAEtD,mBAAe,KAAK;AAAA,EAAA,CACrB;AAED,WAAS,UAAgB;AACvB,eAAW,SAAS;AACZ,YAAA,oBAAoB,UAAU,eAAe,IAAI;AAAA,EAC3D;AAEQ,UAAA,MAAM,UAAU,OAAO;AAE/B,SAAO,CAACC,UAAS,SAAA,MAAM,OAAO,KAAK,GAAG,OAAO;AAC/C;AAEA,SAAS,SAAS,SAAkD;AAClE,aAAW,CAAC,QAAQ,KAAK,KAAK,SAAS;AACjC,QAAA,OAAO,WAAW,KAAK,EAAE;AACpB,aAAA;AAAA,EACX;AAEO,SAAA;AACT;;"}
1
+ {"version":3,"file":"queryDetector.cjs","sources":["../../../src/queryDetector/queryDetector.ts"],"sourcesContent":["import type { AdheseContext } from '@adhese/sdk';\nimport { computed, type ComputedRef, debounce, ref } from '@adhese/sdk-shared';\n\n/**\n * Create a query detector that will match a list of media queries and keeps track of the current matching query\n */\nexport function useQueryDetector(context: AdheseContext, queries: Record<string, string> = {\n phone: '(max-width: 768px)',\n tablet: '(min-width: 769px) and (max-width: 1024px)',\n desktop: '(min-width: 1025px)',\n}): [ComputedRef<string>, () => void] {\n const entries = Object.entries(queries);\n\n const active = ref(getQuery(entries));\n const queryList = entries.map(([, query]) => window.matchMedia(query));\n\n const handleOnChange = debounce((): void => {\n active.value = getQuery(entries);\n }, {\n waitMs: 50,\n });\n\n context.hooks.onInit(() => {\n for (const query of queryList)\n query.addEventListener('change', handleOnChange.call);\n\n handleOnChange.call();\n });\n\n function dispose(): void {\n for (const query of queryList)\n query.removeEventListener('change', handleOnChange.call);\n }\n\n context.hooks.onDispose(dispose);\n\n return [computed(() => active.value), dispose];\n}\n\nfunction getQuery(entries: ReadonlyArray<[string, string]>): string {\n for (const [device, query] of entries) {\n if (window.matchMedia(query).matches)\n return device;\n }\n\n return 'unknown';\n}\n"],"names":["ref","debounce","computed"],"mappings":";;;AAMgB,SAAA,iBAAiB,SAAwB,UAAkC;AAAA,EACzF,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AACX,GAAsC;AAC9B,QAAA,UAAU,OAAO,QAAQ,OAAO;AAEtC,QAAM,SAASA,UAAAA,IAAI,SAAS,OAAO,CAAC;AAC9B,QAAA,YAAY,QAAQ,IAAI,CAAC,CAAA,EAAG,KAAK,MAAM,OAAO,WAAW,KAAK,CAAC;AAE/D,QAAA,iBAAiBC,UAAAA,SAAS,MAAY;AACnC,WAAA,QAAQ,SAAS,OAAO;AAAA,EAAA,GAC9B;AAAA,IACD,QAAQ;AAAA,EAAA,CACT;AAEO,UAAA,MAAM,OAAO,MAAM;AACzB,eAAW,SAAS;AACZ,YAAA,iBAAiB,UAAU,eAAe,IAAI;AAEtD,mBAAe,KAAK;AAAA,EAAA,CACrB;AAED,WAAS,UAAgB;AACvB,eAAW,SAAS;AACZ,YAAA,oBAAoB,UAAU,eAAe,IAAI;AAAA,EAAA;AAGnD,UAAA,MAAM,UAAU,OAAO;AAE/B,SAAO,CAACC,UAAAA,SAAS,MAAM,OAAO,KAAK,GAAG,OAAO;AAC/C;AAEA,SAAS,SAAS,SAAkD;AAClE,aAAW,CAAC,QAAQ,KAAK,KAAK,SAAS;AACjC,QAAA,OAAO,WAAW,KAAK,EAAE;AACpB,aAAA;AAAA,EAAA;AAGJ,SAAA;AACT;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"requestAds.cjs","sources":["../../../src/requestAds/requestAds.ts"],"sourcesContent":["import type { AdheseContext } from '../main.types';\nimport type { AdheseAd } from './requestAds.schema';\nimport { debounce } from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\nimport { requestPreviews } from './requestAds.preview';\nimport { requestWithGet, requestWithPost } from './requestAds.utils';\n\nexport type AdRequestOptions = {\n /**\n * Slot you want to fetch the ad for\n */\n slot: {\n name: string;\n parameters: Map<string, ReadonlyArray<string> | string>;\n };\n context: AdheseContext;\n};\n\nexport type AdMultiRequestOptions = Omit<AdRequestOptions, 'slot'> & {\n slots: ReadonlyArray<AdRequestOptions['slot']>;\n};\n\nconst batch = new Map<string, {\n options: AdRequestOptions;\n resolve(ad: AdheseAd | null): void;\n}>();\n\n/**\n * Debounced function to request ads in batches. This function is debounced to prevent multiple requests for the same ad.\n */\nconst runRequestAdsBatch = debounce(async (context: AdheseContext) => {\n if (batch.size === 0)\n return [];\n\n const ads = await requestAds({\n slots: Array.from(batch.values()).map(({ options }) => options.slot),\n context,\n });\n\n for (const { options, resolve } of batch.values()) {\n const ad = ads.find(({ slotName }) => slotName === options.slot.name);\n\n if (ad)\n resolve(ad);\n else\n resolve(null);\n }\n\n batch.clear();\n\n return ads;\n}, {\n waitMs: 20,\n timing: 'trailing',\n});\n\n/**\n * Request a single ad from the API. If you need to fetch multiple ads at once use the `requestAds` function.\n */\nexport async function requestAd(options: AdRequestOptions): Promise<AdheseAd | null> {\n const promise = new Promise<AdheseAd | null>((resolve) => {\n batch.set(options.slot.name, { options, resolve });\n },\n );\n\n await runRequestAdsBatch.call(options.context);\n\n return promise;\n}\n\n/**\n * Request multiple ads from the API. If you need to fetch a single ad use the `requestAd` function.\n */\nexport async function requestAds(requestOptions: AdMultiRequestOptions): Promise<ReadonlyArray<AdheseAd>> {\n const options = await requestOptions.context.hooks.runOnRequest(requestOptions);\n\n const { context } = options;\n\n try {\n context?.events?.requestAd.dispatch({\n ...options,\n context,\n });\n\n const [response, previews, parseResponse] = await Promise.all([\n context.options.requestType?.toUpperCase() === 'POST'\n ? requestWithPost(options)\n : requestWithGet(options),\n requestPreviews(context.options.account),\n import('./requestAds.schema').then(module => module.parseResponse),\n ]);\n\n logger.debug('Received response', response);\n\n if (!response.ok)\n throw new Error(`Failed to request ad: ${response.status} ${response.statusText}`);\n\n const result = parseResponse((await response.json() as unknown));\n logger.debug('Parsed ad', result);\n\n if (previews.length > 0)\n logger.info(`Found ${previews.length} ${previews.length === 1 ? 'preview' : 'previews'}. Replacing ads in response with preview items`, previews);\n\n const matchedPreviews = previews.map(({ slotName, ...preview }) => {\n const partnerAd = result.find(ad => ad.libId === preview.libId);\n\n return ({\n slotName: `${partnerAd?.slotName ?? slotName}`,\n ...preview,\n });\n });\n\n if (matchedPreviews.length > 0)\n context.events?.previewReceived.dispatch(matchedPreviews);\n\n const mergedResult = await context.hooks.runOnResponse([\n ...result.filter(ad => !previews.some(preview => preview.libId === ad.libId)),\n ...matchedPreviews,\n ]);\n\n context.events?.responseReceived.dispatch(mergedResult);\n\n return mergedResult;\n }\n catch (error) {\n logger.error(String(error));\n context?.events?.requestError.dispatch(error as Error);\n\n throw error;\n }\n}\n"],"names":["debounce","requestWithPost","requestWithGet","requestPreviews","module","logger"],"mappings":";;;;;;AAsBA,MAAM,4BAAY;AAQlB,MAAM,qBAAqBA,UAAAA,SAAS,OAAO,YAA2B;AACpE,MAAI,MAAM,SAAS;AACjB,WAAO;AAEH,QAAA,MAAM,MAAM,WAAW;AAAA,IAC3B,OAAO,MAAM,KAAK,MAAM,OAAQ,CAAA,EAAE,IAAI,CAAC,EAAE,cAAc,QAAQ,IAAI;AAAA,IACnE;AAAA,EAAA,CACD;AAED,aAAW,EAAE,SAAS,QAAa,KAAA,MAAM,UAAU;AAC3C,UAAA,KAAK,IAAI,KAAK,CAAC,EAAE,eAAe,aAAa,QAAQ,KAAK,IAAI;AAEhE,QAAA;AACF,cAAQ,EAAE;AAAA;AAEV,cAAQ,IAAI;AAAA,EAChB;AAEA,QAAM,MAAM;AAEL,SAAA;AACT,GAAG;AAAA,EACD,QAAQ;AAAA,EACR,QAAQ;AACV,CAAC;AAKD,eAAsB,UAAU,SAAqD;AACnF,QAAM,UAAU,IAAI;AAAA,IAAyB,CAAC,YAAY;AACxD,YAAM,IAAI,QAAQ,KAAK,MAAM,EAAE,SAAS,SAAS;AAAA,IACnD;AAAA,EAAA;AAGM,QAAA,mBAAmB,KAAK,QAAQ,OAAO;AAEtC,SAAA;AACT;AAKA,eAAsB,WAAW,gBAAyE;;AACxG,QAAM,UAAU,MAAM,eAAe,QAAQ,MAAM,aAAa,cAAc;AAExE,QAAA,EAAE,QAAY,IAAA;AAEhB,MAAA;AACO,6CAAA,WAAA,mBAAQ,UAAU,SAAS;AAAA,MAClC,GAAG;AAAA,MACH;AAAA,IAAA;AAGF,UAAM,CAAC,UAAU,UAAU,aAAa,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC5D,aAAQ,QAAQ,gBAAhB,mBAA6B,mBAAkB,SAC3CC,iBAAAA,gBAAgB,OAAO,IACvBC,iBAAA,eAAe,OAAO;AAAA,MAC1BC,mCAAgB,QAAQ,QAAQ,OAAO;AAAA,MACvC,QAAO,QAAA,EAAA,KAAA,MAAA,QAAA,yBAAqB,CAAA,EAAE,KAAK,CAAAC,YAAUA,QAAO,aAAa;AAAA,IAAA,CAClE;AAEMC,WAAAA,OAAA,MAAM,qBAAqB,QAAQ;AAE1C,QAAI,CAAC,SAAS;AACN,YAAA,IAAI,MAAM,yBAAyB,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAEnF,UAAM,SAAS,cAAe,MAAM,SAAS,KAAkB,CAAA;AACxDA,WAAAA,OAAA,MAAM,aAAa,MAAM;AAEhC,QAAI,SAAS,SAAS;AACbA,aAAA,OAAA,KAAK,SAAS,SAAS,MAAM,IAAI,SAAS,WAAW,IAAI,YAAY,UAAU,kDAAkD,QAAQ;AAE5I,UAAA,kBAAkB,SAAS,IAAI,CAAC,EAAE,UAAU,GAAG,cAAc;AACjE,YAAM,YAAY,OAAO,KAAK,QAAM,GAAG,UAAU,QAAQ,KAAK;AAEtD,aAAA;AAAA,QACN,UAAU,IAAG,uCAAW,aAAY,QAAQ;AAAA,QAC5C,GAAG;AAAA,MAAA;AAAA,IACL,CACD;AAED,QAAI,gBAAgB,SAAS;AACnB,oBAAA,WAAA,mBAAQ,gBAAgB,SAAS;AAE3C,UAAM,eAAe,MAAM,QAAQ,MAAM,cAAc;AAAA,MACrD,GAAG,OAAO,OAAO,CAAA,OAAM,CAAC,SAAS,KAAK,CAAA,YAAW,QAAQ,UAAU,GAAG,KAAK,CAAC;AAAA,MAC5E,GAAG;AAAA,IAAA,CACJ;AAEO,kBAAA,WAAA,mBAAQ,iBAAiB,SAAS;AAEnC,WAAA;AAAA,WAEF,OAAO;AACLA,WAAAA,OAAA,MAAM,OAAO,KAAK,CAAC;AACjB,6CAAA,WAAA,mBAAQ,aAAa,SAAS;AAEjC,UAAA;AAAA,EACR;AACF;;;"}
1
+ {"version":3,"file":"requestAds.cjs","sources":["../../../src/requestAds/requestAds.ts"],"sourcesContent":["import type { AdheseContext } from '../main.types';\nimport type { AdheseAd } from './requestAds.schema';\nimport { debounce } from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\nimport { requestPreviews } from './requestAds.preview';\nimport { requestWithGet, requestWithPost } from './requestAds.utils';\n\nexport type AdRequestOptions = {\n /**\n * Slot you want to fetch the ad for\n */\n slot: {\n name: string;\n parameters: Map<string, ReadonlyArray<string> | string>;\n };\n context: AdheseContext;\n};\n\nexport type AdMultiRequestOptions = Omit<AdRequestOptions, 'slot'> & {\n slots: ReadonlyArray<AdRequestOptions['slot']>;\n};\n\nconst batch = new Map<string, {\n options: AdRequestOptions;\n resolve(ad: AdheseAd | null): void;\n}>();\n\n/**\n * Debounced function to request ads in batches. This function is debounced to prevent multiple requests for the same ad.\n */\nconst runRequestAdsBatch = debounce(async (context: AdheseContext) => {\n if (batch.size === 0)\n return [];\n\n const ads = await requestAds({\n slots: Array.from(batch.values()).map(({ options }) => options.slot),\n context,\n });\n\n for (const { options, resolve } of batch.values()) {\n const ad = ads.find(({ slotName }) => slotName === options.slot.name);\n\n if (ad)\n resolve(ad);\n else\n resolve(null);\n }\n\n batch.clear();\n\n return ads;\n}, {\n waitMs: 20,\n timing: 'trailing',\n});\n\n/**\n * Request a single ad from the API. If you need to fetch multiple ads at once use the `requestAds` function.\n */\nexport async function requestAd(options: AdRequestOptions): Promise<AdheseAd | null> {\n const promise = new Promise<AdheseAd | null>((resolve) => {\n batch.set(options.slot.name, { options, resolve });\n },\n );\n\n await runRequestAdsBatch.call(options.context);\n\n return promise;\n}\n\n/**\n * Request multiple ads from the API. If you need to fetch a single ad use the `requestAd` function.\n */\nexport async function requestAds(requestOptions: AdMultiRequestOptions): Promise<ReadonlyArray<AdheseAd>> {\n const options = await requestOptions.context.hooks.runOnRequest(requestOptions);\n\n const { context } = options;\n\n try {\n context?.events?.requestAd.dispatch({\n ...options,\n context,\n });\n\n const [response, previews, parseResponse] = await Promise.all([\n context.options.requestType?.toUpperCase() === 'POST'\n ? requestWithPost(options)\n : requestWithGet(options),\n requestPreviews(context.options.account),\n import('./requestAds.schema').then(module => module.parseResponse),\n ]);\n\n logger.debug('Received response', response);\n\n if (!response.ok)\n throw new Error(`Failed to request ad: ${response.status} ${response.statusText}`);\n\n const result = parseResponse((await response.json() as unknown));\n logger.debug('Parsed ad', result);\n\n if (previews.length > 0)\n logger.info(`Found ${previews.length} ${previews.length === 1 ? 'preview' : 'previews'}. Replacing ads in response with preview items`, previews);\n\n const matchedPreviews = previews.map(({ slotName, ...preview }) => {\n const partnerAd = result.find(ad => ad.libId === preview.libId);\n\n return ({\n slotName: `${partnerAd?.slotName ?? slotName}`,\n ...preview,\n });\n });\n\n if (matchedPreviews.length > 0)\n context.events?.previewReceived.dispatch(matchedPreviews);\n\n const mergedResult = await context.hooks.runOnResponse([\n ...result.filter(ad => !previews.some(preview => preview.libId === ad.libId)),\n ...matchedPreviews,\n ]);\n\n context.events?.responseReceived.dispatch(mergedResult);\n\n return mergedResult;\n }\n catch (error) {\n logger.error(String(error));\n context?.events?.requestError.dispatch(error as Error);\n\n throw error;\n }\n}\n"],"names":["debounce","requestWithPost","requestWithGet","requestPreviews","module","logger"],"mappings":";;;;;;AAsBA,MAAM,4BAAY,IAGf;AAKH,MAAM,qBAAqBA,UAAAA,SAAS,OAAO,YAA2B;AACpE,MAAI,MAAM,SAAS;AACjB,WAAO,CAAC;AAEJ,QAAA,MAAM,MAAM,WAAW;AAAA,IAC3B,OAAO,MAAM,KAAK,MAAM,OAAQ,CAAA,EAAE,IAAI,CAAC,EAAE,cAAc,QAAQ,IAAI;AAAA,IACnE;AAAA,EAAA,CACD;AAED,aAAW,EAAE,SAAS,QAAa,KAAA,MAAM,UAAU;AAC3C,UAAA,KAAK,IAAI,KAAK,CAAC,EAAE,SAAe,MAAA,aAAa,QAAQ,KAAK,IAAI;AAEhE,QAAA;AACF,cAAQ,EAAE;AAAA;AAEV,cAAQ,IAAI;AAAA,EAAA;AAGhB,QAAM,MAAM;AAEL,SAAA;AACT,GAAG;AAAA,EACD,QAAQ;AAAA,EACR,QAAQ;AACV,CAAC;AAKD,eAAsB,UAAU,SAAqD;AACnF,QAAM,UAAU,IAAI;AAAA,IAAyB,CAAC,YAAY;AACxD,YAAM,IAAI,QAAQ,KAAK,MAAM,EAAE,SAAS,SAAS;AAAA,IAAA;AAAA,EAEnD;AAEM,QAAA,mBAAmB,KAAK,QAAQ,OAAO;AAEtC,SAAA;AACT;AAKA,eAAsB,WAAW,gBAAyE;;AACxG,QAAM,UAAU,MAAM,eAAe,QAAQ,MAAM,aAAa,cAAc;AAExE,QAAA,EAAE,YAAY;AAEhB,MAAA;AACO,6CAAA,WAAA,mBAAQ,UAAU,SAAS;AAAA,MAClC,GAAG;AAAA,MACH;AAAA,IAAA;AAGF,UAAM,CAAC,UAAU,UAAU,aAAa,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC5D,aAAQ,QAAQ,gBAAhB,mBAA6B,mBAAkB,SAC3CC,iBAAAA,gBAAgB,OAAO,IACvBC,iBAAA,eAAe,OAAO;AAAA,MAC1BC,mCAAgB,QAAQ,QAAQ,OAAO;AAAA,MACvC,QAAA,QAAA,EAAA,KAAA,MAAA,QAAO,yBAAqB,CAAA,EAAE,KAAK,CAAAC,YAAUA,QAAO,aAAa;AAAA,IAAA,CAClE;AAEMC,kBAAA,MAAM,qBAAqB,QAAQ;AAE1C,QAAI,CAAC,SAAS;AACN,YAAA,IAAI,MAAM,yBAAyB,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAEnF,UAAM,SAAS,cAAe,MAAM,SAAS,MAAkB;AACxDA,kBAAA,MAAM,aAAa,MAAM;AAEhC,QAAI,SAAS,SAAS;AACbA,aAAAA,OAAA,KAAK,SAAS,SAAS,MAAM,IAAI,SAAS,WAAW,IAAI,YAAY,UAAU,kDAAkD,QAAQ;AAE5I,UAAA,kBAAkB,SAAS,IAAI,CAAC,EAAE,UAAU,GAAG,cAAc;AACjE,YAAM,YAAY,OAAO,KAAK,QAAM,GAAG,UAAU,QAAQ,KAAK;AAEtD,aAAA;AAAA,QACN,UAAU,IAAG,uCAAW,aAAY,QAAQ;AAAA,QAC5C,GAAG;AAAA,MACL;AAAA,IAAA,CACD;AAED,QAAI,gBAAgB,SAAS;AACnB,oBAAA,WAAA,mBAAQ,gBAAgB,SAAS;AAE3C,UAAM,eAAe,MAAM,QAAQ,MAAM,cAAc;AAAA,MACrD,GAAG,OAAO,OAAO,CAAA,OAAM,CAAC,SAAS,KAAK,CAAA,YAAW,QAAQ,UAAU,GAAG,KAAK,CAAC;AAAA,MAC5E,GAAG;AAAA,IAAA,CACJ;AAEO,kBAAA,WAAA,mBAAQ,iBAAiB,SAAS;AAEnC,WAAA;AAAA,WAEF,OAAO;AACLA,WAAAA,OAAA,MAAM,OAAO,KAAK,CAAC;AACjB,6CAAA,WAAA,mBAAQ,aAAa,SAAS;AAEjC,UAAA;AAAA,EAAA;AAEV;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"requestAds.preview.cjs","sources":["../../../src/requestAds/requestAds.preview.ts"],"sourcesContent":["import type { AdheseAd } from './requestAds.schema';\nimport { logger } from '../logger/logger';\n\n/**\n * Request preview ads for the given account. This function will only return items when there are preview objects in the\n * URL detected.\n */\nexport async function requestPreviews(account: string): Promise<ReadonlyArray<AdheseAd>> {\n const previewObjects = getPreviewObjects();\n\n const [list, adSchema] = await Promise.all([\n Promise.allSettled(previewObjects\n .filter(previewObject => 'adhesePreviewCreativeId' in previewObject)\n .map(async (previewObject) => {\n const endpoint = new URL(`https://${account}-preview.adhese.org/creatives/preview/json/tag.do`);\n endpoint.searchParams.set(\n 'id',\n previewObject.adhesePreviewCreativeId,\n );\n\n const response = await fetch(endpoint.href, {\n method: 'GET',\n headers: {\n accept: 'application/json',\n },\n });\n\n if (!response.ok)\n return Promise.reject(new Error(`Failed to request preview ad with ID: ${previewObject.adhesePreviewCreativeId}`));\n\n return await response.json() as unknown;\n })),\n import('./requestAds.schema').then(module => module.adSchema),\n ]);\n\n return adSchema.array().parse(list\n .filter((response): response is PromiseFulfilledResult<ReadonlyArray<Record<string, unknown>>> => {\n if (response.status === 'rejected') {\n logger.error(response.reason as string);\n return false;\n }\n return response.status === 'fulfilled';\n })\n .flatMap(response => response.value.map(item => ({\n ...item,\n preview: true,\n })))) as ReadonlyArray<AdheseAd>;\n}\n\nfunction getPreviewObjects(): ReadonlyArray<Record<string, string>> {\n const currentUrl = new URL(window.location.href);\n\n const previewObjects: Array<Record<string, string>> = [];\n let currentObject: Record<string, string> = {};\n\n for (const [key, value] of currentUrl.searchParams.entries()) {\n if (key === 'adhesePreviewCreativeId' && Object.keys(currentObject).length > 0) {\n previewObjects.push(currentObject);\n currentObject = {};\n }\n\n currentObject[key] = value;\n }\n\n if (Object.keys(currentObject).length > 0)\n previewObjects.push(currentObject);\n\n return previewObjects;\n}\n"],"names":["module","logger"],"mappings":";;;AAOA,eAAsB,gBAAgB,SAAmD;AACvF,QAAM,iBAAiB;AAEvB,QAAM,CAAC,MAAM,QAAQ,IAAI,MAAM,QAAQ,IAAI;AAAA,IACzC,QAAQ,WAAW,eAChB,OAAO,CAAA,kBAAiB,6BAA6B,aAAa,EAClE,IAAI,OAAO,kBAAkB;AAC5B,YAAM,WAAW,IAAI,IAAI,WAAW,OAAO,mDAAmD;AAC9F,eAAS,aAAa;AAAA,QACpB;AAAA,QACA,cAAc;AAAA,MAAA;AAGhB,YAAM,WAAW,MAAM,MAAM,SAAS,MAAM;AAAA,QAC1C,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,QAAQ;AAAA,QACV;AAAA,MAAA,CACD;AAED,UAAI,CAAC,SAAS;AACL,eAAA,QAAQ,OAAO,IAAI,MAAM,yCAAyC,cAAc,uBAAuB,EAAE,CAAC;AAE5G,aAAA,MAAM,SAAS;IAAK,CAC5B,CAAC;AAAA,IACJ,QAAO,QAAA,EAAA,KAAA,MAAA,QAAA,yBAAqB,CAAA,EAAE,KAAK,CAAAA,YAAUA,QAAO,QAAQ;AAAA,EAAA,CAC7D;AAED,SAAO,SAAS,QAAQ,MAAM,KAC3B,OAAO,CAAC,aAAyF;AAC5F,QAAA,SAAS,WAAW,YAAY;AAC3BC,aAAAA,OAAA,MAAM,SAAS,MAAgB;AAC/B,aAAA;AAAA,IACT;AACA,WAAO,SAAS,WAAW;AAAA,EAAA,CAC5B,EACA,QAAQ,cAAY,SAAS,MAAM,IAAI,CAAS,UAAA;AAAA,IAC/C,GAAG;AAAA,IACH,SAAS;AAAA,EAAA,EACT,CAAC,CAAC;AACR;AAEA,SAAS,oBAA2D;AAClE,QAAM,aAAa,IAAI,IAAI,OAAO,SAAS,IAAI;AAE/C,QAAM,iBAAgD,CAAA;AACtD,MAAI,gBAAwC,CAAA;AAE5C,aAAW,CAAC,KAAK,KAAK,KAAK,WAAW,aAAa,WAAW;AAC5D,QAAI,QAAQ,6BAA6B,OAAO,KAAK,aAAa,EAAE,SAAS,GAAG;AAC9E,qBAAe,KAAK,aAAa;AACjC,sBAAgB,CAAA;AAAA,IAClB;AAEA,kBAAc,GAAG,IAAI;AAAA,EACvB;AAEA,MAAI,OAAO,KAAK,aAAa,EAAE,SAAS;AACtC,mBAAe,KAAK,aAAa;AAE5B,SAAA;AACT;;"}
1
+ {"version":3,"file":"requestAds.preview.cjs","sources":["../../../src/requestAds/requestAds.preview.ts"],"sourcesContent":["import type { AdheseAd } from './requestAds.schema';\nimport { logger } from '../logger/logger';\n\n/**\n * Request preview ads for the given account. This function will only return items when there are preview objects in the\n * URL detected.\n */\nexport async function requestPreviews(account: string): Promise<ReadonlyArray<AdheseAd>> {\n const previewObjects = getPreviewObjects();\n\n const [list, adSchema] = await Promise.all([\n Promise.allSettled(previewObjects\n .filter(previewObject => 'adhesePreviewCreativeId' in previewObject)\n .map(async (previewObject) => {\n const endpoint = new URL(`https://${account}-preview.adhese.org/creatives/preview/json/tag.do`);\n endpoint.searchParams.set(\n 'id',\n previewObject.adhesePreviewCreativeId,\n );\n\n const response = await fetch(endpoint.href, {\n method: 'GET',\n headers: {\n accept: 'application/json',\n },\n });\n\n if (!response.ok)\n return Promise.reject(new Error(`Failed to request preview ad with ID: ${previewObject.adhesePreviewCreativeId}`));\n\n return await response.json() as unknown;\n })),\n import('./requestAds.schema').then(module => module.adSchema),\n ]);\n\n return adSchema.array().parse(list\n .filter((response): response is PromiseFulfilledResult<ReadonlyArray<Record<string, unknown>>> => {\n if (response.status === 'rejected') {\n logger.error(response.reason as string);\n return false;\n }\n return response.status === 'fulfilled';\n })\n .flatMap(response => response.value.map(item => ({\n ...item,\n preview: true,\n })))) as ReadonlyArray<AdheseAd>;\n}\n\nfunction getPreviewObjects(): ReadonlyArray<Record<string, string>> {\n const currentUrl = new URL(window.location.href);\n\n const previewObjects: Array<Record<string, string>> = [];\n let currentObject: Record<string, string> = {};\n\n for (const [key, value] of currentUrl.searchParams.entries()) {\n if (key === 'adhesePreviewCreativeId' && Object.keys(currentObject).length > 0) {\n previewObjects.push(currentObject);\n currentObject = {};\n }\n\n currentObject[key] = value;\n }\n\n if (Object.keys(currentObject).length > 0)\n previewObjects.push(currentObject);\n\n return previewObjects;\n}\n"],"names":["module","logger"],"mappings":";;;AAOA,eAAsB,gBAAgB,SAAmD;AACvF,QAAM,iBAAiB,kBAAkB;AAEzC,QAAM,CAAC,MAAM,QAAQ,IAAI,MAAM,QAAQ,IAAI;AAAA,IACzC,QAAQ,WAAW,eAChB,OAAO,CAAA,kBAAiB,6BAA6B,aAAa,EAClE,IAAI,OAAO,kBAAkB;AAC5B,YAAM,WAAW,IAAI,IAAI,WAAW,OAAO,mDAAmD;AAC9F,eAAS,aAAa;AAAA,QACpB;AAAA,QACA,cAAc;AAAA,MAChB;AAEA,YAAM,WAAW,MAAM,MAAM,SAAS,MAAM;AAAA,QAC1C,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,QAAQ;AAAA,QAAA;AAAA,MACV,CACD;AAED,UAAI,CAAC,SAAS;AACL,eAAA,QAAQ,OAAO,IAAI,MAAM,yCAAyC,cAAc,uBAAuB,EAAE,CAAC;AAE5G,aAAA,MAAM,SAAS,KAAK;AAAA,IAAA,CAC5B,CAAC;AAAA,IACJ,QAAA,QAAA,EAAA,KAAA,MAAA,QAAO,yBAAqB,CAAA,EAAE,KAAK,CAAAA,YAAUA,QAAO,QAAQ;AAAA,EAAA,CAC7D;AAED,SAAO,SAAS,QAAQ,MAAM,KAC3B,OAAO,CAAC,aAAyF;AAC5F,QAAA,SAAS,WAAW,YAAY;AAC3BC,oBAAA,MAAM,SAAS,MAAgB;AAC/B,aAAA;AAAA,IAAA;AAET,WAAO,SAAS,WAAW;AAAA,EAAA,CAC5B,EACA,QAAQ,cAAY,SAAS,MAAM,IAAI,CAAS,UAAA;AAAA,IAC/C,GAAG;AAAA,IACH,SAAS;AAAA,EACX,EAAE,CAAC,CAAC;AACR;AAEA,SAAS,oBAA2D;AAClE,QAAM,aAAa,IAAI,IAAI,OAAO,SAAS,IAAI;AAE/C,QAAM,iBAAgD,CAAC;AACvD,MAAI,gBAAwC,CAAC;AAE7C,aAAW,CAAC,KAAK,KAAK,KAAK,WAAW,aAAa,WAAW;AAC5D,QAAI,QAAQ,6BAA6B,OAAO,KAAK,aAAa,EAAE,SAAS,GAAG;AAC9E,qBAAe,KAAK,aAAa;AACjC,sBAAgB,CAAC;AAAA,IAAA;AAGnB,kBAAc,GAAG,IAAI;AAAA,EAAA;AAGvB,MAAI,OAAO,KAAK,aAAa,EAAE,SAAS;AACtC,mBAAe,KAAK,aAAa;AAE5B,SAAA;AACT;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"requestAds.schema.cjs","sources":["../../../src/requestAds/requestAds.schema.ts"],"sourcesContent":["import {\n booleanLike,\n cssValueLike,\n dateLike,\n isJsonOrHtmlOptionalString,\n isJsonOrHtmlString,\n lazy,\n literal,\n numberLike,\n object,\n string,\n type TypeOf,\n union,\n unknown,\n urlLike,\n type ZodType,\n} from '@adhese/sdk-shared/validators';\n\nconst baseSchema = object({\n adDuration: numberLike.optional(),\n adFormat: string().optional(),\n adType: string(),\n additionalCreativeTracker: urlLike.optional(),\n additionalViewableTracker: string().optional(),\n adspaceEnd: dateLike.optional(),\n adspaceId: string().optional(),\n adspaceKey: string().optional(),\n adspaceStart: dateLike.optional(),\n advertiserId: string().optional(),\n altText: string().optional(),\n auctionable: booleanLike.optional(),\n body: isJsonOrHtmlOptionalString,\n clickTag: urlLike.optional(),\n comment: string().optional(),\n creativeName: string().optional(),\n deliveryGroupId: string().optional(),\n deliveryMultiples: string().optional(),\n ext: string().optional(),\n extension: object({\n mediaType: string(),\n prebid: unknown().optional(),\n }).optional(),\n height: numberLike.optional(),\n id: string().optional(),\n impressionCounter: urlLike.optional(),\n libId: string().optional(),\n orderId: string().optional(),\n orderName: string().optional(),\n orderProperty: string().optional(),\n origin: union([literal('JERLICIA'), literal('DALE')]),\n originData: unknown().optional(),\n originInstance: string().optional(),\n poolPath: urlLike.optional(),\n preview: booleanLike.optional(),\n priority: numberLike.optional(),\n sfSrc: urlLike.optional(),\n share: string().optional(),\n // eslint-disable-next-line ts/naming-convention\n slotID: string(),\n slotName: string(),\n swfSrc: urlLike.optional(),\n tag: isJsonOrHtmlOptionalString,\n tagUrl: urlLike.optional(),\n timeStamp: dateLike.optional(),\n trackedImpressionCounter: urlLike.optional(),\n tracker: urlLike.optional(),\n trackingUrl: urlLike.optional(),\n url: urlLike.optional(),\n viewableImpressionCounter: urlLike.optional(),\n width: numberLike.optional(),\n widthLarge: cssValueLike.optional(),\n});\n\nexport const jerliciaSchema = object({\n origin: literal('JERLICIA'),\n tag: isJsonOrHtmlString,\n}).passthrough();\n\nexport const daleSchema = object({\n origin: literal('DALE'),\n body: isJsonOrHtmlString,\n}).passthrough().transform(({ body, ...data }) => ({\n ...data,\n tag: body,\n}));\n\nexport type AdResponse = (TypeOf<typeof baseSchema> & {\n additionalCreatives?: ReadonlyArray<AdResponse> | string;\n});\n\nconst adResponseSchema: ZodType<AdResponse> = baseSchema.extend({\n additionalCreatives: lazy(() => union([adResponseSchema.array(), string()]).optional()),\n}) as ZodType<AdResponse>;\n\nexport type PreParsedAd = TypeOf<typeof adResponseSchema> & {\n additionalCreatives?: ReadonlyArray<PreParsedAd> | string;\n};\n\nexport type AdheseAd<T = string | Record<string, unknown> | ReadonlyArray<unknown>> = Omit<PreParsedAd, 'tag'> & {\n tag: T | string;\n};\n\nexport const adSchema: ZodType<PreParsedAd> = adResponseSchema.transform(({\n additionalCreatives,\n ...data\n}) => {\n const filteredValue = Object.fromEntries(\n Object.entries(data)\n .filter(([, value]) =>\n Boolean(value)\n && JSON.stringify(value) !== '{}'\n && JSON.stringify(value) !== '[]'),\n ) as typeof data;\n\n return ({\n ...filteredValue,\n additionalCreatives: Array.isArray(additionalCreatives) ? additionalCreatives.map(creative => adSchema.parse(creative)) : additionalCreatives,\n });\n});\n\nexport function parseResponse(response: unknown): ReadonlyArray<AdheseAd> {\n const schemaMap = {\n /* eslint-disable ts/naming-convention */\n JERLICIA: jerliciaSchema,\n DALE: daleSchema,\n /* eslint-enable ts/naming-convention */\n };\n\n const preParsed = adResponseSchema.array().parse(response);\n\n return preParsed.map((item) => {\n const schema = schemaMap[item.origin];\n\n if (!schema)\n return adSchema.parse(item);\n\n return schema.parse(item);\n }) as ReadonlyArray<AdheseAd>;\n}\n"],"names":["object","numberLike","string","urlLike","dateLike","booleanLike","isJsonOrHtmlOptionalString","unknown","union","literal","cssValueLike","isJsonOrHtmlString","lazy"],"mappings":"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"}
1
+ {"version":3,"file":"requestAds.schema.cjs","sources":["../../../src/requestAds/requestAds.schema.ts"],"sourcesContent":["import {\n booleanLike,\n cssValueLike,\n dateLike,\n isJsonOrHtmlOptionalString,\n isJsonOrHtmlString,\n lazy,\n literal,\n numberLike,\n object,\n string,\n type TypeOf,\n union,\n unknown,\n urlLike,\n type ZodType,\n} from '@adhese/sdk-shared/validators';\n\nconst baseSchema = object({\n adDuration: numberLike.optional(),\n adFormat: string().optional(),\n adType: string(),\n additionalCreativeTracker: urlLike.optional(),\n additionalViewableTracker: string().optional(),\n adspaceEnd: dateLike.optional(),\n adspaceId: string().optional(),\n adspaceKey: string().optional(),\n adspaceStart: dateLike.optional(),\n advertiserId: string().optional(),\n altText: string().optional(),\n auctionable: booleanLike.optional(),\n body: isJsonOrHtmlOptionalString,\n clickTag: urlLike.optional(),\n comment: string().optional(),\n creativeName: string().optional(),\n deliveryGroupId: string().optional(),\n deliveryMultiples: string().optional(),\n ext: string().optional(),\n extension: object({\n mediaType: string(),\n prebid: unknown().optional(),\n }).optional(),\n height: numberLike.optional(),\n id: string().optional(),\n impressionCounter: urlLike.optional(),\n libId: string().optional(),\n orderId: string().optional(),\n orderName: string().optional(),\n orderProperty: string().optional(),\n origin: union([literal('JERLICIA'), literal('DALE')]),\n originData: unknown().optional(),\n originInstance: string().optional(),\n poolPath: urlLike.optional(),\n preview: booleanLike.optional(),\n priority: numberLike.optional(),\n sfSrc: urlLike.optional(),\n share: string().optional(),\n // eslint-disable-next-line ts/naming-convention\n slotID: string(),\n slotName: string(),\n swfSrc: urlLike.optional(),\n tag: isJsonOrHtmlOptionalString,\n tagUrl: urlLike.optional(),\n timeStamp: dateLike.optional(),\n trackedImpressionCounter: urlLike.optional(),\n tracker: urlLike.optional(),\n trackingUrl: urlLike.optional(),\n url: urlLike.optional(),\n viewableImpressionCounter: urlLike.optional(),\n width: numberLike.optional(),\n widthLarge: cssValueLike.optional(),\n});\n\nexport const jerliciaSchema = object({\n origin: literal('JERLICIA'),\n tag: isJsonOrHtmlString,\n}).passthrough();\n\nexport const daleSchema = object({\n origin: literal('DALE'),\n body: isJsonOrHtmlString,\n}).passthrough().transform(({ body, ...data }) => ({\n ...data,\n tag: body,\n}));\n\nexport type AdResponse = (TypeOf<typeof baseSchema> & {\n additionalCreatives?: ReadonlyArray<AdResponse> | string;\n});\n\nconst adResponseSchema: ZodType<AdResponse> = baseSchema.extend({\n additionalCreatives: lazy(() => union([adResponseSchema.array(), string()]).optional()),\n}) as ZodType<AdResponse>;\n\nexport type PreParsedAd = TypeOf<typeof adResponseSchema> & {\n additionalCreatives?: ReadonlyArray<PreParsedAd> | string;\n};\n\nexport type AdheseAd<T = string | Record<string, unknown> | ReadonlyArray<unknown>> = Omit<PreParsedAd, 'tag'> & {\n tag: T | string;\n};\n\nexport const adSchema: ZodType<PreParsedAd> = adResponseSchema.transform(({\n additionalCreatives,\n ...data\n}) => {\n const filteredValue = Object.fromEntries(\n Object.entries(data)\n .filter(([, value]) =>\n Boolean(value)\n && JSON.stringify(value) !== '{}'\n && JSON.stringify(value) !== '[]'),\n ) as typeof data;\n\n return ({\n ...filteredValue,\n additionalCreatives: Array.isArray(additionalCreatives) ? additionalCreatives.map(creative => adSchema.parse(creative)) : additionalCreatives,\n });\n});\n\nexport function parseResponse(response: unknown): ReadonlyArray<AdheseAd> {\n const schemaMap = {\n /* eslint-disable ts/naming-convention */\n JERLICIA: jerliciaSchema,\n DALE: daleSchema,\n /* eslint-enable ts/naming-convention */\n };\n\n const preParsed = adResponseSchema.array().parse(response);\n\n return preParsed.map((item) => {\n const schema = schemaMap[item.origin];\n\n if (!schema)\n return adSchema.parse(item);\n\n return schema.parse(item);\n }) as ReadonlyArray<AdheseAd>;\n}\n"],"names":["object","numberLike","string","urlLike","dateLike","booleanLike","isJsonOrHtmlOptionalString","unknown","union","literal","cssValueLike","isJsonOrHtmlString","lazy"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"requestAds.utils.cjs","sources":["../../../src/requestAds/requestAds.utils.ts"],"sourcesContent":["import type { AdMultiRequestOptions } from './requestAds';\nimport { toValue } from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\n\ntype AdPostPayload = {\n slots: ReadonlyArray<{\n slotname: string;\n parameters?: Record<string, ReadonlyArray<string> | string>;\n }>;\n parameters?: Record<string, ReadonlyArray<string> | string>;\n};\n\nexport async function requestWithPost({\n context,\n ...options\n}: Omit<AdMultiRequestOptions, 'method'>): Promise<Response> {\n const payload = {\n ...options,\n slots: options.slots.map(slot => ({\n slotname: slot.name,\n parameters: parseParameters(slot.parameters),\n })),\n parameters: context.parameters && parseParameters(context.parameters),\n } satisfies AdPostPayload;\n\n return fetch(`${new URL(context.options.host).href}json`, {\n method: 'POST',\n body: JSON.stringify(payload),\n headers: {\n // eslint-disable-next-line ts/naming-convention\n 'Content-Type': 'application/json',\n },\n });\n}\n\nexport async function requestWithGet({ context, slots }: Omit<AdMultiRequestOptions, 'method'>): Promise<Response> {\n return fetch(new URL(`${context.options.host}/json/sl${slots.map(slot => toValue(slot.name)).join('/sl')}`), {\n method: 'GET',\n headers: {\n // eslint-disable-next-line ts/naming-convention\n 'Content-Type': 'application/json',\n },\n });\n}\n\nexport function parseParameters<T extends string | ReadonlyArray<string>>(parameters: Map<string, T>): Record<string, T> {\n return Object.fromEntries(Array.from(parameters.entries()).filter(([key]) => {\n if (key.length === 2)\n return true;\n\n logger.warn(`Invalid parameter key: ${key}. Key should be exactly 2 characters long. Key will be ignored.`);\n return false;\n }).map(([key, value]): [string, T] => {\n if (typeof value === 'string')\n return [key, filterSpecialChars(value) as T];\n\n return [key, value.map(filterSpecialChars) as unknown as T];\n }));\n}\n\nfunction filterSpecialChars(value: string): string {\n const specialRegex = /[^\\p{L}\\p{N}_]/gu;\n\n return value.replaceAll(specialRegex, '_');\n}\n"],"names":["toValue","logger"],"mappings":";;;;AAYA,eAAsB,gBAAgB;AAAA,EACpC;AAAA,EACA,GAAG;AACL,GAA6D;AAC3D,QAAM,UAAU;AAAA,IACd,GAAG;AAAA,IACH,OAAO,QAAQ,MAAM,IAAI,CAAS,UAAA;AAAA,MAChC,UAAU,KAAK;AAAA,MACf,YAAY,gBAAgB,KAAK,UAAU;AAAA,IAAA,EAC3C;AAAA,IACF,YAAY,QAAQ,cAAc,gBAAgB,QAAQ,UAAU;AAAA,EAAA;AAG/D,SAAA,MAAM,GAAG,IAAI,IAAI,QAAQ,QAAQ,IAAI,EAAE,IAAI,QAAQ;AAAA,IACxD,QAAQ;AAAA,IACR,MAAM,KAAK,UAAU,OAAO;AAAA,IAC5B,SAAS;AAAA;AAAA,MAEP,gBAAgB;AAAA,IAClB;AAAA,EAAA,CACD;AACH;AAEA,eAAsB,eAAe,EAAE,SAAS,SAAmE;AAC1G,SAAA,MAAM,IAAI,IAAI,GAAG,QAAQ,QAAQ,IAAI,WAAW,MAAM,IAAI,UAAQA,UAAAA,QAAQ,KAAK,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,GAAG;AAAA,IAC3G,QAAQ;AAAA,IACR,SAAS;AAAA;AAAA,MAEP,gBAAgB;AAAA,IAClB;AAAA,EAAA,CACD;AACH;AAEO,SAAS,gBAA0D,YAA+C;AACvH,SAAO,OAAO,YAAY,MAAM,KAAK,WAAW,QAAA,CAAS,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM;AAC3E,QAAI,IAAI,WAAW;AACV,aAAA;AAEFC,WAAA,OAAA,KAAK,0BAA0B,GAAG,iEAAiE;AACnG,WAAA;AAAA,EACR,CAAA,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAmB;AACpC,QAAI,OAAO,UAAU;AACnB,aAAO,CAAC,KAAK,mBAAmB,KAAK,CAAM;AAE7C,WAAO,CAAC,KAAK,MAAM,IAAI,kBAAkB,CAAiB;AAAA,EAC3D,CAAA,CAAC;AACJ;AAEA,SAAS,mBAAmB,OAAuB;AACjD,QAAM,eAAe;AAEd,SAAA,MAAM,WAAW,cAAc,GAAG;AAC3C;;;;"}
1
+ {"version":3,"file":"requestAds.utils.cjs","sources":["../../../src/requestAds/requestAds.utils.ts"],"sourcesContent":["import type { AdMultiRequestOptions } from './requestAds';\nimport { toValue } from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\n\ntype AdPostPayload = {\n slots: ReadonlyArray<{\n slotname: string;\n parameters?: Record<string, ReadonlyArray<string> | string>;\n }>;\n parameters?: Record<string, ReadonlyArray<string> | string>;\n};\n\nexport async function requestWithPost({\n context,\n ...options\n}: Omit<AdMultiRequestOptions, 'method'>): Promise<Response> {\n const payload = {\n ...options,\n slots: options.slots.map(slot => ({\n slotname: slot.name,\n parameters: parseParameters(slot.parameters),\n })),\n parameters: context.parameters && parseParameters(context.parameters),\n } satisfies AdPostPayload;\n\n return fetch(`${new URL(context.options.host).href}json`, {\n method: 'POST',\n body: JSON.stringify(payload),\n headers: {\n // eslint-disable-next-line ts/naming-convention\n 'Content-Type': 'application/json',\n },\n });\n}\n\nexport async function requestWithGet({ context, slots }: Omit<AdMultiRequestOptions, 'method'>): Promise<Response> {\n return fetch(new URL(`${context.options.host}/json/sl${slots.map(slot => toValue(slot.name)).join('/sl')}`), {\n method: 'GET',\n headers: {\n // eslint-disable-next-line ts/naming-convention\n 'Content-Type': 'application/json',\n },\n });\n}\n\nexport function parseParameters<T extends string | ReadonlyArray<string>>(parameters: Map<string, T>): Record<string, T> {\n return Object.fromEntries(Array.from(parameters.entries()).filter(([key]) => {\n if (key.length === 2)\n return true;\n\n logger.warn(`Invalid parameter key: ${key}. Key should be exactly 2 characters long. Key will be ignored.`);\n return false;\n }).map(([key, value]): [string, T] => {\n if (typeof value === 'string')\n return [key, filterSpecialChars(value) as T];\n\n return [key, value.map(filterSpecialChars) as unknown as T];\n }));\n}\n\nfunction filterSpecialChars(value: string): string {\n const specialRegex = /[^\\p{L}\\p{N}_]/gu;\n\n return value.replaceAll(specialRegex, '_');\n}\n"],"names":["toValue","logger"],"mappings":";;;;AAYA,eAAsB,gBAAgB;AAAA,EACpC;AAAA,EACA,GAAG;AACL,GAA6D;AAC3D,QAAM,UAAU;AAAA,IACd,GAAG;AAAA,IACH,OAAO,QAAQ,MAAM,IAAI,CAAS,UAAA;AAAA,MAChC,UAAU,KAAK;AAAA,MACf,YAAY,gBAAgB,KAAK,UAAU;AAAA,IAAA,EAC3C;AAAA,IACF,YAAY,QAAQ,cAAc,gBAAgB,QAAQ,UAAU;AAAA,EACtE;AAEO,SAAA,MAAM,GAAG,IAAI,IAAI,QAAQ,QAAQ,IAAI,EAAE,IAAI,QAAQ;AAAA,IACxD,QAAQ;AAAA,IACR,MAAM,KAAK,UAAU,OAAO;AAAA,IAC5B,SAAS;AAAA;AAAA,MAEP,gBAAgB;AAAA,IAAA;AAAA,EAClB,CACD;AACH;AAEA,eAAsB,eAAe,EAAE,SAAS,SAAmE;AAC1G,SAAA,MAAM,IAAI,IAAI,GAAG,QAAQ,QAAQ,IAAI,WAAW,MAAM,IAAI,UAAQA,UAAAA,QAAQ,KAAK,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,GAAG;AAAA,IAC3G,QAAQ;AAAA,IACR,SAAS;AAAA;AAAA,MAEP,gBAAgB;AAAA,IAAA;AAAA,EAClB,CACD;AACH;AAEO,SAAS,gBAA0D,YAA+C;AACvH,SAAO,OAAO,YAAY,MAAM,KAAK,WAAW,QAAA,CAAS,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM;AAC3E,QAAI,IAAI,WAAW;AACV,aAAA;AAEFC,WAAAA,OAAA,KAAK,0BAA0B,GAAG,iEAAiE;AACnG,WAAA;AAAA,EACR,CAAA,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAmB;AACpC,QAAI,OAAO,UAAU;AACnB,aAAO,CAAC,KAAK,mBAAmB,KAAK,CAAM;AAE7C,WAAO,CAAC,KAAK,MAAM,IAAI,kBAAkB,CAAiB;AAAA,EAAA,CAC3D,CAAC;AACJ;AAEA,SAAS,mBAAmB,OAAuB;AACjD,QAAM,eAAe;AAEd,SAAA,MAAM,WAAW,cAAc,GAAG;AAC3C;;;;"}
@@ -126,10 +126,12 @@ function createSlot(slotOptions) {
126
126
  });
127
127
  const impressionTrackingPixelElement = sdkShared.ref(null);
128
128
  const isImpressionTracked = sdkShared.ref(false);
129
- hooks.onDispose(() => {
130
- if (impressionTrackingPixelElement.value)
131
- impressionTrackingPixelElement.value.remove();
132
- });
129
+ sdkShared.watch([status, isInViewport, data], ([newStatus, newIsInViewport, newData]) => {
130
+ if (newStatus === "rendered" && newIsInViewport && (newData == null ? void 0 : newData.impressionCounter) && !impressionTrackingPixelElement.value) {
131
+ impressionTrackingPixelElement.value = sdkShared.addTrackingPixel(newData.impressionCounter);
132
+ isImpressionTracked.value = true;
133
+ }
134
+ }, { immediate: true });
133
135
  sdkShared.watch(status, async (newStatus, oldStatus) => {
134
136
  var _a;
135
137
  if (newStatus === "loaded" && oldStatus === "rendered") {
@@ -137,6 +139,10 @@ function createSlot(slotOptions) {
137
139
  impressionTrackingPixelElement.value = null;
138
140
  }
139
141
  });
142
+ hooks.onDispose(() => {
143
+ if (impressionTrackingPixelElement.value)
144
+ impressionTrackingPixelElement.value.remove();
145
+ });
140
146
  async function request() {
141
147
  try {
142
148
  if (options.lazyLoading && !isInViewport.value)
@@ -160,6 +166,8 @@ function createSlot(slotOptions) {
160
166
  status.value = response ? "loaded" : "empty";
161
167
  if (!response)
162
168
  cleanElement();
169
+ if (response && context.options.eagerRendering && element.value)
170
+ await render(response);
163
171
  return response;
164
172
  } catch (error) {
165
173
  status.value = "error";
@@ -201,9 +209,6 @@ function createSlot(slotOptions) {
201
209
  ...sdkShared.pick(options, ["width", "height"])
202
210
  }, element.value);
203
211
  }
204
- if (renderAd.impressionCounter && !impressionTrackingPixelElement.value)
205
- impressionTrackingPixelElement.value = sdkShared.addTrackingPixel(renderAd.impressionCounter);
206
- isImpressionTracked.value = true;
207
212
  logger.logger.debug(`Slot rendered ${name.value}`, {
208
213
  renderedElement: element,
209
214
  location: context.location,
@@ -1 +1 @@
1
- {"version":3,"file":"slot.cjs","sources":["../../../src/slot/slot.ts"],"sourcesContent":["import type { AdheseAd } from '@adhese/sdk';\nimport type { AdheseSlot, AdheseSlotContext, AdheseSlotOptions, RenderMode } from './slot.types';\nimport {\n addTrackingPixel,\n computed,\n doNothing,\n effectScope,\n generateName,\n omit,\n pick,\n reactive,\n type Ref,\n ref,\n renderIframe,\n renderInline,\n type RenderOptions,\n shallowRef,\n uniqueId,\n type UnwrapRef,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\nimport { useQueryDetector } from '../queryDetector/queryDetector';\nimport { requestAd as extRequestAd } from '../requestAds/requestAds';\nimport {\n useDomLoaded,\n useRenderIntersectionObserver,\n useSlotHooks,\n useViewabilityObserver,\n} from './slot.composables';\n\nconst renderFunctions: Record<RenderMode, (ad: RenderOptions, element: HTMLElement) => void> = {\n iframe: renderIframe,\n inline: renderInline,\n none: doNothing,\n};\n\nconst defaultOptions = {\n renderMode: 'iframe',\n type: 'normal',\n} satisfies Partial<AdheseSlotOptions>;\n\n/**\n * Create a new slot instance. This slot instance can be used to request and render ads.\n *\n * @param slotOptions {AdheseSlotOptions} The options to create the slot with.\n *\n * @return AdheseSlot The created slot instance.\n */\nexport function createSlot(slotOptions: AdheseSlotOptions): AdheseSlot {\n const scope = effectScope();\n\n return scope.run(() => {\n const slotContext = ref<AdheseSlotContext | null>(null);\n const options = slotOptions.context.hooks.runOnSlotCreate({\n ...defaultOptions,\n ...(Object.fromEntries(Object.entries(slotOptions).filter(([,value]) => value !== undefined)) as AdheseSlotOptions),\n });\n\n const {\n containingElement,\n slot,\n context,\n pluginOptions,\n initialData = null,\n renderMode = 'iframe',\n type = 'normal',\n } = options;\n\n const id = uniqueId();\n const {\n runOnBeforeRender,\n runOnRender,\n runOnBeforeRequest,\n runOnRequest,\n runOnInit,\n runOnDispose,\n runOnEmpty,\n runOnError,\n ...hooks\n } = useSlotHooks(options, slotContext);\n\n const isDisposed = ref(false);\n const parameters = reactive(new Map(Object.entries(options.parameters ?? {})));\n\n const [device, disposeQueryDetector] = useQueryDetector(context, typeof options.format === 'string'\n ? {\n [options.format]: '(min-width: 0px)',\n }\n : Object.fromEntries(options.format.map(item => [item.format, item.query])));\n\n const format = computed(() => typeof options.format === 'string' ? options.format : device.value);\n\n const data = ref<AdheseAd | null>(null) as Ref<AdheseAd | null>;\n const originalData = ref(data.value) as Ref<AdheseAd | null>;\n const name = computed(() => generateName(options.context.location, format.value, options.slot));\n\n const status = ref<UnwrapRef<AdheseSlot>['status']>('initializing');\n\n watch(name, async (newName, oldName) => {\n if (newName === oldName)\n return;\n\n const newAd = await slotContext.value?.request();\n\n if (!newAd)\n return;\n\n slotContext.value?.cleanElement();\n\n data.value = newAd;\n originalData.value = newAd;\n });\n\n const isDomLoaded = useDomLoaded(context);\n\n const element = shallowRef<HTMLElement | null>(null);\n\n function getElement(): HTMLElement | null {\n if (!(typeof options.containingElement === 'string' || !options.containingElement))\n return options.containingElement;\n\n if (!isDomLoaded.value)\n return null;\n\n return document.querySelector<HTMLElement>(`#${options.containingElement}`);\n }\n\n watch(element, async (newElement, oldElement) => {\n if (status.value === 'empty' || status.value === 'error' || status.value === 'loading') {\n return;\n }\n\n if (newElement === null && data.value) {\n status.value = 'loaded';\n\n return;\n }\n\n if (newElement === oldElement || (oldElement === null && newElement === null))\n return;\n\n await render();\n });\n\n const domObserver = new MutationObserver(() => {\n element.value = getElement();\n });\n\n domObserver.observe(document.body, {\n childList: true,\n subtree: true,\n });\n\n watch(\n isDomLoaded,\n () => {\n element.value = getElement();\n },\n { immediate: true, deep: true },\n );\n\n const isInViewport = useRenderIntersectionObserver({\n options,\n element,\n hooks,\n });\n\n watch(isInViewport, async (newIsInViewport) => {\n if (newIsInViewport && status.value !== 'rendered')\n await slotContext.value?.render();\n }, { immediate: true });\n\n hooks.onDispose(() => {\n disposeQueryDetector();\n });\n\n const isViewabilityTracked = useViewabilityObserver({\n context,\n slotContext,\n hooks,\n onTracked(trackingPixel) {\n if (slotContext.value?.data?.viewableImpressionCounter) {\n trackingPixel.value = addTrackingPixel(slotContext.value?.data?.viewableImpressionCounter);\n\n context.logger.debug(`Viewability tracking pixel fired for ${slotContext.value?.name}`);\n }\n },\n });\n\n const impressionTrackingPixelElement = ref<HTMLImageElement | null>(null);\n const isImpressionTracked = ref(false);\n hooks.onDispose(() => {\n if (impressionTrackingPixelElement.value)\n impressionTrackingPixelElement.value.remove();\n });\n watch(status, async (newStatus, oldStatus) => {\n if (newStatus === 'loaded' && oldStatus === 'rendered') {\n impressionTrackingPixelElement.value?.remove();\n impressionTrackingPixelElement.value = null;\n }\n });\n\n async function request(): Promise<AdheseAd | null> {\n try {\n if (options.lazyLoading && !isInViewport.value)\n return null;\n\n status.value = 'loading';\n\n let response = await runOnBeforeRequest(null);\n\n if (!response) {\n response = await extRequestAd({\n slot: {\n name: name.value,\n parameters,\n },\n context,\n });\n }\n\n if (response)\n response = await runOnRequest(response);\n\n data.value = response;\n\n if (!originalData.value)\n originalData.value = response;\n\n status.value = response ? 'loaded' : 'empty';\n\n if (!response)\n cleanElement();\n\n return response;\n }\n catch (error) {\n status.value = 'error';\n\n logger.error(`Error requesting ad for slot ${name.value}`, error);\n\n runOnError(new Error(`Error requesting ad for slot ${name.value}`, { cause: error }));\n\n return null;\n }\n }\n\n async function render(adToRender?: AdheseAd): Promise<HTMLElement | null> {\n if (status.value === 'empty' || status.value === 'error' || status.value === 'initializing') {\n return null;\n }\n\n try {\n if (options.lazyLoading && !isInViewport.value)\n return null;\n\n status.value = 'rendering';\n await waitForDomLoad();\n element.value = getElement();\n\n let renderAd = adToRender ?? data.value ?? originalData.value ?? await request();\n\n renderAd = renderAd && await runOnBeforeRender(renderAd);\n\n if (!element.value && renderMode !== 'none') {\n logger.debug(`Could not render slot for format ${format.value}. No element found.`, slotContext.value);\n\n return null;\n }\n\n if (!renderAd) {\n // eslint-disable-next-line require-atomic-updates\n status.value = 'empty';\n logger.debug(`No ad to render for slot ${name.value}`);\n\n runOnEmpty();\n\n return null;\n }\n\n if (typeof renderAd?.tag !== 'string' && renderMode !== 'none') {\n const error = `Could not render slot for slot ${name.value}. A valid tag doesn't exist or is not HTML string.`;\n logger.error(error, options);\n\n throw new Error(error);\n }\n\n if (renderMode !== 'none' && element.value) {\n renderFunctions[renderMode]({\n ...renderAd,\n ...pick(options, ['width', 'height']),\n } as RenderOptions, element.value);\n }\n\n if (renderAd.impressionCounter && !impressionTrackingPixelElement.value)\n impressionTrackingPixelElement.value = addTrackingPixel(renderAd.impressionCounter);\n\n isImpressionTracked.value = true;\n\n logger.debug(`Slot rendered ${name.value}`, {\n renderedElement: element,\n location: context.location,\n format,\n containingElement,\n });\n\n // eslint-disable-next-line require-atomic-updates\n status.value = 'rendered';\n\n runOnRender(renderAd);\n\n return element.value;\n }\n catch (error) {\n // eslint-disable-next-line require-atomic-updates\n status.value = 'error';\n\n logger.error(`${error}`, options);\n\n runOnError(new Error(error as string));\n\n return null;\n }\n }\n\n function cleanElement(): void {\n if (!element.value || renderMode === 'none')\n return;\n\n element.value.innerHTML = '';\n element.value.style.position = '';\n }\n\n function dispose(): void {\n cleanElement();\n\n element.value = null;\n\n data.value = null;\n originalData.value = null;\n\n domObserver.disconnect();\n\n runOnDispose();\n\n isDisposed.value = true;\n\n scope.stop();\n }\n\n const state = reactive({\n location: context.location ?? '',\n lazyLoading: options.lazyLoading ?? false,\n type,\n slot,\n parameters,\n format,\n name,\n data,\n isViewabilityTracked,\n isImpressionTracked,\n status,\n element,\n isDisposed,\n id,\n pluginOptions,\n isVisible: isInViewport,\n render,\n request,\n dispose,\n cleanElement,\n options: omit(options, ['context']),\n ...hooks,\n });\n\n watch(state, (newState) => {\n slotContext.value = newState;\n }, {\n deep: true,\n immediate: true,\n });\n\n context.hooks.onInit(async () => {\n await runOnInit();\n\n if (status.value === 'empty' || status.value === 'error') {\n return;\n }\n\n if (initialData) {\n status.value = 'loaded';\n\n data.value = initialData;\n data.value = await runOnRequest(initialData);\n\n return;\n }\n\n status.value = 'initialized';\n\n if (options.lazyLoading) {\n return;\n }\n\n data.value = await slotContext.value?.request() ?? null;\n });\n\n return state;\n })!;\n}\n"],"names":["renderIframe","renderInline","doNothing","effectScope","ref","uniqueId","useSlotHooks","reactive","useQueryDetector","computed","generateName","watch","useDomLoaded","shallowRef","useRenderIntersectionObserver","useViewabilityObserver","addTrackingPixel","extRequestAd","logger","waitForDomLoad","pick","omit"],"mappings":"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"}
1
+ {"version":3,"file":"slot.cjs","sources":["../../../src/slot/slot.ts"],"sourcesContent":["import type { AdheseAd } from '@adhese/sdk';\nimport type { AdheseSlot, AdheseSlotContext, AdheseSlotOptions, RenderMode } from './slot.types';\nimport {\n addTrackingPixel,\n computed,\n doNothing,\n effectScope,\n generateName,\n omit,\n pick,\n reactive,\n type Ref,\n ref,\n renderIframe,\n renderInline,\n type RenderOptions,\n shallowRef,\n uniqueId,\n type UnwrapRef,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\nimport { useQueryDetector } from '../queryDetector/queryDetector';\nimport { requestAd as extRequestAd } from '../requestAds/requestAds';\nimport {\n useDomLoaded,\n useRenderIntersectionObserver,\n useSlotHooks,\n useViewabilityObserver,\n} from './slot.composables';\n\nconst renderFunctions: Record<RenderMode, (ad: RenderOptions, element: HTMLElement) => void> = {\n iframe: renderIframe,\n inline: renderInline,\n none: doNothing,\n};\n\nconst defaultOptions = {\n renderMode: 'iframe',\n type: 'normal',\n} satisfies Partial<AdheseSlotOptions>;\n\n/**\n * Create a new slot instance. This slot instance can be used to request and render ads.\n *\n * @param slotOptions {AdheseSlotOptions} The options to create the slot with.\n *\n * @return AdheseSlot The created slot instance.\n */\nexport function createSlot(slotOptions: AdheseSlotOptions): AdheseSlot {\n const scope = effectScope();\n\n return scope.run(() => {\n const slotContext = ref<AdheseSlotContext | null>(null);\n const options = slotOptions.context.hooks.runOnSlotCreate({\n ...defaultOptions,\n ...(Object.fromEntries(Object.entries(slotOptions).filter(([,value]) => value !== undefined)) as AdheseSlotOptions),\n });\n\n const {\n containingElement,\n slot,\n context,\n pluginOptions,\n initialData = null,\n renderMode = 'iframe',\n type = 'normal',\n } = options;\n\n const id = uniqueId();\n const {\n runOnBeforeRender,\n runOnRender,\n runOnBeforeRequest,\n runOnRequest,\n runOnInit,\n runOnDispose,\n runOnEmpty,\n runOnError,\n ...hooks\n } = useSlotHooks(options, slotContext);\n\n const isDisposed = ref(false);\n const parameters = reactive(new Map(Object.entries(options.parameters ?? {})));\n\n const [device, disposeQueryDetector] = useQueryDetector(context, typeof options.format === 'string'\n ? {\n [options.format]: '(min-width: 0px)',\n }\n : Object.fromEntries(options.format.map(item => [item.format, item.query])));\n\n const format = computed(() => typeof options.format === 'string' ? options.format : device.value);\n\n const data = ref<AdheseAd | null>(null) as Ref<AdheseAd | null>;\n const originalData = ref(data.value) as Ref<AdheseAd | null>;\n const name = computed(() => generateName(options.context.location, format.value, options.slot));\n\n const status = ref<UnwrapRef<AdheseSlot>['status']>('initializing');\n\n watch(name, async (newName, oldName) => {\n if (newName === oldName)\n return;\n\n const newAd = await slotContext.value?.request();\n\n if (!newAd)\n return;\n\n slotContext.value?.cleanElement();\n\n data.value = newAd;\n originalData.value = newAd;\n });\n\n const isDomLoaded = useDomLoaded(context);\n\n const element = shallowRef<HTMLElement | null>(null);\n\n function getElement(): HTMLElement | null {\n if (!(typeof options.containingElement === 'string' || !options.containingElement))\n return options.containingElement;\n\n if (!isDomLoaded.value)\n return null;\n\n return document.querySelector<HTMLElement>(`#${options.containingElement}`);\n }\n\n watch(element, async (newElement, oldElement) => {\n if (status.value === 'empty' || status.value === 'error' || status.value === 'loading') {\n return;\n }\n\n if (newElement === null && data.value) {\n status.value = 'loaded';\n\n return;\n }\n\n if (newElement === oldElement || (oldElement === null && newElement === null))\n return;\n\n await render();\n });\n\n const domObserver = new MutationObserver(() => {\n element.value = getElement();\n });\n\n domObserver.observe(document.body, {\n childList: true,\n subtree: true,\n });\n\n watch(\n isDomLoaded,\n () => {\n element.value = getElement();\n },\n { immediate: true, deep: true },\n );\n\n const isInViewport = useRenderIntersectionObserver({\n options,\n element,\n hooks,\n });\n\n watch(isInViewport, async (newIsInViewport) => {\n if (newIsInViewport && status.value !== 'rendered')\n await slotContext.value?.render();\n }, { immediate: true });\n\n hooks.onDispose(() => {\n disposeQueryDetector();\n });\n\n const isViewabilityTracked = useViewabilityObserver({\n context,\n slotContext,\n hooks,\n onTracked(trackingPixel) {\n if (slotContext.value?.data?.viewableImpressionCounter) {\n trackingPixel.value = addTrackingPixel(slotContext.value?.data?.viewableImpressionCounter);\n\n context.logger.debug(`Viewability tracking pixel fired for ${slotContext.value?.name}`);\n }\n },\n });\n\n const impressionTrackingPixelElement = ref<HTMLImageElement | null>(null);\n const isImpressionTracked = ref(false);\n watch([status, isInViewport, data], ([newStatus, newIsInViewport, newData]) => {\n if (newStatus === 'rendered' && newIsInViewport && newData?.impressionCounter && !impressionTrackingPixelElement.value) {\n impressionTrackingPixelElement.value = addTrackingPixel(newData.impressionCounter);\n\n isImpressionTracked.value = true;\n }\n }, { immediate: true });\n watch(status, async (newStatus, oldStatus) => {\n if (newStatus === 'loaded' && oldStatus === 'rendered') {\n impressionTrackingPixelElement.value?.remove();\n impressionTrackingPixelElement.value = null;\n }\n });\n hooks.onDispose(() => {\n if (impressionTrackingPixelElement.value)\n impressionTrackingPixelElement.value.remove();\n });\n\n async function request(): Promise<AdheseAd | null> {\n try {\n if (options.lazyLoading && !isInViewport.value)\n return null;\n\n status.value = 'loading';\n\n let response = await runOnBeforeRequest(null);\n\n if (!response) {\n response = await extRequestAd({\n slot: {\n name: name.value,\n parameters,\n },\n context,\n });\n }\n\n if (response)\n response = await runOnRequest(response);\n\n data.value = response;\n\n if (!originalData.value)\n originalData.value = response;\n\n status.value = response ? 'loaded' : 'empty';\n\n if (!response)\n cleanElement();\n\n if (response && context.options.eagerRendering && element.value)\n await render(response);\n\n return response;\n }\n catch (error) {\n status.value = 'error';\n\n logger.error(`Error requesting ad for slot ${name.value}`, error);\n\n runOnError(new Error(`Error requesting ad for slot ${name.value}`, { cause: error }));\n\n return null;\n }\n }\n\n async function render(adToRender?: AdheseAd): Promise<HTMLElement | null> {\n if (status.value === 'empty' || status.value === 'error' || status.value === 'initializing') {\n return null;\n }\n\n try {\n if (options.lazyLoading && !isInViewport.value)\n return null;\n\n status.value = 'rendering';\n await waitForDomLoad();\n element.value = getElement();\n\n let renderAd = adToRender ?? data.value ?? originalData.value ?? await request();\n\n renderAd = renderAd && await runOnBeforeRender(renderAd);\n\n if (!element.value && renderMode !== 'none') {\n logger.debug(`Could not render slot for format ${format.value}. No element found.`, slotContext.value);\n\n return null;\n }\n\n if (!renderAd) {\n // eslint-disable-next-line require-atomic-updates\n status.value = 'empty';\n logger.debug(`No ad to render for slot ${name.value}`);\n\n runOnEmpty();\n\n return null;\n }\n\n if (typeof renderAd?.tag !== 'string' && renderMode !== 'none') {\n const error = `Could not render slot for slot ${name.value}. A valid tag doesn't exist or is not HTML string.`;\n logger.error(error, options);\n\n throw new Error(error);\n }\n\n if (renderMode !== 'none' && element.value) {\n renderFunctions[renderMode]({\n ...renderAd,\n ...pick(options, ['width', 'height']),\n } as RenderOptions, element.value);\n }\n\n logger.debug(`Slot rendered ${name.value}`, {\n renderedElement: element,\n location: context.location,\n format,\n containingElement,\n });\n\n // eslint-disable-next-line require-atomic-updates\n status.value = 'rendered';\n\n runOnRender(renderAd);\n\n return element.value;\n }\n catch (error) {\n // eslint-disable-next-line require-atomic-updates\n status.value = 'error';\n\n logger.error(`${error}`, options);\n\n runOnError(new Error(error as string));\n\n return null;\n }\n }\n\n function cleanElement(): void {\n if (!element.value || renderMode === 'none')\n return;\n\n element.value.innerHTML = '';\n element.value.style.position = '';\n }\n\n function dispose(): void {\n cleanElement();\n\n element.value = null;\n\n data.value = null;\n originalData.value = null;\n\n domObserver.disconnect();\n\n runOnDispose();\n\n isDisposed.value = true;\n\n scope.stop();\n }\n\n const state = reactive({\n location: context.location ?? '',\n lazyLoading: options.lazyLoading ?? false,\n type,\n slot,\n parameters,\n format,\n name,\n data,\n isViewabilityTracked,\n isImpressionTracked,\n status,\n element,\n isDisposed,\n id,\n pluginOptions,\n isVisible: isInViewport,\n render,\n request,\n dispose,\n cleanElement,\n options: omit(options, ['context']),\n ...hooks,\n });\n\n watch(state, (newState) => {\n slotContext.value = newState;\n }, {\n deep: true,\n immediate: true,\n });\n\n context.hooks.onInit(async () => {\n await runOnInit();\n\n if (status.value === 'empty' || status.value === 'error') {\n return;\n }\n\n if (initialData) {\n status.value = 'loaded';\n\n data.value = initialData;\n data.value = await runOnRequest(initialData);\n\n return;\n }\n\n status.value = 'initialized';\n\n if (options.lazyLoading) {\n return;\n }\n\n data.value = await slotContext.value?.request() ?? null;\n });\n\n return state;\n })!;\n}\n"],"names":["renderIframe","renderInline","doNothing","effectScope","ref","uniqueId","useSlotHooks","reactive","useQueryDetector","computed","generateName","watch","useDomLoaded","shallowRef","useRenderIntersectionObserver","useViewabilityObserver","addTrackingPixel","extRequestAd","logger","waitForDomLoad","pick","omit"],"mappings":";;;;;;;AAgCA,MAAM,kBAAyF;AAAA,EAC7F,QAAQA,UAAA;AAAA,EACR,QAAQC,UAAA;AAAA,EACR,MAAMC,UAAAA;AACR;AAEA,MAAM,iBAAiB;AAAA,EACrB,YAAY;AAAA,EACZ,MAAM;AACR;AASO,SAAS,WAAW,aAA4C;AACrE,QAAM,QAAQC,UAAAA,YAAY;AAEnB,SAAA,MAAM,IAAI,MAAM;AACf,UAAA,cAAcC,cAA8B,IAAI;AACtD,UAAM,UAAU,YAAY,QAAQ,MAAM,gBAAgB;AAAA,MACxD,GAAG;AAAA,MACH,GAAI,OAAO,YAAY,OAAO,QAAQ,WAAW,EAAE,OAAO,CAAC,CAAA,EAAE,KAAK,MAAM,UAAU,MAAS,CAAC;AAAA,IAAA,CAC7F;AAEK,UAAA;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAc;AAAA,MACd,aAAa;AAAA,MACb,OAAO;AAAA,IAAA,IACL;AAEJ,UAAM,KAAKC,UAAAA,SAAS;AACd,UAAA;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IAAA,IACDC,iBAAa,aAAA,SAAS,WAAW;AAE/B,UAAA,aAAaF,cAAI,KAAK;AACtB,UAAA,aAAaG,mBAAS,IAAI,IAAI,OAAO,QAAQ,QAAQ,cAAc,CAAE,CAAA,CAAC,CAAC;AAEvE,UAAA,CAAC,QAAQ,oBAAoB,IAAIC,cAAAA,iBAAiB,SAAS,OAAO,QAAQ,WAAW,WACvF;AAAA,MACE,CAAC,QAAQ,MAAM,GAAG;AAAA,IAEpB,IAAA,OAAO,YAAY,QAAQ,OAAO,IAAI,CAAA,SAAQ,CAAC,KAAK,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC;AAEvE,UAAA,SAASC,UAAAA,SAAS,MAAM,OAAO,QAAQ,WAAW,WAAW,QAAQ,SAAS,OAAO,KAAK;AAE1F,UAAA,OAAOL,cAAqB,IAAI;AAChC,UAAA,eAAeA,UAAAA,IAAI,KAAK,KAAK;AAC7B,UAAA,OAAOK,UAAAA,SAAS,MAAMC,UAAAA,aAAa,QAAQ,QAAQ,UAAU,OAAO,OAAO,QAAQ,IAAI,CAAC;AAExF,UAAA,SAASN,cAAqC,cAAc;AAE5DO,cAAAA,MAAA,MAAM,OAAO,SAAS,YAAY;;AACtC,UAAI,YAAY;AACd;AAEF,YAAM,QAAQ,QAAM,iBAAY,UAAZ,mBAAmB;AAEvC,UAAI,CAAC;AACH;AAEF,wBAAY,UAAZ,mBAAmB;AAEnB,WAAK,QAAQ;AACb,mBAAa,QAAQ;AAAA,IAAA,CACtB;AAEK,UAAA,cAAcC,8BAAa,OAAO;AAElC,UAAA,UAAUC,qBAA+B,IAAI;AAEnD,aAAS,aAAiC;AACxC,UAAI,EAAE,OAAO,QAAQ,sBAAsB,YAAY,CAAC,QAAQ;AAC9D,eAAO,QAAQ;AAEjB,UAAI,CAAC,YAAY;AACR,eAAA;AAET,aAAO,SAAS,cAA2B,IAAI,QAAQ,iBAAiB,EAAE;AAAA,IAAA;AAGtEF,cAAAA,MAAA,SAAS,OAAO,YAAY,eAAe;AAC3C,UAAA,OAAO,UAAU,WAAW,OAAO,UAAU,WAAW,OAAO,UAAU,WAAW;AACtF;AAAA,MAAA;AAGE,UAAA,eAAe,QAAQ,KAAK,OAAO;AACrC,eAAO,QAAQ;AAEf;AAAA,MAAA;AAGF,UAAI,eAAe,cAAe,eAAe,QAAQ,eAAe;AACtE;AAEF,YAAM,OAAO;AAAA,IAAA,CACd;AAEK,UAAA,cAAc,IAAI,iBAAiB,MAAM;AAC7C,cAAQ,QAAQ,WAAW;AAAA,IAAA,CAC5B;AAEW,gBAAA,QAAQ,SAAS,MAAM;AAAA,MACjC,WAAW;AAAA,MACX,SAAS;AAAA,IAAA,CACV;AAEDA,cAAA;AAAA,MACE;AAAA,MACA,MAAM;AACJ,gBAAQ,QAAQ,WAAW;AAAA,MAC7B;AAAA,MACA,EAAE,WAAW,MAAM,MAAM,KAAK;AAAA,IAChC;AAEA,UAAM,eAAeG,iBAAAA,8BAA8B;AAAA,MACjD;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AAEKH,oBAAA,cAAc,OAAO,oBAAoB;;AACzC,UAAA,mBAAmB,OAAO,UAAU;AAChC,gBAAA,iBAAY,UAAZ,mBAAmB;AAAA,IAAO,GACjC,EAAE,WAAW,MAAM;AAEtB,UAAM,UAAU,MAAM;AACC,2BAAA;AAAA,IAAA,CACtB;AAED,UAAM,uBAAuBI,iBAAAA,uBAAuB;AAAA,MAClD;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,eAAe;;AACnB,aAAA,uBAAY,UAAZ,mBAAmB,SAAnB,mBAAyB,2BAA2B;AACtD,wBAAc,QAAQC,UAAA,kBAAiB,uBAAY,UAAZ,mBAAmB,SAAnB,mBAAyB,yBAAyB;AAEzF,kBAAQ,OAAO,MAAM,yCAAwC,iBAAY,UAAZ,mBAAmB,IAAI,EAAE;AAAA,QAAA;AAAA,MACxF;AAAA,IACF,CACD;AAEK,UAAA,iCAAiCZ,cAA6B,IAAI;AAClE,UAAA,sBAAsBA,cAAI,KAAK;AAC/BO,oBAAA,CAAC,QAAQ,cAAc,IAAI,GAAG,CAAC,CAAC,WAAW,iBAAiB,OAAO,MAAM;AAC7E,UAAI,cAAc,cAAc,oBAAmB,mCAAS,sBAAqB,CAAC,+BAA+B,OAAO;AACvF,uCAAA,QAAQK,2BAAiB,QAAQ,iBAAiB;AAEjF,4BAAoB,QAAQ;AAAA,MAAA;AAAA,IAC9B,GACC,EAAE,WAAW,MAAM;AAChBL,cAAAA,MAAA,QAAQ,OAAO,WAAW,cAAc;;AACxC,UAAA,cAAc,YAAY,cAAc,YAAY;AACtD,6CAA+B,UAA/B,mBAAsC;AACtC,uCAA+B,QAAQ;AAAA,MAAA;AAAA,IACzC,CACD;AACD,UAAM,UAAU,MAAM;AACpB,UAAI,+BAA+B;AACjC,uCAA+B,MAAM,OAAO;AAAA,IAAA,CAC/C;AAED,mBAAe,UAAoC;AAC7C,UAAA;AACE,YAAA,QAAQ,eAAe,CAAC,aAAa;AAChC,iBAAA;AAET,eAAO,QAAQ;AAEX,YAAA,WAAW,MAAM,mBAAmB,IAAI;AAE5C,YAAI,CAAC,UAAU;AACb,qBAAW,MAAMM,WAAAA,UAAa;AAAA,YAC5B,MAAM;AAAA,cACJ,MAAM,KAAK;AAAA,cACX;AAAA,YACF;AAAA,YACA;AAAA,UAAA,CACD;AAAA,QAAA;AAGC,YAAA;AACS,qBAAA,MAAM,aAAa,QAAQ;AAExC,aAAK,QAAQ;AAEb,YAAI,CAAC,aAAa;AAChB,uBAAa,QAAQ;AAEhB,eAAA,QAAQ,WAAW,WAAW;AAErC,YAAI,CAAC;AACU,uBAAA;AAEf,YAAI,YAAY,QAAQ,QAAQ,kBAAkB,QAAQ;AACxD,gBAAM,OAAO,QAAQ;AAEhB,eAAA;AAAA,eAEF,OAAO;AACZ,eAAO,QAAQ;AAEfC,eAAA,OAAO,MAAM,gCAAgC,KAAK,KAAK,IAAI,KAAK;AAErD,mBAAA,IAAI,MAAM,gCAAgC,KAAK,KAAK,IAAI,EAAE,OAAO,MAAM,CAAC,CAAC;AAE7E,eAAA;AAAA,MAAA;AAAA,IACT;AAGF,mBAAe,OAAO,YAAoD;AACpE,UAAA,OAAO,UAAU,WAAW,OAAO,UAAU,WAAW,OAAO,UAAU,gBAAgB;AACpF,eAAA;AAAA,MAAA;AAGL,UAAA;AACE,YAAA,QAAQ,eAAe,CAAC,aAAa;AAChC,iBAAA;AAET,eAAO,QAAQ;AACf,cAAMC,yBAAe;AACrB,gBAAQ,QAAQ,WAAW;AAE3B,YAAI,WAAW,cAAc,KAAK,SAAS,aAAa,SAAS,MAAM,QAAQ;AAEpE,mBAAA,YAAY,MAAM,kBAAkB,QAAQ;AAEvD,YAAI,CAAC,QAAQ,SAAS,eAAe,QAAQ;AAC3CD,wBAAO,MAAM,oCAAoC,OAAO,KAAK,uBAAuB,YAAY,KAAK;AAE9F,iBAAA;AAAA,QAAA;AAGT,YAAI,CAAC,UAAU;AAEb,iBAAO,QAAQ;AACfA,iBAAA,OAAO,MAAM,4BAA4B,KAAK,KAAK,EAAE;AAE1C,qBAAA;AAEJ,iBAAA;AAAA,QAAA;AAGT,YAAI,QAAO,qCAAU,SAAQ,YAAY,eAAe,QAAQ;AACxD,gBAAA,QAAQ,kCAAkC,KAAK,KAAK;AACnDA,wBAAA,MAAM,OAAO,OAAO;AAErB,gBAAA,IAAI,MAAM,KAAK;AAAA,QAAA;AAGnB,YAAA,eAAe,UAAU,QAAQ,OAAO;AAC1C,0BAAgB,UAAU,EAAE;AAAA,YAC1B,GAAG;AAAA,YACH,GAAGE,eAAK,SAAS,CAAC,SAAS,QAAQ,CAAC;AAAA,UAAA,GAClB,QAAQ,KAAK;AAAA,QAAA;AAGnCF,eAAA,OAAO,MAAM,iBAAiB,KAAK,KAAK,IAAI;AAAA,UAC1C,iBAAiB;AAAA,UACjB,UAAU,QAAQ;AAAA,UAClB;AAAA,UACA;AAAA,QAAA,CACD;AAGD,eAAO,QAAQ;AAEf,oBAAY,QAAQ;AAEpB,eAAO,QAAQ;AAAA,eAEV,OAAO;AAEZ,eAAO,QAAQ;AAEfA,eAAAA,OAAO,MAAM,GAAG,KAAK,IAAI,OAAO;AAErB,mBAAA,IAAI,MAAM,KAAe,CAAC;AAE9B,eAAA;AAAA,MAAA;AAAA,IACT;AAGF,aAAS,eAAqB;AACxB,UAAA,CAAC,QAAQ,SAAS,eAAe;AACnC;AAEF,cAAQ,MAAM,YAAY;AAClB,cAAA,MAAM,MAAM,WAAW;AAAA,IAAA;AAGjC,aAAS,UAAgB;AACV,mBAAA;AAEb,cAAQ,QAAQ;AAEhB,WAAK,QAAQ;AACb,mBAAa,QAAQ;AAErB,kBAAY,WAAW;AAEV,mBAAA;AAEb,iBAAW,QAAQ;AAEnB,YAAM,KAAK;AAAA,IAAA;AAGb,UAAM,QAAQX,UAAAA,SAAS;AAAA,MACrB,UAAU,QAAQ,YAAY;AAAA,MAC9B,aAAa,QAAQ,eAAe;AAAA,MACpC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAASc,UAAA,KAAK,SAAS,CAAC,SAAS,CAAC;AAAA,MAClC,GAAG;AAAA,IAAA,CACJ;AAEKV,oBAAA,OAAO,CAAC,aAAa;AACzB,kBAAY,QAAQ;AAAA,IAAA,GACnB;AAAA,MACD,MAAM;AAAA,MACN,WAAW;AAAA,IAAA,CACZ;AAEO,YAAA,MAAM,OAAO,YAAY;;AAC/B,YAAM,UAAU;AAEhB,UAAI,OAAO,UAAU,WAAW,OAAO,UAAU,SAAS;AACxD;AAAA,MAAA;AAGF,UAAI,aAAa;AACf,eAAO,QAAQ;AAEf,aAAK,QAAQ;AACR,aAAA,QAAQ,MAAM,aAAa,WAAW;AAE3C;AAAA,MAAA;AAGF,aAAO,QAAQ;AAEf,UAAI,QAAQ,aAAa;AACvB;AAAA,MAAA;AAGF,WAAK,QAAQ,QAAM,iBAAY,UAAZ,mBAAmB,cAAa;AAAA,IAAA,CACpD;AAEM,WAAA;AAAA,EAAA,CACR;AACH;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"slot.composables.cjs","sources":["../../../src/slot/slot.composables.ts"],"sourcesContent":["import type { AdheseAd, AdheseContext, AdheseSlot, AdheseSlotContext, AdheseSlotHooks, AdheseSlotOptions } from '@adhese/sdk';\nimport {\n createAsyncHook,\n createPassiveHook,\n type Ref,\n ref,\n round,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\n\nexport function useDomLoaded(context: AdheseContext): Readonly<Ref<boolean>> {\n const isDomLoaded = ref(false);\n\n context.hooks.onInit(async () => {\n await waitForDomLoad();\n\n isDomLoaded.value = true;\n });\n return isDomLoaded;\n}\n\nexport function useRenderIntersectionObserver({ options, element, hooks }: {\n options: AdheseSlotOptions;\n element: Ref<HTMLElement | null>;\n hooks: AdheseSlotHooks;\n}): Ref<boolean> {\n const isInViewport = ref(false);\n\n const renderIntersectionObserver = new IntersectionObserver((entries) => {\n isInViewport.value = entries.some(entry => entry.isIntersecting);\n }, {\n rootMargin: options.lazyLoadingOptions?.rootMargin ?? '200px',\n threshold: 0,\n });\n\n function observe(newElement: HTMLElement | null, oldElement?: HTMLElement | null): () => void {\n if (oldElement)\n renderIntersectionObserver.unobserve(oldElement);\n\n if (newElement)\n renderIntersectionObserver.observe(newElement);\n\n return () => {\n if (newElement)\n renderIntersectionObserver.unobserve(newElement);\n };\n }\n\n watch(element, observe);\n observe(element.value);\n\n hooks.onDispose(() => {\n renderIntersectionObserver.disconnect();\n });\n\n return isInViewport;\n}\n\nexport function useViewabilityObserver(\n { context, slotContext, hooks, onTracked }: {\n context: AdheseContext;\n slotContext: Ref<AdheseSlot | null>;\n hooks: AdheseSlotHooks;\n onTracked?(trackingPixel: Ref<HTMLImageElement | null>): void;\n },\n): Ref<boolean> {\n let timeoutId: number | null = null;\n const {\n threshold,\n duration,\n rootMargin,\n } = {\n threshold: 0.2,\n duration: 1000,\n rootMargin: '0px',\n ...context.options.viewabilityTrackingOptions,\n } satisfies Required<typeof context.options.viewabilityTrackingOptions>;\n\n const trackingPixel = ref<HTMLImageElement | null>(null);\n\n const isTracked = ref(false);\n\n const viewabilityObserver = new IntersectionObserver(([entry]) => {\n if (context.options.viewabilityTracking && !trackingPixel.value) {\n const ratio = round(entry.intersectionRatio, 1);\n\n if (ratio >= threshold && !timeoutId) {\n // @ts-expect-error The is misfiring to the Node type\n timeoutId = setTimeout(() => {\n timeoutId = null;\n\n onTracked?.(trackingPixel);\n\n isTracked.value = true;\n }, duration);\n }\n else if (ratio < threshold && timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n }\n }, {\n rootMargin,\n threshold: Array.from({ length: 11 }, (_, i) => i * 0.1),\n });\n\n function observe(newElement: HTMLElement | null, oldElement?: HTMLElement | null): () => void {\n if (oldElement)\n viewabilityObserver.unobserve(oldElement);\n\n if (newElement && context.options.viewabilityTracking)\n viewabilityObserver.observe(newElement);\n\n return () => {\n if (newElement)\n viewabilityObserver.unobserve(newElement);\n };\n }\n\n watch(() => slotContext.value?.element, (element) => {\n if (element)\n observe(element);\n }, { immediate: true });\n\n watch(slotContext, (slot) => {\n if (slot?.element)\n viewabilityObserver.observe(slot.element);\n }, { once: true });\n\n hooks.onDispose(() => {\n trackingPixel.value?.remove();\n viewabilityObserver.disconnect();\n });\n\n watch(() => slotContext.value?.status, async (newStatus, oldStatus) => {\n if (newStatus === 'loaded' && oldStatus === 'rendered') {\n trackingPixel.value?.remove();\n trackingPixel.value = null;\n }\n });\n\n return isTracked;\n}\n\nexport function useSlotHooks({ setup }: AdheseSlotOptions, slotContext: Ref<AdheseSlotContext | null>): {\n runOnBeforeRender: ReturnType<typeof createAsyncHook<AdheseAd>>[0];\n runOnRender: ReturnType<typeof createPassiveHook<AdheseAd>>[0];\n runOnBeforeRequest: ReturnType<typeof createAsyncHook<AdheseAd | null>>[0];\n runOnRequest: ReturnType<typeof createAsyncHook<AdheseAd>>[0];\n runOnInit: ReturnType<typeof createAsyncHook<void>>[0];\n runOnDispose: ReturnType<typeof createPassiveHook<void>>[0];\n runOnEmpty: ReturnType<typeof createPassiveHook<void>>[0];\n runOnError: ReturnType<typeof createPassiveHook<Error>>[0];\n} & AdheseSlotHooks {\n const [runOnBeforeRender, onBeforeRender, disposeOnBeforeRender] = createAsyncHook<AdheseAd>();\n const [runOnRender, onRender, disposeOnRender] = createPassiveHook<AdheseAd>();\n const [runOnBeforeRequest, onBeforeRequest, disposeOnBeforeRequest] = createAsyncHook<AdheseAd | null>();\n const [runOnRequest, onRequest, disposeOnRequest] = createAsyncHook<AdheseAd>();\n const [runOnInit, onInit, disposeOnInit] = createAsyncHook();\n const [runOnDispose, onDispose, disposeOnDispose] = createPassiveHook();\n const [runOnEmpty, onEmpty, disposeOnEmpty] = createPassiveHook();\n const [runOnError, onError, disposeOnError] = createPassiveHook<Error>();\n\n setup?.(slotContext, {\n onBeforeRender,\n onRender,\n onBeforeRequest,\n onDispose,\n onRequest,\n onInit,\n onEmpty,\n onError,\n });\n\n onDispose(() => {\n disposeOnBeforeRender();\n disposeOnRender();\n disposeOnBeforeRequest();\n disposeOnRequest();\n disposeOnInit();\n disposeOnDispose();\n disposeOnEmpty();\n disposeOnError();\n });\n\n return { runOnBeforeRender, runOnRender, runOnBeforeRequest, runOnRequest, runOnDispose, onDispose, onBeforeRequest, onRequest, onBeforeRender, onRender, onInit, runOnInit, runOnEmpty, onEmpty, runOnError, onError };\n}\n"],"names":["ref","waitForDomLoad","watch","round","createAsyncHook","createPassiveHook"],"mappings":"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"}
1
+ {"version":3,"file":"slot.composables.cjs","sources":["../../../src/slot/slot.composables.ts"],"sourcesContent":["import type { AdheseAd, AdheseContext, AdheseSlot, AdheseSlotContext, AdheseSlotHooks, AdheseSlotOptions } from '@adhese/sdk';\nimport {\n createAsyncHook,\n createPassiveHook,\n type Ref,\n ref,\n round,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\n\nexport function useDomLoaded(context: AdheseContext): Readonly<Ref<boolean>> {\n const isDomLoaded = ref(false);\n\n context.hooks.onInit(async () => {\n await waitForDomLoad();\n\n isDomLoaded.value = true;\n });\n return isDomLoaded;\n}\n\nexport function useRenderIntersectionObserver({ options, element, hooks }: {\n options: AdheseSlotOptions;\n element: Ref<HTMLElement | null>;\n hooks: AdheseSlotHooks;\n}): Ref<boolean> {\n const isInViewport = ref(false);\n\n const renderIntersectionObserver = new IntersectionObserver((entries) => {\n isInViewport.value = entries.some(entry => entry.isIntersecting);\n }, {\n rootMargin: options.lazyLoadingOptions?.rootMargin ?? '200px',\n threshold: 0,\n });\n\n function observe(newElement: HTMLElement | null, oldElement?: HTMLElement | null): () => void {\n if (oldElement)\n renderIntersectionObserver.unobserve(oldElement);\n\n if (newElement)\n renderIntersectionObserver.observe(newElement);\n\n return () => {\n if (newElement)\n renderIntersectionObserver.unobserve(newElement);\n };\n }\n\n watch(element, observe);\n observe(element.value);\n\n hooks.onDispose(() => {\n renderIntersectionObserver.disconnect();\n });\n\n return isInViewport;\n}\n\nexport function useViewabilityObserver(\n { context, slotContext, hooks, onTracked }: {\n context: AdheseContext;\n slotContext: Ref<AdheseSlot | null>;\n hooks: AdheseSlotHooks;\n onTracked?(trackingPixel: Ref<HTMLImageElement | null>): void;\n },\n): Ref<boolean> {\n let timeoutId: number | null = null;\n const {\n threshold,\n duration,\n rootMargin,\n } = {\n threshold: 0.2,\n duration: 1000,\n rootMargin: '0px',\n ...context.options.viewabilityTrackingOptions,\n } satisfies Required<typeof context.options.viewabilityTrackingOptions>;\n\n const trackingPixel = ref<HTMLImageElement | null>(null);\n\n const isTracked = ref(false);\n\n const viewabilityObserver = new IntersectionObserver(([entry]) => {\n if (context.options.viewabilityTracking && !trackingPixel.value) {\n const ratio = round(entry.intersectionRatio, 1);\n\n if (ratio >= threshold && !timeoutId) {\n // @ts-expect-error The is misfiring to the Node type\n timeoutId = setTimeout(() => {\n timeoutId = null;\n\n onTracked?.(trackingPixel);\n\n isTracked.value = true;\n }, duration);\n }\n else if (ratio < threshold && timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n }\n }, {\n rootMargin,\n threshold: Array.from({ length: 11 }, (_, i) => i * 0.1),\n });\n\n function observe(newElement: HTMLElement | null, oldElement?: HTMLElement | null): () => void {\n if (oldElement)\n viewabilityObserver.unobserve(oldElement);\n\n if (newElement && context.options.viewabilityTracking)\n viewabilityObserver.observe(newElement);\n\n return () => {\n if (newElement)\n viewabilityObserver.unobserve(newElement);\n };\n }\n\n watch(() => slotContext.value?.element, (element) => {\n if (element)\n observe(element);\n }, { immediate: true });\n\n watch(slotContext, (slot) => {\n if (slot?.element)\n viewabilityObserver.observe(slot.element);\n }, { once: true });\n\n hooks.onDispose(() => {\n trackingPixel.value?.remove();\n viewabilityObserver.disconnect();\n });\n\n watch(() => slotContext.value?.status, async (newStatus, oldStatus) => {\n if (newStatus === 'loaded' && oldStatus === 'rendered') {\n trackingPixel.value?.remove();\n trackingPixel.value = null;\n }\n });\n\n return isTracked;\n}\n\nexport function useSlotHooks({ setup }: AdheseSlotOptions, slotContext: Ref<AdheseSlotContext | null>): {\n runOnBeforeRender: ReturnType<typeof createAsyncHook<AdheseAd>>[0];\n runOnRender: ReturnType<typeof createPassiveHook<AdheseAd>>[0];\n runOnBeforeRequest: ReturnType<typeof createAsyncHook<AdheseAd | null>>[0];\n runOnRequest: ReturnType<typeof createAsyncHook<AdheseAd>>[0];\n runOnInit: ReturnType<typeof createAsyncHook<void>>[0];\n runOnDispose: ReturnType<typeof createPassiveHook<void>>[0];\n runOnEmpty: ReturnType<typeof createPassiveHook<void>>[0];\n runOnError: ReturnType<typeof createPassiveHook<Error>>[0];\n} & AdheseSlotHooks {\n const [runOnBeforeRender, onBeforeRender, disposeOnBeforeRender] = createAsyncHook<AdheseAd>();\n const [runOnRender, onRender, disposeOnRender] = createPassiveHook<AdheseAd>();\n const [runOnBeforeRequest, onBeforeRequest, disposeOnBeforeRequest] = createAsyncHook<AdheseAd | null>();\n const [runOnRequest, onRequest, disposeOnRequest] = createAsyncHook<AdheseAd>();\n const [runOnInit, onInit, disposeOnInit] = createAsyncHook();\n const [runOnDispose, onDispose, disposeOnDispose] = createPassiveHook();\n const [runOnEmpty, onEmpty, disposeOnEmpty] = createPassiveHook();\n const [runOnError, onError, disposeOnError] = createPassiveHook<Error>();\n\n setup?.(slotContext, {\n onBeforeRender,\n onRender,\n onBeforeRequest,\n onDispose,\n onRequest,\n onInit,\n onEmpty,\n onError,\n });\n\n onDispose(() => {\n disposeOnBeforeRender();\n disposeOnRender();\n disposeOnBeforeRequest();\n disposeOnRequest();\n disposeOnInit();\n disposeOnDispose();\n disposeOnEmpty();\n disposeOnError();\n });\n\n return { runOnBeforeRender, runOnRender, runOnBeforeRequest, runOnRequest, runOnDispose, onDispose, onBeforeRequest, onRequest, onBeforeRender, onRender, onInit, runOnInit, runOnEmpty, onEmpty, runOnError, onError };\n}\n"],"names":["ref","waitForDomLoad","watch","round","createAsyncHook","createPassiveHook"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"slotManager.cjs","sources":["../../../src/slotManager/slotManager.ts"],"sourcesContent":["import type { AdheseContext } from '../main.types';\nimport type { AdheseSlot, AdheseSlotOptions } from '../slot/slot.types';\nimport { generateSlotSignature } from '@adhese/sdk-shared';\nimport { findDomSlots as extFindDomSlots } from '../findDomSlots/findDomSlots';\nimport { logger } from '../logger/logger';\nimport { createSlot } from '../slot/slot';\n\nexport type AdheseSlotManager = {\n /**\n * Returns all slots that are currently registered and rendered.\n */\n getAll(): ReadonlyArray<AdheseSlot>;\n /**\n * Adds a new slot to the Adhese instance and renders it.\n */\n add(slot: Omit<AdheseSlotOptions, 'context'>): Readonly<AdheseSlot>;\n /**\n * Finds all slots in the DOM and adds them to the Adhese instance.\n */\n findDomSlots(): Promise<ReadonlyArray<AdheseSlot>>;\n /**\n * Returns the slot with the given name.\n */\n get(name: string): AdheseSlot | undefined;\n /**\n * Removes all slots from the Adhese instance and cleans up the slot manager.\n */\n dispose(): void;\n};\n\nexport type SlotManagerOptions = {\n /**\n * List of initial slots to add to the slot manager.\n */\n initialSlots?: ReadonlyArray<Omit<AdheseSlotOptions, 'context' | 'lazy'>>;\n context: AdheseContext;\n};\n\n/**\n * Creates a new slot manager instance. This slot manager instance can be used to manage all slots in the Adhese\n * instance. It will automatically add all slots that are passed in the `initialSlots` array.\n */\nexport function createSlotManager({\n initialSlots = [],\n context,\n}: SlotManagerOptions): AdheseSlotManager {\n context.slots = new Map<string, AdheseSlot>();\n\n function getAll(): ReadonlyArray<AdheseSlot> {\n return Array.from(context.slots).map(([, slot]) => slot);\n }\n\n function add(options: Omit<AdheseSlotOptions, 'context' | 'onDispose'>): Readonly<AdheseSlot> {\n const signature = generateSlotSignature({\n location: context.location,\n format: options.format,\n slot: options.slot,\n parameters: options.parameters,\n },\n );\n\n const current = context.slots.get(signature);\n\n const slot = createSlot({\n ...options as AdheseSlotOptions,\n context,\n initialData: current?.data ?? current?.options.initialData,\n setup(slotContext, slotHooks) {\n options.setup?.(slotContext, slotHooks);\n\n slotHooks.onInit(() => {\n if (!slotContext.value)\n return;\n\n if (current?.status === 'empty' || current?.status === 'error') {\n slotContext.value.status = current?.status;\n }\n });\n\n slotHooks.onDispose(() => {\n context.slots.delete(slot.id);\n logger.debug('Slot removed', {\n slot,\n });\n context.events?.removeSlot.dispatch(slot);\n });\n },\n });\n\n current?.dispose();\n\n context.slots.set(signature, slot);\n\n logger.debug('Slot added', {\n slot,\n slots: Array.from(context.slots.values()),\n });\n\n context.events?.addSlot.dispatch(slot);\n\n return slot;\n }\n\n async function findDomSlots(): Promise<ReadonlyArray<AdheseSlot>> {\n const domSlots = await extFindDomSlots(\n context,\n );\n\n for (const slot of domSlots)\n context.slots.set(slot.id, slot);\n\n return domSlots;\n }\n\n function get(name: string): AdheseSlot | undefined {\n return getAll().find(slot => slot.name === name);\n }\n\n function dispose(): void {\n for (const slot of context.slots.values())\n slot.dispose();\n\n context.slots.clear();\n }\n\n for (const options of initialSlots) {\n add({\n ...options,\n lazyLoading: false,\n });\n }\n\n return {\n getAll,\n add,\n findDomSlots,\n get,\n dispose,\n };\n}\n"],"names":["slot","generateSlotSignature","createSlot","_a","logger","findDomSlots","extFindDomSlots"],"mappings":";;;;;;AA0CO,SAAS,kBAAkB;AAAA,EAChC,eAAe,CAAC;AAAA,EAChB;AACF,GAA0C;AAChC,UAAA,4BAAY;AAEpB,WAAS,SAAoC;AACpC,WAAA,MAAM,KAAK,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAG,EAAAA,KAAI,MAAMA,KAAI;AAAA,EACzD;AAEA,WAAS,IAAI,SAAiF;;AAC5F,UAAM,YAAYC,UAAA;AAAA,MAAsB;AAAA,QACtC,UAAU,QAAQ;AAAA,QAClB,QAAQ,QAAQ;AAAA,QAChB,MAAM,QAAQ;AAAA,QACd,YAAY,QAAQ;AAAA,MACtB;AAAA,IAAA;AAGA,UAAM,UAAU,QAAQ,MAAM,IAAI,SAAS;AAE3C,UAAMD,SAAOE,KAAAA,WAAW;AAAA,MACtB,GAAG;AAAA,MACH;AAAA,MACA,cAAa,mCAAS,UAAQ,mCAAS,QAAQ;AAAA,MAC/C,MAAM,aAAa,WAAW;;AACpB,SAAAC,MAAA,QAAA,UAAA,gBAAAA,IAAA,cAAQ,aAAa;AAE7B,kBAAU,OAAO,MAAM;AACrB,cAAI,CAAC,YAAY;AACf;AAEF,eAAI,mCAAS,YAAW,YAAW,mCAAS,YAAW,SAAS;AAClD,wBAAA,MAAM,SAAS,mCAAS;AAAA,UACtC;AAAA,QAAA,CACD;AAED,kBAAU,UAAU,MAAM;;AAChB,kBAAA,MAAM,OAAOH,OAAK,EAAE;AAC5BI,iBAAA,OAAO,MAAM,gBAAgB;AAAA,YAAA,MAC3BJ;AAAAA,UAAA,CACD;AACO,WAAAG,MAAA,QAAA,WAAA,gBAAAA,IAAQ,WAAW,SAASH;AAAAA,QAAI,CACzC;AAAA,MACH;AAAA,IAAA,CACD;AAED,uCAAS;AAED,YAAA,MAAM,IAAI,WAAWA,MAAI;AAEjCI,WAAA,OAAO,MAAM,cAAc;AAAA,MAAA,MACzBJ;AAAAA,MACA,OAAO,MAAM,KAAK,QAAQ,MAAM,QAAQ;AAAA,IAAA,CACzC;AAEO,kBAAA,WAAA,mBAAQ,QAAQ,SAASA;AAE1B,WAAAA;AAAAA,EACT;AAEA,iBAAeK,iBAAmD;AAChE,UAAM,WAAW,MAAMC,aAAA;AAAA,MACrB;AAAA,IAAA;AAGF,eAAWN,SAAQ;AACjB,cAAQ,MAAM,IAAIA,MAAK,IAAIA,KAAI;AAE1B,WAAA;AAAA,EACT;AAEA,WAAS,IAAI,MAAsC;AACjD,WAAO,OAAS,EAAA,KAAK,CAAQA,UAAAA,MAAK,SAAS,IAAI;AAAA,EACjD;AAEA,WAAS,UAAgB;AACZ,eAAAA,SAAQ,QAAQ,MAAM,OAAO;AACtC,MAAAA,MAAK,QAAQ;AAEf,YAAQ,MAAM;EAChB;AAEA,aAAW,WAAW,cAAc;AAC9B,QAAA;AAAA,MACF,GAAG;AAAA,MACH,aAAa;AAAA,IAAA,CACd;AAAA,EACH;AAEO,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IAAA,cACAK;AAAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;;"}
1
+ {"version":3,"file":"slotManager.cjs","sources":["../../../src/slotManager/slotManager.ts"],"sourcesContent":["import type { AdheseContext } from '../main.types';\nimport type { AdheseSlot, AdheseSlotOptions } from '../slot/slot.types';\nimport { generateSlotSignature } from '@adhese/sdk-shared';\nimport { findDomSlots as extFindDomSlots } from '../findDomSlots/findDomSlots';\nimport { logger } from '../logger/logger';\nimport { createSlot } from '../slot/slot';\n\nexport type AdheseSlotManager = {\n /**\n * Returns all slots that are currently registered and rendered.\n */\n getAll(): ReadonlyArray<AdheseSlot>;\n /**\n * Adds a new slot to the Adhese instance and renders it.\n */\n add(slot: Omit<AdheseSlotOptions, 'context'>): Readonly<AdheseSlot>;\n /**\n * Finds all slots in the DOM and adds them to the Adhese instance.\n */\n findDomSlots(): Promise<ReadonlyArray<AdheseSlot>>;\n /**\n * Returns the slot with the given name.\n */\n get(name: string): AdheseSlot | undefined;\n /**\n * Removes all slots from the Adhese instance and cleans up the slot manager.\n */\n dispose(): void;\n};\n\nexport type SlotManagerOptions = {\n /**\n * List of initial slots to add to the slot manager.\n */\n initialSlots?: ReadonlyArray<Omit<AdheseSlotOptions, 'context' | 'lazy'>>;\n context: AdheseContext;\n};\n\n/**\n * Creates a new slot manager instance. This slot manager instance can be used to manage all slots in the Adhese\n * instance. It will automatically add all slots that are passed in the `initialSlots` array.\n */\nexport function createSlotManager({\n initialSlots = [],\n context,\n}: SlotManagerOptions): AdheseSlotManager {\n context.slots = new Map<string, AdheseSlot>();\n\n function getAll(): ReadonlyArray<AdheseSlot> {\n return Array.from(context.slots).map(([, slot]) => slot);\n }\n\n function add(options: Omit<AdheseSlotOptions, 'context' | 'onDispose'>): Readonly<AdheseSlot> {\n const signature = generateSlotSignature({\n location: context.location,\n format: options.format,\n slot: options.slot,\n parameters: options.parameters,\n },\n );\n\n const current = context.slots.get(signature);\n\n const slot = createSlot({\n ...options as AdheseSlotOptions,\n context,\n initialData: current?.data ?? current?.options.initialData,\n setup(slotContext, slotHooks) {\n options.setup?.(slotContext, slotHooks);\n\n slotHooks.onInit(() => {\n if (!slotContext.value)\n return;\n\n if (current?.status === 'empty' || current?.status === 'error') {\n slotContext.value.status = current?.status;\n }\n });\n\n slotHooks.onDispose(() => {\n context.slots.delete(slot.id);\n logger.debug('Slot removed', {\n slot,\n });\n context.events?.removeSlot.dispatch(slot);\n });\n },\n });\n\n current?.dispose();\n\n context.slots.set(signature, slot);\n\n logger.debug('Slot added', {\n slot,\n slots: Array.from(context.slots.values()),\n });\n\n context.events?.addSlot.dispatch(slot);\n\n return slot;\n }\n\n async function findDomSlots(): Promise<ReadonlyArray<AdheseSlot>> {\n const domSlots = await extFindDomSlots(\n context,\n );\n\n for (const slot of domSlots)\n context.slots.set(slot.id, slot);\n\n return domSlots;\n }\n\n function get(name: string): AdheseSlot | undefined {\n return getAll().find(slot => slot.name === name);\n }\n\n function dispose(): void {\n for (const slot of context.slots.values())\n slot.dispose();\n\n context.slots.clear();\n }\n\n for (const options of initialSlots) {\n add({\n ...options,\n lazyLoading: false,\n });\n }\n\n return {\n getAll,\n add,\n findDomSlots,\n get,\n dispose,\n };\n}\n"],"names":["slot","generateSlotSignature","createSlot","_a","logger","findDomSlots","extFindDomSlots"],"mappings":";;;;;;AA0CO,SAAS,kBAAkB;AAAA,EAChC,eAAe,CAAC;AAAA,EAChB;AACF,GAA0C;AAChC,UAAA,4BAAY,IAAwB;AAE5C,WAAS,SAAoC;AACpC,WAAA,MAAM,KAAK,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAA,EAAGA,KAAI,MAAMA,KAAI;AAAA,EAAA;AAGzD,WAAS,IAAI,SAAiF;;AAC5F,UAAM,YAAYC,UAAA;AAAA,MAAsB;AAAA,QACtC,UAAU,QAAQ;AAAA,QAClB,QAAQ,QAAQ;AAAA,QAChB,MAAM,QAAQ;AAAA,QACd,YAAY,QAAQ;AAAA,MAAA;AAAA,IAEtB;AAEA,UAAM,UAAU,QAAQ,MAAM,IAAI,SAAS;AAE3C,UAAMD,SAAOE,KAAAA,WAAW;AAAA,MACtB,GAAG;AAAA,MACH;AAAA,MACA,cAAa,mCAAS,UAAQ,mCAAS,QAAQ;AAAA,MAC/C,MAAM,aAAa,WAAW;;AACpB,SAAAC,MAAA,QAAA,UAAA,gBAAAA,IAAA,cAAQ,aAAa;AAE7B,kBAAU,OAAO,MAAM;AACrB,cAAI,CAAC,YAAY;AACf;AAEF,eAAI,mCAAS,YAAW,YAAW,mCAAS,YAAW,SAAS;AAClD,wBAAA,MAAM,SAAS,mCAAS;AAAA,UAAA;AAAA,QACtC,CACD;AAED,kBAAU,UAAU,MAAM;;AAChB,kBAAA,MAAM,OAAOH,OAAK,EAAE;AAC5BI,iBAAA,OAAO,MAAM,gBAAgB;AAAA,YAC3BJ,MAAAA;AAAAA,UAAA,CACD;AACO,WAAAG,MAAA,QAAA,WAAA,gBAAAA,IAAQ,WAAW,SAASH;AAAAA,QAAI,CACzC;AAAA,MAAA;AAAA,IACH,CACD;AAED,uCAAS;AAED,YAAA,MAAM,IAAI,WAAWA,MAAI;AAEjCI,WAAA,OAAO,MAAM,cAAc;AAAA,MAAA,MACzBJ;AAAAA,MACA,OAAO,MAAM,KAAK,QAAQ,MAAM,OAAQ,CAAA;AAAA,IAAA,CACzC;AAEO,kBAAA,WAAA,mBAAQ,QAAQ,SAASA;AAE1B,WAAAA;AAAAA,EAAA;AAGT,iBAAeK,iBAAmD;AAChE,UAAM,WAAW,MAAMC,aAAA;AAAA,MACrB;AAAA,IACF;AAEA,eAAWN,SAAQ;AACjB,cAAQ,MAAM,IAAIA,MAAK,IAAIA,KAAI;AAE1B,WAAA;AAAA,EAAA;AAGT,WAAS,IAAI,MAAsC;AACjD,WAAO,OAAS,EAAA,KAAK,CAAQA,UAAAA,MAAK,SAAS,IAAI;AAAA,EAAA;AAGjD,WAAS,UAAgB;AACZ,eAAAA,SAAQ,QAAQ,MAAM,OAAO;AACtC,MAAAA,MAAK,QAAQ;AAEf,YAAQ,MAAM,MAAM;AAAA,EAAA;AAGtB,aAAW,WAAW,cAAc;AAC9B,QAAA;AAAA,MACF,GAAG;AAAA,MACH,aAAa;AAAA,IAAA,CACd;AAAA,EAAA;AAGI,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IAAA,cACAK;AAAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"consent.js","sources":["../../src/consent/consent.ts"],"sourcesContent":["import type { AdheseContext } from '@adhese/sdk';\nimport type { ConsentData } from '../types';\nimport { computed, type ComputedRef, type Ref, ref, watch } from '@adhese/sdk-shared';\n\nexport function useConsent(context: AdheseContext): [\n value: Ref<string>,\n type: ComputedRef<'binary' | 'tcf'>,\n] {\n const consent = ref('none');\n const consentType = computed(() => (consent.value === 'none' || consent.value === 'all') ? 'binary' : 'tcf');\n\n function onTcfConsentChange(data: ConsentData): void {\n if (data.tcString)\n consent.value = data.tcString;\n }\n\n context.hooks.onInit(() => {\n window.__tcfapi?.('addEventListener', 2, onTcfConsentChange);\n });\n\n context.hooks.onDispose(() => {\n window.__tcfapi?.('removeEventListener', 2, onTcfConsentChange);\n });\n\n watch(() => context.consent, (newConsent) => {\n consent.value = newConsent ? 'all' : 'none';\n }, { immediate: true });\n\n watch([consent, consentType], ([newConsent, newConsentType]) => {\n if (newConsentType === 'binary') {\n context.parameters.set('tl', newConsent);\n context.parameters.delete('xt');\n }\n else {\n context.parameters.set('xt', newConsent);\n context.parameters.delete('tl');\n }\n }, { immediate: true });\n\n watch(consent, (newConsent) => {\n context.consentString = newConsent;\n }, { immediate: true });\n\n return [consent, consentType];\n}\n"],"names":[],"mappings":";AAIO,SAAS,WAAW,SAGzB;AACM,QAAA,UAAU,IAAI,MAAM;AACpB,QAAA,cAAc,SAAS,MAAO,QAAQ,UAAU,UAAU,QAAQ,UAAU,QAAS,WAAW,KAAK;AAE3G,WAAS,mBAAmB,MAAyB;AACnD,QAAI,KAAK;AACP,cAAQ,QAAQ,KAAK;AAAA,EACzB;AAEQ,UAAA,MAAM,OAAO,MAAM;;AAClB,iBAAA,aAAA,gCAAW,oBAAoB,GAAG;AAAA,EAAkB,CAC5D;AAEO,UAAA,MAAM,UAAU,MAAM;;AACrB,iBAAA,aAAA,gCAAW,uBAAuB,GAAG;AAAA,EAAkB,CAC/D;AAED,QAAM,MAAM,QAAQ,SAAS,CAAC,eAAe;AACnC,YAAA,QAAQ,aAAa,QAAQ;AAAA,EAAA,GACpC,EAAE,WAAW,KAAA,CAAM;AAEhB,QAAA,CAAC,SAAS,WAAW,GAAG,CAAC,CAAC,YAAY,cAAc,MAAM;AAC9D,QAAI,mBAAmB,UAAU;AACvB,cAAA,WAAW,IAAI,MAAM,UAAU;AAC/B,cAAA,WAAW,OAAO,IAAI;AAAA,IAAA,OAE3B;AACK,cAAA,WAAW,IAAI,MAAM,UAAU;AAC/B,cAAA,WAAW,OAAO,IAAI;AAAA,IAChC;AAAA,EAAA,GACC,EAAE,WAAW,KAAA,CAAM;AAEhB,QAAA,SAAS,CAAC,eAAe;AAC7B,YAAQ,gBAAgB;AAAA,EAAA,GACvB,EAAE,WAAW,KAAA,CAAM;AAEf,SAAA,CAAC,SAAS,WAAW;AAC9B;"}
1
+ {"version":3,"file":"consent.js","sources":["../../src/consent/consent.ts"],"sourcesContent":["import type { AdheseContext } from '@adhese/sdk';\nimport type { ConsentData } from '../types';\nimport { computed, type ComputedRef, type Ref, ref, watch } from '@adhese/sdk-shared';\n\nexport function useConsent(context: AdheseContext): [\n value: Ref<string>,\n type: ComputedRef<'binary' | 'tcf'>,\n] {\n const consent = ref('none');\n const consentType = computed(() => (consent.value === 'none' || consent.value === 'all') ? 'binary' : 'tcf');\n\n function onTcfConsentChange(data: ConsentData): void {\n if (data.tcString)\n consent.value = data.tcString;\n }\n\n context.hooks.onInit(() => {\n window.__tcfapi?.('addEventListener', 2, onTcfConsentChange);\n });\n\n context.hooks.onDispose(() => {\n window.__tcfapi?.('removeEventListener', 2, onTcfConsentChange);\n });\n\n watch(() => context.consent, (newConsent) => {\n consent.value = newConsent ? 'all' : 'none';\n }, { immediate: true });\n\n watch([consent, consentType], ([newConsent, newConsentType]) => {\n if (newConsentType === 'binary') {\n context.parameters.set('tl', newConsent);\n context.parameters.delete('xt');\n }\n else {\n context.parameters.set('xt', newConsent);\n context.parameters.delete('tl');\n }\n }, { immediate: true });\n\n watch(consent, (newConsent) => {\n context.consentString = newConsent;\n }, { immediate: true });\n\n return [consent, consentType];\n}\n"],"names":[],"mappings":";AAIO,SAAS,WAAW,SAGzB;AACM,QAAA,UAAU,IAAI,MAAM;AACpB,QAAA,cAAc,SAAS,MAAO,QAAQ,UAAU,UAAU,QAAQ,UAAU,QAAS,WAAW,KAAK;AAE3G,WAAS,mBAAmB,MAAyB;AACnD,QAAI,KAAK;AACP,cAAQ,QAAQ,KAAK;AAAA,EAAA;AAGjB,UAAA,MAAM,OAAO,MAAM;;AAClB,iBAAA,aAAA,gCAAW,oBAAoB,GAAG;AAAA,EAAkB,CAC5D;AAEO,UAAA,MAAM,UAAU,MAAM;;AACrB,iBAAA,aAAA,gCAAW,uBAAuB,GAAG;AAAA,EAAkB,CAC/D;AAED,QAAM,MAAM,QAAQ,SAAS,CAAC,eAAe;AACnC,YAAA,QAAQ,aAAa,QAAQ;AAAA,EAAA,GACpC,EAAE,WAAW,MAAM;AAEhB,QAAA,CAAC,SAAS,WAAW,GAAG,CAAC,CAAC,YAAY,cAAc,MAAM;AAC9D,QAAI,mBAAmB,UAAU;AACvB,cAAA,WAAW,IAAI,MAAM,UAAU;AAC/B,cAAA,WAAW,OAAO,IAAI;AAAA,IAAA,OAE3B;AACK,cAAA,WAAW,IAAI,MAAM,UAAU;AAC/B,cAAA,WAAW,OAAO,IAAI;AAAA,IAAA;AAAA,EAChC,GACC,EAAE,WAAW,MAAM;AAEhB,QAAA,SAAS,CAAC,eAAe;AAC7B,YAAQ,gBAAgB;AAAA,EAAA,GACvB,EAAE,WAAW,MAAM;AAEf,SAAA,CAAC,SAAS,WAAW;AAC9B;"}
@@ -1 +1 @@
1
- {"version":3,"file":"findDomSlots.js","sources":["../../src/findDomSlots/findDomSlots.ts"],"sourcesContent":["import type { AdheseContext, AdheseSlot } from '@adhese/sdk';\nimport { generateName, waitForDomLoad } from '@adhese/sdk-shared';\nimport { createSlot } from '../slot/slot';\n\n/**\n * Find all slots in the DOM and render them. Ignore slots that are already active.\n */\nexport async function findDomSlots(\n context: AdheseContext,\n): Promise<ReadonlyArray<AdheseSlot>> {\n await waitForDomLoad();\n\n return Array.from(document.querySelectorAll<HTMLElement>('.adunit'))\n .filter((element) => {\n if (!element.dataset.format)\n return false;\n\n const name = generateName(\n context.location,\n element.dataset.format,\n element.dataset.slot,\n );\n\n return !context.getAll?.().some(activeSlot => activeSlot.name === name);\n })\n .map(element => createSlot({\n format: element.dataset.format as string,\n containingElement: element,\n slot: element.dataset.slot,\n context,\n }))\n .filter(slot => !context.getAll?.().some(activeSlot => activeSlot.name === slot.name));\n}\n"],"names":[],"mappings":";;AAOA,eAAsB,aACpB,SACoC;AACpC,QAAM,eAAe;AAEd,SAAA,MAAM,KAAK,SAAS,iBAA8B,SAAS,CAAC,EAChE,OAAO,CAAC,YAAY;;AACf,QAAA,CAAC,QAAQ,QAAQ;AACZ,aAAA;AAET,UAAM,OAAO;AAAA,MACX,QAAQ;AAAA,MACR,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,IAAA;AAGX,WAAA,GAAC,aAAQ,WAAR,iCAAmB,KAAK,CAAc,eAAA,WAAW,SAAS;AAAA,EACnE,CAAA,EACA,IAAI,CAAA,YAAW,WAAW;AAAA,IACzB,QAAQ,QAAQ,QAAQ;AAAA,IACxB,mBAAmB;AAAA,IACnB,MAAM,QAAQ,QAAQ;AAAA,IACtB;AAAA,EAAA,CACD,CAAC,EACD,OAAO;;AAAQ,cAAC,aAAQ,WAAR,iCAAmB,KAAK,CAAc,eAAA,WAAW,SAAS,KAAK;AAAA,GAAK;AACzF;"}
1
+ {"version":3,"file":"findDomSlots.js","sources":["../../src/findDomSlots/findDomSlots.ts"],"sourcesContent":["import type { AdheseContext, AdheseSlot } from '@adhese/sdk';\nimport { generateName, waitForDomLoad } from '@adhese/sdk-shared';\nimport { createSlot } from '../slot/slot';\n\n/**\n * Find all slots in the DOM and render them. Ignore slots that are already active.\n */\nexport async function findDomSlots(\n context: AdheseContext,\n): Promise<ReadonlyArray<AdheseSlot>> {\n await waitForDomLoad();\n\n return Array.from(document.querySelectorAll<HTMLElement>('.adunit'))\n .filter((element) => {\n if (!element.dataset.format)\n return false;\n\n const name = generateName(\n context.location,\n element.dataset.format,\n element.dataset.slot,\n );\n\n return !context.getAll?.().some(activeSlot => activeSlot.name === name);\n })\n .map(element => createSlot({\n format: element.dataset.format as string,\n containingElement: element,\n slot: element.dataset.slot,\n context,\n }))\n .filter(slot => !context.getAll?.().some(activeSlot => activeSlot.name === slot.name));\n}\n"],"names":[],"mappings":";;AAOA,eAAsB,aACpB,SACoC;AACpC,QAAM,eAAe;AAEd,SAAA,MAAM,KAAK,SAAS,iBAA8B,SAAS,CAAC,EAChE,OAAO,CAAC,YAAY;;AACf,QAAA,CAAC,QAAQ,QAAQ;AACZ,aAAA;AAET,UAAM,OAAO;AAAA,MACX,QAAQ;AAAA,MACR,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,IAClB;AAEO,WAAA,GAAC,aAAQ,WAAR,iCAAmB,KAAK,CAAc,eAAA,WAAW,SAAS;AAAA,EACnE,CAAA,EACA,IAAI,CAAA,YAAW,WAAW;AAAA,IACzB,QAAQ,QAAQ,QAAQ;AAAA,IACxB,mBAAmB;AAAA,IACnB,MAAM,QAAQ,QAAQ;AAAA,IACtB;AAAA,EACD,CAAA,CAAC,EACD,OAAO,UAAQ;;AAAA,cAAC,aAAQ,WAAR,iCAAmB,KAAK,CAAc,eAAA,WAAW,SAAS,KAAK;AAAA,GAAK;AACzF;"}
package/dist/hooks.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.js","sources":["../src/hooks.ts"],"sourcesContent":["import type { AdheseAd, AdheseSlotOptions } from './adheseSdk';\nimport type { AdMultiRequestOptions } from './requestAds/requestAds';\nimport { createAsyncHook, createSyncHook } from '@adhese/sdk-shared';\n\n// eslint-disable-next-line ts/explicit-function-return-type,ts/explicit-module-boundary-types\nexport function createGlobalHooks() {\n const disposeFunctions = new Set<() => void>();\n\n let isInit = false;\n const [runOnInit, onInit, disposeOnInit] = createSyncHook({\n onRun(callbacks) {\n isInit = true;\n callbacks?.clear();\n },\n onAdd() {\n if (isInit)\n runOnInit();\n },\n });\n disposeFunctions.add(disposeOnInit);\n\n let isDisposed = false;\n const [runOnDispose, onDispose, disposeOnDispose] = createSyncHook({\n onRun(callbacks) {\n isDisposed = true;\n callbacks?.clear();\n },\n onAdd() {\n if (isDisposed)\n runOnDispose();\n },\n });\n disposeFunctions.add(disposeOnDispose);\n\n const [runOnRequest, onRequest, disposeOnRequest] = createAsyncHook<AdMultiRequestOptions>();\n disposeFunctions.add(disposeOnRequest);\n\n const [runOnResponse, onResponse, disposeOnResponse] = createAsyncHook<ReadonlyArray<AdheseAd>>();\n disposeFunctions.add(disposeOnResponse);\n\n const [runOnSlotCreate, onSlotCreate, disposeOnSlotCreate] = createSyncHook<AdheseSlotOptions>();\n disposeFunctions.add(disposeOnSlotCreate);\n\n function clearAll(): void {\n for (const disposeFunction of disposeFunctions)\n disposeFunction();\n }\n\n return {\n runOnInit,\n onInit,\n runOnDispose,\n onDispose,\n runOnRequest,\n onRequest,\n runOnResponse,\n onResponse,\n runOnSlotCreate,\n onSlotCreate,\n clearAll,\n };\n}\n"],"names":[],"mappings":";AAKO,SAAS,oBAAoB;AAC5B,QAAA,uCAAuB;AAE7B,MAAI,SAAS;AACb,QAAM,CAAC,WAAW,QAAQ,aAAa,IAAI,eAAe;AAAA,IACxD,MAAM,WAAW;AACN,eAAA;AACT,6CAAW;AAAA,IACb;AAAA,IACA,QAAQ;AACF,UAAA;AACQ;IACd;AAAA,EAAA,CACD;AACD,mBAAiB,IAAI,aAAa;AAElC,MAAI,aAAa;AACjB,QAAM,CAAC,cAAc,WAAW,gBAAgB,IAAI,eAAe;AAAA,IACjE,MAAM,WAAW;AACF,mBAAA;AACb,6CAAW;AAAA,IACb;AAAA,IACA,QAAQ;AACF,UAAA;AACW;IACjB;AAAA,EAAA,CACD;AACD,mBAAiB,IAAI,gBAAgB;AAErC,QAAM,CAAC,cAAc,WAAW,gBAAgB,IAAI,gBAAuC;AAC3F,mBAAiB,IAAI,gBAAgB;AAErC,QAAM,CAAC,eAAe,YAAY,iBAAiB,IAAI,gBAAyC;AAChG,mBAAiB,IAAI,iBAAiB;AAEtC,QAAM,CAAC,iBAAiB,cAAc,mBAAmB,IAAI,eAAkC;AAC/F,mBAAiB,IAAI,mBAAmB;AAExC,WAAS,WAAiB;AACxB,eAAW,mBAAmB;AACZ;EACpB;AAEO,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;"}
1
+ {"version":3,"file":"hooks.js","sources":["../src/hooks.ts"],"sourcesContent":["import type { AdheseAd, AdheseSlotOptions } from './adheseSdk';\nimport type { AdMultiRequestOptions } from './requestAds/requestAds';\nimport { createAsyncHook, createSyncHook } from '@adhese/sdk-shared';\n\n// eslint-disable-next-line ts/explicit-function-return-type,ts/explicit-module-boundary-types\nexport function createGlobalHooks() {\n const disposeFunctions = new Set<() => void>();\n\n let isInit = false;\n const [runOnInit, onInit, disposeOnInit] = createSyncHook({\n onRun(callbacks) {\n isInit = true;\n callbacks?.clear();\n },\n onAdd() {\n if (isInit)\n runOnInit();\n },\n });\n disposeFunctions.add(disposeOnInit);\n\n let isDisposed = false;\n const [runOnDispose, onDispose, disposeOnDispose] = createSyncHook({\n onRun(callbacks) {\n isDisposed = true;\n callbacks?.clear();\n },\n onAdd() {\n if (isDisposed)\n runOnDispose();\n },\n });\n disposeFunctions.add(disposeOnDispose);\n\n const [runOnRequest, onRequest, disposeOnRequest] = createAsyncHook<AdMultiRequestOptions>();\n disposeFunctions.add(disposeOnRequest);\n\n const [runOnResponse, onResponse, disposeOnResponse] = createAsyncHook<ReadonlyArray<AdheseAd>>();\n disposeFunctions.add(disposeOnResponse);\n\n const [runOnSlotCreate, onSlotCreate, disposeOnSlotCreate] = createSyncHook<AdheseSlotOptions>();\n disposeFunctions.add(disposeOnSlotCreate);\n\n function clearAll(): void {\n for (const disposeFunction of disposeFunctions)\n disposeFunction();\n }\n\n return {\n runOnInit,\n onInit,\n runOnDispose,\n onDispose,\n runOnRequest,\n onRequest,\n runOnResponse,\n onResponse,\n runOnSlotCreate,\n onSlotCreate,\n clearAll,\n };\n}\n"],"names":[],"mappings":";AAKO,SAAS,oBAAoB;AAC5B,QAAA,uCAAuB,IAAgB;AAE7C,MAAI,SAAS;AACb,QAAM,CAAC,WAAW,QAAQ,aAAa,IAAI,eAAe;AAAA,IACxD,MAAM,WAAW;AACN,eAAA;AACT,6CAAW;AAAA,IACb;AAAA,IACA,QAAQ;AACF,UAAA;AACQ,kBAAA;AAAA,IAAA;AAAA,EACd,CACD;AACD,mBAAiB,IAAI,aAAa;AAElC,MAAI,aAAa;AACjB,QAAM,CAAC,cAAc,WAAW,gBAAgB,IAAI,eAAe;AAAA,IACjE,MAAM,WAAW;AACF,mBAAA;AACb,6CAAW;AAAA,IACb;AAAA,IACA,QAAQ;AACF,UAAA;AACW,qBAAA;AAAA,IAAA;AAAA,EACjB,CACD;AACD,mBAAiB,IAAI,gBAAgB;AAErC,QAAM,CAAC,cAAc,WAAW,gBAAgB,IAAI,gBAAuC;AAC3F,mBAAiB,IAAI,gBAAgB;AAErC,QAAM,CAAC,eAAe,YAAY,iBAAiB,IAAI,gBAAyC;AAChG,mBAAiB,IAAI,iBAAiB;AAEtC,QAAM,CAAC,iBAAiB,cAAc,mBAAmB,IAAI,eAAkC;AAC/F,mBAAiB,IAAI,mBAAmB;AAExC,WAAS,WAAiB;AACxB,eAAW,mBAAmB;AACZ,sBAAA;AAAA,EAAA;AAGb,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;"}
@@ -1 +1 @@
1
- {"version":3,"file":"main.composables.js","sources":["../src/main.composables.ts"],"sourcesContent":["import type { AdheseContextState, MergedOptions } from './main.types';\nimport { watch } from '@adhese/sdk-shared';\nimport { isPreviewMode } from './main.utils';\nimport { useQueryDetector } from './queryDetector/queryDetector';\n\nexport function useMainQueryDetector(mergedOptions: MergedOptions, context: AdheseContextState): void {\n const [device] = useQueryDetector(context, mergedOptions.queries);\n watch(device, async (newDevice) => {\n context.device = newDevice;\n\n context.parameters?.set('dt', newDevice);\n context.parameters?.set('br', newDevice);\n\n await Promise.allSettled(context.getAll().map(async slot => slot.request()));\n }, { immediate: true });\n}\n\nexport function useMainDebugMode(context: AdheseContextState): void {\n if (window.location.search.includes('adhese_debug=true') || isPreviewMode()) {\n context.debug = true;\n }\n\n watch(() => context.debug, async (newDebug) => {\n if (newDebug) {\n context.logger.setMinLogLevelThreshold('debug');\n context.logger.debug('Debug mode enabled');\n context.events?.debugChange.dispatch(true);\n }\n else {\n context.logger.debug('Debug mode disabled');\n context.logger.setMinLogLevelThreshold('info');\n context.events?.debugChange.dispatch(false);\n }\n }, {\n immediate: true,\n });\n\n context.hooks.onDispose(() => {\n context.logger.resetLogs();\n context.logger.debug('Adhese instance disposed');\n });\n}\n\nexport function useMainParameters(context: AdheseContextState, options: MergedOptions): void {\n const parameters = new Map<string, string | ReadonlyArray<string>>();\n\n if (options.logReferrer)\n parameters.set('re', btoa(document.referrer));\n\n if (options.logUrl)\n parameters.set('ur', btoa(window.location.href));\n\n for (const [key, value] of Object.entries({\n ...options.parameters ?? {},\n rn: Math.round(Math.random() * 10_000).toString(),\n }))\n parameters.set(key, value);\n\n context.parameters = parameters;\n\n watch(\n () => context.parameters,\n (newParameters) => {\n context.events?.parametersChange.dispatch(newParameters);\n },\n {\n deep: true,\n },\n );\n}\n"],"names":[],"mappings":";;;AAKgB,SAAA,qBAAqB,eAA8B,SAAmC;AACpG,QAAM,CAAC,MAAM,IAAI,iBAAiB,SAAS,cAAc,OAAO;AAC1D,QAAA,QAAQ,OAAO,cAAc;;AACjC,YAAQ,SAAS;AAET,kBAAA,eAAA,mBAAY,IAAI,MAAM;AACtB,kBAAA,eAAA,mBAAY,IAAI,MAAM;AAExB,UAAA,QAAQ,WAAW,QAAQ,OAAO,EAAE,IAAI,OAAM,SAAQ,KAAK,QAAQ,CAAC,CAAC;AAAA,EAAA,GAC1E,EAAE,WAAW,KAAA,CAAM;AACxB;AAEO,SAAS,iBAAiB,SAAmC;AAClE,MAAI,OAAO,SAAS,OAAO,SAAS,mBAAmB,KAAK,iBAAiB;AAC3E,YAAQ,QAAQ;AAAA,EAClB;AAEA,QAAM,MAAM,QAAQ,OAAO,OAAO,aAAa;;AAC7C,QAAI,UAAU;AACJ,cAAA,OAAO,wBAAwB,OAAO;AACtC,cAAA,OAAO,MAAM,oBAAoB;AACjC,oBAAA,WAAA,mBAAQ,YAAY,SAAS;AAAA,IAAI,OAEtC;AACK,cAAA,OAAO,MAAM,qBAAqB;AAClC,cAAA,OAAO,wBAAwB,MAAM;AACrC,oBAAA,WAAA,mBAAQ,YAAY,SAAS;AAAA,IACvC;AAAA,EAAA,GACC;AAAA,IACD,WAAW;AAAA,EAAA,CACZ;AAEO,UAAA,MAAM,UAAU,MAAM;AAC5B,YAAQ,OAAO;AACP,YAAA,OAAO,MAAM,0BAA0B;AAAA,EAAA,CAChD;AACH;AAEgB,SAAA,kBAAkB,SAA6B,SAA8B;AACrF,QAAA,iCAAiB;AAEvB,MAAI,QAAQ;AACV,eAAW,IAAI,MAAM,KAAK,SAAS,QAAQ,CAAC;AAE9C,MAAI,QAAQ;AACV,eAAW,IAAI,MAAM,KAAK,OAAO,SAAS,IAAI,CAAC;AAEjD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ;AAAA,IACxC,GAAG,QAAQ,cAAc,CAAC;AAAA,IAC1B,IAAI,KAAK,MAAM,KAAK,WAAW,GAAM,EAAE,SAAS;AAAA,EAAA,CACjD;AACY,eAAA,IAAI,KAAK,KAAK;AAE3B,UAAQ,aAAa;AAErB;AAAA,IACE,MAAM,QAAQ;AAAA,IACd,CAAC,kBAAkB;;AACT,oBAAA,WAAA,mBAAQ,iBAAiB,SAAS;AAAA,IAC5C;AAAA,IACA;AAAA,MACE,MAAM;AAAA,IACR;AAAA,EAAA;AAEJ;"}
1
+ {"version":3,"file":"main.composables.js","sources":["../src/main.composables.ts"],"sourcesContent":["import type { AdheseContextState, MergedOptions } from './main.types';\nimport { watch } from '@adhese/sdk-shared';\nimport { isPreviewMode } from './main.utils';\nimport { useQueryDetector } from './queryDetector/queryDetector';\n\nexport function useMainQueryDetector(mergedOptions: MergedOptions, context: AdheseContextState): void {\n const [device] = useQueryDetector(context, mergedOptions.queries);\n watch(device, async (newDevice) => {\n context.device = newDevice;\n\n context.parameters?.set('dt', newDevice);\n context.parameters?.set('br', newDevice);\n\n await Promise.allSettled(context.getAll().map(async slot => slot.request()));\n }, { immediate: true });\n}\n\nexport function useMainDebugMode(context: AdheseContextState): void {\n if (window.location.search.includes('adhese_debug=true') || isPreviewMode()) {\n context.debug = true;\n }\n\n watch(() => context.debug, async (newDebug) => {\n if (newDebug) {\n context.logger.setMinLogLevelThreshold('debug');\n context.logger.debug('Debug mode enabled');\n context.events?.debugChange.dispatch(true);\n }\n else {\n context.logger.debug('Debug mode disabled');\n context.logger.setMinLogLevelThreshold('info');\n context.events?.debugChange.dispatch(false);\n }\n }, {\n immediate: true,\n });\n\n context.hooks.onDispose(() => {\n context.logger.resetLogs();\n context.logger.debug('Adhese instance disposed');\n });\n}\n\nexport function useMainParameters(context: AdheseContextState, options: MergedOptions): void {\n const parameters = new Map<string, string | ReadonlyArray<string>>();\n\n if (options.logReferrer)\n parameters.set('re', btoa(document.referrer));\n\n if (options.logUrl)\n parameters.set('ur', btoa(window.location.href));\n\n for (const [key, value] of Object.entries({\n ...options.parameters ?? {},\n rn: Math.round(Math.random() * 10_000).toString(),\n }))\n parameters.set(key, value);\n\n context.parameters = parameters;\n\n watch(\n () => context.parameters,\n (newParameters) => {\n context.events?.parametersChange.dispatch(newParameters);\n },\n {\n deep: true,\n },\n );\n}\n"],"names":[],"mappings":";;;AAKgB,SAAA,qBAAqB,eAA8B,SAAmC;AACpG,QAAM,CAAC,MAAM,IAAI,iBAAiB,SAAS,cAAc,OAAO;AAC1D,QAAA,QAAQ,OAAO,cAAc;;AACjC,YAAQ,SAAS;AAET,kBAAA,eAAA,mBAAY,IAAI,MAAM;AACtB,kBAAA,eAAA,mBAAY,IAAI,MAAM;AAExB,UAAA,QAAQ,WAAW,QAAQ,OAAO,EAAE,IAAI,OAAM,SAAQ,KAAK,QAAQ,CAAC,CAAC;AAAA,EAAA,GAC1E,EAAE,WAAW,MAAM;AACxB;AAEO,SAAS,iBAAiB,SAAmC;AAClE,MAAI,OAAO,SAAS,OAAO,SAAS,mBAAmB,KAAK,iBAAiB;AAC3E,YAAQ,QAAQ;AAAA,EAAA;AAGlB,QAAM,MAAM,QAAQ,OAAO,OAAO,aAAa;;AAC7C,QAAI,UAAU;AACJ,cAAA,OAAO,wBAAwB,OAAO;AACtC,cAAA,OAAO,MAAM,oBAAoB;AACjC,oBAAA,WAAA,mBAAQ,YAAY,SAAS;AAAA,IAAI,OAEtC;AACK,cAAA,OAAO,MAAM,qBAAqB;AAClC,cAAA,OAAO,wBAAwB,MAAM;AACrC,oBAAA,WAAA,mBAAQ,YAAY,SAAS;AAAA,IAAK;AAAA,EAC5C,GACC;AAAA,IACD,WAAW;AAAA,EAAA,CACZ;AAEO,UAAA,MAAM,UAAU,MAAM;AAC5B,YAAQ,OAAO,UAAU;AACjB,YAAA,OAAO,MAAM,0BAA0B;AAAA,EAAA,CAChD;AACH;AAEgB,SAAA,kBAAkB,SAA6B,SAA8B;AACrF,QAAA,iCAAiB,IAA4C;AAEnE,MAAI,QAAQ;AACV,eAAW,IAAI,MAAM,KAAK,SAAS,QAAQ,CAAC;AAE9C,MAAI,QAAQ;AACV,eAAW,IAAI,MAAM,KAAK,OAAO,SAAS,IAAI,CAAC;AAEjD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ;AAAA,IACxC,GAAG,QAAQ,cAAc,CAAC;AAAA,IAC1B,IAAI,KAAK,MAAM,KAAK,OAAW,IAAA,GAAM,EAAE,SAAS;AAAA,EAAA,CACjD;AACY,eAAA,IAAI,KAAK,KAAK;AAE3B,UAAQ,aAAa;AAErB;AAAA,IACE,MAAM,QAAQ;AAAA,IACd,CAAC,kBAAkB;;AACT,oBAAA,WAAA,mBAAQ,iBAAiB,SAAS;AAAA,IAC5C;AAAA,IACA;AAAA,MACE,MAAM;AAAA,IAAA;AAAA,EAEV;AACF;"}
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sources":["../src/main.ts"],"sourcesContent":["import type {\n Adhese,\n AdheseContextStateWithPlugins,\n AdheseOptions,\n AdhesePlugin,\n MergedOptions,\n} from './main.types';\nimport type { AdheseSlot, AdheseSlotOptions } from './slot/slot.types';\nimport { awaitTimeout, createEventManager, effectScope, omit, reactive, watch } from '@adhese/sdk-shared';\nimport { version } from '../package.json';\nimport { useConsent } from './consent/consent';\nimport { createGlobalHooks } from './hooks';\nimport { logger } from './logger/logger';\nimport { useMainDebugMode, useMainParameters, useMainQueryDetector } from './main.composables';\nimport { fetchAllUnrenderedSlots } from './main.utils';\n\nimport { createSlotManager } from './slotManager/slotManager';\n\n/**\n * Creates an Adhese instance. This instance is your main entry point to the Adhese API.\n *\n * @param options {AdheseOptions} The options to create the Adhese instance with. See the {@link AdheseOptions} type for more information.\n *\n * @return Adhese The Adhese instance.\n */\nexport function createAdhese<T extends ReadonlyArray<AdhesePlugin>>(options: AdheseOptions<T>): Adhese<T> {\n const scope = effectScope();\n\n return scope.run(() => {\n const mergedOptions: MergedOptions = {\n host: `https://ads-${options.account}.adhese.com`,\n poolHost: `https://pool-${options.account}.adhese.com`,\n location: 'homepage',\n requestType: 'POST',\n debug: false,\n initialSlots: [],\n findDomSlotsOnLoad: false,\n consent: false,\n logReferrer: true,\n logUrl: true,\n eagerRendering: false,\n viewabilityTracking: true,\n ...options,\n };\n\n import('./requestAds/requestAds.schema').catch(logger.error);\n\n const hooks = createGlobalHooks();\n\n const context = reactive<AdheseContextStateWithPlugins<T>>({\n location: mergedOptions.location,\n consent: mergedOptions.consent,\n debug: mergedOptions.debug,\n options: mergedOptions,\n logger,\n isDisposed: false,\n parameters: new Map(),\n events: createEventManager(),\n slots: new Map(),\n device: 'unknown',\n hooks,\n plugins: {},\n dispose,\n findDomSlots,\n getAll,\n get,\n addSlot,\n });\n\n for (const [index, plugin] of options.plugins?.entries() ?? []) {\n const data = plugin(context, {\n index,\n version,\n hooks,\n });\n\n const name = data.name as keyof typeof context.plugins;\n context.plugins[name] = omit(data, ['name']) as typeof context.plugins[typeof name];\n }\n\n watch(() => context.location, (newLocation) => {\n context.events?.locationChange.dispatch(newLocation);\n });\n\n useMainParameters(context, mergedOptions);\n\n const slotManager = createSlotManager({\n initialSlots: mergedOptions.initialSlots,\n context,\n });\n\n function getAll(): ReadonlyArray<AdheseSlot> {\n return slotManager.getAll() ?? [];\n }\n context.getAll = getAll;\n\n function get(name: string): AdheseSlot | undefined {\n return slotManager.get(name);\n }\n context.get = get;\n\n function addSlot(slotOptions: AdheseSlotOptions): Readonly<AdheseSlot> {\n return slotManager.add(slotOptions);\n }\n context.addSlot = addSlot;\n\n async function findDomSlots(): Promise<ReadonlyArray<AdheseSlot>> {\n const domSlots = (await slotManager.findDomSlots() ?? []).filter(slot => !slot.lazyLoading);\n\n if (domSlots.length <= 0)\n return [];\n\n await fetchAllUnrenderedSlots(context.getAll());\n\n return domSlots;\n }\n context.findDomSlots = findDomSlots;\n\n useMainDebugMode(context);\n\n useMainQueryDetector(mergedOptions, context);\n\n useConsent(context);\n\n function dispose(): void {\n context.isDisposed = true;\n\n slotManager.dispose();\n context.parameters?.clear();\n context.events?.dispose();\n\n hooks.runOnDispose();\n hooks.clearAll();\n\n scope.stop();\n }\n context.dispose = dispose;\n\n hooks.onInit(async () => {\n await awaitTimeout(0);\n\n if ((slotManager.getAll().length ?? 0) > 0)\n await fetchAllUnrenderedSlots(context.getAll()).catch(logger.error);\n\n if (mergedOptions.findDomSlotsOnLoad)\n await context?.findDomSlots();\n\n logger.debug('Created Adhese SDK instance', {\n mergedOptions,\n });\n\n if (!scope.active)\n dispose();\n });\n\n hooks.runOnInit();\n\n return context as Adhese<T>;\n })!;\n}\n"],"names":["_a"],"mappings":"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"}
1
+ {"version":3,"file":"main.js","sources":["../src/main.ts"],"sourcesContent":["import type {\n Adhese,\n AdheseContextStateWithPlugins,\n AdheseOptions,\n AdhesePlugin,\n MergedOptions,\n} from './main.types';\nimport type { AdheseSlot, AdheseSlotOptions } from './slot/slot.types';\nimport { awaitTimeout, createEventManager, effectScope, omit, reactive, watch } from '@adhese/sdk-shared';\nimport { version } from '../package.json';\nimport { useConsent } from './consent/consent';\nimport { createGlobalHooks } from './hooks';\nimport { logger } from './logger/logger';\nimport { useMainDebugMode, useMainParameters, useMainQueryDetector } from './main.composables';\nimport { fetchAllUnrenderedSlots } from './main.utils';\n\nimport { createSlotManager } from './slotManager/slotManager';\n\n/**\n * Creates an Adhese instance. This instance is your main entry point to the Adhese API.\n *\n * @param options {AdheseOptions} The options to create the Adhese instance with. See the {@link AdheseOptions} type for more information.\n *\n * @return Adhese The Adhese instance.\n */\nexport function createAdhese<T extends ReadonlyArray<AdhesePlugin>>(options: AdheseOptions<T>): Adhese<T> {\n const scope = effectScope();\n\n return scope.run(() => {\n const mergedOptions: MergedOptions = {\n host: `https://ads-${options.account}.adhese.com`,\n poolHost: `https://pool-${options.account}.adhese.com`,\n location: 'homepage',\n requestType: 'POST',\n debug: false,\n initialSlots: [],\n findDomSlotsOnLoad: false,\n consent: false,\n logReferrer: true,\n logUrl: true,\n eagerRendering: false,\n viewabilityTracking: true,\n ...options,\n };\n\n import('./requestAds/requestAds.schema').catch(logger.error);\n\n const hooks = createGlobalHooks();\n\n const context = reactive<AdheseContextStateWithPlugins<T>>({\n location: mergedOptions.location,\n consent: mergedOptions.consent,\n debug: mergedOptions.debug,\n options: mergedOptions,\n logger,\n isDisposed: false,\n parameters: new Map(),\n events: createEventManager(),\n slots: new Map(),\n device: 'unknown',\n hooks,\n plugins: {},\n dispose,\n findDomSlots,\n getAll,\n get,\n addSlot,\n });\n\n for (const [index, plugin] of options.plugins?.entries() ?? []) {\n const data = plugin(context, {\n index,\n version,\n hooks,\n });\n\n const name = data.name as keyof typeof context.plugins;\n context.plugins[name] = omit(data, ['name']) as typeof context.plugins[typeof name];\n }\n\n watch(() => context.location, (newLocation) => {\n context.events?.locationChange.dispatch(newLocation);\n });\n\n useMainParameters(context, mergedOptions);\n\n const slotManager = createSlotManager({\n initialSlots: mergedOptions.initialSlots,\n context,\n });\n\n function getAll(): ReadonlyArray<AdheseSlot> {\n return slotManager.getAll() ?? [];\n }\n context.getAll = getAll;\n\n function get(name: string): AdheseSlot | undefined {\n return slotManager.get(name);\n }\n context.get = get;\n\n function addSlot(slotOptions: AdheseSlotOptions): Readonly<AdheseSlot> {\n return slotManager.add(slotOptions);\n }\n context.addSlot = addSlot;\n\n async function findDomSlots(): Promise<ReadonlyArray<AdheseSlot>> {\n const domSlots = (await slotManager.findDomSlots() ?? []).filter(slot => !slot.lazyLoading);\n\n if (domSlots.length <= 0)\n return [];\n\n await fetchAllUnrenderedSlots(context.getAll());\n\n return domSlots;\n }\n context.findDomSlots = findDomSlots;\n\n useMainDebugMode(context);\n\n useMainQueryDetector(mergedOptions, context);\n\n useConsent(context);\n\n function dispose(): void {\n context.isDisposed = true;\n\n slotManager.dispose();\n context.parameters?.clear();\n context.events?.dispose();\n\n hooks.runOnDispose();\n hooks.clearAll();\n\n scope.stop();\n }\n context.dispose = dispose;\n\n hooks.onInit(async () => {\n await awaitTimeout(0);\n\n if ((slotManager.getAll().length ?? 0) > 0)\n await fetchAllUnrenderedSlots(context.getAll()).catch(logger.error);\n\n if (mergedOptions.findDomSlotsOnLoad)\n await context?.findDomSlots();\n\n logger.debug('Created Adhese SDK instance', {\n mergedOptions,\n });\n\n if (!scope.active)\n dispose();\n });\n\n hooks.runOnInit();\n\n return context as Adhese<T>;\n })!;\n}\n"],"names":["_a"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"main.utils.js","sources":["../src/main.utils.ts"],"sourcesContent":["import type { AdheseSlot } from './slot/slot.types';\nimport { logger } from './logger/logger';\n\n/**\n * Checks if the current page is in preview mode.\n */\nexport function isPreviewMode(): boolean {\n return window.location.search.includes('adhesePreviewCreativeId');\n}\n\nexport async function fetchAllUnrenderedSlots(slots: ReadonlyArray<AdheseSlot>): Promise<void> {\n const filteredSlots = slots.filter(slot => !slot.lazyLoading && !slot.data);\n\n if (filteredSlots.length === 0)\n return;\n\n const results = await Promise.allSettled(filteredSlots.map(slot => slot.request));\n\n for (const [index, result] of results.entries()) {\n if (result.status === 'rejected') {\n logger.error(`Failed to fetch slot data for slot ${filteredSlots[index].name}`, result.reason);\n }\n }\n}\n"],"names":[],"mappings":";AAMO,SAAS,gBAAyB;AACvC,SAAO,OAAO,SAAS,OAAO,SAAS,yBAAyB;AAClE;AAEA,eAAsB,wBAAwB,OAAiD;AACvF,QAAA,gBAAgB,MAAM,OAAO,CAAA,SAAQ,CAAC,KAAK,eAAe,CAAC,KAAK,IAAI;AAE1E,MAAI,cAAc,WAAW;AAC3B;AAEI,QAAA,UAAU,MAAM,QAAQ,WAAW,cAAc,IAAI,CAAA,SAAQ,KAAK,OAAO,CAAC;AAEhF,aAAW,CAAC,OAAO,MAAM,KAAK,QAAQ,WAAW;AAC3C,QAAA,OAAO,WAAW,YAAY;AACzB,aAAA,MAAM,sCAAsC,cAAc,KAAK,EAAE,IAAI,IAAI,OAAO,MAAM;AAAA,IAC/F;AAAA,EACF;AACF;"}
1
+ {"version":3,"file":"main.utils.js","sources":["../src/main.utils.ts"],"sourcesContent":["import type { AdheseSlot } from './slot/slot.types';\nimport { logger } from './logger/logger';\n\n/**\n * Checks if the current page is in preview mode.\n */\nexport function isPreviewMode(): boolean {\n return window.location.search.includes('adhesePreviewCreativeId');\n}\n\nexport async function fetchAllUnrenderedSlots(slots: ReadonlyArray<AdheseSlot>): Promise<void> {\n const filteredSlots = slots.filter(slot => !slot.lazyLoading && !slot.data);\n\n if (filteredSlots.length === 0)\n return;\n\n const results = await Promise.allSettled(filteredSlots.map(slot => slot.request));\n\n for (const [index, result] of results.entries()) {\n if (result.status === 'rejected') {\n logger.error(`Failed to fetch slot data for slot ${filteredSlots[index].name}`, result.reason);\n }\n }\n}\n"],"names":[],"mappings":";AAMO,SAAS,gBAAyB;AACvC,SAAO,OAAO,SAAS,OAAO,SAAS,yBAAyB;AAClE;AAEA,eAAsB,wBAAwB,OAAiD;AACvF,QAAA,gBAAgB,MAAM,OAAO,CAAA,SAAQ,CAAC,KAAK,eAAe,CAAC,KAAK,IAAI;AAE1E,MAAI,cAAc,WAAW;AAC3B;AAEI,QAAA,UAAU,MAAM,QAAQ,WAAW,cAAc,IAAI,CAAA,SAAQ,KAAK,OAAO,CAAC;AAEhF,aAAW,CAAC,OAAO,MAAM,KAAK,QAAQ,WAAW;AAC3C,QAAA,OAAO,WAAW,YAAY;AACzB,aAAA,MAAM,sCAAsC,cAAc,KAAK,EAAE,IAAI,IAAI,OAAO,MAAM;AAAA,IAAA;AAAA,EAC/F;AAEJ;"}
@@ -1,5 +1,5 @@
1
1
  const name = "@adhese/sdk";
2
- const version = "1.4.1";
2
+ const version = "1.4.2";
3
3
  export {
4
4
  name,
5
5
  version
@@ -1 +1 @@
1
- {"version":3,"file":"queryDetector.js","sources":["../../src/queryDetector/queryDetector.ts"],"sourcesContent":["import type { AdheseContext } from '@adhese/sdk';\nimport { computed, type ComputedRef, debounce, ref } from '@adhese/sdk-shared';\n\n/**\n * Create a query detector that will match a list of media queries and keeps track of the current matching query\n */\nexport function useQueryDetector(context: AdheseContext, queries: Record<string, string> = {\n phone: '(max-width: 768px)',\n tablet: '(min-width: 769px) and (max-width: 1024px)',\n desktop: '(min-width: 1025px)',\n}): [ComputedRef<string>, () => void] {\n const entries = Object.entries(queries);\n\n const active = ref(getQuery(entries));\n const queryList = entries.map(([, query]) => window.matchMedia(query));\n\n const handleOnChange = debounce((): void => {\n active.value = getQuery(entries);\n }, {\n waitMs: 50,\n });\n\n context.hooks.onInit(() => {\n for (const query of queryList)\n query.addEventListener('change', handleOnChange.call);\n\n handleOnChange.call();\n });\n\n function dispose(): void {\n for (const query of queryList)\n query.removeEventListener('change', handleOnChange.call);\n }\n\n context.hooks.onDispose(dispose);\n\n return [computed(() => active.value), dispose];\n}\n\nfunction getQuery(entries: ReadonlyArray<[string, string]>): string {\n for (const [device, query] of entries) {\n if (window.matchMedia(query).matches)\n return device;\n }\n\n return 'unknown';\n}\n"],"names":[],"mappings":";AAMgB,SAAA,iBAAiB,SAAwB,UAAkC;AAAA,EACzF,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AACX,GAAsC;AAC9B,QAAA,UAAU,OAAO,QAAQ,OAAO;AAEtC,QAAM,SAAS,IAAI,SAAS,OAAO,CAAC;AAC9B,QAAA,YAAY,QAAQ,IAAI,CAAC,CAAA,EAAG,KAAK,MAAM,OAAO,WAAW,KAAK,CAAC;AAE/D,QAAA,iBAAiB,SAAS,MAAY;AACnC,WAAA,QAAQ,SAAS,OAAO;AAAA,EAAA,GAC9B;AAAA,IACD,QAAQ;AAAA,EAAA,CACT;AAEO,UAAA,MAAM,OAAO,MAAM;AACzB,eAAW,SAAS;AACZ,YAAA,iBAAiB,UAAU,eAAe,IAAI;AAEtD,mBAAe,KAAK;AAAA,EAAA,CACrB;AAED,WAAS,UAAgB;AACvB,eAAW,SAAS;AACZ,YAAA,oBAAoB,UAAU,eAAe,IAAI;AAAA,EAC3D;AAEQ,UAAA,MAAM,UAAU,OAAO;AAE/B,SAAO,CAAC,SAAS,MAAM,OAAO,KAAK,GAAG,OAAO;AAC/C;AAEA,SAAS,SAAS,SAAkD;AAClE,aAAW,CAAC,QAAQ,KAAK,KAAK,SAAS;AACjC,QAAA,OAAO,WAAW,KAAK,EAAE;AACpB,aAAA;AAAA,EACX;AAEO,SAAA;AACT;"}
1
+ {"version":3,"file":"queryDetector.js","sources":["../../src/queryDetector/queryDetector.ts"],"sourcesContent":["import type { AdheseContext } from '@adhese/sdk';\nimport { computed, type ComputedRef, debounce, ref } from '@adhese/sdk-shared';\n\n/**\n * Create a query detector that will match a list of media queries and keeps track of the current matching query\n */\nexport function useQueryDetector(context: AdheseContext, queries: Record<string, string> = {\n phone: '(max-width: 768px)',\n tablet: '(min-width: 769px) and (max-width: 1024px)',\n desktop: '(min-width: 1025px)',\n}): [ComputedRef<string>, () => void] {\n const entries = Object.entries(queries);\n\n const active = ref(getQuery(entries));\n const queryList = entries.map(([, query]) => window.matchMedia(query));\n\n const handleOnChange = debounce((): void => {\n active.value = getQuery(entries);\n }, {\n waitMs: 50,\n });\n\n context.hooks.onInit(() => {\n for (const query of queryList)\n query.addEventListener('change', handleOnChange.call);\n\n handleOnChange.call();\n });\n\n function dispose(): void {\n for (const query of queryList)\n query.removeEventListener('change', handleOnChange.call);\n }\n\n context.hooks.onDispose(dispose);\n\n return [computed(() => active.value), dispose];\n}\n\nfunction getQuery(entries: ReadonlyArray<[string, string]>): string {\n for (const [device, query] of entries) {\n if (window.matchMedia(query).matches)\n return device;\n }\n\n return 'unknown';\n}\n"],"names":[],"mappings":";AAMgB,SAAA,iBAAiB,SAAwB,UAAkC;AAAA,EACzF,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AACX,GAAsC;AAC9B,QAAA,UAAU,OAAO,QAAQ,OAAO;AAEtC,QAAM,SAAS,IAAI,SAAS,OAAO,CAAC;AAC9B,QAAA,YAAY,QAAQ,IAAI,CAAC,CAAA,EAAG,KAAK,MAAM,OAAO,WAAW,KAAK,CAAC;AAE/D,QAAA,iBAAiB,SAAS,MAAY;AACnC,WAAA,QAAQ,SAAS,OAAO;AAAA,EAAA,GAC9B;AAAA,IACD,QAAQ;AAAA,EAAA,CACT;AAEO,UAAA,MAAM,OAAO,MAAM;AACzB,eAAW,SAAS;AACZ,YAAA,iBAAiB,UAAU,eAAe,IAAI;AAEtD,mBAAe,KAAK;AAAA,EAAA,CACrB;AAED,WAAS,UAAgB;AACvB,eAAW,SAAS;AACZ,YAAA,oBAAoB,UAAU,eAAe,IAAI;AAAA,EAAA;AAGnD,UAAA,MAAM,UAAU,OAAO;AAE/B,SAAO,CAAC,SAAS,MAAM,OAAO,KAAK,GAAG,OAAO;AAC/C;AAEA,SAAS,SAAS,SAAkD;AAClE,aAAW,CAAC,QAAQ,KAAK,KAAK,SAAS;AACjC,QAAA,OAAO,WAAW,KAAK,EAAE;AACpB,aAAA;AAAA,EAAA;AAGJ,SAAA;AACT;"}
@@ -1 +1 @@
1
- {"version":3,"file":"requestAds.js","sources":["../../src/requestAds/requestAds.ts"],"sourcesContent":["import type { AdheseContext } from '../main.types';\nimport type { AdheseAd } from './requestAds.schema';\nimport { debounce } from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\nimport { requestPreviews } from './requestAds.preview';\nimport { requestWithGet, requestWithPost } from './requestAds.utils';\n\nexport type AdRequestOptions = {\n /**\n * Slot you want to fetch the ad for\n */\n slot: {\n name: string;\n parameters: Map<string, ReadonlyArray<string> | string>;\n };\n context: AdheseContext;\n};\n\nexport type AdMultiRequestOptions = Omit<AdRequestOptions, 'slot'> & {\n slots: ReadonlyArray<AdRequestOptions['slot']>;\n};\n\nconst batch = new Map<string, {\n options: AdRequestOptions;\n resolve(ad: AdheseAd | null): void;\n}>();\n\n/**\n * Debounced function to request ads in batches. This function is debounced to prevent multiple requests for the same ad.\n */\nconst runRequestAdsBatch = debounce(async (context: AdheseContext) => {\n if (batch.size === 0)\n return [];\n\n const ads = await requestAds({\n slots: Array.from(batch.values()).map(({ options }) => options.slot),\n context,\n });\n\n for (const { options, resolve } of batch.values()) {\n const ad = ads.find(({ slotName }) => slotName === options.slot.name);\n\n if (ad)\n resolve(ad);\n else\n resolve(null);\n }\n\n batch.clear();\n\n return ads;\n}, {\n waitMs: 20,\n timing: 'trailing',\n});\n\n/**\n * Request a single ad from the API. If you need to fetch multiple ads at once use the `requestAds` function.\n */\nexport async function requestAd(options: AdRequestOptions): Promise<AdheseAd | null> {\n const promise = new Promise<AdheseAd | null>((resolve) => {\n batch.set(options.slot.name, { options, resolve });\n },\n );\n\n await runRequestAdsBatch.call(options.context);\n\n return promise;\n}\n\n/**\n * Request multiple ads from the API. If you need to fetch a single ad use the `requestAd` function.\n */\nexport async function requestAds(requestOptions: AdMultiRequestOptions): Promise<ReadonlyArray<AdheseAd>> {\n const options = await requestOptions.context.hooks.runOnRequest(requestOptions);\n\n const { context } = options;\n\n try {\n context?.events?.requestAd.dispatch({\n ...options,\n context,\n });\n\n const [response, previews, parseResponse] = await Promise.all([\n context.options.requestType?.toUpperCase() === 'POST'\n ? requestWithPost(options)\n : requestWithGet(options),\n requestPreviews(context.options.account),\n import('./requestAds.schema').then(module => module.parseResponse),\n ]);\n\n logger.debug('Received response', response);\n\n if (!response.ok)\n throw new Error(`Failed to request ad: ${response.status} ${response.statusText}`);\n\n const result = parseResponse((await response.json() as unknown));\n logger.debug('Parsed ad', result);\n\n if (previews.length > 0)\n logger.info(`Found ${previews.length} ${previews.length === 1 ? 'preview' : 'previews'}. Replacing ads in response with preview items`, previews);\n\n const matchedPreviews = previews.map(({ slotName, ...preview }) => {\n const partnerAd = result.find(ad => ad.libId === preview.libId);\n\n return ({\n slotName: `${partnerAd?.slotName ?? slotName}`,\n ...preview,\n });\n });\n\n if (matchedPreviews.length > 0)\n context.events?.previewReceived.dispatch(matchedPreviews);\n\n const mergedResult = await context.hooks.runOnResponse([\n ...result.filter(ad => !previews.some(preview => preview.libId === ad.libId)),\n ...matchedPreviews,\n ]);\n\n context.events?.responseReceived.dispatch(mergedResult);\n\n return mergedResult;\n }\n catch (error) {\n logger.error(String(error));\n context?.events?.requestError.dispatch(error as Error);\n\n throw error;\n }\n}\n"],"names":[],"mappings":";;;;AAsBA,MAAM,4BAAY;AAQlB,MAAM,qBAAqB,SAAS,OAAO,YAA2B;AACpE,MAAI,MAAM,SAAS;AACjB,WAAO;AAEH,QAAA,MAAM,MAAM,WAAW;AAAA,IAC3B,OAAO,MAAM,KAAK,MAAM,OAAQ,CAAA,EAAE,IAAI,CAAC,EAAE,cAAc,QAAQ,IAAI;AAAA,IACnE;AAAA,EAAA,CACD;AAED,aAAW,EAAE,SAAS,QAAa,KAAA,MAAM,UAAU;AAC3C,UAAA,KAAK,IAAI,KAAK,CAAC,EAAE,eAAe,aAAa,QAAQ,KAAK,IAAI;AAEhE,QAAA;AACF,cAAQ,EAAE;AAAA;AAEV,cAAQ,IAAI;AAAA,EAChB;AAEA,QAAM,MAAM;AAEL,SAAA;AACT,GAAG;AAAA,EACD,QAAQ;AAAA,EACR,QAAQ;AACV,CAAC;AAKD,eAAsB,UAAU,SAAqD;AACnF,QAAM,UAAU,IAAI;AAAA,IAAyB,CAAC,YAAY;AACxD,YAAM,IAAI,QAAQ,KAAK,MAAM,EAAE,SAAS,SAAS;AAAA,IACnD;AAAA,EAAA;AAGM,QAAA,mBAAmB,KAAK,QAAQ,OAAO;AAEtC,SAAA;AACT;AAKA,eAAsB,WAAW,gBAAyE;;AACxG,QAAM,UAAU,MAAM,eAAe,QAAQ,MAAM,aAAa,cAAc;AAExE,QAAA,EAAE,QAAY,IAAA;AAEhB,MAAA;AACO,6CAAA,WAAA,mBAAQ,UAAU,SAAS;AAAA,MAClC,GAAG;AAAA,MACH;AAAA,IAAA;AAGF,UAAM,CAAC,UAAU,UAAU,aAAa,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC5D,aAAQ,QAAQ,gBAAhB,mBAA6B,mBAAkB,SAC3C,gBAAgB,OAAO,IACvB,eAAe,OAAO;AAAA,MAC1B,gBAAgB,QAAQ,QAAQ,OAAO;AAAA,MACvC,OAAO,wBAAqB,EAAE,KAAK,CAAA,WAAU,OAAO,aAAa;AAAA,IAAA,CAClE;AAEM,WAAA,MAAM,qBAAqB,QAAQ;AAE1C,QAAI,CAAC,SAAS;AACN,YAAA,IAAI,MAAM,yBAAyB,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAEnF,UAAM,SAAS,cAAe,MAAM,SAAS,KAAkB,CAAA;AACxD,WAAA,MAAM,aAAa,MAAM;AAEhC,QAAI,SAAS,SAAS;AACb,aAAA,KAAK,SAAS,SAAS,MAAM,IAAI,SAAS,WAAW,IAAI,YAAY,UAAU,kDAAkD,QAAQ;AAE5I,UAAA,kBAAkB,SAAS,IAAI,CAAC,EAAE,UAAU,GAAG,cAAc;AACjE,YAAM,YAAY,OAAO,KAAK,QAAM,GAAG,UAAU,QAAQ,KAAK;AAEtD,aAAA;AAAA,QACN,UAAU,IAAG,uCAAW,aAAY,QAAQ;AAAA,QAC5C,GAAG;AAAA,MAAA;AAAA,IACL,CACD;AAED,QAAI,gBAAgB,SAAS;AACnB,oBAAA,WAAA,mBAAQ,gBAAgB,SAAS;AAE3C,UAAM,eAAe,MAAM,QAAQ,MAAM,cAAc;AAAA,MACrD,GAAG,OAAO,OAAO,CAAA,OAAM,CAAC,SAAS,KAAK,CAAA,YAAW,QAAQ,UAAU,GAAG,KAAK,CAAC;AAAA,MAC5E,GAAG;AAAA,IAAA,CACJ;AAEO,kBAAA,WAAA,mBAAQ,iBAAiB,SAAS;AAEnC,WAAA;AAAA,WAEF,OAAO;AACL,WAAA,MAAM,OAAO,KAAK,CAAC;AACjB,6CAAA,WAAA,mBAAQ,aAAa,SAAS;AAEjC,UAAA;AAAA,EACR;AACF;"}
1
+ {"version":3,"file":"requestAds.js","sources":["../../src/requestAds/requestAds.ts"],"sourcesContent":["import type { AdheseContext } from '../main.types';\nimport type { AdheseAd } from './requestAds.schema';\nimport { debounce } from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\nimport { requestPreviews } from './requestAds.preview';\nimport { requestWithGet, requestWithPost } from './requestAds.utils';\n\nexport type AdRequestOptions = {\n /**\n * Slot you want to fetch the ad for\n */\n slot: {\n name: string;\n parameters: Map<string, ReadonlyArray<string> | string>;\n };\n context: AdheseContext;\n};\n\nexport type AdMultiRequestOptions = Omit<AdRequestOptions, 'slot'> & {\n slots: ReadonlyArray<AdRequestOptions['slot']>;\n};\n\nconst batch = new Map<string, {\n options: AdRequestOptions;\n resolve(ad: AdheseAd | null): void;\n}>();\n\n/**\n * Debounced function to request ads in batches. This function is debounced to prevent multiple requests for the same ad.\n */\nconst runRequestAdsBatch = debounce(async (context: AdheseContext) => {\n if (batch.size === 0)\n return [];\n\n const ads = await requestAds({\n slots: Array.from(batch.values()).map(({ options }) => options.slot),\n context,\n });\n\n for (const { options, resolve } of batch.values()) {\n const ad = ads.find(({ slotName }) => slotName === options.slot.name);\n\n if (ad)\n resolve(ad);\n else\n resolve(null);\n }\n\n batch.clear();\n\n return ads;\n}, {\n waitMs: 20,\n timing: 'trailing',\n});\n\n/**\n * Request a single ad from the API. If you need to fetch multiple ads at once use the `requestAds` function.\n */\nexport async function requestAd(options: AdRequestOptions): Promise<AdheseAd | null> {\n const promise = new Promise<AdheseAd | null>((resolve) => {\n batch.set(options.slot.name, { options, resolve });\n },\n );\n\n await runRequestAdsBatch.call(options.context);\n\n return promise;\n}\n\n/**\n * Request multiple ads from the API. If you need to fetch a single ad use the `requestAd` function.\n */\nexport async function requestAds(requestOptions: AdMultiRequestOptions): Promise<ReadonlyArray<AdheseAd>> {\n const options = await requestOptions.context.hooks.runOnRequest(requestOptions);\n\n const { context } = options;\n\n try {\n context?.events?.requestAd.dispatch({\n ...options,\n context,\n });\n\n const [response, previews, parseResponse] = await Promise.all([\n context.options.requestType?.toUpperCase() === 'POST'\n ? requestWithPost(options)\n : requestWithGet(options),\n requestPreviews(context.options.account),\n import('./requestAds.schema').then(module => module.parseResponse),\n ]);\n\n logger.debug('Received response', response);\n\n if (!response.ok)\n throw new Error(`Failed to request ad: ${response.status} ${response.statusText}`);\n\n const result = parseResponse((await response.json() as unknown));\n logger.debug('Parsed ad', result);\n\n if (previews.length > 0)\n logger.info(`Found ${previews.length} ${previews.length === 1 ? 'preview' : 'previews'}. Replacing ads in response with preview items`, previews);\n\n const matchedPreviews = previews.map(({ slotName, ...preview }) => {\n const partnerAd = result.find(ad => ad.libId === preview.libId);\n\n return ({\n slotName: `${partnerAd?.slotName ?? slotName}`,\n ...preview,\n });\n });\n\n if (matchedPreviews.length > 0)\n context.events?.previewReceived.dispatch(matchedPreviews);\n\n const mergedResult = await context.hooks.runOnResponse([\n ...result.filter(ad => !previews.some(preview => preview.libId === ad.libId)),\n ...matchedPreviews,\n ]);\n\n context.events?.responseReceived.dispatch(mergedResult);\n\n return mergedResult;\n }\n catch (error) {\n logger.error(String(error));\n context?.events?.requestError.dispatch(error as Error);\n\n throw error;\n }\n}\n"],"names":[],"mappings":";;;;AAsBA,MAAM,4BAAY,IAGf;AAKH,MAAM,qBAAqB,SAAS,OAAO,YAA2B;AACpE,MAAI,MAAM,SAAS;AACjB,WAAO,CAAC;AAEJ,QAAA,MAAM,MAAM,WAAW;AAAA,IAC3B,OAAO,MAAM,KAAK,MAAM,OAAQ,CAAA,EAAE,IAAI,CAAC,EAAE,cAAc,QAAQ,IAAI;AAAA,IACnE;AAAA,EAAA,CACD;AAED,aAAW,EAAE,SAAS,QAAa,KAAA,MAAM,UAAU;AAC3C,UAAA,KAAK,IAAI,KAAK,CAAC,EAAE,SAAe,MAAA,aAAa,QAAQ,KAAK,IAAI;AAEhE,QAAA;AACF,cAAQ,EAAE;AAAA;AAEV,cAAQ,IAAI;AAAA,EAAA;AAGhB,QAAM,MAAM;AAEL,SAAA;AACT,GAAG;AAAA,EACD,QAAQ;AAAA,EACR,QAAQ;AACV,CAAC;AAKD,eAAsB,UAAU,SAAqD;AACnF,QAAM,UAAU,IAAI;AAAA,IAAyB,CAAC,YAAY;AACxD,YAAM,IAAI,QAAQ,KAAK,MAAM,EAAE,SAAS,SAAS;AAAA,IAAA;AAAA,EAEnD;AAEM,QAAA,mBAAmB,KAAK,QAAQ,OAAO;AAEtC,SAAA;AACT;AAKA,eAAsB,WAAW,gBAAyE;;AACxG,QAAM,UAAU,MAAM,eAAe,QAAQ,MAAM,aAAa,cAAc;AAExE,QAAA,EAAE,YAAY;AAEhB,MAAA;AACO,6CAAA,WAAA,mBAAQ,UAAU,SAAS;AAAA,MAClC,GAAG;AAAA,MACH;AAAA,IAAA;AAGF,UAAM,CAAC,UAAU,UAAU,aAAa,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC5D,aAAQ,QAAQ,gBAAhB,mBAA6B,mBAAkB,SAC3C,gBAAgB,OAAO,IACvB,eAAe,OAAO;AAAA,MAC1B,gBAAgB,QAAQ,QAAQ,OAAO;AAAA,MACvC,OAAO,wBAAqB,EAAE,KAAK,CAAA,WAAU,OAAO,aAAa;AAAA,IAAA,CAClE;AAEM,WAAA,MAAM,qBAAqB,QAAQ;AAE1C,QAAI,CAAC,SAAS;AACN,YAAA,IAAI,MAAM,yBAAyB,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAEnF,UAAM,SAAS,cAAe,MAAM,SAAS,MAAkB;AACxD,WAAA,MAAM,aAAa,MAAM;AAEhC,QAAI,SAAS,SAAS;AACb,aAAA,KAAK,SAAS,SAAS,MAAM,IAAI,SAAS,WAAW,IAAI,YAAY,UAAU,kDAAkD,QAAQ;AAE5I,UAAA,kBAAkB,SAAS,IAAI,CAAC,EAAE,UAAU,GAAG,cAAc;AACjE,YAAM,YAAY,OAAO,KAAK,QAAM,GAAG,UAAU,QAAQ,KAAK;AAEtD,aAAA;AAAA,QACN,UAAU,IAAG,uCAAW,aAAY,QAAQ;AAAA,QAC5C,GAAG;AAAA,MACL;AAAA,IAAA,CACD;AAED,QAAI,gBAAgB,SAAS;AACnB,oBAAA,WAAA,mBAAQ,gBAAgB,SAAS;AAE3C,UAAM,eAAe,MAAM,QAAQ,MAAM,cAAc;AAAA,MACrD,GAAG,OAAO,OAAO,CAAA,OAAM,CAAC,SAAS,KAAK,CAAA,YAAW,QAAQ,UAAU,GAAG,KAAK,CAAC;AAAA,MAC5E,GAAG;AAAA,IAAA,CACJ;AAEO,kBAAA,WAAA,mBAAQ,iBAAiB,SAAS;AAEnC,WAAA;AAAA,WAEF,OAAO;AACL,WAAA,MAAM,OAAO,KAAK,CAAC;AACjB,6CAAA,WAAA,mBAAQ,aAAa,SAAS;AAEjC,UAAA;AAAA,EAAA;AAEV;"}
@@ -1 +1 @@
1
- {"version":3,"file":"requestAds.preview.js","sources":["../../src/requestAds/requestAds.preview.ts"],"sourcesContent":["import type { AdheseAd } from './requestAds.schema';\nimport { logger } from '../logger/logger';\n\n/**\n * Request preview ads for the given account. This function will only return items when there are preview objects in the\n * URL detected.\n */\nexport async function requestPreviews(account: string): Promise<ReadonlyArray<AdheseAd>> {\n const previewObjects = getPreviewObjects();\n\n const [list, adSchema] = await Promise.all([\n Promise.allSettled(previewObjects\n .filter(previewObject => 'adhesePreviewCreativeId' in previewObject)\n .map(async (previewObject) => {\n const endpoint = new URL(`https://${account}-preview.adhese.org/creatives/preview/json/tag.do`);\n endpoint.searchParams.set(\n 'id',\n previewObject.adhesePreviewCreativeId,\n );\n\n const response = await fetch(endpoint.href, {\n method: 'GET',\n headers: {\n accept: 'application/json',\n },\n });\n\n if (!response.ok)\n return Promise.reject(new Error(`Failed to request preview ad with ID: ${previewObject.adhesePreviewCreativeId}`));\n\n return await response.json() as unknown;\n })),\n import('./requestAds.schema').then(module => module.adSchema),\n ]);\n\n return adSchema.array().parse(list\n .filter((response): response is PromiseFulfilledResult<ReadonlyArray<Record<string, unknown>>> => {\n if (response.status === 'rejected') {\n logger.error(response.reason as string);\n return false;\n }\n return response.status === 'fulfilled';\n })\n .flatMap(response => response.value.map(item => ({\n ...item,\n preview: true,\n })))) as ReadonlyArray<AdheseAd>;\n}\n\nfunction getPreviewObjects(): ReadonlyArray<Record<string, string>> {\n const currentUrl = new URL(window.location.href);\n\n const previewObjects: Array<Record<string, string>> = [];\n let currentObject: Record<string, string> = {};\n\n for (const [key, value] of currentUrl.searchParams.entries()) {\n if (key === 'adhesePreviewCreativeId' && Object.keys(currentObject).length > 0) {\n previewObjects.push(currentObject);\n currentObject = {};\n }\n\n currentObject[key] = value;\n }\n\n if (Object.keys(currentObject).length > 0)\n previewObjects.push(currentObject);\n\n return previewObjects;\n}\n"],"names":[],"mappings":";AAOA,eAAsB,gBAAgB,SAAmD;AACvF,QAAM,iBAAiB;AAEvB,QAAM,CAAC,MAAM,QAAQ,IAAI,MAAM,QAAQ,IAAI;AAAA,IACzC,QAAQ,WAAW,eAChB,OAAO,CAAA,kBAAiB,6BAA6B,aAAa,EAClE,IAAI,OAAO,kBAAkB;AAC5B,YAAM,WAAW,IAAI,IAAI,WAAW,OAAO,mDAAmD;AAC9F,eAAS,aAAa;AAAA,QACpB;AAAA,QACA,cAAc;AAAA,MAAA;AAGhB,YAAM,WAAW,MAAM,MAAM,SAAS,MAAM;AAAA,QAC1C,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,QAAQ;AAAA,QACV;AAAA,MAAA,CACD;AAED,UAAI,CAAC,SAAS;AACL,eAAA,QAAQ,OAAO,IAAI,MAAM,yCAAyC,cAAc,uBAAuB,EAAE,CAAC;AAE5G,aAAA,MAAM,SAAS;IAAK,CAC5B,CAAC;AAAA,IACJ,OAAO,wBAAqB,EAAE,KAAK,CAAA,WAAU,OAAO,QAAQ;AAAA,EAAA,CAC7D;AAED,SAAO,SAAS,QAAQ,MAAM,KAC3B,OAAO,CAAC,aAAyF;AAC5F,QAAA,SAAS,WAAW,YAAY;AAC3B,aAAA,MAAM,SAAS,MAAgB;AAC/B,aAAA;AAAA,IACT;AACA,WAAO,SAAS,WAAW;AAAA,EAAA,CAC5B,EACA,QAAQ,cAAY,SAAS,MAAM,IAAI,CAAS,UAAA;AAAA,IAC/C,GAAG;AAAA,IACH,SAAS;AAAA,EAAA,EACT,CAAC,CAAC;AACR;AAEA,SAAS,oBAA2D;AAClE,QAAM,aAAa,IAAI,IAAI,OAAO,SAAS,IAAI;AAE/C,QAAM,iBAAgD,CAAA;AACtD,MAAI,gBAAwC,CAAA;AAE5C,aAAW,CAAC,KAAK,KAAK,KAAK,WAAW,aAAa,WAAW;AAC5D,QAAI,QAAQ,6BAA6B,OAAO,KAAK,aAAa,EAAE,SAAS,GAAG;AAC9E,qBAAe,KAAK,aAAa;AACjC,sBAAgB,CAAA;AAAA,IAClB;AAEA,kBAAc,GAAG,IAAI;AAAA,EACvB;AAEA,MAAI,OAAO,KAAK,aAAa,EAAE,SAAS;AACtC,mBAAe,KAAK,aAAa;AAE5B,SAAA;AACT;"}
1
+ {"version":3,"file":"requestAds.preview.js","sources":["../../src/requestAds/requestAds.preview.ts"],"sourcesContent":["import type { AdheseAd } from './requestAds.schema';\nimport { logger } from '../logger/logger';\n\n/**\n * Request preview ads for the given account. This function will only return items when there are preview objects in the\n * URL detected.\n */\nexport async function requestPreviews(account: string): Promise<ReadonlyArray<AdheseAd>> {\n const previewObjects = getPreviewObjects();\n\n const [list, adSchema] = await Promise.all([\n Promise.allSettled(previewObjects\n .filter(previewObject => 'adhesePreviewCreativeId' in previewObject)\n .map(async (previewObject) => {\n const endpoint = new URL(`https://${account}-preview.adhese.org/creatives/preview/json/tag.do`);\n endpoint.searchParams.set(\n 'id',\n previewObject.adhesePreviewCreativeId,\n );\n\n const response = await fetch(endpoint.href, {\n method: 'GET',\n headers: {\n accept: 'application/json',\n },\n });\n\n if (!response.ok)\n return Promise.reject(new Error(`Failed to request preview ad with ID: ${previewObject.adhesePreviewCreativeId}`));\n\n return await response.json() as unknown;\n })),\n import('./requestAds.schema').then(module => module.adSchema),\n ]);\n\n return adSchema.array().parse(list\n .filter((response): response is PromiseFulfilledResult<ReadonlyArray<Record<string, unknown>>> => {\n if (response.status === 'rejected') {\n logger.error(response.reason as string);\n return false;\n }\n return response.status === 'fulfilled';\n })\n .flatMap(response => response.value.map(item => ({\n ...item,\n preview: true,\n })))) as ReadonlyArray<AdheseAd>;\n}\n\nfunction getPreviewObjects(): ReadonlyArray<Record<string, string>> {\n const currentUrl = new URL(window.location.href);\n\n const previewObjects: Array<Record<string, string>> = [];\n let currentObject: Record<string, string> = {};\n\n for (const [key, value] of currentUrl.searchParams.entries()) {\n if (key === 'adhesePreviewCreativeId' && Object.keys(currentObject).length > 0) {\n previewObjects.push(currentObject);\n currentObject = {};\n }\n\n currentObject[key] = value;\n }\n\n if (Object.keys(currentObject).length > 0)\n previewObjects.push(currentObject);\n\n return previewObjects;\n}\n"],"names":[],"mappings":";AAOA,eAAsB,gBAAgB,SAAmD;AACvF,QAAM,iBAAiB,kBAAkB;AAEzC,QAAM,CAAC,MAAM,QAAQ,IAAI,MAAM,QAAQ,IAAI;AAAA,IACzC,QAAQ,WAAW,eAChB,OAAO,CAAA,kBAAiB,6BAA6B,aAAa,EAClE,IAAI,OAAO,kBAAkB;AAC5B,YAAM,WAAW,IAAI,IAAI,WAAW,OAAO,mDAAmD;AAC9F,eAAS,aAAa;AAAA,QACpB;AAAA,QACA,cAAc;AAAA,MAChB;AAEA,YAAM,WAAW,MAAM,MAAM,SAAS,MAAM;AAAA,QAC1C,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,QAAQ;AAAA,QAAA;AAAA,MACV,CACD;AAED,UAAI,CAAC,SAAS;AACL,eAAA,QAAQ,OAAO,IAAI,MAAM,yCAAyC,cAAc,uBAAuB,EAAE,CAAC;AAE5G,aAAA,MAAM,SAAS,KAAK;AAAA,IAAA,CAC5B,CAAC;AAAA,IACJ,OAAO,wBAAqB,EAAE,KAAK,CAAA,WAAU,OAAO,QAAQ;AAAA,EAAA,CAC7D;AAED,SAAO,SAAS,QAAQ,MAAM,KAC3B,OAAO,CAAC,aAAyF;AAC5F,QAAA,SAAS,WAAW,YAAY;AAC3B,aAAA,MAAM,SAAS,MAAgB;AAC/B,aAAA;AAAA,IAAA;AAET,WAAO,SAAS,WAAW;AAAA,EAAA,CAC5B,EACA,QAAQ,cAAY,SAAS,MAAM,IAAI,CAAS,UAAA;AAAA,IAC/C,GAAG;AAAA,IACH,SAAS;AAAA,EACX,EAAE,CAAC,CAAC;AACR;AAEA,SAAS,oBAA2D;AAClE,QAAM,aAAa,IAAI,IAAI,OAAO,SAAS,IAAI;AAE/C,QAAM,iBAAgD,CAAC;AACvD,MAAI,gBAAwC,CAAC;AAE7C,aAAW,CAAC,KAAK,KAAK,KAAK,WAAW,aAAa,WAAW;AAC5D,QAAI,QAAQ,6BAA6B,OAAO,KAAK,aAAa,EAAE,SAAS,GAAG;AAC9E,qBAAe,KAAK,aAAa;AACjC,sBAAgB,CAAC;AAAA,IAAA;AAGnB,kBAAc,GAAG,IAAI;AAAA,EAAA;AAGvB,MAAI,OAAO,KAAK,aAAa,EAAE,SAAS;AACtC,mBAAe,KAAK,aAAa;AAE5B,SAAA;AACT;"}
@@ -1 +1 @@
1
- {"version":3,"file":"requestAds.schema.js","sources":["../../src/requestAds/requestAds.schema.ts"],"sourcesContent":["import {\n booleanLike,\n cssValueLike,\n dateLike,\n isJsonOrHtmlOptionalString,\n isJsonOrHtmlString,\n lazy,\n literal,\n numberLike,\n object,\n string,\n type TypeOf,\n union,\n unknown,\n urlLike,\n type ZodType,\n} from '@adhese/sdk-shared/validators';\n\nconst baseSchema = object({\n adDuration: numberLike.optional(),\n adFormat: string().optional(),\n adType: string(),\n additionalCreativeTracker: urlLike.optional(),\n additionalViewableTracker: string().optional(),\n adspaceEnd: dateLike.optional(),\n adspaceId: string().optional(),\n adspaceKey: string().optional(),\n adspaceStart: dateLike.optional(),\n advertiserId: string().optional(),\n altText: string().optional(),\n auctionable: booleanLike.optional(),\n body: isJsonOrHtmlOptionalString,\n clickTag: urlLike.optional(),\n comment: string().optional(),\n creativeName: string().optional(),\n deliveryGroupId: string().optional(),\n deliveryMultiples: string().optional(),\n ext: string().optional(),\n extension: object({\n mediaType: string(),\n prebid: unknown().optional(),\n }).optional(),\n height: numberLike.optional(),\n id: string().optional(),\n impressionCounter: urlLike.optional(),\n libId: string().optional(),\n orderId: string().optional(),\n orderName: string().optional(),\n orderProperty: string().optional(),\n origin: union([literal('JERLICIA'), literal('DALE')]),\n originData: unknown().optional(),\n originInstance: string().optional(),\n poolPath: urlLike.optional(),\n preview: booleanLike.optional(),\n priority: numberLike.optional(),\n sfSrc: urlLike.optional(),\n share: string().optional(),\n // eslint-disable-next-line ts/naming-convention\n slotID: string(),\n slotName: string(),\n swfSrc: urlLike.optional(),\n tag: isJsonOrHtmlOptionalString,\n tagUrl: urlLike.optional(),\n timeStamp: dateLike.optional(),\n trackedImpressionCounter: urlLike.optional(),\n tracker: urlLike.optional(),\n trackingUrl: urlLike.optional(),\n url: urlLike.optional(),\n viewableImpressionCounter: urlLike.optional(),\n width: numberLike.optional(),\n widthLarge: cssValueLike.optional(),\n});\n\nexport const jerliciaSchema = object({\n origin: literal('JERLICIA'),\n tag: isJsonOrHtmlString,\n}).passthrough();\n\nexport const daleSchema = object({\n origin: literal('DALE'),\n body: isJsonOrHtmlString,\n}).passthrough().transform(({ body, ...data }) => ({\n ...data,\n tag: body,\n}));\n\nexport type AdResponse = (TypeOf<typeof baseSchema> & {\n additionalCreatives?: ReadonlyArray<AdResponse> | string;\n});\n\nconst adResponseSchema: ZodType<AdResponse> = baseSchema.extend({\n additionalCreatives: lazy(() => union([adResponseSchema.array(), string()]).optional()),\n}) as ZodType<AdResponse>;\n\nexport type PreParsedAd = TypeOf<typeof adResponseSchema> & {\n additionalCreatives?: ReadonlyArray<PreParsedAd> | string;\n};\n\nexport type AdheseAd<T = string | Record<string, unknown> | ReadonlyArray<unknown>> = Omit<PreParsedAd, 'tag'> & {\n tag: T | string;\n};\n\nexport const adSchema: ZodType<PreParsedAd> = adResponseSchema.transform(({\n additionalCreatives,\n ...data\n}) => {\n const filteredValue = Object.fromEntries(\n Object.entries(data)\n .filter(([, value]) =>\n Boolean(value)\n && JSON.stringify(value) !== '{}'\n && JSON.stringify(value) !== '[]'),\n ) as typeof data;\n\n return ({\n ...filteredValue,\n additionalCreatives: Array.isArray(additionalCreatives) ? additionalCreatives.map(creative => adSchema.parse(creative)) : additionalCreatives,\n });\n});\n\nexport function parseResponse(response: unknown): ReadonlyArray<AdheseAd> {\n const schemaMap = {\n /* eslint-disable ts/naming-convention */\n JERLICIA: jerliciaSchema,\n DALE: daleSchema,\n /* eslint-enable ts/naming-convention */\n };\n\n const preParsed = adResponseSchema.array().parse(response);\n\n return preParsed.map((item) => {\n const schema = schemaMap[item.origin];\n\n if (!schema)\n return adSchema.parse(item);\n\n return schema.parse(item);\n }) as ReadonlyArray<AdheseAd>;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"requestAds.schema.js","sources":["../../src/requestAds/requestAds.schema.ts"],"sourcesContent":["import {\n booleanLike,\n cssValueLike,\n dateLike,\n isJsonOrHtmlOptionalString,\n isJsonOrHtmlString,\n lazy,\n literal,\n numberLike,\n object,\n string,\n type TypeOf,\n union,\n unknown,\n urlLike,\n type ZodType,\n} from '@adhese/sdk-shared/validators';\n\nconst baseSchema = object({\n adDuration: numberLike.optional(),\n adFormat: string().optional(),\n adType: string(),\n additionalCreativeTracker: urlLike.optional(),\n additionalViewableTracker: string().optional(),\n adspaceEnd: dateLike.optional(),\n adspaceId: string().optional(),\n adspaceKey: string().optional(),\n adspaceStart: dateLike.optional(),\n advertiserId: string().optional(),\n altText: string().optional(),\n auctionable: booleanLike.optional(),\n body: isJsonOrHtmlOptionalString,\n clickTag: urlLike.optional(),\n comment: string().optional(),\n creativeName: string().optional(),\n deliveryGroupId: string().optional(),\n deliveryMultiples: string().optional(),\n ext: string().optional(),\n extension: object({\n mediaType: string(),\n prebid: unknown().optional(),\n }).optional(),\n height: numberLike.optional(),\n id: string().optional(),\n impressionCounter: urlLike.optional(),\n libId: string().optional(),\n orderId: string().optional(),\n orderName: string().optional(),\n orderProperty: string().optional(),\n origin: union([literal('JERLICIA'), literal('DALE')]),\n originData: unknown().optional(),\n originInstance: string().optional(),\n poolPath: urlLike.optional(),\n preview: booleanLike.optional(),\n priority: numberLike.optional(),\n sfSrc: urlLike.optional(),\n share: string().optional(),\n // eslint-disable-next-line ts/naming-convention\n slotID: string(),\n slotName: string(),\n swfSrc: urlLike.optional(),\n tag: isJsonOrHtmlOptionalString,\n tagUrl: urlLike.optional(),\n timeStamp: dateLike.optional(),\n trackedImpressionCounter: urlLike.optional(),\n tracker: urlLike.optional(),\n trackingUrl: urlLike.optional(),\n url: urlLike.optional(),\n viewableImpressionCounter: urlLike.optional(),\n width: numberLike.optional(),\n widthLarge: cssValueLike.optional(),\n});\n\nexport const jerliciaSchema = object({\n origin: literal('JERLICIA'),\n tag: isJsonOrHtmlString,\n}).passthrough();\n\nexport const daleSchema = object({\n origin: literal('DALE'),\n body: isJsonOrHtmlString,\n}).passthrough().transform(({ body, ...data }) => ({\n ...data,\n tag: body,\n}));\n\nexport type AdResponse = (TypeOf<typeof baseSchema> & {\n additionalCreatives?: ReadonlyArray<AdResponse> | string;\n});\n\nconst adResponseSchema: ZodType<AdResponse> = baseSchema.extend({\n additionalCreatives: lazy(() => union([adResponseSchema.array(), string()]).optional()),\n}) as ZodType<AdResponse>;\n\nexport type PreParsedAd = TypeOf<typeof adResponseSchema> & {\n additionalCreatives?: ReadonlyArray<PreParsedAd> | string;\n};\n\nexport type AdheseAd<T = string | Record<string, unknown> | ReadonlyArray<unknown>> = Omit<PreParsedAd, 'tag'> & {\n tag: T | string;\n};\n\nexport const adSchema: ZodType<PreParsedAd> = adResponseSchema.transform(({\n additionalCreatives,\n ...data\n}) => {\n const filteredValue = Object.fromEntries(\n Object.entries(data)\n .filter(([, value]) =>\n Boolean(value)\n && JSON.stringify(value) !== '{}'\n && JSON.stringify(value) !== '[]'),\n ) as typeof data;\n\n return ({\n ...filteredValue,\n additionalCreatives: Array.isArray(additionalCreatives) ? additionalCreatives.map(creative => adSchema.parse(creative)) : additionalCreatives,\n });\n});\n\nexport function parseResponse(response: unknown): ReadonlyArray<AdheseAd> {\n const schemaMap = {\n /* eslint-disable ts/naming-convention */\n JERLICIA: jerliciaSchema,\n DALE: daleSchema,\n /* eslint-enable ts/naming-convention */\n };\n\n const preParsed = adResponseSchema.array().parse(response);\n\n return preParsed.map((item) => {\n const schema = schemaMap[item.origin];\n\n if (!schema)\n return adSchema.parse(item);\n\n return schema.parse(item);\n }) as ReadonlyArray<AdheseAd>;\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"requestAds.utils.js","sources":["../../src/requestAds/requestAds.utils.ts"],"sourcesContent":["import type { AdMultiRequestOptions } from './requestAds';\nimport { toValue } from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\n\ntype AdPostPayload = {\n slots: ReadonlyArray<{\n slotname: string;\n parameters?: Record<string, ReadonlyArray<string> | string>;\n }>;\n parameters?: Record<string, ReadonlyArray<string> | string>;\n};\n\nexport async function requestWithPost({\n context,\n ...options\n}: Omit<AdMultiRequestOptions, 'method'>): Promise<Response> {\n const payload = {\n ...options,\n slots: options.slots.map(slot => ({\n slotname: slot.name,\n parameters: parseParameters(slot.parameters),\n })),\n parameters: context.parameters && parseParameters(context.parameters),\n } satisfies AdPostPayload;\n\n return fetch(`${new URL(context.options.host).href}json`, {\n method: 'POST',\n body: JSON.stringify(payload),\n headers: {\n // eslint-disable-next-line ts/naming-convention\n 'Content-Type': 'application/json',\n },\n });\n}\n\nexport async function requestWithGet({ context, slots }: Omit<AdMultiRequestOptions, 'method'>): Promise<Response> {\n return fetch(new URL(`${context.options.host}/json/sl${slots.map(slot => toValue(slot.name)).join('/sl')}`), {\n method: 'GET',\n headers: {\n // eslint-disable-next-line ts/naming-convention\n 'Content-Type': 'application/json',\n },\n });\n}\n\nexport function parseParameters<T extends string | ReadonlyArray<string>>(parameters: Map<string, T>): Record<string, T> {\n return Object.fromEntries(Array.from(parameters.entries()).filter(([key]) => {\n if (key.length === 2)\n return true;\n\n logger.warn(`Invalid parameter key: ${key}. Key should be exactly 2 characters long. Key will be ignored.`);\n return false;\n }).map(([key, value]): [string, T] => {\n if (typeof value === 'string')\n return [key, filterSpecialChars(value) as T];\n\n return [key, value.map(filterSpecialChars) as unknown as T];\n }));\n}\n\nfunction filterSpecialChars(value: string): string {\n const specialRegex = /[^\\p{L}\\p{N}_]/gu;\n\n return value.replaceAll(specialRegex, '_');\n}\n"],"names":[],"mappings":";;AAYA,eAAsB,gBAAgB;AAAA,EACpC;AAAA,EACA,GAAG;AACL,GAA6D;AAC3D,QAAM,UAAU;AAAA,IACd,GAAG;AAAA,IACH,OAAO,QAAQ,MAAM,IAAI,CAAS,UAAA;AAAA,MAChC,UAAU,KAAK;AAAA,MACf,YAAY,gBAAgB,KAAK,UAAU;AAAA,IAAA,EAC3C;AAAA,IACF,YAAY,QAAQ,cAAc,gBAAgB,QAAQ,UAAU;AAAA,EAAA;AAG/D,SAAA,MAAM,GAAG,IAAI,IAAI,QAAQ,QAAQ,IAAI,EAAE,IAAI,QAAQ;AAAA,IACxD,QAAQ;AAAA,IACR,MAAM,KAAK,UAAU,OAAO;AAAA,IAC5B,SAAS;AAAA;AAAA,MAEP,gBAAgB;AAAA,IAClB;AAAA,EAAA,CACD;AACH;AAEA,eAAsB,eAAe,EAAE,SAAS,SAAmE;AAC1G,SAAA,MAAM,IAAI,IAAI,GAAG,QAAQ,QAAQ,IAAI,WAAW,MAAM,IAAI,UAAQ,QAAQ,KAAK,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,GAAG;AAAA,IAC3G,QAAQ;AAAA,IACR,SAAS;AAAA;AAAA,MAEP,gBAAgB;AAAA,IAClB;AAAA,EAAA,CACD;AACH;AAEO,SAAS,gBAA0D,YAA+C;AACvH,SAAO,OAAO,YAAY,MAAM,KAAK,WAAW,QAAA,CAAS,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM;AAC3E,QAAI,IAAI,WAAW;AACV,aAAA;AAEF,WAAA,KAAK,0BAA0B,GAAG,iEAAiE;AACnG,WAAA;AAAA,EACR,CAAA,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAmB;AACpC,QAAI,OAAO,UAAU;AACnB,aAAO,CAAC,KAAK,mBAAmB,KAAK,CAAM;AAE7C,WAAO,CAAC,KAAK,MAAM,IAAI,kBAAkB,CAAiB;AAAA,EAC3D,CAAA,CAAC;AACJ;AAEA,SAAS,mBAAmB,OAAuB;AACjD,QAAM,eAAe;AAEd,SAAA,MAAM,WAAW,cAAc,GAAG;AAC3C;"}
1
+ {"version":3,"file":"requestAds.utils.js","sources":["../../src/requestAds/requestAds.utils.ts"],"sourcesContent":["import type { AdMultiRequestOptions } from './requestAds';\nimport { toValue } from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\n\ntype AdPostPayload = {\n slots: ReadonlyArray<{\n slotname: string;\n parameters?: Record<string, ReadonlyArray<string> | string>;\n }>;\n parameters?: Record<string, ReadonlyArray<string> | string>;\n};\n\nexport async function requestWithPost({\n context,\n ...options\n}: Omit<AdMultiRequestOptions, 'method'>): Promise<Response> {\n const payload = {\n ...options,\n slots: options.slots.map(slot => ({\n slotname: slot.name,\n parameters: parseParameters(slot.parameters),\n })),\n parameters: context.parameters && parseParameters(context.parameters),\n } satisfies AdPostPayload;\n\n return fetch(`${new URL(context.options.host).href}json`, {\n method: 'POST',\n body: JSON.stringify(payload),\n headers: {\n // eslint-disable-next-line ts/naming-convention\n 'Content-Type': 'application/json',\n },\n });\n}\n\nexport async function requestWithGet({ context, slots }: Omit<AdMultiRequestOptions, 'method'>): Promise<Response> {\n return fetch(new URL(`${context.options.host}/json/sl${slots.map(slot => toValue(slot.name)).join('/sl')}`), {\n method: 'GET',\n headers: {\n // eslint-disable-next-line ts/naming-convention\n 'Content-Type': 'application/json',\n },\n });\n}\n\nexport function parseParameters<T extends string | ReadonlyArray<string>>(parameters: Map<string, T>): Record<string, T> {\n return Object.fromEntries(Array.from(parameters.entries()).filter(([key]) => {\n if (key.length === 2)\n return true;\n\n logger.warn(`Invalid parameter key: ${key}. Key should be exactly 2 characters long. Key will be ignored.`);\n return false;\n }).map(([key, value]): [string, T] => {\n if (typeof value === 'string')\n return [key, filterSpecialChars(value) as T];\n\n return [key, value.map(filterSpecialChars) as unknown as T];\n }));\n}\n\nfunction filterSpecialChars(value: string): string {\n const specialRegex = /[^\\p{L}\\p{N}_]/gu;\n\n return value.replaceAll(specialRegex, '_');\n}\n"],"names":[],"mappings":";;AAYA,eAAsB,gBAAgB;AAAA,EACpC;AAAA,EACA,GAAG;AACL,GAA6D;AAC3D,QAAM,UAAU;AAAA,IACd,GAAG;AAAA,IACH,OAAO,QAAQ,MAAM,IAAI,CAAS,UAAA;AAAA,MAChC,UAAU,KAAK;AAAA,MACf,YAAY,gBAAgB,KAAK,UAAU;AAAA,IAAA,EAC3C;AAAA,IACF,YAAY,QAAQ,cAAc,gBAAgB,QAAQ,UAAU;AAAA,EACtE;AAEO,SAAA,MAAM,GAAG,IAAI,IAAI,QAAQ,QAAQ,IAAI,EAAE,IAAI,QAAQ;AAAA,IACxD,QAAQ;AAAA,IACR,MAAM,KAAK,UAAU,OAAO;AAAA,IAC5B,SAAS;AAAA;AAAA,MAEP,gBAAgB;AAAA,IAAA;AAAA,EAClB,CACD;AACH;AAEA,eAAsB,eAAe,EAAE,SAAS,SAAmE;AAC1G,SAAA,MAAM,IAAI,IAAI,GAAG,QAAQ,QAAQ,IAAI,WAAW,MAAM,IAAI,UAAQ,QAAQ,KAAK,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,GAAG;AAAA,IAC3G,QAAQ;AAAA,IACR,SAAS;AAAA;AAAA,MAEP,gBAAgB;AAAA,IAAA;AAAA,EAClB,CACD;AACH;AAEO,SAAS,gBAA0D,YAA+C;AACvH,SAAO,OAAO,YAAY,MAAM,KAAK,WAAW,QAAA,CAAS,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM;AAC3E,QAAI,IAAI,WAAW;AACV,aAAA;AAEF,WAAA,KAAK,0BAA0B,GAAG,iEAAiE;AACnG,WAAA;AAAA,EACR,CAAA,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAmB;AACpC,QAAI,OAAO,UAAU;AACnB,aAAO,CAAC,KAAK,mBAAmB,KAAK,CAAM;AAE7C,WAAO,CAAC,KAAK,MAAM,IAAI,kBAAkB,CAAiB;AAAA,EAAA,CAC3D,CAAC;AACJ;AAEA,SAAS,mBAAmB,OAAuB;AACjD,QAAM,eAAe;AAEd,SAAA,MAAM,WAAW,cAAc,GAAG;AAC3C;"}
@@ -1 +1 @@
1
- {"version":3,"file":"slot.composables.js","sources":["../../src/slot/slot.composables.ts"],"sourcesContent":["import type { AdheseAd, AdheseContext, AdheseSlot, AdheseSlotContext, AdheseSlotHooks, AdheseSlotOptions } from '@adhese/sdk';\nimport {\n createAsyncHook,\n createPassiveHook,\n type Ref,\n ref,\n round,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\n\nexport function useDomLoaded(context: AdheseContext): Readonly<Ref<boolean>> {\n const isDomLoaded = ref(false);\n\n context.hooks.onInit(async () => {\n await waitForDomLoad();\n\n isDomLoaded.value = true;\n });\n return isDomLoaded;\n}\n\nexport function useRenderIntersectionObserver({ options, element, hooks }: {\n options: AdheseSlotOptions;\n element: Ref<HTMLElement | null>;\n hooks: AdheseSlotHooks;\n}): Ref<boolean> {\n const isInViewport = ref(false);\n\n const renderIntersectionObserver = new IntersectionObserver((entries) => {\n isInViewport.value = entries.some(entry => entry.isIntersecting);\n }, {\n rootMargin: options.lazyLoadingOptions?.rootMargin ?? '200px',\n threshold: 0,\n });\n\n function observe(newElement: HTMLElement | null, oldElement?: HTMLElement | null): () => void {\n if (oldElement)\n renderIntersectionObserver.unobserve(oldElement);\n\n if (newElement)\n renderIntersectionObserver.observe(newElement);\n\n return () => {\n if (newElement)\n renderIntersectionObserver.unobserve(newElement);\n };\n }\n\n watch(element, observe);\n observe(element.value);\n\n hooks.onDispose(() => {\n renderIntersectionObserver.disconnect();\n });\n\n return isInViewport;\n}\n\nexport function useViewabilityObserver(\n { context, slotContext, hooks, onTracked }: {\n context: AdheseContext;\n slotContext: Ref<AdheseSlot | null>;\n hooks: AdheseSlotHooks;\n onTracked?(trackingPixel: Ref<HTMLImageElement | null>): void;\n },\n): Ref<boolean> {\n let timeoutId: number | null = null;\n const {\n threshold,\n duration,\n rootMargin,\n } = {\n threshold: 0.2,\n duration: 1000,\n rootMargin: '0px',\n ...context.options.viewabilityTrackingOptions,\n } satisfies Required<typeof context.options.viewabilityTrackingOptions>;\n\n const trackingPixel = ref<HTMLImageElement | null>(null);\n\n const isTracked = ref(false);\n\n const viewabilityObserver = new IntersectionObserver(([entry]) => {\n if (context.options.viewabilityTracking && !trackingPixel.value) {\n const ratio = round(entry.intersectionRatio, 1);\n\n if (ratio >= threshold && !timeoutId) {\n // @ts-expect-error The is misfiring to the Node type\n timeoutId = setTimeout(() => {\n timeoutId = null;\n\n onTracked?.(trackingPixel);\n\n isTracked.value = true;\n }, duration);\n }\n else if (ratio < threshold && timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n }\n }, {\n rootMargin,\n threshold: Array.from({ length: 11 }, (_, i) => i * 0.1),\n });\n\n function observe(newElement: HTMLElement | null, oldElement?: HTMLElement | null): () => void {\n if (oldElement)\n viewabilityObserver.unobserve(oldElement);\n\n if (newElement && context.options.viewabilityTracking)\n viewabilityObserver.observe(newElement);\n\n return () => {\n if (newElement)\n viewabilityObserver.unobserve(newElement);\n };\n }\n\n watch(() => slotContext.value?.element, (element) => {\n if (element)\n observe(element);\n }, { immediate: true });\n\n watch(slotContext, (slot) => {\n if (slot?.element)\n viewabilityObserver.observe(slot.element);\n }, { once: true });\n\n hooks.onDispose(() => {\n trackingPixel.value?.remove();\n viewabilityObserver.disconnect();\n });\n\n watch(() => slotContext.value?.status, async (newStatus, oldStatus) => {\n if (newStatus === 'loaded' && oldStatus === 'rendered') {\n trackingPixel.value?.remove();\n trackingPixel.value = null;\n }\n });\n\n return isTracked;\n}\n\nexport function useSlotHooks({ setup }: AdheseSlotOptions, slotContext: Ref<AdheseSlotContext | null>): {\n runOnBeforeRender: ReturnType<typeof createAsyncHook<AdheseAd>>[0];\n runOnRender: ReturnType<typeof createPassiveHook<AdheseAd>>[0];\n runOnBeforeRequest: ReturnType<typeof createAsyncHook<AdheseAd | null>>[0];\n runOnRequest: ReturnType<typeof createAsyncHook<AdheseAd>>[0];\n runOnInit: ReturnType<typeof createAsyncHook<void>>[0];\n runOnDispose: ReturnType<typeof createPassiveHook<void>>[0];\n runOnEmpty: ReturnType<typeof createPassiveHook<void>>[0];\n runOnError: ReturnType<typeof createPassiveHook<Error>>[0];\n} & AdheseSlotHooks {\n const [runOnBeforeRender, onBeforeRender, disposeOnBeforeRender] = createAsyncHook<AdheseAd>();\n const [runOnRender, onRender, disposeOnRender] = createPassiveHook<AdheseAd>();\n const [runOnBeforeRequest, onBeforeRequest, disposeOnBeforeRequest] = createAsyncHook<AdheseAd | null>();\n const [runOnRequest, onRequest, disposeOnRequest] = createAsyncHook<AdheseAd>();\n const [runOnInit, onInit, disposeOnInit] = createAsyncHook();\n const [runOnDispose, onDispose, disposeOnDispose] = createPassiveHook();\n const [runOnEmpty, onEmpty, disposeOnEmpty] = createPassiveHook();\n const [runOnError, onError, disposeOnError] = createPassiveHook<Error>();\n\n setup?.(slotContext, {\n onBeforeRender,\n onRender,\n onBeforeRequest,\n onDispose,\n onRequest,\n onInit,\n onEmpty,\n onError,\n });\n\n onDispose(() => {\n disposeOnBeforeRender();\n disposeOnRender();\n disposeOnBeforeRequest();\n disposeOnRequest();\n disposeOnInit();\n disposeOnDispose();\n disposeOnEmpty();\n disposeOnError();\n });\n\n return { runOnBeforeRender, runOnRender, runOnBeforeRequest, runOnRequest, runOnDispose, onDispose, onBeforeRequest, onRequest, onBeforeRender, onRender, onInit, runOnInit, runOnEmpty, onEmpty, runOnError, onError };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"slot.composables.js","sources":["../../src/slot/slot.composables.ts"],"sourcesContent":["import type { AdheseAd, AdheseContext, AdheseSlot, AdheseSlotContext, AdheseSlotHooks, AdheseSlotOptions } from '@adhese/sdk';\nimport {\n createAsyncHook,\n createPassiveHook,\n type Ref,\n ref,\n round,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\n\nexport function useDomLoaded(context: AdheseContext): Readonly<Ref<boolean>> {\n const isDomLoaded = ref(false);\n\n context.hooks.onInit(async () => {\n await waitForDomLoad();\n\n isDomLoaded.value = true;\n });\n return isDomLoaded;\n}\n\nexport function useRenderIntersectionObserver({ options, element, hooks }: {\n options: AdheseSlotOptions;\n element: Ref<HTMLElement | null>;\n hooks: AdheseSlotHooks;\n}): Ref<boolean> {\n const isInViewport = ref(false);\n\n const renderIntersectionObserver = new IntersectionObserver((entries) => {\n isInViewport.value = entries.some(entry => entry.isIntersecting);\n }, {\n rootMargin: options.lazyLoadingOptions?.rootMargin ?? '200px',\n threshold: 0,\n });\n\n function observe(newElement: HTMLElement | null, oldElement?: HTMLElement | null): () => void {\n if (oldElement)\n renderIntersectionObserver.unobserve(oldElement);\n\n if (newElement)\n renderIntersectionObserver.observe(newElement);\n\n return () => {\n if (newElement)\n renderIntersectionObserver.unobserve(newElement);\n };\n }\n\n watch(element, observe);\n observe(element.value);\n\n hooks.onDispose(() => {\n renderIntersectionObserver.disconnect();\n });\n\n return isInViewport;\n}\n\nexport function useViewabilityObserver(\n { context, slotContext, hooks, onTracked }: {\n context: AdheseContext;\n slotContext: Ref<AdheseSlot | null>;\n hooks: AdheseSlotHooks;\n onTracked?(trackingPixel: Ref<HTMLImageElement | null>): void;\n },\n): Ref<boolean> {\n let timeoutId: number | null = null;\n const {\n threshold,\n duration,\n rootMargin,\n } = {\n threshold: 0.2,\n duration: 1000,\n rootMargin: '0px',\n ...context.options.viewabilityTrackingOptions,\n } satisfies Required<typeof context.options.viewabilityTrackingOptions>;\n\n const trackingPixel = ref<HTMLImageElement | null>(null);\n\n const isTracked = ref(false);\n\n const viewabilityObserver = new IntersectionObserver(([entry]) => {\n if (context.options.viewabilityTracking && !trackingPixel.value) {\n const ratio = round(entry.intersectionRatio, 1);\n\n if (ratio >= threshold && !timeoutId) {\n // @ts-expect-error The is misfiring to the Node type\n timeoutId = setTimeout(() => {\n timeoutId = null;\n\n onTracked?.(trackingPixel);\n\n isTracked.value = true;\n }, duration);\n }\n else if (ratio < threshold && timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n }\n }, {\n rootMargin,\n threshold: Array.from({ length: 11 }, (_, i) => i * 0.1),\n });\n\n function observe(newElement: HTMLElement | null, oldElement?: HTMLElement | null): () => void {\n if (oldElement)\n viewabilityObserver.unobserve(oldElement);\n\n if (newElement && context.options.viewabilityTracking)\n viewabilityObserver.observe(newElement);\n\n return () => {\n if (newElement)\n viewabilityObserver.unobserve(newElement);\n };\n }\n\n watch(() => slotContext.value?.element, (element) => {\n if (element)\n observe(element);\n }, { immediate: true });\n\n watch(slotContext, (slot) => {\n if (slot?.element)\n viewabilityObserver.observe(slot.element);\n }, { once: true });\n\n hooks.onDispose(() => {\n trackingPixel.value?.remove();\n viewabilityObserver.disconnect();\n });\n\n watch(() => slotContext.value?.status, async (newStatus, oldStatus) => {\n if (newStatus === 'loaded' && oldStatus === 'rendered') {\n trackingPixel.value?.remove();\n trackingPixel.value = null;\n }\n });\n\n return isTracked;\n}\n\nexport function useSlotHooks({ setup }: AdheseSlotOptions, slotContext: Ref<AdheseSlotContext | null>): {\n runOnBeforeRender: ReturnType<typeof createAsyncHook<AdheseAd>>[0];\n runOnRender: ReturnType<typeof createPassiveHook<AdheseAd>>[0];\n runOnBeforeRequest: ReturnType<typeof createAsyncHook<AdheseAd | null>>[0];\n runOnRequest: ReturnType<typeof createAsyncHook<AdheseAd>>[0];\n runOnInit: ReturnType<typeof createAsyncHook<void>>[0];\n runOnDispose: ReturnType<typeof createPassiveHook<void>>[0];\n runOnEmpty: ReturnType<typeof createPassiveHook<void>>[0];\n runOnError: ReturnType<typeof createPassiveHook<Error>>[0];\n} & AdheseSlotHooks {\n const [runOnBeforeRender, onBeforeRender, disposeOnBeforeRender] = createAsyncHook<AdheseAd>();\n const [runOnRender, onRender, disposeOnRender] = createPassiveHook<AdheseAd>();\n const [runOnBeforeRequest, onBeforeRequest, disposeOnBeforeRequest] = createAsyncHook<AdheseAd | null>();\n const [runOnRequest, onRequest, disposeOnRequest] = createAsyncHook<AdheseAd>();\n const [runOnInit, onInit, disposeOnInit] = createAsyncHook();\n const [runOnDispose, onDispose, disposeOnDispose] = createPassiveHook();\n const [runOnEmpty, onEmpty, disposeOnEmpty] = createPassiveHook();\n const [runOnError, onError, disposeOnError] = createPassiveHook<Error>();\n\n setup?.(slotContext, {\n onBeforeRender,\n onRender,\n onBeforeRequest,\n onDispose,\n onRequest,\n onInit,\n onEmpty,\n onError,\n });\n\n onDispose(() => {\n disposeOnBeforeRender();\n disposeOnRender();\n disposeOnBeforeRequest();\n disposeOnRequest();\n disposeOnInit();\n disposeOnDispose();\n disposeOnEmpty();\n disposeOnError();\n });\n\n return { runOnBeforeRender, runOnRender, runOnBeforeRequest, runOnRequest, runOnDispose, onDispose, onBeforeRequest, onRequest, onBeforeRender, onRender, onInit, runOnInit, runOnEmpty, onEmpty, runOnError, onError };\n}\n"],"names":[],"mappings":";AAWO,SAAS,aAAa,SAAgD;AACrE,QAAA,cAAc,IAAI,KAAK;AAErB,UAAA,MAAM,OAAO,YAAY;AAC/B,UAAM,eAAe;AAErB,gBAAY,QAAQ;AAAA,EAAA,CACrB;AACM,SAAA;AACT;AAEO,SAAS,8BAA8B,EAAE,SAAS,SAAS,SAIjD;;AACT,QAAA,eAAe,IAAI,KAAK;AAE9B,QAAM,6BAA6B,IAAI,qBAAqB,CAAC,YAAY;AACvE,iBAAa,QAAQ,QAAQ,KAAK,CAAA,UAAS,MAAM,cAAc;AAAA,EAAA,GAC9D;AAAA,IACD,cAAY,aAAQ,uBAAR,mBAA4B,eAAc;AAAA,IACtD,WAAW;AAAA,EAAA,CACZ;AAEQ,WAAA,QAAQ,YAAgC,YAA6C;AACxF,QAAA;AACF,iCAA2B,UAAU,UAAU;AAE7C,QAAA;AACF,iCAA2B,QAAQ,UAAU;AAE/C,WAAO,MAAM;AACP,UAAA;AACF,mCAA2B,UAAU,UAAU;AAAA,IACnD;AAAA,EAAA;AAGF,QAAM,SAAS,OAAO;AACtB,UAAQ,QAAQ,KAAK;AAErB,QAAM,UAAU,MAAM;AACpB,+BAA2B,WAAW;AAAA,EAAA,CACvC;AAEM,SAAA;AACT;AAEO,SAAS,uBACd,EAAE,SAAS,aAAa,OAAO,aAMjB;AACd,MAAI,YAA2B;AACzB,QAAA;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE;AAAA,IACF,WAAW;AAAA,IACX,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,GAAG,QAAQ,QAAQ;AAAA,EACrB;AAEM,QAAA,gBAAgB,IAA6B,IAAI;AAEjD,QAAA,YAAY,IAAI,KAAK;AAE3B,QAAM,sBAAsB,IAAI,qBAAqB,CAAC,CAAC,KAAK,MAAM;AAChE,QAAI,QAAQ,QAAQ,uBAAuB,CAAC,cAAc,OAAO;AAC/D,YAAM,QAAQ,MAAM,MAAM,mBAAmB,CAAC;AAE1C,UAAA,SAAS,aAAa,CAAC,WAAW;AAEpC,oBAAY,WAAW,MAAM;AACf,sBAAA;AAEZ,iDAAY;AAEZ,oBAAU,QAAQ;AAAA,WACjB,QAAQ;AAAA,MAAA,WAEJ,QAAQ,aAAa,WAAW;AACvC,qBAAa,SAAS;AACV,oBAAA;AAAA,MAAA;AAAA,IACd;AAAA,EACF,GACC;AAAA,IACD;AAAA,IACA,WAAW,MAAM,KAAK,EAAE,QAAQ,GAAG,GAAG,CAAC,GAAG,MAAM,IAAI,GAAG;AAAA,EAAA,CACxD;AAEQ,WAAA,QAAQ,YAAgC,YAA6C;AAIxF,QAAA,cAAc,QAAQ,QAAQ;AAChC,0BAAoB,QAAQ,UAAU;AAExC,WAAO,MAAM;AACP,UAAA;AACF,4BAAoB,UAAU,UAAU;AAAA,IAC5C;AAAA,EAAA;AAGF,QAAM,MAAA;;AAAM,6BAAY,UAAZ,mBAAmB;AAAA,KAAS,CAAC,YAAY;AAC/C,QAAA;AACF,cAAQ,OAAO;AAAA,EAAA,GAChB,EAAE,WAAW,MAAM;AAEhB,QAAA,aAAa,CAAC,SAAS;AAC3B,QAAI,6BAAM;AACY,0BAAA,QAAQ,KAAK,OAAO;AAAA,EAAA,GACzC,EAAE,MAAM,MAAM;AAEjB,QAAM,UAAU,MAAM;;AACpB,wBAAc,UAAd,mBAAqB;AACrB,wBAAoB,WAAW;AAAA,EAAA,CAChC;AAED,QAAM,MAAM;;AAAA,6BAAY,UAAZ,mBAAmB;AAAA,KAAQ,OAAO,WAAW,cAAc;;AACjE,QAAA,cAAc,YAAY,cAAc,YAAY;AACtD,0BAAc,UAAd,mBAAqB;AACrB,oBAAc,QAAQ;AAAA,IAAA;AAAA,EACxB,CACD;AAEM,SAAA;AACT;AAEO,SAAS,aAAa,EAAE,MAAM,GAAsB,aASvC;AAClB,QAAM,CAAC,mBAAmB,gBAAgB,qBAAqB,IAAI,gBAA0B;AAC7F,QAAM,CAAC,aAAa,UAAU,eAAe,IAAI,kBAA4B;AAC7E,QAAM,CAAC,oBAAoB,iBAAiB,sBAAsB,IAAI,gBAAiC;AACvG,QAAM,CAAC,cAAc,WAAW,gBAAgB,IAAI,gBAA0B;AAC9E,QAAM,CAAC,WAAW,QAAQ,aAAa,IAAI,gBAAgB;AAC3D,QAAM,CAAC,cAAc,WAAW,gBAAgB,IAAI,kBAAkB;AACtE,QAAM,CAAC,YAAY,SAAS,cAAc,IAAI,kBAAkB;AAChE,QAAM,CAAC,YAAY,SAAS,cAAc,IAAI,kBAAyB;AAEvE,iCAAQ,aAAa;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAGF,YAAU,MAAM;AACQ,0BAAA;AACN,oBAAA;AACO,2BAAA;AACN,qBAAA;AACH,kBAAA;AACG,qBAAA;AACF,mBAAA;AACA,mBAAA;AAAA,EAAA,CAChB;AAED,SAAO,EAAE,mBAAmB,aAAa,oBAAoB,cAAc,cAAc,WAAW,iBAAiB,WAAW,gBAAgB,UAAU,QAAQ,WAAW,YAAY,SAAS,YAAY,QAAQ;AACxN;"}
package/dist/slot/slot.js CHANGED
@@ -1,4 +1,4 @@
1
- import { effectScope, ref, uniqueId, reactive, computed, generateName, watch, shallowRef, waitForDomLoad, pick, addTrackingPixel, omit, renderIframe, renderInline, doNothing } from "@adhese/sdk-shared";
1
+ import { effectScope, ref, uniqueId, reactive, computed, generateName, watch, shallowRef, addTrackingPixel, waitForDomLoad, pick, omit, renderIframe, renderInline, doNothing } from "@adhese/sdk-shared";
2
2
  import { logger } from "../logger/logger.js";
3
3
  import { useQueryDetector } from "../queryDetector/queryDetector.js";
4
4
  import { requestAd } from "../requestAds/requestAds.js";
@@ -124,10 +124,12 @@ function createSlot(slotOptions) {
124
124
  });
125
125
  const impressionTrackingPixelElement = ref(null);
126
126
  const isImpressionTracked = ref(false);
127
- hooks.onDispose(() => {
128
- if (impressionTrackingPixelElement.value)
129
- impressionTrackingPixelElement.value.remove();
130
- });
127
+ watch([status, isInViewport, data], ([newStatus, newIsInViewport, newData]) => {
128
+ if (newStatus === "rendered" && newIsInViewport && (newData == null ? void 0 : newData.impressionCounter) && !impressionTrackingPixelElement.value) {
129
+ impressionTrackingPixelElement.value = addTrackingPixel(newData.impressionCounter);
130
+ isImpressionTracked.value = true;
131
+ }
132
+ }, { immediate: true });
131
133
  watch(status, async (newStatus, oldStatus) => {
132
134
  var _a;
133
135
  if (newStatus === "loaded" && oldStatus === "rendered") {
@@ -135,6 +137,10 @@ function createSlot(slotOptions) {
135
137
  impressionTrackingPixelElement.value = null;
136
138
  }
137
139
  });
140
+ hooks.onDispose(() => {
141
+ if (impressionTrackingPixelElement.value)
142
+ impressionTrackingPixelElement.value.remove();
143
+ });
138
144
  async function request() {
139
145
  try {
140
146
  if (options.lazyLoading && !isInViewport.value)
@@ -158,6 +164,8 @@ function createSlot(slotOptions) {
158
164
  status.value = response ? "loaded" : "empty";
159
165
  if (!response)
160
166
  cleanElement();
167
+ if (response && context.options.eagerRendering && element.value)
168
+ await render(response);
161
169
  return response;
162
170
  } catch (error) {
163
171
  status.value = "error";
@@ -199,9 +207,6 @@ function createSlot(slotOptions) {
199
207
  ...pick(options, ["width", "height"])
200
208
  }, element.value);
201
209
  }
202
- if (renderAd.impressionCounter && !impressionTrackingPixelElement.value)
203
- impressionTrackingPixelElement.value = addTrackingPixel(renderAd.impressionCounter);
204
- isImpressionTracked.value = true;
205
210
  logger.debug(`Slot rendered ${name.value}`, {
206
211
  renderedElement: element,
207
212
  location: context.location,
@@ -1 +1 @@
1
- {"version":3,"file":"slot.js","sources":["../../src/slot/slot.ts"],"sourcesContent":["import type { AdheseAd } from '@adhese/sdk';\nimport type { AdheseSlot, AdheseSlotContext, AdheseSlotOptions, RenderMode } from './slot.types';\nimport {\n addTrackingPixel,\n computed,\n doNothing,\n effectScope,\n generateName,\n omit,\n pick,\n reactive,\n type Ref,\n ref,\n renderIframe,\n renderInline,\n type RenderOptions,\n shallowRef,\n uniqueId,\n type UnwrapRef,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\nimport { useQueryDetector } from '../queryDetector/queryDetector';\nimport { requestAd as extRequestAd } from '../requestAds/requestAds';\nimport {\n useDomLoaded,\n useRenderIntersectionObserver,\n useSlotHooks,\n useViewabilityObserver,\n} from './slot.composables';\n\nconst renderFunctions: Record<RenderMode, (ad: RenderOptions, element: HTMLElement) => void> = {\n iframe: renderIframe,\n inline: renderInline,\n none: doNothing,\n};\n\nconst defaultOptions = {\n renderMode: 'iframe',\n type: 'normal',\n} satisfies Partial<AdheseSlotOptions>;\n\n/**\n * Create a new slot instance. This slot instance can be used to request and render ads.\n *\n * @param slotOptions {AdheseSlotOptions} The options to create the slot with.\n *\n * @return AdheseSlot The created slot instance.\n */\nexport function createSlot(slotOptions: AdheseSlotOptions): AdheseSlot {\n const scope = effectScope();\n\n return scope.run(() => {\n const slotContext = ref<AdheseSlotContext | null>(null);\n const options = slotOptions.context.hooks.runOnSlotCreate({\n ...defaultOptions,\n ...(Object.fromEntries(Object.entries(slotOptions).filter(([,value]) => value !== undefined)) as AdheseSlotOptions),\n });\n\n const {\n containingElement,\n slot,\n context,\n pluginOptions,\n initialData = null,\n renderMode = 'iframe',\n type = 'normal',\n } = options;\n\n const id = uniqueId();\n const {\n runOnBeforeRender,\n runOnRender,\n runOnBeforeRequest,\n runOnRequest,\n runOnInit,\n runOnDispose,\n runOnEmpty,\n runOnError,\n ...hooks\n } = useSlotHooks(options, slotContext);\n\n const isDisposed = ref(false);\n const parameters = reactive(new Map(Object.entries(options.parameters ?? {})));\n\n const [device, disposeQueryDetector] = useQueryDetector(context, typeof options.format === 'string'\n ? {\n [options.format]: '(min-width: 0px)',\n }\n : Object.fromEntries(options.format.map(item => [item.format, item.query])));\n\n const format = computed(() => typeof options.format === 'string' ? options.format : device.value);\n\n const data = ref<AdheseAd | null>(null) as Ref<AdheseAd | null>;\n const originalData = ref(data.value) as Ref<AdheseAd | null>;\n const name = computed(() => generateName(options.context.location, format.value, options.slot));\n\n const status = ref<UnwrapRef<AdheseSlot>['status']>('initializing');\n\n watch(name, async (newName, oldName) => {\n if (newName === oldName)\n return;\n\n const newAd = await slotContext.value?.request();\n\n if (!newAd)\n return;\n\n slotContext.value?.cleanElement();\n\n data.value = newAd;\n originalData.value = newAd;\n });\n\n const isDomLoaded = useDomLoaded(context);\n\n const element = shallowRef<HTMLElement | null>(null);\n\n function getElement(): HTMLElement | null {\n if (!(typeof options.containingElement === 'string' || !options.containingElement))\n return options.containingElement;\n\n if (!isDomLoaded.value)\n return null;\n\n return document.querySelector<HTMLElement>(`#${options.containingElement}`);\n }\n\n watch(element, async (newElement, oldElement) => {\n if (status.value === 'empty' || status.value === 'error' || status.value === 'loading') {\n return;\n }\n\n if (newElement === null && data.value) {\n status.value = 'loaded';\n\n return;\n }\n\n if (newElement === oldElement || (oldElement === null && newElement === null))\n return;\n\n await render();\n });\n\n const domObserver = new MutationObserver(() => {\n element.value = getElement();\n });\n\n domObserver.observe(document.body, {\n childList: true,\n subtree: true,\n });\n\n watch(\n isDomLoaded,\n () => {\n element.value = getElement();\n },\n { immediate: true, deep: true },\n );\n\n const isInViewport = useRenderIntersectionObserver({\n options,\n element,\n hooks,\n });\n\n watch(isInViewport, async (newIsInViewport) => {\n if (newIsInViewport && status.value !== 'rendered')\n await slotContext.value?.render();\n }, { immediate: true });\n\n hooks.onDispose(() => {\n disposeQueryDetector();\n });\n\n const isViewabilityTracked = useViewabilityObserver({\n context,\n slotContext,\n hooks,\n onTracked(trackingPixel) {\n if (slotContext.value?.data?.viewableImpressionCounter) {\n trackingPixel.value = addTrackingPixel(slotContext.value?.data?.viewableImpressionCounter);\n\n context.logger.debug(`Viewability tracking pixel fired for ${slotContext.value?.name}`);\n }\n },\n });\n\n const impressionTrackingPixelElement = ref<HTMLImageElement | null>(null);\n const isImpressionTracked = ref(false);\n hooks.onDispose(() => {\n if (impressionTrackingPixelElement.value)\n impressionTrackingPixelElement.value.remove();\n });\n watch(status, async (newStatus, oldStatus) => {\n if (newStatus === 'loaded' && oldStatus === 'rendered') {\n impressionTrackingPixelElement.value?.remove();\n impressionTrackingPixelElement.value = null;\n }\n });\n\n async function request(): Promise<AdheseAd | null> {\n try {\n if (options.lazyLoading && !isInViewport.value)\n return null;\n\n status.value = 'loading';\n\n let response = await runOnBeforeRequest(null);\n\n if (!response) {\n response = await extRequestAd({\n slot: {\n name: name.value,\n parameters,\n },\n context,\n });\n }\n\n if (response)\n response = await runOnRequest(response);\n\n data.value = response;\n\n if (!originalData.value)\n originalData.value = response;\n\n status.value = response ? 'loaded' : 'empty';\n\n if (!response)\n cleanElement();\n\n return response;\n }\n catch (error) {\n status.value = 'error';\n\n logger.error(`Error requesting ad for slot ${name.value}`, error);\n\n runOnError(new Error(`Error requesting ad for slot ${name.value}`, { cause: error }));\n\n return null;\n }\n }\n\n async function render(adToRender?: AdheseAd): Promise<HTMLElement | null> {\n if (status.value === 'empty' || status.value === 'error' || status.value === 'initializing') {\n return null;\n }\n\n try {\n if (options.lazyLoading && !isInViewport.value)\n return null;\n\n status.value = 'rendering';\n await waitForDomLoad();\n element.value = getElement();\n\n let renderAd = adToRender ?? data.value ?? originalData.value ?? await request();\n\n renderAd = renderAd && await runOnBeforeRender(renderAd);\n\n if (!element.value && renderMode !== 'none') {\n logger.debug(`Could not render slot for format ${format.value}. No element found.`, slotContext.value);\n\n return null;\n }\n\n if (!renderAd) {\n // eslint-disable-next-line require-atomic-updates\n status.value = 'empty';\n logger.debug(`No ad to render for slot ${name.value}`);\n\n runOnEmpty();\n\n return null;\n }\n\n if (typeof renderAd?.tag !== 'string' && renderMode !== 'none') {\n const error = `Could not render slot for slot ${name.value}. A valid tag doesn't exist or is not HTML string.`;\n logger.error(error, options);\n\n throw new Error(error);\n }\n\n if (renderMode !== 'none' && element.value) {\n renderFunctions[renderMode]({\n ...renderAd,\n ...pick(options, ['width', 'height']),\n } as RenderOptions, element.value);\n }\n\n if (renderAd.impressionCounter && !impressionTrackingPixelElement.value)\n impressionTrackingPixelElement.value = addTrackingPixel(renderAd.impressionCounter);\n\n isImpressionTracked.value = true;\n\n logger.debug(`Slot rendered ${name.value}`, {\n renderedElement: element,\n location: context.location,\n format,\n containingElement,\n });\n\n // eslint-disable-next-line require-atomic-updates\n status.value = 'rendered';\n\n runOnRender(renderAd);\n\n return element.value;\n }\n catch (error) {\n // eslint-disable-next-line require-atomic-updates\n status.value = 'error';\n\n logger.error(`${error}`, options);\n\n runOnError(new Error(error as string));\n\n return null;\n }\n }\n\n function cleanElement(): void {\n if (!element.value || renderMode === 'none')\n return;\n\n element.value.innerHTML = '';\n element.value.style.position = '';\n }\n\n function dispose(): void {\n cleanElement();\n\n element.value = null;\n\n data.value = null;\n originalData.value = null;\n\n domObserver.disconnect();\n\n runOnDispose();\n\n isDisposed.value = true;\n\n scope.stop();\n }\n\n const state = reactive({\n location: context.location ?? '',\n lazyLoading: options.lazyLoading ?? false,\n type,\n slot,\n parameters,\n format,\n name,\n data,\n isViewabilityTracked,\n isImpressionTracked,\n status,\n element,\n isDisposed,\n id,\n pluginOptions,\n isVisible: isInViewport,\n render,\n request,\n dispose,\n cleanElement,\n options: omit(options, ['context']),\n ...hooks,\n });\n\n watch(state, (newState) => {\n slotContext.value = newState;\n }, {\n deep: true,\n immediate: true,\n });\n\n context.hooks.onInit(async () => {\n await runOnInit();\n\n if (status.value === 'empty' || status.value === 'error') {\n return;\n }\n\n if (initialData) {\n status.value = 'loaded';\n\n data.value = initialData;\n data.value = await runOnRequest(initialData);\n\n return;\n }\n\n status.value = 'initialized';\n\n if (options.lazyLoading) {\n return;\n }\n\n data.value = await slotContext.value?.request() ?? null;\n });\n\n return state;\n })!;\n}\n"],"names":["extRequestAd"],"mappings":"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"}
1
+ {"version":3,"file":"slot.js","sources":["../../src/slot/slot.ts"],"sourcesContent":["import type { AdheseAd } from '@adhese/sdk';\nimport type { AdheseSlot, AdheseSlotContext, AdheseSlotOptions, RenderMode } from './slot.types';\nimport {\n addTrackingPixel,\n computed,\n doNothing,\n effectScope,\n generateName,\n omit,\n pick,\n reactive,\n type Ref,\n ref,\n renderIframe,\n renderInline,\n type RenderOptions,\n shallowRef,\n uniqueId,\n type UnwrapRef,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\nimport { useQueryDetector } from '../queryDetector/queryDetector';\nimport { requestAd as extRequestAd } from '../requestAds/requestAds';\nimport {\n useDomLoaded,\n useRenderIntersectionObserver,\n useSlotHooks,\n useViewabilityObserver,\n} from './slot.composables';\n\nconst renderFunctions: Record<RenderMode, (ad: RenderOptions, element: HTMLElement) => void> = {\n iframe: renderIframe,\n inline: renderInline,\n none: doNothing,\n};\n\nconst defaultOptions = {\n renderMode: 'iframe',\n type: 'normal',\n} satisfies Partial<AdheseSlotOptions>;\n\n/**\n * Create a new slot instance. This slot instance can be used to request and render ads.\n *\n * @param slotOptions {AdheseSlotOptions} The options to create the slot with.\n *\n * @return AdheseSlot The created slot instance.\n */\nexport function createSlot(slotOptions: AdheseSlotOptions): AdheseSlot {\n const scope = effectScope();\n\n return scope.run(() => {\n const slotContext = ref<AdheseSlotContext | null>(null);\n const options = slotOptions.context.hooks.runOnSlotCreate({\n ...defaultOptions,\n ...(Object.fromEntries(Object.entries(slotOptions).filter(([,value]) => value !== undefined)) as AdheseSlotOptions),\n });\n\n const {\n containingElement,\n slot,\n context,\n pluginOptions,\n initialData = null,\n renderMode = 'iframe',\n type = 'normal',\n } = options;\n\n const id = uniqueId();\n const {\n runOnBeforeRender,\n runOnRender,\n runOnBeforeRequest,\n runOnRequest,\n runOnInit,\n runOnDispose,\n runOnEmpty,\n runOnError,\n ...hooks\n } = useSlotHooks(options, slotContext);\n\n const isDisposed = ref(false);\n const parameters = reactive(new Map(Object.entries(options.parameters ?? {})));\n\n const [device, disposeQueryDetector] = useQueryDetector(context, typeof options.format === 'string'\n ? {\n [options.format]: '(min-width: 0px)',\n }\n : Object.fromEntries(options.format.map(item => [item.format, item.query])));\n\n const format = computed(() => typeof options.format === 'string' ? options.format : device.value);\n\n const data = ref<AdheseAd | null>(null) as Ref<AdheseAd | null>;\n const originalData = ref(data.value) as Ref<AdheseAd | null>;\n const name = computed(() => generateName(options.context.location, format.value, options.slot));\n\n const status = ref<UnwrapRef<AdheseSlot>['status']>('initializing');\n\n watch(name, async (newName, oldName) => {\n if (newName === oldName)\n return;\n\n const newAd = await slotContext.value?.request();\n\n if (!newAd)\n return;\n\n slotContext.value?.cleanElement();\n\n data.value = newAd;\n originalData.value = newAd;\n });\n\n const isDomLoaded = useDomLoaded(context);\n\n const element = shallowRef<HTMLElement | null>(null);\n\n function getElement(): HTMLElement | null {\n if (!(typeof options.containingElement === 'string' || !options.containingElement))\n return options.containingElement;\n\n if (!isDomLoaded.value)\n return null;\n\n return document.querySelector<HTMLElement>(`#${options.containingElement}`);\n }\n\n watch(element, async (newElement, oldElement) => {\n if (status.value === 'empty' || status.value === 'error' || status.value === 'loading') {\n return;\n }\n\n if (newElement === null && data.value) {\n status.value = 'loaded';\n\n return;\n }\n\n if (newElement === oldElement || (oldElement === null && newElement === null))\n return;\n\n await render();\n });\n\n const domObserver = new MutationObserver(() => {\n element.value = getElement();\n });\n\n domObserver.observe(document.body, {\n childList: true,\n subtree: true,\n });\n\n watch(\n isDomLoaded,\n () => {\n element.value = getElement();\n },\n { immediate: true, deep: true },\n );\n\n const isInViewport = useRenderIntersectionObserver({\n options,\n element,\n hooks,\n });\n\n watch(isInViewport, async (newIsInViewport) => {\n if (newIsInViewport && status.value !== 'rendered')\n await slotContext.value?.render();\n }, { immediate: true });\n\n hooks.onDispose(() => {\n disposeQueryDetector();\n });\n\n const isViewabilityTracked = useViewabilityObserver({\n context,\n slotContext,\n hooks,\n onTracked(trackingPixel) {\n if (slotContext.value?.data?.viewableImpressionCounter) {\n trackingPixel.value = addTrackingPixel(slotContext.value?.data?.viewableImpressionCounter);\n\n context.logger.debug(`Viewability tracking pixel fired for ${slotContext.value?.name}`);\n }\n },\n });\n\n const impressionTrackingPixelElement = ref<HTMLImageElement | null>(null);\n const isImpressionTracked = ref(false);\n watch([status, isInViewport, data], ([newStatus, newIsInViewport, newData]) => {\n if (newStatus === 'rendered' && newIsInViewport && newData?.impressionCounter && !impressionTrackingPixelElement.value) {\n impressionTrackingPixelElement.value = addTrackingPixel(newData.impressionCounter);\n\n isImpressionTracked.value = true;\n }\n }, { immediate: true });\n watch(status, async (newStatus, oldStatus) => {\n if (newStatus === 'loaded' && oldStatus === 'rendered') {\n impressionTrackingPixelElement.value?.remove();\n impressionTrackingPixelElement.value = null;\n }\n });\n hooks.onDispose(() => {\n if (impressionTrackingPixelElement.value)\n impressionTrackingPixelElement.value.remove();\n });\n\n async function request(): Promise<AdheseAd | null> {\n try {\n if (options.lazyLoading && !isInViewport.value)\n return null;\n\n status.value = 'loading';\n\n let response = await runOnBeforeRequest(null);\n\n if (!response) {\n response = await extRequestAd({\n slot: {\n name: name.value,\n parameters,\n },\n context,\n });\n }\n\n if (response)\n response = await runOnRequest(response);\n\n data.value = response;\n\n if (!originalData.value)\n originalData.value = response;\n\n status.value = response ? 'loaded' : 'empty';\n\n if (!response)\n cleanElement();\n\n if (response && context.options.eagerRendering && element.value)\n await render(response);\n\n return response;\n }\n catch (error) {\n status.value = 'error';\n\n logger.error(`Error requesting ad for slot ${name.value}`, error);\n\n runOnError(new Error(`Error requesting ad for slot ${name.value}`, { cause: error }));\n\n return null;\n }\n }\n\n async function render(adToRender?: AdheseAd): Promise<HTMLElement | null> {\n if (status.value === 'empty' || status.value === 'error' || status.value === 'initializing') {\n return null;\n }\n\n try {\n if (options.lazyLoading && !isInViewport.value)\n return null;\n\n status.value = 'rendering';\n await waitForDomLoad();\n element.value = getElement();\n\n let renderAd = adToRender ?? data.value ?? originalData.value ?? await request();\n\n renderAd = renderAd && await runOnBeforeRender(renderAd);\n\n if (!element.value && renderMode !== 'none') {\n logger.debug(`Could not render slot for format ${format.value}. No element found.`, slotContext.value);\n\n return null;\n }\n\n if (!renderAd) {\n // eslint-disable-next-line require-atomic-updates\n status.value = 'empty';\n logger.debug(`No ad to render for slot ${name.value}`);\n\n runOnEmpty();\n\n return null;\n }\n\n if (typeof renderAd?.tag !== 'string' && renderMode !== 'none') {\n const error = `Could not render slot for slot ${name.value}. A valid tag doesn't exist or is not HTML string.`;\n logger.error(error, options);\n\n throw new Error(error);\n }\n\n if (renderMode !== 'none' && element.value) {\n renderFunctions[renderMode]({\n ...renderAd,\n ...pick(options, ['width', 'height']),\n } as RenderOptions, element.value);\n }\n\n logger.debug(`Slot rendered ${name.value}`, {\n renderedElement: element,\n location: context.location,\n format,\n containingElement,\n });\n\n // eslint-disable-next-line require-atomic-updates\n status.value = 'rendered';\n\n runOnRender(renderAd);\n\n return element.value;\n }\n catch (error) {\n // eslint-disable-next-line require-atomic-updates\n status.value = 'error';\n\n logger.error(`${error}`, options);\n\n runOnError(new Error(error as string));\n\n return null;\n }\n }\n\n function cleanElement(): void {\n if (!element.value || renderMode === 'none')\n return;\n\n element.value.innerHTML = '';\n element.value.style.position = '';\n }\n\n function dispose(): void {\n cleanElement();\n\n element.value = null;\n\n data.value = null;\n originalData.value = null;\n\n domObserver.disconnect();\n\n runOnDispose();\n\n isDisposed.value = true;\n\n scope.stop();\n }\n\n const state = reactive({\n location: context.location ?? '',\n lazyLoading: options.lazyLoading ?? false,\n type,\n slot,\n parameters,\n format,\n name,\n data,\n isViewabilityTracked,\n isImpressionTracked,\n status,\n element,\n isDisposed,\n id,\n pluginOptions,\n isVisible: isInViewport,\n render,\n request,\n dispose,\n cleanElement,\n options: omit(options, ['context']),\n ...hooks,\n });\n\n watch(state, (newState) => {\n slotContext.value = newState;\n }, {\n deep: true,\n immediate: true,\n });\n\n context.hooks.onInit(async () => {\n await runOnInit();\n\n if (status.value === 'empty' || status.value === 'error') {\n return;\n }\n\n if (initialData) {\n status.value = 'loaded';\n\n data.value = initialData;\n data.value = await runOnRequest(initialData);\n\n return;\n }\n\n status.value = 'initialized';\n\n if (options.lazyLoading) {\n return;\n }\n\n data.value = await slotContext.value?.request() ?? null;\n });\n\n return state;\n })!;\n}\n"],"names":["extRequestAd"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"slotManager.js","sources":["../../src/slotManager/slotManager.ts"],"sourcesContent":["import type { AdheseContext } from '../main.types';\nimport type { AdheseSlot, AdheseSlotOptions } from '../slot/slot.types';\nimport { generateSlotSignature } from '@adhese/sdk-shared';\nimport { findDomSlots as extFindDomSlots } from '../findDomSlots/findDomSlots';\nimport { logger } from '../logger/logger';\nimport { createSlot } from '../slot/slot';\n\nexport type AdheseSlotManager = {\n /**\n * Returns all slots that are currently registered and rendered.\n */\n getAll(): ReadonlyArray<AdheseSlot>;\n /**\n * Adds a new slot to the Adhese instance and renders it.\n */\n add(slot: Omit<AdheseSlotOptions, 'context'>): Readonly<AdheseSlot>;\n /**\n * Finds all slots in the DOM and adds them to the Adhese instance.\n */\n findDomSlots(): Promise<ReadonlyArray<AdheseSlot>>;\n /**\n * Returns the slot with the given name.\n */\n get(name: string): AdheseSlot | undefined;\n /**\n * Removes all slots from the Adhese instance and cleans up the slot manager.\n */\n dispose(): void;\n};\n\nexport type SlotManagerOptions = {\n /**\n * List of initial slots to add to the slot manager.\n */\n initialSlots?: ReadonlyArray<Omit<AdheseSlotOptions, 'context' | 'lazy'>>;\n context: AdheseContext;\n};\n\n/**\n * Creates a new slot manager instance. This slot manager instance can be used to manage all slots in the Adhese\n * instance. It will automatically add all slots that are passed in the `initialSlots` array.\n */\nexport function createSlotManager({\n initialSlots = [],\n context,\n}: SlotManagerOptions): AdheseSlotManager {\n context.slots = new Map<string, AdheseSlot>();\n\n function getAll(): ReadonlyArray<AdheseSlot> {\n return Array.from(context.slots).map(([, slot]) => slot);\n }\n\n function add(options: Omit<AdheseSlotOptions, 'context' | 'onDispose'>): Readonly<AdheseSlot> {\n const signature = generateSlotSignature({\n location: context.location,\n format: options.format,\n slot: options.slot,\n parameters: options.parameters,\n },\n );\n\n const current = context.slots.get(signature);\n\n const slot = createSlot({\n ...options as AdheseSlotOptions,\n context,\n initialData: current?.data ?? current?.options.initialData,\n setup(slotContext, slotHooks) {\n options.setup?.(slotContext, slotHooks);\n\n slotHooks.onInit(() => {\n if (!slotContext.value)\n return;\n\n if (current?.status === 'empty' || current?.status === 'error') {\n slotContext.value.status = current?.status;\n }\n });\n\n slotHooks.onDispose(() => {\n context.slots.delete(slot.id);\n logger.debug('Slot removed', {\n slot,\n });\n context.events?.removeSlot.dispatch(slot);\n });\n },\n });\n\n current?.dispose();\n\n context.slots.set(signature, slot);\n\n logger.debug('Slot added', {\n slot,\n slots: Array.from(context.slots.values()),\n });\n\n context.events?.addSlot.dispatch(slot);\n\n return slot;\n }\n\n async function findDomSlots(): Promise<ReadonlyArray<AdheseSlot>> {\n const domSlots = await extFindDomSlots(\n context,\n );\n\n for (const slot of domSlots)\n context.slots.set(slot.id, slot);\n\n return domSlots;\n }\n\n function get(name: string): AdheseSlot | undefined {\n return getAll().find(slot => slot.name === name);\n }\n\n function dispose(): void {\n for (const slot of context.slots.values())\n slot.dispose();\n\n context.slots.clear();\n }\n\n for (const options of initialSlots) {\n add({\n ...options,\n lazyLoading: false,\n });\n }\n\n return {\n getAll,\n add,\n findDomSlots,\n get,\n dispose,\n };\n}\n"],"names":["_a","findDomSlots","extFindDomSlots"],"mappings":";;;;AA0CO,SAAS,kBAAkB;AAAA,EAChC,eAAe,CAAC;AAAA,EAChB;AACF,GAA0C;AAChC,UAAA,4BAAY;AAEpB,WAAS,SAAoC;AACpC,WAAA,MAAM,KAAK,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAG,EAAA,IAAI,MAAM,IAAI;AAAA,EACzD;AAEA,WAAS,IAAI,SAAiF;;AAC5F,UAAM,YAAY;AAAA,MAAsB;AAAA,QACtC,UAAU,QAAQ;AAAA,QAClB,QAAQ,QAAQ;AAAA,QAChB,MAAM,QAAQ;AAAA,QACd,YAAY,QAAQ;AAAA,MACtB;AAAA,IAAA;AAGA,UAAM,UAAU,QAAQ,MAAM,IAAI,SAAS;AAE3C,UAAM,OAAO,WAAW;AAAA,MACtB,GAAG;AAAA,MACH;AAAA,MACA,cAAa,mCAAS,UAAQ,mCAAS,QAAQ;AAAA,MAC/C,MAAM,aAAa,WAAW;;AACpB,SAAAA,MAAA,QAAA,UAAA,gBAAAA,IAAA,cAAQ,aAAa;AAE7B,kBAAU,OAAO,MAAM;AACrB,cAAI,CAAC,YAAY;AACf;AAEF,eAAI,mCAAS,YAAW,YAAW,mCAAS,YAAW,SAAS;AAClD,wBAAA,MAAM,SAAS,mCAAS;AAAA,UACtC;AAAA,QAAA,CACD;AAED,kBAAU,UAAU,MAAM;;AAChB,kBAAA,MAAM,OAAO,KAAK,EAAE;AAC5B,iBAAO,MAAM,gBAAgB;AAAA,YAC3B;AAAA,UAAA,CACD;AACO,WAAAA,MAAA,QAAA,WAAA,gBAAAA,IAAQ,WAAW,SAAS;AAAA,QAAI,CACzC;AAAA,MACH;AAAA,IAAA,CACD;AAED,uCAAS;AAED,YAAA,MAAM,IAAI,WAAW,IAAI;AAEjC,WAAO,MAAM,cAAc;AAAA,MACzB;AAAA,MACA,OAAO,MAAM,KAAK,QAAQ,MAAM,QAAQ;AAAA,IAAA,CACzC;AAEO,kBAAA,WAAA,mBAAQ,QAAQ,SAAS;AAE1B,WAAA;AAAA,EACT;AAEA,iBAAeC,iBAAmD;AAChE,UAAM,WAAW,MAAMC;AAAAA,MACrB;AAAA,IAAA;AAGF,eAAW,QAAQ;AACjB,cAAQ,MAAM,IAAI,KAAK,IAAI,IAAI;AAE1B,WAAA;AAAA,EACT;AAEA,WAAS,IAAI,MAAsC;AACjD,WAAO,OAAS,EAAA,KAAK,CAAQ,SAAA,KAAK,SAAS,IAAI;AAAA,EACjD;AAEA,WAAS,UAAgB;AACZ,eAAA,QAAQ,QAAQ,MAAM,OAAO;AACtC,WAAK,QAAQ;AAEf,YAAQ,MAAM;EAChB;AAEA,aAAW,WAAW,cAAc;AAC9B,QAAA;AAAA,MACF,GAAG;AAAA,MACH,aAAa;AAAA,IAAA,CACd;AAAA,EACH;AAEO,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IAAA,cACAD;AAAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;"}
1
+ {"version":3,"file":"slotManager.js","sources":["../../src/slotManager/slotManager.ts"],"sourcesContent":["import type { AdheseContext } from '../main.types';\nimport type { AdheseSlot, AdheseSlotOptions } from '../slot/slot.types';\nimport { generateSlotSignature } from '@adhese/sdk-shared';\nimport { findDomSlots as extFindDomSlots } from '../findDomSlots/findDomSlots';\nimport { logger } from '../logger/logger';\nimport { createSlot } from '../slot/slot';\n\nexport type AdheseSlotManager = {\n /**\n * Returns all slots that are currently registered and rendered.\n */\n getAll(): ReadonlyArray<AdheseSlot>;\n /**\n * Adds a new slot to the Adhese instance and renders it.\n */\n add(slot: Omit<AdheseSlotOptions, 'context'>): Readonly<AdheseSlot>;\n /**\n * Finds all slots in the DOM and adds them to the Adhese instance.\n */\n findDomSlots(): Promise<ReadonlyArray<AdheseSlot>>;\n /**\n * Returns the slot with the given name.\n */\n get(name: string): AdheseSlot | undefined;\n /**\n * Removes all slots from the Adhese instance and cleans up the slot manager.\n */\n dispose(): void;\n};\n\nexport type SlotManagerOptions = {\n /**\n * List of initial slots to add to the slot manager.\n */\n initialSlots?: ReadonlyArray<Omit<AdheseSlotOptions, 'context' | 'lazy'>>;\n context: AdheseContext;\n};\n\n/**\n * Creates a new slot manager instance. This slot manager instance can be used to manage all slots in the Adhese\n * instance. It will automatically add all slots that are passed in the `initialSlots` array.\n */\nexport function createSlotManager({\n initialSlots = [],\n context,\n}: SlotManagerOptions): AdheseSlotManager {\n context.slots = new Map<string, AdheseSlot>();\n\n function getAll(): ReadonlyArray<AdheseSlot> {\n return Array.from(context.slots).map(([, slot]) => slot);\n }\n\n function add(options: Omit<AdheseSlotOptions, 'context' | 'onDispose'>): Readonly<AdheseSlot> {\n const signature = generateSlotSignature({\n location: context.location,\n format: options.format,\n slot: options.slot,\n parameters: options.parameters,\n },\n );\n\n const current = context.slots.get(signature);\n\n const slot = createSlot({\n ...options as AdheseSlotOptions,\n context,\n initialData: current?.data ?? current?.options.initialData,\n setup(slotContext, slotHooks) {\n options.setup?.(slotContext, slotHooks);\n\n slotHooks.onInit(() => {\n if (!slotContext.value)\n return;\n\n if (current?.status === 'empty' || current?.status === 'error') {\n slotContext.value.status = current?.status;\n }\n });\n\n slotHooks.onDispose(() => {\n context.slots.delete(slot.id);\n logger.debug('Slot removed', {\n slot,\n });\n context.events?.removeSlot.dispatch(slot);\n });\n },\n });\n\n current?.dispose();\n\n context.slots.set(signature, slot);\n\n logger.debug('Slot added', {\n slot,\n slots: Array.from(context.slots.values()),\n });\n\n context.events?.addSlot.dispatch(slot);\n\n return slot;\n }\n\n async function findDomSlots(): Promise<ReadonlyArray<AdheseSlot>> {\n const domSlots = await extFindDomSlots(\n context,\n );\n\n for (const slot of domSlots)\n context.slots.set(slot.id, slot);\n\n return domSlots;\n }\n\n function get(name: string): AdheseSlot | undefined {\n return getAll().find(slot => slot.name === name);\n }\n\n function dispose(): void {\n for (const slot of context.slots.values())\n slot.dispose();\n\n context.slots.clear();\n }\n\n for (const options of initialSlots) {\n add({\n ...options,\n lazyLoading: false,\n });\n }\n\n return {\n getAll,\n add,\n findDomSlots,\n get,\n dispose,\n };\n}\n"],"names":["_a","findDomSlots","extFindDomSlots"],"mappings":";;;;AA0CO,SAAS,kBAAkB;AAAA,EAChC,eAAe,CAAC;AAAA,EAChB;AACF,GAA0C;AAChC,UAAA,4BAAY,IAAwB;AAE5C,WAAS,SAAoC;AACpC,WAAA,MAAM,KAAK,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAA,EAAG,IAAI,MAAM,IAAI;AAAA,EAAA;AAGzD,WAAS,IAAI,SAAiF;;AAC5F,UAAM,YAAY;AAAA,MAAsB;AAAA,QACtC,UAAU,QAAQ;AAAA,QAClB,QAAQ,QAAQ;AAAA,QAChB,MAAM,QAAQ;AAAA,QACd,YAAY,QAAQ;AAAA,MAAA;AAAA,IAEtB;AAEA,UAAM,UAAU,QAAQ,MAAM,IAAI,SAAS;AAE3C,UAAM,OAAO,WAAW;AAAA,MACtB,GAAG;AAAA,MACH;AAAA,MACA,cAAa,mCAAS,UAAQ,mCAAS,QAAQ;AAAA,MAC/C,MAAM,aAAa,WAAW;;AACpB,SAAAA,MAAA,QAAA,UAAA,gBAAAA,IAAA,cAAQ,aAAa;AAE7B,kBAAU,OAAO,MAAM;AACrB,cAAI,CAAC,YAAY;AACf;AAEF,eAAI,mCAAS,YAAW,YAAW,mCAAS,YAAW,SAAS;AAClD,wBAAA,MAAM,SAAS,mCAAS;AAAA,UAAA;AAAA,QACtC,CACD;AAED,kBAAU,UAAU,MAAM;;AAChB,kBAAA,MAAM,OAAO,KAAK,EAAE;AAC5B,iBAAO,MAAM,gBAAgB;AAAA,YAC3B;AAAA,UAAA,CACD;AACO,WAAAA,MAAA,QAAA,WAAA,gBAAAA,IAAQ,WAAW,SAAS;AAAA,QAAI,CACzC;AAAA,MAAA;AAAA,IACH,CACD;AAED,uCAAS;AAED,YAAA,MAAM,IAAI,WAAW,IAAI;AAEjC,WAAO,MAAM,cAAc;AAAA,MACzB;AAAA,MACA,OAAO,MAAM,KAAK,QAAQ,MAAM,OAAQ,CAAA;AAAA,IAAA,CACzC;AAEO,kBAAA,WAAA,mBAAQ,QAAQ,SAAS;AAE1B,WAAA;AAAA,EAAA;AAGT,iBAAeC,iBAAmD;AAChE,UAAM,WAAW,MAAMC;AAAAA,MACrB;AAAA,IACF;AAEA,eAAW,QAAQ;AACjB,cAAQ,MAAM,IAAI,KAAK,IAAI,IAAI;AAE1B,WAAA;AAAA,EAAA;AAGT,WAAS,IAAI,MAAsC;AACjD,WAAO,OAAS,EAAA,KAAK,CAAQ,SAAA,KAAK,SAAS,IAAI;AAAA,EAAA;AAGjD,WAAS,UAAgB;AACZ,eAAA,QAAQ,QAAQ,MAAM,OAAO;AACtC,WAAK,QAAQ;AAEf,YAAQ,MAAM,MAAM;AAAA,EAAA;AAGtB,aAAW,WAAW,cAAc;AAC9B,QAAA;AAAA,MACF,GAAG;AAAA,MACH,aAAa;AAAA,IAAA,CACd;AAAA,EAAA;AAGI,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IAAA,cACAD;AAAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@adhese/sdk",
3
3
  "type": "module",
4
- "version": "1.4.1",
4
+ "version": "1.4.2",
5
5
  "description": "Adhese SDK",
6
6
  "license": "GPL-3.0",
7
7
  "repository": {