@adhese/sdk 0.12.0 → 0.14.0
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 +255 -0
- package/dist/index.cjs +281 -360
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +93 -50
- package/dist/index.js +215 -362
- package/dist/index.js.map +1 -1
- package/dist/requestAds.schema-Cb8_FVMb.js +169 -0
- package/dist/requestAds.schema-Cb8_FVMb.js.map +1 -0
- package/dist/requestAds.schema-D3gd-oXt.cjs +169 -0
- package/dist/requestAds.schema-D3gd-oXt.cjs.map +1 -0
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { uniqueId, createLogger, waitForDomLoad, createEventManager } from "@adhese/sdk-shared";
|
|
2
|
-
import { toValue, ref, computed, watch, effectScope, reactive
|
|
1
|
+
import { uniqueId, createLogger, waitForDomLoad, createEventManager, awaitTimeout } from "@adhese/sdk-shared";
|
|
2
|
+
import { toValue, ref, computed, watch, effectScope, reactive } from "@vue/runtime-core";
|
|
3
|
+
import { computed as computed2, customRef, effectScope as effectScope2, isProxy, isReactive, isReadonly, isRef, isShallow, markRaw, reactive as reactive2, readonly, ref as ref2, shallowReactive, shallowReadonly, shallowRef, toRaw, toRefs, toValue as toValue2, unref, watch as watch2, watchEffect, watchPostEffect, watchSyncEffect } from "@vue/runtime-core";
|
|
3
4
|
import { debounce, round, isDeepEqual } from "remeda";
|
|
4
|
-
import { union, coerce, literal, number, string, ZodIssueCode, NEVER, object, unknown, lazy } from "zod";
|
|
5
5
|
function createSafeFrame({
|
|
6
6
|
renderFile,
|
|
7
7
|
context
|
|
@@ -55,56 +55,7 @@ function createSafeFrame({
|
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
57
|
const name = "@adhese/sdk";
|
|
58
|
-
const
|
|
59
|
-
const version = "0.12.0";
|
|
60
|
-
const description = "Adhese SDK";
|
|
61
|
-
const license = "GPL-3.0";
|
|
62
|
-
const repository = {
|
|
63
|
-
type: "git",
|
|
64
|
-
url: "git+https://github.com/adhese/sdk_typescript.git"
|
|
65
|
-
};
|
|
66
|
-
const main = "./dist/index.cjs";
|
|
67
|
-
const module = "./dist/index.js";
|
|
68
|
-
const types = "./dist/index.d.ts";
|
|
69
|
-
const files = [
|
|
70
|
-
"LICENSE",
|
|
71
|
-
"README.md",
|
|
72
|
-
"dist"
|
|
73
|
-
];
|
|
74
|
-
const scripts = {
|
|
75
|
-
dev: "vitest --config vite.config.npm.ts --silent",
|
|
76
|
-
"dev:verbose": "vitest --config vite.config.npm.ts",
|
|
77
|
-
test: "vitest --config vite.config.npm.ts --silent --run --coverage",
|
|
78
|
-
"test:verbose": "vitest --config vite.config.npm.ts --run --coverage",
|
|
79
|
-
build: "npm run build:npm && npm run build:standalone",
|
|
80
|
-
"build:npm": "vite build --config vite.config.npm.ts && tsup src/index.ts --dts-only --minify --format esm",
|
|
81
|
-
"build:standalone": "vite build --config vite.config.standalone.ts",
|
|
82
|
-
lint: "eslint . --ignore-pattern **/*.md/**/*",
|
|
83
|
-
"lint:fix": "eslint --fix . --ignore-pattern **/*.md/**/*",
|
|
84
|
-
clean: "rm -rf dist",
|
|
85
|
-
typecheck: "tsc --noEmit",
|
|
86
|
-
prepareRelease: "npm run build"
|
|
87
|
-
};
|
|
88
|
-
const dependencies = {
|
|
89
|
-
"@adhese/sdk-shared": "^0.2.0",
|
|
90
|
-
"@vue/runtime-core": "^3.4.21",
|
|
91
|
-
remeda: "^1.61.0",
|
|
92
|
-
zod: "^3.23.5"
|
|
93
|
-
};
|
|
94
|
-
const packageJson = {
|
|
95
|
-
name,
|
|
96
|
-
type,
|
|
97
|
-
version,
|
|
98
|
-
description,
|
|
99
|
-
license,
|
|
100
|
-
repository,
|
|
101
|
-
main,
|
|
102
|
-
module,
|
|
103
|
-
types,
|
|
104
|
-
files,
|
|
105
|
-
scripts,
|
|
106
|
-
dependencies
|
|
107
|
-
};
|
|
58
|
+
const version = "0.14.0";
|
|
108
59
|
function renderIframe(ad, element) {
|
|
109
60
|
const iframe = document.createElement("iframe");
|
|
110
61
|
iframe.srcdoc = `
|
|
@@ -145,6 +96,9 @@ function addTrackingPixel(url) {
|
|
|
145
96
|
img.style.top = "0";
|
|
146
97
|
return document.body.appendChild(img);
|
|
147
98
|
}
|
|
99
|
+
const logger = createLogger({
|
|
100
|
+
scope: `${name}@${version}`
|
|
101
|
+
});
|
|
148
102
|
function createQueryDetector({
|
|
149
103
|
onChange,
|
|
150
104
|
queries = {
|
|
@@ -199,7 +153,10 @@ function createAsyncHook(name2, {
|
|
|
199
153
|
onRun == null ? void 0 : onRun(hookMap.get(name2));
|
|
200
154
|
return latestResult;
|
|
201
155
|
};
|
|
202
|
-
|
|
156
|
+
function dispose() {
|
|
157
|
+
hookMap.delete(name2);
|
|
158
|
+
}
|
|
159
|
+
return [run, (callback) => add(callback, { name: name2, onAdd }), dispose];
|
|
203
160
|
}
|
|
204
161
|
function createSyncHook(name2, {
|
|
205
162
|
onRun,
|
|
@@ -219,7 +176,24 @@ function createSyncHook(name2, {
|
|
|
219
176
|
onRun == null ? void 0 : onRun(hookMap.get(name2));
|
|
220
177
|
return latestResult;
|
|
221
178
|
};
|
|
222
|
-
|
|
179
|
+
function dispose() {
|
|
180
|
+
hookMap.delete(name2);
|
|
181
|
+
}
|
|
182
|
+
return [run, (callback) => add(callback, { name: name2, onAdd }), dispose];
|
|
183
|
+
}
|
|
184
|
+
function createPassiveHook(name2, {
|
|
185
|
+
onRun,
|
|
186
|
+
onAdd
|
|
187
|
+
} = {}) {
|
|
188
|
+
hookMap.set(name2, /* @__PURE__ */ new Set());
|
|
189
|
+
function run(arg) {
|
|
190
|
+
Promise.allSettled(Array.from(hookMap.get(name2) ?? []).map((callback) => callback(arg))).catch(console.trace);
|
|
191
|
+
onRun == null ? void 0 : onRun(hookMap.get(name2));
|
|
192
|
+
}
|
|
193
|
+
function dispose() {
|
|
194
|
+
hookMap.delete(name2);
|
|
195
|
+
}
|
|
196
|
+
return [run, (callback) => add(callback, { name: name2, onAdd }), dispose];
|
|
223
197
|
}
|
|
224
198
|
function isCallbackAsync(callback) {
|
|
225
199
|
return callback.constructor.name === "AsyncFunction";
|
|
@@ -256,191 +230,39 @@ const [runOnInit, onInit] = createSyncHook("onInit", {
|
|
|
256
230
|
runOnInit();
|
|
257
231
|
}
|
|
258
232
|
});
|
|
259
|
-
const logger = createLogger({
|
|
260
|
-
scope: "Adhese SDK"
|
|
261
|
-
});
|
|
262
233
|
const [runOnRequest, onRequest] = createAsyncHook("onRequest");
|
|
263
234
|
const [runOnResponse, onResponse] = createAsyncHook("onResponse");
|
|
264
|
-
const numberLike = union([coerce.string().regex(/^\d+$/), literal("")]).transform((value) => value === "" ? void 0 : Number(value));
|
|
265
|
-
const booleanLike = union([coerce.boolean(), literal("")]);
|
|
266
|
-
const urlLike = union([coerce.string(), literal("")]).transform((value) => {
|
|
267
|
-
try {
|
|
268
|
-
return new URL(value);
|
|
269
|
-
} catch {
|
|
270
|
-
return void 0;
|
|
271
|
-
}
|
|
272
|
-
});
|
|
273
|
-
const dateLike = union([coerce.string(), literal("")]).transform((value) => {
|
|
274
|
-
if (value === "")
|
|
275
|
-
return void 0;
|
|
276
|
-
const date = new Date(numberLike.safeParse(value).success ? Number(value) : value);
|
|
277
|
-
if (Number.isNaN(date.getTime()))
|
|
278
|
-
return void 0;
|
|
279
|
-
return date;
|
|
280
|
-
});
|
|
281
|
-
const cssValueLike = union([coerce.string(), literal(""), number()]).transform((value) => {
|
|
282
|
-
if (value === "" || value === 0 || value === "0")
|
|
283
|
-
return void 0;
|
|
284
|
-
if (numberLike.parse(value))
|
|
285
|
-
return `${numberLike.parse(value)}px`;
|
|
286
|
-
return String(value);
|
|
287
|
-
});
|
|
288
|
-
const isJson = string().transform((value, { addIssue }) => {
|
|
289
|
-
try {
|
|
290
|
-
return JSON.parse(value.replaceAll("'", '"'));
|
|
291
|
-
} catch (error) {
|
|
292
|
-
addIssue({
|
|
293
|
-
code: ZodIssueCode.custom,
|
|
294
|
-
message: `Invalid JSON: ${error.message}`
|
|
295
|
-
});
|
|
296
|
-
return NEVER;
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
|
-
const isHtmlString = string().transform((value, { addIssue }) => {
|
|
300
|
-
var _a;
|
|
301
|
-
const htmlParser = new DOMParser();
|
|
302
|
-
try {
|
|
303
|
-
const html = htmlParser.parseFromString(value, "text/html");
|
|
304
|
-
if (((_a = html.body) == null ? void 0 : _a.children.length) === 0)
|
|
305
|
-
throw new Error("Invalid HTML");
|
|
306
|
-
return value;
|
|
307
|
-
} catch (error) {
|
|
308
|
-
addIssue({
|
|
309
|
-
code: ZodIssueCode.custom,
|
|
310
|
-
message: error.message
|
|
311
|
-
});
|
|
312
|
-
return NEVER;
|
|
313
|
-
}
|
|
314
|
-
});
|
|
315
|
-
const isJsonOrHtmlString = union([isJson, isHtmlString]);
|
|
316
|
-
const isJsonOrHtmlOptionalString = union([coerce.string(), isJsonOrHtmlString]).transform((value) => {
|
|
317
|
-
if (value === "")
|
|
318
|
-
return void 0;
|
|
319
|
-
return value;
|
|
320
|
-
}).optional();
|
|
321
|
-
const baseSchema = object({
|
|
322
|
-
adDuration: numberLike.optional(),
|
|
323
|
-
adFormat: string().optional(),
|
|
324
|
-
adType: string(),
|
|
325
|
-
additionalCreativeTracker: urlLike.optional(),
|
|
326
|
-
additionalViewableTracker: string().optional(),
|
|
327
|
-
adspaceEnd: dateLike.optional(),
|
|
328
|
-
adspaceId: string().optional(),
|
|
329
|
-
adspaceKey: string().optional(),
|
|
330
|
-
adspaceStart: dateLike.optional(),
|
|
331
|
-
advertiserId: string().optional(),
|
|
332
|
-
altText: string().optional(),
|
|
333
|
-
auctionable: booleanLike.optional(),
|
|
334
|
-
body: isJsonOrHtmlOptionalString,
|
|
335
|
-
clickTag: urlLike.optional(),
|
|
336
|
-
comment: string().optional(),
|
|
337
|
-
creativeName: string().optional(),
|
|
338
|
-
deliveryGroupId: string().optional(),
|
|
339
|
-
deliveryMultiples: string().optional(),
|
|
340
|
-
ext: string().optional(),
|
|
341
|
-
extension: object({
|
|
342
|
-
mediaType: string(),
|
|
343
|
-
prebid: unknown().optional()
|
|
344
|
-
}).optional(),
|
|
345
|
-
height: numberLike.optional(),
|
|
346
|
-
id: string(),
|
|
347
|
-
impressionCounter: urlLike.optional(),
|
|
348
|
-
libId: string().optional(),
|
|
349
|
-
orderId: string().optional(),
|
|
350
|
-
orderName: string().optional(),
|
|
351
|
-
orderProperty: string().optional(),
|
|
352
|
-
origin: union([literal("JERLICIA"), literal("DALE")]),
|
|
353
|
-
originData: unknown().optional(),
|
|
354
|
-
originInstance: string().optional(),
|
|
355
|
-
poolPath: urlLike.optional(),
|
|
356
|
-
preview: booleanLike.optional(),
|
|
357
|
-
priority: numberLike.optional(),
|
|
358
|
-
sfSrc: urlLike.optional(),
|
|
359
|
-
share: string().optional(),
|
|
360
|
-
// eslint-disable-next-line ts/naming-convention
|
|
361
|
-
slotID: string(),
|
|
362
|
-
slotName: string(),
|
|
363
|
-
swfSrc: urlLike.optional(),
|
|
364
|
-
tag: isJsonOrHtmlOptionalString,
|
|
365
|
-
tagUrl: urlLike.optional(),
|
|
366
|
-
timeStamp: dateLike.optional(),
|
|
367
|
-
trackedImpressionCounter: urlLike.optional(),
|
|
368
|
-
tracker: urlLike.optional(),
|
|
369
|
-
trackingUrl: urlLike.optional(),
|
|
370
|
-
url: urlLike.optional(),
|
|
371
|
-
viewableImpressionCounter: urlLike.optional(),
|
|
372
|
-
width: numberLike.optional(),
|
|
373
|
-
widthLarge: cssValueLike.optional()
|
|
374
|
-
});
|
|
375
|
-
const jerliciaSchema = object({
|
|
376
|
-
origin: literal("JERLICIA"),
|
|
377
|
-
tag: isJsonOrHtmlString
|
|
378
|
-
}).passthrough();
|
|
379
|
-
const daleSchema = object({
|
|
380
|
-
origin: literal("DALE"),
|
|
381
|
-
body: isJsonOrHtmlString
|
|
382
|
-
}).passthrough().transform(({ body, ...data }) => ({
|
|
383
|
-
...data,
|
|
384
|
-
tag: body
|
|
385
|
-
}));
|
|
386
|
-
const adResponseSchema = baseSchema.extend({
|
|
387
|
-
additionalCreatives: lazy(() => union([adResponseSchema.array(), string()]).optional())
|
|
388
|
-
});
|
|
389
|
-
const adSchema = adResponseSchema.transform(({
|
|
390
|
-
additionalCreatives,
|
|
391
|
-
...data
|
|
392
|
-
}) => {
|
|
393
|
-
const filteredValue = Object.fromEntries(
|
|
394
|
-
Object.entries(data).filter(([, value]) => Boolean(value) && JSON.stringify(value) !== "{}" && JSON.stringify(value) !== "[]")
|
|
395
|
-
);
|
|
396
|
-
return {
|
|
397
|
-
...filteredValue,
|
|
398
|
-
additionalCreatives: Array.isArray(additionalCreatives) ? additionalCreatives.map((creative) => adSchema.parse(creative)) : additionalCreatives
|
|
399
|
-
};
|
|
400
|
-
});
|
|
401
|
-
function parseResponse(response) {
|
|
402
|
-
const schemaMap = {
|
|
403
|
-
/* eslint-disable ts/naming-convention */
|
|
404
|
-
JERLICIA: jerliciaSchema,
|
|
405
|
-
DALE: daleSchema
|
|
406
|
-
/* eslint-enable ts/naming-convention */
|
|
407
|
-
};
|
|
408
|
-
const preParsed = adResponseSchema.array().parse(response);
|
|
409
|
-
return preParsed.map((item) => {
|
|
410
|
-
const schema = schemaMap[item.origin];
|
|
411
|
-
if (!schema)
|
|
412
|
-
return adSchema.parse(item);
|
|
413
|
-
return schema.parse(item);
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
235
|
async function requestPreviews(account) {
|
|
417
236
|
const previewObjects = getPreviewObjects();
|
|
418
|
-
const list =
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
237
|
+
const [list, adSchema] = await Promise.all([
|
|
238
|
+
Promise.allSettled(previewObjects.filter((previewObject) => "adhesePreviewCreativeId" in previewObject).map(async (previewObject) => {
|
|
239
|
+
const endpoint = new URL(`https://${account}-preview.adhese.org/creatives/preview/json/tag.do`);
|
|
240
|
+
endpoint.searchParams.set(
|
|
241
|
+
"id",
|
|
242
|
+
previewObject.adhesePreviewCreativeId
|
|
243
|
+
);
|
|
244
|
+
const response = await fetch(endpoint.href, {
|
|
245
|
+
method: "GET",
|
|
246
|
+
headers: {
|
|
247
|
+
accept: "application/json"
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
if (!response.ok)
|
|
251
|
+
return Promise.reject(new Error(`Failed to request preview ad with ID: ${previewObject.adhesePreviewCreativeId}`));
|
|
252
|
+
return await response.json();
|
|
253
|
+
})),
|
|
254
|
+
import("./requestAds.schema-Cb8_FVMb.js").then((module) => module.adSchema)
|
|
255
|
+
]);
|
|
256
|
+
return adSchema.array().parse(list.filter((response) => {
|
|
434
257
|
if (response.status === "rejected") {
|
|
435
258
|
logger.error(response.reason);
|
|
436
259
|
return false;
|
|
437
260
|
}
|
|
438
261
|
return response.status === "fulfilled";
|
|
439
|
-
}).
|
|
262
|
+
}).flatMap((response) => response.value.map((item) => ({
|
|
440
263
|
...item,
|
|
441
264
|
preview: true
|
|
442
|
-
})));
|
|
443
|
-
return adSchema.array().parse(list.flat());
|
|
265
|
+
}))));
|
|
444
266
|
}
|
|
445
267
|
function getPreviewObjects() {
|
|
446
268
|
const currentUrl = new URL(window.location.href);
|
|
@@ -504,19 +326,19 @@ function filterSpecialChars(value) {
|
|
|
504
326
|
return value.replaceAll(specialRegex, "_");
|
|
505
327
|
}
|
|
506
328
|
const batch = /* @__PURE__ */ new Map();
|
|
507
|
-
const
|
|
329
|
+
const runRequestAdsBatch = debounce(async (context) => {
|
|
508
330
|
if (batch.size === 0)
|
|
509
331
|
return [];
|
|
510
332
|
const ads = await requestAds({
|
|
511
333
|
slots: Array.from(batch.values()).map(({ options }) => options.slot),
|
|
512
334
|
context
|
|
513
335
|
});
|
|
514
|
-
for (const { options, resolve
|
|
336
|
+
for (const { options, resolve } of batch.values()) {
|
|
515
337
|
const ad = ads.find(({ slotName }) => toValue(slotName) === toValue(options.slot.name));
|
|
516
338
|
if (ad)
|
|
517
339
|
resolve(ad);
|
|
518
340
|
else
|
|
519
|
-
|
|
341
|
+
resolve(null);
|
|
520
342
|
}
|
|
521
343
|
batch.clear();
|
|
522
344
|
return ads;
|
|
@@ -526,11 +348,11 @@ const debouncedRequestAds = debounce(async (context) => {
|
|
|
526
348
|
});
|
|
527
349
|
async function requestAd(options) {
|
|
528
350
|
const promise = new Promise(
|
|
529
|
-
(resolve
|
|
530
|
-
batch.set(toValue(options.slot.name), { options, resolve
|
|
351
|
+
(resolve) => {
|
|
352
|
+
batch.set(toValue(options.slot.name), { options, resolve });
|
|
531
353
|
}
|
|
532
354
|
);
|
|
533
|
-
await
|
|
355
|
+
await runRequestAdsBatch.call(options.context);
|
|
534
356
|
return promise;
|
|
535
357
|
}
|
|
536
358
|
async function requestAds(requestOptions) {
|
|
@@ -542,7 +364,11 @@ async function requestAds(requestOptions) {
|
|
|
542
364
|
...options,
|
|
543
365
|
context
|
|
544
366
|
});
|
|
545
|
-
const [response, previews] = await Promise.all([
|
|
367
|
+
const [response, previews, parseResponse] = await Promise.all([
|
|
368
|
+
((_b = context.options.requestType) == null ? void 0 : _b.toUpperCase()) === "POST" ? requestWithPost(options) : requestWithGet(options),
|
|
369
|
+
requestPreviews(context.options.account),
|
|
370
|
+
import("./requestAds.schema-Cb8_FVMb.js").then((module) => module.parseResponse)
|
|
371
|
+
]);
|
|
546
372
|
logger.debug("Received response", response);
|
|
547
373
|
if (!response.ok)
|
|
548
374
|
throw new Error(`Failed to request ad: ${response.status} ${response.statusText}`);
|
|
@@ -573,7 +399,6 @@ async function requestAds(requestOptions) {
|
|
|
573
399
|
throw error;
|
|
574
400
|
}
|
|
575
401
|
}
|
|
576
|
-
const [runOnRender, onRender] = createAsyncHook("onRender");
|
|
577
402
|
const [runOnSlotCreate, onSlotCreate] = createSyncHook("onSlotCreate");
|
|
578
403
|
function useViewabilityObserver({ context, ad, name: name2, element }) {
|
|
579
404
|
let timeoutId = null;
|
|
@@ -594,12 +419,11 @@ function useViewabilityObserver({ context, ad, name: name2, element }) {
|
|
|
594
419
|
const ratio = round(entry.intersectionRatio, 1);
|
|
595
420
|
if (ratio >= threshold && !timeoutId) {
|
|
596
421
|
timeoutId = setTimeout(() => {
|
|
597
|
-
var _a
|
|
422
|
+
var _a;
|
|
598
423
|
timeoutId = null;
|
|
599
424
|
if ((_a = ad.value) == null ? void 0 : _a.viewableImpressionCounter) {
|
|
600
425
|
trackingPixel.value = addTrackingPixel(ad.value.viewableImpressionCounter);
|
|
601
426
|
logger.debug(`Viewability tracking pixel fired for ${name2.value}`);
|
|
602
|
-
(_c = context.events) == null ? void 0 : _c.changeSlots.dispatch(Array.from(((_b = context.getAll) == null ? void 0 : _b.call(context)) ?? []));
|
|
603
427
|
}
|
|
604
428
|
}, duration);
|
|
605
429
|
} else if (ratio < threshold && timeoutId) {
|
|
@@ -654,6 +478,22 @@ function useRenderIntersectionObserver({ options, element }) {
|
|
|
654
478
|
renderIntersectionObserver.disconnect();
|
|
655
479
|
}];
|
|
656
480
|
}
|
|
481
|
+
function useSlotHooks({ setup }, slotContext, id) {
|
|
482
|
+
const [runOnSlotRender, onRender, disposeOnRender] = createAsyncHook(`onRender:${id}`);
|
|
483
|
+
const [runOnRequest2, onRequest2, disposeOnRequest] = createAsyncHook(`onRequest:${id}`);
|
|
484
|
+
const [runOnDispose2, onDispose2, disposeOnDispose] = createPassiveHook(`onDispose:${id}`);
|
|
485
|
+
setup == null ? void 0 : setup(slotContext, {
|
|
486
|
+
onRender,
|
|
487
|
+
onDispose: onDispose2,
|
|
488
|
+
onRequest: onRequest2
|
|
489
|
+
});
|
|
490
|
+
onDispose2(() => {
|
|
491
|
+
disposeOnRender();
|
|
492
|
+
disposeOnRequest();
|
|
493
|
+
disposeOnDispose();
|
|
494
|
+
});
|
|
495
|
+
return { runOnSlotRender, runOnRequest: runOnRequest2, runOnDispose: runOnDispose2 };
|
|
496
|
+
}
|
|
657
497
|
const renderFunctions = {
|
|
658
498
|
iframe: renderIframe,
|
|
659
499
|
inline: renderInline
|
|
@@ -661,7 +501,10 @@ const renderFunctions = {
|
|
|
661
501
|
function createSlot(slotOptions) {
|
|
662
502
|
const scope = effectScope();
|
|
663
503
|
return scope.run(() => {
|
|
504
|
+
const slotContext = ref(null);
|
|
664
505
|
const options = runOnSlotCreate(slotOptions);
|
|
506
|
+
const id = uniqueId();
|
|
507
|
+
const { runOnSlotRender, runOnDispose: runOnDispose2, runOnRequest: runOnRequest2 } = useSlotHooks(options, slotContext, id);
|
|
665
508
|
const {
|
|
666
509
|
containingElement,
|
|
667
510
|
slot,
|
|
@@ -684,43 +527,34 @@ function createSlot(slotOptions) {
|
|
|
684
527
|
const originalAd = ref(ad.value);
|
|
685
528
|
const name2 = computed(() => generateName(context.location, format.value, slot));
|
|
686
529
|
watch(name2, async (newName, oldName) => {
|
|
687
|
-
var _a;
|
|
688
530
|
if (newName === oldName)
|
|
689
531
|
return;
|
|
690
|
-
(_a = options.onNameChange) == null ? void 0 : _a.call(options, newName, oldName);
|
|
691
532
|
const newAd = await requestAd$1();
|
|
692
533
|
cleanElement();
|
|
693
534
|
ad.value = newAd;
|
|
694
535
|
originalAd.value = newAd;
|
|
695
536
|
});
|
|
696
537
|
const isDomLoaded = useDomLoaded();
|
|
538
|
+
const isDisposed2 = ref(false);
|
|
697
539
|
const element = computed(
|
|
698
540
|
() => {
|
|
699
541
|
if (!(typeof containingElement === "string" || !containingElement))
|
|
700
542
|
return containingElement;
|
|
701
|
-
if (!isDomLoaded.value)
|
|
543
|
+
if (!isDomLoaded.value || isDisposed2.value)
|
|
702
544
|
return null;
|
|
703
545
|
return document.querySelector(`.adunit[data-format="${format.value}"]#${containingElement}${slot ? `[data-slot="${slot}"]` : ""}`);
|
|
704
546
|
}
|
|
705
547
|
);
|
|
706
|
-
function getElement() {
|
|
707
|
-
var _a, _b;
|
|
708
|
-
if (renderMode === "iframe")
|
|
709
|
-
return ((_a = element.value) == null ? void 0 : _a.querySelector("iframe")) ?? null;
|
|
710
|
-
return ((_b = element.value) == null ? void 0 : _b.innerHTML) ? element.value.firstElementChild : null;
|
|
711
|
-
}
|
|
712
548
|
const [isInViewport, disposeRenderIntersectionObserver] = useRenderIntersectionObserver({
|
|
713
549
|
options,
|
|
714
550
|
element
|
|
715
551
|
});
|
|
716
|
-
const
|
|
552
|
+
const status = ref("initializing");
|
|
717
553
|
watch([ad, isInViewport], async ([newAd, newIsInViewport], [oldAd]) => {
|
|
718
|
-
|
|
719
|
-
if ((!newAd || oldAd && isDeepEqual(newAd, oldAd)) && isRendered.value)
|
|
554
|
+
if ((!newAd || oldAd && isDeepEqual(newAd, oldAd)) && status.value === "rendered")
|
|
720
555
|
return;
|
|
721
|
-
if (newIsInViewport
|
|
556
|
+
if (newIsInViewport)
|
|
722
557
|
await render(newAd ?? void 0);
|
|
723
|
-
(_b = context.events) == null ? void 0 : _b.changeSlots.dispatch(Array.from(((_a = context.getAll) == null ? void 0 : _a.call(context)) ?? []));
|
|
724
558
|
});
|
|
725
559
|
watch(isInViewport, (value) => {
|
|
726
560
|
var _a;
|
|
@@ -738,6 +572,8 @@ function createSlot(slotOptions) {
|
|
|
738
572
|
const impressionTrackingPixelElement = ref(null);
|
|
739
573
|
const isImpressionTracked = computed(() => Boolean(impressionTrackingPixelElement.value));
|
|
740
574
|
async function requestAd$1() {
|
|
575
|
+
status.value = "loading";
|
|
576
|
+
await runOnRequest2();
|
|
741
577
|
const response = await requestAd({
|
|
742
578
|
slot: {
|
|
743
579
|
name: name2.value,
|
|
@@ -745,17 +581,27 @@ function createSlot(slotOptions) {
|
|
|
745
581
|
},
|
|
746
582
|
context
|
|
747
583
|
});
|
|
748
|
-
|
|
584
|
+
if (response) {
|
|
585
|
+
ad.value = response;
|
|
586
|
+
if (!originalAd.value)
|
|
587
|
+
originalAd.value = response;
|
|
588
|
+
status.value = response ? "loaded" : "empty";
|
|
589
|
+
}
|
|
749
590
|
return response;
|
|
750
591
|
}
|
|
751
592
|
async function render(adToRender) {
|
|
752
593
|
var _a, _b;
|
|
594
|
+
status.value = "rendering";
|
|
753
595
|
await waitForDomLoad();
|
|
754
596
|
await waitOnInit;
|
|
755
597
|
let renderAd = adToRender ?? ad.value ?? originalAd.value ?? await requestAd$1();
|
|
756
|
-
if (renderAd)
|
|
757
|
-
|
|
758
|
-
|
|
598
|
+
if (!renderAd) {
|
|
599
|
+
status.value = "empty";
|
|
600
|
+
logger.debug(`No ad to render for slot ${name2.value}`);
|
|
601
|
+
return null;
|
|
602
|
+
}
|
|
603
|
+
renderAd = ((_a = options.onBeforeRender) == null ? void 0 : _a.call(options, renderAd)) ?? renderAd;
|
|
604
|
+
renderAd = await runOnSlotRender(renderAd);
|
|
759
605
|
if (!element.value) {
|
|
760
606
|
const error = `Could not create slot for format ${format.value}. No element found.`;
|
|
761
607
|
logger.error(error, options);
|
|
@@ -781,7 +627,7 @@ function createSlot(slotOptions) {
|
|
|
781
627
|
});
|
|
782
628
|
(_b = options.onRender) == null ? void 0 : _b.call(options, element.value);
|
|
783
629
|
ad.value = renderAd;
|
|
784
|
-
|
|
630
|
+
status.value = "rendered";
|
|
785
631
|
return element.value;
|
|
786
632
|
}
|
|
787
633
|
function cleanElement() {
|
|
@@ -801,9 +647,17 @@ function createSlot(slotOptions) {
|
|
|
801
647
|
disposeViewabilityObserver();
|
|
802
648
|
(_b = options.onDispose) == null ? void 0 : _b.call(options);
|
|
803
649
|
queryDetector == null ? void 0 : queryDetector.dispose();
|
|
650
|
+
runOnDispose2();
|
|
651
|
+
isDisposed2.value = true;
|
|
804
652
|
scope.stop();
|
|
805
653
|
}
|
|
806
|
-
|
|
654
|
+
onInit(async () => {
|
|
655
|
+
status.value = "initialized";
|
|
656
|
+
if (options.lazyLoading)
|
|
657
|
+
return;
|
|
658
|
+
ad.value = await requestAd$1();
|
|
659
|
+
});
|
|
660
|
+
const state = reactive({
|
|
807
661
|
location: context.location ?? "",
|
|
808
662
|
lazyLoading: options.lazyLoading ?? false,
|
|
809
663
|
slot,
|
|
@@ -813,10 +667,21 @@ function createSlot(slotOptions) {
|
|
|
813
667
|
ad,
|
|
814
668
|
isViewabilityTracked,
|
|
815
669
|
isImpressionTracked,
|
|
670
|
+
status,
|
|
671
|
+
element,
|
|
672
|
+
isDisposed: isDisposed2,
|
|
673
|
+
id,
|
|
816
674
|
render,
|
|
817
|
-
|
|
675
|
+
request: requestAd$1,
|
|
818
676
|
dispose
|
|
819
|
-
};
|
|
677
|
+
});
|
|
678
|
+
watch(state, (newState) => {
|
|
679
|
+
slotContext.value = newState;
|
|
680
|
+
}, {
|
|
681
|
+
deep: true,
|
|
682
|
+
immediate: true
|
|
683
|
+
});
|
|
684
|
+
return state;
|
|
820
685
|
});
|
|
821
686
|
}
|
|
822
687
|
function useDomLoaded() {
|
|
@@ -838,7 +703,7 @@ async function findDomSlots(context) {
|
|
|
838
703
|
element.dataset.format,
|
|
839
704
|
element.dataset.slot
|
|
840
705
|
);
|
|
841
|
-
return !((_a = context.getAll) == null ? void 0 : _a.call(context).some((activeSlot) => activeSlot.name
|
|
706
|
+
return !((_a = context.getAll) == null ? void 0 : _a.call(context).some((activeSlot) => activeSlot.name === name2));
|
|
842
707
|
}).map((element) => createSlot({
|
|
843
708
|
format: element.dataset.format,
|
|
844
709
|
containingElement: element,
|
|
@@ -846,87 +711,73 @@ async function findDomSlots(context) {
|
|
|
846
711
|
context
|
|
847
712
|
})).filter((slot) => {
|
|
848
713
|
var _a;
|
|
849
|
-
return !((_a = context.getAll) == null ? void 0 : _a.call(context).some((activeSlot) => activeSlot.name
|
|
714
|
+
return !((_a = context.getAll) == null ? void 0 : _a.call(context).some((activeSlot) => activeSlot.name === slot.name));
|
|
850
715
|
});
|
|
851
716
|
}
|
|
852
717
|
function createSlotManager({
|
|
853
718
|
initialSlots = [],
|
|
854
719
|
context
|
|
855
720
|
}) {
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
721
|
+
context.slots = /* @__PURE__ */ new Map();
|
|
722
|
+
function getAll() {
|
|
723
|
+
return Array.from(context.slots).map(([, slot]) => slot);
|
|
724
|
+
}
|
|
725
|
+
function add2(options) {
|
|
726
|
+
var _a;
|
|
727
|
+
const slot = createSlot({
|
|
728
|
+
...options,
|
|
729
|
+
onDispose: onDispose2,
|
|
730
|
+
context
|
|
862
731
|
});
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
function add2(options) {
|
|
867
|
-
var _a;
|
|
868
|
-
const slot = createSlot({
|
|
869
|
-
...options,
|
|
870
|
-
onDispose: onDispose2,
|
|
871
|
-
context
|
|
872
|
-
});
|
|
873
|
-
if (slots.has(slot.name.value)) {
|
|
874
|
-
slot.dispose();
|
|
875
|
-
throw new Error(`Slot with the name: ${slot.name.value} already exists. Create a new slot with a different format, slot, or the location.`);
|
|
876
|
-
}
|
|
877
|
-
const disposeSlotWatch = watch(slot.name, (newName, previousName) => {
|
|
878
|
-
slots.set(newName, slot);
|
|
879
|
-
slots.delete(previousName);
|
|
880
|
-
});
|
|
881
|
-
function onDispose2() {
|
|
882
|
-
var _a2;
|
|
883
|
-
slots.delete(slot.name.value);
|
|
884
|
-
logger.debug("Slot removed", {
|
|
885
|
-
slot,
|
|
886
|
-
slots: Array.from(slots)
|
|
887
|
-
});
|
|
888
|
-
(_a2 = context.events) == null ? void 0 : _a2.removeSlot.dispatch(slot);
|
|
889
|
-
disposeSlotWatch();
|
|
890
|
-
}
|
|
891
|
-
slots.set(slot.name.value, slot);
|
|
892
|
-
logger.debug("Slot added", {
|
|
893
|
-
slot,
|
|
894
|
-
slots: Array.from(slots.values())
|
|
895
|
-
});
|
|
896
|
-
(_a = context.events) == null ? void 0 : _a.addSlot.dispatch(slot);
|
|
897
|
-
return slot;
|
|
898
|
-
}
|
|
899
|
-
async function findDomSlots$1() {
|
|
900
|
-
const domSlots = await findDomSlots(
|
|
901
|
-
context
|
|
902
|
-
);
|
|
903
|
-
for (const slot of domSlots)
|
|
904
|
-
slots.set(slot.name.value, slot);
|
|
905
|
-
return domSlots;
|
|
732
|
+
if (get(slot.name)) {
|
|
733
|
+
slot.dispose();
|
|
734
|
+
throw new Error(`Slot with the name: ${slot.name} already exists. Create a new slot with a different format, slot, or the location.`);
|
|
906
735
|
}
|
|
907
|
-
function
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
slot.dispose();
|
|
913
|
-
slots.clear();
|
|
914
|
-
scope.stop();
|
|
915
|
-
}
|
|
916
|
-
for (const options of initialSlots) {
|
|
917
|
-
add2({
|
|
918
|
-
...options,
|
|
919
|
-
lazyLoading: false
|
|
736
|
+
function onDispose2() {
|
|
737
|
+
var _a2;
|
|
738
|
+
context.slots.delete(slot.id);
|
|
739
|
+
logger.debug("Slot removed", {
|
|
740
|
+
slot
|
|
920
741
|
});
|
|
742
|
+
(_a2 = context.events) == null ? void 0 : _a2.removeSlot.dispatch(slot);
|
|
921
743
|
}
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
}
|
|
744
|
+
context.slots.set(slot.id, slot);
|
|
745
|
+
logger.debug("Slot added", {
|
|
746
|
+
slot,
|
|
747
|
+
slots: Array.from(context.slots.values())
|
|
748
|
+
});
|
|
749
|
+
(_a = context.events) == null ? void 0 : _a.addSlot.dispatch(slot);
|
|
750
|
+
return slot;
|
|
751
|
+
}
|
|
752
|
+
async function findDomSlots$1() {
|
|
753
|
+
const domSlots = await findDomSlots(
|
|
754
|
+
context
|
|
755
|
+
);
|
|
756
|
+
for (const slot of domSlots)
|
|
757
|
+
context.slots.set(slot.id, slot);
|
|
758
|
+
return domSlots;
|
|
759
|
+
}
|
|
760
|
+
function get(name2) {
|
|
761
|
+
return getAll().find((slot) => slot.name === name2);
|
|
762
|
+
}
|
|
763
|
+
function dispose() {
|
|
764
|
+
for (const slot of context.slots.values())
|
|
765
|
+
slot.dispose();
|
|
766
|
+
context.slots.clear();
|
|
767
|
+
}
|
|
768
|
+
for (const options of initialSlots) {
|
|
769
|
+
add2({
|
|
770
|
+
...options,
|
|
771
|
+
lazyLoading: false
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
return {
|
|
775
|
+
getAll,
|
|
776
|
+
add: add2,
|
|
777
|
+
findDomSlots: findDomSlots$1,
|
|
778
|
+
get,
|
|
779
|
+
dispose
|
|
780
|
+
};
|
|
930
781
|
}
|
|
931
782
|
function onTcfConsentChange(callback) {
|
|
932
783
|
var _a;
|
|
@@ -1005,6 +856,7 @@ function createAdhese(options) {
|
|
|
1005
856
|
isDisposed: false,
|
|
1006
857
|
parameters: /* @__PURE__ */ new Map(),
|
|
1007
858
|
events: createEventManager(),
|
|
859
|
+
slots: /* @__PURE__ */ new Map(),
|
|
1008
860
|
dispose,
|
|
1009
861
|
findDomSlots: findDomSlots2,
|
|
1010
862
|
getAll,
|
|
@@ -1014,10 +866,9 @@ function createAdhese(options) {
|
|
|
1014
866
|
for (const [index, plugin] of mergedOptions.plugins.entries()) {
|
|
1015
867
|
plugin(context, {
|
|
1016
868
|
index,
|
|
1017
|
-
version
|
|
869
|
+
version,
|
|
1018
870
|
onInit,
|
|
1019
871
|
onDispose,
|
|
1020
|
-
onRender,
|
|
1021
872
|
onRequest,
|
|
1022
873
|
onResponse,
|
|
1023
874
|
onSlotCreate
|
|
@@ -1047,16 +898,12 @@ function createAdhese(options) {
|
|
|
1047
898
|
deep: true
|
|
1048
899
|
}
|
|
1049
900
|
);
|
|
1050
|
-
const debouncedFetchAllUnrenderedSlots = debounce(fetchAllUnrenderedSlots, {
|
|
1051
|
-
waitMs: 100,
|
|
1052
|
-
timing: "both"
|
|
1053
|
-
});
|
|
1054
901
|
async function onQueryChange() {
|
|
1055
902
|
var _a, _b;
|
|
1056
903
|
const query = queryDetector.getQuery();
|
|
1057
904
|
(_a = context.parameters) == null ? void 0 : _a.set("dt", query);
|
|
1058
905
|
(_b = context.parameters) == null ? void 0 : _b.set("br", query);
|
|
1059
|
-
await
|
|
906
|
+
await fetchAllUnrenderedSlots();
|
|
1060
907
|
}
|
|
1061
908
|
watch(() => context.consent, (newConsent) => {
|
|
1062
909
|
var _a, _b;
|
|
@@ -1085,15 +932,7 @@ function createAdhese(options) {
|
|
|
1085
932
|
const domSlots = (await slotManager.findDomSlots() ?? []).filter((slot) => !slot.lazyLoading);
|
|
1086
933
|
if (domSlots.length <= 0)
|
|
1087
934
|
return [];
|
|
1088
|
-
|
|
1089
|
-
slot,
|
|
1090
|
-
context
|
|
1091
|
-
})));
|
|
1092
|
-
for (const ad of ads) {
|
|
1093
|
-
const slot = slotManager.get(ad.slotName);
|
|
1094
|
-
if (slot)
|
|
1095
|
-
slot.ad.value = ad;
|
|
1096
|
-
}
|
|
935
|
+
await fetchAllUnrenderedSlots();
|
|
1097
936
|
return domSlots;
|
|
1098
937
|
}
|
|
1099
938
|
context.findDomSlots = findDomSlots2;
|
|
@@ -1112,18 +951,10 @@ function createAdhese(options) {
|
|
|
1112
951
|
immediate: true
|
|
1113
952
|
});
|
|
1114
953
|
async function fetchAllUnrenderedSlots() {
|
|
1115
|
-
const slots = (slotManager.getAll() ?? []).filter((slot) => !slot.lazyLoading && !slot.ad
|
|
954
|
+
const slots = (slotManager.getAll() ?? []).filter((slot) => !slot.lazyLoading && !slot.ad);
|
|
1116
955
|
if (slots.length === 0)
|
|
1117
956
|
return;
|
|
1118
|
-
|
|
1119
|
-
slot,
|
|
1120
|
-
context
|
|
1121
|
-
})));
|
|
1122
|
-
for (const ad of ads) {
|
|
1123
|
-
const slot = slotManager.get(ad.slotName);
|
|
1124
|
-
if (slot)
|
|
1125
|
-
slot.ad.value = ad;
|
|
1126
|
-
}
|
|
957
|
+
await Promise.allSettled(slots.map((slot) => slot.request()));
|
|
1127
958
|
}
|
|
1128
959
|
const disposeOnTcfConsentChange = onTcfConsentChange(async (data) => {
|
|
1129
960
|
var _a, _b;
|
|
@@ -1134,7 +965,7 @@ function createAdhese(options) {
|
|
|
1134
965
|
});
|
|
1135
966
|
(_a = context.parameters) == null ? void 0 : _a.set("xt", data.tcString);
|
|
1136
967
|
(_b = context.parameters) == null ? void 0 : _b.delete("tl");
|
|
1137
|
-
await
|
|
968
|
+
await fetchAllUnrenderedSlots();
|
|
1138
969
|
});
|
|
1139
970
|
function dispose() {
|
|
1140
971
|
var _a, _b;
|
|
@@ -1154,6 +985,7 @@ function createAdhese(options) {
|
|
|
1154
985
|
context.dispose = dispose;
|
|
1155
986
|
onInit(async () => {
|
|
1156
987
|
var _a;
|
|
988
|
+
await awaitTimeout(0);
|
|
1157
989
|
if ((slotManager.getAll().length ?? 0) > 0)
|
|
1158
990
|
await fetchAllUnrenderedSlots().catch(logger.error);
|
|
1159
991
|
if (mergedOptions.findDomSlotsOnLoad)
|
|
@@ -1168,8 +1000,29 @@ function createAdhese(options) {
|
|
|
1168
1000
|
});
|
|
1169
1001
|
}
|
|
1170
1002
|
export {
|
|
1003
|
+
computed2 as computed,
|
|
1171
1004
|
createAdhese,
|
|
1172
|
-
|
|
1173
|
-
|
|
1005
|
+
customRef,
|
|
1006
|
+
effectScope2 as effectScope,
|
|
1007
|
+
isProxy,
|
|
1008
|
+
isReactive,
|
|
1009
|
+
isReadonly,
|
|
1010
|
+
isRef,
|
|
1011
|
+
isShallow,
|
|
1012
|
+
markRaw,
|
|
1013
|
+
reactive2 as reactive,
|
|
1014
|
+
readonly,
|
|
1015
|
+
ref2 as ref,
|
|
1016
|
+
shallowReactive,
|
|
1017
|
+
shallowReadonly,
|
|
1018
|
+
shallowRef,
|
|
1019
|
+
toRaw,
|
|
1020
|
+
toRefs,
|
|
1021
|
+
toValue2 as toValue,
|
|
1022
|
+
unref,
|
|
1023
|
+
watch2 as watch,
|
|
1024
|
+
watchEffect,
|
|
1025
|
+
watchPostEffect,
|
|
1026
|
+
watchSyncEffect
|
|
1174
1027
|
};
|
|
1175
1028
|
//# sourceMappingURL=index.js.map
|