@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/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, shallowReactive, watchEffect } from "@vue/runtime-core";
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 type = "module";
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
- return [run, (callback) => add(callback, { name: name2, onAdd })];
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
- return [run, (callback) => add(callback, { name: name2, onAdd })];
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 = (await Promise.allSettled(previewObjects.filter((previewObject) => "adhesePreviewCreativeId" in previewObject).map(async (previewObject) => {
419
- const endpoint = new URL(`https://${account}-preview.adhese.org/creatives/preview/json/tag.do`);
420
- endpoint.searchParams.set(
421
- "id",
422
- previewObject.adhesePreviewCreativeId
423
- );
424
- const response = await fetch(endpoint.href, {
425
- method: "GET",
426
- headers: {
427
- accept: "application/json"
428
- }
429
- });
430
- if (!response.ok)
431
- return Promise.reject(new Error(`Failed to request preview ad with ID: ${previewObject.adhesePreviewCreativeId}`));
432
- return await response.json();
433
- }))).filter((response) => {
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
- }).map((response) => response.value.map((item) => ({
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 debouncedRequestAds = debounce(async (context) => {
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, reject } of batch.values()) {
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
- reject(new Error(`Ad: ${toValue(options.slot.name)} not found`));
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, reject) => {
530
- batch.set(toValue(options.slot.name), { options, resolve, reject });
351
+ (resolve) => {
352
+ batch.set(toValue(options.slot.name), { options, resolve });
531
353
  }
532
354
  );
533
- await debouncedRequestAds.call(options.context);
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([((_b = context.options.requestType) == null ? void 0 : _b.toUpperCase()) === "POST" ? requestWithPost(options) : requestWithGet(options), requestPreviews(context.options.account)]);
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, _b, _c;
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 isRendered = ref(false);
552
+ const status = ref("initializing");
717
553
  watch([ad, isInViewport], async ([newAd, newIsInViewport], [oldAd]) => {
718
- var _a, _b;
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 || context.options.eagerRendering)
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
- originalAd.value = response;
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
- renderAd = ((_a = options.onBeforeRender) == null ? void 0 : _a.call(options, renderAd)) ?? renderAd;
758
- renderAd = await runOnRender(renderAd);
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
- isRendered.value = true;
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
- return {
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
- getElement,
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.value === name2));
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.value === slot.name.value));
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
- const scope = effectScope();
857
- return scope.run(() => {
858
- const slots = shallowReactive(/* @__PURE__ */ new Map());
859
- watchEffect(() => {
860
- var _a;
861
- (_a = context.events) == null ? void 0 : _a.changeSlots.dispatch(Array.from(slots.values()));
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
- function getAll() {
864
- return Array.from(slots).map(([, slot]) => slot);
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 get(name2) {
908
- return slots.get(name2);
909
- }
910
- function dispose() {
911
- for (const slot of slots.values())
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
- return {
923
- getAll,
924
- add: add2,
925
- findDomSlots: findDomSlots$1,
926
- get,
927
- dispose
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: packageJson.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 debouncedFetchAllUnrenderedSlots.call();
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
- const ads = await Promise.all(domSlots.map((slot) => requestAd({
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.value);
954
+ const slots = (slotManager.getAll() ?? []).filter((slot) => !slot.lazyLoading && !slot.ad);
1116
955
  if (slots.length === 0)
1117
956
  return;
1118
- const ads = await Promise.all(slots.map((slot) => requestAd({
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 debouncedFetchAllUnrenderedSlots.call();
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
- logger,
1173
- requestAd
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