@xenia-martech/sdk-js 1.2.0-dev.8 → 1.2.0-dev.9
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 +69 -5
- package/dist/{actions-35V37IT0.d.cts → actions--1_9Z8ig.d.cts} +13 -2
- package/dist/{actions-35V37IT0.d.ts → actions--1_9Z8ig.d.ts} +13 -2
- package/dist/{api-0IycTYJR.d.cts → api-DbUxT38T.d.ts} +1 -1
- package/dist/{api-COXWLL5L.d.ts → api-DgzJ5s-k.d.cts} +1 -1
- package/dist/chunk-DPXINHQR.cjs +34 -0
- package/dist/chunk-DPXINHQR.cjs.map +1 -0
- package/dist/chunk-FSJMHXS6.js +432 -0
- package/dist/chunk-FSJMHXS6.js.map +1 -0
- package/dist/chunk-GXJLU3RE.cjs +448 -0
- package/dist/chunk-GXJLU3RE.cjs.map +1 -0
- package/dist/{chunk-2DR5AVPX.cjs → chunk-I5EHLRSR.cjs} +11 -10
- package/dist/chunk-I5EHLRSR.cjs.map +1 -0
- package/dist/{chunk-LW5AEJ6K.js → chunk-MEULT5X6.js} +4 -241
- package/dist/chunk-MEULT5X6.js.map +1 -0
- package/dist/{chunk-GWRDZIVA.js → chunk-NDRRSRTU.js} +4 -3
- package/dist/chunk-NDRRSRTU.js.map +1 -0
- package/dist/chunk-RC46KXDM.js +32 -0
- package/dist/chunk-RC46KXDM.js.map +1 -0
- package/dist/{chunk-RWE2OCQL.cjs → chunk-SU25SELD.cjs} +4 -244
- package/dist/chunk-SU25SELD.cjs.map +1 -0
- package/dist/{chunk-WHGK55JP.cjs → chunk-UUIKUU5W.cjs} +5 -5
- package/dist/{chunk-WHGK55JP.cjs.map → chunk-UUIKUU5W.cjs.map} +1 -1
- package/dist/{chunk-QEYONKWY.js → chunk-UVTFGQR6.js} +3 -3
- package/dist/{chunk-QEYONKWY.js.map → chunk-UVTFGQR6.js.map} +1 -1
- package/dist/{chunk-F3WZFXYK.js → chunk-V4EGU3PM.js} +45 -10
- package/dist/chunk-V4EGU3PM.js.map +1 -0
- package/dist/{chunk-IOY6IPUW.cjs → chunk-WMGCQPHY.cjs} +49 -12
- package/dist/chunk-WMGCQPHY.cjs.map +1 -0
- package/dist/client/index.cjs +26 -10
- 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 +26 -10
- package/dist/client/index.js.map +1 -1
- package/dist/client/react/index.cjs +73 -15
- package/dist/client/react/index.cjs.map +1 -1
- package/dist/client/react/index.d.cts +9 -3
- package/dist/client/react/index.d.ts +9 -3
- package/dist/client/react/index.js +73 -15
- package/dist/client/react/index.js.map +1 -1
- package/dist/cms/contentful.cjs +7 -24
- package/dist/cms/contentful.cjs.map +1 -1
- package/dist/cms/contentful.d.cts +5 -4
- package/dist/cms/contentful.d.ts +5 -4
- package/dist/cms/contentful.js +4 -23
- package/dist/cms/contentful.js.map +1 -1
- package/dist/cms/contentstack.cjs +120 -0
- package/dist/cms/contentstack.cjs.map +1 -0
- package/dist/cms/contentstack.d.cts +41 -0
- package/dist/cms/contentstack.d.ts +41 -0
- package/dist/cms/contentstack.js +117 -0
- package/dist/cms/contentstack.js.map +1 -0
- package/dist/{consent-DRCV0N0d.d.ts → consent-Dtiqzz2B.d.cts} +71 -11
- package/dist/{consent-BgAETCkL.d.cts → consent-byYiDMFr.d.ts} +71 -11
- package/dist/{cookie-names-DU3MtcNG.d.ts → cookie-names-B4hda2rX.d.cts} +1 -1
- package/dist/{cookie-names-DFItnSLK.d.cts → cookie-names-DioZXuV0.d.ts} +1 -1
- package/dist/edge/index.cjs +122 -29
- package/dist/edge/index.cjs.map +1 -1
- package/dist/edge/index.d.cts +41 -5
- package/dist/edge/index.d.ts +41 -5
- package/dist/edge/index.js +92 -9
- package/dist/edge/index.js.map +1 -1
- package/dist/index.cjs +31 -31
- package/dist/index.d.cts +4 -5
- package/dist/index.d.ts +4 -5
- package/dist/index.js +2 -2
- package/dist/next/index.cjs +34 -33
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.cts +2 -3
- package/dist/next/index.d.ts +2 -3
- package/dist/next/index.js +8 -7
- package/dist/next/index.js.map +1 -1
- package/dist/{types-DgVHS4Qw.d.ts → personalize-content-D6xeBI7-.d.cts} +150 -1
- package/dist/{types-DgVHS4Qw.d.cts → personalize-content-D6xeBI7-.d.ts} +150 -1
- package/dist/server/index.cjs +30 -30
- package/dist/server/index.d.cts +5 -6
- package/dist/server/index.d.ts +5 -6
- package/dist/server/index.js +5 -5
- package/dist/xenia-sdk.iife.js +3 -3
- package/dist/xenia-sdk.iife.js.map +1 -1
- package/dist/{xenia-server-Cf24mL0c.d.ts → xenia-server-BcgeUHX4.d.ts} +2 -3
- package/dist/{xenia-server-D-bx14lw.d.cts → xenia-server-lv6LtJZP.d.cts} +2 -3
- package/package.json +14 -1
- package/dist/chunk-2DR5AVPX.cjs.map +0 -1
- package/dist/chunk-BQ5PJCZ7.js +0 -179
- package/dist/chunk-BQ5PJCZ7.js.map +0 -1
- package/dist/chunk-F3WZFXYK.js.map +0 -1
- package/dist/chunk-GWRDZIVA.js.map +0 -1
- package/dist/chunk-IOY6IPUW.cjs.map +0 -1
- package/dist/chunk-LW5AEJ6K.js.map +0 -1
- package/dist/chunk-N5M4PI7C.cjs +0 -192
- package/dist/chunk-N5M4PI7C.cjs.map +0 -1
- package/dist/chunk-RWE2OCQL.cjs.map +0 -1
- package/dist/personalize-content-Cwc2AomC.d.ts +0 -141
- package/dist/personalize-content-CxSdplMV.d.cts +0 -141
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/edge/consent.ts","../src/edge/request-facts.ts","../src/edge/trail.ts","../src/edge/webhook.ts","../src/edge/variant.ts","../src/edge/manifest.ts"],"names":["enc"],"mappings":"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","file":"chunk-V4EGU3PM.js","sourcesContent":["import { consentCookieName } from \"../core/cookie-names\";\nimport { parseCookies } from \"../server/cookies\";\n\nexport interface EdgeConsent {\n /** Off: don't ask Xenia, serve base content. */\n personalization: boolean;\n /** Off: decide, but keep no trail or click cookies and send no trail. */\n analytics: boolean;\n}\n\n/**\n * What the edge flow may do for this request, from the consent cookie the browser client's\n * `consent()` writes and the visitor's privacy signals:\n * - no consent cookie (or an unreadable one) → no choice made: everything on, as before;\n * - an explicit choice → followed (JSON `{analytics, personalization}`, or the scopes form\n * `analytics,personalization` where an unlisted scope is refused);\n * - `Sec-GPC: 1` / `DNT: 1` → analytics off, like the browser client's `respectDnt` (default on).\n *\n * Unlike `getConsent()`, an absent cookie isn't \"all denied\": the edge can't tell a visitor who\n * refused from one who was never asked, and refusing both would change every first page view.\n */\nexport function edgeConsent(headers: Headers, opts: { prefix?: string; respectDnt?: boolean } = {}): EdgeConsent {\n const raw = parseCookies(headers.get(\"cookie\"))[consentCookieName(opts.prefix)];\n let consent: EdgeConsent = { personalization: true, analytics: true };\n if (raw) {\n try {\n const parsed: unknown = JSON.parse(raw);\n if (parsed && typeof parsed === \"object\") {\n const p = parsed as Record<string, unknown>;\n consent = { personalization: p.personalization !== false, analytics: p.analytics !== false };\n }\n } catch {\n if (/^[a-z]+(\\s*,\\s*[a-z]+)*$/i.test(raw.trim())) {\n const scopes = new Set(raw.split(\",\").map((s) => s.trim()));\n consent = { personalization: scopes.has(\"personalization\"), analytics: scopes.has(\"analytics\") };\n }\n }\n }\n const privacySignal = headers.get(\"sec-gpc\") === \"1\" || headers.get(\"dnt\") === \"1\";\n if (opts.respectDnt !== false && privacySignal) consent = { ...consent, analytics: false };\n return consent;\n}\n","/**\n * Facts about a request that journey rules read — where the visitor is, on what device, where they\n * came from, their local time — derived from a standard `Request` in any runtime.\n */\nimport type { ViewerGeo } from \"./types\";\n\nconst GEO_KEYS = [\n \"country\",\n \"countryName\",\n \"region\",\n \"regionName\",\n \"city\",\n \"postalCode\",\n \"timeZone\",\n \"latitude\",\n \"longitude\",\n \"source\",\n] as const;\n\n/** Any host's geo object (Netlify, Next.js runtimes, our own edge function). */\ntype GeoLike = {\n country?: string | { code?: string; name?: string };\n countryName?: string;\n region?: string;\n subdivision?: { code?: string; name?: string };\n regionName?: string;\n city?: string;\n postalCode?: string;\n timeZone?: string;\n timezone?: string;\n latitude?: string | number;\n longitude?: string | number;\n};\n\n/** Normalizes any host's geo object into Xenia's `ViewerGeo` keys (values over 100 chars dropped). */\nfunction toViewerGeo(g: GeoLike | undefined, source: string): ViewerGeo | undefined {\n if (!g) return undefined;\n const country = typeof g.country === \"string\" ? g.country : g.country?.code;\n if (!country) return undefined;\n const raw: Record<string, unknown> = {\n country: country.toUpperCase(),\n countryName: g.countryName ?? (typeof g.country === \"object\" ? g.country?.name : undefined),\n region: g.region ?? g.subdivision?.code,\n regionName: g.regionName ?? g.subdivision?.name,\n city: g.city,\n postalCode: g.postalCode,\n timeZone: g.timeZone ?? g.timezone,\n latitude: g.latitude?.toString(),\n longitude: g.longitude?.toString(),\n source,\n };\n const geo: ViewerGeo = {};\n for (const k of GEO_KEYS) {\n const v = raw[k];\n if (typeof v === \"string\" && v && v.length <= 100) geo[k] = v;\n }\n return geo;\n}\n\nconst parseJson = (text: string): GeoLike | undefined => {\n try {\n return JSON.parse(text) as GeoLike;\n } catch {\n return undefined;\n }\n};\n\nfunction safeDecode(v: string): string {\n try {\n return decodeURIComponent(v);\n } catch {\n return v;\n }\n}\n\nfunction safeBase64(v: string): string {\n try {\n return atob(v);\n } catch {\n return \"\";\n }\n}\n\n/** Netlify's per-request context, when running in Netlify's runtime. */\nfunction netlifyContext(): { geo?: GeoLike } | undefined {\n try {\n return (globalThis as unknown as { Netlify?: { context?: { geo?: GeoLike } | null } }).Netlify?.context ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nconst COUNTRY_HEADERS = [\"x-country\", \"x-vercel-ip-country\", \"cloudfront-viewer-country\", \"cf-ipcountry\"];\n\n/** The location headers `viewerGeo` can read, when trusted. */\nexport type GeoHeader = \"x-xn-geo\" | \"x-nf-geo\" | \"x-country\" | \"x-vercel-ip-country\" | \"cloudfront-viewer-country\" | \"cf-ipcountry\";\n\nfunction companions(h: Headers, country: string): GeoLike {\n const of = (name: string) => h.get(name) ?? undefined;\n if (country === \"x-vercel-ip-country\") {\n return { region: of(\"x-vercel-ip-country-region\"), city: safeDecode(of(\"x-vercel-ip-city\") ?? \"\") || undefined, timeZone: of(\"x-vercel-ip-timezone\") };\n }\n if (country === \"cloudfront-viewer-country\") {\n return { region: of(\"cloudfront-viewer-country-region\"), city: safeDecode(of(\"cloudfront-viewer-city\") ?? \"\") || undefined, timeZone: of(\"cloudfront-viewer-time-zone\") };\n }\n return {};\n}\n\n/**\n * The visitor's location as the hosting edge resolved it, and which source supplied it (`via`).\n * Geo must come from the storefront's edge, never Xenia's: `/decide` is server to server. Tried in\n * order — whichever the host provides:\n * 1. Netlify's per-request `Netlify.context.geo` (can't be spoofed by the client, unlike a header)\n * 2. `x-xn-geo` (URI-encoded JSON) from the site's own edge function\n * 3. a `request.geo` some runtimes attach\n * 4. Netlify's `x-nf-geo` header (base64 or URI-encoded JSON)\n * 5. `x-country` (Netlify), `x-vercel-ip-*`, `cloudfront-viewer-*`, `cf-ipcountry`\n * 6. `?xn_country=GB` — only with `devOverride`, for testing geo rules without an edge\n *\n * Headers (2, 4 and 5) are read only when named in `trust`: a visitor can send any header, and only\n * the site knows which ones its own host or edge function sets (and overwrites). Name exactly those,\n * e.g. `[\"x-vercel-ip-country\"]` on Vercel, `[\"cf-ipcountry\"]` behind Cloudflare,\n * `[\"x-nf-geo\", \"x-country\"]` on Netlify. 1 and 3 come from the runtime and are always used.\n */\nexport function viewerGeo(\n request: Request,\n opts: { devOverride?: boolean; trust?: readonly GeoHeader[] } = {},\n): { geo?: ViewerGeo; via: string } {\n const trusted = new Set<string>(opts.trust ?? []);\n const fromNetlify = toViewerGeo(netlifyContext()?.geo, \"edge\");\n if (fromNetlify) return { geo: fromNetlify, via: \"Netlify.context\" };\n\n const h = { get: (name: string) => (trusted.has(name) ? request.headers.get(name) : null) };\n const xn = h.get(\"x-xn-geo\");\n const fromXn = xn ? toViewerGeo(parseJson(safeDecode(xn)), \"edge\") : undefined;\n if (fromXn) return { geo: fromXn, via: \"x-xn-geo (edge function)\" };\n\n const fromRuntime = toViewerGeo((request as unknown as { geo?: GeoLike }).geo, \"edge\");\n if (fromRuntime) return { geo: fromRuntime, via: \"request.geo\" };\n\n const nf = h.get(\"x-nf-geo\");\n if (nf) {\n const fromNf = toViewerGeo(parseJson(safeBase64(nf)) ?? parseJson(safeDecode(nf)), \"edge\");\n if (fromNf) return { geo: fromNf, via: \"x-nf-geo\" };\n }\n\n const via = COUNTRY_HEADERS.find((n) => h.get(n));\n const headerCountry = via ? h.get(via) : null;\n if (via && headerCountry && /^[a-z]{2}$/i.test(headerCountry)) {\n const geo = toViewerGeo(\n {\n country: headerCountry,\n // The region, city and time zone of the same provider as the country header.\n ...companions(request.headers, via),\n },\n \"edge\",\n );\n return { geo, via };\n }\n\n const override = new URL(request.url).searchParams.get(\"xn_country\");\n if (opts.devOverride && override && /^[a-z]{2}$/i.test(override)) {\n return { geo: { country: override.toUpperCase(), source: \"dev\" }, via: \"?xn_country (dev)\" };\n }\n return { via: \"none\" };\n}\n\nexport function deviceOf(headers: Headers): \"mobile\" | \"tablet\" | \"desktop\" {\n const ua = headers.get(\"user-agent\") ?? \"\";\n if (/iPad|Tablet/i.test(ua)) return \"tablet\";\n if (headers.get(\"sec-ch-ua-mobile\") === \"?1\" || /Mobi|Android|iPhone/i.test(ua)) return \"mobile\";\n return \"desktop\";\n}\n\nconst BOT = /bot|crawl|spider|slurp|facebookexternalhit|embedly|preview|whatsapp|bingpreview/i;\n\n/** Crawlers and link-preview fetchers: never decided, never recorded. */\nexport function isBot(userAgent: string | null | undefined): boolean {\n return BOT.test(userAgent ?? \"\");\n}\n\n/** Link prefetches pass through a proxy too; they aren't page views. */\nexport function isPrefetch(headers: Headers): boolean {\n return (\n headers.has(\"next-router-prefetch\") ||\n /prefetch/i.test(headers.get(\"purpose\") ?? \"\") ||\n /prefetch/i.test(headers.get(\"sec-purpose\") ?? \"\")\n );\n}\n\n/**\n * Whether this is the browser loading a page (a full page load), by `Sec-Fetch-Dest`. Requests\n * without it (old browsers, curl) count as page loads.\n */\nexport function isPageLoad(headers: Headers): boolean {\n return (headers.get(\"sec-fetch-dest\") ?? \"document\") === \"document\" && !isPrefetch(headers);\n}\n\nconst UTM: Record<string, string> = {\n utm_source: \"utmSource\",\n utm_medium: \"utmMedium\",\n utm_campaign: \"utmCampaign\",\n utm_content: \"utmContent\",\n utm_term: \"utmTerm\",\n utm_id: \"utmId\",\n};\n\n/**\n * This session's landing context — first-touch attribution, so a campaign carries across pages:\n * the UTMs (≤200 chars each) and an external referrer (≤500), refreshed when the visitor arrives\n * from a new campaign. `saved` is the value kept from earlier (a cookie); `changed` says to save it.\n */\nexport function landingContext(\n url: URL,\n referrer: string | null | undefined,\n saved: string | undefined,\n): { ctx: Record<string, string>; changed: boolean } {\n const fromQuery: Record<string, string> = {};\n for (const [param, fact] of Object.entries(UTM)) {\n const v = url.searchParams.get(param);\n if (v) fromQuery[fact] = v.slice(0, 200);\n }\n const external = referrer && !referrer.startsWith(url.origin) ? referrer.slice(0, 500) : null;\n\n let kept: Record<string, string> | null;\n try {\n const parsed: unknown = saved ? JSON.parse(saved) : null;\n kept = parsed && typeof parsed === \"object\" && !Array.isArray(parsed) ? (parsed as Record<string, string>) : null;\n } catch {\n kept = null;\n }\n if (kept && !Object.keys(fromQuery).length) return { ctx: kept, changed: false };\n return { ctx: { ...fromQuery, ...(external ? { referrer: external } : {}) }, changed: true };\n}\n\nconst WEEKDAYS = [\"sunday\", \"monday\", \"tuesday\", \"wednesday\", \"thursday\", \"friday\", \"saturday\"];\n\n/** Meteorological seasons: Dec–Feb winter, Mar–May spring, Jun–Aug summer, Sep–Nov fall. */\nexport function seasonOf(month: number, southernHemisphere = false): string {\n const north = [\"winter\", \"winter\", \"spring\", \"spring\", \"spring\", \"summer\", \"summer\", \"summer\", \"fall\", \"fall\", \"fall\", \"winter\"];\n const season = north[(month - 1 + 12) % 12];\n if (!southernHemisphere) return season;\n return ({ winter: \"summer\", summer: \"winter\", spring: \"fall\", fall: \"spring\" } as Record<string, string>)[season] ?? season;\n}\n\nfunction validTimeZone(tz: string | undefined): string | undefined {\n if (!tz) return undefined;\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: tz });\n return tz;\n } catch {\n return undefined;\n }\n}\n\nexport interface LocalTime {\n local_weekday: string;\n local_month: number;\n local_hour: number;\n is_weekend: boolean;\n season: string;\n}\n\n/** Weekday, month, hour and season where the visitor is (their time zone; UTC when unknown). */\nexport function localTime(geo: ViewerGeo | undefined, now: Date): LocalTime {\n const timeZone = validTimeZone(geo?.timeZone) ?? \"UTC\";\n const parts = Object.fromEntries(\n new Intl.DateTimeFormat(\"en-US\", { timeZone, weekday: \"long\", month: \"numeric\", hour: \"numeric\", hourCycle: \"h23\" })\n .formatToParts(now)\n .map((p) => [p.type, p.value]),\n );\n const weekday = String(parts.weekday ?? WEEKDAYS[now.getUTCDay()]).toLowerCase();\n const month = Number(parts.month) || now.getUTCMonth() + 1;\n return {\n local_weekday: weekday,\n local_month: month,\n local_hour: Number(parts.hour) % 24,\n is_weekend: weekday === \"saturday\" || weekday === \"sunday\",\n season: seasonOf(month, Number(geo?.latitude) < 0),\n };\n}\n","/**\n * The visitor's recent page views, most recent first, kept in a short-lived first-party cookie\n * (`[[path, at], [path, at, seconds], …]`). The proxy sends it with `/decide`, so profile rules see\n * pages whose analytics events haven't been processed yet; the browser adds client-side navigations\n * and the time spent on a page as the visitor leaves it. Shared by both sides.\n */\nimport { DEFAULT_PREFIX } from \"../core/cookie-names\";\nimport type { TrailView } from \"./types\";\n\nexport const MAX_TRAIL = 8;\n/** Cookie lifetime: a visit ends after 30 idle minutes, like the SDK's session. */\nexport const TRAIL_MAX_AGE_S = 30 * 60;\n\nexport function trailCookieName(prefix: string = DEFAULT_PREFIX): string {\n return `${prefix}_trail`;\n}\n\nconst decode = (v: string) => {\n try {\n return decodeURIComponent(v);\n } catch {\n return v;\n }\n};\n\n/** The trail in a cookie value (raw or URI-encoded); anything malformed reads as no trail. */\nexport function readTrail(value: string | undefined | null): TrailView[] {\n if (!value) return [];\n try {\n const parsed: unknown = JSON.parse(decode(value));\n if (!Array.isArray(parsed)) return [];\n return parsed\n .filter((t): t is [string, number, number?] => Array.isArray(t) && typeof t[0] === \"string\" && typeof t[1] === \"number\")\n .slice(0, MAX_TRAIL)\n .map(([path, at, seconds]) =>\n typeof seconds === \"number\" && seconds >= 0 && seconds <= 86_400 ? { path, at, seconds } : { path, at },\n );\n } catch {\n return [];\n }\n}\n\n/**\n * The trail with this view first: a revisit moves to the front and keeps its first time (its old\n * time on page is dropped — this view's isn't known yet). The same array when `path` is already first.\n */\nexport function withView(trail: TrailView[], path: string, now: number = Date.now()): TrailView[] {\n if (trail[0]?.path === path) return trail;\n const earlier = trail.find((t) => t.path === path);\n return [{ path, at: earlier?.at ?? now }, ...trail.filter((t) => t.path !== path)].slice(0, MAX_TRAIL);\n}\n\n/** The cookie value for a trail (not URI-encoded; cookie setters encode it). */\nexport function trailCookieValue(trail: TrailView[]): string {\n return JSON.stringify(\n trail.slice(0, MAX_TRAIL).map((t) => (t.seconds === undefined ? [t.path, t.at] : [t.path, t.at, t.seconds])),\n );\n}\n","const enc = new TextEncoder();\n\nasync function hmacHex(secret: string, payload: string): Promise<string> {\n const key = await crypto.subtle.importKey(\"raw\", enc.encode(secret), { name: \"HMAC\", hash: \"SHA-256\" }, false, [\"sign\"]);\n const mac = new Uint8Array(await crypto.subtle.sign(\"HMAC\", key, enc.encode(payload)));\n return Array.from(mac, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\n/** Constant-time comparison, so a signature can't be guessed byte by byte. */\nexport function sameString(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a.charCodeAt(i) ^ b.charCodeAt(i);\n return diff === 0;\n}\n\n/**\n * Whether a storefront webhook from Xenia is genuine and fresh:\n * `X-Xenia-Signature: t=<unix s>,v1=<hex HMAC-SHA256(secret, \"<t>.<body>\")>`. Requests older than\n * `toleranceS` are refused, so a captured request can't be replayed. Pass the raw body text.\n */\nexport async function verifyWebhook(\n input: { headers: Headers; body: string },\n secret: string,\n toleranceS = 300,\n): Promise<boolean> {\n const header = input.headers.get(\"x-xenia-signature\") ?? \"\";\n if (!secret || !header) return false;\n const parts = Object.fromEntries(header.split(\",\").map((p) => p.trim().split(\"=\", 2)));\n const t = Number(parts.t);\n if (!Number.isFinite(t) || Math.abs(Date.now() / 1000 - t) > toleranceS || !parts.v1) return false;\n return sameString(await hmacHex(secret, `${parts.t}.${input.body}`), String(parts.v1).toLowerCase());\n}\n","/**\n * The proxy hands a decision to the page as a signed token in the rewritten URL\n * (`/xv/<token>/women`). The token is just the swaps — identical for every visitor in the same\n * variant — so each variant renders once and is then served from the ISR/CDN cache like any static\n * page. A site may carry its own data along (`extra`), e.g. what the page fills itself from.\n *\n * Signed (HMAC-SHA256) so nobody can craft a URL that renders arbitrary entries. Web Crypto only, so\n * it runs in any runtime.\n */\nimport type { EntryDecision } from \"../core/types\";\nimport type { EdgeDecision } from \"./types\";\nimport { sameString } from \"./webhook\";\n\n/**\n * One swap: the base entry's field, the entry shown in its place, and the content key whose\n * decision it is — so the page can report impressions and clicks per journey and entry.\n */\nexport type VariantSwap = [identifier: string, replacementEntryId: string, contentKey?: string];\n\n/** Swaps for one base entry. */\nexport interface SwapGroup {\n base: string;\n swaps: VariantSwap[];\n}\n\n/** The longest payload `decodeVariant` accepts. */\nconst MAX_PAYLOAD = 4096;\n\nconst enc = new TextEncoder();\n\nconst b64url = (bytes: Uint8Array) =>\n btoa(String.fromCharCode(...bytes))\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n\nconst fromB64url = (s: string) =>\n Uint8Array.from(atob(s.replace(/-/g, \"+\").replace(/_/g, \"/\")), (c) => c.charCodeAt(0));\n\nconst keys = new Map<string, Promise<CryptoKey>>();\nconst keyFor = (secret: string) => {\n let key = keys.get(secret);\n if (!key) {\n key = crypto.subtle.importKey(\"raw\", enc.encode(secret), { name: \"HMAC\", hash: \"SHA-256\" }, false, [\"sign\"]);\n keys.set(secret, key);\n }\n return key;\n};\n\nasync function sign(secret: string, payload: string): Promise<string> {\n const mac = await crypto.subtle.sign(\"HMAC\", await keyFor(secret), enc.encode(payload));\n return b64url(new Uint8Array(mac).slice(0, 16));\n}\n\n/** The swap groups of the personalized decisions, in a stable order (stable cache keys). */\nexport function swapGroups(decisions: EdgeDecision[]): SwapGroup[] {\n const byBase = new Map<string, Map<string, VariantSwap>>();\n for (const d of decisions) {\n if (!d.personalized || !d.baseEntryId) continue;\n for (const s of d.swaps) {\n if (!s.identifier || !s.replacementEntryId) continue;\n if (!byBase.has(d.baseEntryId)) byBase.set(d.baseEntryId, new Map());\n byBase.get(d.baseEntryId)!.set(s.identifier, [s.identifier, s.replacementEntryId, d.contentKey]);\n }\n }\n return [...byBase.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([base, swaps]) => ({ base, swaps: [...swaps.values()].sort(([a], [b]) => a.localeCompare(b)) }));\n}\n\n/** Deflate (raw) with the platform's CompressionStream — Node 18+, browsers and edge runtimes. */\nasync function deflate(text: string): Promise<Uint8Array> {\n const stream = new Response(text).body!.pipeThrough(new CompressionStream(\"deflate-raw\"));\n return new Uint8Array(await new Response(stream).arrayBuffer());\n}\n\nasync function inflate(bytes: Uint8Array): Promise<string> {\n const stream = new Response(bytes as BodyInit).body!.pipeThrough(new DecompressionStream(\"deflate-raw\"));\n return new Response(stream).text();\n}\n\n/**\n * The token for a variant. `entries` are the multi-level entry decisions of its personalized keys\n * (`DecideOutcome.entryDecisions`), so the page resolves nested CMS targets without calling Xenia.\n * They travel compressed (`ez`), which fits several times as many decisions.\n *\n * Whatever would still push it past the payload limit is left out — first `extra`, then `entries`\n * (counted in `ed`: the page serves those targets' base content and reports itself incomplete) —\n * rather than making a token no page accepts.\n */\nexport async function encodeVariant(\n groups: SwapGroup[],\n secret: string,\n extra?: unknown,\n entries?: EntryDecision[],\n): Promise<string> {\n const g = groups.map((x) => [x.base, x.swaps]);\n const ez = entries?.length ? b64url(await deflate(JSON.stringify(entries))) : undefined;\n const payloadOf = (x: unknown, withEntries: boolean) =>\n b64url(\n enc.encode(\n JSON.stringify({\n g,\n ...(ez ? (withEntries ? { ez } : { ed: entries!.length }) : {}),\n ...(x === undefined ? {} : { x }),\n }),\n ),\n );\n let payload = payloadOf(extra, true);\n if (payload.length > MAX_PAYLOAD && extra !== undefined) payload = payloadOf(undefined, true);\n if (payload.length > MAX_PAYLOAD && ez) payload = payloadOf(undefined, false);\n return `${payload}.${await sign(secret, payload)}`;\n}\n\n/**\n * The multi-level entry decisions of the personalized `decisions` — what {@link encodeVariant}\n * carries as `entries`.\n */\nexport function variantEntries(\n decisions: EdgeDecision[],\n entryDecisions: Record<string, EntryDecision[]> | undefined,\n): EntryDecision[] {\n if (!entryDecisions) return [];\n return decisions.filter((d) => d.personalized).flatMap((d) => entryDecisions[d.contentKey] ?? []);\n}\n\n/**\n * A page resolver (`personalizeContent({ resolve })`) that answers from a variant token's entries:\n * every level of the page's content key decided up front at the edge, so no Xenia call.\n */\nexport function variantEntryResolver(entries: EntryDecision[] | undefined, contentKey: string) {\n const mine = (entries ?? []).filter((d) => d.contentKey === contentKey);\n return async (ids: string[]): Promise<EntryDecision[]> => {\n const wanted = new Set(ids);\n return mine.filter((d) => wanted.has(d.target));\n };\n}\n\n/**\n * A decoded variant token. `entriesDropped` counts multi-level decisions that didn't fit in the\n * token: their targets show base content.\n */\nexport interface DecodedVariant<E = unknown> {\n groups: SwapGroup[];\n extra?: E;\n entries?: EntryDecision[];\n entriesDropped?: number;\n}\n\n/** The variant in a token, or `null` if it is malformed or not signed with `secret`. */\nexport async function decodeVariant<E = unknown>(token: string, secret: string): Promise<DecodedVariant<E> | null> {\n const [payload, mac, rest] = token.split(\".\");\n if (!payload || !mac || rest !== undefined || payload.length > MAX_PAYLOAD) return null;\n if (!sameString(await sign(secret, payload), mac)) return null;\n try {\n const raw = JSON.parse(new TextDecoder().decode(fromB64url(payload))) as {\n g: [string, VariantSwap[]][];\n x?: E;\n ez?: string;\n ed?: number;\n };\n const groups = raw.g.map(([base, swaps]) => ({ base, swaps }));\n const entries = raw.ez ? (JSON.parse(await inflate(fromB64url(raw.ez))) as EntryDecision[]) : undefined;\n return {\n groups,\n ...(raw.x === undefined ? {} : { extra: raw.x }),\n ...(Array.isArray(entries) ? { entries } : {}),\n ...(typeof raw.ed === \"number\" && raw.ed > 0 ? { entriesDropped: raw.ed } : {}),\n };\n } catch {\n return null;\n }\n}\n","import { DEFAULT_BASE_URL } from \"../core/http-client\";\nimport type { Manifest, PublicManifest } from \"./types\";\n\nexport interface FetchManifestOptions {\n /** Xenia engine base URL. Default the hosted engine. */\n baseUrl?: string;\n /** A server-type SDK token. */\n token: string;\n /** Default 5000 ms. */\n timeoutMs?: number;\n fetch?: typeof fetch;\n /** Extra fetch options, e.g. Next.js `{ next: { revalidate } }`. Their headers are kept. */\n init?: RequestInit;\n}\n\n/** Xenia's manifest (`GET /api/personalization/edge/manifest`). Throws on a non-2xx answer. */\nexport async function fetchManifest(opts: FetchManifestOptions): Promise<Manifest> {\n const base = (opts.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n const headers = new Headers(opts.init?.headers);\n headers.set(\"Authorization\", `Bearer ${opts.token}`);\n const res = await (opts.fetch ?? fetch)(`${base}/api/personalization/edge/manifest`, {\n ...opts.init,\n headers,\n signal: AbortSignal.timeout(opts.timeoutMs ?? 5_000),\n });\n if (!res.ok) throw new Error(`[xenia] manifest ${res.status}`);\n return (await res.json()) as Manifest;\n}\n\n/**\n * The manifest as a storefront may serve it publicly (e.g. from a CDN): the version and the page\n * patterns any live journey targets — no content keys, modes or rules. A proxy reading it decides by\n * path, and Xenia picks the content keys itself.\n */\nexport function trimManifest(m: Manifest): PublicManifest {\n const pages = new Set<string>();\n for (const k of m.keys ?? []) if (k.mode !== \"off\") for (const p of k.pages ?? []) pages.add(p);\n return { version: m.version, pages: [...pages].sort() };\n}\n"]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkUUIKUU5W_cjs = require('./chunk-UUIKUU5W.cjs');
|
|
4
|
+
var chunkGXJLU3RE_cjs = require('./chunk-GXJLU3RE.cjs');
|
|
5
5
|
|
|
6
6
|
// src/edge/consent.ts
|
|
7
7
|
function edgeConsent(headers, opts = {}) {
|
|
8
|
-
const raw =
|
|
8
|
+
const raw = chunkUUIKUU5W_cjs.parseCookies(headers.get("cookie"))[chunkGXJLU3RE_cjs.consentCookieName(opts.prefix)];
|
|
9
9
|
let consent = { personalization: true, analytics: true };
|
|
10
10
|
if (raw) {
|
|
11
11
|
try {
|
|
@@ -211,7 +211,7 @@ function localTime(geo, now) {
|
|
|
211
211
|
// src/edge/trail.ts
|
|
212
212
|
var MAX_TRAIL = 8;
|
|
213
213
|
var TRAIL_MAX_AGE_S = 30 * 60;
|
|
214
|
-
function trailCookieName(prefix =
|
|
214
|
+
function trailCookieName(prefix = chunkGXJLU3RE_cjs.DEFAULT_PREFIX) {
|
|
215
215
|
return `${prefix}_trail`;
|
|
216
216
|
}
|
|
217
217
|
var decode = (v) => {
|
|
@@ -296,13 +296,42 @@ function swapGroups(decisions) {
|
|
|
296
296
|
}
|
|
297
297
|
return [...byBase.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([base, swaps]) => ({ base, swaps: [...swaps.values()].sort(([a], [b]) => a.localeCompare(b)) }));
|
|
298
298
|
}
|
|
299
|
-
async function
|
|
299
|
+
async function deflate(text) {
|
|
300
|
+
const stream = new Response(text).body.pipeThrough(new CompressionStream("deflate-raw"));
|
|
301
|
+
return new Uint8Array(await new Response(stream).arrayBuffer());
|
|
302
|
+
}
|
|
303
|
+
async function inflate(bytes) {
|
|
304
|
+
const stream = new Response(bytes).body.pipeThrough(new DecompressionStream("deflate-raw"));
|
|
305
|
+
return new Response(stream).text();
|
|
306
|
+
}
|
|
307
|
+
async function encodeVariant(groups, secret, extra, entries) {
|
|
300
308
|
const g = groups.map((x) => [x.base, x.swaps]);
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
|
|
309
|
+
const ez = entries?.length ? b64url(await deflate(JSON.stringify(entries))) : void 0;
|
|
310
|
+
const payloadOf = (x, withEntries) => b64url(
|
|
311
|
+
enc2.encode(
|
|
312
|
+
JSON.stringify({
|
|
313
|
+
g,
|
|
314
|
+
...ez ? withEntries ? { ez } : { ed: entries.length } : {},
|
|
315
|
+
...x === void 0 ? {} : { x }
|
|
316
|
+
})
|
|
317
|
+
)
|
|
318
|
+
);
|
|
319
|
+
let payload = payloadOf(extra, true);
|
|
320
|
+
if (payload.length > MAX_PAYLOAD && extra !== void 0) payload = payloadOf(void 0, true);
|
|
321
|
+
if (payload.length > MAX_PAYLOAD && ez) payload = payloadOf(void 0, false);
|
|
304
322
|
return `${payload}.${await sign(secret, payload)}`;
|
|
305
323
|
}
|
|
324
|
+
function variantEntries(decisions, entryDecisions) {
|
|
325
|
+
if (!entryDecisions) return [];
|
|
326
|
+
return decisions.filter((d) => d.personalized).flatMap((d) => entryDecisions[d.contentKey] ?? []);
|
|
327
|
+
}
|
|
328
|
+
function variantEntryResolver(entries, contentKey) {
|
|
329
|
+
const mine = (entries ?? []).filter((d) => d.contentKey === contentKey);
|
|
330
|
+
return async (ids) => {
|
|
331
|
+
const wanted = new Set(ids);
|
|
332
|
+
return mine.filter((d) => wanted.has(d.target));
|
|
333
|
+
};
|
|
334
|
+
}
|
|
306
335
|
async function decodeVariant(token, secret) {
|
|
307
336
|
const [payload, mac, rest] = token.split(".");
|
|
308
337
|
if (!payload || !mac || rest !== void 0 || payload.length > MAX_PAYLOAD) return null;
|
|
@@ -310,7 +339,13 @@ async function decodeVariant(token, secret) {
|
|
|
310
339
|
try {
|
|
311
340
|
const raw = JSON.parse(new TextDecoder().decode(fromB64url(payload)));
|
|
312
341
|
const groups = raw.g.map(([base, swaps]) => ({ base, swaps }));
|
|
313
|
-
|
|
342
|
+
const entries = raw.ez ? JSON.parse(await inflate(fromB64url(raw.ez))) : void 0;
|
|
343
|
+
return {
|
|
344
|
+
groups,
|
|
345
|
+
...raw.x === void 0 ? {} : { extra: raw.x },
|
|
346
|
+
...Array.isArray(entries) ? { entries } : {},
|
|
347
|
+
...typeof raw.ed === "number" && raw.ed > 0 ? { entriesDropped: raw.ed } : {}
|
|
348
|
+
};
|
|
314
349
|
} catch {
|
|
315
350
|
return null;
|
|
316
351
|
}
|
|
@@ -318,7 +353,7 @@ async function decodeVariant(token, secret) {
|
|
|
318
353
|
|
|
319
354
|
// src/edge/manifest.ts
|
|
320
355
|
async function fetchManifest(opts) {
|
|
321
|
-
const base = (opts.baseUrl ??
|
|
356
|
+
const base = (opts.baseUrl ?? chunkGXJLU3RE_cjs.DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
322
357
|
const headers = new Headers(opts.init?.headers);
|
|
323
358
|
headers.set("Authorization", `Bearer ${opts.token}`);
|
|
324
359
|
const res = await (opts.fetch ?? fetch)(`${base}/api/personalization/edge/manifest`, {
|
|
@@ -353,8 +388,10 @@ exports.swapGroups = swapGroups;
|
|
|
353
388
|
exports.trailCookieName = trailCookieName;
|
|
354
389
|
exports.trailCookieValue = trailCookieValue;
|
|
355
390
|
exports.trimManifest = trimManifest;
|
|
391
|
+
exports.variantEntries = variantEntries;
|
|
392
|
+
exports.variantEntryResolver = variantEntryResolver;
|
|
356
393
|
exports.verifyWebhook = verifyWebhook;
|
|
357
394
|
exports.viewerGeo = viewerGeo;
|
|
358
395
|
exports.withView = withView;
|
|
359
|
-
//# sourceMappingURL=chunk-
|
|
360
|
-
//# sourceMappingURL=chunk-
|
|
396
|
+
//# sourceMappingURL=chunk-WMGCQPHY.cjs.map
|
|
397
|
+
//# sourceMappingURL=chunk-WMGCQPHY.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/edge/consent.ts","../src/edge/request-facts.ts","../src/edge/trail.ts","../src/edge/webhook.ts","../src/edge/variant.ts","../src/edge/manifest.ts"],"names":["parseCookies","consentCookieName","DEFAULT_PREFIX","enc","DEFAULT_BASE_URL"],"mappings":"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","file":"chunk-WMGCQPHY.cjs","sourcesContent":["import { consentCookieName } from \"../core/cookie-names\";\nimport { parseCookies } from \"../server/cookies\";\n\nexport interface EdgeConsent {\n /** Off: don't ask Xenia, serve base content. */\n personalization: boolean;\n /** Off: decide, but keep no trail or click cookies and send no trail. */\n analytics: boolean;\n}\n\n/**\n * What the edge flow may do for this request, from the consent cookie the browser client's\n * `consent()` writes and the visitor's privacy signals:\n * - no consent cookie (or an unreadable one) → no choice made: everything on, as before;\n * - an explicit choice → followed (JSON `{analytics, personalization}`, or the scopes form\n * `analytics,personalization` where an unlisted scope is refused);\n * - `Sec-GPC: 1` / `DNT: 1` → analytics off, like the browser client's `respectDnt` (default on).\n *\n * Unlike `getConsent()`, an absent cookie isn't \"all denied\": the edge can't tell a visitor who\n * refused from one who was never asked, and refusing both would change every first page view.\n */\nexport function edgeConsent(headers: Headers, opts: { prefix?: string; respectDnt?: boolean } = {}): EdgeConsent {\n const raw = parseCookies(headers.get(\"cookie\"))[consentCookieName(opts.prefix)];\n let consent: EdgeConsent = { personalization: true, analytics: true };\n if (raw) {\n try {\n const parsed: unknown = JSON.parse(raw);\n if (parsed && typeof parsed === \"object\") {\n const p = parsed as Record<string, unknown>;\n consent = { personalization: p.personalization !== false, analytics: p.analytics !== false };\n }\n } catch {\n if (/^[a-z]+(\\s*,\\s*[a-z]+)*$/i.test(raw.trim())) {\n const scopes = new Set(raw.split(\",\").map((s) => s.trim()));\n consent = { personalization: scopes.has(\"personalization\"), analytics: scopes.has(\"analytics\") };\n }\n }\n }\n const privacySignal = headers.get(\"sec-gpc\") === \"1\" || headers.get(\"dnt\") === \"1\";\n if (opts.respectDnt !== false && privacySignal) consent = { ...consent, analytics: false };\n return consent;\n}\n","/**\n * Facts about a request that journey rules read — where the visitor is, on what device, where they\n * came from, their local time — derived from a standard `Request` in any runtime.\n */\nimport type { ViewerGeo } from \"./types\";\n\nconst GEO_KEYS = [\n \"country\",\n \"countryName\",\n \"region\",\n \"regionName\",\n \"city\",\n \"postalCode\",\n \"timeZone\",\n \"latitude\",\n \"longitude\",\n \"source\",\n] as const;\n\n/** Any host's geo object (Netlify, Next.js runtimes, our own edge function). */\ntype GeoLike = {\n country?: string | { code?: string; name?: string };\n countryName?: string;\n region?: string;\n subdivision?: { code?: string; name?: string };\n regionName?: string;\n city?: string;\n postalCode?: string;\n timeZone?: string;\n timezone?: string;\n latitude?: string | number;\n longitude?: string | number;\n};\n\n/** Normalizes any host's geo object into Xenia's `ViewerGeo` keys (values over 100 chars dropped). */\nfunction toViewerGeo(g: GeoLike | undefined, source: string): ViewerGeo | undefined {\n if (!g) return undefined;\n const country = typeof g.country === \"string\" ? g.country : g.country?.code;\n if (!country) return undefined;\n const raw: Record<string, unknown> = {\n country: country.toUpperCase(),\n countryName: g.countryName ?? (typeof g.country === \"object\" ? g.country?.name : undefined),\n region: g.region ?? g.subdivision?.code,\n regionName: g.regionName ?? g.subdivision?.name,\n city: g.city,\n postalCode: g.postalCode,\n timeZone: g.timeZone ?? g.timezone,\n latitude: g.latitude?.toString(),\n longitude: g.longitude?.toString(),\n source,\n };\n const geo: ViewerGeo = {};\n for (const k of GEO_KEYS) {\n const v = raw[k];\n if (typeof v === \"string\" && v && v.length <= 100) geo[k] = v;\n }\n return geo;\n}\n\nconst parseJson = (text: string): GeoLike | undefined => {\n try {\n return JSON.parse(text) as GeoLike;\n } catch {\n return undefined;\n }\n};\n\nfunction safeDecode(v: string): string {\n try {\n return decodeURIComponent(v);\n } catch {\n return v;\n }\n}\n\nfunction safeBase64(v: string): string {\n try {\n return atob(v);\n } catch {\n return \"\";\n }\n}\n\n/** Netlify's per-request context, when running in Netlify's runtime. */\nfunction netlifyContext(): { geo?: GeoLike } | undefined {\n try {\n return (globalThis as unknown as { Netlify?: { context?: { geo?: GeoLike } | null } }).Netlify?.context ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nconst COUNTRY_HEADERS = [\"x-country\", \"x-vercel-ip-country\", \"cloudfront-viewer-country\", \"cf-ipcountry\"];\n\n/** The location headers `viewerGeo` can read, when trusted. */\nexport type GeoHeader = \"x-xn-geo\" | \"x-nf-geo\" | \"x-country\" | \"x-vercel-ip-country\" | \"cloudfront-viewer-country\" | \"cf-ipcountry\";\n\nfunction companions(h: Headers, country: string): GeoLike {\n const of = (name: string) => h.get(name) ?? undefined;\n if (country === \"x-vercel-ip-country\") {\n return { region: of(\"x-vercel-ip-country-region\"), city: safeDecode(of(\"x-vercel-ip-city\") ?? \"\") || undefined, timeZone: of(\"x-vercel-ip-timezone\") };\n }\n if (country === \"cloudfront-viewer-country\") {\n return { region: of(\"cloudfront-viewer-country-region\"), city: safeDecode(of(\"cloudfront-viewer-city\") ?? \"\") || undefined, timeZone: of(\"cloudfront-viewer-time-zone\") };\n }\n return {};\n}\n\n/**\n * The visitor's location as the hosting edge resolved it, and which source supplied it (`via`).\n * Geo must come from the storefront's edge, never Xenia's: `/decide` is server to server. Tried in\n * order — whichever the host provides:\n * 1. Netlify's per-request `Netlify.context.geo` (can't be spoofed by the client, unlike a header)\n * 2. `x-xn-geo` (URI-encoded JSON) from the site's own edge function\n * 3. a `request.geo` some runtimes attach\n * 4. Netlify's `x-nf-geo` header (base64 or URI-encoded JSON)\n * 5. `x-country` (Netlify), `x-vercel-ip-*`, `cloudfront-viewer-*`, `cf-ipcountry`\n * 6. `?xn_country=GB` — only with `devOverride`, for testing geo rules without an edge\n *\n * Headers (2, 4 and 5) are read only when named in `trust`: a visitor can send any header, and only\n * the site knows which ones its own host or edge function sets (and overwrites). Name exactly those,\n * e.g. `[\"x-vercel-ip-country\"]` on Vercel, `[\"cf-ipcountry\"]` behind Cloudflare,\n * `[\"x-nf-geo\", \"x-country\"]` on Netlify. 1 and 3 come from the runtime and are always used.\n */\nexport function viewerGeo(\n request: Request,\n opts: { devOverride?: boolean; trust?: readonly GeoHeader[] } = {},\n): { geo?: ViewerGeo; via: string } {\n const trusted = new Set<string>(opts.trust ?? []);\n const fromNetlify = toViewerGeo(netlifyContext()?.geo, \"edge\");\n if (fromNetlify) return { geo: fromNetlify, via: \"Netlify.context\" };\n\n const h = { get: (name: string) => (trusted.has(name) ? request.headers.get(name) : null) };\n const xn = h.get(\"x-xn-geo\");\n const fromXn = xn ? toViewerGeo(parseJson(safeDecode(xn)), \"edge\") : undefined;\n if (fromXn) return { geo: fromXn, via: \"x-xn-geo (edge function)\" };\n\n const fromRuntime = toViewerGeo((request as unknown as { geo?: GeoLike }).geo, \"edge\");\n if (fromRuntime) return { geo: fromRuntime, via: \"request.geo\" };\n\n const nf = h.get(\"x-nf-geo\");\n if (nf) {\n const fromNf = toViewerGeo(parseJson(safeBase64(nf)) ?? parseJson(safeDecode(nf)), \"edge\");\n if (fromNf) return { geo: fromNf, via: \"x-nf-geo\" };\n }\n\n const via = COUNTRY_HEADERS.find((n) => h.get(n));\n const headerCountry = via ? h.get(via) : null;\n if (via && headerCountry && /^[a-z]{2}$/i.test(headerCountry)) {\n const geo = toViewerGeo(\n {\n country: headerCountry,\n // The region, city and time zone of the same provider as the country header.\n ...companions(request.headers, via),\n },\n \"edge\",\n );\n return { geo, via };\n }\n\n const override = new URL(request.url).searchParams.get(\"xn_country\");\n if (opts.devOverride && override && /^[a-z]{2}$/i.test(override)) {\n return { geo: { country: override.toUpperCase(), source: \"dev\" }, via: \"?xn_country (dev)\" };\n }\n return { via: \"none\" };\n}\n\nexport function deviceOf(headers: Headers): \"mobile\" | \"tablet\" | \"desktop\" {\n const ua = headers.get(\"user-agent\") ?? \"\";\n if (/iPad|Tablet/i.test(ua)) return \"tablet\";\n if (headers.get(\"sec-ch-ua-mobile\") === \"?1\" || /Mobi|Android|iPhone/i.test(ua)) return \"mobile\";\n return \"desktop\";\n}\n\nconst BOT = /bot|crawl|spider|slurp|facebookexternalhit|embedly|preview|whatsapp|bingpreview/i;\n\n/** Crawlers and link-preview fetchers: never decided, never recorded. */\nexport function isBot(userAgent: string | null | undefined): boolean {\n return BOT.test(userAgent ?? \"\");\n}\n\n/** Link prefetches pass through a proxy too; they aren't page views. */\nexport function isPrefetch(headers: Headers): boolean {\n return (\n headers.has(\"next-router-prefetch\") ||\n /prefetch/i.test(headers.get(\"purpose\") ?? \"\") ||\n /prefetch/i.test(headers.get(\"sec-purpose\") ?? \"\")\n );\n}\n\n/**\n * Whether this is the browser loading a page (a full page load), by `Sec-Fetch-Dest`. Requests\n * without it (old browsers, curl) count as page loads.\n */\nexport function isPageLoad(headers: Headers): boolean {\n return (headers.get(\"sec-fetch-dest\") ?? \"document\") === \"document\" && !isPrefetch(headers);\n}\n\nconst UTM: Record<string, string> = {\n utm_source: \"utmSource\",\n utm_medium: \"utmMedium\",\n utm_campaign: \"utmCampaign\",\n utm_content: \"utmContent\",\n utm_term: \"utmTerm\",\n utm_id: \"utmId\",\n};\n\n/**\n * This session's landing context — first-touch attribution, so a campaign carries across pages:\n * the UTMs (≤200 chars each) and an external referrer (≤500), refreshed when the visitor arrives\n * from a new campaign. `saved` is the value kept from earlier (a cookie); `changed` says to save it.\n */\nexport function landingContext(\n url: URL,\n referrer: string | null | undefined,\n saved: string | undefined,\n): { ctx: Record<string, string>; changed: boolean } {\n const fromQuery: Record<string, string> = {};\n for (const [param, fact] of Object.entries(UTM)) {\n const v = url.searchParams.get(param);\n if (v) fromQuery[fact] = v.slice(0, 200);\n }\n const external = referrer && !referrer.startsWith(url.origin) ? referrer.slice(0, 500) : null;\n\n let kept: Record<string, string> | null;\n try {\n const parsed: unknown = saved ? JSON.parse(saved) : null;\n kept = parsed && typeof parsed === \"object\" && !Array.isArray(parsed) ? (parsed as Record<string, string>) : null;\n } catch {\n kept = null;\n }\n if (kept && !Object.keys(fromQuery).length) return { ctx: kept, changed: false };\n return { ctx: { ...fromQuery, ...(external ? { referrer: external } : {}) }, changed: true };\n}\n\nconst WEEKDAYS = [\"sunday\", \"monday\", \"tuesday\", \"wednesday\", \"thursday\", \"friday\", \"saturday\"];\n\n/** Meteorological seasons: Dec–Feb winter, Mar–May spring, Jun–Aug summer, Sep–Nov fall. */\nexport function seasonOf(month: number, southernHemisphere = false): string {\n const north = [\"winter\", \"winter\", \"spring\", \"spring\", \"spring\", \"summer\", \"summer\", \"summer\", \"fall\", \"fall\", \"fall\", \"winter\"];\n const season = north[(month - 1 + 12) % 12];\n if (!southernHemisphere) return season;\n return ({ winter: \"summer\", summer: \"winter\", spring: \"fall\", fall: \"spring\" } as Record<string, string>)[season] ?? season;\n}\n\nfunction validTimeZone(tz: string | undefined): string | undefined {\n if (!tz) return undefined;\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: tz });\n return tz;\n } catch {\n return undefined;\n }\n}\n\nexport interface LocalTime {\n local_weekday: string;\n local_month: number;\n local_hour: number;\n is_weekend: boolean;\n season: string;\n}\n\n/** Weekday, month, hour and season where the visitor is (their time zone; UTC when unknown). */\nexport function localTime(geo: ViewerGeo | undefined, now: Date): LocalTime {\n const timeZone = validTimeZone(geo?.timeZone) ?? \"UTC\";\n const parts = Object.fromEntries(\n new Intl.DateTimeFormat(\"en-US\", { timeZone, weekday: \"long\", month: \"numeric\", hour: \"numeric\", hourCycle: \"h23\" })\n .formatToParts(now)\n .map((p) => [p.type, p.value]),\n );\n const weekday = String(parts.weekday ?? WEEKDAYS[now.getUTCDay()]).toLowerCase();\n const month = Number(parts.month) || now.getUTCMonth() + 1;\n return {\n local_weekday: weekday,\n local_month: month,\n local_hour: Number(parts.hour) % 24,\n is_weekend: weekday === \"saturday\" || weekday === \"sunday\",\n season: seasonOf(month, Number(geo?.latitude) < 0),\n };\n}\n","/**\n * The visitor's recent page views, most recent first, kept in a short-lived first-party cookie\n * (`[[path, at], [path, at, seconds], …]`). The proxy sends it with `/decide`, so profile rules see\n * pages whose analytics events haven't been processed yet; the browser adds client-side navigations\n * and the time spent on a page as the visitor leaves it. Shared by both sides.\n */\nimport { DEFAULT_PREFIX } from \"../core/cookie-names\";\nimport type { TrailView } from \"./types\";\n\nexport const MAX_TRAIL = 8;\n/** Cookie lifetime: a visit ends after 30 idle minutes, like the SDK's session. */\nexport const TRAIL_MAX_AGE_S = 30 * 60;\n\nexport function trailCookieName(prefix: string = DEFAULT_PREFIX): string {\n return `${prefix}_trail`;\n}\n\nconst decode = (v: string) => {\n try {\n return decodeURIComponent(v);\n } catch {\n return v;\n }\n};\n\n/** The trail in a cookie value (raw or URI-encoded); anything malformed reads as no trail. */\nexport function readTrail(value: string | undefined | null): TrailView[] {\n if (!value) return [];\n try {\n const parsed: unknown = JSON.parse(decode(value));\n if (!Array.isArray(parsed)) return [];\n return parsed\n .filter((t): t is [string, number, number?] => Array.isArray(t) && typeof t[0] === \"string\" && typeof t[1] === \"number\")\n .slice(0, MAX_TRAIL)\n .map(([path, at, seconds]) =>\n typeof seconds === \"number\" && seconds >= 0 && seconds <= 86_400 ? { path, at, seconds } : { path, at },\n );\n } catch {\n return [];\n }\n}\n\n/**\n * The trail with this view first: a revisit moves to the front and keeps its first time (its old\n * time on page is dropped — this view's isn't known yet). The same array when `path` is already first.\n */\nexport function withView(trail: TrailView[], path: string, now: number = Date.now()): TrailView[] {\n if (trail[0]?.path === path) return trail;\n const earlier = trail.find((t) => t.path === path);\n return [{ path, at: earlier?.at ?? now }, ...trail.filter((t) => t.path !== path)].slice(0, MAX_TRAIL);\n}\n\n/** The cookie value for a trail (not URI-encoded; cookie setters encode it). */\nexport function trailCookieValue(trail: TrailView[]): string {\n return JSON.stringify(\n trail.slice(0, MAX_TRAIL).map((t) => (t.seconds === undefined ? [t.path, t.at] : [t.path, t.at, t.seconds])),\n );\n}\n","const enc = new TextEncoder();\n\nasync function hmacHex(secret: string, payload: string): Promise<string> {\n const key = await crypto.subtle.importKey(\"raw\", enc.encode(secret), { name: \"HMAC\", hash: \"SHA-256\" }, false, [\"sign\"]);\n const mac = new Uint8Array(await crypto.subtle.sign(\"HMAC\", key, enc.encode(payload)));\n return Array.from(mac, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\n/** Constant-time comparison, so a signature can't be guessed byte by byte. */\nexport function sameString(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a.charCodeAt(i) ^ b.charCodeAt(i);\n return diff === 0;\n}\n\n/**\n * Whether a storefront webhook from Xenia is genuine and fresh:\n * `X-Xenia-Signature: t=<unix s>,v1=<hex HMAC-SHA256(secret, \"<t>.<body>\")>`. Requests older than\n * `toleranceS` are refused, so a captured request can't be replayed. Pass the raw body text.\n */\nexport async function verifyWebhook(\n input: { headers: Headers; body: string },\n secret: string,\n toleranceS = 300,\n): Promise<boolean> {\n const header = input.headers.get(\"x-xenia-signature\") ?? \"\";\n if (!secret || !header) return false;\n const parts = Object.fromEntries(header.split(\",\").map((p) => p.trim().split(\"=\", 2)));\n const t = Number(parts.t);\n if (!Number.isFinite(t) || Math.abs(Date.now() / 1000 - t) > toleranceS || !parts.v1) return false;\n return sameString(await hmacHex(secret, `${parts.t}.${input.body}`), String(parts.v1).toLowerCase());\n}\n","/**\n * The proxy hands a decision to the page as a signed token in the rewritten URL\n * (`/xv/<token>/women`). The token is just the swaps — identical for every visitor in the same\n * variant — so each variant renders once and is then served from the ISR/CDN cache like any static\n * page. A site may carry its own data along (`extra`), e.g. what the page fills itself from.\n *\n * Signed (HMAC-SHA256) so nobody can craft a URL that renders arbitrary entries. Web Crypto only, so\n * it runs in any runtime.\n */\nimport type { EntryDecision } from \"../core/types\";\nimport type { EdgeDecision } from \"./types\";\nimport { sameString } from \"./webhook\";\n\n/**\n * One swap: the base entry's field, the entry shown in its place, and the content key whose\n * decision it is — so the page can report impressions and clicks per journey and entry.\n */\nexport type VariantSwap = [identifier: string, replacementEntryId: string, contentKey?: string];\n\n/** Swaps for one base entry. */\nexport interface SwapGroup {\n base: string;\n swaps: VariantSwap[];\n}\n\n/** The longest payload `decodeVariant` accepts. */\nconst MAX_PAYLOAD = 4096;\n\nconst enc = new TextEncoder();\n\nconst b64url = (bytes: Uint8Array) =>\n btoa(String.fromCharCode(...bytes))\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n\nconst fromB64url = (s: string) =>\n Uint8Array.from(atob(s.replace(/-/g, \"+\").replace(/_/g, \"/\")), (c) => c.charCodeAt(0));\n\nconst keys = new Map<string, Promise<CryptoKey>>();\nconst keyFor = (secret: string) => {\n let key = keys.get(secret);\n if (!key) {\n key = crypto.subtle.importKey(\"raw\", enc.encode(secret), { name: \"HMAC\", hash: \"SHA-256\" }, false, [\"sign\"]);\n keys.set(secret, key);\n }\n return key;\n};\n\nasync function sign(secret: string, payload: string): Promise<string> {\n const mac = await crypto.subtle.sign(\"HMAC\", await keyFor(secret), enc.encode(payload));\n return b64url(new Uint8Array(mac).slice(0, 16));\n}\n\n/** The swap groups of the personalized decisions, in a stable order (stable cache keys). */\nexport function swapGroups(decisions: EdgeDecision[]): SwapGroup[] {\n const byBase = new Map<string, Map<string, VariantSwap>>();\n for (const d of decisions) {\n if (!d.personalized || !d.baseEntryId) continue;\n for (const s of d.swaps) {\n if (!s.identifier || !s.replacementEntryId) continue;\n if (!byBase.has(d.baseEntryId)) byBase.set(d.baseEntryId, new Map());\n byBase.get(d.baseEntryId)!.set(s.identifier, [s.identifier, s.replacementEntryId, d.contentKey]);\n }\n }\n return [...byBase.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([base, swaps]) => ({ base, swaps: [...swaps.values()].sort(([a], [b]) => a.localeCompare(b)) }));\n}\n\n/** Deflate (raw) with the platform's CompressionStream — Node 18+, browsers and edge runtimes. */\nasync function deflate(text: string): Promise<Uint8Array> {\n const stream = new Response(text).body!.pipeThrough(new CompressionStream(\"deflate-raw\"));\n return new Uint8Array(await new Response(stream).arrayBuffer());\n}\n\nasync function inflate(bytes: Uint8Array): Promise<string> {\n const stream = new Response(bytes as BodyInit).body!.pipeThrough(new DecompressionStream(\"deflate-raw\"));\n return new Response(stream).text();\n}\n\n/**\n * The token for a variant. `entries` are the multi-level entry decisions of its personalized keys\n * (`DecideOutcome.entryDecisions`), so the page resolves nested CMS targets without calling Xenia.\n * They travel compressed (`ez`), which fits several times as many decisions.\n *\n * Whatever would still push it past the payload limit is left out — first `extra`, then `entries`\n * (counted in `ed`: the page serves those targets' base content and reports itself incomplete) —\n * rather than making a token no page accepts.\n */\nexport async function encodeVariant(\n groups: SwapGroup[],\n secret: string,\n extra?: unknown,\n entries?: EntryDecision[],\n): Promise<string> {\n const g = groups.map((x) => [x.base, x.swaps]);\n const ez = entries?.length ? b64url(await deflate(JSON.stringify(entries))) : undefined;\n const payloadOf = (x: unknown, withEntries: boolean) =>\n b64url(\n enc.encode(\n JSON.stringify({\n g,\n ...(ez ? (withEntries ? { ez } : { ed: entries!.length }) : {}),\n ...(x === undefined ? {} : { x }),\n }),\n ),\n );\n let payload = payloadOf(extra, true);\n if (payload.length > MAX_PAYLOAD && extra !== undefined) payload = payloadOf(undefined, true);\n if (payload.length > MAX_PAYLOAD && ez) payload = payloadOf(undefined, false);\n return `${payload}.${await sign(secret, payload)}`;\n}\n\n/**\n * The multi-level entry decisions of the personalized `decisions` — what {@link encodeVariant}\n * carries as `entries`.\n */\nexport function variantEntries(\n decisions: EdgeDecision[],\n entryDecisions: Record<string, EntryDecision[]> | undefined,\n): EntryDecision[] {\n if (!entryDecisions) return [];\n return decisions.filter((d) => d.personalized).flatMap((d) => entryDecisions[d.contentKey] ?? []);\n}\n\n/**\n * A page resolver (`personalizeContent({ resolve })`) that answers from a variant token's entries:\n * every level of the page's content key decided up front at the edge, so no Xenia call.\n */\nexport function variantEntryResolver(entries: EntryDecision[] | undefined, contentKey: string) {\n const mine = (entries ?? []).filter((d) => d.contentKey === contentKey);\n return async (ids: string[]): Promise<EntryDecision[]> => {\n const wanted = new Set(ids);\n return mine.filter((d) => wanted.has(d.target));\n };\n}\n\n/**\n * A decoded variant token. `entriesDropped` counts multi-level decisions that didn't fit in the\n * token: their targets show base content.\n */\nexport interface DecodedVariant<E = unknown> {\n groups: SwapGroup[];\n extra?: E;\n entries?: EntryDecision[];\n entriesDropped?: number;\n}\n\n/** The variant in a token, or `null` if it is malformed or not signed with `secret`. */\nexport async function decodeVariant<E = unknown>(token: string, secret: string): Promise<DecodedVariant<E> | null> {\n const [payload, mac, rest] = token.split(\".\");\n if (!payload || !mac || rest !== undefined || payload.length > MAX_PAYLOAD) return null;\n if (!sameString(await sign(secret, payload), mac)) return null;\n try {\n const raw = JSON.parse(new TextDecoder().decode(fromB64url(payload))) as {\n g: [string, VariantSwap[]][];\n x?: E;\n ez?: string;\n ed?: number;\n };\n const groups = raw.g.map(([base, swaps]) => ({ base, swaps }));\n const entries = raw.ez ? (JSON.parse(await inflate(fromB64url(raw.ez))) as EntryDecision[]) : undefined;\n return {\n groups,\n ...(raw.x === undefined ? {} : { extra: raw.x }),\n ...(Array.isArray(entries) ? { entries } : {}),\n ...(typeof raw.ed === \"number\" && raw.ed > 0 ? { entriesDropped: raw.ed } : {}),\n };\n } catch {\n return null;\n }\n}\n","import { DEFAULT_BASE_URL } from \"../core/http-client\";\nimport type { Manifest, PublicManifest } from \"./types\";\n\nexport interface FetchManifestOptions {\n /** Xenia engine base URL. Default the hosted engine. */\n baseUrl?: string;\n /** A server-type SDK token. */\n token: string;\n /** Default 5000 ms. */\n timeoutMs?: number;\n fetch?: typeof fetch;\n /** Extra fetch options, e.g. Next.js `{ next: { revalidate } }`. Their headers are kept. */\n init?: RequestInit;\n}\n\n/** Xenia's manifest (`GET /api/personalization/edge/manifest`). Throws on a non-2xx answer. */\nexport async function fetchManifest(opts: FetchManifestOptions): Promise<Manifest> {\n const base = (opts.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n const headers = new Headers(opts.init?.headers);\n headers.set(\"Authorization\", `Bearer ${opts.token}`);\n const res = await (opts.fetch ?? fetch)(`${base}/api/personalization/edge/manifest`, {\n ...opts.init,\n headers,\n signal: AbortSignal.timeout(opts.timeoutMs ?? 5_000),\n });\n if (!res.ok) throw new Error(`[xenia] manifest ${res.status}`);\n return (await res.json()) as Manifest;\n}\n\n/**\n * The manifest as a storefront may serve it publicly (e.g. from a CDN): the version and the page\n * patterns any live journey targets — no content keys, modes or rules. A proxy reading it decides by\n * path, and Xenia picks the content keys itself.\n */\nexport function trimManifest(m: Manifest): PublicManifest {\n const pages = new Set<string>();\n for (const k of m.keys ?? []) if (k.mode !== \"off\") for (const p of k.pages ?? []) pages.add(p);\n return { version: m.version, pages: [...pages].sort() };\n}\n"]}
|
package/dist/client/index.cjs
CHANGED
|
@@ -715,7 +715,7 @@ async function personalizeContent(payload, options) {
|
|
|
715
715
|
const next = apply(target, op, d.decision.field ?? target.marker.field, items, cms);
|
|
716
716
|
report({
|
|
717
717
|
target: target.id,
|
|
718
|
-
kind: "runtime",
|
|
718
|
+
kind: target.local ? "static" : "runtime",
|
|
719
719
|
op,
|
|
720
720
|
entryIds: items.map((e) => cms.entryId(e)).filter((id) => !!id),
|
|
721
721
|
contentKey: d.decision.contentKey,
|
|
@@ -725,20 +725,23 @@ async function personalizeContent(payload, options) {
|
|
|
725
725
|
return next;
|
|
726
726
|
};
|
|
727
727
|
for (let round = 0; ; round++) {
|
|
728
|
-
const pending = walk(frontier, cms, settled, round, report, (t) => {
|
|
728
|
+
const pending = walk(frontier, cms, settled, round, report, options.contentKey, (t) => {
|
|
729
729
|
const d = decided.get(t.id);
|
|
730
730
|
return d ? settle(t, d, round) : void 0;
|
|
731
731
|
});
|
|
732
732
|
if (pending.size === 0) return { content: box.root, applied, complete: true };
|
|
733
|
-
|
|
734
|
-
|
|
733
|
+
const remote = [...pending.values()].filter((p) => !p.local).map((p) => p.id);
|
|
734
|
+
const local = [...pending.values()].flatMap((p) => p.local ? [p.local] : []);
|
|
735
|
+
if (!options.resolve && local.length === 0 || round >= maxRounds) {
|
|
736
|
+
return { content: box.root, applied, complete: !options.resolve && round < maxRounds };
|
|
735
737
|
}
|
|
736
738
|
progress(options, { content: box.root, round, pending: [...pending.keys()] });
|
|
737
739
|
let decisions;
|
|
738
740
|
let entriesById;
|
|
739
741
|
let queried;
|
|
740
742
|
try {
|
|
741
|
-
decisions = await withDeadline(options.resolve(
|
|
743
|
+
decisions = options.resolve && remote.length > 0 ? await withDeadline(options.resolve(remote), deadline) : [];
|
|
744
|
+
decisions = [...decisions, ...local];
|
|
742
745
|
({ entriesById, queried } = await withDeadline(loadReplacements(decisions, cms, options.locale), deadline));
|
|
743
746
|
} catch (error) {
|
|
744
747
|
return { content: box.root, applied, complete: false, error: error === TIMEOUT ? void 0 : error };
|
|
@@ -761,7 +764,7 @@ function progress(options, p) {
|
|
|
761
764
|
} catch {
|
|
762
765
|
}
|
|
763
766
|
}
|
|
764
|
-
function walk(frontier, cms, settled, round, report, reuse) {
|
|
767
|
+
function walk(frontier, cms, settled, round, report, contentKey, reuse) {
|
|
765
768
|
const pending = /* @__PURE__ */ new Map();
|
|
766
769
|
const seen = /* @__PURE__ */ new WeakSet();
|
|
767
770
|
const deferred = /* @__PURE__ */ new WeakSet();
|
|
@@ -772,7 +775,8 @@ function walk(frontier, cms, settled, round, report, reuse) {
|
|
|
772
775
|
if (!value || typeof value !== "object" || deferred.has(value)) continue;
|
|
773
776
|
const id = settled.has(value) ? void 0 : cms.entryId(value);
|
|
774
777
|
const marker = id ? cms.marker(value) : null;
|
|
775
|
-
|
|
778
|
+
const local = id && marker?.kind === "static" && marker.ids?.length && cms.staticVariants(value).length === 0 ? localDecision(id, marker, contentKey) : void 0;
|
|
779
|
+
if (id && marker && (marker.kind === "runtime" || local)) {
|
|
776
780
|
const again = reuse({ id, marker, entry: value, slots: [slot] });
|
|
777
781
|
if (again) {
|
|
778
782
|
queue.push(...again);
|
|
@@ -782,7 +786,7 @@ function walk(frontier, cms, settled, round, report, reuse) {
|
|
|
782
786
|
if (existing) {
|
|
783
787
|
existing.slots.push(slot);
|
|
784
788
|
} else {
|
|
785
|
-
pending.set(id, { id, marker, entry: value, slots: [slot] });
|
|
789
|
+
pending.set(id, { id, marker, entry: value, slots: [slot], ...local ? { local } : {} });
|
|
786
790
|
if (marker.op === "items" && marker.field) {
|
|
787
791
|
const held = cms.getField(value, marker.field);
|
|
788
792
|
if (held && typeof held === "object") deferred.add(held);
|
|
@@ -816,6 +820,16 @@ function walk(frontier, cms, settled, round, report, reuse) {
|
|
|
816
820
|
}
|
|
817
821
|
return pending;
|
|
818
822
|
}
|
|
823
|
+
function localDecision(id, marker, contentKey) {
|
|
824
|
+
return {
|
|
825
|
+
target: id,
|
|
826
|
+
op: marker.op ?? "replace",
|
|
827
|
+
...marker.field ? { field: marker.field } : {},
|
|
828
|
+
ids: marker.ids,
|
|
829
|
+
...marker.ct ? { contentType: marker.ct } : {},
|
|
830
|
+
contentKey
|
|
831
|
+
};
|
|
832
|
+
}
|
|
819
833
|
function apply(target, op, field, items, cms) {
|
|
820
834
|
if (op === "items") {
|
|
821
835
|
if (field) {
|
|
@@ -854,9 +868,11 @@ function children(value) {
|
|
|
854
868
|
}
|
|
855
869
|
async function loadReplacements(decisions, cms, locale) {
|
|
856
870
|
const ids = [...new Set(decisions.flatMap((d) => d.ids ?? []))];
|
|
871
|
+
const types = {};
|
|
872
|
+
for (const d of decisions) if (d.contentType) for (const id of d.ids ?? []) types[id] = d.contentType;
|
|
857
873
|
const queries = decisions.filter((d) => !d.ids && d.query);
|
|
858
874
|
const [fetched, ...results] = await Promise.all([
|
|
859
|
-
ids.length > 0 ? cms.fetchEntries(ids, locale) : Promise.resolve([]),
|
|
875
|
+
ids.length > 0 ? cms.fetchEntries(ids, locale, types) : Promise.resolve([]),
|
|
860
876
|
...queries.map((d) => cms.queryEntries(d.query, locale).catch(() => []))
|
|
861
877
|
]);
|
|
862
878
|
const entriesById = /* @__PURE__ */ new Map();
|
|
@@ -887,7 +903,7 @@ function pendingTargets(payload, adapter, contentKey) {
|
|
|
887
903
|
content = cms.prepare ? cms.prepare(content) : content;
|
|
888
904
|
const root = { parent: { root: content }, key: "root", value: content };
|
|
889
905
|
return [...walk([root], cms, /* @__PURE__ */ new WeakSet(), 0, () => {
|
|
890
|
-
}, () => void 0).keys()];
|
|
906
|
+
}, contentKey, () => void 0).keys()];
|
|
891
907
|
} catch {
|
|
892
908
|
return [];
|
|
893
909
|
}
|