@adzenai/core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +141 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +185 -0
- package/dist/index.d.ts +185 -0
- package/dist/index.js +107 -0
- package/dist/index.js.map +1 -0
- package/package.json +37 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
ensureTid: () => ensureTid,
|
|
24
|
+
observeViewability: () => observeViewability,
|
|
25
|
+
readTid: () => readTid,
|
|
26
|
+
registerErrorSink: () => registerErrorSink,
|
|
27
|
+
reportError: () => reportError,
|
|
28
|
+
safeRun: () => safeRun,
|
|
29
|
+
safeRunAsync: () => safeRunAsync,
|
|
30
|
+
uuidv4: () => uuidv4
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(index_exports);
|
|
33
|
+
|
|
34
|
+
// src/errors.ts
|
|
35
|
+
var sinks = /* @__PURE__ */ new Set();
|
|
36
|
+
function registerErrorSink(sink) {
|
|
37
|
+
sinks.add(sink);
|
|
38
|
+
return () => sinks.delete(sink);
|
|
39
|
+
}
|
|
40
|
+
function reportError(err, label) {
|
|
41
|
+
const adzenErr = {
|
|
42
|
+
label,
|
|
43
|
+
message: err instanceof Error ? err.message : String(err),
|
|
44
|
+
stack: err instanceof Error ? err.stack : void 0,
|
|
45
|
+
ts: Date.now()
|
|
46
|
+
};
|
|
47
|
+
for (const sink of sinks) {
|
|
48
|
+
try {
|
|
49
|
+
sink(adzenErr);
|
|
50
|
+
} catch {
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function safeRun(fn, label, fallback) {
|
|
55
|
+
try {
|
|
56
|
+
return fn();
|
|
57
|
+
} catch (err) {
|
|
58
|
+
reportError(err, label);
|
|
59
|
+
return fallback;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async function safeRunAsync(fn, label, fallback) {
|
|
63
|
+
try {
|
|
64
|
+
return await fn();
|
|
65
|
+
} catch (err) {
|
|
66
|
+
reportError(err, label);
|
|
67
|
+
return fallback;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/session.ts
|
|
72
|
+
var TID_KEY = "adzen_tid";
|
|
73
|
+
function uuidv4() {
|
|
74
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
75
|
+
return crypto.randomUUID();
|
|
76
|
+
}
|
|
77
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
78
|
+
const r = Math.random() * 16 | 0;
|
|
79
|
+
const v = c === "x" ? r : r & 3 | 8;
|
|
80
|
+
return v.toString(16);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function readTid() {
|
|
84
|
+
if (typeof localStorage === "undefined") return null;
|
|
85
|
+
try {
|
|
86
|
+
return localStorage.getItem(TID_KEY);
|
|
87
|
+
} catch {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function ensureTid() {
|
|
92
|
+
const existing = readTid();
|
|
93
|
+
if (existing) return existing;
|
|
94
|
+
const id = uuidv4();
|
|
95
|
+
try {
|
|
96
|
+
localStorage.setItem(TID_KEY, id);
|
|
97
|
+
} catch {
|
|
98
|
+
}
|
|
99
|
+
return id;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// src/viewability.ts
|
|
103
|
+
function observeViewability(options) {
|
|
104
|
+
const { element, thresholdMs, onViewed, intersectionThreshold = 1 } = options;
|
|
105
|
+
let timer = null;
|
|
106
|
+
let fired = false;
|
|
107
|
+
const observer = new IntersectionObserver(
|
|
108
|
+
(entries) => {
|
|
109
|
+
for (const entry of entries) {
|
|
110
|
+
if (entry.isIntersecting && !fired) {
|
|
111
|
+
timer = setTimeout(() => {
|
|
112
|
+
fired = true;
|
|
113
|
+
onViewed();
|
|
114
|
+
observer.disconnect();
|
|
115
|
+
}, thresholdMs);
|
|
116
|
+
} else if (!entry.isIntersecting && timer !== null) {
|
|
117
|
+
clearTimeout(timer);
|
|
118
|
+
timer = null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
{ threshold: intersectionThreshold }
|
|
123
|
+
);
|
|
124
|
+
observer.observe(element);
|
|
125
|
+
return () => {
|
|
126
|
+
if (timer !== null) clearTimeout(timer);
|
|
127
|
+
observer.disconnect();
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
131
|
+
0 && (module.exports = {
|
|
132
|
+
ensureTid,
|
|
133
|
+
observeViewability,
|
|
134
|
+
readTid,
|
|
135
|
+
registerErrorSink,
|
|
136
|
+
reportError,
|
|
137
|
+
safeRun,
|
|
138
|
+
safeRunAsync,
|
|
139
|
+
uuidv4
|
|
140
|
+
});
|
|
141
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/session.ts","../src/viewability.ts"],"sourcesContent":["export * from \"./types.js\";\nexport { registerErrorSink, reportError, safeRun, safeRunAsync } from \"./errors.js\";\nexport { uuidv4, readTid, ensureTid } from \"./session.js\";\nexport { observeViewability } from \"./viewability.js\";\nexport type { ViewabilityOptions } from \"./viewability.js\";\n","import type { AdzenError } from \"./types.js\";\n\ntype ErrorSink = (err: AdzenError) => void;\n\nconst sinks = new Set<ErrorSink>();\n\nexport function registerErrorSink(sink: ErrorSink): () => void {\n sinks.add(sink);\n return () => sinks.delete(sink);\n}\n\nexport function reportError(err: unknown, label: string): void {\n const adzenErr: AdzenError = {\n label,\n message: err instanceof Error ? err.message : String(err),\n stack: err instanceof Error ? err.stack : undefined,\n ts: Date.now(),\n };\n for (const sink of sinks) {\n try {\n sink(adzenErr);\n } catch {\n // never let a sink crash the caller\n }\n }\n}\n\nexport function safeRun<T>(fn: () => T, label: string): T | undefined;\nexport function safeRun<T>(fn: () => T, label: string, fallback: T): T;\nexport function safeRun<T>(fn: () => T, label: string, fallback?: T): T | undefined {\n try {\n return fn();\n } catch (err) {\n reportError(err, label);\n return fallback;\n }\n}\n\nexport async function safeRunAsync<T>(fn: () => Promise<T>, label: string): Promise<T | undefined>;\nexport async function safeRunAsync<T>(fn: () => Promise<T>, label: string, fallback: T): Promise<T>;\nexport async function safeRunAsync<T>(\n fn: () => Promise<T>,\n label: string,\n fallback?: T,\n): Promise<T | undefined> {\n try {\n return await fn();\n } catch (err) {\n reportError(err, label);\n return fallback;\n }\n}\n","const TID_KEY = \"adzen_tid\";\n\nexport function uuidv4(): string {\n if (typeof crypto !== \"undefined\" && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\nexport function readTid(): string | null {\n if (typeof localStorage === \"undefined\") return null;\n try {\n return localStorage.getItem(TID_KEY);\n } catch {\n return null;\n }\n}\n\nexport function ensureTid(): string {\n const existing = readTid();\n if (existing) return existing;\n const id = uuidv4();\n try {\n localStorage.setItem(TID_KEY, id);\n } catch {\n // storage unavailable — return ephemeral id\n }\n return id;\n}\n","export interface ViewabilityOptions {\n element: Element;\n thresholdMs: number;\n onViewed: () => void;\n intersectionThreshold?: number;\n}\n\nexport function observeViewability(options: ViewabilityOptions): () => void {\n const { element, thresholdMs, onViewed, intersectionThreshold = 1.0 } = options;\n let timer: ReturnType<typeof setTimeout> | null = null;\n let fired = false;\n\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting && !fired) {\n timer = setTimeout(() => {\n fired = true;\n onViewed();\n observer.disconnect();\n }, thresholdMs);\n } else if (!entry.isIntersecting && timer !== null) {\n clearTimeout(timer);\n timer = null;\n }\n }\n },\n { threshold: intersectionThreshold },\n );\n\n observer.observe(element);\n\n return () => {\n if (timer !== null) clearTimeout(timer);\n observer.disconnect();\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACIA,IAAM,QAAQ,oBAAI,IAAe;AAE1B,SAAS,kBAAkB,MAA6B;AAC7D,QAAM,IAAI,IAAI;AACd,SAAO,MAAM,MAAM,OAAO,IAAI;AAChC;AAEO,SAAS,YAAY,KAAc,OAAqB;AAC7D,QAAM,WAAuB;AAAA,IAC3B;AAAA,IACA,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,IACxD,OAAO,eAAe,QAAQ,IAAI,QAAQ;AAAA,IAC1C,IAAI,KAAK,IAAI;AAAA,EACf;AACA,aAAW,QAAQ,OAAO;AACxB,QAAI;AACF,WAAK,QAAQ;AAAA,IACf,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAIO,SAAS,QAAW,IAAa,OAAe,UAA6B;AAClF,MAAI;AACF,WAAO,GAAG;AAAA,EACZ,SAAS,KAAK;AACZ,gBAAY,KAAK,KAAK;AACtB,WAAO;AAAA,EACT;AACF;AAIA,eAAsB,aACpB,IACA,OACA,UACwB;AACxB,MAAI;AACF,WAAO,MAAM,GAAG;AAAA,EAClB,SAAS,KAAK;AACZ,gBAAY,KAAK,KAAK;AACtB,WAAO;AAAA,EACT;AACF;;;ACnDA,IAAM,UAAU;AAET,SAAS,SAAiB;AAC/B,MAAI,OAAO,WAAW,eAAe,OAAO,YAAY;AACtD,WAAO,OAAO,WAAW;AAAA,EAC3B;AACA,SAAO,uCAAuC,QAAQ,SAAS,CAAC,MAAM;AACpE,UAAM,IAAK,KAAK,OAAO,IAAI,KAAM;AACjC,UAAM,IAAI,MAAM,MAAM,IAAK,IAAI,IAAO;AACtC,WAAO,EAAE,SAAS,EAAE;AAAA,EACtB,CAAC;AACH;AAEO,SAAS,UAAyB;AACvC,MAAI,OAAO,iBAAiB,YAAa,QAAO;AAChD,MAAI;AACF,WAAO,aAAa,QAAQ,OAAO;AAAA,EACrC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,YAAoB;AAClC,QAAM,WAAW,QAAQ;AACzB,MAAI,SAAU,QAAO;AACrB,QAAM,KAAK,OAAO;AAClB,MAAI;AACF,iBAAa,QAAQ,SAAS,EAAE;AAAA,EAClC,QAAQ;AAAA,EAER;AACA,SAAO;AACT;;;ACzBO,SAAS,mBAAmB,SAAyC;AAC1E,QAAM,EAAE,SAAS,aAAa,UAAU,wBAAwB,EAAI,IAAI;AACxE,MAAI,QAA8C;AAClD,MAAI,QAAQ;AAEZ,QAAM,WAAW,IAAI;AAAA,IACnB,CAAC,YAAY;AACX,iBAAW,SAAS,SAAS;AAC3B,YAAI,MAAM,kBAAkB,CAAC,OAAO;AAClC,kBAAQ,WAAW,MAAM;AACvB,oBAAQ;AACR,qBAAS;AACT,qBAAS,WAAW;AAAA,UACtB,GAAG,WAAW;AAAA,QAChB,WAAW,CAAC,MAAM,kBAAkB,UAAU,MAAM;AAClD,uBAAa,KAAK;AAClB,kBAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,IACA,EAAE,WAAW,sBAAsB;AAAA,EACrC;AAEA,WAAS,QAAQ,OAAO;AAExB,SAAO,MAAM;AACX,QAAI,UAAU,KAAM,cAAa,KAAK;AACtC,aAAS,WAAW;AAAA,EACtB;AACF;","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
interface AdzenPlacement {
|
|
2
|
+
ad_id: string;
|
|
3
|
+
campaign_id: string;
|
|
4
|
+
advertiser_name: string;
|
|
5
|
+
advertiser_image_url?: string;
|
|
6
|
+
headline: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
cta_text: string;
|
|
9
|
+
destination_url: string;
|
|
10
|
+
creative_url?: string;
|
|
11
|
+
adUnitPosition: string;
|
|
12
|
+
tracking: TrackingInfo;
|
|
13
|
+
}
|
|
14
|
+
interface TrackingInfo {
|
|
15
|
+
render_url: string;
|
|
16
|
+
view_url: string;
|
|
17
|
+
click_slug: string;
|
|
18
|
+
}
|
|
19
|
+
interface AdzenDecision {
|
|
20
|
+
decision: "serve" | "no_match";
|
|
21
|
+
ad?: AdzenPlacement;
|
|
22
|
+
reason?: string;
|
|
23
|
+
}
|
|
24
|
+
type AdzenEnv = "prod" | "stg" | "dev";
|
|
25
|
+
type AdzenFormat = "banner" | "native" | "sticky" | "in-feed";
|
|
26
|
+
type SlotPosition = "atf" | "btf";
|
|
27
|
+
interface AdzenConsent {
|
|
28
|
+
gdpr?: boolean;
|
|
29
|
+
tcString?: string;
|
|
30
|
+
usp?: string;
|
|
31
|
+
}
|
|
32
|
+
interface AbContext {
|
|
33
|
+
testId?: string;
|
|
34
|
+
variantId?: string;
|
|
35
|
+
chunkId?: string;
|
|
36
|
+
adId?: string;
|
|
37
|
+
}
|
|
38
|
+
interface AdzenDefaults {
|
|
39
|
+
lazyRootMargin: string;
|
|
40
|
+
impressionMinMs: number;
|
|
41
|
+
viewabilityThreshold: number;
|
|
42
|
+
}
|
|
43
|
+
interface AdzenStaticConfig {
|
|
44
|
+
publisherId: string;
|
|
45
|
+
endpoint?: string;
|
|
46
|
+
env?: AdzenEnv;
|
|
47
|
+
debug?: boolean;
|
|
48
|
+
mockMode?: boolean;
|
|
49
|
+
defaults?: Partial<AdzenDefaults>;
|
|
50
|
+
consent?: AdzenConsent;
|
|
51
|
+
abContext?: AbContext;
|
|
52
|
+
onError?: (err: AdzenError) => void;
|
|
53
|
+
}
|
|
54
|
+
interface ResolvedAdzenStaticConfig extends AdzenStaticConfig {
|
|
55
|
+
endpoint: string;
|
|
56
|
+
env: AdzenEnv;
|
|
57
|
+
debug: boolean;
|
|
58
|
+
mockMode: boolean;
|
|
59
|
+
defaults: AdzenDefaults;
|
|
60
|
+
}
|
|
61
|
+
interface SlotSpec {
|
|
62
|
+
id: string;
|
|
63
|
+
format: AdzenFormat;
|
|
64
|
+
sizes?: string[];
|
|
65
|
+
position?: SlotPosition;
|
|
66
|
+
}
|
|
67
|
+
interface PageContext {
|
|
68
|
+
url: string;
|
|
69
|
+
referrer: string | null;
|
|
70
|
+
title: string;
|
|
71
|
+
}
|
|
72
|
+
interface ViewportContext {
|
|
73
|
+
w: number;
|
|
74
|
+
h: number;
|
|
75
|
+
dpr: number;
|
|
76
|
+
}
|
|
77
|
+
interface UserContext {
|
|
78
|
+
tid: string | null;
|
|
79
|
+
consent: AdzenConsent;
|
|
80
|
+
}
|
|
81
|
+
interface DecisionRequest {
|
|
82
|
+
publisherId: string;
|
|
83
|
+
requestId: string;
|
|
84
|
+
slots: SlotSpec[];
|
|
85
|
+
page: PageContext;
|
|
86
|
+
viewport: ViewportContext;
|
|
87
|
+
user: UserContext;
|
|
88
|
+
abContext?: AbContext;
|
|
89
|
+
sdk: {
|
|
90
|
+
version: string;
|
|
91
|
+
ts: number;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
interface BannerCreative {
|
|
95
|
+
format: "banner";
|
|
96
|
+
type: "image" | "html";
|
|
97
|
+
assets: {
|
|
98
|
+
imageUrl?: string;
|
|
99
|
+
html?: string;
|
|
100
|
+
};
|
|
101
|
+
dimensions: {
|
|
102
|
+
w: number;
|
|
103
|
+
h: number;
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
interface NativeCreative {
|
|
107
|
+
format: "native";
|
|
108
|
+
assets: {
|
|
109
|
+
headline: string;
|
|
110
|
+
body?: string;
|
|
111
|
+
cta: string;
|
|
112
|
+
imageUrl?: string;
|
|
113
|
+
advertiser: string;
|
|
114
|
+
sponsorLabel?: string;
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
interface StickyCreative {
|
|
118
|
+
format: "sticky";
|
|
119
|
+
type: "image" | "html";
|
|
120
|
+
assets: {
|
|
121
|
+
imageUrl?: string;
|
|
122
|
+
html?: string;
|
|
123
|
+
};
|
|
124
|
+
dimensions: {
|
|
125
|
+
w: number;
|
|
126
|
+
h: number;
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
type Creative = BannerCreative | NativeCreative | StickyCreative;
|
|
130
|
+
interface Beacons {
|
|
131
|
+
impression: string[];
|
|
132
|
+
view: string[];
|
|
133
|
+
click: string[];
|
|
134
|
+
}
|
|
135
|
+
interface Decision {
|
|
136
|
+
slotId: string;
|
|
137
|
+
creative: Creative;
|
|
138
|
+
clickUrl: string;
|
|
139
|
+
beacons: Beacons;
|
|
140
|
+
abContext?: AbContext;
|
|
141
|
+
debug?: Record<string, unknown>;
|
|
142
|
+
}
|
|
143
|
+
interface DecisionResponse {
|
|
144
|
+
requestId: string;
|
|
145
|
+
decisions: Decision[];
|
|
146
|
+
}
|
|
147
|
+
interface AdzenError {
|
|
148
|
+
label: string;
|
|
149
|
+
message: string;
|
|
150
|
+
stack?: string;
|
|
151
|
+
ts: number;
|
|
152
|
+
}
|
|
153
|
+
type AdzenQueueItem = IArguments | unknown[];
|
|
154
|
+
interface AdzenApi {
|
|
155
|
+
(command: unknown, ...args: unknown[]): void;
|
|
156
|
+
q?: AdzenQueueItem[];
|
|
157
|
+
init?: (config: AdzenStaticConfig) => void;
|
|
158
|
+
}
|
|
159
|
+
interface AdzenBaseConfig {
|
|
160
|
+
endpointUrl?: string;
|
|
161
|
+
apiKey: string;
|
|
162
|
+
timeoutMs?: number;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
type ErrorSink = (err: AdzenError) => void;
|
|
166
|
+
declare function registerErrorSink(sink: ErrorSink): () => void;
|
|
167
|
+
declare function reportError(err: unknown, label: string): void;
|
|
168
|
+
declare function safeRun<T>(fn: () => T, label: string): T | undefined;
|
|
169
|
+
declare function safeRun<T>(fn: () => T, label: string, fallback: T): T;
|
|
170
|
+
declare function safeRunAsync<T>(fn: () => Promise<T>, label: string): Promise<T | undefined>;
|
|
171
|
+
declare function safeRunAsync<T>(fn: () => Promise<T>, label: string, fallback: T): Promise<T>;
|
|
172
|
+
|
|
173
|
+
declare function uuidv4(): string;
|
|
174
|
+
declare function readTid(): string | null;
|
|
175
|
+
declare function ensureTid(): string;
|
|
176
|
+
|
|
177
|
+
interface ViewabilityOptions {
|
|
178
|
+
element: Element;
|
|
179
|
+
thresholdMs: number;
|
|
180
|
+
onViewed: () => void;
|
|
181
|
+
intersectionThreshold?: number;
|
|
182
|
+
}
|
|
183
|
+
declare function observeViewability(options: ViewabilityOptions): () => void;
|
|
184
|
+
|
|
185
|
+
export { type AbContext, type AdzenApi, type AdzenBaseConfig, type AdzenConsent, type AdzenDecision, type AdzenDefaults, type AdzenEnv, type AdzenError, type AdzenFormat, type AdzenPlacement, type AdzenQueueItem, type AdzenStaticConfig, type BannerCreative, type Beacons, type Creative, type Decision, type DecisionRequest, type DecisionResponse, type NativeCreative, type PageContext, type ResolvedAdzenStaticConfig, type SlotPosition, type SlotSpec, type StickyCreative, type TrackingInfo, type UserContext, type ViewabilityOptions, type ViewportContext, ensureTid, observeViewability, readTid, registerErrorSink, reportError, safeRun, safeRunAsync, uuidv4 };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
interface AdzenPlacement {
|
|
2
|
+
ad_id: string;
|
|
3
|
+
campaign_id: string;
|
|
4
|
+
advertiser_name: string;
|
|
5
|
+
advertiser_image_url?: string;
|
|
6
|
+
headline: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
cta_text: string;
|
|
9
|
+
destination_url: string;
|
|
10
|
+
creative_url?: string;
|
|
11
|
+
adUnitPosition: string;
|
|
12
|
+
tracking: TrackingInfo;
|
|
13
|
+
}
|
|
14
|
+
interface TrackingInfo {
|
|
15
|
+
render_url: string;
|
|
16
|
+
view_url: string;
|
|
17
|
+
click_slug: string;
|
|
18
|
+
}
|
|
19
|
+
interface AdzenDecision {
|
|
20
|
+
decision: "serve" | "no_match";
|
|
21
|
+
ad?: AdzenPlacement;
|
|
22
|
+
reason?: string;
|
|
23
|
+
}
|
|
24
|
+
type AdzenEnv = "prod" | "stg" | "dev";
|
|
25
|
+
type AdzenFormat = "banner" | "native" | "sticky" | "in-feed";
|
|
26
|
+
type SlotPosition = "atf" | "btf";
|
|
27
|
+
interface AdzenConsent {
|
|
28
|
+
gdpr?: boolean;
|
|
29
|
+
tcString?: string;
|
|
30
|
+
usp?: string;
|
|
31
|
+
}
|
|
32
|
+
interface AbContext {
|
|
33
|
+
testId?: string;
|
|
34
|
+
variantId?: string;
|
|
35
|
+
chunkId?: string;
|
|
36
|
+
adId?: string;
|
|
37
|
+
}
|
|
38
|
+
interface AdzenDefaults {
|
|
39
|
+
lazyRootMargin: string;
|
|
40
|
+
impressionMinMs: number;
|
|
41
|
+
viewabilityThreshold: number;
|
|
42
|
+
}
|
|
43
|
+
interface AdzenStaticConfig {
|
|
44
|
+
publisherId: string;
|
|
45
|
+
endpoint?: string;
|
|
46
|
+
env?: AdzenEnv;
|
|
47
|
+
debug?: boolean;
|
|
48
|
+
mockMode?: boolean;
|
|
49
|
+
defaults?: Partial<AdzenDefaults>;
|
|
50
|
+
consent?: AdzenConsent;
|
|
51
|
+
abContext?: AbContext;
|
|
52
|
+
onError?: (err: AdzenError) => void;
|
|
53
|
+
}
|
|
54
|
+
interface ResolvedAdzenStaticConfig extends AdzenStaticConfig {
|
|
55
|
+
endpoint: string;
|
|
56
|
+
env: AdzenEnv;
|
|
57
|
+
debug: boolean;
|
|
58
|
+
mockMode: boolean;
|
|
59
|
+
defaults: AdzenDefaults;
|
|
60
|
+
}
|
|
61
|
+
interface SlotSpec {
|
|
62
|
+
id: string;
|
|
63
|
+
format: AdzenFormat;
|
|
64
|
+
sizes?: string[];
|
|
65
|
+
position?: SlotPosition;
|
|
66
|
+
}
|
|
67
|
+
interface PageContext {
|
|
68
|
+
url: string;
|
|
69
|
+
referrer: string | null;
|
|
70
|
+
title: string;
|
|
71
|
+
}
|
|
72
|
+
interface ViewportContext {
|
|
73
|
+
w: number;
|
|
74
|
+
h: number;
|
|
75
|
+
dpr: number;
|
|
76
|
+
}
|
|
77
|
+
interface UserContext {
|
|
78
|
+
tid: string | null;
|
|
79
|
+
consent: AdzenConsent;
|
|
80
|
+
}
|
|
81
|
+
interface DecisionRequest {
|
|
82
|
+
publisherId: string;
|
|
83
|
+
requestId: string;
|
|
84
|
+
slots: SlotSpec[];
|
|
85
|
+
page: PageContext;
|
|
86
|
+
viewport: ViewportContext;
|
|
87
|
+
user: UserContext;
|
|
88
|
+
abContext?: AbContext;
|
|
89
|
+
sdk: {
|
|
90
|
+
version: string;
|
|
91
|
+
ts: number;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
interface BannerCreative {
|
|
95
|
+
format: "banner";
|
|
96
|
+
type: "image" | "html";
|
|
97
|
+
assets: {
|
|
98
|
+
imageUrl?: string;
|
|
99
|
+
html?: string;
|
|
100
|
+
};
|
|
101
|
+
dimensions: {
|
|
102
|
+
w: number;
|
|
103
|
+
h: number;
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
interface NativeCreative {
|
|
107
|
+
format: "native";
|
|
108
|
+
assets: {
|
|
109
|
+
headline: string;
|
|
110
|
+
body?: string;
|
|
111
|
+
cta: string;
|
|
112
|
+
imageUrl?: string;
|
|
113
|
+
advertiser: string;
|
|
114
|
+
sponsorLabel?: string;
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
interface StickyCreative {
|
|
118
|
+
format: "sticky";
|
|
119
|
+
type: "image" | "html";
|
|
120
|
+
assets: {
|
|
121
|
+
imageUrl?: string;
|
|
122
|
+
html?: string;
|
|
123
|
+
};
|
|
124
|
+
dimensions: {
|
|
125
|
+
w: number;
|
|
126
|
+
h: number;
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
type Creative = BannerCreative | NativeCreative | StickyCreative;
|
|
130
|
+
interface Beacons {
|
|
131
|
+
impression: string[];
|
|
132
|
+
view: string[];
|
|
133
|
+
click: string[];
|
|
134
|
+
}
|
|
135
|
+
interface Decision {
|
|
136
|
+
slotId: string;
|
|
137
|
+
creative: Creative;
|
|
138
|
+
clickUrl: string;
|
|
139
|
+
beacons: Beacons;
|
|
140
|
+
abContext?: AbContext;
|
|
141
|
+
debug?: Record<string, unknown>;
|
|
142
|
+
}
|
|
143
|
+
interface DecisionResponse {
|
|
144
|
+
requestId: string;
|
|
145
|
+
decisions: Decision[];
|
|
146
|
+
}
|
|
147
|
+
interface AdzenError {
|
|
148
|
+
label: string;
|
|
149
|
+
message: string;
|
|
150
|
+
stack?: string;
|
|
151
|
+
ts: number;
|
|
152
|
+
}
|
|
153
|
+
type AdzenQueueItem = IArguments | unknown[];
|
|
154
|
+
interface AdzenApi {
|
|
155
|
+
(command: unknown, ...args: unknown[]): void;
|
|
156
|
+
q?: AdzenQueueItem[];
|
|
157
|
+
init?: (config: AdzenStaticConfig) => void;
|
|
158
|
+
}
|
|
159
|
+
interface AdzenBaseConfig {
|
|
160
|
+
endpointUrl?: string;
|
|
161
|
+
apiKey: string;
|
|
162
|
+
timeoutMs?: number;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
type ErrorSink = (err: AdzenError) => void;
|
|
166
|
+
declare function registerErrorSink(sink: ErrorSink): () => void;
|
|
167
|
+
declare function reportError(err: unknown, label: string): void;
|
|
168
|
+
declare function safeRun<T>(fn: () => T, label: string): T | undefined;
|
|
169
|
+
declare function safeRun<T>(fn: () => T, label: string, fallback: T): T;
|
|
170
|
+
declare function safeRunAsync<T>(fn: () => Promise<T>, label: string): Promise<T | undefined>;
|
|
171
|
+
declare function safeRunAsync<T>(fn: () => Promise<T>, label: string, fallback: T): Promise<T>;
|
|
172
|
+
|
|
173
|
+
declare function uuidv4(): string;
|
|
174
|
+
declare function readTid(): string | null;
|
|
175
|
+
declare function ensureTid(): string;
|
|
176
|
+
|
|
177
|
+
interface ViewabilityOptions {
|
|
178
|
+
element: Element;
|
|
179
|
+
thresholdMs: number;
|
|
180
|
+
onViewed: () => void;
|
|
181
|
+
intersectionThreshold?: number;
|
|
182
|
+
}
|
|
183
|
+
declare function observeViewability(options: ViewabilityOptions): () => void;
|
|
184
|
+
|
|
185
|
+
export { type AbContext, type AdzenApi, type AdzenBaseConfig, type AdzenConsent, type AdzenDecision, type AdzenDefaults, type AdzenEnv, type AdzenError, type AdzenFormat, type AdzenPlacement, type AdzenQueueItem, type AdzenStaticConfig, type BannerCreative, type Beacons, type Creative, type Decision, type DecisionRequest, type DecisionResponse, type NativeCreative, type PageContext, type ResolvedAdzenStaticConfig, type SlotPosition, type SlotSpec, type StickyCreative, type TrackingInfo, type UserContext, type ViewabilityOptions, type ViewportContext, ensureTid, observeViewability, readTid, registerErrorSink, reportError, safeRun, safeRunAsync, uuidv4 };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var sinks = /* @__PURE__ */ new Set();
|
|
3
|
+
function registerErrorSink(sink) {
|
|
4
|
+
sinks.add(sink);
|
|
5
|
+
return () => sinks.delete(sink);
|
|
6
|
+
}
|
|
7
|
+
function reportError(err, label) {
|
|
8
|
+
const adzenErr = {
|
|
9
|
+
label,
|
|
10
|
+
message: err instanceof Error ? err.message : String(err),
|
|
11
|
+
stack: err instanceof Error ? err.stack : void 0,
|
|
12
|
+
ts: Date.now()
|
|
13
|
+
};
|
|
14
|
+
for (const sink of sinks) {
|
|
15
|
+
try {
|
|
16
|
+
sink(adzenErr);
|
|
17
|
+
} catch {
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function safeRun(fn, label, fallback) {
|
|
22
|
+
try {
|
|
23
|
+
return fn();
|
|
24
|
+
} catch (err) {
|
|
25
|
+
reportError(err, label);
|
|
26
|
+
return fallback;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function safeRunAsync(fn, label, fallback) {
|
|
30
|
+
try {
|
|
31
|
+
return await fn();
|
|
32
|
+
} catch (err) {
|
|
33
|
+
reportError(err, label);
|
|
34
|
+
return fallback;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// src/session.ts
|
|
39
|
+
var TID_KEY = "adzen_tid";
|
|
40
|
+
function uuidv4() {
|
|
41
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
42
|
+
return crypto.randomUUID();
|
|
43
|
+
}
|
|
44
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
45
|
+
const r = Math.random() * 16 | 0;
|
|
46
|
+
const v = c === "x" ? r : r & 3 | 8;
|
|
47
|
+
return v.toString(16);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
function readTid() {
|
|
51
|
+
if (typeof localStorage === "undefined") return null;
|
|
52
|
+
try {
|
|
53
|
+
return localStorage.getItem(TID_KEY);
|
|
54
|
+
} catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function ensureTid() {
|
|
59
|
+
const existing = readTid();
|
|
60
|
+
if (existing) return existing;
|
|
61
|
+
const id = uuidv4();
|
|
62
|
+
try {
|
|
63
|
+
localStorage.setItem(TID_KEY, id);
|
|
64
|
+
} catch {
|
|
65
|
+
}
|
|
66
|
+
return id;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/viewability.ts
|
|
70
|
+
function observeViewability(options) {
|
|
71
|
+
const { element, thresholdMs, onViewed, intersectionThreshold = 1 } = options;
|
|
72
|
+
let timer = null;
|
|
73
|
+
let fired = false;
|
|
74
|
+
const observer = new IntersectionObserver(
|
|
75
|
+
(entries) => {
|
|
76
|
+
for (const entry of entries) {
|
|
77
|
+
if (entry.isIntersecting && !fired) {
|
|
78
|
+
timer = setTimeout(() => {
|
|
79
|
+
fired = true;
|
|
80
|
+
onViewed();
|
|
81
|
+
observer.disconnect();
|
|
82
|
+
}, thresholdMs);
|
|
83
|
+
} else if (!entry.isIntersecting && timer !== null) {
|
|
84
|
+
clearTimeout(timer);
|
|
85
|
+
timer = null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
{ threshold: intersectionThreshold }
|
|
90
|
+
);
|
|
91
|
+
observer.observe(element);
|
|
92
|
+
return () => {
|
|
93
|
+
if (timer !== null) clearTimeout(timer);
|
|
94
|
+
observer.disconnect();
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
export {
|
|
98
|
+
ensureTid,
|
|
99
|
+
observeViewability,
|
|
100
|
+
readTid,
|
|
101
|
+
registerErrorSink,
|
|
102
|
+
reportError,
|
|
103
|
+
safeRun,
|
|
104
|
+
safeRunAsync,
|
|
105
|
+
uuidv4
|
|
106
|
+
};
|
|
107
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/session.ts","../src/viewability.ts"],"sourcesContent":["import type { AdzenError } from \"./types.js\";\n\ntype ErrorSink = (err: AdzenError) => void;\n\nconst sinks = new Set<ErrorSink>();\n\nexport function registerErrorSink(sink: ErrorSink): () => void {\n sinks.add(sink);\n return () => sinks.delete(sink);\n}\n\nexport function reportError(err: unknown, label: string): void {\n const adzenErr: AdzenError = {\n label,\n message: err instanceof Error ? err.message : String(err),\n stack: err instanceof Error ? err.stack : undefined,\n ts: Date.now(),\n };\n for (const sink of sinks) {\n try {\n sink(adzenErr);\n } catch {\n // never let a sink crash the caller\n }\n }\n}\n\nexport function safeRun<T>(fn: () => T, label: string): T | undefined;\nexport function safeRun<T>(fn: () => T, label: string, fallback: T): T;\nexport function safeRun<T>(fn: () => T, label: string, fallback?: T): T | undefined {\n try {\n return fn();\n } catch (err) {\n reportError(err, label);\n return fallback;\n }\n}\n\nexport async function safeRunAsync<T>(fn: () => Promise<T>, label: string): Promise<T | undefined>;\nexport async function safeRunAsync<T>(fn: () => Promise<T>, label: string, fallback: T): Promise<T>;\nexport async function safeRunAsync<T>(\n fn: () => Promise<T>,\n label: string,\n fallback?: T,\n): Promise<T | undefined> {\n try {\n return await fn();\n } catch (err) {\n reportError(err, label);\n return fallback;\n }\n}\n","const TID_KEY = \"adzen_tid\";\n\nexport function uuidv4(): string {\n if (typeof crypto !== \"undefined\" && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\nexport function readTid(): string | null {\n if (typeof localStorage === \"undefined\") return null;\n try {\n return localStorage.getItem(TID_KEY);\n } catch {\n return null;\n }\n}\n\nexport function ensureTid(): string {\n const existing = readTid();\n if (existing) return existing;\n const id = uuidv4();\n try {\n localStorage.setItem(TID_KEY, id);\n } catch {\n // storage unavailable — return ephemeral id\n }\n return id;\n}\n","export interface ViewabilityOptions {\n element: Element;\n thresholdMs: number;\n onViewed: () => void;\n intersectionThreshold?: number;\n}\n\nexport function observeViewability(options: ViewabilityOptions): () => void {\n const { element, thresholdMs, onViewed, intersectionThreshold = 1.0 } = options;\n let timer: ReturnType<typeof setTimeout> | null = null;\n let fired = false;\n\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting && !fired) {\n timer = setTimeout(() => {\n fired = true;\n onViewed();\n observer.disconnect();\n }, thresholdMs);\n } else if (!entry.isIntersecting && timer !== null) {\n clearTimeout(timer);\n timer = null;\n }\n }\n },\n { threshold: intersectionThreshold },\n );\n\n observer.observe(element);\n\n return () => {\n if (timer !== null) clearTimeout(timer);\n observer.disconnect();\n };\n}\n"],"mappings":";AAIA,IAAM,QAAQ,oBAAI,IAAe;AAE1B,SAAS,kBAAkB,MAA6B;AAC7D,QAAM,IAAI,IAAI;AACd,SAAO,MAAM,MAAM,OAAO,IAAI;AAChC;AAEO,SAAS,YAAY,KAAc,OAAqB;AAC7D,QAAM,WAAuB;AAAA,IAC3B;AAAA,IACA,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,IACxD,OAAO,eAAe,QAAQ,IAAI,QAAQ;AAAA,IAC1C,IAAI,KAAK,IAAI;AAAA,EACf;AACA,aAAW,QAAQ,OAAO;AACxB,QAAI;AACF,WAAK,QAAQ;AAAA,IACf,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAIO,SAAS,QAAW,IAAa,OAAe,UAA6B;AAClF,MAAI;AACF,WAAO,GAAG;AAAA,EACZ,SAAS,KAAK;AACZ,gBAAY,KAAK,KAAK;AACtB,WAAO;AAAA,EACT;AACF;AAIA,eAAsB,aACpB,IACA,OACA,UACwB;AACxB,MAAI;AACF,WAAO,MAAM,GAAG;AAAA,EAClB,SAAS,KAAK;AACZ,gBAAY,KAAK,KAAK;AACtB,WAAO;AAAA,EACT;AACF;;;ACnDA,IAAM,UAAU;AAET,SAAS,SAAiB;AAC/B,MAAI,OAAO,WAAW,eAAe,OAAO,YAAY;AACtD,WAAO,OAAO,WAAW;AAAA,EAC3B;AACA,SAAO,uCAAuC,QAAQ,SAAS,CAAC,MAAM;AACpE,UAAM,IAAK,KAAK,OAAO,IAAI,KAAM;AACjC,UAAM,IAAI,MAAM,MAAM,IAAK,IAAI,IAAO;AACtC,WAAO,EAAE,SAAS,EAAE;AAAA,EACtB,CAAC;AACH;AAEO,SAAS,UAAyB;AACvC,MAAI,OAAO,iBAAiB,YAAa,QAAO;AAChD,MAAI;AACF,WAAO,aAAa,QAAQ,OAAO;AAAA,EACrC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,YAAoB;AAClC,QAAM,WAAW,QAAQ;AACzB,MAAI,SAAU,QAAO;AACrB,QAAM,KAAK,OAAO;AAClB,MAAI;AACF,iBAAa,QAAQ,SAAS,EAAE;AAAA,EAClC,QAAQ;AAAA,EAER;AACA,SAAO;AACT;;;ACzBO,SAAS,mBAAmB,SAAyC;AAC1E,QAAM,EAAE,SAAS,aAAa,UAAU,wBAAwB,EAAI,IAAI;AACxE,MAAI,QAA8C;AAClD,MAAI,QAAQ;AAEZ,QAAM,WAAW,IAAI;AAAA,IACnB,CAAC,YAAY;AACX,iBAAW,SAAS,SAAS;AAC3B,YAAI,MAAM,kBAAkB,CAAC,OAAO;AAClC,kBAAQ,WAAW,MAAM;AACvB,oBAAQ;AACR,qBAAS;AACT,qBAAS,WAAW;AAAA,UACtB,GAAG,WAAW;AAAA,QAChB,WAAW,CAAC,MAAM,kBAAkB,UAAU,MAAM;AAClD,uBAAa,KAAK;AAClB,kBAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,IACA,EAAE,WAAW,sBAAsB;AAAA,EACrC;AAEA,WAAS,QAAQ,OAAO;AAExB,SAAO,MAAM;AACX,QAAI,UAAU,KAAM,cAAa,KAAK;AACtC,aAAS,WAAW;AAAA,EACtB;AACF;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@adzenai/core",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Core types and utilities for the Adzen AI ad SDK",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public"
|
|
9
|
+
},
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"require": {
|
|
17
|
+
"types": "./dist/index.d.cts",
|
|
18
|
+
"default": "./dist/index.cjs"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"main": "./dist/index.cjs",
|
|
23
|
+
"module": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"files": ["dist"],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsup",
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"clean": "rm -rf dist",
|
|
30
|
+
"typecheck": "tsc --noEmit"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"tsup": "^8.1.0",
|
|
34
|
+
"typescript": "^5.5.0",
|
|
35
|
+
"vitest": "^2.1.0"
|
|
36
|
+
}
|
|
37
|
+
}
|