@adhese/sdk 1.0.0 → 1.0.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.
- package/CHANGELOG.md +12 -0
- package/dist/cjs/main.cjs +3 -4
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/main.composables.cjs +4 -0
- package/dist/cjs/main.composables.cjs.map +1 -1
- package/dist/cjs/main.utils.cjs +1 -12
- package/dist/cjs/main.utils.cjs.map +1 -1
- package/dist/cjs/package.json.cjs +1 -1
- package/dist/cjs/slot/slot.cjs +0 -1
- package/dist/cjs/slot/slot.cjs.map +1 -1
- package/dist/main.composables.js +4 -0
- package/dist/main.composables.js.map +1 -1
- package/dist/main.js +4 -5
- package/dist/main.js.map +1 -1
- package/dist/main.utils.js +2 -13
- package/dist/main.utils.js.map +1 -1
- package/dist/package.json.js +1 -1
- package/dist/slot/slot.js +0 -1
- package/dist/slot/slot.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @adhese/sdk
|
|
2
2
|
|
|
3
|
+
## 1.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ce4a2c0: Fix fetching of initialSlots and dom slots on init not being handled properly causing issues with debug mode not being recognized when set in the URL or when in preview mode
|
|
8
|
+
|
|
9
|
+
## 1.0.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- d4cedb4: Fix ad data getting set when the data is passed via the render function
|
|
14
|
+
|
|
3
15
|
## 1.0.0
|
|
4
16
|
|
|
5
17
|
### Major Changes
|
package/dist/cjs/main.cjs
CHANGED
|
@@ -27,7 +27,6 @@ function createAdhese(options) {
|
|
|
27
27
|
viewabilityTracking: true,
|
|
28
28
|
...options
|
|
29
29
|
};
|
|
30
|
-
main_utils.setupLogging(mergedOptions);
|
|
31
30
|
const hooks$1 = hooks.createGlobalHooks();
|
|
32
31
|
const context = sdkShared.reactive({
|
|
33
32
|
location: mergedOptions.location,
|
|
@@ -101,14 +100,14 @@ function createAdhese(options) {
|
|
|
101
100
|
}
|
|
102
101
|
context.dispose = dispose;
|
|
103
102
|
hooks$1.onInit(async () => {
|
|
104
|
-
var _a2;
|
|
105
103
|
await sdkShared.awaitTimeout(0);
|
|
106
104
|
if ((slotManager$1.getAll().length ?? 0) > 0)
|
|
107
105
|
await main_utils.fetchAllUnrenderedSlots(context.getAll()).catch(logger.logger.error);
|
|
108
106
|
if (mergedOptions.findDomSlotsOnLoad)
|
|
109
107
|
await (context == null ? void 0 : context.findDomSlots());
|
|
110
|
-
|
|
111
|
-
|
|
108
|
+
logger.logger.debug("Created Adhese SDK instance", {
|
|
109
|
+
mergedOptions
|
|
110
|
+
});
|
|
112
111
|
if (!scope.active)
|
|
113
112
|
dispose();
|
|
114
113
|
});
|
package/dist/cjs/main.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.cjs","sources":["../../src/main.ts"],"sourcesContent":["import { awaitTimeout, createEventManager, effectScope, omit, reactive, watch } from '@adhese/sdk-shared';\nimport { version } from '../package.json';\nimport { createSlotManager } from './slotManager/slotManager';\nimport { useConsent } from './consent/consent';\nimport { fetchAllUnrenderedSlots
|
|
1
|
+
{"version":3,"file":"main.cjs","sources":["../../src/main.ts"],"sourcesContent":["import { awaitTimeout, createEventManager, effectScope, omit, reactive, watch } from '@adhese/sdk-shared';\nimport { version } from '../package.json';\nimport { createSlotManager } from './slotManager/slotManager';\nimport { useConsent } from './consent/consent';\nimport { fetchAllUnrenderedSlots } from './main.utils';\nimport type {\n Adhese,\n AdheseContextStateWithPlugins,\n AdheseOptions,\n AdhesePlugin,\n MergedOptions,\n} from './main.types';\nimport { logger } from './logger/logger';\nimport { useMainDebugMode, useMainParameters, useMainQueryDetector } from './main.composables';\nimport { createGlobalHooks } from './hooks';\n\nimport type { AdheseSlot, AdheseSlotOptions } from './slot/slot.types';\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 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","hooks","createGlobalHooks","reactive","logger","createEventManager","version","omit","watch","_a","useMainParameters","slotManager","createSlotManager","fetchAllUnrenderedSlots","useMainDebugMode","useMainQueryDetector","useConsent","awaitTimeout"],"mappings":";;;;;;;;;;AAyBO,SAAS,aAAoD,SAAsC;AACxG,QAAM,QAAQA,UAAAA;AAEP,SAAA,MAAM,IAAI,MAAM;;AACrB,UAAM,gBAA+B;AAAA,MACnC,MAAM,eAAe,QAAQ,OAAO;AAAA,MACpC,UAAU,gBAAgB,QAAQ,OAAO;AAAA,MACzC,UAAU;AAAA,MACV,aAAa;AAAA,MACb,OAAO;AAAA,MACP,cAAc,CAAC;AAAA,MACf,oBAAoB;AAAA,MACpB,SAAS;AAAA,MACT,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,gBAAgB;AAAA,MAChB,qBAAqB;AAAA,MACrB,GAAG;AAAA,IAAA;AAGL,UAAMC,UAAQC,MAAAA;AAEd,UAAM,UAAUC,UAAAA,SAA2C;AAAA,MACzD,UAAU,cAAc;AAAA,MACxB,SAAS,cAAc;AAAA,MACvB,OAAO,cAAc;AAAA,MACrB,SAAS;AAAA,MAAA,QACTC,OAAA;AAAA,MACA,YAAY;AAAA,MACZ,gCAAgB,IAAI;AAAA,MACpB,QAAQC,UAAAA,mBAAmB;AAAA,MAC3B,2BAAW,IAAI;AAAA,MACf,QAAQ;AAAA,MAAA,OACRJ;AAAAA,MACA,SAAS,CAAC;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AAEU,eAAA,CAAC,OAAO,MAAM,OAAK,aAAQ,YAAR,mBAAiB,cAAa,IAAI;AACxD,YAAA,OAAO,OAAO,SAAS;AAAA,QAC3B;AAAA,QAAA,SACAK,SAAA;AAAA,QAAA,OACAL;AAAAA,MAAA,CACD;AAED,YAAM,OAAO,KAAK;AAClB,cAAQ,QAAQ,IAAI,IAAIM,eAAK,MAAM,CAAC,MAAM,CAAC;AAAA,IAC7C;AAEAC,cAAAA,MAAM,MAAM,QAAQ,UAAU,CAAC,gBAAgB;;AACrC,OAAAC,MAAA,QAAA,WAAA,gBAAAA,IAAQ,eAAe,SAAS;AAAA,IAAW,CACpD;AAEDC,uCAAkB,SAAS,aAAa;AAExC,UAAMC,gBAAcC,YAAAA,kBAAkB;AAAA,MACpC,cAAc,cAAc;AAAA,MAC5B;AAAA,IAAA,CACD;AAED,aAAS,SAAoC;AACpC,aAAAD,cAAY,OAAO,KAAK;IACjC;AACA,YAAQ,SAAS;AAEjB,aAAS,IAAI,MAAsC;AAC1C,aAAAA,cAAY,IAAI,IAAI;AAAA,IAC7B;AACA,YAAQ,MAAM;AAEd,aAAS,QAAQ,aAAsD;AAC9D,aAAAA,cAAY,IAAI,WAAW;AAAA,IACpC;AACA,YAAQ,UAAU;AAElB,mBAAe,eAAmD;AAC1D,YAAA,YAAY,MAAMA,cAAY,aAAa,KAAK,CAAA,GAAI,OAAO,CAAA,SAAQ,CAAC,KAAK,WAAW;AAE1F,UAAI,SAAS,UAAU;AACrB,eAAO;AAEH,YAAAE,mCAAwB,QAAQ,OAAA,CAAQ;AAEvC,aAAA;AAAA,IACT;AACA,YAAQ,eAAe;AAEvBC,qBAAA,iBAAiB,OAAO;AAExBC,0CAAqB,eAAe,OAAO;AAE3CC,YAAA,WAAW,OAAO;AAElB,aAAS,UAAgB;;AACvB,cAAQ,aAAa;AAErBL,oBAAY,QAAQ;AACpB,OAAAF,MAAA,QAAQ,eAAR,gBAAAA,IAAoB;AACpB,oBAAQ,WAAR,mBAAgB;AAEhBR,cAAM,aAAa;AACnBA,cAAM,SAAS;AAEf,YAAM,KAAK;AAAA,IACb;AACA,YAAQ,UAAU;AAElBA,YAAM,OAAO,YAAY;AACvB,YAAMgB,UAAAA,aAAa,CAAC;AAEpB,WAAKN,cAAY,OAAS,EAAA,UAAU,KAAK;AACvC,cAAME,WAAAA,wBAAwB,QAAQ,OAAA,CAAQ,EAAE,MAAMT,OAAAA,OAAO,KAAK;AAEpE,UAAI,cAAc;AAChB,eAAM,mCAAS;AAEjBA,aAAA,OAAO,MAAM,+BAA+B;AAAA,QAC1C;AAAA,MAAA,CACD;AAED,UAAI,CAAC,MAAM;AACD;IAAA,CACX;AAEDH,YAAM,UAAU;AAET,WAAA;AAAA,EAAA,CACR;AACH;;"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const sdkShared = require("@adhese/sdk-shared");
|
|
4
4
|
const queryDetector = require("./queryDetector/queryDetector.cjs");
|
|
5
|
+
const main_utils = require("./main.utils.cjs");
|
|
5
6
|
function useMainQueryDetector(mergedOptions, context) {
|
|
6
7
|
const [device] = queryDetector.useQueryDetector(context, mergedOptions.queries);
|
|
7
8
|
sdkShared.watch(device, async (newDevice) => {
|
|
@@ -13,6 +14,9 @@ function useMainQueryDetector(mergedOptions, context) {
|
|
|
13
14
|
}, { immediate: true });
|
|
14
15
|
}
|
|
15
16
|
function useMainDebugMode(context) {
|
|
17
|
+
if (window.location.search.includes("adhese_debug=true") || main_utils.isPreviewMode()) {
|
|
18
|
+
context.debug = true;
|
|
19
|
+
}
|
|
16
20
|
sdkShared.watch(() => context.debug, async (newDebug) => {
|
|
17
21
|
var _a, _b;
|
|
18
22
|
if (newDebug) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.composables.cjs","sources":["../../src/main.composables.ts"],"sourcesContent":["import { watch } from '@adhese/sdk-shared';\nimport type { AdheseContextState, MergedOptions } from './main.types';\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(slot => slot.request()));\n }, { immediate: true });\n}\n\nexport function useMainDebugMode(context: AdheseContextState): void {\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.info('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"],"mappings":"
|
|
1
|
+
{"version":3,"file":"main.composables.cjs","sources":["../../src/main.composables.ts"],"sourcesContent":["import { watch } from '@adhese/sdk-shared';\nimport type { AdheseContextState, MergedOptions } from './main.types';\nimport { useQueryDetector } from './queryDetector/queryDetector';\nimport { isPreviewMode } from './main.utils';\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(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.info('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,CAAQ,SAAA,KAAK,QAAQ,CAAC,CAAC;AAAA,EAAA,GACpE,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,KAAK,0BAA0B;AAAA,EAAA,CAC/C;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;;;;"}
|
package/dist/cjs/main.utils.cjs
CHANGED
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const logger = require("./logger/logger.cjs");
|
|
4
|
-
function setupLogging(mergedOptions) {
|
|
5
|
-
if (mergedOptions.debug || window.location.search.includes("adhese_debug=true")) {
|
|
6
|
-
logger.logger.setMinLogLevelThreshold("debug");
|
|
7
|
-
logger.logger.debug("Debug logging enabled");
|
|
8
|
-
}
|
|
9
|
-
logger.logger.debug("Created Adhese SDK instance", {
|
|
10
|
-
mergedOptions
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
3
|
function isPreviewMode() {
|
|
14
4
|
return window.location.search.includes("adhesePreviewCreativeId");
|
|
15
5
|
}
|
|
@@ -17,9 +7,8 @@ async function fetchAllUnrenderedSlots(slots) {
|
|
|
17
7
|
const filteredSlots = slots.filter((slot) => !slot.lazyLoading && !slot.data);
|
|
18
8
|
if (filteredSlots.length === 0)
|
|
19
9
|
return;
|
|
20
|
-
await Promise.
|
|
10
|
+
await Promise.all(filteredSlots.map((slot) => slot.request));
|
|
21
11
|
}
|
|
22
12
|
exports.fetchAllUnrenderedSlots = fetchAllUnrenderedSlots;
|
|
23
13
|
exports.isPreviewMode = isPreviewMode;
|
|
24
|
-
exports.setupLogging = setupLogging;
|
|
25
14
|
//# sourceMappingURL=main.utils.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.utils.cjs","sources":["../../src/main.utils.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"main.utils.cjs","sources":["../../src/main.utils.ts"],"sourcesContent":["import type { AdheseSlot } from './slot/slot.types';\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 await Promise.all(filteredSlots.map(slot => slot.request));\n}\n"],"names":[],"mappings":";;AAKO,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;AAEF,QAAM,QAAQ,IAAI,cAAc,IAAI,CAAQ,SAAA,KAAK,OAAO,CAAC;AAC3D;;;"}
|
|
@@ -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.0.
|
|
4
|
+
const version = "1.0.2";
|
|
5
5
|
exports.name = name;
|
|
6
6
|
exports.version = version;
|
|
7
7
|
//# sourceMappingURL=package.json.cjs.map
|
package/dist/cjs/slot/slot.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slot.cjs","sources":["../../../src/slot/slot.ts"],"sourcesContent":["import {\n type Ref,\n type RenderOptions,\n type UnwrapRef,\n addTrackingPixel,\n computed,\n doNothing,\n effectScope,\n generateName,\n isDeepEqual,\n omit,\n reactive,\n ref,\n renderIframe,\n renderInline,\n uniqueId,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\nimport type { AdheseAd } from '@adhese/sdk';\nimport { requestAd as extRequestAd } from '../requestAds/requestAds';\nimport { logger } from '../logger/logger';\nimport { useQueryDetector } from '../queryDetector/queryDetector';\nimport type { AdheseSlot, AdheseSlotContext, AdheseSlotOptions, RenderMode } from './slot.types';\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 ...slotOptions,\n });\n\n const {\n containingElement,\n slot,\n context,\n pluginOptions,\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 ...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 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 = computed(() => {\n if (!(typeof options.containingElement === 'string' || !options.containingElement))\n return options.containingElement;\n\n if (!isDomLoaded.value || slotContext.value?.isDisposed)\n return null;\n\n return document.querySelector<HTMLElement>(`.adunit[data-format=\"${format.value}\"]#${options.containingElement}${options.slot ? `[data-slot=\"${options.slot}\"]` : ''}`);\n },\n );\n\n const isInViewport = useRenderIntersectionObserver({\n options,\n element,\n hooks,\n });\n\n const status = ref<UnwrapRef<AdheseSlot>['status']>('initializing');\n\n watch([data, isInViewport], async ([newData, newIsInViewport], [oldData]) => {\n if ((!newData || (oldData && isDeepEqual(newData, oldData))) && status.value === 'rendered')\n return;\n\n if (newIsInViewport)\n await slotContext.value?.render(newData ?? undefined);\n });\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\n async function request(): Promise<AdheseAd | null> {\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\n async function render(adToRender?: AdheseAd): Promise<HTMLElement | null> {\n status.value = 'rendering';\n\n await waitForDomLoad();\n\n let renderAd = adToRender ?? data.value ?? originalData.value ?? await request();\n\n renderAd = renderAd && await runOnBeforeRender(renderAd);\n\n if (!renderAd) {\n status.value = 'empty';\n logger.debug(`No ad to render for slot ${name.value}`);\n\n return null;\n }\n\n if (!element.value) {\n const error = `Could not create slot for format ${format.value}. No element found.`;\n logger.error(error, options);\n throw new Error(error);\n }\n\n if (context.debug)\n element.value.style.position = 'relative';\n\n if (typeof renderAd?.tag !== 'string') {\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 status.value = 'error';\n throw new Error(error);\n }\n\n renderFunctions[renderMode](renderAd as RenderOptions, element.value);\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 data.value = renderAd;\n\n status.value = 'rendered';\n\n runOnRender(renderAd);\n\n return element.value;\n }\n\n function cleanElement(): void {\n if (!element.value)\n return;\n\n element.value.innerHTML = '';\n element.value.style.position = '';\n element.value.style.width = '';\n element.value.style.height = '';\n\n data.value = null;\n originalData.value = null;\n }\n\n function dispose(): void {\n cleanElement();\n\n data.value = null;\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 status.value = 'initialized';\n\n runOnInit();\n\n if (options.lazyLoading)\n return;\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","useRenderIntersectionObserver","isDeepEqual","useViewabilityObserver","addTrackingPixel","extRequestAd","waitForDomLoad","logger","omit"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"slot.cjs","sources":["../../../src/slot/slot.ts"],"sourcesContent":["import {\n type Ref,\n type RenderOptions,\n type UnwrapRef,\n addTrackingPixel,\n computed,\n doNothing,\n effectScope,\n generateName,\n isDeepEqual,\n omit,\n reactive,\n ref,\n renderIframe,\n renderInline,\n uniqueId,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\nimport type { AdheseAd } from '@adhese/sdk';\nimport { requestAd as extRequestAd } from '../requestAds/requestAds';\nimport { logger } from '../logger/logger';\nimport { useQueryDetector } from '../queryDetector/queryDetector';\nimport type { AdheseSlot, AdheseSlotContext, AdheseSlotOptions, RenderMode } from './slot.types';\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 ...slotOptions,\n });\n\n const {\n containingElement,\n slot,\n context,\n pluginOptions,\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 ...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 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 = computed(() => {\n if (!(typeof options.containingElement === 'string' || !options.containingElement))\n return options.containingElement;\n\n if (!isDomLoaded.value || slotContext.value?.isDisposed)\n return null;\n\n return document.querySelector<HTMLElement>(`.adunit[data-format=\"${format.value}\"]#${options.containingElement}${options.slot ? `[data-slot=\"${options.slot}\"]` : ''}`);\n },\n );\n\n const isInViewport = useRenderIntersectionObserver({\n options,\n element,\n hooks,\n });\n\n const status = ref<UnwrapRef<AdheseSlot>['status']>('initializing');\n\n watch([data, isInViewport], async ([newData, newIsInViewport], [oldData]) => {\n if ((!newData || (oldData && isDeepEqual(newData, oldData))) && status.value === 'rendered')\n return;\n\n if (newIsInViewport)\n await slotContext.value?.render(newData ?? undefined);\n });\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\n async function request(): Promise<AdheseAd | null> {\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\n async function render(adToRender?: AdheseAd): Promise<HTMLElement | null> {\n status.value = 'rendering';\n\n await waitForDomLoad();\n\n let renderAd = adToRender ?? data.value ?? originalData.value ?? await request();\n\n renderAd = renderAd && await runOnBeforeRender(renderAd);\n\n if (!renderAd) {\n status.value = 'empty';\n logger.debug(`No ad to render for slot ${name.value}`);\n\n return null;\n }\n\n if (!element.value) {\n const error = `Could not create slot for format ${format.value}. No element found.`;\n logger.error(error, options);\n throw new Error(error);\n }\n\n if (context.debug)\n element.value.style.position = 'relative';\n\n if (typeof renderAd?.tag !== 'string') {\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 status.value = 'error';\n throw new Error(error);\n }\n\n renderFunctions[renderMode](renderAd as RenderOptions, element.value);\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 status.value = 'rendered';\n\n runOnRender(renderAd);\n\n return element.value;\n }\n\n function cleanElement(): void {\n if (!element.value)\n return;\n\n element.value.innerHTML = '';\n element.value.style.position = '';\n element.value.style.width = '';\n element.value.style.height = '';\n\n data.value = null;\n originalData.value = null;\n }\n\n function dispose(): void {\n cleanElement();\n\n data.value = null;\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 status.value = 'initialized';\n\n runOnInit();\n\n if (options.lazyLoading)\n return;\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","useRenderIntersectionObserver","isDeepEqual","useViewabilityObserver","addTrackingPixel","extRequestAd","waitForDomLoad","logger","omit"],"mappings":"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"}
|
package/dist/main.composables.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { watch } from "@adhese/sdk-shared";
|
|
2
2
|
import { useQueryDetector } from "./queryDetector/queryDetector.js";
|
|
3
|
+
import { isPreviewMode } from "./main.utils.js";
|
|
3
4
|
function useMainQueryDetector(mergedOptions, context) {
|
|
4
5
|
const [device] = useQueryDetector(context, mergedOptions.queries);
|
|
5
6
|
watch(device, async (newDevice) => {
|
|
@@ -11,6 +12,9 @@ function useMainQueryDetector(mergedOptions, context) {
|
|
|
11
12
|
}, { immediate: true });
|
|
12
13
|
}
|
|
13
14
|
function useMainDebugMode(context) {
|
|
15
|
+
if (window.location.search.includes("adhese_debug=true") || isPreviewMode()) {
|
|
16
|
+
context.debug = true;
|
|
17
|
+
}
|
|
14
18
|
watch(() => context.debug, async (newDebug) => {
|
|
15
19
|
var _a, _b;
|
|
16
20
|
if (newDebug) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.composables.js","sources":["../src/main.composables.ts"],"sourcesContent":["import { watch } from '@adhese/sdk-shared';\nimport type { AdheseContextState, MergedOptions } from './main.types';\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(slot => slot.request()));\n }, { immediate: true });\n}\n\nexport function useMainDebugMode(context: AdheseContextState): void {\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.info('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":"
|
|
1
|
+
{"version":3,"file":"main.composables.js","sources":["../src/main.composables.ts"],"sourcesContent":["import { watch } from '@adhese/sdk-shared';\nimport type { AdheseContextState, MergedOptions } from './main.types';\nimport { useQueryDetector } from './queryDetector/queryDetector';\nimport { isPreviewMode } from './main.utils';\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(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.info('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,CAAQ,SAAA,KAAK,QAAQ,CAAC,CAAC;AAAA,EAAA,GACpE,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,KAAK,0BAA0B;AAAA,EAAA,CAC/C;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;"}
|
package/dist/main.js
CHANGED
|
@@ -2,7 +2,7 @@ import { effectScope, reactive, createEventManager, omit, watch, awaitTimeout }
|
|
|
2
2
|
import { version } from "./package.json.js";
|
|
3
3
|
import { createSlotManager } from "./slotManager/slotManager.js";
|
|
4
4
|
import { useConsent } from "./consent/consent.js";
|
|
5
|
-
import {
|
|
5
|
+
import { fetchAllUnrenderedSlots } from "./main.utils.js";
|
|
6
6
|
import { logger } from "./logger/logger.js";
|
|
7
7
|
import { useMainParameters, useMainDebugMode, useMainQueryDetector } from "./main.composables.js";
|
|
8
8
|
import { createGlobalHooks } from "./hooks.js";
|
|
@@ -25,7 +25,6 @@ function createAdhese(options) {
|
|
|
25
25
|
viewabilityTracking: true,
|
|
26
26
|
...options
|
|
27
27
|
};
|
|
28
|
-
setupLogging(mergedOptions);
|
|
29
28
|
const hooks = createGlobalHooks();
|
|
30
29
|
const context = reactive({
|
|
31
30
|
location: mergedOptions.location,
|
|
@@ -99,14 +98,14 @@ function createAdhese(options) {
|
|
|
99
98
|
}
|
|
100
99
|
context.dispose = dispose;
|
|
101
100
|
hooks.onInit(async () => {
|
|
102
|
-
var _a2;
|
|
103
101
|
await awaitTimeout(0);
|
|
104
102
|
if ((slotManager.getAll().length ?? 0) > 0)
|
|
105
103
|
await fetchAllUnrenderedSlots(context.getAll()).catch(logger.error);
|
|
106
104
|
if (mergedOptions.findDomSlotsOnLoad)
|
|
107
105
|
await (context == null ? void 0 : context.findDomSlots());
|
|
108
|
-
|
|
109
|
-
|
|
106
|
+
logger.debug("Created Adhese SDK instance", {
|
|
107
|
+
mergedOptions
|
|
108
|
+
});
|
|
110
109
|
if (!scope.active)
|
|
111
110
|
dispose();
|
|
112
111
|
});
|
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sources":["../src/main.ts"],"sourcesContent":["import { awaitTimeout, createEventManager, effectScope, omit, reactive, watch } from '@adhese/sdk-shared';\nimport { version } from '../package.json';\nimport { createSlotManager } from './slotManager/slotManager';\nimport { useConsent } from './consent/consent';\nimport { fetchAllUnrenderedSlots
|
|
1
|
+
{"version":3,"file":"main.js","sources":["../src/main.ts"],"sourcesContent":["import { awaitTimeout, createEventManager, effectScope, omit, reactive, watch } from '@adhese/sdk-shared';\nimport { version } from '../package.json';\nimport { createSlotManager } from './slotManager/slotManager';\nimport { useConsent } from './consent/consent';\nimport { fetchAllUnrenderedSlots } from './main.utils';\nimport type {\n Adhese,\n AdheseContextStateWithPlugins,\n AdheseOptions,\n AdhesePlugin,\n MergedOptions,\n} from './main.types';\nimport { logger } from './logger/logger';\nimport { useMainDebugMode, useMainParameters, useMainQueryDetector } from './main.composables';\nimport { createGlobalHooks } from './hooks';\n\nimport type { AdheseSlot, AdheseSlotOptions } from './slot/slot.types';\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 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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"}
|
package/dist/main.utils.js
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
import { logger } from "./logger/logger.js";
|
|
2
|
-
function setupLogging(mergedOptions) {
|
|
3
|
-
if (mergedOptions.debug || window.location.search.includes("adhese_debug=true")) {
|
|
4
|
-
logger.setMinLogLevelThreshold("debug");
|
|
5
|
-
logger.debug("Debug logging enabled");
|
|
6
|
-
}
|
|
7
|
-
logger.debug("Created Adhese SDK instance", {
|
|
8
|
-
mergedOptions
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
1
|
function isPreviewMode() {
|
|
12
2
|
return window.location.search.includes("adhesePreviewCreativeId");
|
|
13
3
|
}
|
|
@@ -15,11 +5,10 @@ async function fetchAllUnrenderedSlots(slots) {
|
|
|
15
5
|
const filteredSlots = slots.filter((slot) => !slot.lazyLoading && !slot.data);
|
|
16
6
|
if (filteredSlots.length === 0)
|
|
17
7
|
return;
|
|
18
|
-
await Promise.
|
|
8
|
+
await Promise.all(filteredSlots.map((slot) => slot.request));
|
|
19
9
|
}
|
|
20
10
|
export {
|
|
21
11
|
fetchAllUnrenderedSlots,
|
|
22
|
-
isPreviewMode
|
|
23
|
-
setupLogging
|
|
12
|
+
isPreviewMode
|
|
24
13
|
};
|
|
25
14
|
//# sourceMappingURL=main.utils.js.map
|
package/dist/main.utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.utils.js","sources":["../src/main.utils.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"main.utils.js","sources":["../src/main.utils.ts"],"sourcesContent":["import type { AdheseSlot } from './slot/slot.types';\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 await Promise.all(filteredSlots.map(slot => slot.request));\n}\n"],"names":[],"mappings":"AAKO,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;AAEF,QAAM,QAAQ,IAAI,cAAc,IAAI,CAAQ,SAAA,KAAK,OAAO,CAAC;AAC3D;"}
|
package/dist/package.json.js
CHANGED
package/dist/slot/slot.js
CHANGED
package/dist/slot/slot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slot.js","sources":["../../src/slot/slot.ts"],"sourcesContent":["import {\n type Ref,\n type RenderOptions,\n type UnwrapRef,\n addTrackingPixel,\n computed,\n doNothing,\n effectScope,\n generateName,\n isDeepEqual,\n omit,\n reactive,\n ref,\n renderIframe,\n renderInline,\n uniqueId,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\nimport type { AdheseAd } from '@adhese/sdk';\nimport { requestAd as extRequestAd } from '../requestAds/requestAds';\nimport { logger } from '../logger/logger';\nimport { useQueryDetector } from '../queryDetector/queryDetector';\nimport type { AdheseSlot, AdheseSlotContext, AdheseSlotOptions, RenderMode } from './slot.types';\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 ...slotOptions,\n });\n\n const {\n containingElement,\n slot,\n context,\n pluginOptions,\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 ...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 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 = computed(() => {\n if (!(typeof options.containingElement === 'string' || !options.containingElement))\n return options.containingElement;\n\n if (!isDomLoaded.value || slotContext.value?.isDisposed)\n return null;\n\n return document.querySelector<HTMLElement>(`.adunit[data-format=\"${format.value}\"]#${options.containingElement}${options.slot ? `[data-slot=\"${options.slot}\"]` : ''}`);\n },\n );\n\n const isInViewport = useRenderIntersectionObserver({\n options,\n element,\n hooks,\n });\n\n const status = ref<UnwrapRef<AdheseSlot>['status']>('initializing');\n\n watch([data, isInViewport], async ([newData, newIsInViewport], [oldData]) => {\n if ((!newData || (oldData && isDeepEqual(newData, oldData))) && status.value === 'rendered')\n return;\n\n if (newIsInViewport)\n await slotContext.value?.render(newData ?? undefined);\n });\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\n async function request(): Promise<AdheseAd | null> {\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\n async function render(adToRender?: AdheseAd): Promise<HTMLElement | null> {\n status.value = 'rendering';\n\n await waitForDomLoad();\n\n let renderAd = adToRender ?? data.value ?? originalData.value ?? await request();\n\n renderAd = renderAd && await runOnBeforeRender(renderAd);\n\n if (!renderAd) {\n status.value = 'empty';\n logger.debug(`No ad to render for slot ${name.value}`);\n\n return null;\n }\n\n if (!element.value) {\n const error = `Could not create slot for format ${format.value}. No element found.`;\n logger.error(error, options);\n throw new Error(error);\n }\n\n if (context.debug)\n element.value.style.position = 'relative';\n\n if (typeof renderAd?.tag !== 'string') {\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 status.value = 'error';\n throw new Error(error);\n }\n\n renderFunctions[renderMode](renderAd as RenderOptions, element.value);\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 data.value = renderAd;\n\n status.value = 'rendered';\n\n runOnRender(renderAd);\n\n return element.value;\n }\n\n function cleanElement(): void {\n if (!element.value)\n return;\n\n element.value.innerHTML = '';\n element.value.style.position = '';\n element.value.style.width = '';\n element.value.style.height = '';\n\n data.value = null;\n originalData.value = null;\n }\n\n function dispose(): void {\n cleanElement();\n\n data.value = null;\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 status.value = 'initialized';\n\n runOnInit();\n\n if (options.lazyLoading)\n return;\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 {\n type Ref,\n type RenderOptions,\n type UnwrapRef,\n addTrackingPixel,\n computed,\n doNothing,\n effectScope,\n generateName,\n isDeepEqual,\n omit,\n reactive,\n ref,\n renderIframe,\n renderInline,\n uniqueId,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\nimport type { AdheseAd } from '@adhese/sdk';\nimport { requestAd as extRequestAd } from '../requestAds/requestAds';\nimport { logger } from '../logger/logger';\nimport { useQueryDetector } from '../queryDetector/queryDetector';\nimport type { AdheseSlot, AdheseSlotContext, AdheseSlotOptions, RenderMode } from './slot.types';\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 ...slotOptions,\n });\n\n const {\n containingElement,\n slot,\n context,\n pluginOptions,\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 ...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 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 = computed(() => {\n if (!(typeof options.containingElement === 'string' || !options.containingElement))\n return options.containingElement;\n\n if (!isDomLoaded.value || slotContext.value?.isDisposed)\n return null;\n\n return document.querySelector<HTMLElement>(`.adunit[data-format=\"${format.value}\"]#${options.containingElement}${options.slot ? `[data-slot=\"${options.slot}\"]` : ''}`);\n },\n );\n\n const isInViewport = useRenderIntersectionObserver({\n options,\n element,\n hooks,\n });\n\n const status = ref<UnwrapRef<AdheseSlot>['status']>('initializing');\n\n watch([data, isInViewport], async ([newData, newIsInViewport], [oldData]) => {\n if ((!newData || (oldData && isDeepEqual(newData, oldData))) && status.value === 'rendered')\n return;\n\n if (newIsInViewport)\n await slotContext.value?.render(newData ?? undefined);\n });\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\n async function request(): Promise<AdheseAd | null> {\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\n async function render(adToRender?: AdheseAd): Promise<HTMLElement | null> {\n status.value = 'rendering';\n\n await waitForDomLoad();\n\n let renderAd = adToRender ?? data.value ?? originalData.value ?? await request();\n\n renderAd = renderAd && await runOnBeforeRender(renderAd);\n\n if (!renderAd) {\n status.value = 'empty';\n logger.debug(`No ad to render for slot ${name.value}`);\n\n return null;\n }\n\n if (!element.value) {\n const error = `Could not create slot for format ${format.value}. No element found.`;\n logger.error(error, options);\n throw new Error(error);\n }\n\n if (context.debug)\n element.value.style.position = 'relative';\n\n if (typeof renderAd?.tag !== 'string') {\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 status.value = 'error';\n throw new Error(error);\n }\n\n renderFunctions[renderMode](renderAd as RenderOptions, element.value);\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 status.value = 'rendered';\n\n runOnRender(renderAd);\n\n return element.value;\n }\n\n function cleanElement(): void {\n if (!element.value)\n return;\n\n element.value.innerHTML = '';\n element.value.style.position = '';\n element.value.style.width = '';\n element.value.style.height = '';\n\n data.value = null;\n originalData.value = null;\n }\n\n function dispose(): void {\n cleanElement();\n\n data.value = null;\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 status.value = 'initialized';\n\n runOnInit();\n\n if (options.lazyLoading)\n return;\n\n data.value = await slotContext.value?.request() ?? null;\n });\n\n return state;\n })!;\n}\n"],"names":["extRequestAd"],"mappings":"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"}
|