@adhese/sdk 1.9.4 → 1.9.5
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.cjs +1 -1
- package/dist/cjs/slot/slot.cjs.map +1 -1
- package/dist/package.json.js +1 -1
- package/dist/slot/slot.js +1 -1
- package/dist/slot/slot.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.9.
|
|
4
|
+
const version = "1.9.5";
|
|
5
5
|
exports.name = name;
|
|
6
6
|
exports.version = version;
|
|
7
7
|
//# sourceMappingURL=package.json.cjs.map
|
package/dist/cjs/slot/slot.cjs
CHANGED
|
@@ -102,7 +102,7 @@ function createSlot(slotOptions) {
|
|
|
102
102
|
if (newElement === oldElement || oldElement === null && newElement === null) {
|
|
103
103
|
return;
|
|
104
104
|
}
|
|
105
|
-
if (!context.options.eagerRendering) {
|
|
105
|
+
if (!context.options.eagerRendering && !oldElement) {
|
|
106
106
|
return;
|
|
107
107
|
}
|
|
108
108
|
await render();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slot.cjs","sources":["../../../src/slot/slot.ts"],"sourcesContent":["import type { AdheseAd } from '@adhese/sdk';\nimport type {\n AdheseSlot,\n AdheseSlotContext,\n AdheseSlotOptions,\n RenderMode,\n} from './slot.types';\nimport {\n addTrackingPixel,\n computed,\n doNothing,\n effectScope,\n generateName,\n omit,\n pick,\n reactive,\n type Ref,\n ref,\n renderIframe,\n renderInline,\n type RenderOptions,\n shallowRef,\n uniqueId,\n type UnwrapRef,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\nimport { useQueryDetector } from '../queryDetector/queryDetector';\nimport { requestAd as extRequestAd } from '../requestAds/requestAds';\nimport {\n useDomLoaded,\n useRenderIntersectionObserver,\n useSlotHooks,\n useViewabilityObserver,\n} from './slot.composables';\n\nconst renderFunctions: Record<\n RenderMode,\n (ad: RenderOptions, element: HTMLElement) => void\n> = {\n iframe: renderIframe,\n inline: renderInline,\n none: doNothing,\n};\n\nconst defaultOptions = {\n renderMode: 'iframe',\n type: 'normal',\n} satisfies Partial<AdheseSlotOptions>;\n\n/**\n * Create a new slot instance. This slot instance can be used to request and render ads.\n *\n * @param slotOptions {AdheseSlotOptions} The options to create the slot with.\n *\n * @return AdheseSlot The created slot instance.\n */\nexport function createSlot(slotOptions: AdheseSlotOptions): AdheseSlot {\n const scope = effectScope();\n\n return scope.run(() => {\n const slotContext = ref<AdheseSlotContext | null>(null);\n const options = slotOptions.context.hooks.runOnSlotCreate({\n ...defaultOptions,\n ...(Object.fromEntries(\n Object.entries(slotOptions).filter(([, value]) => value !== undefined),\n ) as AdheseSlotOptions),\n });\n\n const {\n containingElement,\n slot,\n context,\n pluginOptions,\n initialData = null,\n type = 'normal',\n } = options;\n\n let { renderMode = 'iframe' } = options;\n\n const id = uniqueId();\n const {\n runOnBeforeRender,\n runOnRender,\n runOnBeforeRequest,\n runOnRequest,\n runOnInit,\n runOnDispose,\n runOnEmpty,\n runOnError,\n runOnImpressionTracked,\n runOnViewableTracked,\n ...hooks\n } = useSlotHooks(options, slotContext);\n\n const isDisposed = ref(false);\n const parameters = reactive(\n new Map(Object.entries(options.parameters ?? {})),\n );\n\n const [device, disposeQueryDetector] = useQueryDetector(\n context,\n typeof options.format === 'string'\n ? {\n [options.format]: '(min-width: 0px)',\n }\n : Object.fromEntries(\n options.format.map(item => [item.format, item.query]),\n ),\n );\n\n const format = computed(() =>\n typeof options.format === 'string' ? options.format : device.value,\n );\n\n const data = ref<AdheseAd | null>(null) as Ref<AdheseAd | null>;\n const originalData = ref(data.value) as Ref<AdheseAd | null>;\n const name = computed(() =>\n generateName(options.context.location, format.value, options.slot),\n );\n\n const status = ref<UnwrapRef<AdheseSlot>['status']>('initializing');\n\n watch(name, async (newName, oldName) => {\n if (newName === oldName)\n return;\n\n const newAd = await slotContext.value?.request();\n\n if (!newAd)\n return;\n\n slotContext.value?.cleanElement();\n\n data.value = newAd;\n originalData.value = newAd;\n });\n\n const isDomLoaded = useDomLoaded(context);\n\n const element = shallowRef<HTMLElement | null>(null);\n\n function getElement(): HTMLElement | null {\n if (\n !(\n typeof options.containingElement === 'string'\n || !options.containingElement\n )\n ) {\n return options.containingElement;\n }\n\n if (!isDomLoaded.value)\n return null;\n\n return document.querySelector<HTMLElement>(\n `#${options.containingElement}`,\n );\n }\n\n watch(element, async (newElement, oldElement) => {\n if (\n status.value === 'empty'\n || status.value === 'error'\n || status.value === 'loading'\n ) {\n return;\n }\n\n if (newElement === null && data.value) {\n status.value = 'loaded';\n\n return;\n }\n\n if (\n newElement === oldElement\n || (oldElement === null && newElement === null)\n ) {\n return;\n }\n if (!context.options.eagerRendering) {\n return;\n }\n await render();\n });\n\n const domObserver = new MutationObserver(() => {\n element.value = getElement();\n });\n\n domObserver.observe(document.body, {\n childList: true,\n subtree: true,\n });\n\n watch(\n isDomLoaded,\n () => {\n element.value = getElement();\n },\n { immediate: true, deep: true },\n );\n\n const isInViewport = useRenderIntersectionObserver({\n options,\n element,\n hooks,\n });\n\n watch(\n isInViewport,\n async (newIsInViewport) => {\n if (newIsInViewport && status.value !== 'rendered')\n await slotContext.value?.render();\n },\n { immediate: true },\n );\n\n hooks.onDispose(() => {\n disposeQueryDetector();\n });\n\n const isViewabilityTracked = useViewabilityObserver({\n context,\n slotContext,\n hooks,\n onTracked(trackingPixel) {\n let viewabilityPixel;\n if (slotContext.value?.data?.origin === undefined) {\n context.logger.warn(\n `Origin not found for ${slotContext.value?.name}`,\n );\n return;\n }\n switch (slotContext.value?.data?.origin) {\n case 'DALE': {\n // @ts-expect-error - Data structure is not typed and very messy to type\n const seatbid = slotContext.value?.data?.originData?.seatbid;\n const bid = seatbid ? seatbid[0]?.bid[0] : undefined;\n viewabilityPixel = bid\n ? bid.ext?.adhese?.viewableImpressionCounter\n : undefined;\n break;\n }\n case 'JERLICIA':\n viewabilityPixel\n = slotContext.value?.data?.viewableImpressionCounter;\n break;\n }\n if (viewabilityPixel) {\n trackingPixel.value = addTrackingPixel(viewabilityPixel);\n context.logger.debug(\n `Viewability tracking pixel fired for ${slotContext.value?.name}`,\n );\n runOnViewableTracked(slotContext.value?.data);\n }\n },\n });\n\n const impressionTrackingPixelElement = ref<HTMLImageElement | null>(null);\n const additionalTrackingPixelElement = ref<HTMLImageElement | null>(null);\n const isImpressionTracked = ref(false);\n const isAdditionalTracked = ref(false);\n watch(\n [status, isInViewport, data],\n ([newStatus, newIsInViewport, newData]) => {\n if (newStatus === 'rendered' && newIsInViewport) {\n if (\n newData?.impressionCounter\n && !impressionTrackingPixelElement.value\n ) {\n impressionTrackingPixelElement.value = addTrackingPixel(\n newData.impressionCounter,\n );\n runOnImpressionTracked(newData);\n isImpressionTracked.value = true;\n context.logger.debug(\n `Impression tracking pixel fired for ${slotContext.value?.name}`,\n );\n }\n if (\n newData?.additionalTracker\n && !additionalTrackingPixelElement.value\n ) {\n additionalTrackingPixelElement.value = addTrackingPixel(\n newData.additionalTracker,\n );\n isAdditionalTracked.value = true;\n context.logger.debug(\n `Additional Impression tracking pixel fired for ${slotContext.value?.name}`,\n );\n }\n }\n },\n { immediate: true },\n );\n watch(status, async (newStatus, oldStatus) => {\n if ((newStatus === 'loaded' && oldStatus === 'rendered') || (newStatus === 'loading' && (oldStatus === 'rendered'))) {\n impressionTrackingPixelElement.value?.remove();\n impressionTrackingPixelElement.value = null;\n additionalTrackingPixelElement.value?.remove();\n additionalTrackingPixelElement.value = null;\n }\n });\n hooks.onDispose(() => {\n if (impressionTrackingPixelElement.value)\n impressionTrackingPixelElement.value.remove();\n if (additionalTrackingPixelElement.value)\n additionalTrackingPixelElement.value.remove();\n });\n\n async function request(): Promise<AdheseAd | null> {\n try {\n if (options.lazyLoading && !isInViewport.value)\n return null;\n\n status.value = 'loading';\n\n let response = await runOnBeforeRequest(null);\n\n if (!response) {\n response = await extRequestAd({\n slot: {\n name: name.value,\n parameters,\n },\n context,\n });\n }\n\n if (response)\n response = await runOnRequest(response);\n\n data.value = response;\n\n if (!originalData.value)\n originalData.value = response;\n\n status.value = response ? 'loaded' : 'empty';\n\n if (!response)\n cleanElement();\n\n if (response && context.options.eagerRendering && element.value)\n await render(response);\n\n return response;\n }\n catch (error) {\n processOnError(error as string);\n return null;\n }\n }\n\n async function render(adToRender?: AdheseAd): Promise<HTMLElement | null> {\n if (\n status.value === 'empty'\n || status.value === 'error'\n || status.value === 'initializing'\n ) {\n return null;\n }\n\n try {\n if (options.lazyLoading && !isInViewport.value)\n return null;\n\n status.value = 'rendering';\n await waitForDomLoad();\n element.value = getElement();\n\n let renderAd\n = adToRender ?? data.value ?? originalData.value ?? (await request());\n\n renderAd = renderAd && (await runOnBeforeRender(renderAd));\n\n renderMode = renderAd?.renderMode ?? renderMode;\n\n if (!element.value && renderMode !== 'none') {\n logger.debug(\n `Could not render slot for format ${format.value}. No element found.`,\n slotContext.value,\n );\n\n return null;\n }\n\n if (!renderAd) {\n return null;\n }\n\n if (typeof renderAd?.tag !== 'string' && renderMode !== 'none') {\n const error = `Could not render slot for slot ${name.value}. A valid tag doesn't exist or is not HTML string.`;\n throw new Error(error);\n }\n\n if (renderMode !== 'none' && element.value) {\n renderFunctions[renderMode](\n {\n ...renderAd,\n ...pick(options, ['width', 'height']),\n } as RenderOptions,\n element.value,\n );\n }\n\n logger.debug(`Slot rendered ${name.value}`, {\n renderedElement: element,\n location: context.location,\n format,\n containingElement,\n });\n\n // eslint-disable-next-line require-atomic-updates\n status.value = 'rendered';\n\n runOnRender(renderAd);\n\n return element.value;\n }\n catch (error) {\n processOnError(error as string);\n return null;\n }\n }\n\n function processOnEmpty(): void {\n status.value = 'empty';\n logger.debug(`No ad to render for slot ${name.value}`);\n runOnEmpty();\n }\n\n function processOnError(error: string): void {\n if (status.value !== 'error') {\n status.value = 'error';\n logger.error(error);\n runOnError(new Error(error, {\n cause: error,\n }));\n }\n }\n\n function cleanElement(): void {\n if (!element.value || renderMode === 'none')\n return;\n\n element.value.innerHTML = '';\n element.value.style.position = '';\n }\n\n function dispose(): void {\n cleanElement();\n\n element.value = null;\n\n data.value = null;\n originalData.value = null;\n\n domObserver.disconnect();\n\n runOnDispose();\n\n isDisposed.value = true;\n\n scope.stop();\n }\n\n const state = reactive({\n location: context.location ?? '',\n lazyLoading: options.lazyLoading ?? false,\n type,\n slot,\n parameters,\n format,\n name,\n data,\n isViewabilityTracked,\n isImpressionTracked,\n status,\n element,\n isDisposed,\n id,\n pluginOptions,\n isVisible: isInViewport,\n render,\n request,\n dispose,\n processOnEmpty,\n processOnError,\n cleanElement,\n options: omit(options, ['context']),\n ...hooks,\n });\n\n watch(\n state,\n (newState) => {\n slotContext.value = newState;\n },\n {\n deep: true,\n immediate: true,\n },\n );\n\n context.hooks.onInit(async () => {\n await runOnInit();\n\n if (status.value === 'empty' || status.value === 'error') {\n return;\n }\n\n if (initialData) {\n status.value = 'loaded';\n\n data.value = initialData;\n data.value = await runOnRequest(initialData);\n\n return;\n }\n\n status.value = 'initialized';\n\n if (options.lazyLoading) {\n return;\n }\n\n data.value = (await slotContext.value?.request()) ?? null;\n });\n\n return state;\n })!;\n}\n"],"names":["renderIframe","renderInline","doNothing","effectScope","ref","uniqueId","useSlotHooks","reactive","useQueryDetector","computed","generateName","watch","useDomLoaded","shallowRef","useRenderIntersectionObserver","useViewabilityObserver","addTrackingPixel","extRequestAd","waitForDomLoad","logger","pick","omit"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"slot.cjs","sources":["../../../src/slot/slot.ts"],"sourcesContent":["import type { AdheseAd } from '@adhese/sdk';\nimport type {\n AdheseSlot,\n AdheseSlotContext,\n AdheseSlotOptions,\n RenderMode,\n} from './slot.types';\nimport {\n addTrackingPixel,\n computed,\n doNothing,\n effectScope,\n generateName,\n omit,\n pick,\n reactive,\n type Ref,\n ref,\n renderIframe,\n renderInline,\n type RenderOptions,\n shallowRef,\n uniqueId,\n type UnwrapRef,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\nimport { useQueryDetector } from '../queryDetector/queryDetector';\nimport { requestAd as extRequestAd } from '../requestAds/requestAds';\nimport {\n useDomLoaded,\n useRenderIntersectionObserver,\n useSlotHooks,\n useViewabilityObserver,\n} from './slot.composables';\n\nconst renderFunctions: Record<\n RenderMode,\n (ad: RenderOptions, element: HTMLElement) => void\n> = {\n iframe: renderIframe,\n inline: renderInline,\n none: doNothing,\n};\n\nconst defaultOptions = {\n renderMode: 'iframe',\n type: 'normal',\n} satisfies Partial<AdheseSlotOptions>;\n\n/**\n * Create a new slot instance. This slot instance can be used to request and render ads.\n *\n * @param slotOptions {AdheseSlotOptions} The options to create the slot with.\n *\n * @return AdheseSlot The created slot instance.\n */\nexport function createSlot(slotOptions: AdheseSlotOptions): AdheseSlot {\n const scope = effectScope();\n\n return scope.run(() => {\n const slotContext = ref<AdheseSlotContext | null>(null);\n const options = slotOptions.context.hooks.runOnSlotCreate({\n ...defaultOptions,\n ...(Object.fromEntries(\n Object.entries(slotOptions).filter(([, value]) => value !== undefined),\n ) as AdheseSlotOptions),\n });\n\n const {\n containingElement,\n slot,\n context,\n pluginOptions,\n initialData = null,\n type = 'normal',\n } = options;\n\n let { renderMode = 'iframe' } = options;\n\n const id = uniqueId();\n const {\n runOnBeforeRender,\n runOnRender,\n runOnBeforeRequest,\n runOnRequest,\n runOnInit,\n runOnDispose,\n runOnEmpty,\n runOnError,\n runOnImpressionTracked,\n runOnViewableTracked,\n ...hooks\n } = useSlotHooks(options, slotContext);\n\n const isDisposed = ref(false);\n const parameters = reactive(\n new Map(Object.entries(options.parameters ?? {})),\n );\n\n const [device, disposeQueryDetector] = useQueryDetector(\n context,\n typeof options.format === 'string'\n ? {\n [options.format]: '(min-width: 0px)',\n }\n : Object.fromEntries(\n options.format.map(item => [item.format, item.query]),\n ),\n );\n\n const format = computed(() =>\n typeof options.format === 'string' ? options.format : device.value,\n );\n\n const data = ref<AdheseAd | null>(null) as Ref<AdheseAd | null>;\n const originalData = ref(data.value) as Ref<AdheseAd | null>;\n const name = computed(() =>\n generateName(options.context.location, format.value, options.slot),\n );\n\n const status = ref<UnwrapRef<AdheseSlot>['status']>('initializing');\n\n watch(name, async (newName, oldName) => {\n if (newName === oldName)\n return;\n\n const newAd = await slotContext.value?.request();\n\n if (!newAd)\n return;\n\n slotContext.value?.cleanElement();\n\n data.value = newAd;\n originalData.value = newAd;\n });\n\n const isDomLoaded = useDomLoaded(context);\n\n const element = shallowRef<HTMLElement | null>(null);\n\n function getElement(): HTMLElement | null {\n if (\n !(\n typeof options.containingElement === 'string'\n || !options.containingElement\n )\n ) {\n return options.containingElement;\n }\n\n if (!isDomLoaded.value)\n return null;\n\n return document.querySelector<HTMLElement>(\n `#${options.containingElement}`,\n );\n }\n\n watch(element, async (newElement, oldElement) => {\n if (\n status.value === 'empty'\n || status.value === 'error'\n || status.value === 'loading'\n ) {\n return;\n }\n\n if (newElement === null && data.value) {\n status.value = 'loaded';\n\n return;\n }\n\n if (\n newElement === oldElement\n || (oldElement === null && newElement === null)\n ) {\n return;\n }\n if (!context.options.eagerRendering && !oldElement) {\n return;\n }\n await render();\n });\n\n const domObserver = new MutationObserver(() => {\n element.value = getElement();\n });\n\n domObserver.observe(document.body, {\n childList: true,\n subtree: true,\n });\n\n watch(\n isDomLoaded,\n () => {\n element.value = getElement();\n },\n { immediate: true, deep: true },\n );\n\n const isInViewport = useRenderIntersectionObserver({\n options,\n element,\n hooks,\n });\n\n watch(\n isInViewport,\n async (newIsInViewport) => {\n if (newIsInViewport && status.value !== 'rendered')\n await slotContext.value?.render();\n },\n { immediate: true },\n );\n\n hooks.onDispose(() => {\n disposeQueryDetector();\n });\n\n const isViewabilityTracked = useViewabilityObserver({\n context,\n slotContext,\n hooks,\n onTracked(trackingPixel) {\n let viewabilityPixel;\n if (slotContext.value?.data?.origin === undefined) {\n context.logger.warn(\n `Origin not found for ${slotContext.value?.name}`,\n );\n return;\n }\n switch (slotContext.value?.data?.origin) {\n case 'DALE': {\n // @ts-expect-error - Data structure is not typed and very messy to type\n const seatbid = slotContext.value?.data?.originData?.seatbid;\n const bid = seatbid ? seatbid[0]?.bid[0] : undefined;\n viewabilityPixel = bid\n ? bid.ext?.adhese?.viewableImpressionCounter\n : undefined;\n break;\n }\n case 'JERLICIA':\n viewabilityPixel\n = slotContext.value?.data?.viewableImpressionCounter;\n break;\n }\n if (viewabilityPixel) {\n trackingPixel.value = addTrackingPixel(viewabilityPixel);\n context.logger.debug(\n `Viewability tracking pixel fired for ${slotContext.value?.name}`,\n );\n runOnViewableTracked(slotContext.value?.data);\n }\n },\n });\n\n const impressionTrackingPixelElement = ref<HTMLImageElement | null>(null);\n const additionalTrackingPixelElement = ref<HTMLImageElement | null>(null);\n const isImpressionTracked = ref(false);\n const isAdditionalTracked = ref(false);\n watch(\n [status, isInViewport, data],\n ([newStatus, newIsInViewport, newData]) => {\n if (newStatus === 'rendered' && newIsInViewport) {\n if (\n newData?.impressionCounter\n && !impressionTrackingPixelElement.value\n ) {\n impressionTrackingPixelElement.value = addTrackingPixel(\n newData.impressionCounter,\n );\n runOnImpressionTracked(newData);\n isImpressionTracked.value = true;\n context.logger.debug(\n `Impression tracking pixel fired for ${slotContext.value?.name}`,\n );\n }\n if (\n newData?.additionalTracker\n && !additionalTrackingPixelElement.value\n ) {\n additionalTrackingPixelElement.value = addTrackingPixel(\n newData.additionalTracker,\n );\n isAdditionalTracked.value = true;\n context.logger.debug(\n `Additional Impression tracking pixel fired for ${slotContext.value?.name}`,\n );\n }\n }\n },\n { immediate: true },\n );\n watch(status, async (newStatus, oldStatus) => {\n if ((newStatus === 'loaded' && oldStatus === 'rendered') || (newStatus === 'loading' && (oldStatus === 'rendered'))) {\n impressionTrackingPixelElement.value?.remove();\n impressionTrackingPixelElement.value = null;\n additionalTrackingPixelElement.value?.remove();\n additionalTrackingPixelElement.value = null;\n }\n });\n hooks.onDispose(() => {\n if (impressionTrackingPixelElement.value)\n impressionTrackingPixelElement.value.remove();\n if (additionalTrackingPixelElement.value)\n additionalTrackingPixelElement.value.remove();\n });\n\n async function request(): Promise<AdheseAd | null> {\n try {\n if (options.lazyLoading && !isInViewport.value)\n return null;\n\n status.value = 'loading';\n\n let response = await runOnBeforeRequest(null);\n\n if (!response) {\n response = await extRequestAd({\n slot: {\n name: name.value,\n parameters,\n },\n context,\n });\n }\n\n if (response)\n response = await runOnRequest(response);\n\n data.value = response;\n\n if (!originalData.value)\n originalData.value = response;\n\n status.value = response ? 'loaded' : 'empty';\n\n if (!response)\n cleanElement();\n\n if (response && context.options.eagerRendering && element.value)\n await render(response);\n\n return response;\n }\n catch (error) {\n processOnError(error as string);\n return null;\n }\n }\n\n async function render(adToRender?: AdheseAd): Promise<HTMLElement | null> {\n if (\n status.value === 'empty'\n || status.value === 'error'\n || status.value === 'initializing'\n ) {\n return null;\n }\n\n try {\n if (options.lazyLoading && !isInViewport.value)\n return null;\n\n status.value = 'rendering';\n await waitForDomLoad();\n element.value = getElement();\n\n let renderAd\n = adToRender ?? data.value ?? originalData.value ?? (await request());\n\n renderAd = renderAd && (await runOnBeforeRender(renderAd));\n\n renderMode = renderAd?.renderMode ?? renderMode;\n\n if (!element.value && renderMode !== 'none') {\n logger.debug(\n `Could not render slot for format ${format.value}. No element found.`,\n slotContext.value,\n );\n\n return null;\n }\n\n if (!renderAd) {\n return null;\n }\n\n if (typeof renderAd?.tag !== 'string' && renderMode !== 'none') {\n const error = `Could not render slot for slot ${name.value}. A valid tag doesn't exist or is not HTML string.`;\n throw new Error(error);\n }\n\n if (renderMode !== 'none' && element.value) {\n renderFunctions[renderMode](\n {\n ...renderAd,\n ...pick(options, ['width', 'height']),\n } as RenderOptions,\n element.value,\n );\n }\n\n logger.debug(`Slot rendered ${name.value}`, {\n renderedElement: element,\n location: context.location,\n format,\n containingElement,\n });\n\n // eslint-disable-next-line require-atomic-updates\n status.value = 'rendered';\n\n runOnRender(renderAd);\n\n return element.value;\n }\n catch (error) {\n processOnError(error as string);\n return null;\n }\n }\n\n function processOnEmpty(): void {\n status.value = 'empty';\n logger.debug(`No ad to render for slot ${name.value}`);\n runOnEmpty();\n }\n\n function processOnError(error: string): void {\n if (status.value !== 'error') {\n status.value = 'error';\n logger.error(error);\n runOnError(new Error(error, {\n cause: error,\n }));\n }\n }\n\n function cleanElement(): void {\n if (!element.value || renderMode === 'none')\n return;\n\n element.value.innerHTML = '';\n element.value.style.position = '';\n }\n\n function dispose(): void {\n cleanElement();\n\n element.value = null;\n\n data.value = null;\n originalData.value = null;\n\n domObserver.disconnect();\n\n runOnDispose();\n\n isDisposed.value = true;\n\n scope.stop();\n }\n\n const state = reactive({\n location: context.location ?? '',\n lazyLoading: options.lazyLoading ?? false,\n type,\n slot,\n parameters,\n format,\n name,\n data,\n isViewabilityTracked,\n isImpressionTracked,\n status,\n element,\n isDisposed,\n id,\n pluginOptions,\n isVisible: isInViewport,\n render,\n request,\n dispose,\n processOnEmpty,\n processOnError,\n cleanElement,\n options: omit(options, ['context']),\n ...hooks,\n });\n\n watch(\n state,\n (newState) => {\n slotContext.value = newState;\n },\n {\n deep: true,\n immediate: true,\n },\n );\n\n context.hooks.onInit(async () => {\n await runOnInit();\n\n if (status.value === 'empty' || status.value === 'error') {\n return;\n }\n\n if (initialData) {\n status.value = 'loaded';\n\n data.value = initialData;\n data.value = await runOnRequest(initialData);\n\n return;\n }\n\n status.value = 'initialized';\n\n if (options.lazyLoading) {\n return;\n }\n\n data.value = (await slotContext.value?.request()) ?? null;\n });\n\n return state;\n })!;\n}\n"],"names":["renderIframe","renderInline","doNothing","effectScope","ref","uniqueId","useSlotHooks","reactive","useQueryDetector","computed","generateName","watch","useDomLoaded","shallowRef","useRenderIntersectionObserver","useViewabilityObserver","addTrackingPixel","extRequestAd","waitForDomLoad","logger","pick","omit"],"mappings":"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"}
|
package/dist/package.json.js
CHANGED
package/dist/slot/slot.js
CHANGED
|
@@ -100,7 +100,7 @@ function createSlot(slotOptions) {
|
|
|
100
100
|
if (newElement === oldElement || oldElement === null && newElement === null) {
|
|
101
101
|
return;
|
|
102
102
|
}
|
|
103
|
-
if (!context.options.eagerRendering) {
|
|
103
|
+
if (!context.options.eagerRendering && !oldElement) {
|
|
104
104
|
return;
|
|
105
105
|
}
|
|
106
106
|
await render();
|
package/dist/slot/slot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slot.js","sources":["../../src/slot/slot.ts"],"sourcesContent":["import type { AdheseAd } from '@adhese/sdk';\nimport type {\n AdheseSlot,\n AdheseSlotContext,\n AdheseSlotOptions,\n RenderMode,\n} from './slot.types';\nimport {\n addTrackingPixel,\n computed,\n doNothing,\n effectScope,\n generateName,\n omit,\n pick,\n reactive,\n type Ref,\n ref,\n renderIframe,\n renderInline,\n type RenderOptions,\n shallowRef,\n uniqueId,\n type UnwrapRef,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\nimport { useQueryDetector } from '../queryDetector/queryDetector';\nimport { requestAd as extRequestAd } from '../requestAds/requestAds';\nimport {\n useDomLoaded,\n useRenderIntersectionObserver,\n useSlotHooks,\n useViewabilityObserver,\n} from './slot.composables';\n\nconst renderFunctions: Record<\n RenderMode,\n (ad: RenderOptions, element: HTMLElement) => void\n> = {\n iframe: renderIframe,\n inline: renderInline,\n none: doNothing,\n};\n\nconst defaultOptions = {\n renderMode: 'iframe',\n type: 'normal',\n} satisfies Partial<AdheseSlotOptions>;\n\n/**\n * Create a new slot instance. This slot instance can be used to request and render ads.\n *\n * @param slotOptions {AdheseSlotOptions} The options to create the slot with.\n *\n * @return AdheseSlot The created slot instance.\n */\nexport function createSlot(slotOptions: AdheseSlotOptions): AdheseSlot {\n const scope = effectScope();\n\n return scope.run(() => {\n const slotContext = ref<AdheseSlotContext | null>(null);\n const options = slotOptions.context.hooks.runOnSlotCreate({\n ...defaultOptions,\n ...(Object.fromEntries(\n Object.entries(slotOptions).filter(([, value]) => value !== undefined),\n ) as AdheseSlotOptions),\n });\n\n const {\n containingElement,\n slot,\n context,\n pluginOptions,\n initialData = null,\n type = 'normal',\n } = options;\n\n let { renderMode = 'iframe' } = options;\n\n const id = uniqueId();\n const {\n runOnBeforeRender,\n runOnRender,\n runOnBeforeRequest,\n runOnRequest,\n runOnInit,\n runOnDispose,\n runOnEmpty,\n runOnError,\n runOnImpressionTracked,\n runOnViewableTracked,\n ...hooks\n } = useSlotHooks(options, slotContext);\n\n const isDisposed = ref(false);\n const parameters = reactive(\n new Map(Object.entries(options.parameters ?? {})),\n );\n\n const [device, disposeQueryDetector] = useQueryDetector(\n context,\n typeof options.format === 'string'\n ? {\n [options.format]: '(min-width: 0px)',\n }\n : Object.fromEntries(\n options.format.map(item => [item.format, item.query]),\n ),\n );\n\n const format = computed(() =>\n typeof options.format === 'string' ? options.format : device.value,\n );\n\n const data = ref<AdheseAd | null>(null) as Ref<AdheseAd | null>;\n const originalData = ref(data.value) as Ref<AdheseAd | null>;\n const name = computed(() =>\n generateName(options.context.location, format.value, options.slot),\n );\n\n const status = ref<UnwrapRef<AdheseSlot>['status']>('initializing');\n\n watch(name, async (newName, oldName) => {\n if (newName === oldName)\n return;\n\n const newAd = await slotContext.value?.request();\n\n if (!newAd)\n return;\n\n slotContext.value?.cleanElement();\n\n data.value = newAd;\n originalData.value = newAd;\n });\n\n const isDomLoaded = useDomLoaded(context);\n\n const element = shallowRef<HTMLElement | null>(null);\n\n function getElement(): HTMLElement | null {\n if (\n !(\n typeof options.containingElement === 'string'\n || !options.containingElement\n )\n ) {\n return options.containingElement;\n }\n\n if (!isDomLoaded.value)\n return null;\n\n return document.querySelector<HTMLElement>(\n `#${options.containingElement}`,\n );\n }\n\n watch(element, async (newElement, oldElement) => {\n if (\n status.value === 'empty'\n || status.value === 'error'\n || status.value === 'loading'\n ) {\n return;\n }\n\n if (newElement === null && data.value) {\n status.value = 'loaded';\n\n return;\n }\n\n if (\n newElement === oldElement\n || (oldElement === null && newElement === null)\n ) {\n return;\n }\n if (!context.options.eagerRendering) {\n return;\n }\n await render();\n });\n\n const domObserver = new MutationObserver(() => {\n element.value = getElement();\n });\n\n domObserver.observe(document.body, {\n childList: true,\n subtree: true,\n });\n\n watch(\n isDomLoaded,\n () => {\n element.value = getElement();\n },\n { immediate: true, deep: true },\n );\n\n const isInViewport = useRenderIntersectionObserver({\n options,\n element,\n hooks,\n });\n\n watch(\n isInViewport,\n async (newIsInViewport) => {\n if (newIsInViewport && status.value !== 'rendered')\n await slotContext.value?.render();\n },\n { immediate: true },\n );\n\n hooks.onDispose(() => {\n disposeQueryDetector();\n });\n\n const isViewabilityTracked = useViewabilityObserver({\n context,\n slotContext,\n hooks,\n onTracked(trackingPixel) {\n let viewabilityPixel;\n if (slotContext.value?.data?.origin === undefined) {\n context.logger.warn(\n `Origin not found for ${slotContext.value?.name}`,\n );\n return;\n }\n switch (slotContext.value?.data?.origin) {\n case 'DALE': {\n // @ts-expect-error - Data structure is not typed and very messy to type\n const seatbid = slotContext.value?.data?.originData?.seatbid;\n const bid = seatbid ? seatbid[0]?.bid[0] : undefined;\n viewabilityPixel = bid\n ? bid.ext?.adhese?.viewableImpressionCounter\n : undefined;\n break;\n }\n case 'JERLICIA':\n viewabilityPixel\n = slotContext.value?.data?.viewableImpressionCounter;\n break;\n }\n if (viewabilityPixel) {\n trackingPixel.value = addTrackingPixel(viewabilityPixel);\n context.logger.debug(\n `Viewability tracking pixel fired for ${slotContext.value?.name}`,\n );\n runOnViewableTracked(slotContext.value?.data);\n }\n },\n });\n\n const impressionTrackingPixelElement = ref<HTMLImageElement | null>(null);\n const additionalTrackingPixelElement = ref<HTMLImageElement | null>(null);\n const isImpressionTracked = ref(false);\n const isAdditionalTracked = ref(false);\n watch(\n [status, isInViewport, data],\n ([newStatus, newIsInViewport, newData]) => {\n if (newStatus === 'rendered' && newIsInViewport) {\n if (\n newData?.impressionCounter\n && !impressionTrackingPixelElement.value\n ) {\n impressionTrackingPixelElement.value = addTrackingPixel(\n newData.impressionCounter,\n );\n runOnImpressionTracked(newData);\n isImpressionTracked.value = true;\n context.logger.debug(\n `Impression tracking pixel fired for ${slotContext.value?.name}`,\n );\n }\n if (\n newData?.additionalTracker\n && !additionalTrackingPixelElement.value\n ) {\n additionalTrackingPixelElement.value = addTrackingPixel(\n newData.additionalTracker,\n );\n isAdditionalTracked.value = true;\n context.logger.debug(\n `Additional Impression tracking pixel fired for ${slotContext.value?.name}`,\n );\n }\n }\n },\n { immediate: true },\n );\n watch(status, async (newStatus, oldStatus) => {\n if ((newStatus === 'loaded' && oldStatus === 'rendered') || (newStatus === 'loading' && (oldStatus === 'rendered'))) {\n impressionTrackingPixelElement.value?.remove();\n impressionTrackingPixelElement.value = null;\n additionalTrackingPixelElement.value?.remove();\n additionalTrackingPixelElement.value = null;\n }\n });\n hooks.onDispose(() => {\n if (impressionTrackingPixelElement.value)\n impressionTrackingPixelElement.value.remove();\n if (additionalTrackingPixelElement.value)\n additionalTrackingPixelElement.value.remove();\n });\n\n async function request(): Promise<AdheseAd | null> {\n try {\n if (options.lazyLoading && !isInViewport.value)\n return null;\n\n status.value = 'loading';\n\n let response = await runOnBeforeRequest(null);\n\n if (!response) {\n response = await extRequestAd({\n slot: {\n name: name.value,\n parameters,\n },\n context,\n });\n }\n\n if (response)\n response = await runOnRequest(response);\n\n data.value = response;\n\n if (!originalData.value)\n originalData.value = response;\n\n status.value = response ? 'loaded' : 'empty';\n\n if (!response)\n cleanElement();\n\n if (response && context.options.eagerRendering && element.value)\n await render(response);\n\n return response;\n }\n catch (error) {\n processOnError(error as string);\n return null;\n }\n }\n\n async function render(adToRender?: AdheseAd): Promise<HTMLElement | null> {\n if (\n status.value === 'empty'\n || status.value === 'error'\n || status.value === 'initializing'\n ) {\n return null;\n }\n\n try {\n if (options.lazyLoading && !isInViewport.value)\n return null;\n\n status.value = 'rendering';\n await waitForDomLoad();\n element.value = getElement();\n\n let renderAd\n = adToRender ?? data.value ?? originalData.value ?? (await request());\n\n renderAd = renderAd && (await runOnBeforeRender(renderAd));\n\n renderMode = renderAd?.renderMode ?? renderMode;\n\n if (!element.value && renderMode !== 'none') {\n logger.debug(\n `Could not render slot for format ${format.value}. No element found.`,\n slotContext.value,\n );\n\n return null;\n }\n\n if (!renderAd) {\n return null;\n }\n\n if (typeof renderAd?.tag !== 'string' && renderMode !== 'none') {\n const error = `Could not render slot for slot ${name.value}. A valid tag doesn't exist or is not HTML string.`;\n throw new Error(error);\n }\n\n if (renderMode !== 'none' && element.value) {\n renderFunctions[renderMode](\n {\n ...renderAd,\n ...pick(options, ['width', 'height']),\n } as RenderOptions,\n element.value,\n );\n }\n\n logger.debug(`Slot rendered ${name.value}`, {\n renderedElement: element,\n location: context.location,\n format,\n containingElement,\n });\n\n // eslint-disable-next-line require-atomic-updates\n status.value = 'rendered';\n\n runOnRender(renderAd);\n\n return element.value;\n }\n catch (error) {\n processOnError(error as string);\n return null;\n }\n }\n\n function processOnEmpty(): void {\n status.value = 'empty';\n logger.debug(`No ad to render for slot ${name.value}`);\n runOnEmpty();\n }\n\n function processOnError(error: string): void {\n if (status.value !== 'error') {\n status.value = 'error';\n logger.error(error);\n runOnError(new Error(error, {\n cause: error,\n }));\n }\n }\n\n function cleanElement(): void {\n if (!element.value || renderMode === 'none')\n return;\n\n element.value.innerHTML = '';\n element.value.style.position = '';\n }\n\n function dispose(): void {\n cleanElement();\n\n element.value = null;\n\n data.value = null;\n originalData.value = null;\n\n domObserver.disconnect();\n\n runOnDispose();\n\n isDisposed.value = true;\n\n scope.stop();\n }\n\n const state = reactive({\n location: context.location ?? '',\n lazyLoading: options.lazyLoading ?? false,\n type,\n slot,\n parameters,\n format,\n name,\n data,\n isViewabilityTracked,\n isImpressionTracked,\n status,\n element,\n isDisposed,\n id,\n pluginOptions,\n isVisible: isInViewport,\n render,\n request,\n dispose,\n processOnEmpty,\n processOnError,\n cleanElement,\n options: omit(options, ['context']),\n ...hooks,\n });\n\n watch(\n state,\n (newState) => {\n slotContext.value = newState;\n },\n {\n deep: true,\n immediate: true,\n },\n );\n\n context.hooks.onInit(async () => {\n await runOnInit();\n\n if (status.value === 'empty' || status.value === 'error') {\n return;\n }\n\n if (initialData) {\n status.value = 'loaded';\n\n data.value = initialData;\n data.value = await runOnRequest(initialData);\n\n return;\n }\n\n status.value = 'initialized';\n\n if (options.lazyLoading) {\n return;\n }\n\n data.value = (await slotContext.value?.request()) ?? null;\n });\n\n return state;\n })!;\n}\n"],"names":["extRequestAd"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"slot.js","sources":["../../src/slot/slot.ts"],"sourcesContent":["import type { AdheseAd } from '@adhese/sdk';\nimport type {\n AdheseSlot,\n AdheseSlotContext,\n AdheseSlotOptions,\n RenderMode,\n} from './slot.types';\nimport {\n addTrackingPixel,\n computed,\n doNothing,\n effectScope,\n generateName,\n omit,\n pick,\n reactive,\n type Ref,\n ref,\n renderIframe,\n renderInline,\n type RenderOptions,\n shallowRef,\n uniqueId,\n type UnwrapRef,\n waitForDomLoad,\n watch,\n} from '@adhese/sdk-shared';\nimport { logger } from '../logger/logger';\nimport { useQueryDetector } from '../queryDetector/queryDetector';\nimport { requestAd as extRequestAd } from '../requestAds/requestAds';\nimport {\n useDomLoaded,\n useRenderIntersectionObserver,\n useSlotHooks,\n useViewabilityObserver,\n} from './slot.composables';\n\nconst renderFunctions: Record<\n RenderMode,\n (ad: RenderOptions, element: HTMLElement) => void\n> = {\n iframe: renderIframe,\n inline: renderInline,\n none: doNothing,\n};\n\nconst defaultOptions = {\n renderMode: 'iframe',\n type: 'normal',\n} satisfies Partial<AdheseSlotOptions>;\n\n/**\n * Create a new slot instance. This slot instance can be used to request and render ads.\n *\n * @param slotOptions {AdheseSlotOptions} The options to create the slot with.\n *\n * @return AdheseSlot The created slot instance.\n */\nexport function createSlot(slotOptions: AdheseSlotOptions): AdheseSlot {\n const scope = effectScope();\n\n return scope.run(() => {\n const slotContext = ref<AdheseSlotContext | null>(null);\n const options = slotOptions.context.hooks.runOnSlotCreate({\n ...defaultOptions,\n ...(Object.fromEntries(\n Object.entries(slotOptions).filter(([, value]) => value !== undefined),\n ) as AdheseSlotOptions),\n });\n\n const {\n containingElement,\n slot,\n context,\n pluginOptions,\n initialData = null,\n type = 'normal',\n } = options;\n\n let { renderMode = 'iframe' } = options;\n\n const id = uniqueId();\n const {\n runOnBeforeRender,\n runOnRender,\n runOnBeforeRequest,\n runOnRequest,\n runOnInit,\n runOnDispose,\n runOnEmpty,\n runOnError,\n runOnImpressionTracked,\n runOnViewableTracked,\n ...hooks\n } = useSlotHooks(options, slotContext);\n\n const isDisposed = ref(false);\n const parameters = reactive(\n new Map(Object.entries(options.parameters ?? {})),\n );\n\n const [device, disposeQueryDetector] = useQueryDetector(\n context,\n typeof options.format === 'string'\n ? {\n [options.format]: '(min-width: 0px)',\n }\n : Object.fromEntries(\n options.format.map(item => [item.format, item.query]),\n ),\n );\n\n const format = computed(() =>\n typeof options.format === 'string' ? options.format : device.value,\n );\n\n const data = ref<AdheseAd | null>(null) as Ref<AdheseAd | null>;\n const originalData = ref(data.value) as Ref<AdheseAd | null>;\n const name = computed(() =>\n generateName(options.context.location, format.value, options.slot),\n );\n\n const status = ref<UnwrapRef<AdheseSlot>['status']>('initializing');\n\n watch(name, async (newName, oldName) => {\n if (newName === oldName)\n return;\n\n const newAd = await slotContext.value?.request();\n\n if (!newAd)\n return;\n\n slotContext.value?.cleanElement();\n\n data.value = newAd;\n originalData.value = newAd;\n });\n\n const isDomLoaded = useDomLoaded(context);\n\n const element = shallowRef<HTMLElement | null>(null);\n\n function getElement(): HTMLElement | null {\n if (\n !(\n typeof options.containingElement === 'string'\n || !options.containingElement\n )\n ) {\n return options.containingElement;\n }\n\n if (!isDomLoaded.value)\n return null;\n\n return document.querySelector<HTMLElement>(\n `#${options.containingElement}`,\n );\n }\n\n watch(element, async (newElement, oldElement) => {\n if (\n status.value === 'empty'\n || status.value === 'error'\n || status.value === 'loading'\n ) {\n return;\n }\n\n if (newElement === null && data.value) {\n status.value = 'loaded';\n\n return;\n }\n\n if (\n newElement === oldElement\n || (oldElement === null && newElement === null)\n ) {\n return;\n }\n if (!context.options.eagerRendering && !oldElement) {\n return;\n }\n await render();\n });\n\n const domObserver = new MutationObserver(() => {\n element.value = getElement();\n });\n\n domObserver.observe(document.body, {\n childList: true,\n subtree: true,\n });\n\n watch(\n isDomLoaded,\n () => {\n element.value = getElement();\n },\n { immediate: true, deep: true },\n );\n\n const isInViewport = useRenderIntersectionObserver({\n options,\n element,\n hooks,\n });\n\n watch(\n isInViewport,\n async (newIsInViewport) => {\n if (newIsInViewport && status.value !== 'rendered')\n await slotContext.value?.render();\n },\n { immediate: true },\n );\n\n hooks.onDispose(() => {\n disposeQueryDetector();\n });\n\n const isViewabilityTracked = useViewabilityObserver({\n context,\n slotContext,\n hooks,\n onTracked(trackingPixel) {\n let viewabilityPixel;\n if (slotContext.value?.data?.origin === undefined) {\n context.logger.warn(\n `Origin not found for ${slotContext.value?.name}`,\n );\n return;\n }\n switch (slotContext.value?.data?.origin) {\n case 'DALE': {\n // @ts-expect-error - Data structure is not typed and very messy to type\n const seatbid = slotContext.value?.data?.originData?.seatbid;\n const bid = seatbid ? seatbid[0]?.bid[0] : undefined;\n viewabilityPixel = bid\n ? bid.ext?.adhese?.viewableImpressionCounter\n : undefined;\n break;\n }\n case 'JERLICIA':\n viewabilityPixel\n = slotContext.value?.data?.viewableImpressionCounter;\n break;\n }\n if (viewabilityPixel) {\n trackingPixel.value = addTrackingPixel(viewabilityPixel);\n context.logger.debug(\n `Viewability tracking pixel fired for ${slotContext.value?.name}`,\n );\n runOnViewableTracked(slotContext.value?.data);\n }\n },\n });\n\n const impressionTrackingPixelElement = ref<HTMLImageElement | null>(null);\n const additionalTrackingPixelElement = ref<HTMLImageElement | null>(null);\n const isImpressionTracked = ref(false);\n const isAdditionalTracked = ref(false);\n watch(\n [status, isInViewport, data],\n ([newStatus, newIsInViewport, newData]) => {\n if (newStatus === 'rendered' && newIsInViewport) {\n if (\n newData?.impressionCounter\n && !impressionTrackingPixelElement.value\n ) {\n impressionTrackingPixelElement.value = addTrackingPixel(\n newData.impressionCounter,\n );\n runOnImpressionTracked(newData);\n isImpressionTracked.value = true;\n context.logger.debug(\n `Impression tracking pixel fired for ${slotContext.value?.name}`,\n );\n }\n if (\n newData?.additionalTracker\n && !additionalTrackingPixelElement.value\n ) {\n additionalTrackingPixelElement.value = addTrackingPixel(\n newData.additionalTracker,\n );\n isAdditionalTracked.value = true;\n context.logger.debug(\n `Additional Impression tracking pixel fired for ${slotContext.value?.name}`,\n );\n }\n }\n },\n { immediate: true },\n );\n watch(status, async (newStatus, oldStatus) => {\n if ((newStatus === 'loaded' && oldStatus === 'rendered') || (newStatus === 'loading' && (oldStatus === 'rendered'))) {\n impressionTrackingPixelElement.value?.remove();\n impressionTrackingPixelElement.value = null;\n additionalTrackingPixelElement.value?.remove();\n additionalTrackingPixelElement.value = null;\n }\n });\n hooks.onDispose(() => {\n if (impressionTrackingPixelElement.value)\n impressionTrackingPixelElement.value.remove();\n if (additionalTrackingPixelElement.value)\n additionalTrackingPixelElement.value.remove();\n });\n\n async function request(): Promise<AdheseAd | null> {\n try {\n if (options.lazyLoading && !isInViewport.value)\n return null;\n\n status.value = 'loading';\n\n let response = await runOnBeforeRequest(null);\n\n if (!response) {\n response = await extRequestAd({\n slot: {\n name: name.value,\n parameters,\n },\n context,\n });\n }\n\n if (response)\n response = await runOnRequest(response);\n\n data.value = response;\n\n if (!originalData.value)\n originalData.value = response;\n\n status.value = response ? 'loaded' : 'empty';\n\n if (!response)\n cleanElement();\n\n if (response && context.options.eagerRendering && element.value)\n await render(response);\n\n return response;\n }\n catch (error) {\n processOnError(error as string);\n return null;\n }\n }\n\n async function render(adToRender?: AdheseAd): Promise<HTMLElement | null> {\n if (\n status.value === 'empty'\n || status.value === 'error'\n || status.value === 'initializing'\n ) {\n return null;\n }\n\n try {\n if (options.lazyLoading && !isInViewport.value)\n return null;\n\n status.value = 'rendering';\n await waitForDomLoad();\n element.value = getElement();\n\n let renderAd\n = adToRender ?? data.value ?? originalData.value ?? (await request());\n\n renderAd = renderAd && (await runOnBeforeRender(renderAd));\n\n renderMode = renderAd?.renderMode ?? renderMode;\n\n if (!element.value && renderMode !== 'none') {\n logger.debug(\n `Could not render slot for format ${format.value}. No element found.`,\n slotContext.value,\n );\n\n return null;\n }\n\n if (!renderAd) {\n return null;\n }\n\n if (typeof renderAd?.tag !== 'string' && renderMode !== 'none') {\n const error = `Could not render slot for slot ${name.value}. A valid tag doesn't exist or is not HTML string.`;\n throw new Error(error);\n }\n\n if (renderMode !== 'none' && element.value) {\n renderFunctions[renderMode](\n {\n ...renderAd,\n ...pick(options, ['width', 'height']),\n } as RenderOptions,\n element.value,\n );\n }\n\n logger.debug(`Slot rendered ${name.value}`, {\n renderedElement: element,\n location: context.location,\n format,\n containingElement,\n });\n\n // eslint-disable-next-line require-atomic-updates\n status.value = 'rendered';\n\n runOnRender(renderAd);\n\n return element.value;\n }\n catch (error) {\n processOnError(error as string);\n return null;\n }\n }\n\n function processOnEmpty(): void {\n status.value = 'empty';\n logger.debug(`No ad to render for slot ${name.value}`);\n runOnEmpty();\n }\n\n function processOnError(error: string): void {\n if (status.value !== 'error') {\n status.value = 'error';\n logger.error(error);\n runOnError(new Error(error, {\n cause: error,\n }));\n }\n }\n\n function cleanElement(): void {\n if (!element.value || renderMode === 'none')\n return;\n\n element.value.innerHTML = '';\n element.value.style.position = '';\n }\n\n function dispose(): void {\n cleanElement();\n\n element.value = null;\n\n data.value = null;\n originalData.value = null;\n\n domObserver.disconnect();\n\n runOnDispose();\n\n isDisposed.value = true;\n\n scope.stop();\n }\n\n const state = reactive({\n location: context.location ?? '',\n lazyLoading: options.lazyLoading ?? false,\n type,\n slot,\n parameters,\n format,\n name,\n data,\n isViewabilityTracked,\n isImpressionTracked,\n status,\n element,\n isDisposed,\n id,\n pluginOptions,\n isVisible: isInViewport,\n render,\n request,\n dispose,\n processOnEmpty,\n processOnError,\n cleanElement,\n options: omit(options, ['context']),\n ...hooks,\n });\n\n watch(\n state,\n (newState) => {\n slotContext.value = newState;\n },\n {\n deep: true,\n immediate: true,\n },\n );\n\n context.hooks.onInit(async () => {\n await runOnInit();\n\n if (status.value === 'empty' || status.value === 'error') {\n return;\n }\n\n if (initialData) {\n status.value = 'loaded';\n\n data.value = initialData;\n data.value = await runOnRequest(initialData);\n\n return;\n }\n\n status.value = 'initialized';\n\n if (options.lazyLoading) {\n return;\n }\n\n data.value = (await slotContext.value?.request()) ?? null;\n });\n\n return state;\n })!;\n}\n"],"names":["extRequestAd"],"mappings":"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"}
|