@adhese/sdk 1.6.1 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/cjs/package.json.cjs +1 -1
- package/dist/cjs/slot/slot.composables.cjs +2 -2
- package/dist/cjs/slot/slot.composables.cjs.map +1 -1
- package/dist/package.json.js +1 -1
- package/dist/slot/slot.composables.js +2 -2
- package/dist/slot/slot.composables.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const name = "@adhese/sdk";
|
|
4
|
-
const version = "1.6.
|
|
4
|
+
const version = "1.6.2";
|
|
5
5
|
exports.name = name;
|
|
6
6
|
exports.version = version;
|
|
7
7
|
//# sourceMappingURL=package.json.cjs.map
|
|
@@ -76,8 +76,8 @@ function useViewabilityObserver({ context, slotContext, hooks, onTracked }) {
|
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
78
|
sdkShared.watch(() => {
|
|
79
|
-
var _a;
|
|
80
|
-
return (_a = slotContext.value) == null ? void 0 : _a.element;
|
|
79
|
+
var _a, _b;
|
|
80
|
+
return ((_a = slotContext.value) == null ? void 0 : _a.status) === "rendered" && ((_b = slotContext.value) == null ? void 0 : _b.element);
|
|
81
81
|
}, (element) => {
|
|
82
82
|
if (element)
|
|
83
83
|
observe(element);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slot.composables.cjs","sources":["../../../src/slot/slot.composables.ts"],"sourcesContent":["import type { AdheseAd, AdheseContext, AdheseSlot, AdheseSlotContext, AdheseSlotHooks, AdheseSlotOptions } from '@adhese/sdk';\nimport {\n createAsyncHook,\n createPassiveHook,\n type Ref,\n ref,\n round,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\n\nexport function useDomLoaded(context: AdheseContext): Readonly<Ref<boolean>> {\n const isDomLoaded = ref(false);\n\n context.hooks.onInit(async () => {\n await waitForDomLoad();\n\n isDomLoaded.value = true;\n });\n return isDomLoaded;\n}\n\nexport function useRenderIntersectionObserver({ options, element, hooks }: {\n options: AdheseSlotOptions;\n element: Ref<HTMLElement | null>;\n hooks: AdheseSlotHooks;\n}): Ref<boolean> {\n const isInViewport = ref(false);\n\n const renderIntersectionObserver = new IntersectionObserver((entries) => {\n isInViewport.value = entries.some(entry => entry.isIntersecting);\n }, {\n rootMargin: options.lazyLoadingOptions?.rootMargin ?? '200px',\n threshold: 0,\n });\n\n function observe(newElement: HTMLElement | null, oldElement?: HTMLElement | null): () => void {\n if (oldElement)\n renderIntersectionObserver.unobserve(oldElement);\n\n if (newElement)\n renderIntersectionObserver.observe(newElement);\n\n return () => {\n if (newElement)\n renderIntersectionObserver.unobserve(newElement);\n };\n }\n\n watch(element, observe);\n observe(element.value);\n\n hooks.onDispose(() => {\n renderIntersectionObserver.disconnect();\n });\n\n return isInViewport;\n}\n\nexport function useViewabilityObserver(\n { context, slotContext, hooks, onTracked }: {\n context: AdheseContext;\n slotContext: Ref<AdheseSlot | null>;\n hooks: AdheseSlotHooks;\n onTracked?(trackingPixel: Ref<HTMLImageElement | null>): void;\n },\n): Ref<boolean> {\n let timeoutId: number | null = null;\n const {\n threshold,\n duration,\n rootMargin,\n } = {\n threshold: 0.5,\n duration: 1000,\n rootMargin: '0px',\n ...context.options.viewabilityTrackingOptions,\n } satisfies Required<typeof context.options.viewabilityTrackingOptions>;\n\n const trackingPixel = ref<HTMLImageElement | null>(null);\n\n const isTracked = ref(false);\n\n const viewabilityObserver = new IntersectionObserver(([entry]) => {\n if (context.options.viewabilityTracking && !trackingPixel.value) {\n const ratio = round(entry.intersectionRatio, 1);\n\n if (ratio >= threshold && !timeoutId) {\n // @ts-expect-error The is misfiring to the Node type\n timeoutId = setTimeout(() => {\n timeoutId = null;\n\n onTracked?.(trackingPixel);\n\n isTracked.value = true;\n }, duration);\n }\n else if (ratio < threshold && timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n }\n }, {\n rootMargin,\n threshold: Array.from({ length: 11 }, (_, i) => i * 0.1),\n });\n\n function observe(newElement: HTMLElement | null, oldElement?: HTMLElement | null): () => void {\n if (oldElement)\n viewabilityObserver.unobserve(oldElement);\n\n if (newElement && context.options.viewabilityTracking)\n viewabilityObserver.observe(newElement);\n\n return () => {\n if (newElement)\n viewabilityObserver.unobserve(newElement);\n };\n }\n\n watch(() => slotContext.value?.element, (element) => {\n if (element)\n observe(element);\n }, { immediate: true });\n\n watch(slotContext, (slot) => {\n if (slot?.element)\n viewabilityObserver.observe(slot.element);\n }, { once: true });\n\n hooks.onDispose(() => {\n trackingPixel.value?.remove();\n viewabilityObserver.disconnect();\n });\n\n watch(() => slotContext.value?.status, async (newStatus, oldStatus) => {\n if (newStatus === 'loaded' && oldStatus === 'rendered') {\n trackingPixel.value?.remove();\n trackingPixel.value = null;\n }\n });\n\n return isTracked;\n}\n\nexport function useSlotHooks({ setup }: AdheseSlotOptions, slotContext: Ref<AdheseSlotContext | null>): {\n runOnBeforeRender: ReturnType<typeof createAsyncHook<AdheseAd>>[0];\n runOnRender: ReturnType<typeof createPassiveHook<AdheseAd>>[0];\n runOnBeforeRequest: ReturnType<typeof createAsyncHook<AdheseAd | null>>[0];\n runOnRequest: ReturnType<typeof createAsyncHook<AdheseAd>>[0];\n runOnInit: ReturnType<typeof createAsyncHook<void>>[0];\n runOnDispose: ReturnType<typeof createPassiveHook<void>>[0];\n runOnEmpty: ReturnType<typeof createPassiveHook<void>>[0];\n runOnError: ReturnType<typeof createPassiveHook<Error>>[0];\n} & AdheseSlotHooks {\n const [runOnBeforeRender, onBeforeRender, disposeOnBeforeRender] = createAsyncHook<AdheseAd>();\n const [runOnRender, onRender, disposeOnRender] = createPassiveHook<AdheseAd>();\n const [runOnBeforeRequest, onBeforeRequest, disposeOnBeforeRequest] = createAsyncHook<AdheseAd | null>();\n const [runOnRequest, onRequest, disposeOnRequest] = createAsyncHook<AdheseAd>();\n const [runOnInit, onInit, disposeOnInit] = createAsyncHook();\n const [runOnDispose, onDispose, disposeOnDispose] = createPassiveHook();\n const [runOnEmpty, onEmpty, disposeOnEmpty] = createPassiveHook();\n const [runOnError, onError, disposeOnError] = createPassiveHook<Error>();\n\n setup?.(slotContext, {\n onBeforeRender,\n onRender,\n onBeforeRequest,\n onDispose,\n onRequest,\n onInit,\n onEmpty,\n onError,\n });\n\n onDispose(() => {\n disposeOnBeforeRender();\n disposeOnRender();\n disposeOnBeforeRequest();\n disposeOnRequest();\n disposeOnInit();\n disposeOnDispose();\n disposeOnEmpty();\n disposeOnError();\n });\n\n return { runOnBeforeRender, runOnRender, runOnBeforeRequest, runOnRequest, runOnDispose, onDispose, onBeforeRequest, onRequest, onBeforeRender, onRender, onInit, runOnInit, runOnEmpty, onEmpty, runOnError, onError };\n}\n"],"names":["ref","waitForDomLoad","watch","round","createAsyncHook","createPassiveHook"],"mappings":";;;AAWO,SAAS,aAAa,SAAgD;AACrE,QAAA,cAAcA,cAAI,KAAK;AAErB,UAAA,MAAM,OAAO,YAAY;AAC/B,UAAMC,yBAAe;AAErB,gBAAY,QAAQ;AAAA,EAAA,CACrB;AACM,SAAA;AACT;AAEO,SAAS,8BAA8B,EAAE,SAAS,SAAS,SAIjD;;AACT,QAAA,eAAeD,cAAI,KAAK;AAE9B,QAAM,6BAA6B,IAAI,qBAAqB,CAAC,YAAY;AACvE,iBAAa,QAAQ,QAAQ,KAAK,CAAA,UAAS,MAAM,cAAc;AAAA,EAAA,GAC9D;AAAA,IACD,cAAY,aAAQ,uBAAR,mBAA4B,eAAc;AAAA,IACtD,WAAW;AAAA,EAAA,CACZ;AAEQ,WAAA,QAAQ,YAAgC,YAA6C;AACxF,QAAA;AACF,iCAA2B,UAAU,UAAU;AAE7C,QAAA;AACF,iCAA2B,QAAQ,UAAU;AAE/C,WAAO,MAAM;AACP,UAAA;AACF,mCAA2B,UAAU,UAAU;AAAA,IACnD;AAAA,EAAA;AAGFE,YAAA,MAAM,SAAS,OAAO;AACtB,UAAQ,QAAQ,KAAK;AAErB,QAAM,UAAU,MAAM;AACpB,+BAA2B,WAAW;AAAA,EAAA,CACvC;AAEM,SAAA;AACT;AAEO,SAAS,uBACd,EAAE,SAAS,aAAa,OAAO,aAMjB;AACd,MAAI,YAA2B;AACzB,QAAA;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE;AAAA,IACF,WAAW;AAAA,IACX,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,GAAG,QAAQ,QAAQ;AAAA,EACrB;AAEM,QAAA,gBAAgBF,cAA6B,IAAI;AAEjD,QAAA,YAAYA,cAAI,KAAK;AAE3B,QAAM,sBAAsB,IAAI,qBAAqB,CAAC,CAAC,KAAK,MAAM;AAChE,QAAI,QAAQ,QAAQ,uBAAuB,CAAC,cAAc,OAAO;AAC/D,YAAM,QAAQG,UAAA,MAAM,MAAM,mBAAmB,CAAC;AAE1C,UAAA,SAAS,aAAa,CAAC,WAAW;AAEpC,oBAAY,WAAW,MAAM;AACf,sBAAA;AAEZ,iDAAY;AAEZ,oBAAU,QAAQ;AAAA,WACjB,QAAQ;AAAA,MAAA,WAEJ,QAAQ,aAAa,WAAW;AACvC,qBAAa,SAAS;AACV,oBAAA;AAAA,MAAA;AAAA,IACd;AAAA,EACF,GACC;AAAA,IACD;AAAA,IACA,WAAW,MAAM,KAAK,EAAE,QAAQ,GAAG,GAAG,CAAC,GAAG,MAAM,IAAI,GAAG;AAAA,EAAA,CACxD;AAEQ,WAAA,QAAQ,YAAgC,YAA6C;AAIxF,QAAA,cAAc,QAAQ,QAAQ;AAChC,0BAAoB,QAAQ,UAAU;AAExC,WAAO,MAAM;AACP,UAAA;AACF,4BAAoB,UAAU,UAAU;AAAA,IAC5C;AAAA,EAAA;
|
|
1
|
+
{"version":3,"file":"slot.composables.cjs","sources":["../../../src/slot/slot.composables.ts"],"sourcesContent":["import type { AdheseAd, AdheseContext, AdheseSlot, AdheseSlotContext, AdheseSlotHooks, AdheseSlotOptions } from '@adhese/sdk';\nimport {\n createAsyncHook,\n createPassiveHook,\n type Ref,\n ref,\n round,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\n\nexport function useDomLoaded(context: AdheseContext): Readonly<Ref<boolean>> {\n const isDomLoaded = ref(false);\n\n context.hooks.onInit(async () => {\n await waitForDomLoad();\n\n isDomLoaded.value = true;\n });\n return isDomLoaded;\n}\n\nexport function useRenderIntersectionObserver({ options, element, hooks }: {\n options: AdheseSlotOptions;\n element: Ref<HTMLElement | null>;\n hooks: AdheseSlotHooks;\n}): Ref<boolean> {\n const isInViewport = ref(false);\n\n const renderIntersectionObserver = new IntersectionObserver((entries) => {\n isInViewport.value = entries.some(entry => entry.isIntersecting);\n }, {\n rootMargin: options.lazyLoadingOptions?.rootMargin ?? '200px',\n threshold: 0,\n });\n\n function observe(newElement: HTMLElement | null, oldElement?: HTMLElement | null): () => void {\n if (oldElement)\n renderIntersectionObserver.unobserve(oldElement);\n\n if (newElement)\n renderIntersectionObserver.observe(newElement);\n\n return () => {\n if (newElement)\n renderIntersectionObserver.unobserve(newElement);\n };\n }\n\n watch(element, observe);\n observe(element.value);\n\n hooks.onDispose(() => {\n renderIntersectionObserver.disconnect();\n });\n\n return isInViewport;\n}\n\nexport function useViewabilityObserver(\n { context, slotContext, hooks, onTracked }: {\n context: AdheseContext;\n slotContext: Ref<AdheseSlot | null>;\n hooks: AdheseSlotHooks;\n onTracked?(trackingPixel: Ref<HTMLImageElement | null>): void;\n },\n): Ref<boolean> {\n let timeoutId: number | null = null;\n const {\n threshold,\n duration,\n rootMargin,\n } = {\n threshold: 0.5,\n duration: 1000,\n rootMargin: '0px',\n ...context.options.viewabilityTrackingOptions,\n } satisfies Required<typeof context.options.viewabilityTrackingOptions>;\n\n const trackingPixel = ref<HTMLImageElement | null>(null);\n\n const isTracked = ref(false);\n\n const viewabilityObserver = new IntersectionObserver(([entry]) => {\n if (context.options.viewabilityTracking && !trackingPixel.value) {\n const ratio = round(entry.intersectionRatio, 1);\n\n if (ratio >= threshold && !timeoutId) {\n // @ts-expect-error The is misfiring to the Node type\n timeoutId = setTimeout(() => {\n timeoutId = null;\n\n onTracked?.(trackingPixel);\n\n isTracked.value = true;\n }, duration);\n }\n else if (ratio < threshold && timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n }\n }, {\n rootMargin,\n threshold: Array.from({ length: 11 }, (_, i) => i * 0.1),\n });\n\n function observe(newElement: HTMLElement | null, oldElement?: HTMLElement | null): () => void {\n if (oldElement)\n viewabilityObserver.unobserve(oldElement);\n\n if (newElement && context.options.viewabilityTracking)\n viewabilityObserver.observe(newElement);\n\n return () => {\n if (newElement)\n viewabilityObserver.unobserve(newElement);\n };\n }\n\n watch(() => slotContext.value?.status === 'rendered' && slotContext.value?.element, (element) => {\n if (element)\n observe(element);\n }, { immediate: true });\n\n watch(slotContext, (slot) => {\n if (slot?.element)\n viewabilityObserver.observe(slot.element);\n }, { once: true });\n\n hooks.onDispose(() => {\n trackingPixel.value?.remove();\n viewabilityObserver.disconnect();\n });\n\n watch(() => slotContext.value?.status, async (newStatus, oldStatus) => {\n if (newStatus === 'loaded' && oldStatus === 'rendered') {\n trackingPixel.value?.remove();\n trackingPixel.value = null;\n }\n });\n\n return isTracked;\n}\n\nexport function useSlotHooks({ setup }: AdheseSlotOptions, slotContext: Ref<AdheseSlotContext | null>): {\n runOnBeforeRender: ReturnType<typeof createAsyncHook<AdheseAd>>[0];\n runOnRender: ReturnType<typeof createPassiveHook<AdheseAd>>[0];\n runOnBeforeRequest: ReturnType<typeof createAsyncHook<AdheseAd | null>>[0];\n runOnRequest: ReturnType<typeof createAsyncHook<AdheseAd>>[0];\n runOnInit: ReturnType<typeof createAsyncHook<void>>[0];\n runOnDispose: ReturnType<typeof createPassiveHook<void>>[0];\n runOnEmpty: ReturnType<typeof createPassiveHook<void>>[0];\n runOnError: ReturnType<typeof createPassiveHook<Error>>[0];\n} & AdheseSlotHooks {\n const [runOnBeforeRender, onBeforeRender, disposeOnBeforeRender] = createAsyncHook<AdheseAd>();\n const [runOnRender, onRender, disposeOnRender] = createPassiveHook<AdheseAd>();\n const [runOnBeforeRequest, onBeforeRequest, disposeOnBeforeRequest] = createAsyncHook<AdheseAd | null>();\n const [runOnRequest, onRequest, disposeOnRequest] = createAsyncHook<AdheseAd>();\n const [runOnInit, onInit, disposeOnInit] = createAsyncHook();\n const [runOnDispose, onDispose, disposeOnDispose] = createPassiveHook();\n const [runOnEmpty, onEmpty, disposeOnEmpty] = createPassiveHook();\n const [runOnError, onError, disposeOnError] = createPassiveHook<Error>();\n\n setup?.(slotContext, {\n onBeforeRender,\n onRender,\n onBeforeRequest,\n onDispose,\n onRequest,\n onInit,\n onEmpty,\n onError,\n });\n\n onDispose(() => {\n disposeOnBeforeRender();\n disposeOnRender();\n disposeOnBeforeRequest();\n disposeOnRequest();\n disposeOnInit();\n disposeOnDispose();\n disposeOnEmpty();\n disposeOnError();\n });\n\n return { runOnBeforeRender, runOnRender, runOnBeforeRequest, runOnRequest, runOnDispose, onDispose, onBeforeRequest, onRequest, onBeforeRender, onRender, onInit, runOnInit, runOnEmpty, onEmpty, runOnError, onError };\n}\n"],"names":["ref","waitForDomLoad","watch","round","createAsyncHook","createPassiveHook"],"mappings":";;;AAWO,SAAS,aAAa,SAAgD;AACrE,QAAA,cAAcA,cAAI,KAAK;AAErB,UAAA,MAAM,OAAO,YAAY;AAC/B,UAAMC,yBAAe;AAErB,gBAAY,QAAQ;AAAA,EAAA,CACrB;AACM,SAAA;AACT;AAEO,SAAS,8BAA8B,EAAE,SAAS,SAAS,SAIjD;;AACT,QAAA,eAAeD,cAAI,KAAK;AAE9B,QAAM,6BAA6B,IAAI,qBAAqB,CAAC,YAAY;AACvE,iBAAa,QAAQ,QAAQ,KAAK,CAAA,UAAS,MAAM,cAAc;AAAA,EAAA,GAC9D;AAAA,IACD,cAAY,aAAQ,uBAAR,mBAA4B,eAAc;AAAA,IACtD,WAAW;AAAA,EAAA,CACZ;AAEQ,WAAA,QAAQ,YAAgC,YAA6C;AACxF,QAAA;AACF,iCAA2B,UAAU,UAAU;AAE7C,QAAA;AACF,iCAA2B,QAAQ,UAAU;AAE/C,WAAO,MAAM;AACP,UAAA;AACF,mCAA2B,UAAU,UAAU;AAAA,IACnD;AAAA,EAAA;AAGFE,YAAA,MAAM,SAAS,OAAO;AACtB,UAAQ,QAAQ,KAAK;AAErB,QAAM,UAAU,MAAM;AACpB,+BAA2B,WAAW;AAAA,EAAA,CACvC;AAEM,SAAA;AACT;AAEO,SAAS,uBACd,EAAE,SAAS,aAAa,OAAO,aAMjB;AACd,MAAI,YAA2B;AACzB,QAAA;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE;AAAA,IACF,WAAW;AAAA,IACX,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,GAAG,QAAQ,QAAQ;AAAA,EACrB;AAEM,QAAA,gBAAgBF,cAA6B,IAAI;AAEjD,QAAA,YAAYA,cAAI,KAAK;AAE3B,QAAM,sBAAsB,IAAI,qBAAqB,CAAC,CAAC,KAAK,MAAM;AAChE,QAAI,QAAQ,QAAQ,uBAAuB,CAAC,cAAc,OAAO;AAC/D,YAAM,QAAQG,UAAA,MAAM,MAAM,mBAAmB,CAAC;AAE1C,UAAA,SAAS,aAAa,CAAC,WAAW;AAEpC,oBAAY,WAAW,MAAM;AACf,sBAAA;AAEZ,iDAAY;AAEZ,oBAAU,QAAQ;AAAA,WACjB,QAAQ;AAAA,MAAA,WAEJ,QAAQ,aAAa,WAAW;AACvC,qBAAa,SAAS;AACV,oBAAA;AAAA,MAAA;AAAA,IACd;AAAA,EACF,GACC;AAAA,IACD;AAAA,IACA,WAAW,MAAM,KAAK,EAAE,QAAQ,GAAG,GAAG,CAAC,GAAG,MAAM,IAAI,GAAG;AAAA,EAAA,CACxD;AAEQ,WAAA,QAAQ,YAAgC,YAA6C;AAIxF,QAAA,cAAc,QAAQ,QAAQ;AAChC,0BAAoB,QAAQ,UAAU;AAExC,WAAO,MAAM;AACP,UAAA;AACF,4BAAoB,UAAU,UAAU;AAAA,IAC5C;AAAA,EAAA;AAGID,kBAAA,MAAA;;AAAM,8BAAY,UAAZ,mBAAmB,YAAW,gBAAc,iBAAY,UAAZ,mBAAmB;AAAA,KAAS,CAAC,YAAY;AAC3F,QAAA;AACF,cAAQ,OAAO;AAAA,EAAA,GAChB,EAAE,WAAW,MAAM;AAEhBA,kBAAA,aAAa,CAAC,SAAS;AAC3B,QAAI,6BAAM;AACY,0BAAA,QAAQ,KAAK,OAAO;AAAA,EAAA,GACzC,EAAE,MAAM,MAAM;AAEjB,QAAM,UAAU,MAAM;;AACpB,wBAAc,UAAd,mBAAqB;AACrB,wBAAoB,WAAW;AAAA,EAAA,CAChC;AAEDA,YAAA,MAAM,MAAM;;AAAA,6BAAY,UAAZ,mBAAmB;AAAA,KAAQ,OAAO,WAAW,cAAc;;AACjE,QAAA,cAAc,YAAY,cAAc,YAAY;AACtD,0BAAc,UAAd,mBAAqB;AACrB,oBAAc,QAAQ;AAAA,IAAA;AAAA,EACxB,CACD;AAEM,SAAA;AACT;AAEO,SAAS,aAAa,EAAE,MAAM,GAAsB,aASvC;AAClB,QAAM,CAAC,mBAAmB,gBAAgB,qBAAqB,IAAIE,UAAAA,gBAA0B;AAC7F,QAAM,CAAC,aAAa,UAAU,eAAe,IAAIC,UAAAA,kBAA4B;AAC7E,QAAM,CAAC,oBAAoB,iBAAiB,sBAAsB,IAAID,UAAAA,gBAAiC;AACvG,QAAM,CAAC,cAAc,WAAW,gBAAgB,IAAIA,UAAAA,gBAA0B;AAC9E,QAAM,CAAC,WAAW,QAAQ,aAAa,IAAIA,UAAAA,gBAAgB;AAC3D,QAAM,CAAC,cAAc,WAAW,gBAAgB,IAAIC,UAAAA,kBAAkB;AACtE,QAAM,CAAC,YAAY,SAAS,cAAc,IAAIA,UAAAA,kBAAkB;AAChE,QAAM,CAAC,YAAY,SAAS,cAAc,IAAIA,UAAAA,kBAAyB;AAEvE,iCAAQ,aAAa;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAGF,YAAU,MAAM;AACQ,0BAAA;AACN,oBAAA;AACO,2BAAA;AACN,qBAAA;AACH,kBAAA;AACG,qBAAA;AACF,mBAAA;AACA,mBAAA;AAAA,EAAA,CAChB;AAED,SAAO,EAAE,mBAAmB,aAAa,oBAAoB,cAAc,cAAc,WAAW,iBAAiB,WAAW,gBAAgB,UAAU,QAAQ,WAAW,YAAY,SAAS,YAAY,QAAQ;AACxN;;;;;"}
|
package/dist/package.json.js
CHANGED
|
@@ -74,8 +74,8 @@ function useViewabilityObserver({ context, slotContext, hooks, onTracked }) {
|
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
76
|
watch(() => {
|
|
77
|
-
var _a;
|
|
78
|
-
return (_a = slotContext.value) == null ? void 0 : _a.element;
|
|
77
|
+
var _a, _b;
|
|
78
|
+
return ((_a = slotContext.value) == null ? void 0 : _a.status) === "rendered" && ((_b = slotContext.value) == null ? void 0 : _b.element);
|
|
79
79
|
}, (element) => {
|
|
80
80
|
if (element)
|
|
81
81
|
observe(element);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slot.composables.js","sources":["../../src/slot/slot.composables.ts"],"sourcesContent":["import type { AdheseAd, AdheseContext, AdheseSlot, AdheseSlotContext, AdheseSlotHooks, AdheseSlotOptions } from '@adhese/sdk';\nimport {\n createAsyncHook,\n createPassiveHook,\n type Ref,\n ref,\n round,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\n\nexport function useDomLoaded(context: AdheseContext): Readonly<Ref<boolean>> {\n const isDomLoaded = ref(false);\n\n context.hooks.onInit(async () => {\n await waitForDomLoad();\n\n isDomLoaded.value = true;\n });\n return isDomLoaded;\n}\n\nexport function useRenderIntersectionObserver({ options, element, hooks }: {\n options: AdheseSlotOptions;\n element: Ref<HTMLElement | null>;\n hooks: AdheseSlotHooks;\n}): Ref<boolean> {\n const isInViewport = ref(false);\n\n const renderIntersectionObserver = new IntersectionObserver((entries) => {\n isInViewport.value = entries.some(entry => entry.isIntersecting);\n }, {\n rootMargin: options.lazyLoadingOptions?.rootMargin ?? '200px',\n threshold: 0,\n });\n\n function observe(newElement: HTMLElement | null, oldElement?: HTMLElement | null): () => void {\n if (oldElement)\n renderIntersectionObserver.unobserve(oldElement);\n\n if (newElement)\n renderIntersectionObserver.observe(newElement);\n\n return () => {\n if (newElement)\n renderIntersectionObserver.unobserve(newElement);\n };\n }\n\n watch(element, observe);\n observe(element.value);\n\n hooks.onDispose(() => {\n renderIntersectionObserver.disconnect();\n });\n\n return isInViewport;\n}\n\nexport function useViewabilityObserver(\n { context, slotContext, hooks, onTracked }: {\n context: AdheseContext;\n slotContext: Ref<AdheseSlot | null>;\n hooks: AdheseSlotHooks;\n onTracked?(trackingPixel: Ref<HTMLImageElement | null>): void;\n },\n): Ref<boolean> {\n let timeoutId: number | null = null;\n const {\n threshold,\n duration,\n rootMargin,\n } = {\n threshold: 0.5,\n duration: 1000,\n rootMargin: '0px',\n ...context.options.viewabilityTrackingOptions,\n } satisfies Required<typeof context.options.viewabilityTrackingOptions>;\n\n const trackingPixel = ref<HTMLImageElement | null>(null);\n\n const isTracked = ref(false);\n\n const viewabilityObserver = new IntersectionObserver(([entry]) => {\n if (context.options.viewabilityTracking && !trackingPixel.value) {\n const ratio = round(entry.intersectionRatio, 1);\n\n if (ratio >= threshold && !timeoutId) {\n // @ts-expect-error The is misfiring to the Node type\n timeoutId = setTimeout(() => {\n timeoutId = null;\n\n onTracked?.(trackingPixel);\n\n isTracked.value = true;\n }, duration);\n }\n else if (ratio < threshold && timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n }\n }, {\n rootMargin,\n threshold: Array.from({ length: 11 }, (_, i) => i * 0.1),\n });\n\n function observe(newElement: HTMLElement | null, oldElement?: HTMLElement | null): () => void {\n if (oldElement)\n viewabilityObserver.unobserve(oldElement);\n\n if (newElement && context.options.viewabilityTracking)\n viewabilityObserver.observe(newElement);\n\n return () => {\n if (newElement)\n viewabilityObserver.unobserve(newElement);\n };\n }\n\n watch(() => slotContext.value?.element, (element) => {\n if (element)\n observe(element);\n }, { immediate: true });\n\n watch(slotContext, (slot) => {\n if (slot?.element)\n viewabilityObserver.observe(slot.element);\n }, { once: true });\n\n hooks.onDispose(() => {\n trackingPixel.value?.remove();\n viewabilityObserver.disconnect();\n });\n\n watch(() => slotContext.value?.status, async (newStatus, oldStatus) => {\n if (newStatus === 'loaded' && oldStatus === 'rendered') {\n trackingPixel.value?.remove();\n trackingPixel.value = null;\n }\n });\n\n return isTracked;\n}\n\nexport function useSlotHooks({ setup }: AdheseSlotOptions, slotContext: Ref<AdheseSlotContext | null>): {\n runOnBeforeRender: ReturnType<typeof createAsyncHook<AdheseAd>>[0];\n runOnRender: ReturnType<typeof createPassiveHook<AdheseAd>>[0];\n runOnBeforeRequest: ReturnType<typeof createAsyncHook<AdheseAd | null>>[0];\n runOnRequest: ReturnType<typeof createAsyncHook<AdheseAd>>[0];\n runOnInit: ReturnType<typeof createAsyncHook<void>>[0];\n runOnDispose: ReturnType<typeof createPassiveHook<void>>[0];\n runOnEmpty: ReturnType<typeof createPassiveHook<void>>[0];\n runOnError: ReturnType<typeof createPassiveHook<Error>>[0];\n} & AdheseSlotHooks {\n const [runOnBeforeRender, onBeforeRender, disposeOnBeforeRender] = createAsyncHook<AdheseAd>();\n const [runOnRender, onRender, disposeOnRender] = createPassiveHook<AdheseAd>();\n const [runOnBeforeRequest, onBeforeRequest, disposeOnBeforeRequest] = createAsyncHook<AdheseAd | null>();\n const [runOnRequest, onRequest, disposeOnRequest] = createAsyncHook<AdheseAd>();\n const [runOnInit, onInit, disposeOnInit] = createAsyncHook();\n const [runOnDispose, onDispose, disposeOnDispose] = createPassiveHook();\n const [runOnEmpty, onEmpty, disposeOnEmpty] = createPassiveHook();\n const [runOnError, onError, disposeOnError] = createPassiveHook<Error>();\n\n setup?.(slotContext, {\n onBeforeRender,\n onRender,\n onBeforeRequest,\n onDispose,\n onRequest,\n onInit,\n onEmpty,\n onError,\n });\n\n onDispose(() => {\n disposeOnBeforeRender();\n disposeOnRender();\n disposeOnBeforeRequest();\n disposeOnRequest();\n disposeOnInit();\n disposeOnDispose();\n disposeOnEmpty();\n disposeOnError();\n });\n\n return { runOnBeforeRender, runOnRender, runOnBeforeRequest, runOnRequest, runOnDispose, onDispose, onBeforeRequest, onRequest, onBeforeRender, onRender, onInit, runOnInit, runOnEmpty, onEmpty, runOnError, onError };\n}\n"],"names":[],"mappings":";AAWO,SAAS,aAAa,SAAgD;AACrE,QAAA,cAAc,IAAI,KAAK;AAErB,UAAA,MAAM,OAAO,YAAY;AAC/B,UAAM,eAAe;AAErB,gBAAY,QAAQ;AAAA,EAAA,CACrB;AACM,SAAA;AACT;AAEO,SAAS,8BAA8B,EAAE,SAAS,SAAS,SAIjD;;AACT,QAAA,eAAe,IAAI,KAAK;AAE9B,QAAM,6BAA6B,IAAI,qBAAqB,CAAC,YAAY;AACvE,iBAAa,QAAQ,QAAQ,KAAK,CAAA,UAAS,MAAM,cAAc;AAAA,EAAA,GAC9D;AAAA,IACD,cAAY,aAAQ,uBAAR,mBAA4B,eAAc;AAAA,IACtD,WAAW;AAAA,EAAA,CACZ;AAEQ,WAAA,QAAQ,YAAgC,YAA6C;AACxF,QAAA;AACF,iCAA2B,UAAU,UAAU;AAE7C,QAAA;AACF,iCAA2B,QAAQ,UAAU;AAE/C,WAAO,MAAM;AACP,UAAA;AACF,mCAA2B,UAAU,UAAU;AAAA,IACnD;AAAA,EAAA;AAGF,QAAM,SAAS,OAAO;AACtB,UAAQ,QAAQ,KAAK;AAErB,QAAM,UAAU,MAAM;AACpB,+BAA2B,WAAW;AAAA,EAAA,CACvC;AAEM,SAAA;AACT;AAEO,SAAS,uBACd,EAAE,SAAS,aAAa,OAAO,aAMjB;AACd,MAAI,YAA2B;AACzB,QAAA;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE;AAAA,IACF,WAAW;AAAA,IACX,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,GAAG,QAAQ,QAAQ;AAAA,EACrB;AAEM,QAAA,gBAAgB,IAA6B,IAAI;AAEjD,QAAA,YAAY,IAAI,KAAK;AAE3B,QAAM,sBAAsB,IAAI,qBAAqB,CAAC,CAAC,KAAK,MAAM;AAChE,QAAI,QAAQ,QAAQ,uBAAuB,CAAC,cAAc,OAAO;AAC/D,YAAM,QAAQ,MAAM,MAAM,mBAAmB,CAAC;AAE1C,UAAA,SAAS,aAAa,CAAC,WAAW;AAEpC,oBAAY,WAAW,MAAM;AACf,sBAAA;AAEZ,iDAAY;AAEZ,oBAAU,QAAQ;AAAA,WACjB,QAAQ;AAAA,MAAA,WAEJ,QAAQ,aAAa,WAAW;AACvC,qBAAa,SAAS;AACV,oBAAA;AAAA,MAAA;AAAA,IACd;AAAA,EACF,GACC;AAAA,IACD;AAAA,IACA,WAAW,MAAM,KAAK,EAAE,QAAQ,GAAG,GAAG,CAAC,GAAG,MAAM,IAAI,GAAG;AAAA,EAAA,CACxD;AAEQ,WAAA,QAAQ,YAAgC,YAA6C;AAIxF,QAAA,cAAc,QAAQ,QAAQ;AAChC,0BAAoB,QAAQ,UAAU;AAExC,WAAO,MAAM;AACP,UAAA;AACF,4BAAoB,UAAU,UAAU;AAAA,IAC5C;AAAA,EAAA;
|
|
1
|
+
{"version":3,"file":"slot.composables.js","sources":["../../src/slot/slot.composables.ts"],"sourcesContent":["import type { AdheseAd, AdheseContext, AdheseSlot, AdheseSlotContext, AdheseSlotHooks, AdheseSlotOptions } from '@adhese/sdk';\nimport {\n createAsyncHook,\n createPassiveHook,\n type Ref,\n ref,\n round,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\n\nexport function useDomLoaded(context: AdheseContext): Readonly<Ref<boolean>> {\n const isDomLoaded = ref(false);\n\n context.hooks.onInit(async () => {\n await waitForDomLoad();\n\n isDomLoaded.value = true;\n });\n return isDomLoaded;\n}\n\nexport function useRenderIntersectionObserver({ options, element, hooks }: {\n options: AdheseSlotOptions;\n element: Ref<HTMLElement | null>;\n hooks: AdheseSlotHooks;\n}): Ref<boolean> {\n const isInViewport = ref(false);\n\n const renderIntersectionObserver = new IntersectionObserver((entries) => {\n isInViewport.value = entries.some(entry => entry.isIntersecting);\n }, {\n rootMargin: options.lazyLoadingOptions?.rootMargin ?? '200px',\n threshold: 0,\n });\n\n function observe(newElement: HTMLElement | null, oldElement?: HTMLElement | null): () => void {\n if (oldElement)\n renderIntersectionObserver.unobserve(oldElement);\n\n if (newElement)\n renderIntersectionObserver.observe(newElement);\n\n return () => {\n if (newElement)\n renderIntersectionObserver.unobserve(newElement);\n };\n }\n\n watch(element, observe);\n observe(element.value);\n\n hooks.onDispose(() => {\n renderIntersectionObserver.disconnect();\n });\n\n return isInViewport;\n}\n\nexport function useViewabilityObserver(\n { context, slotContext, hooks, onTracked }: {\n context: AdheseContext;\n slotContext: Ref<AdheseSlot | null>;\n hooks: AdheseSlotHooks;\n onTracked?(trackingPixel: Ref<HTMLImageElement | null>): void;\n },\n): Ref<boolean> {\n let timeoutId: number | null = null;\n const {\n threshold,\n duration,\n rootMargin,\n } = {\n threshold: 0.5,\n duration: 1000,\n rootMargin: '0px',\n ...context.options.viewabilityTrackingOptions,\n } satisfies Required<typeof context.options.viewabilityTrackingOptions>;\n\n const trackingPixel = ref<HTMLImageElement | null>(null);\n\n const isTracked = ref(false);\n\n const viewabilityObserver = new IntersectionObserver(([entry]) => {\n if (context.options.viewabilityTracking && !trackingPixel.value) {\n const ratio = round(entry.intersectionRatio, 1);\n\n if (ratio >= threshold && !timeoutId) {\n // @ts-expect-error The is misfiring to the Node type\n timeoutId = setTimeout(() => {\n timeoutId = null;\n\n onTracked?.(trackingPixel);\n\n isTracked.value = true;\n }, duration);\n }\n else if (ratio < threshold && timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n }\n }, {\n rootMargin,\n threshold: Array.from({ length: 11 }, (_, i) => i * 0.1),\n });\n\n function observe(newElement: HTMLElement | null, oldElement?: HTMLElement | null): () => void {\n if (oldElement)\n viewabilityObserver.unobserve(oldElement);\n\n if (newElement && context.options.viewabilityTracking)\n viewabilityObserver.observe(newElement);\n\n return () => {\n if (newElement)\n viewabilityObserver.unobserve(newElement);\n };\n }\n\n watch(() => slotContext.value?.status === 'rendered' && slotContext.value?.element, (element) => {\n if (element)\n observe(element);\n }, { immediate: true });\n\n watch(slotContext, (slot) => {\n if (slot?.element)\n viewabilityObserver.observe(slot.element);\n }, { once: true });\n\n hooks.onDispose(() => {\n trackingPixel.value?.remove();\n viewabilityObserver.disconnect();\n });\n\n watch(() => slotContext.value?.status, async (newStatus, oldStatus) => {\n if (newStatus === 'loaded' && oldStatus === 'rendered') {\n trackingPixel.value?.remove();\n trackingPixel.value = null;\n }\n });\n\n return isTracked;\n}\n\nexport function useSlotHooks({ setup }: AdheseSlotOptions, slotContext: Ref<AdheseSlotContext | null>): {\n runOnBeforeRender: ReturnType<typeof createAsyncHook<AdheseAd>>[0];\n runOnRender: ReturnType<typeof createPassiveHook<AdheseAd>>[0];\n runOnBeforeRequest: ReturnType<typeof createAsyncHook<AdheseAd | null>>[0];\n runOnRequest: ReturnType<typeof createAsyncHook<AdheseAd>>[0];\n runOnInit: ReturnType<typeof createAsyncHook<void>>[0];\n runOnDispose: ReturnType<typeof createPassiveHook<void>>[0];\n runOnEmpty: ReturnType<typeof createPassiveHook<void>>[0];\n runOnError: ReturnType<typeof createPassiveHook<Error>>[0];\n} & AdheseSlotHooks {\n const [runOnBeforeRender, onBeforeRender, disposeOnBeforeRender] = createAsyncHook<AdheseAd>();\n const [runOnRender, onRender, disposeOnRender] = createPassiveHook<AdheseAd>();\n const [runOnBeforeRequest, onBeforeRequest, disposeOnBeforeRequest] = createAsyncHook<AdheseAd | null>();\n const [runOnRequest, onRequest, disposeOnRequest] = createAsyncHook<AdheseAd>();\n const [runOnInit, onInit, disposeOnInit] = createAsyncHook();\n const [runOnDispose, onDispose, disposeOnDispose] = createPassiveHook();\n const [runOnEmpty, onEmpty, disposeOnEmpty] = createPassiveHook();\n const [runOnError, onError, disposeOnError] = createPassiveHook<Error>();\n\n setup?.(slotContext, {\n onBeforeRender,\n onRender,\n onBeforeRequest,\n onDispose,\n onRequest,\n onInit,\n onEmpty,\n onError,\n });\n\n onDispose(() => {\n disposeOnBeforeRender();\n disposeOnRender();\n disposeOnBeforeRequest();\n disposeOnRequest();\n disposeOnInit();\n disposeOnDispose();\n disposeOnEmpty();\n disposeOnError();\n });\n\n return { runOnBeforeRender, runOnRender, runOnBeforeRequest, runOnRequest, runOnDispose, onDispose, onBeforeRequest, onRequest, onBeforeRender, onRender, onInit, runOnInit, runOnEmpty, onEmpty, runOnError, onError };\n}\n"],"names":[],"mappings":"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"}
|