@xenia-martech/sdk-js 1.2.0-dev.1 → 1.2.0-dev.3
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/README.md +6 -1
- package/dist/{actions-D9_aAvCv.d.cts → actions-Bhji05Pe.d.cts} +19 -4
- package/dist/{actions-D9_aAvCv.d.ts → actions-Bhji05Pe.d.ts} +19 -4
- package/dist/{api-CktVQ6Gl.d.ts → api-BqSvWgBZ.d.cts} +4 -2
- package/dist/{api-BEPW0Uan.d.cts → api-ByoECRhR.d.ts} +4 -2
- package/dist/{chunk-DWFVDNU5.js → chunk-INM2SPH4.js} +4 -4
- package/dist/chunk-INM2SPH4.js.map +1 -0
- package/dist/{chunk-7NGJC7CF.js → chunk-TGG5Y4QD.js} +17 -6
- package/dist/chunk-TGG5Y4QD.js.map +1 -0
- package/dist/{chunk-3PYPPIUM.cjs → chunk-TRRMMPBH.cjs} +13 -13
- package/dist/chunk-TRRMMPBH.cjs.map +1 -0
- package/dist/{chunk-IBNIRT7J.cjs → chunk-YZG6JR4E.cjs} +17 -6
- package/dist/chunk-YZG6JR4E.cjs.map +1 -0
- package/dist/client/index.cjs +43 -8
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +2 -2
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +43 -8
- package/dist/client/index.js.map +1 -1
- package/dist/client/react/index.cjs +46 -11
- package/dist/client/react/index.cjs.map +1 -1
- package/dist/client/react/index.d.cts +2 -2
- package/dist/client/react/index.d.ts +2 -2
- package/dist/client/react/index.js +46 -11
- package/dist/client/react/index.js.map +1 -1
- package/dist/cms/contentful.cjs +2 -1
- package/dist/cms/contentful.cjs.map +1 -1
- package/dist/cms/contentful.d.cts +1 -1
- package/dist/cms/contentful.d.ts +1 -1
- package/dist/cms/contentful.js +2 -1
- package/dist/cms/contentful.js.map +1 -1
- package/dist/{cookie-names-CLqtmGBM.d.ts → cookie-names-Bxd-VNyJ.d.ts} +1 -1
- package/dist/{cookie-names-BACctagz.d.cts → cookie-names-RXVfGYPE.d.cts} +1 -1
- package/dist/index.cjs +21 -21
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/next/index.cjs +9 -9
- package/dist/next/index.d.cts +3 -3
- package/dist/next/index.d.ts +3 -3
- package/dist/next/index.js +2 -2
- package/dist/{personalize-content-Clc1oMYY.d.cts → personalize-content-Bf6YZdkZ.d.cts} +12 -1
- package/dist/{personalize-content-Clc1oMYY.d.ts → personalize-content-Bf6YZdkZ.d.ts} +12 -1
- package/dist/server/index.cjs +19 -19
- package/dist/server/index.d.cts +5 -5
- package/dist/server/index.d.ts +5 -5
- package/dist/server/index.js +3 -3
- package/dist/xenia-sdk.iife.js +3 -3
- package/dist/xenia-sdk.iife.js.map +1 -1
- package/dist/{xenia-server-BWhWD0La.d.ts → xenia-server-CcjQenru.d.ts} +2 -2
- package/dist/{xenia-server-o_wDOcei.d.cts → xenia-server-MlI3Khya.d.cts} +2 -2
- package/package.json +1 -1
- package/dist/chunk-3PYPPIUM.cjs.map +0 -1
- package/dist/chunk-7NGJC7CF.js.map +0 -1
- package/dist/chunk-DWFVDNU5.js.map +0 -1
- package/dist/chunk-IBNIRT7J.cjs.map +0 -1
|
@@ -555,7 +555,7 @@ var XeniaApi = class {
|
|
|
555
555
|
* ({@link personalizeContent}) calls this once per round with the runtime
|
|
556
556
|
* targets it found; callers rarely need it directly.
|
|
557
557
|
*/
|
|
558
|
-
async resolveEntries(entryIds, opts
|
|
558
|
+
async resolveEntries(entryIds, opts) {
|
|
559
559
|
const { data } = await this.http.request({
|
|
560
560
|
method: "POST",
|
|
561
561
|
path: "/api/personalization/resolve-entries",
|
|
@@ -563,7 +563,8 @@ var XeniaApi = class {
|
|
|
563
563
|
body: compact({
|
|
564
564
|
entryIds,
|
|
565
565
|
data: opts.data,
|
|
566
|
-
locale: opts.locale
|
|
566
|
+
locale: opts.locale,
|
|
567
|
+
contentKey: opts.contentKey
|
|
567
568
|
})
|
|
568
569
|
});
|
|
569
570
|
return data;
|
|
@@ -687,7 +688,7 @@ var DEFAULT_TIMEOUT_MS = 300;
|
|
|
687
688
|
var DEFAULT_MAX_ROUNDS = 3;
|
|
688
689
|
var copyOf = (v) => v && typeof v === "object" && typeof structuredClone === "function" ? structuredClone(v) : v;
|
|
689
690
|
async function personalizeContent(payload, options) {
|
|
690
|
-
const
|
|
691
|
+
const cms = scopedAdapter(options.cms, options.contentKey);
|
|
691
692
|
const maxRounds = options.maxRounds ?? DEFAULT_MAX_ROUNDS;
|
|
692
693
|
const deadline = Date.now() + (options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
693
694
|
const applied = [];
|
|
@@ -886,7 +887,8 @@ function withDeadline(promise, deadline) {
|
|
|
886
887
|
})
|
|
887
888
|
]).finally(() => clearTimeout(timer));
|
|
888
889
|
}
|
|
889
|
-
function pendingTargets(payload,
|
|
890
|
+
function pendingTargets(payload, adapter, contentKey) {
|
|
891
|
+
const cms = scopedAdapter(adapter, contentKey);
|
|
890
892
|
try {
|
|
891
893
|
let content = typeof structuredClone === "function" ? structuredClone(payload) : payload;
|
|
892
894
|
content = cms.prepare ? cms.prepare(content) : content;
|
|
@@ -897,6 +899,15 @@ function pendingTargets(payload, cms) {
|
|
|
897
899
|
return [];
|
|
898
900
|
}
|
|
899
901
|
}
|
|
902
|
+
function scopedAdapter(cms, contentKey) {
|
|
903
|
+
return {
|
|
904
|
+
...cms,
|
|
905
|
+
marker(entry) {
|
|
906
|
+
const m = cms.marker(entry);
|
|
907
|
+
return m && contentKey && m.keys?.includes(contentKey) ? m : null;
|
|
908
|
+
}
|
|
909
|
+
};
|
|
910
|
+
}
|
|
900
911
|
async function personalizePage(ref, options) {
|
|
901
912
|
let page;
|
|
902
913
|
try {
|
|
@@ -1238,6 +1249,20 @@ var AutoTracker = class {
|
|
|
1238
1249
|
}
|
|
1239
1250
|
};
|
|
1240
1251
|
|
|
1252
|
+
// src/server/cookies.ts
|
|
1253
|
+
function parseCookies(header) {
|
|
1254
|
+
const out = {};
|
|
1255
|
+
if (!header) return out;
|
|
1256
|
+
for (const part of header.split(";")) {
|
|
1257
|
+
const idx = part.indexOf("=");
|
|
1258
|
+
if (idx === -1) continue;
|
|
1259
|
+
const key = part.slice(0, idx).trim();
|
|
1260
|
+
const value = part.slice(idx + 1).trim();
|
|
1261
|
+
if (key) out[key] = decodeURIComponent(value);
|
|
1262
|
+
}
|
|
1263
|
+
return out;
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1241
1266
|
// src/client/identity.ts
|
|
1242
1267
|
var SESSION_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
1243
1268
|
var Identity = class {
|
|
@@ -1285,10 +1310,19 @@ var Identity = class {
|
|
|
1285
1310
|
} catch {
|
|
1286
1311
|
}
|
|
1287
1312
|
}
|
|
1313
|
+
/** The visitor id already in the cookie — e.g. minted by `xeniaProxy()` on the first request. */
|
|
1314
|
+
readVisitorCookie() {
|
|
1315
|
+
if (!this.cookie || typeof document === "undefined") return null;
|
|
1316
|
+
try {
|
|
1317
|
+
return parseCookies(document.cookie)[this.cookieName()] || null;
|
|
1318
|
+
} catch {
|
|
1319
|
+
return null;
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1288
1322
|
// ── Device id ────────────────────────────────────────────────────────────
|
|
1289
1323
|
/**
|
|
1290
|
-
* Resolve a stable device id: localStorage cache →
|
|
1291
|
-
* browser fingerprint. Cached for the session and across reloads.
|
|
1324
|
+
* Resolve a stable device id: localStorage cache → the visitor cookie a server already set →
|
|
1325
|
+
* MediaDevices → SHA-256 browser fingerprint. Cached for the session and across reloads.
|
|
1292
1326
|
*/
|
|
1293
1327
|
async resolveDeviceId() {
|
|
1294
1328
|
if (this.deviceId) {
|
|
@@ -1305,7 +1339,8 @@ var Identity = class {
|
|
|
1305
1339
|
}
|
|
1306
1340
|
} catch {
|
|
1307
1341
|
}
|
|
1308
|
-
let id =
|
|
1342
|
+
let id = this.readVisitorCookie();
|
|
1343
|
+
if (!id) id = await this.mediaDeviceId();
|
|
1309
1344
|
if (!id) id = await this.fingerprint();
|
|
1310
1345
|
this.deviceId = id;
|
|
1311
1346
|
try {
|
|
@@ -2384,7 +2419,7 @@ var XeniaClient = class {
|
|
|
2384
2419
|
return personalizePage(ref, { ...opts, resolve: this.entryResolver(opts) });
|
|
2385
2420
|
}
|
|
2386
2421
|
entryResolver(opts) {
|
|
2387
|
-
const resolveOpts = this.withVisitor({ data: opts.data, locale: opts.locale });
|
|
2422
|
+
const resolveOpts = { ...this.withVisitor({ data: opts.data, locale: opts.locale }), contentKey: opts.contentKey };
|
|
2388
2423
|
return async (ids) => (await this.api.resolveEntries(ids, resolveOpts)).decisions ?? [];
|
|
2389
2424
|
}
|
|
2390
2425
|
/** The SDK-owned visitor anchor: the `identify()`/`config.visitorId` id, else the device id. */
|
|
@@ -2801,8 +2836,8 @@ function usePersonalizedContent(page, opts) {
|
|
|
2801
2836
|
const xenia = useXenia();
|
|
2802
2837
|
const hide = opts.render === "hide-until-resolved";
|
|
2803
2838
|
const initialPending = react.useMemo(
|
|
2804
|
-
() => new Set(page == null ? [] : pendingTargets(page, opts.cms)),
|
|
2805
|
-
[page]
|
|
2839
|
+
() => new Set(page == null ? [] : pendingTargets(page, opts.cms, opts.contentKey)),
|
|
2840
|
+
[page, opts.contentKey]
|
|
2806
2841
|
// markers live in `page`; a new adapter object for the same page changes nothing
|
|
2807
2842
|
);
|
|
2808
2843
|
const [state, setState] = react.useState(
|
|
@@ -2810,7 +2845,7 @@ function usePersonalizedContent(page, opts) {
|
|
|
2810
2845
|
);
|
|
2811
2846
|
const optsRef = react.useRef(opts);
|
|
2812
2847
|
optsRef.current = opts;
|
|
2813
|
-
const optsKey = JSON.stringify({ data: opts.data ?? {}, locale: opts.locale });
|
|
2848
|
+
const optsKey = JSON.stringify({ data: opts.data ?? {}, locale: opts.locale, contentKey: opts.contentKey });
|
|
2814
2849
|
react.useEffect(() => {
|
|
2815
2850
|
if (page == null) return;
|
|
2816
2851
|
let active = true;
|