@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.
Files changed (96) hide show
  1. package/README.md +69 -5
  2. package/dist/{actions-35V37IT0.d.cts → actions--1_9Z8ig.d.cts} +13 -2
  3. package/dist/{actions-35V37IT0.d.ts → actions--1_9Z8ig.d.ts} +13 -2
  4. package/dist/{api-0IycTYJR.d.cts → api-DbUxT38T.d.ts} +1 -1
  5. package/dist/{api-COXWLL5L.d.ts → api-DgzJ5s-k.d.cts} +1 -1
  6. package/dist/chunk-DPXINHQR.cjs +34 -0
  7. package/dist/chunk-DPXINHQR.cjs.map +1 -0
  8. package/dist/chunk-FSJMHXS6.js +432 -0
  9. package/dist/chunk-FSJMHXS6.js.map +1 -0
  10. package/dist/chunk-GXJLU3RE.cjs +448 -0
  11. package/dist/chunk-GXJLU3RE.cjs.map +1 -0
  12. package/dist/{chunk-2DR5AVPX.cjs → chunk-I5EHLRSR.cjs} +11 -10
  13. package/dist/chunk-I5EHLRSR.cjs.map +1 -0
  14. package/dist/{chunk-LW5AEJ6K.js → chunk-MEULT5X6.js} +4 -241
  15. package/dist/chunk-MEULT5X6.js.map +1 -0
  16. package/dist/{chunk-GWRDZIVA.js → chunk-NDRRSRTU.js} +4 -3
  17. package/dist/chunk-NDRRSRTU.js.map +1 -0
  18. package/dist/chunk-RC46KXDM.js +32 -0
  19. package/dist/chunk-RC46KXDM.js.map +1 -0
  20. package/dist/{chunk-RWE2OCQL.cjs → chunk-SU25SELD.cjs} +4 -244
  21. package/dist/chunk-SU25SELD.cjs.map +1 -0
  22. package/dist/{chunk-WHGK55JP.cjs → chunk-UUIKUU5W.cjs} +5 -5
  23. package/dist/{chunk-WHGK55JP.cjs.map → chunk-UUIKUU5W.cjs.map} +1 -1
  24. package/dist/{chunk-QEYONKWY.js → chunk-UVTFGQR6.js} +3 -3
  25. package/dist/{chunk-QEYONKWY.js.map → chunk-UVTFGQR6.js.map} +1 -1
  26. package/dist/{chunk-F3WZFXYK.js → chunk-V4EGU3PM.js} +45 -10
  27. package/dist/chunk-V4EGU3PM.js.map +1 -0
  28. package/dist/{chunk-IOY6IPUW.cjs → chunk-WMGCQPHY.cjs} +49 -12
  29. package/dist/chunk-WMGCQPHY.cjs.map +1 -0
  30. package/dist/client/index.cjs +26 -10
  31. package/dist/client/index.cjs.map +1 -1
  32. package/dist/client/index.d.cts +2 -2
  33. package/dist/client/index.d.ts +2 -2
  34. package/dist/client/index.js +26 -10
  35. package/dist/client/index.js.map +1 -1
  36. package/dist/client/react/index.cjs +73 -15
  37. package/dist/client/react/index.cjs.map +1 -1
  38. package/dist/client/react/index.d.cts +9 -3
  39. package/dist/client/react/index.d.ts +9 -3
  40. package/dist/client/react/index.js +73 -15
  41. package/dist/client/react/index.js.map +1 -1
  42. package/dist/cms/contentful.cjs +7 -24
  43. package/dist/cms/contentful.cjs.map +1 -1
  44. package/dist/cms/contentful.d.cts +5 -4
  45. package/dist/cms/contentful.d.ts +5 -4
  46. package/dist/cms/contentful.js +4 -23
  47. package/dist/cms/contentful.js.map +1 -1
  48. package/dist/cms/contentstack.cjs +120 -0
  49. package/dist/cms/contentstack.cjs.map +1 -0
  50. package/dist/cms/contentstack.d.cts +41 -0
  51. package/dist/cms/contentstack.d.ts +41 -0
  52. package/dist/cms/contentstack.js +117 -0
  53. package/dist/cms/contentstack.js.map +1 -0
  54. package/dist/{consent-DRCV0N0d.d.ts → consent-Dtiqzz2B.d.cts} +71 -11
  55. package/dist/{consent-BgAETCkL.d.cts → consent-byYiDMFr.d.ts} +71 -11
  56. package/dist/{cookie-names-DU3MtcNG.d.ts → cookie-names-B4hda2rX.d.cts} +1 -1
  57. package/dist/{cookie-names-DFItnSLK.d.cts → cookie-names-DioZXuV0.d.ts} +1 -1
  58. package/dist/edge/index.cjs +122 -29
  59. package/dist/edge/index.cjs.map +1 -1
  60. package/dist/edge/index.d.cts +41 -5
  61. package/dist/edge/index.d.ts +41 -5
  62. package/dist/edge/index.js +92 -9
  63. package/dist/edge/index.js.map +1 -1
  64. package/dist/index.cjs +31 -31
  65. package/dist/index.d.cts +4 -5
  66. package/dist/index.d.ts +4 -5
  67. package/dist/index.js +2 -2
  68. package/dist/next/index.cjs +34 -33
  69. package/dist/next/index.cjs.map +1 -1
  70. package/dist/next/index.d.cts +2 -3
  71. package/dist/next/index.d.ts +2 -3
  72. package/dist/next/index.js +8 -7
  73. package/dist/next/index.js.map +1 -1
  74. package/dist/{types-DgVHS4Qw.d.ts → personalize-content-D6xeBI7-.d.cts} +150 -1
  75. package/dist/{types-DgVHS4Qw.d.cts → personalize-content-D6xeBI7-.d.ts} +150 -1
  76. package/dist/server/index.cjs +30 -30
  77. package/dist/server/index.d.cts +5 -6
  78. package/dist/server/index.d.ts +5 -6
  79. package/dist/server/index.js +5 -5
  80. package/dist/xenia-sdk.iife.js +3 -3
  81. package/dist/xenia-sdk.iife.js.map +1 -1
  82. package/dist/{xenia-server-Cf24mL0c.d.ts → xenia-server-BcgeUHX4.d.ts} +2 -3
  83. package/dist/{xenia-server-D-bx14lw.d.cts → xenia-server-lv6LtJZP.d.cts} +2 -3
  84. package/package.json +14 -1
  85. package/dist/chunk-2DR5AVPX.cjs.map +0 -1
  86. package/dist/chunk-BQ5PJCZ7.js +0 -179
  87. package/dist/chunk-BQ5PJCZ7.js.map +0 -1
  88. package/dist/chunk-F3WZFXYK.js.map +0 -1
  89. package/dist/chunk-GWRDZIVA.js.map +0 -1
  90. package/dist/chunk-IOY6IPUW.cjs.map +0 -1
  91. package/dist/chunk-LW5AEJ6K.js.map +0 -1
  92. package/dist/chunk-N5M4PI7C.cjs +0 -192
  93. package/dist/chunk-N5M4PI7C.cjs.map +0 -1
  94. package/dist/chunk-RWE2OCQL.cjs.map +0 -1
  95. package/dist/personalize-content-Cwc2AomC.d.ts +0 -141
  96. package/dist/personalize-content-CxSdplMV.d.cts +0 -141
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/next/shared.ts","../../src/edge/debug-entries.ts","../../src/next/edge-debug.ts","../../src/next/edge-proxy.ts","../../src/next/edge-routes.ts","../../src/next/index.ts"],"names":["headers","isPrefetch","NextResponse","isBot","DEFAULT_PREFIX","visitorCookieName","trailCookieName","landingContext","viewerGeo","generateUlid","deviceOf","readTrail","edgeConsent","isPageLoad","trailCookieValue","TRAIL_MAX_AGE_S","withView","localTime","swapGroups","encodeVariant","fetchManifest","trimManifest","verifyWebhook","revalidatePath","cookies","createXeniaServer","contextFromUrl","getConsent","React"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { VisitorCookieOptions } from \"../core/types\";\n\n/** Request header the proxy stamps with the URL being served (a Server Component can't see its own). */\nexport const URL_HEADER = \"x-xenia-url\";\n\n/** `NextResponse.cookies.set` attributes for the visitor cookie. Default: `path=/`, `SameSite=Lax`, one year. */\nexport function cookieAttributes(c: VisitorCookieOptions = {}) {\n const sameSite = c.sameSite ?? \"Lax\";\n return {\n path: \"/\",\n maxAge: Math.floor((c.maxAgeDays ?? 365) * 86400),\n sameSite: sameSite.toLowerCase() as \"lax\" | \"strict\" | \"none\",\n secure: c.secure || sameSite === \"None\",\n ...(c.domain && { domain: c.domain }),\n };\n}\n\n/**\n * The request headers to hand the render: the URL on {@link URL_HEADER}, and a cookie just minted\n * (`name=value`) added to the forwarded `Cookie` header — `NextRequest.cookies.set` doesn't rewrite\n * it, and `cookies()` reads that — so this very request's render already sees it.\n */\nexport function forwardedHeaders(headers: Headers, url: string, newCookie?: string): Headers {\n const forwarded = new Headers(headers);\n forwarded.set(URL_HEADER, url);\n if (newCookie) {\n const header = forwarded.get(\"cookie\");\n forwarded.set(\"cookie\", header ? `${header}; ${newCookie}` : newCookie);\n }\n return forwarded;\n}\n","/** One page's entry in the edge debug cookie (written by `xeniaEdgeProxy({ debug })`, read by `<XeniaDebugPanel>`). */\nexport type DebugEntry = Record<string, unknown> & { page: string };\n\n/** The debug cookie's pages (it may arrive encoded once or twice); anything unreadable is none. */\nexport function readDebugEntries(raw: string | undefined | null): Record<string, DebugEntry> {\n if (!raw) return {};\n try {\n let text = decodeURIComponent(raw);\n if (text.startsWith(\"%\")) text = decodeURIComponent(text);\n const parsed: unknown = JSON.parse(text);\n return parsed && typeof parsed === \"object\" && !Array.isArray(parsed) ? (parsed as Record<string, DebugEntry>) : {};\n } catch {\n return {};\n }\n}\n","/**\n * QA and debugging for the edge flow (`xeniaEdgeProxy`'s `qa` and `debug` options):\n * - QA overrides: `?xn_geo=<city>` places the visitor in a QA city, `?xn_date=YYYY-MM-DD` decides\n * as of that day (midday in the US), `?xn_geo=off` forgets them; kept for the visit in a cookie;\n * - the debug cookie: what was decided for each of the last few pages, read by `<XeniaDebugPanel>`.\n * A cookie rather than the HTML, because variant pages are cached and shared.\n */\nimport type { NextRequest, NextResponse } from \"next/server\";\nimport { isPrefetch } from \"../edge/request-facts\";\nimport { readDebugEntries, type DebugEntry } from \"../edge/debug-entries\";\nimport type { ViewerGeo } from \"../edge/types\";\nimport type { EdgeDecisionInfo } from \"./edge-proxy\";\n\nexport { readDebugEntries, type DebugEntry };\n\n/** Cities a QA visitor can be placed in, with what an edge would report for them. */\nexport const QA_CITIES: Record<string, ViewerGeo> = {\n minneapolis: { country: \"US\", region: \"MN\", regionName: \"Minnesota\", city: \"Minneapolis\", timeZone: \"America/Chicago\", latitude: \"44.98\", longitude: \"-93.27\" },\n chicago: { country: \"US\", region: \"IL\", regionName: \"Illinois\", city: \"Chicago\", timeZone: \"America/Chicago\", latitude: \"41.88\", longitude: \"-87.63\" },\n miami: { country: \"US\", region: \"FL\", regionName: \"Florida\", city: \"Miami\", timeZone: \"America/New_York\", latitude: \"25.76\", longitude: \"-80.19\" },\n new_york: { country: \"US\", region: \"NY\", regionName: \"New York\", city: \"New York\", timeZone: \"America/New_York\", latitude: \"40.71\", longitude: \"-74.01\" },\n los_angeles: { country: \"US\", region: \"CA\", regionName: \"California\", city: \"Los Angeles\", timeZone: \"America/Los_Angeles\", latitude: \"34.05\", longitude: \"-118.24\" },\n seattle: { country: \"US\", region: \"WA\", regionName: \"Washington\", city: \"Seattle\", timeZone: \"America/Los_Angeles\", latitude: \"47.61\", longitude: \"-122.33\" },\n london: { country: \"GB\", region: \"ENG\", regionName: \"England\", city: \"London\", timeZone: \"Europe/London\", latitude: \"51.51\", longitude: \"-0.13\" },\n sydney: { country: \"AU\", region: \"NSW\", regionName: \"New South Wales\", city: \"Sydney\", timeZone: \"Australia/Sydney\", latitude: \"-33.87\", longitude: \"151.21\" },\n};\n\nexport interface QaState {\n geo?: string;\n date?: string;\n}\n\nconst QA_MAX_AGE_S = 60 * 60;\n\nconst validDate = (d: unknown): d is string =>\n typeof d === \"string\" && /^\\d{4}-\\d{2}-\\d{2}$/.test(d) && !Number.isNaN(Date.parse(d));\n\n/** The QA overrides for this request: from the URL (then remembered) or the cookie, each checked alike. */\nexport function readQa(request: NextRequest, cities: Record<string, ViewerGeo>, cookie: string): { qa: QaState; changed: boolean } {\n const isCity = (c: unknown): c is string => typeof c === \"string\" && Object.hasOwn(cities, c);\n let qa: QaState;\n try {\n const saved = JSON.parse(request.cookies.get(cookie)?.value ?? \"{}\") as Record<string, unknown> | null;\n qa = {\n ...(isCity(saved?.geo) ? { geo: saved.geo } : {}),\n ...(validDate(saved?.date) ? { date: saved.date } : {}),\n };\n } catch {\n qa = {};\n }\n const p = request.nextUrl.searchParams;\n let changed = false;\n // `off` forgets what was remembered; values on the same URL then apply on a clean slate.\n if (p.get(\"xn_geo\") === \"off\") {\n changed = Object.keys(qa).length > 0;\n qa = {};\n }\n const city = p.get(\"xn_geo\")?.toLowerCase();\n if (isCity(city)) {\n qa = { ...qa, geo: city };\n changed = true;\n }\n const date = p.get(\"xn_date\");\n if (validDate(date)) {\n qa = { ...qa, date };\n changed = true;\n }\n return { qa, changed };\n}\n\nexport function rememberQa(response: NextResponse, qa: QaState, cookie: string) {\n if (Object.keys(qa).length) response.cookies.set(cookie, JSON.stringify(qa), { path: \"/\", maxAge: QA_MAX_AGE_S, sameSite: \"lax\" });\n else response.cookies.delete(cookie);\n}\n\n/** \"Now\" for a QA date: midday in the US (17:00 UTC) that day. */\nexport const qaNow = (qa: QaState): Date | undefined => (qa.date ? new Date(`${qa.date}T17:00:00Z`) : undefined);\n\n// ── debug cookie ─────────────────────────────────────────────────────────────\n\n/** Longest page path kept in an entry (a longer one would make the header itself too large). */\nconst MAX_PAGE = 200;\n/** Room for the cookie's value, under the browser's 4096 bytes for name, value and attributes. */\nconst DEBUG_COOKIE_MAX = 3900;\nconst DEBUG_PAGES = 4;\nconst DEBUG_MAX_AGE_S = 300;\n/** Location headers named on the panel, to show whether the host's geo reached the proxy. */\nconst GEO_HEADERS = [\"x-xn-geo\", \"x-nf-geo\", \"x-country\", \"x-vercel-ip-country\", \"cloudfront-viewer-country\", \"cf-ipcountry\"];\n\nconst geoLabel = (g: ViewerGeo | undefined) =>\n g ? `${g.city ? `${g.city}, ` : \"\"}${g.country ?? \"-\"}${g.region ? `/${g.region}` : \"\"} (${g.source ?? \"?\"})` : \"none\";\n\n/** The location sources that reached the proxy: geo headers, and Netlify's runtime context. */\nfunction sourcesSeen(request: Request): string[] {\n const seen = GEO_HEADERS.filter((n) => request.headers.get(n));\n const g = globalThis as unknown as { Netlify?: { context?: unknown } };\n if (g.Netlify) seen.push(g.Netlify.context ? \"Netlify.context\" : \"Netlify (no context)\");\n return seen;\n}\n\n/**\n * The visitor's local time to the minute (\"Thursday 21:58\") — what the `local_*` facts were made\n * from: the request's time (or a QA date) in the visitor's time zone, UTC (said so) when unknown.\n */\nfunction localTimeLabel(timeZone: string | undefined, now: Date): string {\n const format = (tz: string) =>\n new Intl.DateTimeFormat(\"en-GB\", { timeZone: tz, weekday: \"long\", hour: \"2-digit\", minute: \"2-digit\", hourCycle: \"h23\" }).format(now).replace(\",\", \"\");\n if (timeZone) {\n try {\n return format(timeZone);\n } catch {\n /* not a time zone this runtime knows */\n }\n }\n return `${format(\"UTC\")} (UTC)`;\n}\n\n/** Each Visitor Intent answer with its strongest scores (a step with many options would overflow the cookie). */\nfunction profileSummary(profile: Record<string, unknown> | null | undefined) {\n if (!profile) return undefined;\n const answers = Object.fromEntries(\n Object.entries((profile.answers ?? {}) as Record<string, Record<string, unknown> & { scores?: Record<string, number> }>).map(([name, a]) => [\n name,\n { ...a, scores: Object.fromEntries(Object.entries(a?.scores ?? {}).filter(([, v]) => v > 0).sort((x, y) => y[1] - x[1]).slice(0, 5)) },\n ]),\n );\n return { answers, pageViews: profile.page_views, lastSection: profile.last_section, campaign: profile.last_utm_campaign };\n}\n\nconst SOURCES: Record<string, string> = { skipped: \"site page\", \"not-targeted\": \"not targeted\", \"no-consent\": \"no consent\", error: \"error\" };\n\n/** What the panel shows for one page view. */\nexport function debugEntry(info: EdgeDecisionInfo): DebugEntry {\n const { outcome } = info;\n return {\n page: info.ctx.path,\n geo: geoLabel(info.ctx.geo),\n // Structured, for the panel's Request tab.\n request: {\n location: info.ctx.geo,\n via: info.ctx.geoVia,\n seen: sourcesSeen(info.ctx.request),\n ...(info.ctx.detectedGeo ? { detected: info.ctx.detectedGeo } : {}),\n device: info.ctx.device,\n consent: info.ctx.consent,\n localTime: localTimeLabel(info.ctx.geo?.timeZone, info.ctx.now),\n },\n source: outcome?.source ?? SOURCES[info.exit] ?? info.exit,\n ...(outcome ? { ms: outcome.ms, profile: profileSummary(outcome.profile) } : {}),\n decisions: (outcome?.decisions ?? []).map((d) => ({\n key: d.contentKey,\n result: d.personalized ? d.variant || \"personalized\" : d.reason?.startsWith(\"suppressed\") ? \"suppressed\" : (d.bucket ?? \"base\"),\n reason: d.reason,\n trace: d.trace,\n })),\n };\n}\n\n/**\n * Add this page's entry, keyed by page — a link prefetch passes through the proxy too, and must not\n * replace the page's own entry. Keeps the last few pages; drops the oldest until it fits, then this\n * page's profile.\n */\nexport function writeDebug(request: NextRequest, response: NextResponse, entry: DebugEntry, cookie: string) {\n if (isPrefetch(request.headers)) return;\n entry = { ...entry, page: entry.page.slice(0, MAX_PAGE) };\n const pages = readDebugEntries(request.cookies.get(cookie)?.value);\n delete pages[entry.page];\n pages[entry.page] = { ...entry, at: Date.now() };\n // Browsers drop a cookie over 4 KB whole, and the value is encoded twice (here and by `cookies.set`).\n let entries = Object.entries(pages).slice(-DEBUG_PAGES);\n const encoded = () => encodeURIComponent(JSON.stringify(Object.fromEntries(entries)));\n while (entries.length > 1 && encodeURIComponent(encoded()).length > DEBUG_COOKIE_MAX) entries = entries.slice(1);\n if (encodeURIComponent(encoded()).length > DEBUG_COOKIE_MAX) {\n const { profile: _drop, ...rest } = pages[entry.page];\n void _drop;\n entries = [[entry.page, rest as DebugEntry]];\n }\n if (encodeURIComponent(encoded()).length > DEBUG_COOKIE_MAX) {\n entries = [[entry.page, { page: entry.page, source: entry.source, note: \"entry too large for the debug cookie\" } as DebugEntry]];\n }\n response.cookies.set(cookie, encoded(), { path: \"/\", maxAge: DEBUG_MAX_AGE_S, sameSite: \"lax\" });\n}\n","/**\n * The edge decide flow in one proxy call: which page views need Xenia, the facts Xenia decides on,\n * and the rewrite to the variant page. Every failure ends in base content.\n *\n * Cost per request:\n * - page no journey targets → an in-memory manifest lookup, no Xenia call\n * - targeted page, returning visitor → an in-memory decision-cache hit\n * - targeted page, first view this session → one `/decide` call, capped at the budget\n */\nimport { NextResponse, type NextRequest } from \"next/server\";\nimport { DEFAULT_PREFIX, visitorCookieName } from \"../core/cookie-names\";\nimport { generateUlid } from \"../core/id\";\nimport type { VisitorCookieOptions } from \"../core/types\";\nimport type { DecideOutcome, XeniaEdge } from \"../edge/client\";\nimport { edgeConsent, type EdgeConsent } from \"../edge/consent\";\nimport { deviceOf, isBot, isPageLoad, landingContext, localTime, viewerGeo, type GeoHeader } from \"../edge/request-facts\";\nimport { TRAIL_MAX_AGE_S, readTrail, trailCookieName, trailCookieValue, withView } from \"../edge/trail\";\nimport type { EdgeDecision, EdgeFacts, ManifestKey, TrailView, ViewerGeo } from \"../edge/types\";\nimport { encodeVariant, swapGroups, type SwapGroup } from \"../edge/variant\";\nimport { QA_CITIES, debugEntry, qaNow, readQa, rememberQa, writeDebug, type DebugEntry } from \"./edge-debug\";\nimport { cookieAttributes, forwardedHeaders } from \"./shared\";\n\n/** What the proxy knows about this page view. `prepare` may change the fields marked so. */\nexport interface EdgeRequestContext {\n request: NextRequest;\n host: string | null;\n path: string;\n /** The visitor this view is decided for (changeable in `prepare`, e.g. a profile's own visitor). */\n visitorId: string;\n /** The visitor cookie the browser sent, if any. */\n existingVisitorId?: string;\n /** Where the visitor is (changeable in `prepare`, e.g. a QA city). */\n geo?: ViewerGeo;\n /** Which source supplied `geo` (see `viewerGeo`). */\n geoVia: string;\n /** While a QA city stands in for `geo`: what the edge really detected (for the debug panel). */\n detectedGeo?: ViewerGeo;\n device: \"mobile\" | \"tablet\" | \"desktop\";\n /** First-touch campaign and referrer (changeable in `prepare`). */\n landing: Record<string, string>;\n /** Recent views before this one (changeable in `prepare`). */\n previousTrail: TrailView[];\n /** The trail with this view first — set after `prepare`. */\n trail: TrailView[];\n consent: EdgeConsent;\n /** \"Now\" for local-time facts: the real time, or a QA date (changeable in `prepare`). */\n now: Date;\n}\n\n/** `error`: something threw (a hook, the edge client) — base content was served. */\nexport type EdgeExit = \"skipped\" | \"not-targeted\" | \"no-consent\" | \"decided\" | \"error\";\n\nexport interface EdgeDecisionInfo<S = unknown> {\n ctx: EdgeRequestContext;\n exit: EdgeExit;\n /** The facts sent to `/decide` (standard ones with the site's on top); absent when skipped. */\n facts?: EdgeFacts;\n outcome?: DecideOutcome;\n side?: S;\n /** The response about to be returned — set cookies on it here. */\n response: NextResponse;\n}\n\nexport interface XeniaEdgeProxyOptions<S = unknown> {\n /** One client per instance: `createXeniaEdge(…)` from `/edge`. */\n edge: XeniaEdge;\n /** Server-only secret the variant token is signed with. */\n variantSecret: string;\n /** Where variant pages live. Default `/xv` (`/xv/<token>/women`). */\n variantPrefix?: string;\n /** Must match the browser client's `config.prefix`, if you set one. */\n prefix?: string;\n cookie?: VisitorCookieOptions;\n /**\n * The location headers your host (or edge function) sets and overwrites, e.g.\n * `[\"x-vercel-ip-country\"]` — see `viewerGeo`. Default none: a visitor can send any header.\n */\n geoHeaders?: readonly GeoHeader[];\n /** Treat `Sec-GPC` / `DNT` as analytics off. Default true. */\n respectDnt?: boolean;\n /** Paths with no variant page (app routes): their views join the trail, but they're never decided. */\n skip?: (path: string) => boolean;\n /** Adjust the context before facts are built: the visitor, geo, landing or earlier trail. */\n prepare?: (ctx: EdgeRequestContext) => void | Promise<void>;\n /** The site's own facts, on top of the standard ones. */\n facts?: (ctx: EdgeRequestContext) => EdgeFacts | Promise<EdgeFacts>;\n /** What else makes this visitor's decision different (a new value → a fresh decision). */\n cacheFacts?: (ctx: EdgeRequestContext) => EdgeFacts | Promise<EdgeFacts>;\n /** This view's `/decide` budget, instead of the client's (e.g. a journey that calls a back office). */\n budgetMs?: (ctx: EdgeRequestContext) => number | undefined;\n /** Work started before `/decide` and awaited after it; its result reaches the hooks below as `side`. */\n alongside?: (ctx: EdgeRequestContext, keys: ManifestKey[]) => Promise<S>;\n filterDecisions?: (decisions: EdgeDecision[], ctx: EdgeRequestContext, side: S | undefined, outcome: DecideOutcome) => EdgeDecision[];\n /**\n * Where to render this view: a URL to rewrite to, `null` for the page itself, `undefined` for the\n * default (the signed variant page when anything was swapped). Called on every exit but `skipped`;\n * `outcome` is absent when Xenia wasn't asked.\n */\n rewrite?: (\n ctx: EdgeRequestContext,\n groups: SwapGroup[],\n side: S | undefined,\n outcome: DecideOutcome | undefined,\n ) => URL | null | undefined | Promise<URL | null | undefined>;\n /** Carried in the variant token beside the swaps (left out if it would make the token too long). */\n extra?: (ctx: EdgeRequestContext, side: S | undefined, outcome: DecideOutcome) => unknown;\n /** Called on every exit, with the response about to be returned. */\n onDecision?: (info: EdgeDecisionInfo<S>) => void | Promise<void>;\n /** Anything that threw on the way (base content was served instead). Default: nothing. */\n onError?: (error: unknown) => void;\n /**\n * Write what was decided for each page to the `<prefix>_debug` cookie `<XeniaDebugPanel>` reads.\n * For development and QA only — turn it on with `process.env.NODE_ENV === \"development\"` or a flag.\n */\n debug?: boolean;\n /** Fields of your own for the panel (or replacements for the SDK's), per page view. */\n debugInfo?: (info: EdgeDecisionInfo<S>) => Record<string, unknown>;\n /**\n * QA overrides for development and QA only: `?xn_geo=<city>` (`QA_CITIES`, or your own `cities`),\n * `?xn_date=YYYY-MM-DD`, `?xn_geo=off` to forget them, and `?xn_country=GB` under `next dev`.\n */\n qa?: boolean | { cities?: Record<string, ViewerGeo> };\n}\n\nconst MAX_QUERY = 20;\nconst MAX_QUERY_VALUE = 500;\n\n/**\n * Next.js `proxy.ts`/`middleware.ts` step for edge personalization: ensures the visitor cookie\n * (like `xeniaProxy()`), keeps the landing campaign and page trail, decides targeted pages with\n * Xenia within the budget and rewrites a personalized view to its signed variant page\n * (`decodeVariant` there). Respects consent (see `edgeConsent`).\n *\n * ```ts\n * const edge = createXeniaEdge({ baseUrl, token: process.env.XENIA_SDK_TOKEN! });\n * export const proxy = (request: NextRequest) =>\n * xeniaEdgeProxy(request, { edge, variantSecret: process.env.XENIA_VARIANT_SECRET! });\n * ```\n */\nexport async function xeniaEdgeProxy<S = unknown>(request: NextRequest, opts: XeniaEdgeProxyOptions<S>): Promise<NextResponse> {\n if (request.method !== \"GET\" && request.method !== \"HEAD\") return NextResponse.next();\n if (isBot(request.headers.get(\"user-agent\"))) return NextResponse.next();\n\n const started = Date.now();\n const prefix = opts.prefix ?? DEFAULT_PREFIX;\n const vidCookie = visitorCookieName(prefix);\n const ctxCookie = `${prefix}_ctx`;\n const trailCookie = trailCookieName(prefix);\n const { pathname: path } = request.nextUrl;\n const existingVisitorId = request.cookies.get(vidCookie)?.value;\n const landing = landingContext(request.nextUrl, request.headers.get(\"referer\"), request.cookies.get(ctxCookie)?.value);\n const qaOn = Boolean(opts.qa);\n const cities = (typeof opts.qa === \"object\" && opts.qa.cities) || QA_CITIES;\n const qaCookie = `${prefix}_qa_ctx`;\n const { qa, changed: qaChanged } = qaOn ? readQa(request, cities, qaCookie) : { qa: {}, changed: false };\n const detected = viewerGeo(request, { trust: opts.geoHeaders, devOverride: qaOn && process.env.NODE_ENV === \"development\" });\n const qaCity = qa.geo && Object.hasOwn(cities, qa.geo) ? cities[qa.geo] : undefined;\n const { geo, via } = qaCity ? { geo: { ...qaCity, source: \"qa\" }, via: \"qa\" } : detected;\n\n const ctx: EdgeRequestContext = {\n request,\n host: request.headers.get(\"host\"),\n path,\n visitorId: existingVisitorId ?? generateUlid(),\n existingVisitorId,\n geo,\n geoVia: via,\n ...(qaCity && detected.geo ? { detectedGeo: detected.geo } : {}),\n device: deviceOf(request.headers),\n landing: landing.ctx,\n previousTrail: readTrail(request.cookies.get(trailCookie)?.value),\n trail: [],\n consent: edgeConsent(request.headers, { prefix, respectDnt: opts.respectDnt }),\n now: qaNow(qa) ?? new Date(),\n };\n // Read when the response is built, so a visitor `prepare` switched to is the one forwarded.\n const newVisitor = () => ctx.visitorId !== existingVisitorId;\n const forwarded = () =>\n forwardedHeaders(request.headers, request.url, newVisitor() ? `${vidCookie}=${ctx.visitorId}` : undefined);\n const base = () => NextResponse.next({ request: { headers: forwarded() } });\n const respond = (url: URL | null | undefined) =>\n url ? NextResponse.rewrite(url, { request: { headers: forwarded() } }) : base();\n\n const finish = async (\n response: NextResponse,\n exit: EdgeExit,\n desc: string,\n rest: Omit<EdgeDecisionInfo<S>, \"ctx\" | \"exit\" | \"response\"> = {},\n ) => {\n if (newVisitor()) response.cookies.set(vidCookie, ctx.visitorId, cookieAttributes(opts.cookie));\n if (landing.changed || ctx.landing !== landing.ctx) {\n response.cookies.set(ctxCookie, JSON.stringify(ctx.landing), { path: \"/\", sameSite: \"lax\", httpOnly: true });\n }\n if (ctx.consent.analytics && isPageLoad(request.headers) && ctx.trail.length && ctx.trail !== ctx.previousTrail) {\n response.cookies.set(trailCookie, trailCookieValue(ctx.trail), { path: \"/\", maxAge: TRAIL_MAX_AGE_S, sameSite: \"lax\" });\n }\n response.headers.set(\"Server-Timing\", `xenia;dur=${Date.now() - started};desc=\"${desc}\"`);\n if (qaChanged) rememberQa(response, qa, qaCookie);\n try {\n const info: EdgeDecisionInfo<S> = { ctx, exit, response, ...rest };\n await opts.onDecision?.(info);\n if (opts.debug) writeDebug(request, response, { ...debugEntry(info), ...opts.debugInfo?.(info) } as DebugEntry, `${prefix}_debug`);\n } catch (error) {\n opts.onError?.(error);\n }\n return response;\n };\n\n // Every failure — a throwing hook, a bad manifest entry — ends in base content, never an error page.\n try {\n return await decideAndRespond();\n } catch (error) {\n opts.onError?.(error);\n return finish(base(), \"error\", \"error\");\n }\n\n async function decideAndRespond(): Promise<NextResponse> {\n await opts.prepare?.(ctx);\n ctx.trail = withView(ctx.previousTrail, path);\n\n if (opts.skip?.(path)) return finish(base(), \"skipped\", \"site page\");\n\n const query: Record<string, string> = {};\n for (const [k, v] of request.nextUrl.searchParams) {\n if (Object.keys(query).length >= MAX_QUERY) break;\n if (v.length <= MAX_QUERY_VALUE) query[k] = v;\n }\n const facts: EdgeFacts = {\n ...ctx.landing,\n ...localTime(ctx.geo, ctx.now),\n device: ctx.device,\n path,\n url: request.nextUrl.href,\n query,\n ...(ctx.geo ? { geo: ctx.geo as Record<string, string> } : {}),\n ...(ctx.trail[1] ? { previousPath: ctx.trail[1].path } : {}),\n ...(await opts.facts?.(ctx)),\n };\n\n if (!ctx.consent.personalization) {\n return finish(respond(await opts.rewrite?.(ctx, [], undefined, undefined)), \"no-consent\", \"no consent\", { facts });\n }\n\n // No manifest yet (a cold start whose first fetch hasn't come back): decide by path, and Xenia\n // answers \"none\" for pages no journey targets — rather than serving base content to every visitor.\n const keys = (await opts.edge.match(ctx.host, path)) ?? [{ contentKey: \"\", mode: \"server\" as const, pages: [path] }];\n if (!keys.length) {\n return finish(respond(await opts.rewrite?.(ctx, [], undefined, undefined)), \"not-targeted\", \"not targeted\", { facts });\n }\n\n const pending = opts.alongside?.(ctx, keys);\n const cacheFacts: EdgeFacts = {\n ...ctx.landing,\n device: ctx.device,\n country: ctx.geo?.country ?? \"\",\n city: ctx.geo?.city ?? \"\",\n // A page the visitor hadn't viewed, a time on page, or a click can change their profile.\n pages: ctx.trail.map((t) => t.path).sort().join(\" \"),\n timed: ctx.trail.filter((t) => t.seconds !== undefined).map((t) => `${t.path}:${Math.round(t.seconds!)}`).sort().join(\" \"),\n clicks: request.cookies.get(`${prefix}_clicks`)?.value ?? \"0\",\n // A QA date is another moment: never answer it from today's cached decision.\n ...(qa.date ? { qaDate: qa.date } : {}),\n ...(await opts.cacheFacts?.(ctx)),\n };\n const outcome = await opts.edge.decide(keys, {\n host: ctx.host,\n path,\n visitorId: ctx.visitorId,\n facts,\n cacheFacts,\n ...(ctx.consent.analytics ? { trail: ctx.trail } : {}),\n budgetMs: opts.budgetMs?.(ctx),\n });\n const side = await pending;\n const decisions = opts.filterDecisions ? opts.filterDecisions(outcome.decisions, ctx, side, outcome) : outcome.decisions;\n const groups = swapGroups(decisions);\n\n let url = await opts.rewrite?.(ctx, groups, side, outcome);\n if (url === undefined && groups.length) {\n const token = await encodeVariant(groups, opts.variantSecret, await opts.extra?.(ctx, side, outcome));\n url = request.nextUrl.clone();\n url.pathname = `${opts.variantPrefix ?? \"/xv\"}/${token}${path === \"/\" ? \"\" : path}`;\n }\n return finish(respond(url), \"decided\", outcome.source, { facts, outcome, side });\n }\n}\n","/** Route Handlers a Next.js storefront serves for edge personalization. */\nimport { revalidatePath } from \"next/cache\";\nimport { fetchManifest, trimManifest } from \"../edge/manifest\";\nimport type { PublicManifest } from \"../edge/types\";\nimport { verifyWebhook } from \"../edge/webhook\";\n\nconst EMPTY: PublicManifest = { version: \"\", pages: [] };\n\n/**\n * Part of the manifest fetch's cache key. Next's fetch cache outlives builds (`.next/cache`, which\n * hosts like Netlify keep between builds), and the route's `revalidate` makes the fetch use it even\n * without its own option, so a new build would bake in a manifest up to `revalidate` old. One key per\n * process gives every build a fresh copy; `cache: \"no-store\"` would instead make the route dynamic\n * and lose the CDN copy. `revalidatePath` (the storefront webhook) still clears it.\n */\nconst PROCESS_KEY = `${Date.now()}-${Math.random().toString(36).slice(2)}`;\nconst MAX_WEBHOOK_BODY = 64 * 1024;\n\n/**\n * `GET` for a public, CDN-cached copy of the manifest (version + targeted page patterns only — no\n * content keys or rules), so a cold proxy instance reads it from the nearby CDN instead of waiting on\n * Xenia, and the server token never leaves the server. Point the edge client's `manifestUrl` at it.\n * At build time an unreachable Xenia serves an empty manifest instead of failing the deploy; at\n * runtime it throws, so the cache keeps the last good copy.\n *\n * ```ts\n * // app/api/xenia/manifest/route.ts\n * export const revalidate = 36000; // a safety net — the storefront webhook regenerates it at once\n * export const GET = createManifestRoute({ token: process.env.XENIA_SDK_TOKEN, revalidate });\n * ```\n */\nexport function createManifestRoute(opts: { token?: string; baseUrl?: string; revalidate?: number }): () => Promise<Response> {\n return async () => {\n if (!opts.token) return Response.json(EMPTY);\n try {\n const manifest = await fetchManifest({\n baseUrl: opts.baseUrl,\n token: opts.token,\n init: {\n headers: { \"X-Xenia-Cache-Key\": PROCESS_KEY },\n ...(opts.revalidate !== undefined && { next: { revalidate: opts.revalidate } }),\n } as RequestInit,\n });\n return Response.json(trimManifest(manifest));\n } catch (error) {\n if (process.env.NEXT_PHASE === \"phase-production-build\") {\n console.warn(\"[xenia] manifest unavailable at build:\", error instanceof Error ? error.message : error);\n return Response.json(EMPTY);\n }\n throw error;\n }\n };\n}\n\n/**\n * `POST` for Xenia's storefront webhook (Journey Orchestrator → Storefront webhook): verifies the\n * signature (`verifyWebhook`), answers `ping`, and on `manifest.changed` regenerates `paths` (the\n * manifest route) at once, then runs `onManifestChanged` (e.g. a rebuild hook) and merges what it\n * returns into the response.\n */\nexport function createRevalidateRoute(opts: {\n secret?: string;\n paths: string[];\n onManifestChanged?: () => Promise<Record<string, unknown>> | Record<string, unknown>;\n}): (request: Request) => Promise<Response> {\n return async (request) => {\n const body = await request.text();\n if (body.length > MAX_WEBHOOK_BODY || !(await verifyWebhook({ headers: request.headers, body }, opts.secret ?? \"\"))) {\n return Response.json({ error: \"invalid signature\" }, { status: 401 });\n }\n const event = request.headers.get(\"x-xenia-event\") ?? \"\";\n if (event === \"ping\") return Response.json({ ok: true, event });\n if (event !== \"manifest.changed\") return Response.json({ ok: true, ignored: event });\n for (const path of opts.paths) revalidatePath(path);\n return Response.json({ ok: true, event, revalidated: opts.paths, ...(await opts.onManifestChanged?.()) });\n };\n}\n","/**\n * `@xenia-martech/sdk-js/next` — Next.js (App Router, 15+) glue for the server SDK.\n *\n * A Server Component can't see its own URL or set cookies during render, so the two halves split\n * the work: `xeniaProxy()` runs in `proxy.ts`/`middleware.ts` (mints the visitor cookie, stamps the\n * URL onto a request header), and `xeniaServerFromNext()` reads both back to bind a per-request\n * `XeniaServer`. Use them together; each alone degrades gracefully (no URL context / a throwaway\n * visitor id).\n */\n\nimport * as React from \"react\";\nimport { cookies, headers } from \"next/headers\";\nimport { NextResponse, type NextRequest } from \"next/server\";\nimport { visitorCookieName } from \"../core/cookie-names\";\nimport { generateUlid } from \"../core/id\";\nimport { contextFromUrl } from \"../core/request-context\";\nimport type { ConsentState, VisitorCookieOptions, XeniaConfig } from \"../core/types\";\nimport { getConsent } from \"../server/cookies\";\nimport { createXeniaServer, type XeniaServer } from \"../server/xenia-server\";\nimport { URL_HEADER, cookieAttributes, forwardedHeaders } from \"./shared\";\n\nexport { URL_HEADER };\nexport { xeniaEdgeProxy } from \"./edge-proxy\";\nexport type { EdgeDecisionInfo, EdgeExit, EdgeRequestContext, XeniaEdgeProxyOptions } from \"./edge-proxy\";\nexport { createManifestRoute, createRevalidateRoute } from \"./edge-routes\";\nexport { QA_CITIES, readDebugEntries } from \"./edge-debug\";\nexport type { DebugEntry, QaState } from \"./edge-debug\";\n\n\nexport interface XeniaProxyOptions {\n /** Request headers to forward (e.g. your own additions); defaults to the incoming ones. */\n headers?: Headers;\n /** Must match the browser client's `config.prefix`, if you set one. */\n prefix?: string;\n /** Visitor cookie attributes. Default: `path=/`, `SameSite=Lax`, one year. */\n cookie?: VisitorCookieOptions;\n}\n\n/**\n * Next.js proxy/middleware step: ensure the visitor cookie exists and stamp the URL onto\n * {@link URL_HEADER}, then continue. A new visitor id is also put on the forwarded `Cookie` header,\n * so this very request's render already sees it.\n *\n * ```ts\n * // proxy.ts\n * export const proxy = (request: NextRequest) => xeniaProxy(request);\n * ```\n */\nexport function xeniaProxy(request: NextRequest, opts: XeniaProxyOptions = {}): NextResponse {\n const name = visitorCookieName(opts.prefix);\n const existing = request.cookies.get(name)?.value;\n const visitorId = existing ?? generateUlid();\n\n const forwarded = forwardedHeaders(opts.headers ?? request.headers, request.url, existing ? undefined : `${name}=${visitorId}`);\n\n const response = NextResponse.next({ request: { headers: forwarded } });\n if (!existing) response.cookies.set(name, visitorId, cookieAttributes(opts.cookie));\n return response;\n}\n\n/**\n * A `XeniaServer` bound to this request's visitor (the cookie `xeniaProxy()` set) and URL context\n * (path, query, UTMs, referrer). For Server Components, Server Actions and Route Handlers.\n * `config.visitorId`/`config.context` still win when passed.\n */\nexport async function xeniaServerFromNext(config: XeniaConfig): Promise<XeniaServer> {\n const [jar, h] = await Promise.all([cookies(), headers()]);\n const name = visitorCookieName(config.prefix);\n let visitorId = config.visitorId ?? jar.get(name)?.value;\n if (!visitorId) {\n visitorId = generateUlid();\n try {\n jar.set(name, visitorId, cookieAttributes());\n } catch {\n // Expected during a Server Component render; xeniaProxy() is the place that persists it.\n }\n }\n return createXeniaServer({\n ...config,\n visitorId,\n context: { ...contextFromUrl(h.get(URL_HEADER), h.get(\"referer\")), ...config.context },\n });\n}\n\n/** This request's consent, from the cookie the browser client's `consent()` (or `consentCookie()`) wrote. */\nexport async function consentFromNext(prefix?: string): Promise<ConsentState> {\n return getConsent((await headers()).get(\"cookie\"), prefix);\n}\n\n// ── CMS page personalization ──────────────────────────────────────────────────\n\n// One store per server request (React.cache scopes it to the render), so every section that asks\n// for the same page shares ONE personalization run. Falls back to \"no sharing\" outside React\n// Server Components, where `cache` is unavailable.\nconst requestStore: () => Map<string, Promise<unknown>> =\n typeof (React as { cache?: unknown }).cache === \"function\"\n ? (React as unknown as { cache: <F extends () => unknown>(fn: F) => F }).cache(() => new Map())\n : () => new Map();\n\n/**\n * Run `personalize` at most once per request for `key`, and share the promise. Lets a page shell\n * render immediately while each personalized section awaits the same run inside its own\n * `<Suspense>`, streaming in as soon as it's ready:\n *\n * ```tsx\n * const run = (ref) => personalizeOnce(`page:${ref}`, async () =>\n * (await xeniaServerFromNext(config)).personalizePage(ref, { cms, timeoutMs: 800 }));\n *\n * export default async function Page({ params }) {\n * const xenia = await xeniaServerFromNext(config);\n * const base = await xenia.personalizePage(ref, { cms, maxRounds: 0 }); // CMS only, no Xenia call\n * const pending = new Set(pendingTargets(base.content, cms)); // from the markers\n * return base.content.fields.sections.map((s) =>\n * pending.has(s.sys.id) ? (\n * <Suspense key={s.sys.id} fallback={<SectionSkeleton />}> // never base content that will change\n * <PersonalizedSection id={s.sys.id} run={() => run(ref)} />\n * </Suspense>\n * ) : (\n * <Section key={s.sys.id} entry={s} />\n * ));\n * }\n * ```\n *\n * To finish deeper levels in the browser instead, pass `maxRounds: 1` here and hand the result's\n * `content` to `usePersonalizedContent` — already-decided entries are not asked about again.\n */\nexport function personalizeOnce<T>(key: string, personalize: () => Promise<T>): Promise<T> {\n const store = requestStore();\n let run = store.get(key) as Promise<T> | undefined;\n if (!run) {\n run = personalize();\n store.set(key, run);\n }\n return run;\n}\n"]}
1
+ {"version":3,"sources":["../../src/next/shared.ts","../../src/edge/debug-entries.ts","../../src/next/edge-debug.ts","../../src/next/edge-proxy.ts","../../src/next/edge-routes.ts","../../src/next/index.ts"],"names":["headers","isPrefetch","NextResponse","isBot","DEFAULT_PREFIX","visitorCookieName","trailCookieName","landingContext","viewerGeo","generateUlid","deviceOf","readTrail","edgeConsent","isPageLoad","trailCookieValue","TRAIL_MAX_AGE_S","withView","localTime","swapGroups","variantEntries","encodeVariant","fetchManifest","trimManifest","verifyWebhook","revalidatePath","cookies","createXeniaServer","contextFromUrl","getConsent","React"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { VisitorCookieOptions } from \"../core/types\";\n\n/** Request header the proxy stamps with the URL being served (a Server Component can't see its own). */\nexport const URL_HEADER = \"x-xenia-url\";\n\n/** `NextResponse.cookies.set` attributes for the visitor cookie. Default: `path=/`, `SameSite=Lax`, one year. */\nexport function cookieAttributes(c: VisitorCookieOptions = {}) {\n const sameSite = c.sameSite ?? \"Lax\";\n return {\n path: \"/\",\n maxAge: Math.floor((c.maxAgeDays ?? 365) * 86400),\n sameSite: sameSite.toLowerCase() as \"lax\" | \"strict\" | \"none\",\n secure: c.secure || sameSite === \"None\",\n ...(c.domain && { domain: c.domain }),\n };\n}\n\n/**\n * The request headers to hand the render: the URL on {@link URL_HEADER}, and a cookie just minted\n * (`name=value`) added to the forwarded `Cookie` header — `NextRequest.cookies.set` doesn't rewrite\n * it, and `cookies()` reads that — so this very request's render already sees it.\n */\nexport function forwardedHeaders(headers: Headers, url: string, newCookie?: string): Headers {\n const forwarded = new Headers(headers);\n forwarded.set(URL_HEADER, url);\n if (newCookie) {\n const header = forwarded.get(\"cookie\");\n forwarded.set(\"cookie\", header ? `${header}; ${newCookie}` : newCookie);\n }\n return forwarded;\n}\n","/** One page's entry in the edge debug cookie (written by `xeniaEdgeProxy({ debug })`, read by `<XeniaDebugPanel>`). */\nexport type DebugEntry = Record<string, unknown> & { page: string };\n\n/** The debug cookie's pages (it may arrive encoded once or twice); anything unreadable is none. */\nexport function readDebugEntries(raw: string | undefined | null): Record<string, DebugEntry> {\n if (!raw) return {};\n try {\n let text = decodeURIComponent(raw);\n if (text.startsWith(\"%\")) text = decodeURIComponent(text);\n const parsed: unknown = JSON.parse(text);\n return parsed && typeof parsed === \"object\" && !Array.isArray(parsed) ? (parsed as Record<string, DebugEntry>) : {};\n } catch {\n return {};\n }\n}\n","/**\n * QA and debugging for the edge flow (`xeniaEdgeProxy`'s `qa` and `debug` options):\n * - QA overrides: `?xn_geo=<city>` places the visitor in a QA city, `?xn_date=YYYY-MM-DD` decides\n * as of that day (midday in the US), `?xn_geo=off` forgets them; kept for the visit in a cookie;\n * - the debug cookie: what was decided for each of the last few pages, read by `<XeniaDebugPanel>`.\n * A cookie rather than the HTML, because variant pages are cached and shared.\n */\nimport type { NextRequest, NextResponse } from \"next/server\";\nimport { isPrefetch } from \"../edge/request-facts\";\nimport { readDebugEntries, type DebugEntry } from \"../edge/debug-entries\";\nimport type { ViewerGeo } from \"../edge/types\";\nimport type { EdgeDecisionInfo } from \"./edge-proxy\";\n\nexport { readDebugEntries, type DebugEntry };\n\n/** Cities a QA visitor can be placed in, with what an edge would report for them. */\nexport const QA_CITIES: Record<string, ViewerGeo> = {\n minneapolis: { country: \"US\", region: \"MN\", regionName: \"Minnesota\", city: \"Minneapolis\", timeZone: \"America/Chicago\", latitude: \"44.98\", longitude: \"-93.27\" },\n chicago: { country: \"US\", region: \"IL\", regionName: \"Illinois\", city: \"Chicago\", timeZone: \"America/Chicago\", latitude: \"41.88\", longitude: \"-87.63\" },\n miami: { country: \"US\", region: \"FL\", regionName: \"Florida\", city: \"Miami\", timeZone: \"America/New_York\", latitude: \"25.76\", longitude: \"-80.19\" },\n new_york: { country: \"US\", region: \"NY\", regionName: \"New York\", city: \"New York\", timeZone: \"America/New_York\", latitude: \"40.71\", longitude: \"-74.01\" },\n los_angeles: { country: \"US\", region: \"CA\", regionName: \"California\", city: \"Los Angeles\", timeZone: \"America/Los_Angeles\", latitude: \"34.05\", longitude: \"-118.24\" },\n seattle: { country: \"US\", region: \"WA\", regionName: \"Washington\", city: \"Seattle\", timeZone: \"America/Los_Angeles\", latitude: \"47.61\", longitude: \"-122.33\" },\n london: { country: \"GB\", region: \"ENG\", regionName: \"England\", city: \"London\", timeZone: \"Europe/London\", latitude: \"51.51\", longitude: \"-0.13\" },\n sydney: { country: \"AU\", region: \"NSW\", regionName: \"New South Wales\", city: \"Sydney\", timeZone: \"Australia/Sydney\", latitude: \"-33.87\", longitude: \"151.21\" },\n};\n\nexport interface QaState {\n geo?: string;\n date?: string;\n}\n\nconst QA_MAX_AGE_S = 60 * 60;\n\nconst validDate = (d: unknown): d is string =>\n typeof d === \"string\" && /^\\d{4}-\\d{2}-\\d{2}$/.test(d) && !Number.isNaN(Date.parse(d));\n\n/** The QA overrides for this request: from the URL (then remembered) or the cookie, each checked alike. */\nexport function readQa(request: NextRequest, cities: Record<string, ViewerGeo>, cookie: string): { qa: QaState; changed: boolean } {\n const isCity = (c: unknown): c is string => typeof c === \"string\" && Object.hasOwn(cities, c);\n let qa: QaState;\n try {\n const saved = JSON.parse(request.cookies.get(cookie)?.value ?? \"{}\") as Record<string, unknown> | null;\n qa = {\n ...(isCity(saved?.geo) ? { geo: saved.geo } : {}),\n ...(validDate(saved?.date) ? { date: saved.date } : {}),\n };\n } catch {\n qa = {};\n }\n const p = request.nextUrl.searchParams;\n let changed = false;\n // `off` forgets what was remembered; values on the same URL then apply on a clean slate.\n if (p.get(\"xn_geo\") === \"off\") {\n changed = Object.keys(qa).length > 0;\n qa = {};\n }\n const city = p.get(\"xn_geo\")?.toLowerCase();\n if (isCity(city)) {\n qa = { ...qa, geo: city };\n changed = true;\n }\n const date = p.get(\"xn_date\");\n if (validDate(date)) {\n qa = { ...qa, date };\n changed = true;\n }\n return { qa, changed };\n}\n\nexport function rememberQa(response: NextResponse, qa: QaState, cookie: string) {\n if (Object.keys(qa).length) response.cookies.set(cookie, JSON.stringify(qa), { path: \"/\", maxAge: QA_MAX_AGE_S, sameSite: \"lax\" });\n else response.cookies.delete(cookie);\n}\n\n/** \"Now\" for a QA date: midday in the US (17:00 UTC) that day. */\nexport const qaNow = (qa: QaState): Date | undefined => (qa.date ? new Date(`${qa.date}T17:00:00Z`) : undefined);\n\n// ── debug cookie ─────────────────────────────────────────────────────────────\n\n/** Longest page path kept in an entry (a longer one would make the header itself too large). */\nconst MAX_PAGE = 200;\n/** Room for the cookie's value, under the browser's 4096 bytes for name, value and attributes. */\nconst DEBUG_COOKIE_MAX = 3900;\nconst DEBUG_PAGES = 4;\nconst DEBUG_MAX_AGE_S = 300;\n/** Location headers named on the panel, to show whether the host's geo reached the proxy. */\nconst GEO_HEADERS = [\"x-xn-geo\", \"x-nf-geo\", \"x-country\", \"x-vercel-ip-country\", \"cloudfront-viewer-country\", \"cf-ipcountry\"];\n\nconst geoLabel = (g: ViewerGeo | undefined) =>\n g ? `${g.city ? `${g.city}, ` : \"\"}${g.country ?? \"-\"}${g.region ? `/${g.region}` : \"\"} (${g.source ?? \"?\"})` : \"none\";\n\n/** The location sources that reached the proxy: geo headers, and Netlify's runtime context. */\nfunction sourcesSeen(request: Request): string[] {\n const seen = GEO_HEADERS.filter((n) => request.headers.get(n));\n const g = globalThis as unknown as { Netlify?: { context?: unknown } };\n if (g.Netlify) seen.push(g.Netlify.context ? \"Netlify.context\" : \"Netlify (no context)\");\n return seen;\n}\n\n/**\n * The visitor's local time to the minute (\"Thursday 21:58\") — what the `local_*` facts were made\n * from: the request's time (or a QA date) in the visitor's time zone, UTC (said so) when unknown.\n */\nfunction localTimeLabel(timeZone: string | undefined, now: Date): string {\n const format = (tz: string) =>\n new Intl.DateTimeFormat(\"en-GB\", { timeZone: tz, weekday: \"long\", hour: \"2-digit\", minute: \"2-digit\", hourCycle: \"h23\" }).format(now).replace(\",\", \"\");\n if (timeZone) {\n try {\n return format(timeZone);\n } catch {\n /* not a time zone this runtime knows */\n }\n }\n return `${format(\"UTC\")} (UTC)`;\n}\n\n/** Each Visitor Intent answer with its strongest scores (a step with many options would overflow the cookie). */\nfunction profileSummary(profile: Record<string, unknown> | null | undefined) {\n if (!profile) return undefined;\n const answers = Object.fromEntries(\n Object.entries((profile.answers ?? {}) as Record<string, Record<string, unknown> & { scores?: Record<string, number> }>).map(([name, a]) => [\n name,\n { ...a, scores: Object.fromEntries(Object.entries(a?.scores ?? {}).filter(([, v]) => v > 0).sort((x, y) => y[1] - x[1]).slice(0, 5)) },\n ]),\n );\n return { answers, pageViews: profile.page_views, lastSection: profile.last_section, campaign: profile.last_utm_campaign };\n}\n\nconst SOURCES: Record<string, string> = { skipped: \"site page\", \"not-targeted\": \"not targeted\", \"no-consent\": \"no consent\", error: \"error\" };\n\n/** What the panel shows for one page view. */\nexport function debugEntry(info: EdgeDecisionInfo): DebugEntry {\n const { outcome } = info;\n return {\n page: info.ctx.path,\n geo: geoLabel(info.ctx.geo),\n // Structured, for the panel's Request tab.\n request: {\n location: info.ctx.geo,\n via: info.ctx.geoVia,\n seen: sourcesSeen(info.ctx.request),\n ...(info.ctx.detectedGeo ? { detected: info.ctx.detectedGeo } : {}),\n device: info.ctx.device,\n consent: info.ctx.consent,\n localTime: localTimeLabel(info.ctx.geo?.timeZone, info.ctx.now),\n },\n source: outcome?.source ?? SOURCES[info.exit] ?? info.exit,\n ...(outcome ? { ms: outcome.ms, profile: profileSummary(outcome.profile) } : {}),\n decisions: (outcome?.decisions ?? []).map((d) => ({\n key: d.contentKey,\n result: d.personalized ? d.variant || \"personalized\" : d.reason?.startsWith(\"suppressed\") ? \"suppressed\" : (d.bucket ?? \"base\"),\n reason: d.reason,\n trace: d.trace,\n })),\n };\n}\n\n/**\n * Add this page's entry, keyed by page — a link prefetch passes through the proxy too, and must not\n * replace the page's own entry. Keeps the last few pages; drops the oldest until it fits, then this\n * page's profile.\n */\nexport function writeDebug(request: NextRequest, response: NextResponse, entry: DebugEntry, cookie: string) {\n if (isPrefetch(request.headers)) return;\n entry = { ...entry, page: entry.page.slice(0, MAX_PAGE) };\n const pages = readDebugEntries(request.cookies.get(cookie)?.value);\n delete pages[entry.page];\n pages[entry.page] = { ...entry, at: Date.now() };\n // Browsers drop a cookie over 4 KB whole, and the value is encoded twice (here and by `cookies.set`).\n let entries = Object.entries(pages).slice(-DEBUG_PAGES);\n const encoded = () => encodeURIComponent(JSON.stringify(Object.fromEntries(entries)));\n while (entries.length > 1 && encodeURIComponent(encoded()).length > DEBUG_COOKIE_MAX) entries = entries.slice(1);\n if (encodeURIComponent(encoded()).length > DEBUG_COOKIE_MAX) {\n const { profile: _drop, ...rest } = pages[entry.page];\n void _drop;\n entries = [[entry.page, rest as DebugEntry]];\n }\n if (encodeURIComponent(encoded()).length > DEBUG_COOKIE_MAX) {\n entries = [[entry.page, { page: entry.page, source: entry.source, note: \"entry too large for the debug cookie\" } as DebugEntry]];\n }\n response.cookies.set(cookie, encoded(), { path: \"/\", maxAge: DEBUG_MAX_AGE_S, sameSite: \"lax\" });\n}\n","/**\n * The edge decide flow in one proxy call: which page views need Xenia, the facts Xenia decides on,\n * and the rewrite to the variant page. Every failure ends in base content.\n *\n * Cost per request:\n * - page no journey targets → an in-memory manifest lookup, no Xenia call\n * - targeted page, returning visitor → an in-memory decision-cache hit\n * - targeted page, first view this session → one `/decide` call, capped at the budget\n */\nimport { NextResponse, type NextRequest } from \"next/server\";\nimport { DEFAULT_PREFIX, visitorCookieName } from \"../core/cookie-names\";\nimport { generateUlid } from \"../core/id\";\nimport type { VisitorCookieOptions } from \"../core/types\";\nimport type { DecideOutcome, XeniaEdge } from \"../edge/client\";\nimport { edgeConsent, type EdgeConsent } from \"../edge/consent\";\nimport { deviceOf, isBot, isPageLoad, landingContext, localTime, viewerGeo, type GeoHeader } from \"../edge/request-facts\";\nimport { TRAIL_MAX_AGE_S, readTrail, trailCookieName, trailCookieValue, withView } from \"../edge/trail\";\nimport type { EdgeDecision, EdgeFacts, ManifestKey, TrailView, ViewerGeo } from \"../edge/types\";\nimport { encodeVariant, swapGroups, variantEntries, type SwapGroup } from \"../edge/variant\";\nimport { QA_CITIES, debugEntry, qaNow, readQa, rememberQa, writeDebug, type DebugEntry } from \"./edge-debug\";\nimport { cookieAttributes, forwardedHeaders } from \"./shared\";\n\n/** What the proxy knows about this page view. `prepare` may change the fields marked so. */\nexport interface EdgeRequestContext {\n request: NextRequest;\n host: string | null;\n path: string;\n /** The visitor this view is decided for (changeable in `prepare`, e.g. a profile's own visitor). */\n visitorId: string;\n /** The visitor cookie the browser sent, if any. */\n existingVisitorId?: string;\n /** Where the visitor is (changeable in `prepare`, e.g. a QA city). */\n geo?: ViewerGeo;\n /** Which source supplied `geo` (see `viewerGeo`). */\n geoVia: string;\n /** While a QA city stands in for `geo`: what the edge really detected (for the debug panel). */\n detectedGeo?: ViewerGeo;\n device: \"mobile\" | \"tablet\" | \"desktop\";\n /** First-touch campaign and referrer (changeable in `prepare`). */\n landing: Record<string, string>;\n /** Recent views before this one (changeable in `prepare`). */\n previousTrail: TrailView[];\n /** The trail with this view first — set after `prepare`. */\n trail: TrailView[];\n consent: EdgeConsent;\n /** \"Now\" for local-time facts: the real time, or a QA date (changeable in `prepare`). */\n now: Date;\n}\n\n/** `error`: something threw (a hook, the edge client) — base content was served. */\nexport type EdgeExit = \"skipped\" | \"not-targeted\" | \"no-consent\" | \"decided\" | \"error\";\n\nexport interface EdgeDecisionInfo<S = unknown> {\n ctx: EdgeRequestContext;\n exit: EdgeExit;\n /** The facts sent to `/decide` (standard ones with the site's on top); absent when skipped. */\n facts?: EdgeFacts;\n outcome?: DecideOutcome;\n side?: S;\n /** The response about to be returned — set cookies on it here. */\n response: NextResponse;\n}\n\nexport interface XeniaEdgeProxyOptions<S = unknown> {\n /** One client per instance: `createXeniaEdge(…)` from `/edge`. */\n edge: XeniaEdge;\n /** Server-only secret the variant token is signed with. */\n variantSecret: string;\n /** Where variant pages live. Default `/xv` (`/xv/<token>/women`). */\n variantPrefix?: string;\n /** Must match the browser client's `config.prefix`, if you set one. */\n prefix?: string;\n cookie?: VisitorCookieOptions;\n /**\n * The location headers your host (or edge function) sets and overwrites, e.g.\n * `[\"x-vercel-ip-country\"]` — see `viewerGeo`. Default none: a visitor can send any header.\n */\n geoHeaders?: readonly GeoHeader[];\n /** Treat `Sec-GPC` / `DNT` as analytics off. Default true. */\n respectDnt?: boolean;\n /** Paths with no variant page (app routes): their views join the trail, but they're never decided. */\n skip?: (path: string) => boolean;\n /** Adjust the context before facts are built: the visitor, geo, landing or earlier trail. */\n prepare?: (ctx: EdgeRequestContext) => void | Promise<void>;\n /** The site's own facts, on top of the standard ones. */\n facts?: (ctx: EdgeRequestContext) => EdgeFacts | Promise<EdgeFacts>;\n /** What else makes this visitor's decision different (a new value → a fresh decision). */\n cacheFacts?: (ctx: EdgeRequestContext) => EdgeFacts | Promise<EdgeFacts>;\n /** This view's `/decide` budget, instead of the client's (e.g. a journey that calls a back office). */\n budgetMs?: (ctx: EdgeRequestContext) => number | undefined;\n /** Work started before `/decide` and awaited after it; its result reaches the hooks below as `side`. */\n alongside?: (ctx: EdgeRequestContext, keys: ManifestKey[]) => Promise<S>;\n filterDecisions?: (decisions: EdgeDecision[], ctx: EdgeRequestContext, side: S | undefined, outcome: DecideOutcome) => EdgeDecision[];\n /**\n * Where to render this view: a URL to rewrite to, `null` for the page itself, `undefined` for the\n * default (the signed variant page when anything was swapped). Called on every exit but `skipped`;\n * `outcome` is absent when Xenia wasn't asked.\n */\n rewrite?: (\n ctx: EdgeRequestContext,\n groups: SwapGroup[],\n side: S | undefined,\n outcome: DecideOutcome | undefined,\n ) => URL | null | undefined | Promise<URL | null | undefined>;\n /** Carried in the variant token beside the swaps (left out if it would make the token too long). */\n extra?: (ctx: EdgeRequestContext, side: S | undefined, outcome: DecideOutcome) => unknown;\n /** Called on every exit, with the response about to be returned. */\n onDecision?: (info: EdgeDecisionInfo<S>) => void | Promise<void>;\n /** Anything that threw on the way (base content was served instead). Default: nothing. */\n onError?: (error: unknown) => void;\n /**\n * Write what was decided for each page to the `<prefix>_debug` cookie `<XeniaDebugPanel>` reads.\n * For development and QA only — turn it on with `process.env.NODE_ENV === \"development\"` or a flag.\n */\n debug?: boolean;\n /** Fields of your own for the panel (or replacements for the SDK's), per page view. */\n debugInfo?: (info: EdgeDecisionInfo<S>) => Record<string, unknown>;\n /**\n * QA overrides for development and QA only: `?xn_geo=<city>` (`QA_CITIES`, or your own `cities`),\n * `?xn_date=YYYY-MM-DD`, `?xn_geo=off` to forget them, and `?xn_country=GB` under `next dev`.\n */\n qa?: boolean | { cities?: Record<string, ViewerGeo> };\n}\n\nconst MAX_QUERY = 20;\nconst MAX_QUERY_VALUE = 500;\n\n/**\n * Next.js `proxy.ts`/`middleware.ts` step for edge personalization: ensures the visitor cookie\n * (like `xeniaProxy()`), keeps the landing campaign and page trail, decides targeted pages with\n * Xenia within the budget and rewrites a personalized view to its signed variant page\n * (`decodeVariant` there). Respects consent (see `edgeConsent`).\n *\n * ```ts\n * const edge = createXeniaEdge({ baseUrl, token: process.env.XENIA_SDK_TOKEN! });\n * export const proxy = (request: NextRequest) =>\n * xeniaEdgeProxy(request, { edge, variantSecret: process.env.XENIA_VARIANT_SECRET! });\n * ```\n */\nexport async function xeniaEdgeProxy<S = unknown>(request: NextRequest, opts: XeniaEdgeProxyOptions<S>): Promise<NextResponse> {\n if (request.method !== \"GET\" && request.method !== \"HEAD\") return NextResponse.next();\n if (isBot(request.headers.get(\"user-agent\"))) return NextResponse.next();\n\n const started = Date.now();\n const prefix = opts.prefix ?? DEFAULT_PREFIX;\n const vidCookie = visitorCookieName(prefix);\n const ctxCookie = `${prefix}_ctx`;\n const trailCookie = trailCookieName(prefix);\n const { pathname: path } = request.nextUrl;\n const existingVisitorId = request.cookies.get(vidCookie)?.value;\n const landing = landingContext(request.nextUrl, request.headers.get(\"referer\"), request.cookies.get(ctxCookie)?.value);\n const qaOn = Boolean(opts.qa);\n const cities = (typeof opts.qa === \"object\" && opts.qa.cities) || QA_CITIES;\n const qaCookie = `${prefix}_qa_ctx`;\n const { qa, changed: qaChanged } = qaOn ? readQa(request, cities, qaCookie) : { qa: {}, changed: false };\n const detected = viewerGeo(request, { trust: opts.geoHeaders, devOverride: qaOn && process.env.NODE_ENV === \"development\" });\n const qaCity = qa.geo && Object.hasOwn(cities, qa.geo) ? cities[qa.geo] : undefined;\n const { geo, via } = qaCity ? { geo: { ...qaCity, source: \"qa\" }, via: \"qa\" } : detected;\n\n const ctx: EdgeRequestContext = {\n request,\n host: request.headers.get(\"host\"),\n path,\n visitorId: existingVisitorId ?? generateUlid(),\n existingVisitorId,\n geo,\n geoVia: via,\n ...(qaCity && detected.geo ? { detectedGeo: detected.geo } : {}),\n device: deviceOf(request.headers),\n landing: landing.ctx,\n previousTrail: readTrail(request.cookies.get(trailCookie)?.value),\n trail: [],\n consent: edgeConsent(request.headers, { prefix, respectDnt: opts.respectDnt }),\n now: qaNow(qa) ?? new Date(),\n };\n // Read when the response is built, so a visitor `prepare` switched to is the one forwarded.\n const newVisitor = () => ctx.visitorId !== existingVisitorId;\n const forwarded = () =>\n forwardedHeaders(request.headers, request.url, newVisitor() ? `${vidCookie}=${ctx.visitorId}` : undefined);\n const base = () => NextResponse.next({ request: { headers: forwarded() } });\n const respond = (url: URL | null | undefined) =>\n url ? NextResponse.rewrite(url, { request: { headers: forwarded() } }) : base();\n\n const finish = async (\n response: NextResponse,\n exit: EdgeExit,\n desc: string,\n rest: Omit<EdgeDecisionInfo<S>, \"ctx\" | \"exit\" | \"response\"> = {},\n ) => {\n if (newVisitor()) response.cookies.set(vidCookie, ctx.visitorId, cookieAttributes(opts.cookie));\n if (landing.changed || ctx.landing !== landing.ctx) {\n response.cookies.set(ctxCookie, JSON.stringify(ctx.landing), { path: \"/\", sameSite: \"lax\", httpOnly: true });\n }\n if (ctx.consent.analytics && isPageLoad(request.headers) && ctx.trail.length && ctx.trail !== ctx.previousTrail) {\n response.cookies.set(trailCookie, trailCookieValue(ctx.trail), { path: \"/\", maxAge: TRAIL_MAX_AGE_S, sameSite: \"lax\" });\n }\n response.headers.set(\"Server-Timing\", `xenia;dur=${Date.now() - started};desc=\"${desc}\"`);\n if (qaChanged) rememberQa(response, qa, qaCookie);\n try {\n const info: EdgeDecisionInfo<S> = { ctx, exit, response, ...rest };\n await opts.onDecision?.(info);\n if (opts.debug) writeDebug(request, response, { ...debugEntry(info), ...opts.debugInfo?.(info) } as DebugEntry, `${prefix}_debug`);\n } catch (error) {\n opts.onError?.(error);\n }\n return response;\n };\n\n // Every failure — a throwing hook, a bad manifest entry — ends in base content, never an error page.\n try {\n return await decideAndRespond();\n } catch (error) {\n opts.onError?.(error);\n return finish(base(), \"error\", \"error\");\n }\n\n async function decideAndRespond(): Promise<NextResponse> {\n await opts.prepare?.(ctx);\n ctx.trail = withView(ctx.previousTrail, path);\n\n if (opts.skip?.(path)) return finish(base(), \"skipped\", \"site page\");\n\n const query: Record<string, string> = {};\n for (const [k, v] of request.nextUrl.searchParams) {\n if (Object.keys(query).length >= MAX_QUERY) break;\n if (v.length <= MAX_QUERY_VALUE) query[k] = v;\n }\n const facts: EdgeFacts = {\n ...ctx.landing,\n ...localTime(ctx.geo, ctx.now),\n device: ctx.device,\n path,\n url: request.nextUrl.href,\n query,\n ...(ctx.geo ? { geo: ctx.geo as Record<string, string> } : {}),\n ...(ctx.trail[1] ? { previousPath: ctx.trail[1].path } : {}),\n ...(await opts.facts?.(ctx)),\n };\n\n if (!ctx.consent.personalization) {\n return finish(respond(await opts.rewrite?.(ctx, [], undefined, undefined)), \"no-consent\", \"no consent\", { facts });\n }\n\n // No manifest yet (a cold start whose first fetch hasn't come back): decide by path, and Xenia\n // answers \"none\" for pages no journey targets — rather than serving base content to every visitor.\n const keys = (await opts.edge.match(ctx.host, path)) ?? [{ contentKey: \"\", mode: \"server\" as const, pages: [path] }];\n if (!keys.length) {\n return finish(respond(await opts.rewrite?.(ctx, [], undefined, undefined)), \"not-targeted\", \"not targeted\", { facts });\n }\n\n const pending = opts.alongside?.(ctx, keys);\n const cacheFacts: EdgeFacts = {\n ...ctx.landing,\n device: ctx.device,\n country: ctx.geo?.country ?? \"\",\n city: ctx.geo?.city ?? \"\",\n // A page the visitor hadn't viewed, a time on page, or a click can change their profile.\n pages: ctx.trail.map((t) => t.path).sort().join(\" \"),\n timed: ctx.trail.filter((t) => t.seconds !== undefined).map((t) => `${t.path}:${Math.round(t.seconds!)}`).sort().join(\" \"),\n clicks: request.cookies.get(`${prefix}_clicks`)?.value ?? \"0\",\n // A QA date is another moment: never answer it from today's cached decision.\n ...(qa.date ? { qaDate: qa.date } : {}),\n ...(await opts.cacheFacts?.(ctx)),\n };\n const outcome = await opts.edge.decide(keys, {\n host: ctx.host,\n path,\n visitorId: ctx.visitorId,\n facts,\n cacheFacts,\n ...(ctx.consent.analytics ? { trail: ctx.trail } : {}),\n budgetMs: opts.budgetMs?.(ctx),\n });\n const side = await pending;\n const decisions = opts.filterDecisions ? opts.filterDecisions(outcome.decisions, ctx, side, outcome) : outcome.decisions;\n const groups = swapGroups(decisions);\n\n const entries = variantEntries(decisions, outcome.entryDecisions);\n\n let url = await opts.rewrite?.(ctx, groups, side, outcome);\n if (url === undefined && (groups.length || entries.length)) {\n const token = await encodeVariant(groups, opts.variantSecret, await opts.extra?.(ctx, side, outcome), entries);\n url = request.nextUrl.clone();\n url.pathname = `${opts.variantPrefix ?? \"/xv\"}/${token}${path === \"/\" ? \"\" : path}`;\n }\n return finish(respond(url), \"decided\", outcome.source, { facts, outcome, side });\n }\n}\n","/** Route Handlers a Next.js storefront serves for edge personalization. */\nimport { revalidatePath } from \"next/cache\";\nimport { fetchManifest, trimManifest } from \"../edge/manifest\";\nimport type { PublicManifest } from \"../edge/types\";\nimport { verifyWebhook } from \"../edge/webhook\";\n\nconst EMPTY: PublicManifest = { version: \"\", pages: [] };\n\n/**\n * Part of the manifest fetch's cache key. Next's fetch cache outlives builds (`.next/cache`, which\n * hosts like Netlify keep between builds), and the route's `revalidate` makes the fetch use it even\n * without its own option, so a new build would bake in a manifest up to `revalidate` old. One key per\n * process gives every build a fresh copy; `cache: \"no-store\"` would instead make the route dynamic\n * and lose the CDN copy. `revalidatePath` (the storefront webhook) still clears it.\n */\nconst PROCESS_KEY = `${Date.now()}-${Math.random().toString(36).slice(2)}`;\nconst MAX_WEBHOOK_BODY = 64 * 1024;\n\n/**\n * `GET` for a public, CDN-cached copy of the manifest (version + targeted page patterns only — no\n * content keys or rules), so a cold proxy instance reads it from the nearby CDN instead of waiting on\n * Xenia, and the server token never leaves the server. Point the edge client's `manifestUrl` at it.\n * At build time an unreachable Xenia serves an empty manifest instead of failing the deploy; at\n * runtime it throws, so the cache keeps the last good copy.\n *\n * ```ts\n * // app/api/xenia/manifest/route.ts\n * export const revalidate = 36000; // a safety net — the storefront webhook regenerates it at once\n * export const GET = createManifestRoute({ token: process.env.XENIA_SDK_TOKEN, revalidate });\n * ```\n */\nexport function createManifestRoute(opts: { token?: string; baseUrl?: string; revalidate?: number }): () => Promise<Response> {\n return async () => {\n if (!opts.token) return Response.json(EMPTY);\n try {\n const manifest = await fetchManifest({\n baseUrl: opts.baseUrl,\n token: opts.token,\n init: {\n headers: { \"X-Xenia-Cache-Key\": PROCESS_KEY },\n ...(opts.revalidate !== undefined && { next: { revalidate: opts.revalidate } }),\n } as RequestInit,\n });\n return Response.json(trimManifest(manifest));\n } catch (error) {\n if (process.env.NEXT_PHASE === \"phase-production-build\") {\n console.warn(\"[xenia] manifest unavailable at build:\", error instanceof Error ? error.message : error);\n return Response.json(EMPTY);\n }\n throw error;\n }\n };\n}\n\n/**\n * `POST` for Xenia's storefront webhook (Journey Orchestrator → Storefront webhook): verifies the\n * signature (`verifyWebhook`), answers `ping`, and on `manifest.changed` regenerates `paths` (the\n * manifest route) at once, then runs `onManifestChanged` (e.g. a rebuild hook) and merges what it\n * returns into the response.\n */\nexport function createRevalidateRoute(opts: {\n secret?: string;\n paths: string[];\n onManifestChanged?: () => Promise<Record<string, unknown>> | Record<string, unknown>;\n}): (request: Request) => Promise<Response> {\n return async (request) => {\n const body = await request.text();\n if (body.length > MAX_WEBHOOK_BODY || !(await verifyWebhook({ headers: request.headers, body }, opts.secret ?? \"\"))) {\n return Response.json({ error: \"invalid signature\" }, { status: 401 });\n }\n const event = request.headers.get(\"x-xenia-event\") ?? \"\";\n if (event === \"ping\") return Response.json({ ok: true, event });\n if (event !== \"manifest.changed\") return Response.json({ ok: true, ignored: event });\n for (const path of opts.paths) revalidatePath(path);\n return Response.json({ ok: true, event, revalidated: opts.paths, ...(await opts.onManifestChanged?.()) });\n };\n}\n","/**\n * `@xenia-martech/sdk-js/next` — Next.js (App Router, 15+) glue for the server SDK.\n *\n * A Server Component can't see its own URL or set cookies during render, so the two halves split\n * the work: `xeniaProxy()` runs in `proxy.ts`/`middleware.ts` (mints the visitor cookie, stamps the\n * URL onto a request header), and `xeniaServerFromNext()` reads both back to bind a per-request\n * `XeniaServer`. Use them together; each alone degrades gracefully (no URL context / a throwaway\n * visitor id).\n */\n\nimport * as React from \"react\";\nimport { cookies, headers } from \"next/headers\";\nimport { NextResponse, type NextRequest } from \"next/server\";\nimport { visitorCookieName } from \"../core/cookie-names\";\nimport { generateUlid } from \"../core/id\";\nimport { contextFromUrl } from \"../core/request-context\";\nimport type { ConsentState, VisitorCookieOptions, XeniaConfig } from \"../core/types\";\nimport { getConsent } from \"../server/cookies\";\nimport { createXeniaServer, type XeniaServer } from \"../server/xenia-server\";\nimport { URL_HEADER, cookieAttributes, forwardedHeaders } from \"./shared\";\n\nexport { URL_HEADER };\nexport { xeniaEdgeProxy } from \"./edge-proxy\";\nexport type { EdgeDecisionInfo, EdgeExit, EdgeRequestContext, XeniaEdgeProxyOptions } from \"./edge-proxy\";\nexport { createManifestRoute, createRevalidateRoute } from \"./edge-routes\";\nexport { QA_CITIES, readDebugEntries } from \"./edge-debug\";\nexport type { DebugEntry, QaState } from \"./edge-debug\";\n\n\nexport interface XeniaProxyOptions {\n /** Request headers to forward (e.g. your own additions); defaults to the incoming ones. */\n headers?: Headers;\n /** Must match the browser client's `config.prefix`, if you set one. */\n prefix?: string;\n /** Visitor cookie attributes. Default: `path=/`, `SameSite=Lax`, one year. */\n cookie?: VisitorCookieOptions;\n}\n\n/**\n * Next.js proxy/middleware step: ensure the visitor cookie exists and stamp the URL onto\n * {@link URL_HEADER}, then continue. A new visitor id is also put on the forwarded `Cookie` header,\n * so this very request's render already sees it.\n *\n * ```ts\n * // proxy.ts\n * export const proxy = (request: NextRequest) => xeniaProxy(request);\n * ```\n */\nexport function xeniaProxy(request: NextRequest, opts: XeniaProxyOptions = {}): NextResponse {\n const name = visitorCookieName(opts.prefix);\n const existing = request.cookies.get(name)?.value;\n const visitorId = existing ?? generateUlid();\n\n const forwarded = forwardedHeaders(opts.headers ?? request.headers, request.url, existing ? undefined : `${name}=${visitorId}`);\n\n const response = NextResponse.next({ request: { headers: forwarded } });\n if (!existing) response.cookies.set(name, visitorId, cookieAttributes(opts.cookie));\n return response;\n}\n\n/**\n * A `XeniaServer` bound to this request's visitor (the cookie `xeniaProxy()` set) and URL context\n * (path, query, UTMs, referrer). For Server Components, Server Actions and Route Handlers.\n * `config.visitorId`/`config.context` still win when passed.\n */\nexport async function xeniaServerFromNext(config: XeniaConfig): Promise<XeniaServer> {\n const [jar, h] = await Promise.all([cookies(), headers()]);\n const name = visitorCookieName(config.prefix);\n let visitorId = config.visitorId ?? jar.get(name)?.value;\n if (!visitorId) {\n visitorId = generateUlid();\n try {\n jar.set(name, visitorId, cookieAttributes());\n } catch {\n // Expected during a Server Component render; xeniaProxy() is the place that persists it.\n }\n }\n return createXeniaServer({\n ...config,\n visitorId,\n context: { ...contextFromUrl(h.get(URL_HEADER), h.get(\"referer\")), ...config.context },\n });\n}\n\n/** This request's consent, from the cookie the browser client's `consent()` (or `consentCookie()`) wrote. */\nexport async function consentFromNext(prefix?: string): Promise<ConsentState> {\n return getConsent((await headers()).get(\"cookie\"), prefix);\n}\n\n// ── CMS page personalization ──────────────────────────────────────────────────\n\n// One store per server request (React.cache scopes it to the render), so every section that asks\n// for the same page shares ONE personalization run. Falls back to \"no sharing\" outside React\n// Server Components, where `cache` is unavailable.\nconst requestStore: () => Map<string, Promise<unknown>> =\n typeof (React as { cache?: unknown }).cache === \"function\"\n ? (React as unknown as { cache: <F extends () => unknown>(fn: F) => F }).cache(() => new Map())\n : () => new Map();\n\n/**\n * Run `personalize` at most once per request for `key`, and share the promise. Lets a page shell\n * render immediately while each personalized section awaits the same run inside its own\n * `<Suspense>`, streaming in as soon as it's ready:\n *\n * ```tsx\n * const run = (ref) => personalizeOnce(`page:${ref}`, async () =>\n * (await xeniaServerFromNext(config)).personalizePage(ref, { cms, timeoutMs: 800 }));\n *\n * export default async function Page({ params }) {\n * const xenia = await xeniaServerFromNext(config);\n * const base = await xenia.personalizePage(ref, { cms, maxRounds: 0 }); // CMS only, no Xenia call\n * const pending = new Set(pendingTargets(base.content, cms)); // from the markers\n * return base.content.fields.sections.map((s) =>\n * pending.has(s.sys.id) ? (\n * <Suspense key={s.sys.id} fallback={<SectionSkeleton />}> // never base content that will change\n * <PersonalizedSection id={s.sys.id} run={() => run(ref)} />\n * </Suspense>\n * ) : (\n * <Section key={s.sys.id} entry={s} />\n * ));\n * }\n * ```\n *\n * To finish deeper levels in the browser instead, pass `maxRounds: 1` here and hand the result's\n * `content` to `usePersonalizedContent` — already-decided entries are not asked about again.\n */\nexport function personalizeOnce<T>(key: string, personalize: () => Promise<T>): Promise<T> {\n const store = requestStore();\n let run = store.get(key) as Promise<T> | undefined;\n if (!run) {\n run = personalize();\n store.set(key, run);\n }\n return run;\n}\n"]}
@@ -1,10 +1,9 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
- import { V as VisitorCookieOptions } from '../types-DgVHS4Qw.cjs';
2
+ import { V as VisitorCookieOptions } from '../personalize-content-D6xeBI7-.cjs';
3
3
  import { ConsentState, XeniaConfig } from '../index.cjs';
4
4
  import { XeniaServer } from '../server/index.cjs';
5
5
  import { ViewerGeo, TrailView, EdgeConsent, EdgeFacts, DecideOutcome, XeniaEdge, GeoHeader, ManifestKey, EdgeDecision, SwapGroup } from '../edge/index.cjs';
6
- import '../api-0IycTYJR.cjs';
7
- import '../personalize-content-CxSdplMV.cjs';
6
+ import '../api-DgzJ5s-k.cjs';
8
7
 
9
8
  /** Request header the proxy stamps with the URL being served (a Server Component can't see its own). */
10
9
  declare const URL_HEADER = "x-xenia-url";
@@ -1,10 +1,9 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
- import { V as VisitorCookieOptions } from '../types-DgVHS4Qw.js';
2
+ import { V as VisitorCookieOptions } from '../personalize-content-D6xeBI7-.js';
3
3
  import { ConsentState, XeniaConfig } from '../index.js';
4
4
  import { XeniaServer } from '../server/index.js';
5
5
  import { ViewerGeo, TrailView, EdgeConsent, EdgeFacts, DecideOutcome, XeniaEdge, GeoHeader, ManifestKey, EdgeDecision, SwapGroup } from '../edge/index.js';
6
- import '../api-COXWLL5L.js';
7
- import '../personalize-content-Cwc2AomC.js';
6
+ import '../api-DbUxT38T.js';
8
7
 
9
8
  /** Request header the proxy stamps with the URL being served (a Server Component can't see its own). */
10
9
  declare const URL_HEADER = "x-xenia-url";
@@ -1,8 +1,8 @@
1
- import { createXeniaServer } from '../chunk-GWRDZIVA.js';
2
- import { generateUlid, contextFromUrl } from '../chunk-LW5AEJ6K.js';
3
- import { isBot, trailCookieName, landingContext, viewerGeo, edgeConsent, readTrail, deviceOf, withView, localTime, swapGroups, encodeVariant, fetchManifest, trimManifest, verifyWebhook, isPageLoad, trailCookieValue, TRAIL_MAX_AGE_S, isPrefetch } from '../chunk-F3WZFXYK.js';
4
- import { getConsent } from '../chunk-QEYONKWY.js';
5
- import { DEFAULT_PREFIX, visitorCookieName } from '../chunk-BQ5PJCZ7.js';
1
+ import { createXeniaServer } from '../chunk-NDRRSRTU.js';
2
+ import { generateUlid, contextFromUrl } from '../chunk-MEULT5X6.js';
3
+ import { isBot, trailCookieName, landingContext, viewerGeo, edgeConsent, readTrail, deviceOf, withView, localTime, swapGroups, variantEntries, encodeVariant, fetchManifest, trimManifest, verifyWebhook, isPageLoad, trailCookieValue, TRAIL_MAX_AGE_S, isPrefetch } from '../chunk-V4EGU3PM.js';
4
+ import { getConsent } from '../chunk-UVTFGQR6.js';
5
+ import { DEFAULT_PREFIX, visitorCookieName } from '../chunk-FSJMHXS6.js';
6
6
  import * as React from 'react';
7
7
  import { cookies, headers } from 'next/headers';
8
8
  import { NextResponse } from 'next/server';
@@ -286,9 +286,10 @@ async function xeniaEdgeProxy(request, opts) {
286
286
  const side = await pending;
287
287
  const decisions = opts.filterDecisions ? opts.filterDecisions(outcome.decisions, ctx, side, outcome) : outcome.decisions;
288
288
  const groups = swapGroups(decisions);
289
+ const entries = variantEntries(decisions, outcome.entryDecisions);
289
290
  let url = await opts.rewrite?.(ctx, groups, side, outcome);
290
- if (url === void 0 && groups.length) {
291
- const token = await encodeVariant(groups, opts.variantSecret, await opts.extra?.(ctx, side, outcome));
291
+ if (url === void 0 && (groups.length || entries.length)) {
292
+ const token = await encodeVariant(groups, opts.variantSecret, await opts.extra?.(ctx, side, outcome), entries);
292
293
  url = request.nextUrl.clone();
293
294
  url.pathname = `${opts.variantPrefix ?? "/xv"}/${token}${path === "/" ? "" : path}`;
294
295
  }