@adhese/sdk-lite 1.0.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/README.md +18 -15
- package/dist/cjs/sdkLite.cjs +35 -35
- package/dist/cjs/sdkLite.cjs.map +1 -1
- package/dist/sdkLite.d.ts +4 -5
- package/dist/sdkLite.js +37 -37
- package/dist/sdkLite.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @adhese/sdk-lite
|
|
2
2
|
|
|
3
|
+
## 1.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d29a909: Remove logger to optmize output js file
|
|
8
|
+
|
|
9
|
+
## 1.1.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 431b736: When not passing an element to a lite slot the parent element of the script where it's called is selected
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 431b736: Improve documentation
|
|
18
|
+
|
|
3
19
|
## 1.0.0
|
|
4
20
|
|
|
5
21
|
### Major Changes
|
package/README.md
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
# @adhese/sdk-lite
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
## Installation
|
|
5
|
-
```bash
|
|
6
|
-
npm install @adhese/sdk-lite
|
|
7
|
-
```
|
|
2
|
+
The Adhese SDK Lite is a lightweight version of the Adhese SDK. It is a smaller package that can only render a single
|
|
3
|
+
slot. This package is most useful for use in places like Google Tag Manager.
|
|
8
4
|
|
|
9
5
|
## Usage
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
To create a slot, you need to call the `createSlot` function with an object containing the account, location, and format.
|
|
7
|
+
|
|
8
|
+
The slot will be created alongside the script tag in which the function is called.
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
10
|
+
```html
|
|
11
|
+
<body>
|
|
12
|
+
<div>
|
|
13
|
+
<script src="adheseLite.js"></script>
|
|
14
|
+
<script>
|
|
15
|
+
AdheseLite.createSlot({
|
|
16
|
+
account: 'your-account-id',
|
|
17
|
+
location: 'location-name',
|
|
18
|
+
format: 'format-name',
|
|
19
|
+
})
|
|
20
|
+
</script>
|
|
21
|
+
</div>
|
|
22
|
+
</body>
|
|
20
23
|
```
|
package/dist/cjs/sdkLite.cjs
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const sdkShared = require("@adhese/sdk-shared");
|
|
4
|
-
const
|
|
5
|
-
const version = "1.0.0";
|
|
4
|
+
const version = "1.1.1";
|
|
6
5
|
const renderFunctions = {
|
|
7
6
|
iframe: sdkShared.renderIframe,
|
|
8
7
|
inline: sdkShared.renderInline
|
|
9
8
|
};
|
|
10
9
|
function createSlot(options) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
minLogLevelThreshold: options.debug ? "debug" : "info"
|
|
14
|
-
});
|
|
15
|
-
const name$1 = sdkShared.generateName(options.location, options.format, options.slot);
|
|
10
|
+
var _a;
|
|
11
|
+
const name = sdkShared.generateName(options.location, options.format, options.slot);
|
|
16
12
|
const trackingPixels = /* @__PURE__ */ new Set();
|
|
17
13
|
const renderIntersectionObserver = new IntersectionObserver(onRenderIntersection, {
|
|
18
14
|
rootMargin: "200px",
|
|
@@ -32,19 +28,27 @@ function createSlot(options) {
|
|
|
32
28
|
...consentParameters
|
|
33
29
|
};
|
|
34
30
|
let isImpressionTracked = false;
|
|
31
|
+
const element = options.containingElement ?? document.createElement("div");
|
|
32
|
+
if (!options.containingElement) {
|
|
33
|
+
element.id = `${name}:${sdkShared.uniqueId(3)}`;
|
|
34
|
+
element.classList.add("adunit");
|
|
35
|
+
element.dataset.format = options.format;
|
|
36
|
+
element.dataset.slot = options.format;
|
|
37
|
+
element.dataset.location = options.location;
|
|
38
|
+
(_a = document.currentScript) == null ? void 0 : _a.insertAdjacentElement("beforebegin", element);
|
|
39
|
+
}
|
|
35
40
|
const context = {
|
|
36
41
|
options,
|
|
37
|
-
name
|
|
38
|
-
logger,
|
|
42
|
+
name,
|
|
39
43
|
parameters,
|
|
44
|
+
element,
|
|
40
45
|
async request() {
|
|
41
|
-
var
|
|
42
|
-
logger.debug(`Requesting ad for slot ${name$1}`, this);
|
|
46
|
+
var _a2;
|
|
43
47
|
const response = await fetch(`${options.host ?? `https://ads-${options.account}.adhese.com`}/json`, {
|
|
44
48
|
method: "POST",
|
|
45
49
|
body: JSON.stringify({
|
|
46
50
|
slots: [{
|
|
47
|
-
slotname: name
|
|
51
|
+
slotname: name
|
|
48
52
|
}],
|
|
49
53
|
parameters
|
|
50
54
|
}),
|
|
@@ -54,50 +58,45 @@ function createSlot(options) {
|
|
|
54
58
|
}
|
|
55
59
|
});
|
|
56
60
|
if (!response.ok)
|
|
57
|
-
throw new Error(`Failed to request ad for slot ${name
|
|
61
|
+
throw new Error(`Failed to request ad for slot ${name}. Status: ${response.status}`);
|
|
58
62
|
const [data] = await response.json();
|
|
59
63
|
this.data = data;
|
|
60
|
-
|
|
61
|
-
(_a = options.onRequest) == null ? void 0 : _a.call(options, this);
|
|
64
|
+
(_a2 = options.onRequest) == null ? void 0 : _a2.call(options, this);
|
|
62
65
|
return data;
|
|
63
66
|
},
|
|
64
67
|
async render() {
|
|
65
|
-
var
|
|
68
|
+
var _a2, _b;
|
|
66
69
|
const data = this.data ?? await this.request();
|
|
67
|
-
|
|
70
|
+
element.removeEventListener("click", onClick);
|
|
68
71
|
if (!data) {
|
|
69
|
-
(
|
|
70
|
-
|
|
71
|
-
return options.containingElement;
|
|
72
|
+
(_a2 = options.onEmpty) == null ? void 0 : _a2.call(options, this);
|
|
73
|
+
return element;
|
|
72
74
|
}
|
|
73
75
|
if (typeof data.tag !== "string")
|
|
74
76
|
throw new Error("Received invalid ad data, tag is not a string");
|
|
75
|
-
renderFunctions[options.renderMode ?? "iframe"](data,
|
|
77
|
+
renderFunctions[options.renderMode ?? "iframe"](data, element);
|
|
76
78
|
(_b = options.onRender) == null ? void 0 : _b.call(options, this);
|
|
77
|
-
logger.debug(`Rendered slot ${name$1}`, this);
|
|
78
79
|
if (data.impressionCounter && !isImpressionTracked) {
|
|
79
80
|
trackingPixels.add(sdkShared.addTrackingPixel(data.impressionCounter));
|
|
80
81
|
isImpressionTracked = true;
|
|
81
82
|
}
|
|
82
83
|
if (data.viewableImpressionCounter) {
|
|
83
|
-
viewabilityTrackingIntersectionObserver.observe(
|
|
84
|
+
viewabilityTrackingIntersectionObserver.observe(element);
|
|
84
85
|
}
|
|
85
|
-
|
|
86
|
-
return
|
|
86
|
+
element.addEventListener("click", onClick);
|
|
87
|
+
return element;
|
|
87
88
|
},
|
|
88
89
|
dispose() {
|
|
89
|
-
var
|
|
90
|
-
(
|
|
91
|
-
|
|
90
|
+
var _a2;
|
|
91
|
+
(_a2 = options.onDispose) == null ? void 0 : _a2.call(options, this);
|
|
92
|
+
element.innerHTML = "";
|
|
92
93
|
for (const pixel of trackingPixels) {
|
|
93
94
|
pixel.remove();
|
|
94
95
|
}
|
|
95
96
|
trackingPixels.clear();
|
|
96
97
|
renderIntersectionObserver == null ? void 0 : renderIntersectionObserver.disconnect();
|
|
97
98
|
viewabilityTrackingIntersectionObserver.disconnect();
|
|
98
|
-
|
|
99
|
-
logger.debug(`Disposing slot ${name$1}`, this);
|
|
100
|
-
logger.resetLogs();
|
|
99
|
+
element.removeEventListener("click", onClick);
|
|
101
100
|
}
|
|
102
101
|
};
|
|
103
102
|
let isClickTracked = false;
|
|
@@ -113,10 +112,10 @@ function createSlot(options) {
|
|
|
113
112
|
const threshold = 0.2;
|
|
114
113
|
if (ratio >= threshold && !timeoutId) {
|
|
115
114
|
timeoutId = setTimeout(() => {
|
|
116
|
-
var
|
|
115
|
+
var _a2, _b;
|
|
117
116
|
timeoutId = null;
|
|
118
117
|
viewabilityTrackingIntersectionObserver.disconnect();
|
|
119
|
-
if ((
|
|
118
|
+
if ((_a2 = context.data) == null ? void 0 : _a2.viewableImpressionCounter) {
|
|
120
119
|
trackingPixels.add(sdkShared.addTrackingPixel((_b = context.data) == null ? void 0 : _b.viewableImpressionCounter));
|
|
121
120
|
}
|
|
122
121
|
}, 1e3);
|
|
@@ -127,12 +126,13 @@ function createSlot(options) {
|
|
|
127
126
|
}
|
|
128
127
|
function onRenderIntersection([entry]) {
|
|
129
128
|
if (entry.isIntersecting) {
|
|
130
|
-
context.render().catch(
|
|
129
|
+
context.render().catch(console.error);
|
|
131
130
|
renderIntersectionObserver == null ? void 0 : renderIntersectionObserver.disconnect();
|
|
132
131
|
}
|
|
133
132
|
}
|
|
134
|
-
renderIntersectionObserver.observe(
|
|
133
|
+
renderIntersectionObserver.observe(element);
|
|
135
134
|
return context;
|
|
136
135
|
}
|
|
137
136
|
exports.createSlot = createSlot;
|
|
137
|
+
exports.version = version;
|
|
138
138
|
//# sourceMappingURL=sdkLite.cjs.map
|
package/dist/cjs/sdkLite.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdkLite.cjs","sources":["../../src/sdkLite.ts"],"sourcesContent":["import {\n type
|
|
1
|
+
{"version":3,"file":"sdkLite.cjs","sources":["../../src/sdkLite.ts"],"sourcesContent":["import {\n type RenderOptions,\n addTrackingPixel,\n generateName,\n renderIframe,\n renderInline,\n round,\n uniqueId,\n} from '@adhese/sdk-shared';\n\ntype RenderMode = 'iframe' | 'inline';\n\nexport type AdheseLiteSlotOptions = {\n containingElement?: HTMLElement;\n format: string;\n account: string;\n location: string;\n host?: string;\n renderMode?: RenderMode;\n parameters?: Record<string, string | ReadonlyArray<string>>;\n slot?: string;\n consent?: boolean | string;\n clickTrackerUrl?: string | URL;\n onDispose?(slot: AdheseLiteSlot): void;\n onRender?(slot: AdheseLiteSlot): void;\n onRequest?(slot: AdheseLiteSlot): void;\n onEmpty?(slot: AdheseLiteSlot): void;\n};\n\nexport type AdheseLiteSlot = {\n options: AdheseLiteSlotOptions;\n name: string;\n data?: AdheseLiteAd;\n parameters: Record<string, string | ReadonlyArray<string>>;\n element: HTMLElement;\n render(): Promise<HTMLElement>;\n request(): Promise<AdheseLiteAd | null>;\n dispose(): void;\n};\n\nexport type AdheseLiteAd = {\n tag: string;\n width?: string;\n height?: string;\n impressionCounter?: string;\n viewableImpressionCounter?: string;\n};\n\nconst renderFunctions: Record<RenderMode, (ad: RenderOptions, element: HTMLElement) => void> = {\n iframe: renderIframe,\n inline: renderInline,\n};\n\nexport function createSlot(options: AdheseLiteSlotOptions): AdheseLiteSlot {\n const name = generateName(options.location, options.format, options.slot);\n\n const trackingPixels = new Set<HTMLImageElement>();\n\n const renderIntersectionObserver = new IntersectionObserver(onRenderIntersection, {\n rootMargin: '200px',\n threshold: 0,\n });\n\n const viewabilityTrackingIntersectionObserver = new IntersectionObserver(onViewabilityIntersection, {\n rootMargin: '0px',\n threshold: Array.from({ length: 11 }, (_, i) => i * 0.1),\n });\n\n const consentParameters: {\n tl: 'all' | 'none';\n } | {\n xt: string;\n } = typeof options.consent === 'string'\n ? {\n xt: options.consent,\n }\n : {\n tl: options.consent ? 'all' : 'none',\n };\n\n const parameters = {\n ...options.parameters,\n ...consentParameters,\n };\n\n let isImpressionTracked = false;\n\n const element = options.containingElement ?? document.createElement('div');\n\n if (!options.containingElement) {\n element.id = `${name}:${uniqueId(3)}`;\n element.classList.add('adunit');\n element.dataset.format = options.format;\n element.dataset.slot = options.format;\n element.dataset.location = options.location;\n\n document.currentScript?.insertAdjacentElement('beforebegin', element);\n }\n\n const context: AdheseLiteSlot = {\n options,\n name,\n parameters,\n element,\n async request(): Promise<AdheseLiteAd | null> {\n const response = await fetch(`${options.host ?? `https://ads-${options.account}.adhese.com`}/json`, {\n method: 'POST',\n body: JSON.stringify({\n slots: [{\n slotname: name,\n }],\n parameters,\n }),\n headers: {\n // eslint-disable-next-line ts/naming-convention\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok)\n throw new Error(`Failed to request ad for slot ${name}. Status: ${response.status}`);\n\n const [data] = await response.json() as ReadonlyArray<AdheseLiteAd>;\n\n this.data = data;\n\n options.onRequest?.(this);\n\n return data;\n },\n async render(): Promise<HTMLElement> {\n const data = this.data ?? (await this.request());\n element.removeEventListener('click', onClick);\n\n if (!data) {\n options.onEmpty?.(this);\n\n return element;\n }\n\n if (typeof data.tag !== 'string')\n throw new Error('Received invalid ad data, tag is not a string');\n\n renderFunctions[options.renderMode ?? 'iframe'](data, element);\n\n options.onRender?.(this);\n\n if (data.impressionCounter && !isImpressionTracked) {\n trackingPixels.add(addTrackingPixel(data.impressionCounter));\n isImpressionTracked = true;\n }\n\n if (data.viewableImpressionCounter) {\n viewabilityTrackingIntersectionObserver.observe(element);\n }\n\n element.addEventListener('click', onClick);\n\n return element;\n },\n dispose(): void {\n options.onDispose?.(this);\n\n element.innerHTML = '';\n\n for (const pixel of trackingPixels) {\n pixel.remove();\n }\n trackingPixels.clear();\n\n renderIntersectionObserver?.disconnect();\n viewabilityTrackingIntersectionObserver.disconnect();\n\n element.removeEventListener('click', onClick);\n },\n };\n\n let isClickTracked = false;\n function onClick(): void {\n if (options.clickTrackerUrl && !isClickTracked) {\n trackingPixels.add(addTrackingPixel(options.clickTrackerUrl));\n isClickTracked = true;\n }\n }\n\n let timeoutId: number | null = null;\n function onViewabilityIntersection([entry]: ReadonlyArray<IntersectionObserverEntry>): void {\n const ratio = round(entry.intersectionRatio, 1);\n const threshold = 0.2;\n\n if (ratio >= threshold && !timeoutId) {\n // @ts-expect-error The is misfiring to the Node type\n timeoutId = setTimeout(() => {\n timeoutId = null;\n viewabilityTrackingIntersectionObserver.disconnect();\n\n if (context.data?.viewableImpressionCounter) {\n trackingPixels.add(addTrackingPixel(context.data?.viewableImpressionCounter));\n }\n }, 1000);\n }\n else if (ratio < threshold && timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n }\n\n function onRenderIntersection([entry]: ReadonlyArray<IntersectionObserverEntry>): void {\n if (entry.isIntersecting) {\n context.render().catch(console.error);\n renderIntersectionObserver?.disconnect();\n }\n }\n renderIntersectionObserver.observe(element);\n return context;\n}\n\nexport { version } from '../package.json';\n"],"names":["renderIframe","renderInline","generateName","uniqueId","_a","addTrackingPixel","round"],"mappings":"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"}
|
package/dist/sdkLite.d.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
var version = "1.1.1";
|
|
2
2
|
|
|
3
3
|
type RenderMode = 'iframe' | 'inline';
|
|
4
4
|
type AdheseLiteSlotOptions = {
|
|
5
|
-
containingElement
|
|
5
|
+
containingElement?: HTMLElement;
|
|
6
6
|
format: string;
|
|
7
7
|
account: string;
|
|
8
8
|
location: string;
|
|
9
9
|
host?: string;
|
|
10
|
-
debug?: boolean;
|
|
11
10
|
renderMode?: RenderMode;
|
|
12
11
|
parameters?: Record<string, string | ReadonlyArray<string>>;
|
|
13
12
|
slot?: string;
|
|
@@ -22,8 +21,8 @@ type AdheseLiteSlot = {
|
|
|
22
21
|
options: AdheseLiteSlotOptions;
|
|
23
22
|
name: string;
|
|
24
23
|
data?: AdheseLiteAd;
|
|
25
|
-
logger: Logger<DefaultLogLevels>;
|
|
26
24
|
parameters: Record<string, string | ReadonlyArray<string>>;
|
|
25
|
+
element: HTMLElement;
|
|
27
26
|
render(): Promise<HTMLElement>;
|
|
28
27
|
request(): Promise<AdheseLiteAd | null>;
|
|
29
28
|
dispose(): void;
|
|
@@ -37,4 +36,4 @@ type AdheseLiteAd = {
|
|
|
37
36
|
};
|
|
38
37
|
declare function createSlot(options: AdheseLiteSlotOptions): AdheseLiteSlot;
|
|
39
38
|
|
|
40
|
-
export { type AdheseLiteAd, type AdheseLiteSlot, type AdheseLiteSlotOptions, createSlot };
|
|
39
|
+
export { type AdheseLiteAd, type AdheseLiteSlot, type AdheseLiteSlotOptions, createSlot, version };
|
package/dist/sdkLite.js
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
const
|
|
3
|
-
const version = "1.0.0";
|
|
1
|
+
import { generateName, uniqueId, round, addTrackingPixel, renderIframe, renderInline } from "@adhese/sdk-shared";
|
|
2
|
+
const version = "1.1.1";
|
|
4
3
|
const renderFunctions = {
|
|
5
4
|
iframe: renderIframe,
|
|
6
5
|
inline: renderInline
|
|
7
6
|
};
|
|
8
7
|
function createSlot(options) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
minLogLevelThreshold: options.debug ? "debug" : "info"
|
|
12
|
-
});
|
|
13
|
-
const name$1 = generateName(options.location, options.format, options.slot);
|
|
8
|
+
var _a;
|
|
9
|
+
const name = generateName(options.location, options.format, options.slot);
|
|
14
10
|
const trackingPixels = /* @__PURE__ */ new Set();
|
|
15
11
|
const renderIntersectionObserver = new IntersectionObserver(onRenderIntersection, {
|
|
16
12
|
rootMargin: "200px",
|
|
@@ -30,19 +26,27 @@ function createSlot(options) {
|
|
|
30
26
|
...consentParameters
|
|
31
27
|
};
|
|
32
28
|
let isImpressionTracked = false;
|
|
29
|
+
const element = options.containingElement ?? document.createElement("div");
|
|
30
|
+
if (!options.containingElement) {
|
|
31
|
+
element.id = `${name}:${uniqueId(3)}`;
|
|
32
|
+
element.classList.add("adunit");
|
|
33
|
+
element.dataset.format = options.format;
|
|
34
|
+
element.dataset.slot = options.format;
|
|
35
|
+
element.dataset.location = options.location;
|
|
36
|
+
(_a = document.currentScript) == null ? void 0 : _a.insertAdjacentElement("beforebegin", element);
|
|
37
|
+
}
|
|
33
38
|
const context = {
|
|
34
39
|
options,
|
|
35
|
-
name
|
|
36
|
-
logger,
|
|
40
|
+
name,
|
|
37
41
|
parameters,
|
|
42
|
+
element,
|
|
38
43
|
async request() {
|
|
39
|
-
var
|
|
40
|
-
logger.debug(`Requesting ad for slot ${name$1}`, this);
|
|
44
|
+
var _a2;
|
|
41
45
|
const response = await fetch(`${options.host ?? `https://ads-${options.account}.adhese.com`}/json`, {
|
|
42
46
|
method: "POST",
|
|
43
47
|
body: JSON.stringify({
|
|
44
48
|
slots: [{
|
|
45
|
-
slotname: name
|
|
49
|
+
slotname: name
|
|
46
50
|
}],
|
|
47
51
|
parameters
|
|
48
52
|
}),
|
|
@@ -52,50 +56,45 @@ function createSlot(options) {
|
|
|
52
56
|
}
|
|
53
57
|
});
|
|
54
58
|
if (!response.ok)
|
|
55
|
-
throw new Error(`Failed to request ad for slot ${name
|
|
59
|
+
throw new Error(`Failed to request ad for slot ${name}. Status: ${response.status}`);
|
|
56
60
|
const [data] = await response.json();
|
|
57
61
|
this.data = data;
|
|
58
|
-
|
|
59
|
-
(_a = options.onRequest) == null ? void 0 : _a.call(options, this);
|
|
62
|
+
(_a2 = options.onRequest) == null ? void 0 : _a2.call(options, this);
|
|
60
63
|
return data;
|
|
61
64
|
},
|
|
62
65
|
async render() {
|
|
63
|
-
var
|
|
66
|
+
var _a2, _b;
|
|
64
67
|
const data = this.data ?? await this.request();
|
|
65
|
-
|
|
68
|
+
element.removeEventListener("click", onClick);
|
|
66
69
|
if (!data) {
|
|
67
|
-
(
|
|
68
|
-
|
|
69
|
-
return options.containingElement;
|
|
70
|
+
(_a2 = options.onEmpty) == null ? void 0 : _a2.call(options, this);
|
|
71
|
+
return element;
|
|
70
72
|
}
|
|
71
73
|
if (typeof data.tag !== "string")
|
|
72
74
|
throw new Error("Received invalid ad data, tag is not a string");
|
|
73
|
-
renderFunctions[options.renderMode ?? "iframe"](data,
|
|
75
|
+
renderFunctions[options.renderMode ?? "iframe"](data, element);
|
|
74
76
|
(_b = options.onRender) == null ? void 0 : _b.call(options, this);
|
|
75
|
-
logger.debug(`Rendered slot ${name$1}`, this);
|
|
76
77
|
if (data.impressionCounter && !isImpressionTracked) {
|
|
77
78
|
trackingPixels.add(addTrackingPixel(data.impressionCounter));
|
|
78
79
|
isImpressionTracked = true;
|
|
79
80
|
}
|
|
80
81
|
if (data.viewableImpressionCounter) {
|
|
81
|
-
viewabilityTrackingIntersectionObserver.observe(
|
|
82
|
+
viewabilityTrackingIntersectionObserver.observe(element);
|
|
82
83
|
}
|
|
83
|
-
|
|
84
|
-
return
|
|
84
|
+
element.addEventListener("click", onClick);
|
|
85
|
+
return element;
|
|
85
86
|
},
|
|
86
87
|
dispose() {
|
|
87
|
-
var
|
|
88
|
-
(
|
|
89
|
-
|
|
88
|
+
var _a2;
|
|
89
|
+
(_a2 = options.onDispose) == null ? void 0 : _a2.call(options, this);
|
|
90
|
+
element.innerHTML = "";
|
|
90
91
|
for (const pixel of trackingPixels) {
|
|
91
92
|
pixel.remove();
|
|
92
93
|
}
|
|
93
94
|
trackingPixels.clear();
|
|
94
95
|
renderIntersectionObserver == null ? void 0 : renderIntersectionObserver.disconnect();
|
|
95
96
|
viewabilityTrackingIntersectionObserver.disconnect();
|
|
96
|
-
|
|
97
|
-
logger.debug(`Disposing slot ${name$1}`, this);
|
|
98
|
-
logger.resetLogs();
|
|
97
|
+
element.removeEventListener("click", onClick);
|
|
99
98
|
}
|
|
100
99
|
};
|
|
101
100
|
let isClickTracked = false;
|
|
@@ -111,10 +110,10 @@ function createSlot(options) {
|
|
|
111
110
|
const threshold = 0.2;
|
|
112
111
|
if (ratio >= threshold && !timeoutId) {
|
|
113
112
|
timeoutId = setTimeout(() => {
|
|
114
|
-
var
|
|
113
|
+
var _a2, _b;
|
|
115
114
|
timeoutId = null;
|
|
116
115
|
viewabilityTrackingIntersectionObserver.disconnect();
|
|
117
|
-
if ((
|
|
116
|
+
if ((_a2 = context.data) == null ? void 0 : _a2.viewableImpressionCounter) {
|
|
118
117
|
trackingPixels.add(addTrackingPixel((_b = context.data) == null ? void 0 : _b.viewableImpressionCounter));
|
|
119
118
|
}
|
|
120
119
|
}, 1e3);
|
|
@@ -125,14 +124,15 @@ function createSlot(options) {
|
|
|
125
124
|
}
|
|
126
125
|
function onRenderIntersection([entry]) {
|
|
127
126
|
if (entry.isIntersecting) {
|
|
128
|
-
context.render().catch(
|
|
127
|
+
context.render().catch(console.error);
|
|
129
128
|
renderIntersectionObserver == null ? void 0 : renderIntersectionObserver.disconnect();
|
|
130
129
|
}
|
|
131
130
|
}
|
|
132
|
-
renderIntersectionObserver.observe(
|
|
131
|
+
renderIntersectionObserver.observe(element);
|
|
133
132
|
return context;
|
|
134
133
|
}
|
|
135
134
|
export {
|
|
136
|
-
createSlot
|
|
135
|
+
createSlot,
|
|
136
|
+
version
|
|
137
137
|
};
|
|
138
138
|
//# sourceMappingURL=sdkLite.js.map
|
package/dist/sdkLite.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdkLite.js","sources":["../src/sdkLite.ts"],"sourcesContent":["import {\n type
|
|
1
|
+
{"version":3,"file":"sdkLite.js","sources":["../src/sdkLite.ts"],"sourcesContent":["import {\n type RenderOptions,\n addTrackingPixel,\n generateName,\n renderIframe,\n renderInline,\n round,\n uniqueId,\n} from '@adhese/sdk-shared';\n\ntype RenderMode = 'iframe' | 'inline';\n\nexport type AdheseLiteSlotOptions = {\n containingElement?: HTMLElement;\n format: string;\n account: string;\n location: string;\n host?: string;\n renderMode?: RenderMode;\n parameters?: Record<string, string | ReadonlyArray<string>>;\n slot?: string;\n consent?: boolean | string;\n clickTrackerUrl?: string | URL;\n onDispose?(slot: AdheseLiteSlot): void;\n onRender?(slot: AdheseLiteSlot): void;\n onRequest?(slot: AdheseLiteSlot): void;\n onEmpty?(slot: AdheseLiteSlot): void;\n};\n\nexport type AdheseLiteSlot = {\n options: AdheseLiteSlotOptions;\n name: string;\n data?: AdheseLiteAd;\n parameters: Record<string, string | ReadonlyArray<string>>;\n element: HTMLElement;\n render(): Promise<HTMLElement>;\n request(): Promise<AdheseLiteAd | null>;\n dispose(): void;\n};\n\nexport type AdheseLiteAd = {\n tag: string;\n width?: string;\n height?: string;\n impressionCounter?: string;\n viewableImpressionCounter?: string;\n};\n\nconst renderFunctions: Record<RenderMode, (ad: RenderOptions, element: HTMLElement) => void> = {\n iframe: renderIframe,\n inline: renderInline,\n};\n\nexport function createSlot(options: AdheseLiteSlotOptions): AdheseLiteSlot {\n const name = generateName(options.location, options.format, options.slot);\n\n const trackingPixels = new Set<HTMLImageElement>();\n\n const renderIntersectionObserver = new IntersectionObserver(onRenderIntersection, {\n rootMargin: '200px',\n threshold: 0,\n });\n\n const viewabilityTrackingIntersectionObserver = new IntersectionObserver(onViewabilityIntersection, {\n rootMargin: '0px',\n threshold: Array.from({ length: 11 }, (_, i) => i * 0.1),\n });\n\n const consentParameters: {\n tl: 'all' | 'none';\n } | {\n xt: string;\n } = typeof options.consent === 'string'\n ? {\n xt: options.consent,\n }\n : {\n tl: options.consent ? 'all' : 'none',\n };\n\n const parameters = {\n ...options.parameters,\n ...consentParameters,\n };\n\n let isImpressionTracked = false;\n\n const element = options.containingElement ?? document.createElement('div');\n\n if (!options.containingElement) {\n element.id = `${name}:${uniqueId(3)}`;\n element.classList.add('adunit');\n element.dataset.format = options.format;\n element.dataset.slot = options.format;\n element.dataset.location = options.location;\n\n document.currentScript?.insertAdjacentElement('beforebegin', element);\n }\n\n const context: AdheseLiteSlot = {\n options,\n name,\n parameters,\n element,\n async request(): Promise<AdheseLiteAd | null> {\n const response = await fetch(`${options.host ?? `https://ads-${options.account}.adhese.com`}/json`, {\n method: 'POST',\n body: JSON.stringify({\n slots: [{\n slotname: name,\n }],\n parameters,\n }),\n headers: {\n // eslint-disable-next-line ts/naming-convention\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok)\n throw new Error(`Failed to request ad for slot ${name}. Status: ${response.status}`);\n\n const [data] = await response.json() as ReadonlyArray<AdheseLiteAd>;\n\n this.data = data;\n\n options.onRequest?.(this);\n\n return data;\n },\n async render(): Promise<HTMLElement> {\n const data = this.data ?? (await this.request());\n element.removeEventListener('click', onClick);\n\n if (!data) {\n options.onEmpty?.(this);\n\n return element;\n }\n\n if (typeof data.tag !== 'string')\n throw new Error('Received invalid ad data, tag is not a string');\n\n renderFunctions[options.renderMode ?? 'iframe'](data, element);\n\n options.onRender?.(this);\n\n if (data.impressionCounter && !isImpressionTracked) {\n trackingPixels.add(addTrackingPixel(data.impressionCounter));\n isImpressionTracked = true;\n }\n\n if (data.viewableImpressionCounter) {\n viewabilityTrackingIntersectionObserver.observe(element);\n }\n\n element.addEventListener('click', onClick);\n\n return element;\n },\n dispose(): void {\n options.onDispose?.(this);\n\n element.innerHTML = '';\n\n for (const pixel of trackingPixels) {\n pixel.remove();\n }\n trackingPixels.clear();\n\n renderIntersectionObserver?.disconnect();\n viewabilityTrackingIntersectionObserver.disconnect();\n\n element.removeEventListener('click', onClick);\n },\n };\n\n let isClickTracked = false;\n function onClick(): void {\n if (options.clickTrackerUrl && !isClickTracked) {\n trackingPixels.add(addTrackingPixel(options.clickTrackerUrl));\n isClickTracked = true;\n }\n }\n\n let timeoutId: number | null = null;\n function onViewabilityIntersection([entry]: ReadonlyArray<IntersectionObserverEntry>): void {\n const ratio = round(entry.intersectionRatio, 1);\n const threshold = 0.2;\n\n if (ratio >= threshold && !timeoutId) {\n // @ts-expect-error The is misfiring to the Node type\n timeoutId = setTimeout(() => {\n timeoutId = null;\n viewabilityTrackingIntersectionObserver.disconnect();\n\n if (context.data?.viewableImpressionCounter) {\n trackingPixels.add(addTrackingPixel(context.data?.viewableImpressionCounter));\n }\n }, 1000);\n }\n else if (ratio < threshold && timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n }\n\n function onRenderIntersection([entry]: ReadonlyArray<IntersectionObserverEntry>): void {\n if (entry.isIntersecting) {\n context.render().catch(console.error);\n renderIntersectionObserver?.disconnect();\n }\n }\n renderIntersectionObserver.observe(element);\n return context;\n}\n\nexport { version } from '../package.json';\n"],"names":["_a"],"mappings":";;AAgDA,MAAM,kBAAyF;AAAA,EAC7F,QAAQ;AAAA,EACR,QAAQ;AACV;AAEO,SAAS,WAAW,SAAgD;;AACzE,QAAM,OAAO,aAAa,QAAQ,UAAU,QAAQ,QAAQ,QAAQ,IAAI;AAElE,QAAA,qCAAqB;AAErB,QAAA,6BAA6B,IAAI,qBAAqB,sBAAsB;AAAA,IAChF,YAAY;AAAA,IACZ,WAAW;AAAA,EAAA,CACZ;AAEK,QAAA,0CAA0C,IAAI,qBAAqB,2BAA2B;AAAA,IAClG,YAAY;AAAA,IACZ,WAAW,MAAM,KAAK,EAAE,QAAQ,MAAM,CAAC,GAAG,MAAM,IAAI,GAAG;AAAA,EAAA,CACxD;AAED,QAAM,oBAIF,OAAO,QAAQ,YAAY,WAC3B;AAAA,IACE,IAAI,QAAQ;AAAA,EAAA,IAEd;AAAA,IACE,IAAI,QAAQ,UAAU,QAAQ;AAAA,EAAA;AAGpC,QAAM,aAAa;AAAA,IACjB,GAAG,QAAQ;AAAA,IACX,GAAG;AAAA,EAAA;AAGL,MAAI,sBAAsB;AAE1B,QAAM,UAAU,QAAQ,qBAAqB,SAAS,cAAc,KAAK;AAErE,MAAA,CAAC,QAAQ,mBAAmB;AAC9B,YAAQ,KAAK,GAAG,IAAI,IAAI,SAAS,CAAC,CAAC;AAC3B,YAAA,UAAU,IAAI,QAAQ;AACtB,YAAA,QAAQ,SAAS,QAAQ;AACzB,YAAA,QAAQ,OAAO,QAAQ;AACvB,YAAA,QAAQ,WAAW,QAAQ;AAE1B,mBAAA,kBAAA,mBAAe,sBAAsB,eAAe;AAAA,EAC/D;AAEA,QAAM,UAA0B;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,UAAwC;;AACtC,YAAA,WAAW,MAAM,MAAM,GAAG,QAAQ,QAAQ,eAAe,QAAQ,OAAO,aAAa,SAAS;AAAA,QAClG,QAAQ;AAAA,QACR,MAAM,KAAK,UAAU;AAAA,UACnB,OAAO,CAAC;AAAA,YACN,UAAU;AAAA,UAAA,CACX;AAAA,UACD;AAAA,QAAA,CACD;AAAA,QACD,SAAS;AAAA;AAAA,UAEP,gBAAgB;AAAA,QAClB;AAAA,MAAA,CACD;AAED,UAAI,CAAC,SAAS;AACZ,cAAM,IAAI,MAAM,iCAAiC,IAAI,aAAa,SAAS,MAAM,EAAE;AAErF,YAAM,CAAC,IAAI,IAAI,MAAM,SAAS,KAAK;AAEnC,WAAK,OAAO;AAEZ,OAAAA,MAAA,QAAQ,cAAR,gBAAAA,IAAA,cAAoB;AAEb,aAAA;AAAA,IACT;AAAA,IACA,MAAM,SAA+B;;AACnC,YAAM,OAAO,KAAK,QAAS,MAAM,KAAK,QAAQ;AACtC,cAAA,oBAAoB,SAAS,OAAO;AAE5C,UAAI,CAAC,MAAM;AACT,SAAAA,MAAA,QAAQ,YAAR,gBAAAA,IAAA,cAAkB;AAEX,eAAA;AAAA,MACT;AAEI,UAAA,OAAO,KAAK,QAAQ;AAChB,cAAA,IAAI,MAAM,+CAA+C;AAEjE,sBAAgB,QAAQ,cAAc,QAAQ,EAAE,MAAM,OAAO;AAE7D,oBAAQ,aAAR,iCAAmB;AAEf,UAAA,KAAK,qBAAqB,CAAC,qBAAqB;AAClD,uBAAe,IAAI,iBAAiB,KAAK,iBAAiB,CAAC;AACrC,8BAAA;AAAA,MACxB;AAEA,UAAI,KAAK,2BAA2B;AAClC,gDAAwC,QAAQ,OAAO;AAAA,MACzD;AAEQ,cAAA,iBAAiB,SAAS,OAAO;AAElC,aAAA;AAAA,IACT;AAAA,IACA,UAAgB;;AACd,OAAAA,MAAA,QAAQ,cAAR,gBAAAA,IAAA,cAAoB;AAEpB,cAAQ,YAAY;AAEpB,iBAAW,SAAS,gBAAgB;AAClC,cAAM,OAAO;AAAA,MACf;AACA,qBAAe,MAAM;AAErB,+EAA4B;AAC5B,8CAAwC,WAAW;AAE3C,cAAA,oBAAoB,SAAS,OAAO;AAAA,IAC9C;AAAA,EAAA;AAGF,MAAI,iBAAiB;AACrB,WAAS,UAAgB;AACnB,QAAA,QAAQ,mBAAmB,CAAC,gBAAgB;AAC9C,qBAAe,IAAI,iBAAiB,QAAQ,eAAe,CAAC;AAC3C,uBAAA;AAAA,IACnB;AAAA,EACF;AAEA,MAAI,YAA2B;AACtB,WAAA,0BAA0B,CAAC,KAAK,GAAmD;AAC1F,UAAM,QAAQ,MAAM,MAAM,mBAAmB,CAAC;AAC9C,UAAM,YAAY;AAEd,QAAA,SAAS,aAAa,CAAC,WAAW;AAEpC,kBAAY,WAAW,MAAM;;AACf,oBAAA;AACZ,gDAAwC,WAAW;AAE/C,aAAAA,MAAA,QAAQ,SAAR,gBAAAA,IAAc,2BAA2B;AAC3C,yBAAe,IAAI,kBAAiB,aAAQ,SAAR,mBAAc,yBAAyB,CAAC;AAAA,QAC9E;AAAA,SACC,GAAI;AAAA,IAAA,WAEA,QAAQ,aAAa,WAAW;AACvC,mBAAa,SAAS;AACV,kBAAA;AAAA,IACd;AAAA,EACF;AAES,WAAA,qBAAqB,CAAC,KAAK,GAAmD;AACrF,QAAI,MAAM,gBAAgB;AACxB,cAAQ,OAAO,EAAE,MAAM,QAAQ,KAAK;AACpC,+EAA4B;AAAA,IAC9B;AAAA,EACF;AACA,6BAA2B,QAAQ,OAAO;AACnC,SAAA;AACT;"}
|