@xenia-martech/sdk-js 1.0.0-dev.27 → 1.0.0-dev.29

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 (35) hide show
  1. package/CSS_VARIABLES.md +7 -0
  2. package/README.md +50 -1
  3. package/dist/{actions-CkiSdvSa.d.cts → actions-CcBYV--3.d.cts} +177 -1
  4. package/dist/{actions-CkiSdvSa.d.ts → actions-CcBYV--3.d.ts} +177 -1
  5. package/dist/{chunk-UOW3GK4I.cjs → chunk-WYM4CQVG.cjs} +96 -4
  6. package/dist/chunk-WYM4CQVG.cjs.map +1 -0
  7. package/dist/{chunk-7D2HJMW6.js → chunk-XXNDHYAS.js} +96 -4
  8. package/dist/chunk-XXNDHYAS.js.map +1 -0
  9. package/dist/client/index.cjs +543 -27
  10. package/dist/client/index.cjs.map +1 -1
  11. package/dist/client/index.d.cts +112 -3
  12. package/dist/client/index.d.ts +112 -3
  13. package/dist/client/index.js +540 -28
  14. package/dist/client/index.js.map +1 -1
  15. package/dist/client/react/index.cjs +539 -27
  16. package/dist/client/react/index.cjs.map +1 -1
  17. package/dist/client/react/index.d.cts +2 -2
  18. package/dist/client/react/index.d.ts +2 -2
  19. package/dist/client/react/index.js +539 -27
  20. package/dist/client/react/index.js.map +1 -1
  21. package/dist/{cookie-names-C3LKDhsg.d.cts → cookie-names-B3b0XNc2.d.cts} +153 -1
  22. package/dist/{cookie-names-C3LKDhsg.d.ts → cookie-names-B3b0XNc2.d.ts} +153 -1
  23. package/dist/index.cjs +20 -20
  24. package/dist/index.d.cts +2 -2
  25. package/dist/index.d.ts +2 -2
  26. package/dist/index.js +1 -1
  27. package/dist/server/index.cjs +15 -15
  28. package/dist/server/index.d.cts +2 -2
  29. package/dist/server/index.d.ts +2 -2
  30. package/dist/server/index.js +2 -2
  31. package/dist/xenia-sdk.iife.js +37 -3
  32. package/dist/xenia-sdk.iife.js.map +1 -1
  33. package/package.json +1 -1
  34. package/dist/chunk-7D2HJMW6.js.map +0 -1
  35. package/dist/chunk-UOW3GK4I.cjs.map +0 -1
@@ -381,6 +381,109 @@ interface MessageCta {
381
381
  /** Optional event fired when the CTA is clicked. */
382
382
  event?: string;
383
383
  }
384
+ /**
385
+ * Widget-specific rendering/interaction behavior for a message-placement action —
386
+ * ORTHOGONAL to `type` (the existing `banner|popup|modal|inline` placement enum, which
387
+ * stays exactly as-is). `type` says WHERE it renders; `widgetType` says WHAT it is.
388
+ * Keeping these separate is what lets `core/actions.ts`'s `MESSAGE_TYPES` allowlist AND
389
+ * the PHP SDK's `XeniaActions::KNOWN_TYPES` allowlist (same value set) stay completely
390
+ * unchanged — the PHP SDK needs zero code changes for widget support.
391
+ *
392
+ * `"standard"` (or omitted) is a plain message/popup — the existing card path, unmodified.
393
+ * A future 3rd widget type is one new literal here + one new dispatch-table entry in
394
+ * `client/widgets/index.ts`, not a rewrite.
395
+ */
396
+ type WidgetType = "standard" | "spin-wheel";
397
+ /**
398
+ * A prize/outcome segment shown to the visitor for a spin-wheel widget — label/color ONLY.
399
+ * Real weight/prize-code are marketer-authored server-side config (`config.widgetSubmissions`)
400
+ * and never leave the backend; they never appear here.
401
+ */
402
+ interface WidgetSegment {
403
+ id: string;
404
+ label: string;
405
+ colorHex?: string;
406
+ /** Marks this segment as a non-winning outcome (e.g. "Try Again") — drives which of the
407
+ * win/loss reveal screens (see WidgetStyle) the widget shows once this segment resolves. */
408
+ isLoss?: boolean;
409
+ }
410
+ /**
411
+ * The SAFE runtime envelope describing how a widget's captured form submission is
412
+ * dispatched — never a credential, never a prize weight/code (see the cross-repo
413
+ * contract). The SDK does not branch on `mode`'s value itself; it only follows whichever
414
+ * ref field is present (`flowRef` vs `bindingRef`) to pick an endpoint — `mode`/`ref` are
415
+ * otherwise relayed to the backend verbatim, uninterpreted.
416
+ */
417
+ interface WidgetFormSubmit {
418
+ /** `true` for spin-wheel (server must resolve an outcome before anything renders). */
419
+ requiresResolve: boolean;
420
+ /** `"journey"` or `"endpoint"` — informational only; the SDK never branches on this value. */
421
+ mode: "journey" | "endpoint" | (string & {});
422
+ /** Present only when `mode === "journey" && !requiresResolve` — the direct `/flow` fast path, no secret. */
423
+ flowRef?: string;
424
+ /** Present whenever `requiresResolve || mode === "endpoint"`. */
425
+ bindingRef?: string;
426
+ /**
427
+ * Minimum time (ms) to keep the success state visible after a submit resolves, before the
428
+ * card dismisses itself — configured marketer-side on the webhook-response node's
429
+ * Form-submission panel. The real dispatch typically responds in well under 100ms, which
430
+ * would otherwise make the card vanish before a visitor registers it succeeded at all.
431
+ * Defaults to 900 when absent (an older/unconfigured binding).
432
+ */
433
+ successDisplayMs?: number;
434
+ }
435
+ /**
436
+ * Per-action visual overrides for a widget's own window chrome (spin-wheel).
437
+ * Deliberately narrow — everything about the widget's actual CONTENT (spinner/win/loss screens)
438
+ * is full marketer/AI-authored HTML (`spinnerHtml`/`winHtml`/`lossHtml` on `XeniaAction`, same
439
+ * pattern as a popup's `body`), not a field here. This only covers the two things that live
440
+ * OUTSIDE that HTML, in the SDK's own generated chrome around it.
441
+ */
442
+ interface WidgetStyle {
443
+ /**
444
+ * Hides the built-in close (×) button. No spin-wheel renderer draws one of its own anymore
445
+ * (see `spin-wheel.ts`'s `html()`) — every screen's own `spinnerHtml`/`winHtml`/`lossHtml`
446
+ * carries its own close affordance, matched by the same heuristic every custom-HTML surface
447
+ * honors (`wireCloseAffordances`). Currently vestigial: not exposed in Content Studio's AI
448
+ * schema, and not read by any widget renderer's `html()`.
449
+ */
450
+ hideCloseButton?: boolean;
451
+ /** Hides the dimmed backdrop behind the modal/popup/banner. Defaults to shown. */
452
+ hideOverlay?: boolean;
453
+ }
454
+ /**
455
+ * Server-resolved outcome for a spin-wheel submission
456
+ * (`XeniaClient.submitWidgetForm`'s response). Absent for a plain form submit.
457
+ * `segmentId` matches an `id` in the action's `segments` list. Never the whole prize
458
+ * config (weight/internal code) — only what the backend decides is safe to reveal.
459
+ */
460
+ interface WidgetPrize {
461
+ segmentId?: string;
462
+ label?: string;
463
+ colorHex?: string;
464
+ [key: string]: JsonValue | undefined;
465
+ }
466
+ /**
467
+ * Response from a widget form submission (`XeniaClient.submitWidgetForm`) — whichever
468
+ * endpoint was actually hit (the `/flow` fast path or `/widget-submissions`), normalized
469
+ * to one shape. `actions` flows through the existing `parseActions()`/`ActionRenderer.apply()`
470
+ * pipeline unchanged; `prize` is read directly by the spin-wheel widget module to drive
471
+ * its reveal.
472
+ */
473
+ interface WidgetSubmitResponse {
474
+ status: number;
475
+ body: JsonValue;
476
+ actions: XeniaAction[];
477
+ prize?: WidgetPrize;
478
+ /** True when this visitor already played and the stored result is being replayed, not re-rolled. */
479
+ alreadyPlayed?: boolean;
480
+ /** Whether the configured dispatch (journey invoke / outbound endpoint call) actually fired. */
481
+ dispatched?: boolean;
482
+ /** Present when `dispatched` is false and the server attempted but failed the configured dispatch. */
483
+ dispatchError?: string;
484
+ widgetType?: WidgetType;
485
+ receivedAt: number;
486
+ }
384
487
  /**
385
488
  * A render directive the SDK executes in the browser. Marketers emit these in
386
489
  * a `webhook-response` node body under the `xeniaActions` key.
@@ -416,6 +519,43 @@ type XeniaAction = {
416
519
  /** Anchor within the placement (see {@link MessagePosition}). Defaults to the
417
520
  * SDK's built-in default per type (popup: bottom-right; banner: bottom). */
418
521
  position?: MessagePosition;
522
+ /** Orthogonal widget-behavior driver — see {@link WidgetType}. Omitted/`"standard"` renders
523
+ * exactly like today. */
524
+ widgetType?: WidgetType;
525
+ /** Label/color-only outcome segments for `spin-wheel` widgets. */
526
+ segments?: WidgetSegment[];
527
+ /** Safe form-submission envelope — see {@link WidgetFormSubmit}. Absent when the action has
528
+ * no capturable outcome. */
529
+ formSubmit?: WidgetFormSubmit;
530
+ /** Per-action visual overrides for the widget's own window — see {@link WidgetStyle}. */
531
+ style?: WidgetStyle;
532
+ /**
533
+ * Full marketer/AI-authored HTML for `spin-wheel`'s pre-spin face (title/subtitle/spin
534
+ * button/background — the whole visual design) — independent of the generic `html` field
535
+ * above, which spin-wheel never reads. The primary, ordinary way this screen
536
+ * is authored (same role `body` plays for a popup) — there is no separate generated
537
+ * template to fall back to. To keep the wheel and spin button working, include an element
538
+ * carrying `data-xenia-wheel-slot` (the SDK mounts the generated SVG wheel + pointer
539
+ * there) and one carrying `data-xenia-spin` (the SDK wires the spin click there) —
540
+ * omitting either simply drops that capability, same as any other custom-HTML widget.
541
+ */
542
+ spinnerHtml?: string;
543
+ /**
544
+ * Full marketer/AI-authored HTML for the win-reveal screen (`spin-wheel`), shown once a
545
+ * spin resolves to a non-`isLoss` segment — the primary way this screen is authored,
546
+ * same role as {@link spinnerHtml}. Include `data-xenia-wheel-prize` on any element to
547
+ * receive the resolved prize label, and `data-xenia-wheel-cta` on a button to wire its
548
+ * click to dismiss (same close-affordance heuristics as any other custom-HTML widget also
549
+ * apply here — see `wireCloseAffordances`).
550
+ */
551
+ winHtml?: string;
552
+ /**
553
+ * Full marketer/AI-authored HTML for the loss/"try again" screen, shown once a
554
+ * spin resolves to a segment with {@link WidgetSegment.isLoss} set. Same hooks and
555
+ * same primary-authoring role as {@link winHtml} (a losing outcome still has a `label`,
556
+ * e.g. "Try Again", so `data-xenia-wheel-prize` is still honored here).
557
+ */
558
+ lossHtml?: string;
419
559
  } | {
420
560
  type: "redirect";
421
561
  url: string;
@@ -452,6 +592,18 @@ declare class XeniaApi {
452
592
  * duplicate the journey run.
453
593
  */
454
594
  webhook(triggerId: string, data?: JsonValue, method?: "GET" | "POST"): Promise<WebhookResponse>;
595
+ /**
596
+ * Widget form submission — `POST /widget-submissions?ref={bindingRef}`. Used whenever the
597
+ * action's `formSubmit.requiresResolve` is true (spin-wheel, which must have a
598
+ * server-resolved outcome before anything renders) or `mode === "endpoint"` — the common
599
+ * plain-popup case (`mode === "journey" && !requiresResolve`) bypasses this entirely and calls
600
+ * {@link webhook} against `flowRef` instead (see `XeniaClient.submitWidgetForm`'s endpoint
601
+ * selection).
602
+ *
603
+ * Not retried (`noRetry: true`), styled like {@link webhook} — a retried POST must never
604
+ * double-fire a journey or double-resolve a prize server-side.
605
+ */
606
+ submitWidget(ref: string, body?: JsonValue): Promise<WidgetSubmitResponse>;
455
607
  /**
456
608
  * Unified event batch (max 100/request per the backend) — `POST /api/events/v1`.
457
609
  * Records analytics for every event and matches/advances a journey for any
@@ -528,4 +680,4 @@ declare const VISITOR_COOKIE: string;
528
680
  */
529
681
  declare const CONSENT_COOKIE: string;
530
682
 
531
- export { type AnalyticsContext as A, CONSENT_COOKIE as C, DEFAULT_PREFIX as D, type EventContext as E, type HttpMethod as H, type IdentifyRequest as I, type JsonValue as J, type MessageCta as M, type PersonalizationSwap as P, type RetryConfig as R, type TrackOptions as T, VISITOR_COOKIE as V, type WebhookResponse as W, type XeniaAction as X, type AnalyticsEventName as a, type AnalyticsIdentity as b, type AnalyticsIngestResponse as c, type ConsentState as d, type EventIdentity as e, type IdentifyResponse as f, type InteractionType as g, type JsonObject as h, type MessagePlacement as i, type ResolveBatchItem as j, type ResolveBatchResult as k, type ResolveOptions as l, type ResolveResult as m, XeniaApi as n, type XeniaConfig as o, type XeniaEvent as p, consentCookieName as q, parseActions as r, type CallerIdentity as s, visitorCookieName as v };
683
+ export { type AnalyticsContext as A, CONSENT_COOKIE as C, DEFAULT_PREFIX as D, type EventContext as E, type HttpMethod as H, type IdentifyRequest as I, type JsonValue as J, type MessageCta as M, type PersonalizationSwap as P, type RetryConfig as R, type TrackOptions as T, VISITOR_COOKIE as V, type WebhookResponse as W, type XeniaAction as X, type AnalyticsEventName as a, type AnalyticsIdentity as b, type AnalyticsIngestResponse as c, type ConsentState as d, type EventIdentity as e, type IdentifyResponse as f, type InteractionType as g, type JsonObject as h, type MessagePlacement as i, type ResolveBatchItem as j, type ResolveBatchResult as k, type ResolveOptions as l, type ResolveResult as m, type WidgetFormSubmit as n, type WidgetPrize as o, type WidgetSegment as p, type WidgetSubmitResponse as q, type WidgetType as r, XeniaApi as s, type XeniaConfig as t, type XeniaEvent as u, consentCookieName as v, parseActions as w, visitorCookieName as x, type CallerIdentity as y };
@@ -381,6 +381,109 @@ interface MessageCta {
381
381
  /** Optional event fired when the CTA is clicked. */
382
382
  event?: string;
383
383
  }
384
+ /**
385
+ * Widget-specific rendering/interaction behavior for a message-placement action —
386
+ * ORTHOGONAL to `type` (the existing `banner|popup|modal|inline` placement enum, which
387
+ * stays exactly as-is). `type` says WHERE it renders; `widgetType` says WHAT it is.
388
+ * Keeping these separate is what lets `core/actions.ts`'s `MESSAGE_TYPES` allowlist AND
389
+ * the PHP SDK's `XeniaActions::KNOWN_TYPES` allowlist (same value set) stay completely
390
+ * unchanged — the PHP SDK needs zero code changes for widget support.
391
+ *
392
+ * `"standard"` (or omitted) is a plain message/popup — the existing card path, unmodified.
393
+ * A future 3rd widget type is one new literal here + one new dispatch-table entry in
394
+ * `client/widgets/index.ts`, not a rewrite.
395
+ */
396
+ type WidgetType = "standard" | "spin-wheel";
397
+ /**
398
+ * A prize/outcome segment shown to the visitor for a spin-wheel widget — label/color ONLY.
399
+ * Real weight/prize-code are marketer-authored server-side config (`config.widgetSubmissions`)
400
+ * and never leave the backend; they never appear here.
401
+ */
402
+ interface WidgetSegment {
403
+ id: string;
404
+ label: string;
405
+ colorHex?: string;
406
+ /** Marks this segment as a non-winning outcome (e.g. "Try Again") — drives which of the
407
+ * win/loss reveal screens (see WidgetStyle) the widget shows once this segment resolves. */
408
+ isLoss?: boolean;
409
+ }
410
+ /**
411
+ * The SAFE runtime envelope describing how a widget's captured form submission is
412
+ * dispatched — never a credential, never a prize weight/code (see the cross-repo
413
+ * contract). The SDK does not branch on `mode`'s value itself; it only follows whichever
414
+ * ref field is present (`flowRef` vs `bindingRef`) to pick an endpoint — `mode`/`ref` are
415
+ * otherwise relayed to the backend verbatim, uninterpreted.
416
+ */
417
+ interface WidgetFormSubmit {
418
+ /** `true` for spin-wheel (server must resolve an outcome before anything renders). */
419
+ requiresResolve: boolean;
420
+ /** `"journey"` or `"endpoint"` — informational only; the SDK never branches on this value. */
421
+ mode: "journey" | "endpoint" | (string & {});
422
+ /** Present only when `mode === "journey" && !requiresResolve` — the direct `/flow` fast path, no secret. */
423
+ flowRef?: string;
424
+ /** Present whenever `requiresResolve || mode === "endpoint"`. */
425
+ bindingRef?: string;
426
+ /**
427
+ * Minimum time (ms) to keep the success state visible after a submit resolves, before the
428
+ * card dismisses itself — configured marketer-side on the webhook-response node's
429
+ * Form-submission panel. The real dispatch typically responds in well under 100ms, which
430
+ * would otherwise make the card vanish before a visitor registers it succeeded at all.
431
+ * Defaults to 900 when absent (an older/unconfigured binding).
432
+ */
433
+ successDisplayMs?: number;
434
+ }
435
+ /**
436
+ * Per-action visual overrides for a widget's own window chrome (spin-wheel).
437
+ * Deliberately narrow — everything about the widget's actual CONTENT (spinner/win/loss screens)
438
+ * is full marketer/AI-authored HTML (`spinnerHtml`/`winHtml`/`lossHtml` on `XeniaAction`, same
439
+ * pattern as a popup's `body`), not a field here. This only covers the two things that live
440
+ * OUTSIDE that HTML, in the SDK's own generated chrome around it.
441
+ */
442
+ interface WidgetStyle {
443
+ /**
444
+ * Hides the built-in close (×) button. No spin-wheel renderer draws one of its own anymore
445
+ * (see `spin-wheel.ts`'s `html()`) — every screen's own `spinnerHtml`/`winHtml`/`lossHtml`
446
+ * carries its own close affordance, matched by the same heuristic every custom-HTML surface
447
+ * honors (`wireCloseAffordances`). Currently vestigial: not exposed in Content Studio's AI
448
+ * schema, and not read by any widget renderer's `html()`.
449
+ */
450
+ hideCloseButton?: boolean;
451
+ /** Hides the dimmed backdrop behind the modal/popup/banner. Defaults to shown. */
452
+ hideOverlay?: boolean;
453
+ }
454
+ /**
455
+ * Server-resolved outcome for a spin-wheel submission
456
+ * (`XeniaClient.submitWidgetForm`'s response). Absent for a plain form submit.
457
+ * `segmentId` matches an `id` in the action's `segments` list. Never the whole prize
458
+ * config (weight/internal code) — only what the backend decides is safe to reveal.
459
+ */
460
+ interface WidgetPrize {
461
+ segmentId?: string;
462
+ label?: string;
463
+ colorHex?: string;
464
+ [key: string]: JsonValue | undefined;
465
+ }
466
+ /**
467
+ * Response from a widget form submission (`XeniaClient.submitWidgetForm`) — whichever
468
+ * endpoint was actually hit (the `/flow` fast path or `/widget-submissions`), normalized
469
+ * to one shape. `actions` flows through the existing `parseActions()`/`ActionRenderer.apply()`
470
+ * pipeline unchanged; `prize` is read directly by the spin-wheel widget module to drive
471
+ * its reveal.
472
+ */
473
+ interface WidgetSubmitResponse {
474
+ status: number;
475
+ body: JsonValue;
476
+ actions: XeniaAction[];
477
+ prize?: WidgetPrize;
478
+ /** True when this visitor already played and the stored result is being replayed, not re-rolled. */
479
+ alreadyPlayed?: boolean;
480
+ /** Whether the configured dispatch (journey invoke / outbound endpoint call) actually fired. */
481
+ dispatched?: boolean;
482
+ /** Present when `dispatched` is false and the server attempted but failed the configured dispatch. */
483
+ dispatchError?: string;
484
+ widgetType?: WidgetType;
485
+ receivedAt: number;
486
+ }
384
487
  /**
385
488
  * A render directive the SDK executes in the browser. Marketers emit these in
386
489
  * a `webhook-response` node body under the `xeniaActions` key.
@@ -416,6 +519,43 @@ type XeniaAction = {
416
519
  /** Anchor within the placement (see {@link MessagePosition}). Defaults to the
417
520
  * SDK's built-in default per type (popup: bottom-right; banner: bottom). */
418
521
  position?: MessagePosition;
522
+ /** Orthogonal widget-behavior driver — see {@link WidgetType}. Omitted/`"standard"` renders
523
+ * exactly like today. */
524
+ widgetType?: WidgetType;
525
+ /** Label/color-only outcome segments for `spin-wheel` widgets. */
526
+ segments?: WidgetSegment[];
527
+ /** Safe form-submission envelope — see {@link WidgetFormSubmit}. Absent when the action has
528
+ * no capturable outcome. */
529
+ formSubmit?: WidgetFormSubmit;
530
+ /** Per-action visual overrides for the widget's own window — see {@link WidgetStyle}. */
531
+ style?: WidgetStyle;
532
+ /**
533
+ * Full marketer/AI-authored HTML for `spin-wheel`'s pre-spin face (title/subtitle/spin
534
+ * button/background — the whole visual design) — independent of the generic `html` field
535
+ * above, which spin-wheel never reads. The primary, ordinary way this screen
536
+ * is authored (same role `body` plays for a popup) — there is no separate generated
537
+ * template to fall back to. To keep the wheel and spin button working, include an element
538
+ * carrying `data-xenia-wheel-slot` (the SDK mounts the generated SVG wheel + pointer
539
+ * there) and one carrying `data-xenia-spin` (the SDK wires the spin click there) —
540
+ * omitting either simply drops that capability, same as any other custom-HTML widget.
541
+ */
542
+ spinnerHtml?: string;
543
+ /**
544
+ * Full marketer/AI-authored HTML for the win-reveal screen (`spin-wheel`), shown once a
545
+ * spin resolves to a non-`isLoss` segment — the primary way this screen is authored,
546
+ * same role as {@link spinnerHtml}. Include `data-xenia-wheel-prize` on any element to
547
+ * receive the resolved prize label, and `data-xenia-wheel-cta` on a button to wire its
548
+ * click to dismiss (same close-affordance heuristics as any other custom-HTML widget also
549
+ * apply here — see `wireCloseAffordances`).
550
+ */
551
+ winHtml?: string;
552
+ /**
553
+ * Full marketer/AI-authored HTML for the loss/"try again" screen, shown once a
554
+ * spin resolves to a segment with {@link WidgetSegment.isLoss} set. Same hooks and
555
+ * same primary-authoring role as {@link winHtml} (a losing outcome still has a `label`,
556
+ * e.g. "Try Again", so `data-xenia-wheel-prize` is still honored here).
557
+ */
558
+ lossHtml?: string;
419
559
  } | {
420
560
  type: "redirect";
421
561
  url: string;
@@ -452,6 +592,18 @@ declare class XeniaApi {
452
592
  * duplicate the journey run.
453
593
  */
454
594
  webhook(triggerId: string, data?: JsonValue, method?: "GET" | "POST"): Promise<WebhookResponse>;
595
+ /**
596
+ * Widget form submission — `POST /widget-submissions?ref={bindingRef}`. Used whenever the
597
+ * action's `formSubmit.requiresResolve` is true (spin-wheel, which must have a
598
+ * server-resolved outcome before anything renders) or `mode === "endpoint"` — the common
599
+ * plain-popup case (`mode === "journey" && !requiresResolve`) bypasses this entirely and calls
600
+ * {@link webhook} against `flowRef` instead (see `XeniaClient.submitWidgetForm`'s endpoint
601
+ * selection).
602
+ *
603
+ * Not retried (`noRetry: true`), styled like {@link webhook} — a retried POST must never
604
+ * double-fire a journey or double-resolve a prize server-side.
605
+ */
606
+ submitWidget(ref: string, body?: JsonValue): Promise<WidgetSubmitResponse>;
455
607
  /**
456
608
  * Unified event batch (max 100/request per the backend) — `POST /api/events/v1`.
457
609
  * Records analytics for every event and matches/advances a journey for any
@@ -528,4 +680,4 @@ declare const VISITOR_COOKIE: string;
528
680
  */
529
681
  declare const CONSENT_COOKIE: string;
530
682
 
531
- export { type AnalyticsContext as A, CONSENT_COOKIE as C, DEFAULT_PREFIX as D, type EventContext as E, type HttpMethod as H, type IdentifyRequest as I, type JsonValue as J, type MessageCta as M, type PersonalizationSwap as P, type RetryConfig as R, type TrackOptions as T, VISITOR_COOKIE as V, type WebhookResponse as W, type XeniaAction as X, type AnalyticsEventName as a, type AnalyticsIdentity as b, type AnalyticsIngestResponse as c, type ConsentState as d, type EventIdentity as e, type IdentifyResponse as f, type InteractionType as g, type JsonObject as h, type MessagePlacement as i, type ResolveBatchItem as j, type ResolveBatchResult as k, type ResolveOptions as l, type ResolveResult as m, XeniaApi as n, type XeniaConfig as o, type XeniaEvent as p, consentCookieName as q, parseActions as r, type CallerIdentity as s, visitorCookieName as v };
683
+ export { type AnalyticsContext as A, CONSENT_COOKIE as C, DEFAULT_PREFIX as D, type EventContext as E, type HttpMethod as H, type IdentifyRequest as I, type JsonValue as J, type MessageCta as M, type PersonalizationSwap as P, type RetryConfig as R, type TrackOptions as T, VISITOR_COOKIE as V, type WebhookResponse as W, type XeniaAction as X, type AnalyticsEventName as a, type AnalyticsIdentity as b, type AnalyticsIngestResponse as c, type ConsentState as d, type EventIdentity as e, type IdentifyResponse as f, type InteractionType as g, type JsonObject as h, type MessagePlacement as i, type ResolveBatchItem as j, type ResolveBatchResult as k, type ResolveOptions as l, type ResolveResult as m, type WidgetFormSubmit as n, type WidgetPrize as o, type WidgetSegment as p, type WidgetSubmitResponse as q, type WidgetType as r, XeniaApi as s, type XeniaConfig as t, type XeniaEvent as u, consentCookieName as v, parseActions as w, visitorCookieName as x, type CallerIdentity as y };
package/dist/index.cjs CHANGED
@@ -1,84 +1,84 @@
1
1
  'use strict';
2
2
 
3
- var chunkUOW3GK4I_cjs = require('./chunk-UOW3GK4I.cjs');
3
+ var chunkWYM4CQVG_cjs = require('./chunk-WYM4CQVG.cjs');
4
4
 
5
5
 
6
6
 
7
7
  Object.defineProperty(exports, "CONSENT_COOKIE", {
8
8
  enumerable: true,
9
- get: function () { return chunkUOW3GK4I_cjs.CONSENT_COOKIE; }
9
+ get: function () { return chunkWYM4CQVG_cjs.CONSENT_COOKIE; }
10
10
  });
11
11
  Object.defineProperty(exports, "DEFAULT_PREFIX", {
12
12
  enumerable: true,
13
- get: function () { return chunkUOW3GK4I_cjs.DEFAULT_PREFIX; }
13
+ get: function () { return chunkWYM4CQVG_cjs.DEFAULT_PREFIX; }
14
14
  });
15
15
  Object.defineProperty(exports, "HttpClient", {
16
16
  enumerable: true,
17
- get: function () { return chunkUOW3GK4I_cjs.HttpClient; }
17
+ get: function () { return chunkWYM4CQVG_cjs.HttpClient; }
18
18
  });
19
19
  Object.defineProperty(exports, "HttpError", {
20
20
  enumerable: true,
21
- get: function () { return chunkUOW3GK4I_cjs.HttpError; }
21
+ get: function () { return chunkWYM4CQVG_cjs.HttpError; }
22
22
  });
23
23
  Object.defineProperty(exports, "LocalStorageResponseStore", {
24
24
  enumerable: true,
25
- get: function () { return chunkUOW3GK4I_cjs.LocalStorageResponseStore; }
25
+ get: function () { return chunkWYM4CQVG_cjs.LocalStorageResponseStore; }
26
26
  });
27
27
  Object.defineProperty(exports, "MAX_EVENT_ID_LENGTH", {
28
28
  enumerable: true,
29
- get: function () { return chunkUOW3GK4I_cjs.MAX_EVENT_ID_LENGTH; }
29
+ get: function () { return chunkWYM4CQVG_cjs.MAX_EVENT_ID_LENGTH; }
30
30
  });
31
31
  Object.defineProperty(exports, "MemoryResponseStore", {
32
32
  enumerable: true,
33
- get: function () { return chunkUOW3GK4I_cjs.MemoryResponseStore; }
33
+ get: function () { return chunkWYM4CQVG_cjs.MemoryResponseStore; }
34
34
  });
35
35
  Object.defineProperty(exports, "VISITOR_COOKIE", {
36
36
  enumerable: true,
37
- get: function () { return chunkUOW3GK4I_cjs.VISITOR_COOKIE; }
37
+ get: function () { return chunkWYM4CQVG_cjs.VISITOR_COOKIE; }
38
38
  });
39
39
  Object.defineProperty(exports, "XeniaApi", {
40
40
  enumerable: true,
41
- get: function () { return chunkUOW3GK4I_cjs.XeniaApi; }
41
+ get: function () { return chunkWYM4CQVG_cjs.XeniaApi; }
42
42
  });
43
43
  Object.defineProperty(exports, "buildUrl", {
44
44
  enumerable: true,
45
- get: function () { return chunkUOW3GK4I_cjs.buildUrl; }
45
+ get: function () { return chunkWYM4CQVG_cjs.buildUrl; }
46
46
  });
47
47
  Object.defineProperty(exports, "consentCookieName", {
48
48
  enumerable: true,
49
- get: function () { return chunkUOW3GK4I_cjs.consentCookieName; }
49
+ get: function () { return chunkWYM4CQVG_cjs.consentCookieName; }
50
50
  });
51
51
  Object.defineProperty(exports, "contextFromUrl", {
52
52
  enumerable: true,
53
- get: function () { return chunkUOW3GK4I_cjs.contextFromUrl; }
53
+ get: function () { return chunkWYM4CQVG_cjs.contextFromUrl; }
54
54
  });
55
55
  Object.defineProperty(exports, "extractContentSwaps", {
56
56
  enumerable: true,
57
- get: function () { return chunkUOW3GK4I_cjs.extractContentSwaps; }
57
+ get: function () { return chunkWYM4CQVG_cjs.extractContentSwaps; }
58
58
  });
59
59
  Object.defineProperty(exports, "generateUlid", {
60
60
  enumerable: true,
61
- get: function () { return chunkUOW3GK4I_cjs.generateUlid; }
61
+ get: function () { return chunkWYM4CQVG_cjs.generateUlid; }
62
62
  });
63
63
  Object.defineProperty(exports, "isBrowser", {
64
64
  enumerable: true,
65
- get: function () { return chunkUOW3GK4I_cjs.isBrowser; }
65
+ get: function () { return chunkWYM4CQVG_cjs.isBrowser; }
66
66
  });
67
67
  Object.defineProperty(exports, "parseActions", {
68
68
  enumerable: true,
69
- get: function () { return chunkUOW3GK4I_cjs.parseActions; }
69
+ get: function () { return chunkWYM4CQVG_cjs.parseActions; }
70
70
  });
71
71
  Object.defineProperty(exports, "spliceSlots", {
72
72
  enumerable: true,
73
- get: function () { return chunkUOW3GK4I_cjs.spliceSlots; }
73
+ get: function () { return chunkWYM4CQVG_cjs.spliceSlots; }
74
74
  });
75
75
  Object.defineProperty(exports, "toEventId", {
76
76
  enumerable: true,
77
- get: function () { return chunkUOW3GK4I_cjs.toEventId; }
77
+ get: function () { return chunkWYM4CQVG_cjs.toEventId; }
78
78
  });
79
79
  Object.defineProperty(exports, "visitorCookieName", {
80
80
  enumerable: true,
81
- get: function () { return chunkUOW3GK4I_cjs.visitorCookieName; }
81
+ get: function () { return chunkWYM4CQVG_cjs.visitorCookieName; }
82
82
  });
83
83
  //# sourceMappingURL=index.cjs.map
84
84
  //# sourceMappingURL=index.cjs.map
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RetryConfig, H as HttpMethod, J as JsonValue, E as EventContext, W as WebhookResponse } from './cookie-names-C3LKDhsg.cjs';
2
- export { A as AnalyticsContext, a as AnalyticsEventName, b as AnalyticsIdentity, c as AnalyticsIngestResponse, C as CONSENT_COOKIE, d as ConsentState, D as DEFAULT_PREFIX, e as EventIdentity, I as IdentifyRequest, f as IdentifyResponse, g as InteractionType, h as JsonObject, M as MessageCta, i as MessagePlacement, P as PersonalizationSwap, j as ResolveBatchItem, k as ResolveBatchResult, l as ResolveOptions, m as ResolveResult, T as TrackOptions, V as VISITOR_COOKIE, X as XeniaAction, n as XeniaApi, o as XeniaConfig, p as XeniaEvent, q as consentCookieName, r as parseActions, v as visitorCookieName } from './cookie-names-C3LKDhsg.cjs';
1
+ import { R as RetryConfig, H as HttpMethod, J as JsonValue, E as EventContext, W as WebhookResponse } from './cookie-names-B3b0XNc2.cjs';
2
+ export { A as AnalyticsContext, a as AnalyticsEventName, b as AnalyticsIdentity, c as AnalyticsIngestResponse, C as CONSENT_COOKIE, d as ConsentState, D as DEFAULT_PREFIX, e as EventIdentity, I as IdentifyRequest, f as IdentifyResponse, g as InteractionType, h as JsonObject, M as MessageCta, i as MessagePlacement, P as PersonalizationSwap, j as ResolveBatchItem, k as ResolveBatchResult, l as ResolveOptions, m as ResolveResult, T as TrackOptions, V as VISITOR_COOKIE, n as WidgetFormSubmit, o as WidgetPrize, p as WidgetSegment, q as WidgetSubmitResponse, r as WidgetType, X as XeniaAction, s as XeniaApi, t as XeniaConfig, u as XeniaEvent, v as consentCookieName, w as parseActions, x as visitorCookieName } from './cookie-names-B3b0XNc2.cjs';
3
3
 
4
4
  /** Returns true when running in a browser environment (SSR-safe). */
5
5
  declare function isBrowser(): boolean;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RetryConfig, H as HttpMethod, J as JsonValue, E as EventContext, W as WebhookResponse } from './cookie-names-C3LKDhsg.js';
2
- export { A as AnalyticsContext, a as AnalyticsEventName, b as AnalyticsIdentity, c as AnalyticsIngestResponse, C as CONSENT_COOKIE, d as ConsentState, D as DEFAULT_PREFIX, e as EventIdentity, I as IdentifyRequest, f as IdentifyResponse, g as InteractionType, h as JsonObject, M as MessageCta, i as MessagePlacement, P as PersonalizationSwap, j as ResolveBatchItem, k as ResolveBatchResult, l as ResolveOptions, m as ResolveResult, T as TrackOptions, V as VISITOR_COOKIE, X as XeniaAction, n as XeniaApi, o as XeniaConfig, p as XeniaEvent, q as consentCookieName, r as parseActions, v as visitorCookieName } from './cookie-names-C3LKDhsg.js';
1
+ import { R as RetryConfig, H as HttpMethod, J as JsonValue, E as EventContext, W as WebhookResponse } from './cookie-names-B3b0XNc2.js';
2
+ export { A as AnalyticsContext, a as AnalyticsEventName, b as AnalyticsIdentity, c as AnalyticsIngestResponse, C as CONSENT_COOKIE, d as ConsentState, D as DEFAULT_PREFIX, e as EventIdentity, I as IdentifyRequest, f as IdentifyResponse, g as InteractionType, h as JsonObject, M as MessageCta, i as MessagePlacement, P as PersonalizationSwap, j as ResolveBatchItem, k as ResolveBatchResult, l as ResolveOptions, m as ResolveResult, T as TrackOptions, V as VISITOR_COOKIE, n as WidgetFormSubmit, o as WidgetPrize, p as WidgetSegment, q as WidgetSubmitResponse, r as WidgetType, X as XeniaAction, s as XeniaApi, t as XeniaConfig, u as XeniaEvent, v as consentCookieName, w as parseActions, x as visitorCookieName } from './cookie-names-B3b0XNc2.js';
3
3
 
4
4
  /** Returns true when running in a browser environment (SSR-safe). */
5
5
  declare function isBrowser(): boolean;
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export { CONSENT_COOKIE, DEFAULT_PREFIX, HttpClient, HttpError, LocalStorageResponseStore, MAX_EVENT_ID_LENGTH, MemoryResponseStore, VISITOR_COOKIE, XeniaApi, buildUrl, consentCookieName, contextFromUrl, extractContentSwaps, generateUlid, isBrowser, parseActions, spliceSlots, toEventId, visitorCookieName } from './chunk-7D2HJMW6.js';
1
+ export { CONSENT_COOKIE, DEFAULT_PREFIX, HttpClient, HttpError, LocalStorageResponseStore, MAX_EVENT_ID_LENGTH, MemoryResponseStore, VISITOR_COOKIE, XeniaApi, buildUrl, consentCookieName, contextFromUrl, extractContentSwaps, generateUlid, isBrowser, parseActions, spliceSlots, toEventId, visitorCookieName } from './chunk-XXNDHYAS.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkUOW3GK4I_cjs = require('../chunk-UOW3GK4I.cjs');
3
+ var chunkWYM4CQVG_cjs = require('../chunk-WYM4CQVG.cjs');
4
4
 
5
5
  // src/core/event-payload.ts
6
6
  var RESERVED = /* @__PURE__ */ new Set([
@@ -62,7 +62,7 @@ var XeniaServer = class {
62
62
  /** Ambient request context attached to every call — see {@link XeniaConfig.context}. */
63
63
  context;
64
64
  constructor(config) {
65
- this.api = new chunkUOW3GK4I_cjs.XeniaApi(config);
65
+ this.api = new chunkWYM4CQVG_cjs.XeniaApi(config);
66
66
  this.visitorId = config.visitorId;
67
67
  this.context = config.context;
68
68
  }
@@ -75,7 +75,7 @@ var XeniaServer = class {
75
75
  async track(eventName, opts = {}) {
76
76
  const event = {
77
77
  eventName,
78
- eventId: opts.eventId ? chunkUOW3GK4I_cjs.toEventId(opts.eventId) : chunkUOW3GK4I_cjs.generateUlid(),
78
+ eventId: opts.eventId ? chunkWYM4CQVG_cjs.toEventId(opts.eventId) : chunkWYM4CQVG_cjs.generateUlid(),
79
79
  eventVersion: opts.eventVersion ?? 1,
80
80
  occurredAtMs: opts.occurredAtMs ?? Date.now(),
81
81
  source: opts.source ?? "xenia-server-sdk",
@@ -153,13 +153,13 @@ var XeniaServer = class {
153
153
  * nothing was passed — preserving today's behavior for callers using neither.
154
154
  */
155
155
  withVisitor(opts) {
156
- const identity = chunkUOW3GK4I_cjs.compact({
156
+ const identity = chunkWYM4CQVG_cjs.compact({
157
157
  ...opts?.identity,
158
158
  visitorId: this.visitorId ?? opts?.identity?.visitorId
159
159
  });
160
160
  const merged = {
161
- ...chunkUOW3GK4I_cjs.compact(this.context ?? {}),
162
- ...chunkUOW3GK4I_cjs.compact(opts?.context ?? {}),
161
+ ...chunkWYM4CQVG_cjs.compact(this.context ?? {}),
162
+ ...chunkWYM4CQVG_cjs.compact(opts?.context ?? {}),
163
163
  ...identity
164
164
  };
165
165
  if (Object.keys(merged).length === 0 && !this.visitorId) return opts;
@@ -173,7 +173,7 @@ function createXeniaServer(config) {
173
173
 
174
174
  // src/server/token.ts
175
175
  async function refreshSdkToken(opts) {
176
- const http = new chunkUOW3GK4I_cjs.HttpClient({ baseUrl: opts.baseUrl, timeout: opts.timeout });
176
+ const http = new chunkWYM4CQVG_cjs.HttpClient({ baseUrl: opts.baseUrl, timeout: opts.timeout });
177
177
  const { data } = await http.request({
178
178
  method: "POST",
179
179
  path: "/api/personalization/token/refresh",
@@ -218,10 +218,10 @@ function parseCookies(header) {
218
218
  return out;
219
219
  }
220
220
  function getVisitorId(cookieHeader, prefix) {
221
- return parseCookies(cookieHeader)[chunkUOW3GK4I_cjs.visitorCookieName(prefix)] ?? null;
221
+ return parseCookies(cookieHeader)[chunkWYM4CQVG_cjs.visitorCookieName(prefix)] ?? null;
222
222
  }
223
223
  function getConsent(cookieHeader, prefix) {
224
- const raw = parseCookies(cookieHeader)[chunkUOW3GK4I_cjs.consentCookieName(prefix)];
224
+ const raw = parseCookies(cookieHeader)[chunkWYM4CQVG_cjs.consentCookieName(prefix)];
225
225
  if (!raw) return { analytics: false, marketing: false, personalization: false };
226
226
  try {
227
227
  const parsed = JSON.parse(raw);
@@ -238,27 +238,27 @@ function getConsent(cookieHeader, prefix) {
238
238
 
239
239
  Object.defineProperty(exports, "CONSENT_COOKIE", {
240
240
  enumerable: true,
241
- get: function () { return chunkUOW3GK4I_cjs.CONSENT_COOKIE; }
241
+ get: function () { return chunkWYM4CQVG_cjs.CONSENT_COOKIE; }
242
242
  });
243
243
  Object.defineProperty(exports, "VISITOR_COOKIE", {
244
244
  enumerable: true,
245
- get: function () { return chunkUOW3GK4I_cjs.VISITOR_COOKIE; }
245
+ get: function () { return chunkWYM4CQVG_cjs.VISITOR_COOKIE; }
246
246
  });
247
247
  Object.defineProperty(exports, "XeniaApi", {
248
248
  enumerable: true,
249
- get: function () { return chunkUOW3GK4I_cjs.XeniaApi; }
249
+ get: function () { return chunkWYM4CQVG_cjs.XeniaApi; }
250
250
  });
251
251
  Object.defineProperty(exports, "consentCookieName", {
252
252
  enumerable: true,
253
- get: function () { return chunkUOW3GK4I_cjs.consentCookieName; }
253
+ get: function () { return chunkWYM4CQVG_cjs.consentCookieName; }
254
254
  });
255
255
  Object.defineProperty(exports, "parseActions", {
256
256
  enumerable: true,
257
- get: function () { return chunkUOW3GK4I_cjs.parseActions; }
257
+ get: function () { return chunkWYM4CQVG_cjs.parseActions; }
258
258
  });
259
259
  Object.defineProperty(exports, "visitorCookieName", {
260
260
  enumerable: true,
261
- get: function () { return chunkUOW3GK4I_cjs.visitorCookieName; }
261
+ get: function () { return chunkWYM4CQVG_cjs.visitorCookieName; }
262
262
  });
263
263
  exports.XeniaServer = XeniaServer;
264
264
  exports.createTokenRoute = createTokenRoute;
@@ -1,5 +1,5 @@
1
- import { s as CallerIdentity, A as AnalyticsContext, J as JsonValue, d as ConsentState, e as EventIdentity, E as EventContext, n as XeniaApi, o as XeniaConfig, a as AnalyticsEventName, c as AnalyticsIngestResponse, W as WebhookResponse, I as IdentifyRequest, f as IdentifyResponse, l as ResolveOptions, m as ResolveResult, j as ResolveBatchItem, k as ResolveBatchResult } from '../cookie-names-C3LKDhsg.cjs';
2
- export { b as AnalyticsIdentity, C as CONSENT_COOKIE, P as PersonalizationSwap, V as VISITOR_COOKIE, p as XeniaEvent, q as consentCookieName, r as parseActions, v as visitorCookieName } from '../cookie-names-C3LKDhsg.cjs';
1
+ import { y as CallerIdentity, A as AnalyticsContext, J as JsonValue, d as ConsentState, e as EventIdentity, E as EventContext, s as XeniaApi, t as XeniaConfig, a as AnalyticsEventName, c as AnalyticsIngestResponse, W as WebhookResponse, I as IdentifyRequest, f as IdentifyResponse, l as ResolveOptions, m as ResolveResult, j as ResolveBatchItem, k as ResolveBatchResult } from '../cookie-names-B3b0XNc2.cjs';
2
+ export { b as AnalyticsIdentity, C as CONSENT_COOKIE, P as PersonalizationSwap, V as VISITOR_COOKIE, u as XeniaEvent, v as consentCookieName, w as parseActions, x as visitorCookieName } from '../cookie-names-B3b0XNc2.cjs';
3
3
 
4
4
  /**
5
5
  * Extra per-call identity/context for server-side webhook calls — an override on top of whatever the
@@ -1,5 +1,5 @@
1
- import { s as CallerIdentity, A as AnalyticsContext, J as JsonValue, d as ConsentState, e as EventIdentity, E as EventContext, n as XeniaApi, o as XeniaConfig, a as AnalyticsEventName, c as AnalyticsIngestResponse, W as WebhookResponse, I as IdentifyRequest, f as IdentifyResponse, l as ResolveOptions, m as ResolveResult, j as ResolveBatchItem, k as ResolveBatchResult } from '../cookie-names-C3LKDhsg.js';
2
- export { b as AnalyticsIdentity, C as CONSENT_COOKIE, P as PersonalizationSwap, V as VISITOR_COOKIE, p as XeniaEvent, q as consentCookieName, r as parseActions, v as visitorCookieName } from '../cookie-names-C3LKDhsg.js';
1
+ import { y as CallerIdentity, A as AnalyticsContext, J as JsonValue, d as ConsentState, e as EventIdentity, E as EventContext, s as XeniaApi, t as XeniaConfig, a as AnalyticsEventName, c as AnalyticsIngestResponse, W as WebhookResponse, I as IdentifyRequest, f as IdentifyResponse, l as ResolveOptions, m as ResolveResult, j as ResolveBatchItem, k as ResolveBatchResult } from '../cookie-names-B3b0XNc2.js';
2
+ export { b as AnalyticsIdentity, C as CONSENT_COOKIE, P as PersonalizationSwap, V as VISITOR_COOKIE, u as XeniaEvent, v as consentCookieName, w as parseActions, x as visitorCookieName } from '../cookie-names-B3b0XNc2.js';
3
3
 
4
4
  /**
5
5
  * Extra per-call identity/context for server-side webhook calls — an override on top of whatever the
@@ -1,5 +1,5 @@
1
- import { XeniaApi, toEventId, generateUlid, compact, HttpClient, visitorCookieName, consentCookieName } from '../chunk-7D2HJMW6.js';
2
- export { CONSENT_COOKIE, VISITOR_COOKIE, XeniaApi, consentCookieName, parseActions, visitorCookieName } from '../chunk-7D2HJMW6.js';
1
+ import { XeniaApi, toEventId, generateUlid, compact, HttpClient, visitorCookieName, consentCookieName } from '../chunk-XXNDHYAS.js';
2
+ export { CONSENT_COOKIE, VISITOR_COOKIE, XeniaApi, consentCookieName, parseActions, visitorCookieName } from '../chunk-XXNDHYAS.js';
3
3
 
4
4
  // src/core/event-payload.ts
5
5
  var RESERVED = /* @__PURE__ */ new Set([