@doswiftly/storefront-sdk 19.0.0 → 19.1.0

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 (30) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/dist/core/client/create-client.d.ts.map +1 -1
  3. package/dist/core/client/create-client.js +8 -1
  4. package/dist/core/client/remote-debug-transport.d.ts +48 -0
  5. package/dist/core/client/remote-debug-transport.d.ts.map +1 -0
  6. package/dist/core/client/remote-debug-transport.js +198 -0
  7. package/dist/core/client/types.d.ts +51 -1
  8. package/dist/core/client/types.d.ts.map +1 -1
  9. package/dist/core/index.d.ts +3 -1
  10. package/dist/core/index.d.ts.map +1 -1
  11. package/dist/core/index.js +3 -0
  12. package/dist/react/cookies.d.ts +11 -1
  13. package/dist/react/cookies.d.ts.map +1 -1
  14. package/dist/react/cookies.js +11 -4
  15. package/dist/react/hooks/use-cart-manager.d.ts +7 -0
  16. package/dist/react/hooks/use-cart-manager.d.ts.map +1 -1
  17. package/dist/react/hooks/use-cart-manager.js +5 -2
  18. package/dist/react/providers/cart-manager-provider.d.ts +8 -1
  19. package/dist/react/providers/cart-manager-provider.d.ts.map +1 -1
  20. package/dist/react/providers/cart-manager-provider.js +2 -1
  21. package/dist/react/providers/storefront-provider.d.ts +12 -1
  22. package/dist/react/providers/storefront-provider.d.ts.map +1 -1
  23. package/dist/react/providers/storefront-provider.js +4 -3
  24. package/dist/react/stores/currency.store.d.ts +6 -1
  25. package/dist/react/stores/currency.store.d.ts.map +1 -1
  26. package/dist/react/stores/currency.store.js +49 -41
  27. package/dist/react/stores/language.store.d.ts +6 -1
  28. package/dist/react/stores/language.store.d.ts.map +1 -1
  29. package/dist/react/stores/language.store.js +46 -38
  30. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,69 @@
1
1
  # Changelog
2
2
 
3
+ ## 19.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 868894e: Add remote debug shipping for both GraphQL **and** cookie-lifecycle events, so you can trace a real shopper session end-to-end instead of reproducing it with DevTools open.
8
+
9
+ **Why**: the most useful checkout signal is often "when was the `cart-id` / currency / language cookie set or cleared?" (e.g. `cart-id` cleared by `complete()`), but debug output previously covered only GraphQL request/response. Now both flow through one channel keyed by a single `sessionId`, so one filter in your logs gives the full interleaved timeline.
10
+
11
+ **Additive (backward-compatible)** — everything is opt-in and off by default:
12
+ 1. `DebugOptions.remote?: boolean | RemoteDebugOptions | RemoteDebugSink` — ship debug events to a backend ingest endpoint. Pass a pre-built transport (a `RemoteDebugSink`) to share **one** channel/`sessionId` across the client and the cookie stores.
13
+ 2. New `createRemoteDebugTransport(...)` factory (+ `RemoteDebugTransport` / `RemoteDebugSink` / `RemoteDebugOptions` types).
14
+ 3. Cookie stores emit a new `DebugEvent` with `phase: 'cookie'` (`{ name, action: 'set' | 'clear', value?, maxAge? }`) when wired with a sink:
15
+ - `createBrowserCartCookieStore({ onDebug })` — `cart-id` (when you own the cookie store).
16
+ - `useCartManager({ cookieDebug })` / `<CartManagerProvider cookieDebug={...}>` — `cart-id` when the cart manager owns the cookie store.
17
+ - `createCurrencyStore({ onDebug })` / `createLanguageStore(initial, { onDebug })` — currency / language.
18
+ - `<StorefrontProvider cookieDebug={...}>` forwards the sink to the currency + language stores.
19
+ 4. `DebugOptions`, `DebugEvent`, `RemoteDebugOptions`, `RemoteDebugSink` are exported for typing.
20
+
21
+ **Usage example** (one shared channel across GraphQL + cookies):
22
+
23
+ ```ts
24
+ import {
25
+ createStorefrontClient,
26
+ createRemoteDebugTransport,
27
+ createBrowserCartCookieStore,
28
+ } from "@doswiftly/storefront-sdk";
29
+
30
+ const debugOn = process.env.NEXT_PUBLIC_SDK_DEBUG_REMOTE === "true";
31
+ const transport = debugOn
32
+ ? createRemoteDebugTransport({
33
+ endpoint: `${apiUrl}/storefront/debug-logs`,
34
+ shopSlug,
35
+ fetch: globalThis.fetch,
36
+ })
37
+ : null;
38
+
39
+ const client = createStorefrontClient({
40
+ apiUrl,
41
+ shopSlug,
42
+ debug: transport
43
+ ? { userErrors: true, response: true, timing: true, remote: transport }
44
+ : false,
45
+ });
46
+
47
+ // cart-id set/clear on the same channel:
48
+ const cartCookieStore = createBrowserCartCookieStore(
49
+ transport ? { onDebug: (e) => transport.capture(e) } : undefined,
50
+ );
51
+
52
+ // currency + language via the provider:
53
+ // <StorefrontProvider cookieDebug={transport ? (e) => transport.capture(e) : undefined} … />
54
+ ```
55
+
56
+ Behaviour:
57
+ - **Batched** (default 10 events / 5s); `keepalive` is used on page-hide/unload flushes so trailing events survive a navigation or payment-gateway redirect.
58
+ - **Fire-and-forget**: a failed send is swallowed — telemetry can never break the request that produced it.
59
+ - Cookies are **not** sent (`credentials: 'omit'`); the shop is identified by the `X-Shop-Slug` header.
60
+ - **Redaction**: the SDK masks `Authorization` / `customerAccessToken` in _headers_. It does **not** redact request `variables` or response bodies — the backend ingest endpoint masks emails + credential-named fields. Enable `response` / `headers` only for operations whose payload you're comfortable sending to your backend.
61
+ - Default endpoint is `${apiUrl}/storefront/debug-logs`; override via `RemoteDebugOptions.endpoint`.
62
+
63
+ **Migration checklist for existing storefronts**:
64
+ - [ ] No action required — all of the above is opt-in and defaults to off.
65
+ - [ ] To adopt: build one transport (gated behind an env flag), pass it to `createStorefrontClient`, the cart cookie store, and `<StorefrontProvider cookieDebug>`, then confirm requests to `/storefront/debug-logs`.
66
+
3
67
  ## 19.0.0
4
68
 
5
69
  ### Major Changes
@@ -1 +1 @@
1
- {"version":3,"file":"create-client.d.ts","sourceRoot":"","sources":["../../../src/core/client/create-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,sBAAsB,EACtB,gBAAgB,EAKjB,MAAM,SAAS,CAAC;AAOjB,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,sBAAsB,GAAG,gBAAgB,CA0GvF"}
1
+ {"version":3,"file":"create-client.d.ts","sourceRoot":"","sources":["../../../src/core/client/create-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,sBAAsB,EACtB,gBAAgB,EAKjB,MAAM,SAAS,CAAC;AAQjB,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,sBAAsB,GAAG,gBAAgB,CAgHvF"}
@@ -11,6 +11,7 @@
11
11
  * 0 runtime dependencies.
12
12
  */
13
13
  import { createExecute, resolveDebugOptions } from './execute';
14
+ import { maybeAttachRemoteTransport } from './remote-debug-transport';
14
15
  import { compose } from './compose';
15
16
  import { dedupe } from './dedupe';
16
17
  import { hashQuery } from './hash';
@@ -24,7 +25,13 @@ export function createStorefrontClient(config) {
24
25
  // Normalise the public `boolean | 'verbose' | DebugOptions` union into the
25
26
  // canonical ResolvedDebugOptions shape (or null = no logging). Env var
26
27
  // fallback (`DOSWIFTLY_SDK_DEBUG`) applies only when `debug` is undefined.
27
- const resolvedDebug = resolveDebugOptions(debug);
28
+ // When `debug.remote` is set, the resolved sink is wrapped so every event is
29
+ // also shipped to the backend ingest endpoint (default `${apiUrl}/storefront/debug-logs`).
30
+ const resolvedDebug = maybeAttachRemoteTransport(resolveDebugOptions(debug), debug, {
31
+ apiUrl,
32
+ shopSlug,
33
+ fetch: customFetch,
34
+ });
28
35
  // Create the innermost execute function (native fetch)
29
36
  const innerExecute = createExecute({ endpoint, fetch: customFetch, debug: resolvedDebug });
30
37
  /**
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Remote debug transport — batches debug events and ships them to a backend ingest
3
+ * endpoint over `fetch`. 0 runtime dependencies (only `fetch`, `Date`, `globalThis.crypto`).
4
+ *
5
+ * Fire-and-forget by contract: a failed flush is swallowed so telemetry can never break the
6
+ * storefront request that produced the event. The buffer flushes when it reaches `batchSize`,
7
+ * after `flushIntervalMs`, or when the page is hidden / unloading (browser only) — the last one
8
+ * matters for redirect-heavy flows (e.g. payment gateway hand-off) where trailing events would
9
+ * otherwise be lost. `fetch(..., { keepalive: true })` lets that final send complete during unload.
10
+ *
11
+ * Credentials are never sent (`credentials: 'omit'`) — this is telemetry, not an authenticated
12
+ * call. The shop is identified by the `X-Shop-Slug` header; the backend validates it.
13
+ */
14
+ import type { DebugEvent, DebugOptions } from './types';
15
+ import type { ResolvedDebugOptions } from './execute';
16
+ export interface RemoteDebugTransportConfig {
17
+ /** Fully-resolved ingest endpoint URL. */
18
+ endpoint: string;
19
+ /** Shop slug sent as `X-Shop-Slug` so the backend can resolve the tenant. */
20
+ shopSlug: string;
21
+ /** Fetch implementation (the same one the client transport uses). */
22
+ fetch: typeof globalThis.fetch;
23
+ batchSize?: number;
24
+ flushIntervalMs?: number;
25
+ sessionId?: string;
26
+ sdkVersion?: string;
27
+ }
28
+ export interface RemoteDebugTransport {
29
+ /** Buffer one debug event; flushes automatically per the batching policy. */
30
+ capture(event: DebugEvent): void;
31
+ }
32
+ export declare function createRemoteDebugTransport(config: RemoteDebugTransportConfig): RemoteDebugTransport;
33
+ /**
34
+ * Build a `phase: 'cookie'` {@link DebugEvent} for a cookie set/clear. Single construction point so
35
+ * the cart / currency / language stores emit an identical shape (`{ name, action, value?, maxAge? }`).
36
+ */
37
+ export declare function cookieDebugEvent(name: string, action: 'set' | 'clear', value?: string, maxAge?: number): DebugEvent;
38
+ /**
39
+ * If `debug.remote` is enabled, wrap the resolved debug sink so every event is also handed to a
40
+ * remote transport. Returns the input untouched when remote is off (or debug is disabled), so the
41
+ * local `log` behaviour is preserved exactly.
42
+ */
43
+ export declare function maybeAttachRemoteTransport(resolved: ResolvedDebugOptions | null, debugConfig: boolean | 'verbose' | DebugOptions | undefined, context: {
44
+ apiUrl: string;
45
+ shopSlug: string;
46
+ fetch: typeof globalThis.fetch;
47
+ }): ResolvedDebugOptions | null;
48
+ //# sourceMappingURL=remote-debug-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-debug-transport.d.ts","sourceRoot":"","sources":["../../../src/core/client/remote-debug-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAuC,MAAM,SAAS,CAAC;AAC7F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAMtD,MAAM,WAAW,0BAA0B;IACzC,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,6EAA6E;IAC7E,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;CAClC;AAuDD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,0BAA0B,GAAG,oBAAoB,CAmFnG;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,KAAK,GAAG,OAAO,EACvB,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,CAKZ;AAOD;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,oBAAoB,GAAG,IAAI,EACrC,WAAW,EAAE,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,EAC3D,OAAO,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;CAAE,GAC5E,oBAAoB,GAAG,IAAI,CA0C7B"}
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Remote debug transport — batches debug events and ships them to a backend ingest
3
+ * endpoint over `fetch`. 0 runtime dependencies (only `fetch`, `Date`, `globalThis.crypto`).
4
+ *
5
+ * Fire-and-forget by contract: a failed flush is swallowed so telemetry can never break the
6
+ * storefront request that produced the event. The buffer flushes when it reaches `batchSize`,
7
+ * after `flushIntervalMs`, or when the page is hidden / unloading (browser only) — the last one
8
+ * matters for redirect-heavy flows (e.g. payment gateway hand-off) where trailing events would
9
+ * otherwise be lost. `fetch(..., { keepalive: true })` lets that final send complete during unload.
10
+ *
11
+ * Credentials are never sent (`credentials: 'omit'`) — this is telemetry, not an authenticated
12
+ * call. The shop is identified by the `X-Shop-Slug` header; the backend validates it.
13
+ */
14
+ import { CART_COOKIE_NAME } from '../cart/cookie-config';
15
+ const DEFAULT_BATCH_SIZE = 10;
16
+ const DEFAULT_FLUSH_INTERVAL_MS = 5000;
17
+ /**
18
+ * Pull identifying ids out of operation variables so the backend log is filterable by cart /
19
+ * order without parsing the whole payload. `cartId` comes from an explicit `cartId` variable, or
20
+ * from the `id` variable on cart operations (cart mutations pass the cart as `id: cartId`). The
21
+ * operation-name check is anchored (`^cart`) so only cart operations (`CartAddLines`, …) qualify —
22
+ * an unrelated op that merely contains "cart" (e.g. `ProductInCartBadge`) won't mislabel its `id`.
23
+ */
24
+ function extractIdentifiers(event) {
25
+ // Cookie events carry the value directly — surface the cart-id so its set/clear correlates with
26
+ // the cart's GraphQL operations under one `cartId` filter.
27
+ if (event.phase === 'cookie') {
28
+ const cookie = event.data;
29
+ return cookie.name === CART_COOKIE_NAME && typeof cookie.value === 'string'
30
+ ? { cartId: cookie.value }
31
+ : {};
32
+ }
33
+ const variables = event.data.variables;
34
+ if (!variables || typeof variables !== 'object')
35
+ return {};
36
+ const v = variables;
37
+ const op = event.operationName ?? '';
38
+ const out = {};
39
+ const cartId = typeof v.cartId === 'string'
40
+ ? v.cartId
41
+ : /^cart/i.test(op) && typeof v.id === 'string'
42
+ ? v.id
43
+ : undefined;
44
+ if (cartId)
45
+ out.cartId = cartId;
46
+ if (typeof v.orderId === 'string')
47
+ out.orderId = v.orderId;
48
+ return out;
49
+ }
50
+ /**
51
+ * Generate a session correlation id. Prefers `crypto.randomUUID`; falls back to a
52
+ * timestamp + random suffix when unavailable (uniqueness within one client is all that is
53
+ * required here — there is no security property to preserve).
54
+ */
55
+ function generateSessionId() {
56
+ const c = globalThis.crypto;
57
+ if (c && typeof c.randomUUID === 'function')
58
+ return c.randomUUID();
59
+ return `sdk-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
60
+ }
61
+ export function createRemoteDebugTransport(config) {
62
+ const { endpoint, shopSlug, fetch: fetchFn, batchSize = DEFAULT_BATCH_SIZE, flushIntervalMs = DEFAULT_FLUSH_INTERVAL_MS, sdkVersion, } = config;
63
+ const sessionId = config.sessionId ?? generateSessionId();
64
+ let buffer = [];
65
+ let timer = null;
66
+ function clearFlushTimer() {
67
+ if (timer !== null) {
68
+ clearTimeout(timer);
69
+ timer = null;
70
+ }
71
+ }
72
+ function flush(useKeepalive = false) {
73
+ if (buffer.length === 0)
74
+ return;
75
+ const events = buffer;
76
+ buffer = [];
77
+ clearFlushTimer();
78
+ // Fire-and-forget — a transport failure must never surface to the caller.
79
+ void Promise.resolve()
80
+ .then(() => fetchFn(endpoint, {
81
+ method: 'POST',
82
+ headers: {
83
+ 'Content-Type': 'application/json',
84
+ 'X-Shop-Slug': shopSlug,
85
+ },
86
+ body: JSON.stringify({ sessionId, sdkVersion, events }),
87
+ // `keepalive` only for unload flushes — on a live page a large batch can exceed the
88
+ // browser's keepalive body quota (~64KB) and be rejected (then silently swallowed),
89
+ // whereas an ordinary fetch has no such cap. Unload flushes need it to survive navigation.
90
+ keepalive: useKeepalive,
91
+ credentials: 'omit',
92
+ }))
93
+ .catch(() => undefined);
94
+ }
95
+ // Flush on page hide / unload so trailing events survive a navigation or gateway redirect.
96
+ // Browser-only — guarded so the core stays usable in Node / Edge / Deno. These listeners live for
97
+ // the transport's lifetime (no teardown): the storefront client is expected to be created once per
98
+ // app (the SDK's singleton/Context convention), so they are registered once. Do not build a new
99
+ // client with `debug.remote` on every render — that would accumulate listeners.
100
+ const g = globalThis;
101
+ if (typeof g.addEventListener === 'function') {
102
+ g.addEventListener('pagehide', () => flush(true));
103
+ g.addEventListener('visibilitychange', () => {
104
+ if (g.document?.visibilityState === 'hidden')
105
+ flush(true);
106
+ });
107
+ }
108
+ return {
109
+ capture(event) {
110
+ buffer.push({
111
+ timestamp: new Date().toISOString(),
112
+ phase: event.phase,
113
+ operationName: event.operationName ?? null,
114
+ ...extractIdentifiers(event),
115
+ data: event.data,
116
+ });
117
+ if (buffer.length >= batchSize) {
118
+ flush();
119
+ }
120
+ else if (timer === null) {
121
+ timer = setTimeout(() => flush(), flushIntervalMs);
122
+ // Don't keep a Node/Edge event loop alive for a pending flush (browser timers are numbers
123
+ // with no `unref`; Node/Edge timers are objects that have it).
124
+ if (timer && typeof timer === 'object' && 'unref' in timer) {
125
+ timer.unref();
126
+ }
127
+ }
128
+ },
129
+ };
130
+ }
131
+ /**
132
+ * Build a `phase: 'cookie'` {@link DebugEvent} for a cookie set/clear. Single construction point so
133
+ * the cart / currency / language stores emit an identical shape (`{ name, action, value?, maxAge? }`).
134
+ */
135
+ export function cookieDebugEvent(name, action, value, maxAge) {
136
+ const data = { name, action };
137
+ if (value !== undefined)
138
+ data.value = value;
139
+ if (maxAge !== undefined)
140
+ data.maxAge = maxAge;
141
+ return { phase: 'cookie', operationName: undefined, data };
142
+ }
143
+ /** True when `remote` is a pre-built sink (has a callable `capture`) rather than options/boolean. */
144
+ function isRemoteSink(remote) {
145
+ return typeof remote === 'object' && typeof remote.capture === 'function';
146
+ }
147
+ /**
148
+ * If `debug.remote` is enabled, wrap the resolved debug sink so every event is also handed to a
149
+ * remote transport. Returns the input untouched when remote is off (or debug is disabled), so the
150
+ * local `log` behaviour is preserved exactly.
151
+ */
152
+ export function maybeAttachRemoteTransport(resolved, debugConfig, context) {
153
+ if (!resolved)
154
+ return resolved;
155
+ // `remote` only exists on the object form of `debug` (`DebugOptions`).
156
+ if (typeof debugConfig !== 'object' || !debugConfig.remote) {
157
+ return resolved;
158
+ }
159
+ const remote = debugConfig.remote;
160
+ // A pre-built sink (e.g. a transport shared with the cookie stores) is used as-is, so the whole
161
+ // app reports through one channel + sessionId. Otherwise build a transport from the options.
162
+ let transport;
163
+ if (isRemoteSink(remote)) {
164
+ transport = remote;
165
+ }
166
+ else {
167
+ const remoteOpts = remote === true ? {} : remote;
168
+ transport = createRemoteDebugTransport({
169
+ endpoint: remoteOpts.endpoint ?? `${context.apiUrl.replace(/\/$/, '')}/storefront/debug-logs`,
170
+ shopSlug: context.shopSlug,
171
+ fetch: context.fetch,
172
+ batchSize: remoteOpts.batchSize,
173
+ flushIntervalMs: remoteOpts.flushIntervalMs,
174
+ sessionId: remoteOpts.sessionId,
175
+ sdkVersion: remoteOpts.sdkVersion,
176
+ });
177
+ }
178
+ const originalLog = resolved.log;
179
+ return {
180
+ ...resolved,
181
+ // Telemetry must never break the request: `execute` calls `debug.log` synchronously outside any
182
+ // try/catch, so a throwing local sink or remote `capture` is swallowed here.
183
+ log: (event) => {
184
+ try {
185
+ originalLog(event);
186
+ }
187
+ catch {
188
+ /* local sink threw — ignore */
189
+ }
190
+ try {
191
+ transport.capture(event);
192
+ }
193
+ catch {
194
+ /* remote sink threw — ignore */
195
+ }
196
+ },
197
+ };
198
+ }
@@ -110,14 +110,64 @@ export interface DebugOptions {
110
110
  userErrors?: boolean;
111
111
  /** Custom logger sink. Default `console.log('[StorefrontSDK]', event.phase, event.operationName, event.data)`. Use for routing into `pino` / `winston`. */
112
112
  log?: (event: DebugEvent) => void;
113
+ /**
114
+ * Ship debug events to a remote ingest endpoint, in addition to the local `log` sink.
115
+ *
116
+ * Pass `true` to use defaults, or a `RemoteDebugOptions` object to customise the endpoint and
117
+ * batching. Events are buffered and sent with `fetch` (with `keepalive` on page-unload flushes so
118
+ * trailing events survive a navigation); a failed send is swallowed so telemetry can never break
119
+ * the request that produced it. Cookies are not sent (`credentials: 'omit'`). Default `false`.
120
+ *
121
+ * Redaction note: the SDK masks `Authorization` / `customerAccessToken` in *headers*. It does NOT
122
+ * redact the request `variables` or response body it ships — the backend ingest endpoint is the
123
+ * safety net there (it masks emails and credential-named fields). Enable `response` / `headers`
124
+ * only for operations whose payload you are comfortable sending to your backend.
125
+ *
126
+ * Which events are shipped is governed by the other flags above — `remote: true` alone ships the
127
+ * minimal set (request variables + response status + `userErrors`); enable `response` / `headers`
128
+ * / `timing` to ship more.
129
+ *
130
+ * Pass a pre-built transport (a `RemoteDebugSink`, e.g. from `createRemoteDebugTransport`) to
131
+ * share ONE channel + sessionId across the GraphQL client and the cookie stores, so a single
132
+ * `sessionId` in your logs gives the full interleaved timeline (GraphQL + cookie set/clear).
133
+ */
134
+ remote?: boolean | RemoteDebugOptions | RemoteDebugSink;
135
+ }
136
+ /**
137
+ * Configuration for the remote debug transport (`DebugOptions.remote`). All fields optional.
138
+ */
139
+ export interface RemoteDebugOptions {
140
+ /** Ingest endpoint URL. Default `${apiUrl}/storefront/debug-logs`. */
141
+ endpoint?: string;
142
+ /** Flush the buffer once this many events accumulate. Default `10`. */
143
+ batchSize?: number;
144
+ /** Flush the buffer after this many milliseconds even if `batchSize` is not reached. Default `5000`. */
145
+ flushIntervalMs?: number;
146
+ /** Correlation id grouping every event from one client instance. Default a generated id. */
147
+ sessionId?: string;
148
+ /** Optional client/build version label attached to every batch. */
149
+ sdkVersion?: string;
150
+ }
151
+ /**
152
+ * Minimal surface of a debug transport — accepts already-built `DebugEvent`s. A `RemoteDebugSink`
153
+ * created once (via `createRemoteDebugTransport`) and shared between the GraphQL client and the
154
+ * cookie stores forms a single debug channel with one `sessionId`.
155
+ */
156
+ export interface RemoteDebugSink {
157
+ capture(event: DebugEvent): void;
113
158
  }
114
159
  /**
115
160
  * Structured event handed to a custom `DebugOptions.log` sink. Stable contract:
116
161
  * `phase` and `operationName` are always present; `data` carries the merged
117
162
  * payload selected by `DebugOptions` flags.
163
+ *
164
+ * `phase: 'cookie'` events come from the SDK cookie layer (cart / currency / language) rather than
165
+ * the GraphQL transport — `operationName` is `undefined` and `data` is
166
+ * `{ name, action: 'set' | 'clear', value?, maxAge? }`. They let you see exactly when a cookie was
167
+ * written or removed (e.g. `cart-id` cleared by `complete()`) alongside the GraphQL timeline.
118
168
  */
119
169
  export interface DebugEvent {
120
- phase: 'request' | 'response';
170
+ phase: 'request' | 'response' | 'cookie';
121
171
  operationName: string | undefined;
122
172
  data: Record<string, unknown>;
123
173
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/client/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/client/types.ts"],"names":[],"mappings":"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"}
@@ -34,7 +34,9 @@
34
34
  * ```
35
35
  */
36
36
  export { createStorefrontClient } from './client/create-client';
37
- export type { StorefrontClient, StorefrontClientConfig, Middleware, ExecuteFn, GraphQLRequest, GraphQLResponse, GraphQLErrorInfo, UserError, CacheStrategy, CacheOptions, TypedDocumentString, } from './client/types';
37
+ export type { StorefrontClient, StorefrontClientConfig, Middleware, ExecuteFn, GraphQLRequest, GraphQLResponse, GraphQLErrorInfo, UserError, CacheStrategy, CacheOptions, TypedDocumentString, DebugOptions, DebugEvent, RemoteDebugOptions, RemoteDebugSink, } from './client/types';
38
+ export { createRemoteDebugTransport } from './client/remote-debug-transport';
39
+ export type { RemoteDebugTransport, RemoteDebugTransportConfig } from './client/remote-debug-transport';
38
40
  export { authMiddleware } from './middleware/auth';
39
41
  export { currencyMiddleware } from './middleware/currency';
40
42
  export { languageMiddleware } from './middleware/language';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAGH,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,YAAY,EACV,gBAAgB,EAChB,sBAAsB,EACtB,UAAU,EACV,SAAS,EACT,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,kBAAkB,EAClB,eAAe,GAChB,MAAM,gBAAgB,CAAC;AAIxB,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,YAAY,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAGxG,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACxB,KAAK,2BAA2B,EAChC,KAAK,8BAA8B,EACnC,KAAK,YAAY,GAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,KAAK,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAG9F,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AAGjF,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,KAAK,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAGpF,OAAO,EACL,SAAS,EACT,UAAU,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,0BAA0B,EAC1B,KAAK,cAAc,GACpB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAGnF,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACxB,4BAA4B,EAC5B,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,wBAAwB,EACxB,eAAe,EACf,qBAAqB,EACrB,yBAAyB,EACzB,gBAAgB,EAChB,kBAAkB,EAClB,+BAA+B,EAC/B,8BAA8B,GAC/B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAEV,IAAI,EACJ,QAAQ,EACR,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,QAAQ,EACR,kBAAkB,EAClB,YAAY,EACZ,QAAQ,EACR,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACtB,cAAc,EACd,KAAK,EACL,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,KAAK,EACL,cAAc,EAGd,aAAa,EACb,uBAAuB,EACvB,uBAAuB,EACvB,+BAA+B,EAC/B,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,WAAW,EAEX,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,sBAAsB,EACtB,kBAAkB,EAClB,2BAA2B,EAC3B,gBAAgB,EAChB,2BAA2B,EAC3B,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAC5B,sBAAsB,EACtB,uBAAuB,EACvB,gCAAgC,EAChC,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAGhB,gBAAgB,EAEhB,wBAAwB,EACxB,YAAY,EACZ,uBAAuB,GACxB,MAAM,cAAc,CAAC;AAQtB,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACrB,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,eAAe,EACf,UAAU,EACV,eAAe,EACf,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,4BAA4B,EAC5B,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,EACtB,iBAAiB,EACjB,uBAAuB,EACvB,eAAe,EACf,qBAAqB,EACrB,4BAA4B,EAC5B,8BAA8B,GAC/B,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACnG,YAAY,EACV,QAAQ,EACR,mBAAmB,EACnB,cAAc,EACd,UAAU,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,2BAA2B,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EACL,mBAAmB,EACnB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,GAC1B,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,UAAU,GAChB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,KAAK,gBAAgB,EACrB,mBAAmB,EACnB,uBAAuB,EACvB,KAAK,mBAAmB,EACxB,0BAA0B,EAC1B,8BAA8B,EAC9B,KAAK,yBAAyB,GAC/B,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAG/G,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAG/G,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAG7E,OAAO,EAAE,YAAY,EAAE,KAAK,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAGzE,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,EACxB,6BAA6B,GAC9B,MAAM,iBAAiB,CAAC;AAGzB,YAAY,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAG/E,OAAO,EAAE,qBAAqB,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGlF,OAAO,EAAE,KAAK,SAAS,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAG7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC"}
@@ -35,6 +35,9 @@
35
35
  */
36
36
  // Client factory
37
37
  export { createStorefrontClient } from './client/create-client';
38
+ // Remote debug transport — build one and share it across the client + cookie stores
39
+ // (`debug: { remote: transport }`) for a single debug channel / sessionId.
40
+ export { createRemoteDebugTransport } from './client/remote-debug-transport';
38
41
  // Middleware
39
42
  export { authMiddleware } from './middleware/auth';
40
43
  export { currencyMiddleware } from './middleware/currency';
@@ -26,6 +26,16 @@ export declare function setCookie(name: string, value: string, options?: {
26
26
  */
27
27
  export declare function deleteCookie(name: string, path?: string): void;
28
28
  import type { CartCookieStore } from '../core/cart/cart-recovery';
29
+ import type { DebugEvent } from '../core/client/types';
30
+ export interface BrowserCartCookieStoreOptions {
31
+ /**
32
+ * Optional debug sink. When provided, every `set` / `clear` of the `cart-id` cookie emits a
33
+ * `phase: 'cookie'` {@link DebugEvent}. Wire it to the same transport the GraphQL client uses
34
+ * (one shared sessionId) to see exactly when the cart cookie is written or removed — e.g. the
35
+ * `clear()` that `complete()` performs after checkout.
36
+ */
37
+ onDebug?: (event: DebugEvent) => void;
38
+ }
29
39
  /**
30
40
  * Build a browser-side `CartCookieStore` backed by `document.cookie`.
31
41
  *
@@ -45,5 +55,5 @@ import type { CartCookieStore } from '../core/cart/cart-recovery';
45
55
  * });
46
56
  * ```
47
57
  */
48
- export declare function createBrowserCartCookieStore(): CartCookieStore;
58
+ export declare function createBrowserCartCookieStore(options?: BrowserCartCookieStoreOptions): CartCookieStore;
49
59
  //# sourceMappingURL=cookies.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/react/cookies.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIrD;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACpF,IAAI,CAON;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAM,GAAG,IAAI,CAG3D;AAGD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAElE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,4BAA4B,IAAI,eAAe,CAQ9D"}
1
+ {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/react/cookies.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIrD;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACpF,IAAI,CAON;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAM,GAAG,IAAI,CAG3D;AAGD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGvD,MAAM,WAAW,6BAA6B;IAC5C;;;;;OAKG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACvC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,CAAC,EAAE,6BAA6B,GACtC,eAAe,CAcjB"}
@@ -38,6 +38,7 @@ export function deleteCookie(name, path = '/') {
38
38
  document.cookie = `${name}=;max-age=0;path=${path}`;
39
39
  }
40
40
  import { CART_COOKIE_NAME, CART_COOKIE_MAX_AGE } from '../core/cart/cookie-config';
41
+ import { cookieDebugEvent } from '../core/client/remote-debug-transport';
41
42
  /**
42
43
  * Build a browser-side `CartCookieStore` backed by `document.cookie`.
43
44
  *
@@ -57,12 +58,18 @@ import { CART_COOKIE_NAME, CART_COOKIE_MAX_AGE } from '../core/cart/cookie-confi
57
58
  * });
58
59
  * ```
59
60
  */
60
- export function createBrowserCartCookieStore() {
61
+ export function createBrowserCartCookieStore(options) {
62
+ const emit = options?.onDebug;
61
63
  return {
62
64
  get: () => getCookie(CART_COOKIE_NAME),
63
- set: (cartId, options) => {
64
- setCookie(CART_COOKIE_NAME, cartId, { maxAge: options?.maxAge ?? CART_COOKIE_MAX_AGE });
65
+ set: (cartId, setOptions) => {
66
+ const maxAge = setOptions?.maxAge ?? CART_COOKIE_MAX_AGE;
67
+ setCookie(CART_COOKIE_NAME, cartId, { maxAge });
68
+ emit?.(cookieDebugEvent(CART_COOKIE_NAME, 'set', cartId, maxAge));
69
+ },
70
+ clear: () => {
71
+ deleteCookie(CART_COOKIE_NAME);
72
+ emit?.(cookieDebugEvent(CART_COOKIE_NAME, 'clear'));
65
73
  },
66
- clear: () => deleteCookie(CART_COOKIE_NAME),
67
74
  };
68
75
  }
@@ -87,6 +87,7 @@
87
87
  */
88
88
  import type { Cart, CartLineInput, CartLineUpdateInput, CartBuyerIdentityInput, CartAddressInput, CartAttributeInput, CartCompleteInput, CartSelectShippingMethodInput, CartSelectPaymentMethodInput, CartClearPaymentSelectionInput, CartApplyGiftCardInput, CartRemoveGiftCardInput, CartUpdateGiftCardRecipientInput, PaymentCreateInput, PaymentSession } from '../../core/cart/types';
89
89
  import type { CartMutationOutcome, CartCompleteOutcome } from '../../core/cart/cart-client';
90
+ import type { DebugEvent } from '../../core/client/types';
90
91
  import { type CartExpiredEvent } from '../../core/cart/cart-recovery';
91
92
  /**
92
93
  * Names of mutations exposed by the hook — narrows `status.operation` for
@@ -165,6 +166,12 @@ export interface UseCartManagerOptions extends CartManagerLifecycleCallbacks {
165
166
  * customer service "view this cart", multi-cart B2B selectors.
166
167
  */
167
168
  initialCartId?: string | null;
169
+ /**
170
+ * Optional debug sink — emits a `phase: 'cookie'` {@link DebugEvent} whenever the `cart-id`
171
+ * cookie is set or cleared (including the `clear()` that `complete()` performs after checkout).
172
+ * Wire it to the same transport the GraphQL client uses for a single shared debug timeline.
173
+ */
174
+ cookieDebug?: (event: DebugEvent) => void;
168
175
  }
169
176
  export interface UseCartManagerResult {
170
177
  getCart: () => Promise<Cart | null>;
@@ -1 +1 @@
1
- {"version":3,"file":"use-cart-manager.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/use-cart-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-cart-manager.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/use-cart-manager.ts"],"names":[],"mappings":"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"}
@@ -117,8 +117,11 @@ function isDedicatedChannelError(err) {
117
117
  export function useCartManager(options) {
118
118
  const { cartClient } = useStorefrontClientContext();
119
119
  const [status, setStatus] = useState({ type: 'idle' });
120
- // Cookie store is stateless — keep one instance per hook mount.
121
- const cookieStore = useMemo(() => createBrowserCartCookieStore(), []);
120
+ // Cookie store is stateless — keep one instance per hook mount. A stable ref-backed wrapper lets
121
+ // the optional `cookieDebug` change without rebuilding the store (and therefore the runner).
122
+ const cookieDebugRef = useRef(options?.cookieDebug);
123
+ cookieDebugRef.current = options?.cookieDebug;
124
+ const cookieStore = useMemo(() => createBrowserCartCookieStore({ onDebug: (event) => cookieDebugRef.current?.(event) }), []);
122
125
  // Latest-callback ref: the mutation wrapper reads `lifecycleRef.current` so it
123
126
  // always fires the current callbacks while keeping its own deps array empty
124
127
  // (a stable `wrapMutation` avoids rebuilding every mutation on each render).
@@ -29,19 +29,26 @@
29
29
  */
30
30
  import { type ReactNode } from 'react';
31
31
  import { type CartManagerLifecycleCallbacks, type UseCartManagerResult } from '../hooks/use-cart-manager';
32
+ import type { DebugEvent } from '../../core/client/types';
32
33
  export interface CartManagerProviderProps extends CartManagerLifecycleCallbacks {
33
34
  /**
34
35
  * Server-known cart-id seed forwarded to `useCartManager`. Used only when the
35
36
  * `cart-id` cookie is empty on mount — the cookie always wins when present.
36
37
  */
37
38
  initialCartId?: string | null;
39
+ /**
40
+ * Optional debug sink forwarded to `useCartManager` — emits a `phase: 'cookie'` {@link DebugEvent}
41
+ * on every `cart-id` set/clear (including the `complete()` clear). Wire it to the same transport
42
+ * the GraphQL client uses for one shared debug timeline.
43
+ */
44
+ cookieDebug?: (event: DebugEvent) => void;
38
45
  children: ReactNode;
39
46
  }
40
47
  /**
41
48
  * Creates one `useCartManager` instance and exposes it to descendants via
42
49
  * Context. Lifecycle callbacks are forwarded to the underlying hook.
43
50
  */
44
- export declare function CartManagerProvider({ initialCartId, onMutationStart, onMutationSuccess, onMutationError, children, }: CartManagerProviderProps): import("react/jsx-runtime").JSX.Element;
51
+ export declare function CartManagerProvider({ initialCartId, cookieDebug, onMutationStart, onMutationSuccess, onMutationError, children, }: CartManagerProviderProps): import("react/jsx-runtime").JSX.Element;
45
52
  /**
46
53
  * Read the shared cart manager provided by the nearest `<CartManagerProvider>`.
47
54
  * Throws when called outside a provider.
@@ -1 +1 @@
1
- {"version":3,"file":"cart-manager-provider.d.ts","sourceRoot":"","sources":["../../../src/react/providers/cart-manager-provider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,EAEL,KAAK,6BAA6B,EAClC,KAAK,oBAAoB,EAC1B,MAAM,2BAA2B,CAAC;AAKnC,MAAM,WAAW,wBAAyB,SAAQ,6BAA6B;IAC7E;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,QAAQ,GACT,EAAE,wBAAwB,2CAS1B;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,oBAAoB,CAM5D"}
1
+ {"version":3,"file":"cart-manager-provider.d.ts","sourceRoot":"","sources":["../../../src/react/providers/cart-manager-provider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,EAEL,KAAK,6BAA6B,EAClC,KAAK,oBAAoB,EAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAK1D,MAAM,WAAW,wBAAyB,SAAQ,6BAA6B;IAC7E;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAC1C,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,aAAa,EACb,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,QAAQ,GACT,EAAE,wBAAwB,2CAU1B;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,oBAAoB,CAM5D"}
@@ -37,9 +37,10 @@ CartManagerContext.displayName = 'CartManagerContext';
37
37
  * Creates one `useCartManager` instance and exposes it to descendants via
38
38
  * Context. Lifecycle callbacks are forwarded to the underlying hook.
39
39
  */
40
- export function CartManagerProvider({ initialCartId, onMutationStart, onMutationSuccess, onMutationError, children, }) {
40
+ export function CartManagerProvider({ initialCartId, cookieDebug, onMutationStart, onMutationSuccess, onMutationError, children, }) {
41
41
  const manager = useCartManager({
42
42
  initialCartId,
43
+ cookieDebug,
43
44
  onMutationStart,
44
45
  onMutationSuccess,
45
46
  onMutationError,
@@ -31,6 +31,7 @@
31
31
  */
32
32
  import { type StorefrontClientProviderProps } from './storefront-client-provider';
33
33
  import { type CurrencyProviderProps } from './currency-provider';
34
+ import type { DebugEvent } from '../../core/client/types';
34
35
  export interface StorefrontProviderProps extends StorefrontClientProviderProps {
35
36
  shopData: CurrencyProviderProps['shopData'];
36
37
  /**
@@ -91,6 +92,16 @@ export interface StorefrontProviderProps extends StorefrontClientProviderProps {
91
92
  * scheduler arm on the first render (cold start) without a whoami round-trip.
92
93
  */
93
94
  initialExpiresAt?: string | null;
95
+ /**
96
+ * Optional debug sink for cookie events. When provided, the currency and language stores emit a
97
+ * `phase: 'cookie'` {@link DebugEvent} whenever their cookie is written. Wire it to the same
98
+ * transport the GraphQL client uses (one shared sessionId) so cookie writes appear on the same
99
+ * timeline as GraphQL operations. (Cart-id events are wired separately on the cart cookie store.)
100
+ *
101
+ * Must be referentially stable (e.g. from a memoized module singleton) — the stores are created
102
+ * once at provider mount, so a later `cookieDebug` swap is not observed.
103
+ */
104
+ cookieDebug?: (event: DebugEvent) => void;
94
105
  }
95
- export declare function StorefrontProvider({ children, config, middleware, shopData, initialIsAuthenticated, initialAccessToken, initialExpiresAt, initialLanguage, autoRefresh, authBasePath, }: StorefrontProviderProps): import("react/jsx-runtime").JSX.Element;
106
+ export declare function StorefrontProvider({ children, config, middleware, shopData, initialIsAuthenticated, initialAccessToken, initialExpiresAt, initialLanguage, autoRefresh, authBasePath, cookieDebug, }: StorefrontProviderProps): import("react/jsx-runtime").JSX.Element;
96
107
  //# sourceMappingURL=storefront-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"storefront-provider.d.ts","sourceRoot":"","sources":["../../../src/react/providers/storefront-provider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AASH,OAAO,EAA4B,KAAK,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAC5G,OAAO,EAAoB,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AASnF,MAAM,WAAW,uBAAwB,SAAQ,6BAA6B;IAC5E,QAAQ,EAAE,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAC5C;;;;;;;;;;OAUG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;;;;;;;;;;;;;;OAgBG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,MAAM,EACN,UAAU,EACV,QAAQ,EACR,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,YAAY,GACb,EAAE,uBAAuB,2CAwCzB"}
1
+ {"version":3,"file":"storefront-provider.d.ts","sourceRoot":"","sources":["../../../src/react/providers/storefront-provider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AASH,OAAO,EAA4B,KAAK,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAC5G,OAAO,EAAoB,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAQnF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D,MAAM,WAAW,uBAAwB,SAAQ,6BAA6B;IAC5E,QAAQ,EAAE,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAC5C;;;;;;;;;;OAUG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;;;;;;;;;;;;;;OAgBG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CAC3C;AAED,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,MAAM,EACN,UAAU,EACV,QAAQ,EACR,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,YAAY,EACZ,WAAW,GACZ,EAAE,uBAAuB,2CAyCzB"}
@@ -45,10 +45,11 @@ import { BotProtectionWidget } from '../bot-protection/bot-protection-widget';
45
45
  import { createSessionExpiredEmitter } from '../../core/auth/session-events';
46
46
  import { SessionExpiredContext } from '../hooks/use-session-expired';
47
47
  import { useSessionRefresh } from '../hooks/use-session-refresh';
48
- export function StorefrontProvider({ children, config, middleware, shopData, initialIsAuthenticated, initialAccessToken, initialExpiresAt, initialLanguage, autoRefresh, authBasePath, }) {
48
+ export function StorefrontProvider({ children, config, middleware, shopData, initialIsAuthenticated, initialAccessToken, initialExpiresAt, initialLanguage, autoRefresh, authBasePath, cookieDebug, }) {
49
49
  const authStoreRef = useRef(createAuthStore({ initialIsAuthenticated, initialAccessToken, initialExpiresAt }));
50
- const currencyStoreRef = useRef(createCurrencyStore());
51
- const languageStoreRef = useRef(createLanguageStore(initialLanguage));
50
+ const cookieDebugOptions = cookieDebug ? { onDebug: cookieDebug } : undefined;
51
+ const currencyStoreRef = useRef(createCurrencyStore(cookieDebugOptions));
52
+ const languageStoreRef = useRef(createLanguageStore(initialLanguage, cookieDebugOptions));
52
53
  const sessionExpiredRef = useRef(createSessionExpiredEmitter());
53
54
  const botProtectionRef = useRef(shopData.botProtection ? createBotProtectionManager(shopData.botProtection) : null);
54
55
  return (_jsx(AuthStoreContext.Provider, { value: authStoreRef.current, children: _jsx(CurrencyStoreContext.Provider, { value: currencyStoreRef.current, children: _jsx(LanguageStoreContext.Provider, { value: languageStoreRef.current, children: _jsx(StorefrontClientProvider, { config: config, middleware: middleware, botProtection: botProtectionRef.current, botProtectionOperations: shopData.botProtection?.protectedOperations, sessionExpiredEmitter: sessionExpiredRef.current, authBasePath: authBasePath, children: _jsx(BotProtectionContext.Provider, { value: { manager: botProtectionRef.current }, children: _jsx(CurrencyProvider, { shopData: shopData, children: _jsxs(LanguageProvider, { shopData: shopData, children: [_jsx(BotProtectionWidget, { manager: botProtectionRef.current }), _jsx(SessionRefreshRunner, { autoRefresh: autoRefresh, emitter: sessionExpiredRef.current }), _jsx(SessionExpiredContext.Provider, { value: sessionExpiredRef.current, children: children })] }) }) }) }) }) }) }));
@@ -6,6 +6,11 @@
6
6
  * through React Context — eliminates module duplication in Turbopack.
7
7
  */
8
8
  import type { ShopConfig } from '../types/shop-config';
9
+ import type { DebugEvent } from '../../core/client/types';
10
+ export interface CreateCurrencyStoreOptions {
11
+ /** Optional debug sink — emits a `phase: 'cookie'` event whenever the currency cookie is written. */
12
+ onDebug?: (event: DebugEvent) => void;
13
+ }
9
14
  /**
10
15
  * @deprecated Use ShopConfig instead. Kept for backward compatibility of type exports.
11
16
  */
@@ -18,7 +23,7 @@ export interface CurrencyStore {
18
23
  initialize: (shopData: ShopConfig) => void;
19
24
  setCurrency: (currency: string) => void;
20
25
  }
21
- export declare const createCurrencyStore: () => import("zustand").StoreApi<CurrencyStore>;
26
+ export declare const createCurrencyStore: (options?: CreateCurrencyStoreOptions) => import("zustand").StoreApi<CurrencyStore>;
22
27
  export declare const selectCurrency: (state: CurrencyStore) => string | null;
23
28
  export declare const selectBaseCurrency: (state: CurrencyStore) => string | null;
24
29
  export declare const selectSupportedCurrencies: (state: CurrencyStore) => string[];
@@ -1 +1 @@
1
- {"version":3,"file":"currency.store.d.ts","sourceRoot":"","sources":["../../../src/react/stores/currency.store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAIvD;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC;AAE1C,MAAM,WAAW,aAAa;IAE5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAGlB,UAAU,EAAE,CAAC,QAAQ,EAAE,UAAU,KAAK,IAAI,CAAC;IAC3C,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED,eAAO,MAAM,mBAAmB,iDAqD3B,CAAC;AAMN,eAAO,MAAM,cAAc,GAAI,OAAO,aAAa,kBAAmB,CAAC;AACvE,eAAO,MAAM,kBAAkB,GAAI,OAAO,aAAa,kBAAuB,CAAC;AAC/E,eAAO,MAAM,yBAAyB,GAAI,OAAO,aAAa,aAA8B,CAAC;AAC7F,eAAO,MAAM,cAAc,GAAI,OAAO,aAAa,YAAmB,CAAC"}
1
+ {"version":3,"file":"currency.store.d.ts","sourceRoot":"","sources":["../../../src/react/stores/currency.store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAG1D,MAAM,WAAW,0BAA0B;IACzC,qGAAqG;IACrG,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACvC;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC;AAE1C,MAAM,WAAW,aAAa;IAE5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAGlB,UAAU,EAAE,CAAC,QAAQ,EAAE,UAAU,KAAK,IAAI,CAAC;IAC3C,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED,eAAO,MAAM,mBAAmB,GAAI,UAAU,0BAA0B,8CA2DvE,CAAC;AAMF,eAAO,MAAM,cAAc,GAAI,OAAO,aAAa,kBAAmB,CAAC;AACvE,eAAO,MAAM,kBAAkB,GAAI,OAAO,aAAa,kBAAuB,CAAC;AAC/E,eAAO,MAAM,yBAAyB,GAAI,OAAO,aAAa,aAA8B,CAAC;AAC7F,eAAO,MAAM,cAAc,GAAI,OAAO,aAAa,YAAmB,CAAC"}
@@ -8,48 +8,56 @@
8
8
  import { createStore } from 'zustand/vanilla';
9
9
  import { CURRENCY_COOKIE_NAME, CURRENCY_COOKIE_MAX_AGE } from '../../core/currency/cookie-config';
10
10
  import { getCookie, setCookie } from '../cookies';
11
- export const createCurrencyStore = () => createStore()((set, get) => ({
12
- baseCurrency: null,
13
- supportedCurrencies: [],
14
- currency: null,
15
- isLoaded: false,
16
- initialize: (shopData) => {
17
- // 1. Try saved currency from cookie (SSR-safe)
18
- const saved = getCookie(CURRENCY_COOKIE_NAME);
19
- // 2. Try to detect from browser locale
20
- let detected;
21
- if (shopData.localeToCurrencyMap && typeof navigator !== 'undefined') {
22
- const browserLocale = navigator.language;
23
- const match = shopData.localeToCurrencyMap.find((m) => m.locale === browserLocale);
24
- detected = match?.currency;
25
- }
26
- // 3. Determine final currency (priority: saved > detected > base)
27
- const finalCurrency = saved && shopData.supportedCurrencies.includes(saved)
28
- ? saved
29
- : detected && shopData.supportedCurrencies.includes(detected)
30
- ? detected
31
- : shopData.currencyCode;
32
- set({
33
- baseCurrency: shopData.currencyCode,
34
- supportedCurrencies: shopData.supportedCurrencies,
35
- currency: finalCurrency,
36
- isLoaded: true,
37
- });
38
- // Ensure cookie is set if we determined a currency
39
- if (finalCurrency && !saved) {
40
- setCookie(CURRENCY_COOKIE_NAME, finalCurrency, { maxAge: CURRENCY_COOKIE_MAX_AGE });
41
- }
42
- },
43
- setCurrency: (currency) => {
44
- const { supportedCurrencies } = get();
45
- if (!supportedCurrencies.includes(currency)) {
46
- console.warn(`[CurrencyStore] Currency ${currency} not supported`);
47
- return;
48
- }
49
- set({ currency });
11
+ import { cookieDebugEvent } from '../../core/client/remote-debug-transport';
12
+ export const createCurrencyStore = (options) => {
13
+ const emit = options?.onDebug;
14
+ const persist = (currency) => {
50
15
  setCookie(CURRENCY_COOKIE_NAME, currency, { maxAge: CURRENCY_COOKIE_MAX_AGE });
51
- },
52
- }));
16
+ emit?.(cookieDebugEvent(CURRENCY_COOKIE_NAME, 'set', currency, CURRENCY_COOKIE_MAX_AGE));
17
+ };
18
+ return createStore()((set, get) => ({
19
+ baseCurrency: null,
20
+ supportedCurrencies: [],
21
+ currency: null,
22
+ isLoaded: false,
23
+ initialize: (shopData) => {
24
+ // 1. Try saved currency from cookie (SSR-safe)
25
+ const saved = getCookie(CURRENCY_COOKIE_NAME);
26
+ // 2. Try to detect from browser locale
27
+ let detected;
28
+ if (shopData.localeToCurrencyMap && typeof navigator !== 'undefined') {
29
+ const browserLocale = navigator.language;
30
+ const match = shopData.localeToCurrencyMap.find((m) => m.locale === browserLocale);
31
+ detected = match?.currency;
32
+ }
33
+ // 3. Determine final currency (priority: saved > detected > base)
34
+ const finalCurrency = saved && shopData.supportedCurrencies.includes(saved)
35
+ ? saved
36
+ : detected && shopData.supportedCurrencies.includes(detected)
37
+ ? detected
38
+ : shopData.currencyCode;
39
+ set({
40
+ baseCurrency: shopData.currencyCode,
41
+ supportedCurrencies: shopData.supportedCurrencies,
42
+ currency: finalCurrency,
43
+ isLoaded: true,
44
+ });
45
+ // Ensure cookie is set if we determined a currency
46
+ if (finalCurrency && !saved) {
47
+ persist(finalCurrency);
48
+ }
49
+ },
50
+ setCurrency: (currency) => {
51
+ const { supportedCurrencies } = get();
52
+ if (!supportedCurrencies.includes(currency)) {
53
+ console.warn(`[CurrencyStore] Currency ${currency} not supported`);
54
+ return;
55
+ }
56
+ set({ currency });
57
+ persist(currency);
58
+ },
59
+ }));
60
+ };
53
61
  // ---------------------------------------------------------------------------
54
62
  // Selectors (for use with useCurrencyStore(selector))
55
63
  // ---------------------------------------------------------------------------
@@ -17,6 +17,11 @@
17
17
  * - SDK language store (X-Lang header, framework-agnostic)
18
18
  */
19
19
  import type { ShopConfig } from '../types/shop-config';
20
+ import type { DebugEvent } from '../../core/client/types';
21
+ export interface CreateLanguageStoreOptions {
22
+ /** Optional debug sink — emits a `phase: 'cookie'` event whenever the language cookie is written. */
23
+ onDebug?: (event: DebugEvent) => void;
24
+ }
20
25
  export interface LanguageStore {
21
26
  defaultLanguage: string | null;
22
27
  supportedLanguages: string[];
@@ -25,7 +30,7 @@ export interface LanguageStore {
25
30
  initialize: (shopData: ShopConfig) => void;
26
31
  setLanguage: (language: string) => void;
27
32
  }
28
- export declare const createLanguageStore: (initialLanguage?: string | null) => import("zustand").StoreApi<LanguageStore>;
33
+ export declare const createLanguageStore: (initialLanguage?: string | null, options?: CreateLanguageStoreOptions) => import("zustand").StoreApi<LanguageStore>;
29
34
  export declare const selectLanguage: (state: LanguageStore) => string | null;
30
35
  export declare const selectDefaultLanguage: (state: LanguageStore) => string | null;
31
36
  export declare const selectSupportedLanguages: (state: LanguageStore) => string[];
@@ -1 +1 @@
1
- {"version":3,"file":"language.store.d.ts","sourceRoot":"","sources":["../../../src/react/stores/language.store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAIvD,MAAM,WAAW,aAAa;IAE5B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAGlB,UAAU,EAAE,CAAC,QAAQ,EAAE,UAAU,KAAK,IAAI,CAAC;IAC3C,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED,eAAO,MAAM,mBAAmB,GAAI,kBAAkB,MAAM,GAAG,IAAI,8CA4C9D,CAAC;AAMN,eAAO,MAAM,cAAc,GAAI,OAAO,aAAa,kBAAmB,CAAC;AACvE,eAAO,MAAM,qBAAqB,GAAI,OAAO,aAAa,kBAA0B,CAAC;AACrF,eAAO,MAAM,wBAAwB,GAAI,OAAO,aAAa,aAA6B,CAAC;AAC3F,eAAO,MAAM,sBAAsB,GAAI,OAAO,aAAa,YAAmB,CAAC"}
1
+ {"version":3,"file":"language.store.d.ts","sourceRoot":"","sources":["../../../src/react/stores/language.store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAG1D,MAAM,WAAW,0BAA0B;IACzC,qGAAqG;IACrG,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,aAAa;IAE5B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAGlB,UAAU,EAAE,CAAC,QAAQ,EAAE,UAAU,KAAK,IAAI,CAAC;IAC3C,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED,eAAO,MAAM,mBAAmB,GAC9B,kBAAkB,MAAM,GAAG,IAAI,EAC/B,UAAU,0BAA0B,8CAmDrC,CAAC;AAMF,eAAO,MAAM,cAAc,GAAI,OAAO,aAAa,kBAAmB,CAAC;AACvE,eAAO,MAAM,qBAAqB,GAAI,OAAO,aAAa,kBAA0B,CAAC;AACrF,eAAO,MAAM,wBAAwB,GAAI,OAAO,aAAa,aAA6B,CAAC;AAC3F,eAAO,MAAM,sBAAsB,GAAI,OAAO,aAAa,YAAmB,CAAC"}
@@ -19,45 +19,53 @@
19
19
  import { createStore } from 'zustand/vanilla';
20
20
  import { LANGUAGE_COOKIE_NAME, LANGUAGE_COOKIE_MAX_AGE } from '../../core/language/cookie-config';
21
21
  import { getCookie, setCookie } from '../cookies';
22
- export const createLanguageStore = (initialLanguage) => createStore()((set, get) => ({
23
- defaultLanguage: null,
24
- supportedLanguages: [],
25
- language: initialLanguage ?? null,
26
- isLoaded: false,
27
- initialize: (shopData) => {
28
- const supported = shopData.supportedLanguages ?? [];
29
- const current = get().language;
30
- const saved = getCookie(LANGUAGE_COOKIE_NAME);
31
- // Priority: current (from initialLanguage/URL) > cookie (validated) > default
32
- const finalLanguage = current && (supported.length === 0 || supported.includes(current))
33
- ? current
34
- : saved && (supported.length === 0 || supported.includes(saved))
35
- ? saved
36
- : shopData.defaultLanguage ?? null;
37
- set({
38
- defaultLanguage: shopData.defaultLanguage ?? null,
39
- supportedLanguages: supported,
40
- language: finalLanguage,
41
- isLoaded: true,
42
- });
43
- // Persist cookie if determined from fallback (not already saved)
44
- if (finalLanguage && finalLanguage !== saved) {
45
- setCookie(LANGUAGE_COOKIE_NAME, finalLanguage, { maxAge: LANGUAGE_COOKIE_MAX_AGE });
46
- }
47
- },
48
- setLanguage: (language) => {
49
- const { supportedLanguages } = get();
50
- // Validate vs supported (bypass if empty — LanguageSyncProvider may call before initialize)
51
- if (supportedLanguages.length > 0 && !supportedLanguages.includes(language)) {
52
- console.warn(`[LanguageStore] Language ${language} not supported`);
53
- return;
54
- }
55
- if (get().language === language)
56
- return;
22
+ import { cookieDebugEvent } from '../../core/client/remote-debug-transport';
23
+ export const createLanguageStore = (initialLanguage, options) => {
24
+ const emit = options?.onDebug;
25
+ const persist = (language) => {
57
26
  setCookie(LANGUAGE_COOKIE_NAME, language, { maxAge: LANGUAGE_COOKIE_MAX_AGE });
58
- set({ language });
59
- },
60
- }));
27
+ emit?.(cookieDebugEvent(LANGUAGE_COOKIE_NAME, 'set', language, LANGUAGE_COOKIE_MAX_AGE));
28
+ };
29
+ return createStore()((set, get) => ({
30
+ defaultLanguage: null,
31
+ supportedLanguages: [],
32
+ language: initialLanguage ?? null,
33
+ isLoaded: false,
34
+ initialize: (shopData) => {
35
+ const supported = shopData.supportedLanguages ?? [];
36
+ const current = get().language;
37
+ const saved = getCookie(LANGUAGE_COOKIE_NAME);
38
+ // Priority: current (from initialLanguage/URL) > cookie (validated) > default
39
+ const finalLanguage = current && (supported.length === 0 || supported.includes(current))
40
+ ? current
41
+ : saved && (supported.length === 0 || supported.includes(saved))
42
+ ? saved
43
+ : shopData.defaultLanguage ?? null;
44
+ set({
45
+ defaultLanguage: shopData.defaultLanguage ?? null,
46
+ supportedLanguages: supported,
47
+ language: finalLanguage,
48
+ isLoaded: true,
49
+ });
50
+ // Persist cookie if determined from fallback (not already saved)
51
+ if (finalLanguage && finalLanguage !== saved) {
52
+ persist(finalLanguage);
53
+ }
54
+ },
55
+ setLanguage: (language) => {
56
+ const { supportedLanguages } = get();
57
+ // Validate vs supported (bypass if empty — LanguageSyncProvider may call before initialize)
58
+ if (supportedLanguages.length > 0 && !supportedLanguages.includes(language)) {
59
+ console.warn(`[LanguageStore] Language ${language} not supported`);
60
+ return;
61
+ }
62
+ if (get().language === language)
63
+ return;
64
+ persist(language);
65
+ set({ language });
66
+ },
67
+ }));
68
+ };
61
69
  // ---------------------------------------------------------------------------
62
70
  // Selectors (for use with useLanguageStore(selector))
63
71
  // ---------------------------------------------------------------------------
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doswiftly/storefront-sdk",
3
- "version": "19.0.0",
3
+ "version": "19.1.0",
4
4
  "description": "Storefront runtime SDK for DoSwiftly Commerce — layered transport, middleware pipeline, React providers, Zustand stores, cache strategies. 0 runtime dependencies in core.",
5
5
  "type": "module",
6
6
  "sideEffects": false,