@adhese/sdk 0.4.0 → 0.5.1

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/dist/es/index.js CHANGED
@@ -1,12 +1,7 @@
1
- var __defProp = Object.defineProperty;
2
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => {
4
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
- return value;
6
- };
7
1
  import { createDevtools } from "@adhese/sdk-devtools";
8
- import { debounce, uniqueId, random, round } from "lodash-es";
9
- import { union, coerce, literal, object, string, unknown, lazy } from "zod";
2
+ import { effectScope, shallowReactive, watchEffect, watch, reactive, ref, computed, toValue } from "@vue/runtime-core";
3
+ import { debounce, uniqueId, random, round, isEqual } from "lodash-es";
4
+ import { union, coerce, literal, number, string, ZodIssueCode, NEVER, object, unknown, lazy } from "zod";
10
5
  async function waitForDomLoad() {
11
6
  return new Promise((resolve) => {
12
7
  function onDomLoad() {
@@ -66,91 +61,132 @@ function createEvent() {
66
61
  removeListener
67
62
  };
68
63
  }
64
+ function renderIframe(ad, element) {
65
+ const iframe = document.createElement("iframe");
66
+ iframe.srcdoc = `
67
+ <!DOCTYPE html>
68
+ <html>
69
+ <head>
70
+ <style>
71
+ body {
72
+ margin: 0;
73
+ padding: 0;
74
+ overflow: hidden;
75
+ }
76
+ </style>
77
+ </head>
78
+ <body>
79
+ ${String(ad.tag)}
80
+ </body>
81
+ `.replaceAll(/\s+/g, " ").trim();
82
+ iframe.style.border = "none";
83
+ iframe.style.width = ad.width ?? "auto";
84
+ iframe.style.height = ad.height ?? "auto";
85
+ element.replaceChildren(iframe);
86
+ }
87
+ function renderInline(ad, element) {
88
+ element.style.width = ad.width ?? "auto";
89
+ element.style.height = ad.height ?? "auto";
90
+ element.innerHTML = String(ad.tag);
91
+ }
92
+ function generateName(location, format, slot) {
93
+ return `${location}${slot ? `${slot}` : ""}-${format}`;
94
+ }
69
95
  async function findDomSlots(context) {
70
96
  await waitForDomLoad();
71
- return (await Promise.all(Array.from(document.querySelectorAll(".adunit")).filter((element) => Boolean(element.dataset.format)).map((element) => createSlot({
97
+ return Array.from(document.querySelectorAll(".adunit")).filter((element) => {
98
+ var _a;
99
+ if (!element.dataset.format)
100
+ return false;
101
+ const name = generateName(
102
+ context.location,
103
+ element.dataset.format,
104
+ element.dataset.slot
105
+ );
106
+ return !((_a = context.getAll) == null ? void 0 : _a.call(context).some((activeSlot) => activeSlot.name.value === name));
107
+ }).map((element) => createSlot({
72
108
  format: element.dataset.format,
73
109
  containingElement: element,
74
110
  slot: element.dataset.slot,
75
111
  context
76
- })))).filter((slot) => {
112
+ })).filter((slot) => {
77
113
  var _a;
78
- return !((_a = context.getAll) == null ? void 0 : _a.call(context).some((activeSlot) => activeSlot.getName() === slot.getName()));
114
+ return !((_a = context.getAll) == null ? void 0 : _a.call(context).some((activeSlot) => activeSlot.name.value === slot.name.value));
79
115
  });
80
116
  }
81
- async function createSlotManager({
117
+ function createSlotManager({
82
118
  initialSlots = [],
83
119
  context
84
120
  }) {
85
- const slots = /* @__PURE__ */ new Map();
86
- await Promise.allSettled(initialSlots.map(async (slot) => add({
87
- ...slot,
88
- lazyLoading: false
89
- })));
90
- function getAll() {
91
- return Array.from(slots).map(([, slot]) => slot);
92
- }
93
- async function add(options) {
94
- var _a, _b;
95
- const slot = await createSlot({
96
- ...options,
97
- onDispose,
98
- onNameChange,
99
- context
121
+ const scope = effectScope();
122
+ return scope.run(() => {
123
+ const slots = shallowReactive(/* @__PURE__ */ new Map());
124
+ watchEffect(() => {
125
+ var _a;
126
+ (_a = context.events) == null ? void 0 : _a.changeSlots.dispatch(Array.from(slots.values()));
100
127
  });
101
- function onDispose() {
102
- var _a2, _b2;
103
- slots.delete(slot.getName());
104
- logger.debug("Slot removed", {
128
+ function getAll() {
129
+ return Array.from(slots).map(([, slot]) => slot);
130
+ }
131
+ function add(options) {
132
+ var _a;
133
+ const slot = createSlot({
134
+ ...options,
135
+ onDispose,
136
+ context
137
+ });
138
+ function onDispose() {
139
+ var _a2;
140
+ slots.delete(slot.name.value);
141
+ logger.debug("Slot removed", {
142
+ slot,
143
+ slots: Array.from(slots)
144
+ });
145
+ (_a2 = context.events) == null ? void 0 : _a2.removeSlot.dispatch(slot);
146
+ }
147
+ slots.set(slot.name.value, slot);
148
+ watch(slot.name, (newName, previousName) => {
149
+ slots.set(newName, slot);
150
+ slots.delete(previousName);
151
+ });
152
+ logger.debug("Slot added", {
105
153
  slot,
106
- slots: Array.from(slots)
154
+ slots: Array.from(slots.values())
107
155
  });
108
- (_a2 = context.events) == null ? void 0 : _a2.removeSlot.dispatch(slot);
109
- (_b2 = context.events) == null ? void 0 : _b2.changeSlots.dispatch(Array.from(slots.values()));
156
+ (_a = context.events) == null ? void 0 : _a.addSlot.dispatch(slot);
157
+ return slot;
110
158
  }
111
- slots.set(slot.getName(), slot);
112
- function onNameChange(newName, previousName) {
113
- var _a2;
114
- slots.set(newName, slot);
115
- slots.delete(previousName);
116
- (_a2 = context.events) == null ? void 0 : _a2.changeSlots.dispatch(Array.from(slots.values()));
159
+ async function findDomSlots$1() {
160
+ const domSlots = await findDomSlots(
161
+ context
162
+ );
163
+ for (const slot of domSlots)
164
+ slots.set(slot.name.value, slot);
165
+ return domSlots;
117
166
  }
118
- logger.debug("Slot added", {
119
- slot,
120
- slots: Array.from(slots.values())
121
- });
122
- (_a = context.events) == null ? void 0 : _a.addSlot.dispatch(slot);
123
- (_b = context.events) == null ? void 0 : _b.changeSlots.dispatch(Array.from(slots.values()));
124
- return slot;
125
- }
126
- async function findDomSlots$1() {
127
- var _a;
128
- const domSlots = await findDomSlots(
129
- context
130
- );
131
- for (const slot of domSlots) {
132
- slots.set(slot.getName(), slot);
133
- (_a = context.events) == null ? void 0 : _a.changeSlots.dispatch(Array.from(slots.values()));
167
+ function get(name) {
168
+ return slots.get(name);
134
169
  }
135
- return domSlots;
136
- }
137
- function get(name) {
138
- return slots.get(name);
139
- }
140
- function dispose() {
141
- var _a;
142
- for (const slot of slots.values())
143
- slot.dispose();
144
- slots.clear();
145
- (_a = context.events) == null ? void 0 : _a.changeSlots.dispatch(Array.from(slots.values()));
146
- }
147
- return {
148
- getAll,
149
- add,
150
- findDomSlots: findDomSlots$1,
151
- get,
152
- dispose
153
- };
170
+ function dispose() {
171
+ for (const slot of slots.values())
172
+ slot.dispose();
173
+ slots.clear();
174
+ scope.stop();
175
+ }
176
+ for (const options of initialSlots) {
177
+ add({
178
+ ...options,
179
+ lazyLoading: false
180
+ });
181
+ }
182
+ return {
183
+ getAll,
184
+ add,
185
+ findDomSlots: findDomSlots$1,
186
+ get,
187
+ dispose
188
+ };
189
+ });
154
190
  }
155
191
  function onTcfConsentChange(callback) {
156
192
  var _a;
@@ -270,7 +306,7 @@ const logger = createLogger({
270
306
  scope: "Adhese SDK"
271
307
  });
272
308
  function createParameters(options, queryDetector) {
273
- const parameters = new MapWithEvents();
309
+ const parameters = /* @__PURE__ */ new Map();
274
310
  if (options.logReferrer)
275
311
  parameters.set("re", btoa(document.referrer));
276
312
  if (options.logUrl)
@@ -297,230 +333,234 @@ function setupLogging(mergedOptions) {
297
333
  function isPreviewMode() {
298
334
  return window.location.search.includes("adhesePreviewCreativeId");
299
335
  }
300
- class MapWithEvents extends Map {
301
- constructor() {
302
- super(...arguments);
303
- __publicField(this, "listeners", /* @__PURE__ */ new Set());
336
+ function createHook({
337
+ onRun,
338
+ onAdd
339
+ }) {
340
+ const callbacks = /* @__PURE__ */ new Set();
341
+ function run() {
342
+ for (const callback of callbacks)
343
+ callback();
344
+ onRun == null ? void 0 : onRun(callbacks);
304
345
  }
305
- addEventListener(listener) {
306
- this.listeners.add(listener);
346
+ function add(callback) {
347
+ callbacks.add(callback);
348
+ onAdd == null ? void 0 : onAdd(callbacks);
307
349
  }
308
- removeEventListener(listener) {
309
- this.listeners.delete(listener);
350
+ return [run, add];
351
+ }
352
+ let resolveOnInitPromise = () => {
353
+ };
354
+ let isInit = false;
355
+ new Promise((resolve) => {
356
+ resolveOnInitPromise = resolve;
357
+ });
358
+ const [runOnInit, onInit] = createHook({
359
+ onRun(callbacks) {
360
+ isInit = true;
361
+ resolveOnInitPromise();
362
+ logger.debug("Initialization completed");
363
+ callbacks.clear();
364
+ },
365
+ onAdd() {
366
+ if (isInit)
367
+ runOnInit();
310
368
  }
311
- set(key, value) {
312
- const set = super.set(key, value);
313
- this.listeners.forEach((listener) => {
314
- listener();
369
+ });
370
+ function createAdhese(options) {
371
+ const scope = effectScope();
372
+ return scope.run(() => {
373
+ const mergedOptions = {
374
+ host: `https://ads-${options.account}.adhese.com`,
375
+ poolHost: `https://pool-${options.account}.adhese.com`,
376
+ location: "homepage",
377
+ requestType: "POST",
378
+ debug: false,
379
+ initialSlots: [],
380
+ findDomSlotsOnLoad: false,
381
+ consent: false,
382
+ logReferrer: true,
383
+ logUrl: true,
384
+ eagerRendering: false,
385
+ viewabilityTracking: true,
386
+ ...options
387
+ };
388
+ setupLogging(mergedOptions);
389
+ const context = reactive({
390
+ location: mergedOptions.location,
391
+ consent: mergedOptions.consent,
392
+ debug: mergedOptions.debug,
393
+ getAll,
394
+ get,
395
+ options: mergedOptions,
396
+ logger
315
397
  });
316
- return set;
317
- }
318
- clear() {
319
- super.clear();
320
- this.listeners.forEach((listener) => {
321
- listener();
398
+ context.events = createEventManager();
399
+ function getLocation() {
400
+ return context.location;
401
+ }
402
+ function setLocation(newLocation) {
403
+ var _a;
404
+ context.location = newLocation;
405
+ (_a = context.events) == null ? void 0 : _a.locationChange.dispatch(newLocation);
406
+ }
407
+ const queryDetector = createQueryDetector({
408
+ onChange: onQueryChange,
409
+ queries: mergedOptions.queries
322
410
  });
323
- }
324
- delete(key) {
325
- const deleted = super.delete(key);
326
- this.listeners.forEach((listener) => {
327
- listener();
411
+ context.parameters = createParameters(mergedOptions, queryDetector);
412
+ watch(
413
+ context.parameters,
414
+ onParametersChange,
415
+ {
416
+ deep: true,
417
+ immediate: true
418
+ }
419
+ );
420
+ function onParametersChange() {
421
+ var _a;
422
+ if (context.parameters)
423
+ (_a = context.events) == null ? void 0 : _a.parametersChange.dispatch(context.parameters);
424
+ }
425
+ async function onQueryChange() {
426
+ var _a, _b;
427
+ const query = queryDetector.getQuery();
428
+ (_a = context.parameters) == null ? void 0 : _a.set("dt", query);
429
+ (_b = context.parameters) == null ? void 0 : _b.set("br", query);
430
+ await fetchAndRenderAllSlots();
431
+ }
432
+ function getConsent() {
433
+ return context.consent;
434
+ }
435
+ function setConsent(newConsent) {
436
+ var _a, _b;
437
+ (_a = context.parameters) == null ? void 0 : _a.set("tl", newConsent ? "all" : "none");
438
+ context.consent = newConsent;
439
+ (_b = context.events) == null ? void 0 : _b.consentChange.dispatch(newConsent);
440
+ }
441
+ const slotManager = createSlotManager({
442
+ initialSlots: mergedOptions.initialSlots,
443
+ context
328
444
  });
329
- return deleted;
330
- }
331
- /**
332
- * Remove all listeners and clear the map.
333
- */
334
- dispose() {
335
- this.listeners.clear();
336
- super.clear();
337
- }
338
- }
339
- async function createAdhese(options) {
340
- var _a;
341
- const mergedOptions = {
342
- host: `https://ads-${options.account}.adhese.com`,
343
- poolHost: `https://pool-${options.account}.adhese.com`,
344
- location: "homepage",
345
- requestType: "POST",
346
- debug: false,
347
- initialSlots: [],
348
- findDomSlotsOnLoad: false,
349
- consent: false,
350
- logReferrer: true,
351
- logUrl: true,
352
- eagerRendering: false,
353
- viewabilityTracking: true,
354
- ...options
355
- };
356
- setupLogging(mergedOptions);
357
- const context = new Proxy({
358
- location: mergedOptions.location,
359
- consent: mergedOptions.consent,
360
- debug: mergedOptions.debug,
361
- getAll,
362
- get,
363
- options: mergedOptions,
364
- logger
365
- }, {});
366
- context.events = createEventManager();
367
- function getLocation() {
368
- return context.location;
369
- }
370
- function setLocation(newLocation) {
371
- var _a2;
372
- context.location = newLocation;
373
- (_a2 = context.events) == null ? void 0 : _a2.locationChange.dispatch(newLocation);
374
- }
375
- const queryDetector = createQueryDetector({
376
- onChange: onQueryChange,
377
- queries: mergedOptions.queries
378
- });
379
- context.parameters = createParameters(mergedOptions, queryDetector);
380
- context.parameters.addEventListener(onParametersChange);
381
- let unmountDevtools;
382
- if (mergedOptions.debug || window.location.search.includes("adhese_debug=true") || isPreviewMode()) {
383
- unmountDevtools = await createDevtools(context);
384
- (_a = context.events) == null ? void 0 : _a.debugChange.dispatch(true);
385
- }
386
- function onParametersChange() {
387
- var _a2;
388
- if (context.parameters)
389
- (_a2 = context.events) == null ? void 0 : _a2.parametersChange.dispatch(context.parameters);
390
- }
391
- async function onQueryChange() {
392
- var _a2, _b;
393
- const query = queryDetector.getQuery();
394
- (_a2 = context.parameters) == null ? void 0 : _a2.set("dt", query);
395
- (_b = context.parameters) == null ? void 0 : _b.set("br", query);
396
- await fetchAndRenderAllSlots();
397
- }
398
- function getConsent() {
399
- return context.consent;
400
- }
401
- function setConsent(newConsent) {
402
- var _a2, _b;
403
- (_a2 = context.parameters) == null ? void 0 : _a2.set("tl", newConsent ? "all" : "none");
404
- context.consent = newConsent;
405
- (_b = context.events) == null ? void 0 : _b.consentChange.dispatch(newConsent);
406
- }
407
- const slotManager = await createSlotManager({
408
- initialSlots: mergedOptions.initialSlots,
409
- context
410
- });
411
- function getAll() {
412
- return slotManager.getAll();
413
- }
414
- function get(name) {
415
- return slotManager.get(name);
416
- }
417
- async function addSlot(slotOptions) {
418
- const slot = await slotManager.add(slotOptions);
419
- if (!slot.lazyLoading) {
420
- const ad = await requestAd({
421
- slot,
422
- host: mergedOptions.host,
423
- parameters: context.parameters,
424
- account: mergedOptions.account,
445
+ function getAll() {
446
+ return slotManager.getAll() ?? [];
447
+ }
448
+ function get(name) {
449
+ return slotManager.get(name);
450
+ }
451
+ async function addSlot(slotOptions) {
452
+ if (!slotManager)
453
+ throw new Error("Slot manager not initialized");
454
+ const slot = slotManager.add(slotOptions);
455
+ if (!slot.lazyLoading) {
456
+ slot.ad.value = await requestAd({
457
+ slot,
458
+ context
459
+ });
460
+ }
461
+ return slot;
462
+ }
463
+ async function findDomSlots2() {
464
+ const domSlots = (await slotManager.findDomSlots() ?? []).filter((slot) => !slot.lazyLoading);
465
+ if (domSlots.length <= 0)
466
+ return [];
467
+ const ads = await requestAds({
468
+ slots: domSlots,
425
469
  context
426
470
  });
427
- await slot.setAd(ad);
471
+ for (const ad of ads) {
472
+ const slot = slotManager.get(ad.slotName);
473
+ if (slot)
474
+ slot.ad.value = ad;
475
+ }
476
+ return domSlots;
428
477
  }
429
- return slot;
430
- }
431
- async function findDomSlots2() {
432
- const domSlots = (await slotManager.findDomSlots()).filter((slot) => !slot.lazyLoading);
433
- const ads = await requestAds({
434
- host: mergedOptions.host,
435
- slots: domSlots,
436
- method: mergedOptions.requestType,
437
- account: mergedOptions.account,
438
- parameters: context.parameters,
439
- context
478
+ let unmountDevtools;
479
+ async function toggleDebug() {
480
+ var _a, _b;
481
+ context.debug = !context.debug;
482
+ if (context.debug && !unmountDevtools) {
483
+ unmountDevtools = await createDevtools(context);
484
+ logger.setMinLogLevelThreshold("debug");
485
+ logger.debug("Debug mode enabled");
486
+ (_a = context.events) == null ? void 0 : _a.debugChange.dispatch(true);
487
+ } else {
488
+ logger.debug("Debug mode disabled");
489
+ unmountDevtools == null ? void 0 : unmountDevtools();
490
+ unmountDevtools = void 0;
491
+ logger.setMinLogLevelThreshold("info");
492
+ (_b = context.events) == null ? void 0 : _b.debugChange.dispatch(false);
493
+ }
494
+ return context.debug;
495
+ }
496
+ async function fetchAndRenderAllSlots() {
497
+ const slots = (slotManager.getAll() ?? []).filter((slot) => !slot.lazyLoading);
498
+ if (slots.length === 0)
499
+ return;
500
+ const ads = await requestAds({
501
+ slots,
502
+ context
503
+ });
504
+ for (const ad of ads) {
505
+ const slot = slotManager.get(ad.slotName);
506
+ if (slot)
507
+ slot.ad.value = ad;
508
+ }
509
+ }
510
+ const disposeOnTcfConsentChange = onTcfConsentChange(async (data) => {
511
+ var _a, _b;
512
+ if (!data.tcString)
513
+ return;
514
+ logger.debug("TCF v2 consent data received", {
515
+ data
516
+ });
517
+ (_a = context.parameters) == null ? void 0 : _a.set("xt", data.tcString);
518
+ (_b = context.parameters) == null ? void 0 : _b.delete("tl");
519
+ await fetchAndRenderAllSlots();
440
520
  });
441
- await Promise.allSettled(ads.map((ad) => {
442
- var _a2;
443
- return (_a2 = slotManager.get(ad.slotName)) == null ? void 0 : _a2.setAd(ad);
444
- }));
445
- return domSlots;
446
- }
447
- async function toggleDebug() {
448
- var _a2, _b;
449
- context.debug = !context.debug;
450
- if (context.debug && !unmountDevtools) {
451
- unmountDevtools = await createDevtools(context);
452
- logger.setMinLogLevelThreshold("debug");
453
- logger.debug("Debug mode enabled");
454
- (_a2 = context.events) == null ? void 0 : _a2.debugChange.dispatch(true);
455
- } else {
456
- logger.debug("Debug mode disabled");
521
+ function dispose() {
522
+ var _a, _b;
457
523
  unmountDevtools == null ? void 0 : unmountDevtools();
458
- unmountDevtools = void 0;
459
- logger.setMinLogLevelThreshold("info");
460
- (_b = context.events) == null ? void 0 : _b.debugChange.dispatch(false);
524
+ queryDetector.dispose();
525
+ slotManager.dispose();
526
+ queryDetector.dispose();
527
+ disposeOnTcfConsentChange();
528
+ (_a = context.parameters) == null ? void 0 : _a.clear();
529
+ logger.resetLogs();
530
+ (_b = context.events) == null ? void 0 : _b.dispose();
531
+ logger.info("Adhese instance disposed");
532
+ scope.stop();
461
533
  }
462
- return context.debug;
463
- }
464
- async function fetchAndRenderAllSlots() {
465
- const slots = slotManager.getAll().filter((slot) => !slot.lazyLoading);
466
- if (slots.length === 0)
467
- return;
468
- const ads = await requestAds({
469
- host: mergedOptions.host,
470
- slots,
471
- method: mergedOptions.requestType,
472
- account: mergedOptions.account,
534
+ onInit(async () => {
535
+ var _a;
536
+ if ((slotManager.getAll().length ?? 0) > 0)
537
+ await fetchAndRenderAllSlots().catch(logger.error);
538
+ if (mergedOptions.findDomSlotsOnLoad)
539
+ await findDomSlots2();
540
+ if (mergedOptions.debug || window.location.search.includes("adhese_debug=true") || isPreviewMode()) {
541
+ unmountDevtools = await createDevtools(context);
542
+ (_a = context.events) == null ? void 0 : _a.debugChange.dispatch(true);
543
+ }
544
+ if (!scope.active)
545
+ dispose();
546
+ });
547
+ runOnInit();
548
+ return {
549
+ ...mergedOptions,
550
+ ...slotManager,
473
551
  parameters: context.parameters,
552
+ events: context.events,
553
+ getLocation,
554
+ setLocation,
555
+ getConsent,
556
+ setConsent,
557
+ addSlot,
558
+ findDomSlots: findDomSlots2,
559
+ dispose,
560
+ toggleDebug,
474
561
  context
475
- });
476
- await Promise.allSettled(ads.map((ad) => {
477
- var _a2;
478
- return (_a2 = slotManager.get(ad.slotName)) == null ? void 0 : _a2.setAd(ad);
479
- }));
480
- }
481
- const disposeOnTcfConsentChange = onTcfConsentChange(async (data) => {
482
- var _a2, _b;
483
- if (!data.tcString)
484
- return;
485
- logger.debug("TCF v2 consent data received", {
486
- data
487
- });
488
- (_a2 = context.parameters) == null ? void 0 : _a2.set("xt", data.tcString);
489
- (_b = context.parameters) == null ? void 0 : _b.delete("tl");
490
- await fetchAndRenderAllSlots();
562
+ };
491
563
  });
492
- if (slotManager.getAll().length > 0)
493
- await fetchAndRenderAllSlots().catch(logger.error);
494
- function dispose() {
495
- var _a2, _b, _c;
496
- queryDetector.dispose();
497
- slotManager.dispose();
498
- queryDetector.dispose();
499
- disposeOnTcfConsentChange();
500
- (_a2 = context.parameters) == null ? void 0 : _a2.dispose();
501
- (_b = context.parameters) == null ? void 0 : _b.clear();
502
- logger.resetLogs();
503
- (_c = context.events) == null ? void 0 : _c.dispose();
504
- unmountDevtools == null ? void 0 : unmountDevtools();
505
- logger.info("Adhese instance disposed");
506
- }
507
- if (mergedOptions.findDomSlotsOnLoad)
508
- await slotManager.findDomSlots();
509
- return {
510
- ...mergedOptions,
511
- ...slotManager,
512
- parameters: context.parameters,
513
- events: context.events,
514
- getLocation,
515
- setLocation,
516
- getConsent,
517
- setConsent,
518
- addSlot,
519
- findDomSlots: findDomSlots2,
520
- dispose,
521
- toggleDebug,
522
- context
523
- };
524
564
  }
525
565
  function addTrackingPixel(url) {
526
566
  const img = document.createElement("img");
@@ -533,119 +573,7 @@ function addTrackingPixel(url) {
533
573
  img.style.top = "0";
534
574
  return document.body.appendChild(img);
535
575
  }
536
- function renderIframe(ad, element) {
537
- const iframe = document.createElement("iframe");
538
- iframe.srcdoc = `
539
- <!DOCTYPE html>
540
- <html>
541
- <head>
542
- <style>
543
- body {
544
- margin: 0;
545
- padding: 0;
546
- overflow: hidden;
547
- }
548
- </style>
549
- </head>
550
- <body>
551
- ${ad.tag}
552
- </body>
553
- `.replaceAll(/\s+/g, " ").trim();
554
- iframe.style.border = "none";
555
- iframe.style.width = ad.width ? `${ad.width}px` : "100%";
556
- iframe.style.height = ad.height ? `${ad.height}px` : "100%";
557
- element.replaceChildren(iframe);
558
- }
559
- function renderInline(ad, element) {
560
- element.style.width = ad.width ? `${ad.width}px` : "100%";
561
- element.style.height = ad.height ? `${ad.height}px` : "100%";
562
- element.innerHTML = ad.tag;
563
- }
564
- const renderFunctions = {
565
- iframe: renderIframe,
566
- inline: renderInline
567
- };
568
- async function createSlot(options) {
569
- var _a;
570
- const {
571
- containingElement,
572
- slot,
573
- context,
574
- renderMode = "iframe"
575
- } = options;
576
- await waitForDomLoad();
577
- const parameters = new Map(Object.entries(options.parameters ?? {}));
578
- let format;
579
- let queryDetector = null;
580
- if (typeof options.format === "string") {
581
- format = options.format;
582
- } else {
583
- queryDetector = createQueryDetector({
584
- onChange: setFormat,
585
- queries: Object.fromEntries(options.format.map((item) => [item.format, item.query]))
586
- });
587
- format = queryDetector.getQuery();
588
- }
589
- async function setFormat(newFormat) {
590
- var _a2;
591
- const oldName = getName();
592
- format = newFormat;
593
- (_a2 = options.onNameChange) == null ? void 0 : _a2.call(options, getName(), oldName);
594
- const newAd = await requestAd({
595
- slot: {
596
- getName,
597
- parameters
598
- },
599
- account: context.options.account,
600
- host: context.options.host,
601
- parameters: context.parameters,
602
- method: context.options.requestType,
603
- context
604
- });
605
- cleanElement();
606
- await setAd(newAd);
607
- }
608
- function getFormat() {
609
- return format;
610
- }
611
- let element = typeof containingElement === "string" || !containingElement ? document.querySelector(`.adunit[data-format="${format}"]#${containingElement}${slot ? `[data-slot="${slot}"]` : ""}`) : containingElement;
612
- function getElement() {
613
- if (renderMode === "iframe")
614
- return (element == null ? void 0 : element.querySelector("iframe")) ?? null;
615
- return (element == null ? void 0 : element.innerHTML) ? element.firstElementChild : null;
616
- }
617
- let impressionTrackingPixelElement = null;
618
- let viewabilityTrackingPixelElement = null;
619
- let isInViewport = false;
620
- let ad = null;
621
- function getAd() {
622
- return ad;
623
- }
624
- async function setAd(newAd) {
625
- var _a2, _b;
626
- ad = newAd;
627
- if (isInViewport || context.options.eagerRendering)
628
- await render(ad);
629
- if (element) {
630
- element.style.width = `${ad.width}px`;
631
- element.style.height = `${ad.height}px`;
632
- }
633
- await ((_b = context.events) == null ? void 0 : _b.changeSlots.dispatchAsync(Array.from(((_a2 = context.getAll) == null ? void 0 : _a2.call(context)) ?? [])));
634
- }
635
- const renderIntersectionObserver = new IntersectionObserver((entries) => {
636
- isInViewport = entries.some((entry) => entry.isIntersecting);
637
- if (isInViewport) {
638
- (async () => {
639
- if (!ad && options.lazyLoading)
640
- await render();
641
- else if (ad)
642
- await render(ad);
643
- })().catch(logger.error);
644
- }
645
- }, {
646
- rootMargin: ((_a = options.lazyLoadingOptions) == null ? void 0 : _a.rootMargin) ?? "200px",
647
- threshold: 0
648
- });
576
+ function useViewabilityObserver({ context, ad, name, element }) {
649
577
  let timeoutId = null;
650
578
  const {
651
579
  threshold,
@@ -657,17 +585,19 @@ async function createSlot(options) {
657
585
  rootMargin: "0px",
658
586
  ...context.options.viewabilityTrackingOptions
659
587
  };
588
+ const trackingPixel = ref(null);
589
+ const isTracked = computed(() => Boolean(trackingPixel.value));
660
590
  const viewabilityObserver = new IntersectionObserver(([entry]) => {
661
- if (context.options.viewabilityTracking && !viewabilityTrackingPixelElement && ad) {
591
+ if (context.options.viewabilityTracking && !trackingPixel.value && ad) {
662
592
  const ratio = round(entry.intersectionRatio, 1);
663
593
  if (ratio >= threshold && !timeoutId) {
664
594
  timeoutId = setTimeout(() => {
665
- var _a2, _b;
595
+ var _a, _b, _c;
666
596
  timeoutId = null;
667
- if (ad == null ? void 0 : ad.viewableImpressionCounter) {
668
- viewabilityTrackingPixelElement = addTrackingPixel(ad.viewableImpressionCounter);
669
- logger.debug(`Viewability tracking pixel fired for ${getName()}`);
670
- (_b = context.events) == null ? void 0 : _b.changeSlots.dispatch(Array.from(((_a2 = context.getAll) == null ? void 0 : _a2.call(context)) ?? []));
597
+ if ((_a = ad.value) == null ? void 0 : _a.viewableImpressionCounter) {
598
+ trackingPixel.value = addTrackingPixel(ad.value.viewableImpressionCounter);
599
+ logger.debug(`Viewability tracking pixel fired for ${name.value}`);
600
+ (_c = context.events) == null ? void 0 : _c.changeSlots.dispatch(Array.from(((_b = context.getAll) == null ? void 0 : _b.call(context)) ?? []));
671
601
  }
672
602
  }, duration);
673
603
  } else if (ratio < threshold && timeoutId) {
@@ -679,91 +609,221 @@ async function createSlot(options) {
679
609
  rootMargin,
680
610
  threshold: Array.from({ length: 11 }, (_, i) => i * 0.1)
681
611
  });
682
- if (element && context.options.viewabilityTracking)
683
- viewabilityObserver.observe(element);
684
- if (element)
685
- renderIntersectionObserver.observe(element);
686
- async function render(adToRender) {
687
- var _a2, _b;
688
- await waitForDomLoad();
689
- ad = adToRender ?? ad ?? await requestAd({
690
- slot: {
691
- getName,
692
- parameters
693
- },
694
- account: context.options.account,
695
- host: context.options.host,
696
- parameters: context.parameters,
697
- method: context.options.requestType,
698
- context
699
- });
700
- if (!element) {
701
- const error = `Could not create slot for format ${format}. No element found.`;
702
- logger.error(error, options);
703
- throw new Error(error);
704
- }
705
- if (context.debug)
706
- element.style.position = "relative";
707
- renderFunctions[renderMode](ad, element);
708
- if ((ad == null ? void 0 : ad.impressionCounter) && !impressionTrackingPixelElement) {
709
- impressionTrackingPixelElement = addTrackingPixel(ad.impressionCounter);
710
- logger.debug(`Impression tracking pixel fired for ${getName()}`);
711
- }
712
- logger.debug("Slot rendered", {
713
- renderedElement: element,
714
- location: context.location,
715
- format,
716
- containingElement
717
- });
718
- renderIntersectionObserver.disconnect();
719
- await ((_b = context.events) == null ? void 0 : _b.changeSlots.dispatchAsync(Array.from(((_a2 = context.getAll) == null ? void 0 : _a2.call(context)) ?? [])));
720
- return element;
721
- }
722
- function cleanElement() {
723
- if (!element)
724
- return;
725
- element.innerHTML = "";
726
- element.style.position = "";
727
- element.style.width = "";
728
- element.style.height = "";
729
- }
730
- function getName() {
731
- return `${context.location}${slot ? `${slot}` : ""}-${format}`;
612
+ function observe(newElement, oldElement) {
613
+ if (oldElement)
614
+ viewabilityObserver.unobserve(oldElement);
615
+ if (newElement && context.options.viewabilityTracking)
616
+ viewabilityObserver.observe(newElement);
617
+ return () => {
618
+ if (newElement)
619
+ viewabilityObserver.unobserve(newElement);
620
+ };
732
621
  }
733
- function dispose() {
734
- var _a2;
735
- cleanElement();
736
- impressionTrackingPixelElement == null ? void 0 : impressionTrackingPixelElement.remove();
737
- viewabilityTrackingPixelElement == null ? void 0 : viewabilityTrackingPixelElement.remove();
738
- element = null;
739
- ad = null;
740
- renderIntersectionObserver.disconnect();
622
+ watch(element, observe);
623
+ observe(element.value);
624
+ return [isTracked, () => {
625
+ var _a;
626
+ (_a = trackingPixel.value) == null ? void 0 : _a.remove();
741
627
  viewabilityObserver.disconnect();
742
- (_a2 = options.onDispose) == null ? void 0 : _a2.call(options);
743
- queryDetector == null ? void 0 : queryDetector.dispose();
744
- }
745
- function isViewabilityTracked() {
746
- return Boolean(viewabilityTrackingPixelElement);
747
- }
748
- function isImpressionTracked() {
749
- return Boolean(impressionTrackingPixelElement);
628
+ }];
629
+ }
630
+ function useRenderIntersectionObserver({ ad, options, element, render }) {
631
+ var _a;
632
+ const isInViewport = ref(false);
633
+ const renderIntersectionObserver = new IntersectionObserver((entries) => {
634
+ isInViewport.value = entries.some((entry) => entry.isIntersecting);
635
+ if (isInViewport.value) {
636
+ (async () => {
637
+ if (!ad.value && options.lazyLoading)
638
+ await render();
639
+ await render(ad.value ?? void 0);
640
+ })().catch(logger.error);
641
+ }
642
+ }, {
643
+ rootMargin: ((_a = options.lazyLoadingOptions) == null ? void 0 : _a.rootMargin) ?? "200px",
644
+ threshold: 0
645
+ });
646
+ function observe(newElement, oldElement) {
647
+ if (oldElement)
648
+ renderIntersectionObserver.unobserve(oldElement);
649
+ if (newElement)
650
+ renderIntersectionObserver.observe(newElement);
651
+ return () => {
652
+ if (newElement)
653
+ renderIntersectionObserver.unobserve(newElement);
654
+ };
750
655
  }
751
- return {
752
- location: context.location,
753
- lazyLoading: options.lazyLoading ?? false,
754
- slot,
755
- parameters,
756
- setFormat,
757
- getFormat,
758
- render,
759
- getElement,
760
- getName,
761
- getAd,
762
- setAd,
763
- isViewabilityTracked,
764
- isImpressionTracked,
765
- dispose
766
- };
656
+ watch(element, observe);
657
+ observe(element.value);
658
+ return [isInViewport, () => {
659
+ renderIntersectionObserver.disconnect();
660
+ }];
661
+ }
662
+ const renderFunctions = {
663
+ iframe: renderIframe,
664
+ inline: renderInline
665
+ };
666
+ function createSlot(options) {
667
+ const scope = effectScope();
668
+ return scope.run(() => {
669
+ const {
670
+ containingElement,
671
+ slot,
672
+ context,
673
+ renderMode = "iframe"
674
+ } = options;
675
+ const parameters = reactive(new Map(Object.entries(options.parameters ?? {})));
676
+ let queryDetector = null;
677
+ if (typeof options.format !== "string") {
678
+ queryDetector = createQueryDetector({
679
+ onChange: onQueryChange,
680
+ queries: Object.fromEntries(options.format.map((item) => [item.format, item.query]))
681
+ });
682
+ }
683
+ const format = ref(queryDetector ? queryDetector.getQuery() : options.format);
684
+ function onQueryChange(newFormat) {
685
+ format.value = newFormat;
686
+ }
687
+ const ad = ref(null);
688
+ const originalAd = ref(ad.value);
689
+ const name = computed(() => generateName(context.location, format.value, slot));
690
+ watch(name, async (newName, oldName) => {
691
+ var _a;
692
+ if (newName === oldName)
693
+ return;
694
+ (_a = options.onNameChange) == null ? void 0 : _a.call(options, newName, oldName);
695
+ const newAd = await requestAd$1();
696
+ cleanElement();
697
+ ad.value = newAd;
698
+ originalAd.value = newAd;
699
+ });
700
+ const isDomLoaded = useDomLoaded();
701
+ const element = computed(
702
+ () => {
703
+ if (!(typeof containingElement === "string" || !containingElement))
704
+ return containingElement;
705
+ if (!isDomLoaded.value)
706
+ return null;
707
+ return document.querySelector(`.adunit[data-format="${format.value}"]#${containingElement}${slot ? `[data-slot="${slot}"]` : ""}`);
708
+ }
709
+ );
710
+ function getElement() {
711
+ var _a, _b;
712
+ if (renderMode === "iframe")
713
+ return ((_a = element.value) == null ? void 0 : _a.querySelector("iframe")) ?? null;
714
+ return ((_b = element.value) == null ? void 0 : _b.innerHTML) ? element.value.firstElementChild : null;
715
+ }
716
+ const [isInViewport, disposeRenderIntersectionObserver] = useRenderIntersectionObserver({
717
+ ad,
718
+ options,
719
+ element,
720
+ render
721
+ });
722
+ watch([ad, isInViewport], async ([newAd, newIsInViewport], [oldAd]) => {
723
+ var _a, _b;
724
+ if (!newAd || isEqual(newAd, oldAd))
725
+ return;
726
+ if (newIsInViewport || context.options.eagerRendering)
727
+ await render(newAd);
728
+ if (element.value) {
729
+ element.value.style.width = `${newAd.width}px`;
730
+ element.value.style.height = `${newAd.height}px`;
731
+ }
732
+ (_b = context.events) == null ? void 0 : _b.changeSlots.dispatch(Array.from(((_a = context.getAll) == null ? void 0 : _a.call(context)) ?? []));
733
+ });
734
+ const [
735
+ isViewabilityTracked,
736
+ disposeViewabilityObserver
737
+ ] = useViewabilityObserver({
738
+ context,
739
+ ad,
740
+ name,
741
+ element
742
+ });
743
+ const impressionTrackingPixelElement = ref(null);
744
+ const isImpressionTracked = computed(() => Boolean(impressionTrackingPixelElement.value));
745
+ async function requestAd$1() {
746
+ const response = await requestAd({
747
+ slot: {
748
+ name: name.value,
749
+ parameters
750
+ },
751
+ context
752
+ });
753
+ originalAd.value = response;
754
+ return response;
755
+ }
756
+ async function render(adToRender) {
757
+ var _a, _b;
758
+ await waitForDomLoad();
759
+ const renderAd = adToRender ?? ad.value ?? await requestAd$1();
760
+ if (originalAd.value) {
761
+ ad.value = ((_a = options.onBeforeRender) == null ? void 0 : _a.call(options, adToRender ?? originalAd.value)) ?? renderAd;
762
+ }
763
+ if (!element.value) {
764
+ const error = `Could not create slot for format ${format.value}. No element found.`;
765
+ logger.error(error, options);
766
+ throw new Error(error);
767
+ }
768
+ if (context.debug)
769
+ element.value.style.position = "relative";
770
+ renderFunctions[renderMode](renderAd, element.value);
771
+ if (renderAd.impressionCounter && !impressionTrackingPixelElement.value) {
772
+ impressionTrackingPixelElement.value = addTrackingPixel(renderAd.impressionCounter);
773
+ logger.debug(`Impression tracking pixel fired for ${name.value}`);
774
+ }
775
+ logger.debug("Slot rendered", {
776
+ renderedElement: element,
777
+ location: context.location,
778
+ format,
779
+ containingElement
780
+ });
781
+ (_b = options.onRender) == null ? void 0 : _b.call(options, element.value);
782
+ disposeRenderIntersectionObserver();
783
+ return element.value;
784
+ }
785
+ function cleanElement() {
786
+ if (!element.value)
787
+ return;
788
+ element.value.innerHTML = "";
789
+ element.value.style.position = "";
790
+ element.value.style.width = "";
791
+ element.value.style.height = "";
792
+ }
793
+ function dispose() {
794
+ var _a, _b;
795
+ cleanElement();
796
+ (_a = impressionTrackingPixelElement.value) == null ? void 0 : _a.remove();
797
+ ad.value = null;
798
+ disposeRenderIntersectionObserver();
799
+ disposeViewabilityObserver();
800
+ (_b = options.onDispose) == null ? void 0 : _b.call(options);
801
+ queryDetector == null ? void 0 : queryDetector.dispose();
802
+ scope.stop();
803
+ }
804
+ return {
805
+ location: context.location,
806
+ lazyLoading: options.lazyLoading ?? false,
807
+ slot,
808
+ parameters,
809
+ format,
810
+ name,
811
+ ad,
812
+ isViewabilityTracked,
813
+ isImpressionTracked,
814
+ render,
815
+ getElement,
816
+ dispose
817
+ };
818
+ });
819
+ }
820
+ function useDomLoaded() {
821
+ const isDomLoaded = ref(false);
822
+ onInit(async () => {
823
+ await waitForDomLoad();
824
+ isDomLoaded.value = true;
825
+ });
826
+ return isDomLoaded;
767
827
  }
768
828
  const numberLike = union([coerce.string().regex(/^\d+$/), literal("")]).transform((value) => value === "" ? void 0 : Number(value));
769
829
  const booleanLike = union([coerce.boolean(), literal("")]);
@@ -782,6 +842,46 @@ const dateLike = union([coerce.string(), literal("")]).transform((value) => {
782
842
  return void 0;
783
843
  return date;
784
844
  });
845
+ const cssValueLike = union([coerce.string(), literal(""), number()]).transform((value) => {
846
+ if (value === "" || value === 0 || value === "0")
847
+ return void 0;
848
+ if (numberLike.parse(value))
849
+ return `${numberLike.parse(value)}px`;
850
+ return String(value);
851
+ });
852
+ const isJson = string().transform((value, { addIssue }) => {
853
+ try {
854
+ return JSON.parse(value.replaceAll("'", '"'));
855
+ } catch (error) {
856
+ addIssue({
857
+ code: ZodIssueCode.custom,
858
+ message: `Invalid JSON: ${error.message}`
859
+ });
860
+ return NEVER;
861
+ }
862
+ });
863
+ const isHtmlString = string().transform((value, { addIssue }) => {
864
+ var _a;
865
+ const htmlParser = new DOMParser();
866
+ try {
867
+ const html = htmlParser.parseFromString(value, "text/html");
868
+ if (((_a = html.body) == null ? void 0 : _a.children.length) === 0)
869
+ throw new Error("Invalid HTML");
870
+ return value;
871
+ } catch (error) {
872
+ addIssue({
873
+ code: ZodIssueCode.custom,
874
+ message: error.message
875
+ });
876
+ return NEVER;
877
+ }
878
+ });
879
+ const isJsonOrHtmlString = union([isJson, isHtmlString]);
880
+ const isJsonOrHtmlOptionalString = union([coerce.string(), isJsonOrHtmlString]).transform((value) => {
881
+ if (value === "")
882
+ return void 0;
883
+ return value;
884
+ }).optional();
785
885
  const baseSchema = object({
786
886
  adDuration: numberLike.optional(),
787
887
  adFormat: string().optional(),
@@ -795,7 +895,7 @@ const baseSchema = object({
795
895
  advertiserId: string().optional(),
796
896
  altText: string().optional(),
797
897
  auctionable: booleanLike.optional(),
798
- body: string().optional(),
898
+ body: isJsonOrHtmlOptionalString,
799
899
  clickTag: urlLike.optional(),
800
900
  comment: string().optional(),
801
901
  creativeName: string().optional(),
@@ -806,7 +906,7 @@ const baseSchema = object({
806
906
  mediaType: string(),
807
907
  prebid: unknown().optional()
808
908
  }).optional(),
809
- height: numberLike.optional(),
909
+ height: cssValueLike.optional(),
810
910
  id: string().optional(),
811
911
  impressionCounter: urlLike.optional(),
812
912
  libId: string().optional(),
@@ -824,7 +924,7 @@ const baseSchema = object({
824
924
  slotID: string(),
825
925
  slotName: string(),
826
926
  swfSrc: urlLike.optional(),
827
- tag: string().optional(),
927
+ tag: isJsonOrHtmlOptionalString,
828
928
  tagUrl: urlLike.optional(),
829
929
  timeStamp: dateLike.optional(),
830
930
  trackedImpressionCounter: urlLike.optional(),
@@ -832,16 +932,16 @@ const baseSchema = object({
832
932
  trackingUrl: urlLike.optional(),
833
933
  url: urlLike.optional(),
834
934
  viewableImpressionCounter: urlLike.optional(),
835
- width: numberLike.optional(),
836
- widthLarge: numberLike.optional()
935
+ width: cssValueLike.optional(),
936
+ widthLarge: cssValueLike.optional()
837
937
  });
838
938
  const jerliciaSchema = object({
839
939
  origin: literal("JERLICIA"),
840
- tag: string()
940
+ tag: isJsonOrHtmlString
841
941
  }).passthrough();
842
942
  const daleSchema = object({
843
943
  origin: literal("DALE"),
844
- body: string()
944
+ body: isJsonOrHtmlString
845
945
  }).passthrough().transform(({ body, ...data }) => ({
846
946
  ...data,
847
947
  tag: body
@@ -921,16 +1021,16 @@ function getPreviewObjects() {
921
1021
  return previewObjects;
922
1022
  }
923
1023
  function requestWithPost({
924
- host,
1024
+ context: { options: { host }, parameters },
925
1025
  ...options
926
1026
  }) {
927
1027
  const payload = {
928
1028
  ...options,
929
1029
  slots: options.slots.map((slot) => ({
930
- slotname: slot.getName(),
1030
+ slotname: toValue(slot.name),
931
1031
  parameters: parseParameters(slot.parameters)
932
1032
  })),
933
- parameters: options.parameters && parseParameters(options.parameters)
1033
+ parameters: parameters && parseParameters(parameters)
934
1034
  };
935
1035
  return fetch(`${new URL(host).href}json`, {
936
1036
  method: "POST",
@@ -941,8 +1041,8 @@ function requestWithPost({
941
1041
  }
942
1042
  });
943
1043
  }
944
- async function requestWithGet(options) {
945
- return fetch(new URL(`${options.host}/json/sl${options.slots.map((slot) => slot.getName()).join("/sl")}`), {
1044
+ async function requestWithGet({ context, slots }) {
1045
+ return fetch(new URL(`${context.options.host}/json/sl${slots.map((slot) => toValue(slot.name)).join("/sl")}`), {
946
1046
  method: "GET",
947
1047
  headers: {
948
1048
  // eslint-disable-next-line ts/naming-convention
@@ -958,19 +1058,15 @@ function parseParameters(parameters) {
958
1058
  return false;
959
1059
  }));
960
1060
  }
961
- async function requestAds({
962
- method = "POST",
963
- context,
964
- ...options
965
- }) {
966
- var _a, _b, _c, _d;
1061
+ async function requestAds(options) {
1062
+ var _a, _b, _c, _d, _e;
1063
+ const { context } = options;
967
1064
  try {
968
1065
  (_a = context.events) == null ? void 0 : _a.requestAd.dispatch({
969
1066
  ...options,
970
- context,
971
- method
1067
+ context
972
1068
  });
973
- const [response, previews] = await Promise.all([(method == null ? void 0 : method.toUpperCase()) === "POST" ? requestWithPost(options) : requestWithGet(options), requestPreviews(options.account)]);
1069
+ const [response, previews] = await Promise.all([((_b = context.options.requestType) == null ? void 0 : _b.toUpperCase()) === "POST" ? requestWithPost(options) : requestWithGet(options), requestPreviews(context.options.account)]);
974
1070
  logger.debug("Received response", response);
975
1071
  if (!response.ok)
976
1072
  throw new Error(`Failed to request ad: ${response.status} ${response.statusText}`);
@@ -986,18 +1082,18 @@ async function requestAds({
986
1082
  };
987
1083
  });
988
1084
  if (matchedPreviews.length > 0)
989
- (_b = context.events) == null ? void 0 : _b.previewReceived.dispatch(matchedPreviews);
1085
+ (_c = context.events) == null ? void 0 : _c.previewReceived.dispatch(matchedPreviews);
990
1086
  const mergedResult = [
991
1087
  ...result.filter((ad) => !previews.some((preview) => preview.libId === ad.libId)),
992
1088
  ...matchedPreviews
993
1089
  ];
994
1090
  if (mergedResult.length === 0)
995
1091
  throw new Error("No ads found");
996
- (_c = context.events) == null ? void 0 : _c.responseReceived.dispatch(mergedResult);
1092
+ (_d = context.events) == null ? void 0 : _d.responseReceived.dispatch(mergedResult);
997
1093
  return mergedResult;
998
1094
  } catch (error) {
999
1095
  logger.error(String(error));
1000
- (_d = context.events) == null ? void 0 : _d.requestError.dispatch(error);
1096
+ (_e = context.events) == null ? void 0 : _e.requestError.dispatch(error);
1001
1097
  throw error;
1002
1098
  }
1003
1099
  }