@xenia-martech/sdk-js 1.0.1-dev.1 → 1.1.0-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -4
- package/dist/{actions-CcBYV--3.d.cts → actions-CKeiofxJ.d.cts} +19 -1
- package/dist/{actions-CcBYV--3.d.ts → actions-CKeiofxJ.d.ts} +19 -1
- package/dist/{cookie-names-B3b0XNc2.d.cts → api-URhxxi4x.d.cts} +19 -42
- package/dist/{cookie-names-B3b0XNc2.d.ts → api-URhxxi4x.d.ts} +19 -42
- package/dist/chunk-5D7SJIO4.cjs +109 -0
- package/dist/chunk-5D7SJIO4.cjs.map +1 -0
- package/dist/{chunk-XXNDHYAS.js → chunk-FYSEKFIY.js} +45 -103
- package/dist/chunk-FYSEKFIY.js.map +1 -0
- package/dist/{chunk-WYM4CQVG.cjs → chunk-JEKVN7HK.cjs} +46 -106
- package/dist/chunk-JEKVN7HK.cjs.map +1 -0
- package/dist/chunk-TLTG3BTC.js +104 -0
- package/dist/chunk-TLTG3BTC.js.map +1 -0
- package/dist/chunk-U2WBBOYT.cjs +233 -0
- package/dist/chunk-U2WBBOYT.cjs.map +1 -0
- package/dist/chunk-WYAMPEVV.js +227 -0
- package/dist/chunk-WYAMPEVV.js.map +1 -0
- package/dist/client/index.cjs +60 -6
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +25 -3
- package/dist/client/index.d.ts +25 -3
- package/dist/client/index.js +59 -7
- package/dist/client/index.js.map +1 -1
- package/dist/client/react/index.cjs +58 -6
- package/dist/client/react/index.cjs.map +1 -1
- package/dist/client/react/index.d.cts +2 -2
- package/dist/client/react/index.d.ts +2 -2
- package/dist/client/react/index.js +58 -6
- package/dist/client/react/index.js.map +1 -1
- package/dist/cookie-names-8FxbGKGS.d.ts +127 -0
- package/dist/cookie-names-QYMiEMAq.d.cts +127 -0
- package/dist/index.cjs +41 -32
- package/dist/index.d.cts +4 -71
- package/dist/index.d.ts +4 -71
- package/dist/index.js +2 -1
- package/dist/next/index.cjs +59 -0
- package/dist/next/index.cjs.map +1 -0
- package/dist/next/index.d.cts +45 -0
- package/dist/next/index.d.ts +45 -0
- package/dist/next/index.js +54 -0
- package/dist/next/index.js.map +1 -0
- package/dist/server/index.cjs +38 -214
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +5 -104
- package/dist/server/index.d.ts +5 -104
- package/dist/server/index.js +5 -204
- package/dist/server/index.js.map +1 -1
- package/dist/xenia-sdk.iife.js +3 -3
- package/dist/xenia-sdk.iife.js.map +1 -1
- package/dist/xenia-server-D-ozqSgv.d.ts +126 -0
- package/dist/xenia-server-rs3Gpbw7.d.cts +126 -0
- package/package.json +26 -7
- package/dist/chunk-WYM4CQVG.cjs.map +0 -1
- package/dist/chunk-XXNDHYAS.js.map +0 -1
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { m as RetryConfig, C as CircuitBreakerConfig, H as HttpMethod, J as JsonValue, X as XeniaAction, d as ConsentState } from './api-URhxxi4x.js';
|
|
2
|
+
|
|
3
|
+
/** Returns true when running in a browser environment (SSR-safe). */
|
|
4
|
+
declare function isBrowser(): boolean;
|
|
5
|
+
/** Appends query parameters to a URL. Returns the URL unchanged when empty. */
|
|
6
|
+
declare function buildUrl(url: string, queryParams?: Record<string, string>): string;
|
|
7
|
+
/** Options for a single request. */
|
|
8
|
+
interface RequestOptions {
|
|
9
|
+
method?: HttpMethod;
|
|
10
|
+
/** Path appended to `baseUrl` (should start with `/`). */
|
|
11
|
+
path: string;
|
|
12
|
+
headers?: Record<string, string>;
|
|
13
|
+
query?: Record<string, string>;
|
|
14
|
+
body?: JsonValue;
|
|
15
|
+
/** Per-request timeout override in ms. */
|
|
16
|
+
timeout?: number;
|
|
17
|
+
/** Disable retry for this request (e.g. long-polling webhook). */
|
|
18
|
+
noRetry?: boolean;
|
|
19
|
+
/** Per-request retry override. */
|
|
20
|
+
retry?: RetryConfig;
|
|
21
|
+
/**
|
|
22
|
+
* Keep the request alive past page unload (`fetch`'s `keepalive` flag).
|
|
23
|
+
* Used for best-effort flushes on `pagehide`, where `sendBeacon` can't be
|
|
24
|
+
* used instead because it doesn't support custom headers (tenant scope).
|
|
25
|
+
*/
|
|
26
|
+
keepalive?: boolean;
|
|
27
|
+
}
|
|
28
|
+
/** Result of a request: the raw Response plus the parsed JSON (or null). */
|
|
29
|
+
interface HttpResult {
|
|
30
|
+
response: Response;
|
|
31
|
+
data: JsonValue;
|
|
32
|
+
}
|
|
33
|
+
/** Error thrown for non-2xx responses (after retries are exhausted). */
|
|
34
|
+
declare class HttpError extends Error {
|
|
35
|
+
readonly status: number;
|
|
36
|
+
readonly data: JsonValue;
|
|
37
|
+
constructor(status: number, data: JsonValue, message?: string);
|
|
38
|
+
}
|
|
39
|
+
/** Thrown without a network call while an endpoint's circuit is open (see {@link CircuitBreakerConfig}). */
|
|
40
|
+
declare class CircuitOpenError extends Error {
|
|
41
|
+
readonly endpoint: string;
|
|
42
|
+
constructor(endpoint: string);
|
|
43
|
+
}
|
|
44
|
+
interface HttpClientOptions {
|
|
45
|
+
/** Defaults to {@link DEFAULT_BASE_URL} when omitted. */
|
|
46
|
+
baseUrl?: string;
|
|
47
|
+
defaultHeaders?: Record<string, string>;
|
|
48
|
+
timeout?: number;
|
|
49
|
+
retry?: RetryConfig;
|
|
50
|
+
circuitBreaker?: boolean | CircuitBreakerConfig;
|
|
51
|
+
debug?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Minimal fetch wrapper shared by all runtimes.
|
|
55
|
+
*
|
|
56
|
+
* - Injects default headers (tenant scope, content-type).
|
|
57
|
+
* - Applies an `AbortController` timeout.
|
|
58
|
+
* - Retries transient failures (network error, `429`, `5xx`) with exponential
|
|
59
|
+
* backoff, honoring a `Retry-After` header when present.
|
|
60
|
+
* - Parses JSON, falling back to `null` on empty/invalid bodies.
|
|
61
|
+
*/
|
|
62
|
+
declare class HttpClient {
|
|
63
|
+
private readonly baseUrl;
|
|
64
|
+
private readonly defaultHeaders;
|
|
65
|
+
private readonly timeout;
|
|
66
|
+
private readonly retry;
|
|
67
|
+
private readonly debug;
|
|
68
|
+
private readonly breaker;
|
|
69
|
+
constructor(opts: HttpClientOptions);
|
|
70
|
+
request(opts: RequestOptions): Promise<HttpResult>;
|
|
71
|
+
private send;
|
|
72
|
+
private fetchWithTimeout;
|
|
73
|
+
private parseBody;
|
|
74
|
+
private isRetryableStatus;
|
|
75
|
+
private retryAfterMs;
|
|
76
|
+
private log;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Parse render actions out of a webhook-response body.
|
|
81
|
+
*
|
|
82
|
+
* The convention: marketers return `{ "xeniaActions": [ ... ] }` (or a bare
|
|
83
|
+
* array) from the `webhook-response` node. Any body without a recognizable
|
|
84
|
+
* `xeniaActions` array yields an empty list — a safe no-op.
|
|
85
|
+
*/
|
|
86
|
+
declare function parseActions(body: JsonValue): XeniaAction[];
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Cookie names shared by the browser and server halves of the SDK.
|
|
90
|
+
*
|
|
91
|
+
* The visitor cookie is the one channel where two runtimes must agree on a literal string: the
|
|
92
|
+
* browser writes it, a same-origin server reads it back, and that match is what lets a server-side
|
|
93
|
+
* conversion attribute to a browser-entered journey. `config.prefix` namespaces it — so two Xenia
|
|
94
|
+
* apps on one domain keep separate visitors — which means **both halves must derive the name the
|
|
95
|
+
* same way**. Deriving it on one side and hardcoding it on the other silently breaks the link for
|
|
96
|
+
* anyone using a custom prefix: the server just finds no cookie and falls back to no visitor.
|
|
97
|
+
*
|
|
98
|
+
* Always build the name with these helpers rather than interpolating it by hand.
|
|
99
|
+
*/
|
|
100
|
+
|
|
101
|
+
/** Default storage/cookie prefix, matching `XeniaConfig.prefix`. */
|
|
102
|
+
declare const DEFAULT_PREFIX = "xenia";
|
|
103
|
+
/** Name of the first-party cookie carrying the SDK-owned visitor id, for a given prefix. */
|
|
104
|
+
declare function visitorCookieName(prefix?: string): string;
|
|
105
|
+
/** Name of the first-party cookie carrying consent scopes, for a given prefix. */
|
|
106
|
+
declare function consentCookieName(prefix?: string): string;
|
|
107
|
+
/**
|
|
108
|
+
* The visitor cookie name for the DEFAULT prefix (`"xenia_vid"`).
|
|
109
|
+
*
|
|
110
|
+
* Correct for the common case, and kept so existing code (e.g. reading the cookie straight out of a
|
|
111
|
+
* framework's cookie jar) keeps working. If you set `config.prefix`, use {@link visitorCookieName}
|
|
112
|
+
* instead — this constant will not match what the browser wrote.
|
|
113
|
+
*/
|
|
114
|
+
declare const VISITOR_COOKIE: string;
|
|
115
|
+
/**
|
|
116
|
+
* The consent cookie name for the DEFAULT prefix (`"xenia_consent"`). Same custom-prefix caveat as
|
|
117
|
+
* {@link VISITOR_COOKIE}.
|
|
118
|
+
*/
|
|
119
|
+
declare const CONSENT_COOKIE: string;
|
|
120
|
+
/**
|
|
121
|
+
* A `document.cookie` string carrying consent, in the JSON form the server SDK's `getConsent()`
|
|
122
|
+
* reads back. The browser client's `consent()` writes it; a page with its own consent banner and no
|
|
123
|
+
* browser client can write it directly, so server-side calls see the visitor's choice.
|
|
124
|
+
*/
|
|
125
|
+
declare function consentCookie(state: ConsentState, prefix?: string, maxAgeDays?: number): string;
|
|
126
|
+
|
|
127
|
+
export { CONSENT_COOKIE as C, DEFAULT_PREFIX as D, HttpClient as H, type RequestOptions as R, VISITOR_COOKIE as V, CircuitOpenError as a, type HttpClientOptions as b, HttpError as c, type HttpResult as d, buildUrl as e, consentCookie as f, consentCookieName as g, isBrowser as i, parseActions as p, visitorCookieName as v };
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { m as RetryConfig, C as CircuitBreakerConfig, H as HttpMethod, J as JsonValue, X as XeniaAction, d as ConsentState } from './api-URhxxi4x.cjs';
|
|
2
|
+
|
|
3
|
+
/** Returns true when running in a browser environment (SSR-safe). */
|
|
4
|
+
declare function isBrowser(): boolean;
|
|
5
|
+
/** Appends query parameters to a URL. Returns the URL unchanged when empty. */
|
|
6
|
+
declare function buildUrl(url: string, queryParams?: Record<string, string>): string;
|
|
7
|
+
/** Options for a single request. */
|
|
8
|
+
interface RequestOptions {
|
|
9
|
+
method?: HttpMethod;
|
|
10
|
+
/** Path appended to `baseUrl` (should start with `/`). */
|
|
11
|
+
path: string;
|
|
12
|
+
headers?: Record<string, string>;
|
|
13
|
+
query?: Record<string, string>;
|
|
14
|
+
body?: JsonValue;
|
|
15
|
+
/** Per-request timeout override in ms. */
|
|
16
|
+
timeout?: number;
|
|
17
|
+
/** Disable retry for this request (e.g. long-polling webhook). */
|
|
18
|
+
noRetry?: boolean;
|
|
19
|
+
/** Per-request retry override. */
|
|
20
|
+
retry?: RetryConfig;
|
|
21
|
+
/**
|
|
22
|
+
* Keep the request alive past page unload (`fetch`'s `keepalive` flag).
|
|
23
|
+
* Used for best-effort flushes on `pagehide`, where `sendBeacon` can't be
|
|
24
|
+
* used instead because it doesn't support custom headers (tenant scope).
|
|
25
|
+
*/
|
|
26
|
+
keepalive?: boolean;
|
|
27
|
+
}
|
|
28
|
+
/** Result of a request: the raw Response plus the parsed JSON (or null). */
|
|
29
|
+
interface HttpResult {
|
|
30
|
+
response: Response;
|
|
31
|
+
data: JsonValue;
|
|
32
|
+
}
|
|
33
|
+
/** Error thrown for non-2xx responses (after retries are exhausted). */
|
|
34
|
+
declare class HttpError extends Error {
|
|
35
|
+
readonly status: number;
|
|
36
|
+
readonly data: JsonValue;
|
|
37
|
+
constructor(status: number, data: JsonValue, message?: string);
|
|
38
|
+
}
|
|
39
|
+
/** Thrown without a network call while an endpoint's circuit is open (see {@link CircuitBreakerConfig}). */
|
|
40
|
+
declare class CircuitOpenError extends Error {
|
|
41
|
+
readonly endpoint: string;
|
|
42
|
+
constructor(endpoint: string);
|
|
43
|
+
}
|
|
44
|
+
interface HttpClientOptions {
|
|
45
|
+
/** Defaults to {@link DEFAULT_BASE_URL} when omitted. */
|
|
46
|
+
baseUrl?: string;
|
|
47
|
+
defaultHeaders?: Record<string, string>;
|
|
48
|
+
timeout?: number;
|
|
49
|
+
retry?: RetryConfig;
|
|
50
|
+
circuitBreaker?: boolean | CircuitBreakerConfig;
|
|
51
|
+
debug?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Minimal fetch wrapper shared by all runtimes.
|
|
55
|
+
*
|
|
56
|
+
* - Injects default headers (tenant scope, content-type).
|
|
57
|
+
* - Applies an `AbortController` timeout.
|
|
58
|
+
* - Retries transient failures (network error, `429`, `5xx`) with exponential
|
|
59
|
+
* backoff, honoring a `Retry-After` header when present.
|
|
60
|
+
* - Parses JSON, falling back to `null` on empty/invalid bodies.
|
|
61
|
+
*/
|
|
62
|
+
declare class HttpClient {
|
|
63
|
+
private readonly baseUrl;
|
|
64
|
+
private readonly defaultHeaders;
|
|
65
|
+
private readonly timeout;
|
|
66
|
+
private readonly retry;
|
|
67
|
+
private readonly debug;
|
|
68
|
+
private readonly breaker;
|
|
69
|
+
constructor(opts: HttpClientOptions);
|
|
70
|
+
request(opts: RequestOptions): Promise<HttpResult>;
|
|
71
|
+
private send;
|
|
72
|
+
private fetchWithTimeout;
|
|
73
|
+
private parseBody;
|
|
74
|
+
private isRetryableStatus;
|
|
75
|
+
private retryAfterMs;
|
|
76
|
+
private log;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Parse render actions out of a webhook-response body.
|
|
81
|
+
*
|
|
82
|
+
* The convention: marketers return `{ "xeniaActions": [ ... ] }` (or a bare
|
|
83
|
+
* array) from the `webhook-response` node. Any body without a recognizable
|
|
84
|
+
* `xeniaActions` array yields an empty list — a safe no-op.
|
|
85
|
+
*/
|
|
86
|
+
declare function parseActions(body: JsonValue): XeniaAction[];
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Cookie names shared by the browser and server halves of the SDK.
|
|
90
|
+
*
|
|
91
|
+
* The visitor cookie is the one channel where two runtimes must agree on a literal string: the
|
|
92
|
+
* browser writes it, a same-origin server reads it back, and that match is what lets a server-side
|
|
93
|
+
* conversion attribute to a browser-entered journey. `config.prefix` namespaces it — so two Xenia
|
|
94
|
+
* apps on one domain keep separate visitors — which means **both halves must derive the name the
|
|
95
|
+
* same way**. Deriving it on one side and hardcoding it on the other silently breaks the link for
|
|
96
|
+
* anyone using a custom prefix: the server just finds no cookie and falls back to no visitor.
|
|
97
|
+
*
|
|
98
|
+
* Always build the name with these helpers rather than interpolating it by hand.
|
|
99
|
+
*/
|
|
100
|
+
|
|
101
|
+
/** Default storage/cookie prefix, matching `XeniaConfig.prefix`. */
|
|
102
|
+
declare const DEFAULT_PREFIX = "xenia";
|
|
103
|
+
/** Name of the first-party cookie carrying the SDK-owned visitor id, for a given prefix. */
|
|
104
|
+
declare function visitorCookieName(prefix?: string): string;
|
|
105
|
+
/** Name of the first-party cookie carrying consent scopes, for a given prefix. */
|
|
106
|
+
declare function consentCookieName(prefix?: string): string;
|
|
107
|
+
/**
|
|
108
|
+
* The visitor cookie name for the DEFAULT prefix (`"xenia_vid"`).
|
|
109
|
+
*
|
|
110
|
+
* Correct for the common case, and kept so existing code (e.g. reading the cookie straight out of a
|
|
111
|
+
* framework's cookie jar) keeps working. If you set `config.prefix`, use {@link visitorCookieName}
|
|
112
|
+
* instead — this constant will not match what the browser wrote.
|
|
113
|
+
*/
|
|
114
|
+
declare const VISITOR_COOKIE: string;
|
|
115
|
+
/**
|
|
116
|
+
* The consent cookie name for the DEFAULT prefix (`"xenia_consent"`). Same custom-prefix caveat as
|
|
117
|
+
* {@link VISITOR_COOKIE}.
|
|
118
|
+
*/
|
|
119
|
+
declare const CONSENT_COOKIE: string;
|
|
120
|
+
/**
|
|
121
|
+
* A `document.cookie` string carrying consent, in the JSON form the server SDK's `getConsent()`
|
|
122
|
+
* reads back. The browser client's `consent()` writes it; a page with its own consent banner and no
|
|
123
|
+
* browser client can write it directly, so server-side calls see the visitor's choice.
|
|
124
|
+
*/
|
|
125
|
+
declare function consentCookie(state: ConsentState, prefix?: string, maxAgeDays?: number): string;
|
|
126
|
+
|
|
127
|
+
export { CONSENT_COOKIE as C, DEFAULT_PREFIX as D, HttpClient as H, type RequestOptions as R, VISITOR_COOKIE as V, CircuitOpenError as a, type HttpClientOptions as b, HttpError as c, type HttpResult as d, buildUrl as e, consentCookie as f, consentCookieName as g, isBrowser as i, parseActions as p, visitorCookieName as v };
|
package/dist/index.cjs
CHANGED
|
@@ -1,84 +1,93 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunk5D7SJIO4_cjs = require('./chunk-5D7SJIO4.cjs');
|
|
4
|
+
var chunkJEKVN7HK_cjs = require('./chunk-JEKVN7HK.cjs');
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
|
|
8
|
+
Object.defineProperty(exports, "LocalStorageResponseStore", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () { return chunk5D7SJIO4_cjs.LocalStorageResponseStore; }
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "MemoryResponseStore", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return chunk5D7SJIO4_cjs.MemoryResponseStore; }
|
|
15
|
+
});
|
|
16
|
+
Object.defineProperty(exports, "extractContentSwaps", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return chunk5D7SJIO4_cjs.extractContentSwaps; }
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(exports, "spliceSlots", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
get: function () { return chunk5D7SJIO4_cjs.spliceSlots; }
|
|
23
|
+
});
|
|
7
24
|
Object.defineProperty(exports, "CONSENT_COOKIE", {
|
|
8
25
|
enumerable: true,
|
|
9
|
-
get: function () { return
|
|
26
|
+
get: function () { return chunkJEKVN7HK_cjs.CONSENT_COOKIE; }
|
|
27
|
+
});
|
|
28
|
+
Object.defineProperty(exports, "CircuitOpenError", {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
get: function () { return chunkJEKVN7HK_cjs.CircuitOpenError; }
|
|
10
31
|
});
|
|
11
32
|
Object.defineProperty(exports, "DEFAULT_PREFIX", {
|
|
12
33
|
enumerable: true,
|
|
13
|
-
get: function () { return
|
|
34
|
+
get: function () { return chunkJEKVN7HK_cjs.DEFAULT_PREFIX; }
|
|
14
35
|
});
|
|
15
36
|
Object.defineProperty(exports, "HttpClient", {
|
|
16
37
|
enumerable: true,
|
|
17
|
-
get: function () { return
|
|
38
|
+
get: function () { return chunkJEKVN7HK_cjs.HttpClient; }
|
|
18
39
|
});
|
|
19
40
|
Object.defineProperty(exports, "HttpError", {
|
|
20
41
|
enumerable: true,
|
|
21
|
-
get: function () { return
|
|
22
|
-
});
|
|
23
|
-
Object.defineProperty(exports, "LocalStorageResponseStore", {
|
|
24
|
-
enumerable: true,
|
|
25
|
-
get: function () { return chunkWYM4CQVG_cjs.LocalStorageResponseStore; }
|
|
42
|
+
get: function () { return chunkJEKVN7HK_cjs.HttpError; }
|
|
26
43
|
});
|
|
27
44
|
Object.defineProperty(exports, "MAX_EVENT_ID_LENGTH", {
|
|
28
45
|
enumerable: true,
|
|
29
|
-
get: function () { return
|
|
30
|
-
});
|
|
31
|
-
Object.defineProperty(exports, "MemoryResponseStore", {
|
|
32
|
-
enumerable: true,
|
|
33
|
-
get: function () { return chunkWYM4CQVG_cjs.MemoryResponseStore; }
|
|
46
|
+
get: function () { return chunkJEKVN7HK_cjs.MAX_EVENT_ID_LENGTH; }
|
|
34
47
|
});
|
|
35
48
|
Object.defineProperty(exports, "VISITOR_COOKIE", {
|
|
36
49
|
enumerable: true,
|
|
37
|
-
get: function () { return
|
|
50
|
+
get: function () { return chunkJEKVN7HK_cjs.VISITOR_COOKIE; }
|
|
38
51
|
});
|
|
39
52
|
Object.defineProperty(exports, "XeniaApi", {
|
|
40
53
|
enumerable: true,
|
|
41
|
-
get: function () { return
|
|
54
|
+
get: function () { return chunkJEKVN7HK_cjs.XeniaApi; }
|
|
42
55
|
});
|
|
43
56
|
Object.defineProperty(exports, "buildUrl", {
|
|
44
57
|
enumerable: true,
|
|
45
|
-
get: function () { return
|
|
58
|
+
get: function () { return chunkJEKVN7HK_cjs.buildUrl; }
|
|
46
59
|
});
|
|
47
|
-
Object.defineProperty(exports, "
|
|
60
|
+
Object.defineProperty(exports, "consentCookie", {
|
|
48
61
|
enumerable: true,
|
|
49
|
-
get: function () { return
|
|
62
|
+
get: function () { return chunkJEKVN7HK_cjs.consentCookie; }
|
|
50
63
|
});
|
|
51
|
-
Object.defineProperty(exports, "
|
|
64
|
+
Object.defineProperty(exports, "consentCookieName", {
|
|
52
65
|
enumerable: true,
|
|
53
|
-
get: function () { return
|
|
66
|
+
get: function () { return chunkJEKVN7HK_cjs.consentCookieName; }
|
|
54
67
|
});
|
|
55
|
-
Object.defineProperty(exports, "
|
|
68
|
+
Object.defineProperty(exports, "contextFromUrl", {
|
|
56
69
|
enumerable: true,
|
|
57
|
-
get: function () { return
|
|
70
|
+
get: function () { return chunkJEKVN7HK_cjs.contextFromUrl; }
|
|
58
71
|
});
|
|
59
72
|
Object.defineProperty(exports, "generateUlid", {
|
|
60
73
|
enumerable: true,
|
|
61
|
-
get: function () { return
|
|
74
|
+
get: function () { return chunkJEKVN7HK_cjs.generateUlid; }
|
|
62
75
|
});
|
|
63
76
|
Object.defineProperty(exports, "isBrowser", {
|
|
64
77
|
enumerable: true,
|
|
65
|
-
get: function () { return
|
|
78
|
+
get: function () { return chunkJEKVN7HK_cjs.isBrowser; }
|
|
66
79
|
});
|
|
67
80
|
Object.defineProperty(exports, "parseActions", {
|
|
68
81
|
enumerable: true,
|
|
69
|
-
get: function () { return
|
|
70
|
-
});
|
|
71
|
-
Object.defineProperty(exports, "spliceSlots", {
|
|
72
|
-
enumerable: true,
|
|
73
|
-
get: function () { return chunkWYM4CQVG_cjs.spliceSlots; }
|
|
82
|
+
get: function () { return chunkJEKVN7HK_cjs.parseActions; }
|
|
74
83
|
});
|
|
75
84
|
Object.defineProperty(exports, "toEventId", {
|
|
76
85
|
enumerable: true,
|
|
77
|
-
get: function () { return
|
|
86
|
+
get: function () { return chunkJEKVN7HK_cjs.toEventId; }
|
|
78
87
|
});
|
|
79
88
|
Object.defineProperty(exports, "visitorCookieName", {
|
|
80
89
|
enumerable: true,
|
|
81
|
-
get: function () { return
|
|
90
|
+
get: function () { return chunkJEKVN7HK_cjs.visitorCookieName; }
|
|
82
91
|
});
|
|
83
92
|
//# sourceMappingURL=index.cjs.map
|
|
84
93
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.d.cts
CHANGED
|
@@ -1,73 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { A as AnalyticsContext, a as AnalyticsEventName, b as AnalyticsIdentity, c as AnalyticsIngestResponse, C as
|
|
3
|
-
|
|
4
|
-
/** Returns true when running in a browser environment (SSR-safe). */
|
|
5
|
-
declare function isBrowser(): boolean;
|
|
6
|
-
/** Appends query parameters to a URL. Returns the URL unchanged when empty. */
|
|
7
|
-
declare function buildUrl(url: string, queryParams?: Record<string, string>): string;
|
|
8
|
-
/** Options for a single request. */
|
|
9
|
-
interface RequestOptions {
|
|
10
|
-
method?: HttpMethod;
|
|
11
|
-
/** Path appended to `baseUrl` (should start with `/`). */
|
|
12
|
-
path: string;
|
|
13
|
-
headers?: Record<string, string>;
|
|
14
|
-
query?: Record<string, string>;
|
|
15
|
-
body?: JsonValue;
|
|
16
|
-
/** Per-request timeout override in ms. */
|
|
17
|
-
timeout?: number;
|
|
18
|
-
/** Disable retry for this request (e.g. long-polling webhook). */
|
|
19
|
-
noRetry?: boolean;
|
|
20
|
-
/** Per-request retry override. */
|
|
21
|
-
retry?: RetryConfig;
|
|
22
|
-
/**
|
|
23
|
-
* Keep the request alive past page unload (`fetch`'s `keepalive` flag).
|
|
24
|
-
* Used for best-effort flushes on `pagehide`, where `sendBeacon` can't be
|
|
25
|
-
* used instead because it doesn't support custom headers (tenant scope).
|
|
26
|
-
*/
|
|
27
|
-
keepalive?: boolean;
|
|
28
|
-
}
|
|
29
|
-
/** Result of a request: the raw Response plus the parsed JSON (or null). */
|
|
30
|
-
interface HttpResult {
|
|
31
|
-
response: Response;
|
|
32
|
-
data: JsonValue;
|
|
33
|
-
}
|
|
34
|
-
/** Error thrown for non-2xx responses (after retries are exhausted). */
|
|
35
|
-
declare class HttpError extends Error {
|
|
36
|
-
readonly status: number;
|
|
37
|
-
readonly data: JsonValue;
|
|
38
|
-
constructor(status: number, data: JsonValue, message?: string);
|
|
39
|
-
}
|
|
40
|
-
interface HttpClientOptions {
|
|
41
|
-
/** Defaults to {@link DEFAULT_BASE_URL} when omitted. */
|
|
42
|
-
baseUrl?: string;
|
|
43
|
-
defaultHeaders?: Record<string, string>;
|
|
44
|
-
timeout?: number;
|
|
45
|
-
retry?: RetryConfig;
|
|
46
|
-
debug?: boolean;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Minimal fetch wrapper shared by all runtimes.
|
|
50
|
-
*
|
|
51
|
-
* - Injects default headers (tenant scope, content-type).
|
|
52
|
-
* - Applies an `AbortController` timeout.
|
|
53
|
-
* - Retries transient failures (network error, `429`, `5xx`) with exponential
|
|
54
|
-
* backoff, honoring a `Retry-After` header when present.
|
|
55
|
-
* - Parses JSON, falling back to `null` on empty/invalid bodies.
|
|
56
|
-
*/
|
|
57
|
-
declare class HttpClient {
|
|
58
|
-
private readonly baseUrl;
|
|
59
|
-
private readonly defaultHeaders;
|
|
60
|
-
private readonly timeout;
|
|
61
|
-
private readonly retry;
|
|
62
|
-
private readonly debug;
|
|
63
|
-
constructor(opts: HttpClientOptions);
|
|
64
|
-
request(opts: RequestOptions): Promise<HttpResult>;
|
|
65
|
-
private fetchWithTimeout;
|
|
66
|
-
private parseBody;
|
|
67
|
-
private isRetryableStatus;
|
|
68
|
-
private retryAfterMs;
|
|
69
|
-
private log;
|
|
70
|
-
}
|
|
1
|
+
import { J as JsonValue, E as EventContext, W as WebhookResponse } from './api-URhxxi4x.cjs';
|
|
2
|
+
export { A as AnalyticsContext, a as AnalyticsEventName, b as AnalyticsIdentity, c as AnalyticsIngestResponse, C as CircuitBreakerConfig, d as ConsentState, e as EventIdentity, H as HttpMethod, I as IdentifyRequest, f as IdentifyResponse, g as InteractionType, h as JsonObject, M as MessageCta, i as MessagePlacement, P as PersonalizationSwap, R as ResolveBatchItem, j as ResolveBatchResult, k as ResolveOptions, l as ResolveResult, m as RetryConfig, T as TrackOptions, 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 } from './api-URhxxi4x.cjs';
|
|
3
|
+
export { C as CONSENT_COOKIE, a as CircuitOpenError, D as DEFAULT_PREFIX, H as HttpClient, b as HttpClientOptions, c as HttpError, d as HttpResult, R as RequestOptions, V as VISITOR_COOKIE, e as buildUrl, f as consentCookie, g as consentCookieName, i as isBrowser, p as parseActions, v as visitorCookieName } from './cookie-names-QYMiEMAq.cjs';
|
|
71
4
|
|
|
72
5
|
/**
|
|
73
6
|
* Generate a ULID (Universally Unique Lexicographically Sortable Identifier):
|
|
@@ -175,4 +108,4 @@ declare class LocalStorageResponseStore implements ResponseStore {
|
|
|
175
108
|
clear(): void;
|
|
176
109
|
}
|
|
177
110
|
|
|
178
|
-
export { type ContentSwap, EventContext,
|
|
111
|
+
export { type ContentSwap, EventContext, JsonValue, LocalStorageResponseStore, MAX_EVENT_ID_LENGTH, MemoryResponseStore, type ResponseStore, WebhookResponse, contextFromUrl, extractContentSwaps, generateUlid, spliceSlots, toEventId };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,73 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { A as AnalyticsContext, a as AnalyticsEventName, b as AnalyticsIdentity, c as AnalyticsIngestResponse, C as
|
|
3
|
-
|
|
4
|
-
/** Returns true when running in a browser environment (SSR-safe). */
|
|
5
|
-
declare function isBrowser(): boolean;
|
|
6
|
-
/** Appends query parameters to a URL. Returns the URL unchanged when empty. */
|
|
7
|
-
declare function buildUrl(url: string, queryParams?: Record<string, string>): string;
|
|
8
|
-
/** Options for a single request. */
|
|
9
|
-
interface RequestOptions {
|
|
10
|
-
method?: HttpMethod;
|
|
11
|
-
/** Path appended to `baseUrl` (should start with `/`). */
|
|
12
|
-
path: string;
|
|
13
|
-
headers?: Record<string, string>;
|
|
14
|
-
query?: Record<string, string>;
|
|
15
|
-
body?: JsonValue;
|
|
16
|
-
/** Per-request timeout override in ms. */
|
|
17
|
-
timeout?: number;
|
|
18
|
-
/** Disable retry for this request (e.g. long-polling webhook). */
|
|
19
|
-
noRetry?: boolean;
|
|
20
|
-
/** Per-request retry override. */
|
|
21
|
-
retry?: RetryConfig;
|
|
22
|
-
/**
|
|
23
|
-
* Keep the request alive past page unload (`fetch`'s `keepalive` flag).
|
|
24
|
-
* Used for best-effort flushes on `pagehide`, where `sendBeacon` can't be
|
|
25
|
-
* used instead because it doesn't support custom headers (tenant scope).
|
|
26
|
-
*/
|
|
27
|
-
keepalive?: boolean;
|
|
28
|
-
}
|
|
29
|
-
/** Result of a request: the raw Response plus the parsed JSON (or null). */
|
|
30
|
-
interface HttpResult {
|
|
31
|
-
response: Response;
|
|
32
|
-
data: JsonValue;
|
|
33
|
-
}
|
|
34
|
-
/** Error thrown for non-2xx responses (after retries are exhausted). */
|
|
35
|
-
declare class HttpError extends Error {
|
|
36
|
-
readonly status: number;
|
|
37
|
-
readonly data: JsonValue;
|
|
38
|
-
constructor(status: number, data: JsonValue, message?: string);
|
|
39
|
-
}
|
|
40
|
-
interface HttpClientOptions {
|
|
41
|
-
/** Defaults to {@link DEFAULT_BASE_URL} when omitted. */
|
|
42
|
-
baseUrl?: string;
|
|
43
|
-
defaultHeaders?: Record<string, string>;
|
|
44
|
-
timeout?: number;
|
|
45
|
-
retry?: RetryConfig;
|
|
46
|
-
debug?: boolean;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Minimal fetch wrapper shared by all runtimes.
|
|
50
|
-
*
|
|
51
|
-
* - Injects default headers (tenant scope, content-type).
|
|
52
|
-
* - Applies an `AbortController` timeout.
|
|
53
|
-
* - Retries transient failures (network error, `429`, `5xx`) with exponential
|
|
54
|
-
* backoff, honoring a `Retry-After` header when present.
|
|
55
|
-
* - Parses JSON, falling back to `null` on empty/invalid bodies.
|
|
56
|
-
*/
|
|
57
|
-
declare class HttpClient {
|
|
58
|
-
private readonly baseUrl;
|
|
59
|
-
private readonly defaultHeaders;
|
|
60
|
-
private readonly timeout;
|
|
61
|
-
private readonly retry;
|
|
62
|
-
private readonly debug;
|
|
63
|
-
constructor(opts: HttpClientOptions);
|
|
64
|
-
request(opts: RequestOptions): Promise<HttpResult>;
|
|
65
|
-
private fetchWithTimeout;
|
|
66
|
-
private parseBody;
|
|
67
|
-
private isRetryableStatus;
|
|
68
|
-
private retryAfterMs;
|
|
69
|
-
private log;
|
|
70
|
-
}
|
|
1
|
+
import { J as JsonValue, E as EventContext, W as WebhookResponse } from './api-URhxxi4x.js';
|
|
2
|
+
export { A as AnalyticsContext, a as AnalyticsEventName, b as AnalyticsIdentity, c as AnalyticsIngestResponse, C as CircuitBreakerConfig, d as ConsentState, e as EventIdentity, H as HttpMethod, I as IdentifyRequest, f as IdentifyResponse, g as InteractionType, h as JsonObject, M as MessageCta, i as MessagePlacement, P as PersonalizationSwap, R as ResolveBatchItem, j as ResolveBatchResult, k as ResolveOptions, l as ResolveResult, m as RetryConfig, T as TrackOptions, 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 } from './api-URhxxi4x.js';
|
|
3
|
+
export { C as CONSENT_COOKIE, a as CircuitOpenError, D as DEFAULT_PREFIX, H as HttpClient, b as HttpClientOptions, c as HttpError, d as HttpResult, R as RequestOptions, V as VISITOR_COOKIE, e as buildUrl, f as consentCookie, g as consentCookieName, i as isBrowser, p as parseActions, v as visitorCookieName } from './cookie-names-8FxbGKGS.js';
|
|
71
4
|
|
|
72
5
|
/**
|
|
73
6
|
* Generate a ULID (Universally Unique Lexicographically Sortable Identifier):
|
|
@@ -175,4 +108,4 @@ declare class LocalStorageResponseStore implements ResponseStore {
|
|
|
175
108
|
clear(): void;
|
|
176
109
|
}
|
|
177
110
|
|
|
178
|
-
export { type ContentSwap, EventContext,
|
|
111
|
+
export { type ContentSwap, EventContext, JsonValue, LocalStorageResponseStore, MAX_EVENT_ID_LENGTH, MemoryResponseStore, type ResponseStore, WebhookResponse, contextFromUrl, extractContentSwaps, generateUlid, spliceSlots, toEventId };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { LocalStorageResponseStore, MemoryResponseStore, extractContentSwaps, spliceSlots } from './chunk-TLTG3BTC.js';
|
|
2
|
+
export { CONSENT_COOKIE, CircuitOpenError, DEFAULT_PREFIX, HttpClient, HttpError, MAX_EVENT_ID_LENGTH, VISITOR_COOKIE, XeniaApi, buildUrl, consentCookie, consentCookieName, contextFromUrl, generateUlid, isBrowser, parseActions, toEventId, visitorCookieName } from './chunk-FYSEKFIY.js';
|
|
2
3
|
//# sourceMappingURL=index.js.map
|
|
3
4
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkU2WBBOYT_cjs = require('../chunk-U2WBBOYT.cjs');
|
|
4
|
+
var chunkJEKVN7HK_cjs = require('../chunk-JEKVN7HK.cjs');
|
|
5
|
+
var headers = require('next/headers');
|
|
6
|
+
var server = require('next/server');
|
|
7
|
+
|
|
8
|
+
var URL_HEADER = "x-xenia-url";
|
|
9
|
+
function cookieAttributes(c = {}) {
|
|
10
|
+
const sameSite = c.sameSite ?? "Lax";
|
|
11
|
+
return {
|
|
12
|
+
path: "/",
|
|
13
|
+
maxAge: Math.floor((c.maxAgeDays ?? 365) * 86400),
|
|
14
|
+
sameSite: sameSite.toLowerCase(),
|
|
15
|
+
secure: c.secure || sameSite === "None",
|
|
16
|
+
...c.domain && { domain: c.domain }
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function xeniaProxy(request, opts = {}) {
|
|
20
|
+
const name = chunkJEKVN7HK_cjs.visitorCookieName(opts.prefix);
|
|
21
|
+
const existing = request.cookies.get(name)?.value;
|
|
22
|
+
const visitorId = existing ?? chunkJEKVN7HK_cjs.generateUlid();
|
|
23
|
+
const forwarded = new Headers(opts.headers ?? request.headers);
|
|
24
|
+
forwarded.set(URL_HEADER, request.url);
|
|
25
|
+
if (!existing) {
|
|
26
|
+
const header = forwarded.get("cookie");
|
|
27
|
+
forwarded.set("cookie", header ? `${header}; ${name}=${visitorId}` : `${name}=${visitorId}`);
|
|
28
|
+
}
|
|
29
|
+
const response = server.NextResponse.next({ request: { headers: forwarded } });
|
|
30
|
+
if (!existing) response.cookies.set(name, visitorId, cookieAttributes(opts.cookie));
|
|
31
|
+
return response;
|
|
32
|
+
}
|
|
33
|
+
async function xeniaServerFromNext(config) {
|
|
34
|
+
const [jar, h] = await Promise.all([headers.cookies(), headers.headers()]);
|
|
35
|
+
const name = chunkJEKVN7HK_cjs.visitorCookieName(config.prefix);
|
|
36
|
+
let visitorId = config.visitorId ?? jar.get(name)?.value;
|
|
37
|
+
if (!visitorId) {
|
|
38
|
+
visitorId = chunkJEKVN7HK_cjs.generateUlid();
|
|
39
|
+
try {
|
|
40
|
+
jar.set(name, visitorId, cookieAttributes());
|
|
41
|
+
} catch {
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return chunkU2WBBOYT_cjs.createXeniaServer({
|
|
45
|
+
...config,
|
|
46
|
+
visitorId,
|
|
47
|
+
context: { ...chunkJEKVN7HK_cjs.contextFromUrl(h.get(URL_HEADER), h.get("referer")), ...config.context }
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async function consentFromNext(prefix) {
|
|
51
|
+
return chunkU2WBBOYT_cjs.getConsent((await headers.headers()).get("cookie"), prefix);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
exports.URL_HEADER = URL_HEADER;
|
|
55
|
+
exports.consentFromNext = consentFromNext;
|
|
56
|
+
exports.xeniaProxy = xeniaProxy;
|
|
57
|
+
exports.xeniaServerFromNext = xeniaServerFromNext;
|
|
58
|
+
//# sourceMappingURL=index.cjs.map
|
|
59
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/next/index.ts"],"names":["visitorCookieName","generateUlid","NextResponse","cookies","headers","createXeniaServer","contextFromUrl","getConsent"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\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 { 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\";\n\n/** Request header `xeniaProxy()` stamps with the URL being served. */\nexport const URL_HEADER = \"x-xenia-url\";\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\nfunction 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 * 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 = new Headers(opts.headers ?? request.headers);\n forwarded.set(URL_HEADER, request.url);\n if (!existing) {\n // NextRequest.cookies.set doesn't rewrite the forwarded Cookie header, and cookies() reads that.\n const header = forwarded.get(\"cookie\");\n forwarded.set(\"cookie\", header ? `${header}; ${name}=${visitorId}` : `${name}=${visitorId}`);\n }\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"]}
|