@doswiftly/storefront-sdk 17.0.0 → 18.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 (86) hide show
  1. package/CHANGELOG.md +976 -0
  2. package/README.md +47 -4
  3. package/dist/core/auth/auth-client.d.ts +39 -3
  4. package/dist/core/auth/auth-client.d.ts.map +1 -1
  5. package/dist/core/auth/auth-client.js +51 -3
  6. package/dist/core/auth/cookie-config.d.ts +52 -3
  7. package/dist/core/auth/cookie-config.d.ts.map +1 -1
  8. package/dist/core/auth/cookie-config.js +60 -6
  9. package/dist/core/auth/handlers.d.ts +46 -0
  10. package/dist/core/auth/handlers.d.ts.map +1 -1
  11. package/dist/core/auth/handlers.js +9 -2
  12. package/dist/core/auth/session-events.d.ts +38 -0
  13. package/dist/core/auth/session-events.d.ts.map +1 -0
  14. package/dist/core/auth/session-events.js +35 -0
  15. package/dist/core/cart/cart-recovery.d.ts +23 -0
  16. package/dist/core/cart/cart-recovery.d.ts.map +1 -1
  17. package/dist/core/cart/cart-recovery.js +20 -3
  18. package/dist/core/cart/types.d.ts +2 -1
  19. package/dist/core/cart/types.d.ts.map +1 -1
  20. package/dist/core/cart/types.js +7 -1
  21. package/dist/core/client/create-client.d.ts.map +1 -1
  22. package/dist/core/client/create-client.js +7 -3
  23. package/dist/core/client/execute.d.ts +29 -3
  24. package/dist/core/client/execute.d.ts.map +1 -1
  25. package/dist/core/client/execute.js +174 -3
  26. package/dist/core/client/types.d.ts +50 -2
  27. package/dist/core/client/types.d.ts.map +1 -1
  28. package/dist/core/errors.d.ts +6 -0
  29. package/dist/core/errors.d.ts.map +1 -1
  30. package/dist/core/errors.js +6 -0
  31. package/dist/core/generated/operation-types.d.ts +838 -221
  32. package/dist/core/generated/operation-types.d.ts.map +1 -1
  33. package/dist/core/generated/operation-types.js +560 -1
  34. package/dist/core/index.d.ts +6 -3
  35. package/dist/core/index.d.ts.map +1 -1
  36. package/dist/core/index.js +12 -2
  37. package/dist/core/middleware/session-retry.d.ts +47 -0
  38. package/dist/core/middleware/session-retry.d.ts.map +1 -0
  39. package/dist/core/middleware/session-retry.js +71 -0
  40. package/dist/core/operations/auth.d.ts.map +1 -1
  41. package/dist/core/operations/auth.js +1 -0
  42. package/dist/core/operations/cart.d.ts.map +1 -1
  43. package/dist/core/operations/cart.js +15 -11
  44. package/dist/react/components/PaymentInstrumentSection.d.ts.map +1 -1
  45. package/dist/react/components/PaymentInstrumentSection.js +4 -4
  46. package/dist/react/components/PaymentInstrumentTile.d.ts +7 -7
  47. package/dist/react/components/PaymentInstrumentTile.d.ts.map +1 -1
  48. package/dist/react/components/PaymentInstrumentTile.js +4 -3
  49. package/dist/react/hooks/use-cart-manager.d.ts +133 -13
  50. package/dist/react/hooks/use-cart-manager.d.ts.map +1 -1
  51. package/dist/react/hooks/use-cart-manager.js +220 -16
  52. package/dist/react/hooks/use-login.d.ts.map +1 -1
  53. package/dist/react/hooks/use-login.js +3 -3
  54. package/dist/react/hooks/use-refresh-token.d.ts.map +1 -1
  55. package/dist/react/hooks/use-refresh-token.js +6 -4
  56. package/dist/react/hooks/use-session-expired.d.ts +16 -0
  57. package/dist/react/hooks/use-session-expired.d.ts.map +1 -0
  58. package/dist/react/hooks/use-session-expired.js +26 -0
  59. package/dist/react/hooks/use-session-refresh.d.ts +32 -0
  60. package/dist/react/hooks/use-session-refresh.d.ts.map +1 -0
  61. package/dist/react/hooks/use-session-refresh.js +147 -0
  62. package/dist/react/index.d.ts +5 -1
  63. package/dist/react/index.d.ts.map +1 -1
  64. package/dist/react/index.js +3 -0
  65. package/dist/react/providers/cart-manager-provider.d.ts +50 -0
  66. package/dist/react/providers/cart-manager-provider.d.ts.map +1 -0
  67. package/dist/react/providers/cart-manager-provider.js +59 -0
  68. package/dist/react/providers/storefront-client-provider.d.ts +10 -1
  69. package/dist/react/providers/storefront-client-provider.d.ts.map +1 -1
  70. package/dist/react/providers/storefront-client-provider.js +38 -3
  71. package/dist/react/providers/storefront-provider.d.ts +51 -3
  72. package/dist/react/providers/storefront-provider.d.ts.map +1 -1
  73. package/dist/react/providers/storefront-provider.js +22 -5
  74. package/dist/react/server/create-storefront-auth-route.d.ts +63 -0
  75. package/dist/react/server/create-storefront-auth-route.d.ts.map +1 -0
  76. package/dist/react/server/create-storefront-auth-route.js +239 -0
  77. package/dist/react/server/get-initial-auth.d.ts +57 -0
  78. package/dist/react/server/get-initial-auth.d.ts.map +1 -0
  79. package/dist/react/server/get-initial-auth.js +55 -0
  80. package/dist/react/server/index.d.ts +3 -0
  81. package/dist/react/server/index.d.ts.map +1 -1
  82. package/dist/react/server/index.js +6 -0
  83. package/dist/react/stores/auth.store.d.ts +46 -2
  84. package/dist/react/stores/auth.store.d.ts.map +1 -1
  85. package/dist/react/stores/auth.store.js +19 -7
  86. package/package.json +4 -2
@@ -7,23 +7,53 @@
7
7
  *
8
8
  * Per-operation strategy:
9
9
  *
10
- * | Operation | Strategy | Why |
11
- * | ----------------------- | ------------------------------------- | --------------------------------------------- |
12
- * | `addItem` | Auto-replay (atomic `cartCreate`) | Storefront expects "add to cart" always works |
13
- * | `updateBuyerIdentity` | Auto-replay | User just typed email/phone — keep it |
14
- * | `setShippingAddress` | Auto-replay | User just typed address — keep it |
15
- * | `updateDiscountCodes` | Auto-replay | Coupon valid independently of cart |
16
- * | `updateNote` | Auto-replay | Stateless / idempotent |
17
- * | `updateItem` | Bail + `cart-expired` event | `lineId` refers to a line in the dead cart |
18
- * | `removeItem` | Bail + `cart-expired` event | jw. |
10
+ * | Operation | Strategy | Why |
11
+ * | -------------------------- | ------------------------------------- | --------------------------------------------- |
12
+ * | `addItem` | Auto-replay (atomic `cartCreate`) | Storefront expects "add to cart" always works |
13
+ * | `updateBuyerIdentity` | Auto-replay | User just typed email/phone — keep it |
14
+ * | `setShippingAddress` | Auto-replay | User just typed address — keep it |
15
+ * | `updateDiscountCodes` | Auto-replay | Coupon valid independently of cart |
16
+ * | `updateNote` | Auto-replay | Stateless / idempotent |
17
+ * | `updateAttributes` | Auto-replay | Stateless metadata atomic re-create OK |
18
+ * | `updateItem` | Bail + `cart-expired` event | `lineId` refers to a line in the dead cart |
19
+ * | `removeItem` | Bail + `cart-expired` event | jw. |
20
+ * | `setBillingAddress` | Bail + `cart-expired` event | Cart must exist (separate from shipping) |
21
+ * | `selectShippingMethod` | Bail + `cart-expired` event | Method tied to cart contents + address |
22
+ * | `selectPaymentMethod` | Bail + `cart-expired` event | Payment selection on existing cart state |
23
+ * | `clearPaymentSelection` | Bail + `cart-expired` event | Operates on existing cart payment fields |
24
+ * | `applyGiftCard` | Bail + `cart-expired` event | Balance allocation tied to cart total |
25
+ * | `removeGiftCard` | Bail + `cart-expired` event | `giftCardId` refers to row on dead cart |
26
+ * | `updateGiftCardRecipient` | Bail + `cart-expired` event | `lineId` refers to a line in the dead cart |
27
+ * | `complete` | Bail + `cart-expired` event | Finalised cart cannot be auto-recreated |
28
+ * | `createPayment` | Out of recovery scope | Operates on `orderId` (post-complete) |
19
29
  *
20
30
  * On bail the runner clears the cookie and calls every `onExpired` listener
21
31
  * with a `CartExpiredEvent`. UI subscribes once globally and shows a toast /
22
32
  * banner — caller code never writes `try / catch` per mutation.
23
33
  *
34
+ * After `complete` success the hook auto-clears the `cart-id` cookie and
35
+ * resets status to `idle` — buyer returning to `/checkout` (back from the
36
+ * payment gateway, deep link, new tab) gets a fresh empty cart instead of the
37
+ * CONVERTED cart. Manual `clearCart()` remains available as an escape hatch.
38
+ *
24
39
  * Auto-creates cart on first add. Cart id persisted in `cart-id` cookie
25
40
  * (SSR/edge visible, 30 days, samesite=lax).
26
41
  *
42
+ * ### Server-known cart-id (env seed, magic-link, iframe, customer service)
43
+ *
44
+ * Pass `{ initialCartId }` to seed the hook with a cart-id resolved server-side
45
+ * (read from URL params in a Route Handler, env var for dev fixtures, parent
46
+ * `postMessage` for embedded iframe, admin "view this cart" lookup). The hook
47
+ * applies priority `cookie wins → seed → auto-create`. The seed is eagerly
48
+ * written to the cart-id cookie so cross-tab tabs and standard recovery
49
+ * semantics operate on a canonical value. A stale seed goes through the same
50
+ * recovery flow as a stale cookie — `addItem` auto-replays through
51
+ * `cartCreate({ lines })`, state-dependent ops bail with `cart-expired`.
52
+ *
53
+ * Mirrors the `<StorefrontProvider initialAccessToken>` pattern for the
54
+ * cart-id half of the checkout state — both are seeds for the first render
55
+ * when the client cannot read the canonical source itself.
56
+ *
27
57
  * @example
28
58
  * ```tsx
29
59
  * function CartUI() {
@@ -34,21 +64,79 @@
34
64
  * return <button onClick={() => addItem([{ variantId, quantity: 1 }])}>Add</button>;
35
65
  * }
36
66
  * ```
67
+ *
68
+ * @example Server-known cart-id
69
+ * ```tsx
70
+ * // app/checkout/page.tsx — Server Component
71
+ * import { cookies } from 'next/headers';
72
+ * import { CART_COOKIE_NAME } from '@doswiftly/storefront-sdk';
73
+ *
74
+ * export default async function CheckoutPage() {
75
+ * const cookieJar = await cookies();
76
+ * const initialCartId =
77
+ * cookieJar.get(CART_COOKIE_NAME)?.value ?? process.env.NEXT_PUBLIC_DEV_CART_ID ?? null;
78
+ * return <CheckoutClient initialCartId={initialCartId} />;
79
+ * }
80
+ *
81
+ * // CheckoutClient.tsx — 'use client'
82
+ * function CheckoutClient({ initialCartId }: { initialCartId: string | null }) {
83
+ * const { complete, selectPaymentMethod, addItem } = useCartManager({ initialCartId });
84
+ * // ... rest unchanged — hook handles seed → cookie → recovery transparently
85
+ * }
86
+ * ```
37
87
  */
38
88
  'use client';
39
- import { useCallback, useMemo, useState } from 'react';
89
+ import { useCallback, useMemo, useRef, useState } from 'react';
40
90
  import { useStorefrontClientContext } from '../providers/storefront-client-provider';
41
- import { createCartRecoveryRunner, recreateWithInput, } from '../../core/cart/cart-recovery';
91
+ import { createCartRecoveryRunner, recreateWithInput, CartRecoveryNotPossibleError, CartSessionRequiredError, } from '../../core/cart/cart-recovery';
42
92
  import { createBrowserCartCookieStore } from '../cookies';
43
- export function useCartManager() {
93
+ /**
94
+ * Invoke an optional lifecycle callback without letting a thrown callback
95
+ * reject the cart mutation it wraps. A misbehaving UI side-effect (toast,
96
+ * navigation) must never corrupt cart state or surface as a failed mutation —
97
+ * but the throw is logged so the consumer bug stays debuggable.
98
+ */
99
+ function safeInvoke(run) {
100
+ try {
101
+ run();
102
+ }
103
+ catch (err) {
104
+ console.warn('[storefront-sdk] cart manager lifecycle callback threw', err);
105
+ }
106
+ }
107
+ /**
108
+ * Cart expiry (`CartRecoveryNotPossibleError`) and session loss
109
+ * (`CartSessionRequiredError`) are surfaced through their own dedicated
110
+ * channels (`onExpired` / the session-expired event) and carry SDK-internal
111
+ * English messages. They are NOT routed to `onMutationError`, whose error is
112
+ * meant to be surfaceable to the buyer.
113
+ */
114
+ function isDedicatedChannelError(err) {
115
+ return err instanceof CartRecoveryNotPossibleError || err instanceof CartSessionRequiredError;
116
+ }
117
+ export function useCartManager(options) {
44
118
  const { cartClient } = useStorefrontClientContext();
45
119
  const [status, setStatus] = useState({ type: 'idle' });
46
120
  // Cookie store is stateless — keep one instance per hook mount.
47
121
  const cookieStore = useMemo(() => createBrowserCartCookieStore(), []);
122
+ // Latest-callback ref: the mutation wrapper reads `lifecycleRef.current` so it
123
+ // always fires the current callbacks while keeping its own deps array empty
124
+ // (a stable `wrapMutation` avoids rebuilding every mutation on each render).
125
+ const lifecycleRef = useRef({});
126
+ lifecycleRef.current = {
127
+ onMutationStart: options?.onMutationStart,
128
+ onMutationSuccess: options?.onMutationSuccess,
129
+ onMutationError: options?.onMutationError,
130
+ };
131
+ // Normalize seed so the runner identity is stable across `undefined` /
132
+ // `null` props and only flips when the storefront actually swaps the seed.
133
+ const initialCartId = options?.initialCartId ?? null;
48
134
  // Recovery runner is bound to cartClient identity (changes only on provider
49
135
  // re-mount). Sharing one runner per hook gives concurrent operations a single
50
- // recovery coordinator (Phase 0 mutex).
51
- const runner = useMemo(() => createCartRecoveryRunner({ cartClient, cookieStore }), [cartClient, cookieStore]);
136
+ // recovery coordinator (Phase 0 mutex). `initialCartId` is part of the
137
+ // identity so a switch (e.g. cart switcher in a multi-cart B2B UI) rebuilds
138
+ // the runner instead of carrying the previous seed forward.
139
+ const runner = useMemo(() => createCartRecoveryRunner({ cartClient, cookieStore, initialCartId }), [cartClient, cookieStore, initialCartId]);
52
140
  // Subscribe to cart-expired events. The returned unsubscribe function is
53
141
  // bound to the current runner identity — wrap calls in
54
142
  // `useEffect(() => onExpired(...), [onExpired])` so React re-subscribes when
@@ -58,14 +146,19 @@ export function useCartManager() {
58
146
  // recovery semantics to the runner (which fires onExpired separately).
59
147
  const wrapMutation = useCallback(async (operation, run, failureFallbackMessage) => {
60
148
  setStatus({ type: 'loading', operation });
149
+ safeInvoke(() => lifecycleRef.current.onMutationStart?.(operation));
61
150
  try {
62
151
  const result = await run();
63
152
  setStatus({ type: 'success', operation });
153
+ safeInvoke(() => lifecycleRef.current.onMutationSuccess?.(operation));
64
154
  return result;
65
155
  }
66
156
  catch (err) {
67
157
  const error = err instanceof Error ? err : new Error(failureFallbackMessage);
68
158
  setStatus({ type: 'error', operation, error });
159
+ if (!isDedicatedChannelError(error)) {
160
+ safeInvoke(() => lifecycleRef.current.onMutationError?.(operation, error));
161
+ }
69
162
  throw err;
70
163
  }
71
164
  }, []);
@@ -98,6 +191,11 @@ export function useCartManager() {
98
191
  run: (cartId) => cartClient.updateNote(cartId, note),
99
192
  recreateAndRun: recreateWithInput({ note }),
100
193
  }), 'Failed to update note'), [runner, cartClient, wrapMutation]);
194
+ const updateAttributes = useCallback((attributes) => wrapMutation('updateAttributes', () => runner.execute({
195
+ name: 'updateAttributes',
196
+ run: (cartId) => cartClient.updateAttributes(cartId, attributes),
197
+ recreateAndRun: recreateWithInput({ attributes }),
198
+ }), 'Failed to update cart attributes'), [runner, cartClient, wrapMutation]);
101
199
  // --- Bail-on-stale mutations (no recreateAndRun — fires onExpired + throws) ---
102
200
  const updateItem = useCallback((lines) => wrapMutation('updateItem', () => runner.execute({
103
201
  name: 'updateItem',
@@ -107,6 +205,73 @@ export function useCartManager() {
107
205
  name: 'removeItem',
108
206
  run: (cartId) => cartClient.removeItems(cartId, lineIds),
109
207
  }), 'Failed to remove from cart'), [runner, cartClient, wrapMutation]);
208
+ const setBillingAddress = useCallback((address) => wrapMutation('setBillingAddress', () => runner.execute({
209
+ name: 'setBillingAddress',
210
+ run: (cartId) => cartClient.setBillingAddress({ cartId, address }),
211
+ }), 'Failed to set billing address'), [runner, cartClient, wrapMutation]);
212
+ const selectShippingMethod = useCallback((input) => wrapMutation('selectShippingMethod', () => runner.execute({
213
+ name: 'selectShippingMethod',
214
+ run: (cartId) => cartClient.selectShippingMethod({ cartId, ...input }),
215
+ }), 'Failed to select shipping method'), [runner, cartClient, wrapMutation]);
216
+ const selectPaymentMethod = useCallback((input) => wrapMutation('selectPaymentMethod', () => runner.execute({
217
+ name: 'selectPaymentMethod',
218
+ run: (cartId) => cartClient.selectPaymentMethod({ cartId, ...input }),
219
+ }), 'Failed to select payment method'), [runner, cartClient, wrapMutation]);
220
+ const clearPaymentSelection = useCallback((input) => wrapMutation('clearPaymentSelection', () => runner.execute({
221
+ name: 'clearPaymentSelection',
222
+ run: (cartId) => cartClient.clearPaymentSelection({ cartId, ...(input ?? {}) }),
223
+ }), 'Failed to clear payment selection'), [runner, cartClient, wrapMutation]);
224
+ const applyGiftCard = useCallback((input) => wrapMutation('applyGiftCard', () => runner.execute({
225
+ name: 'applyGiftCard',
226
+ run: (cartId) => cartClient.applyGiftCard({ cartId, ...input }),
227
+ }), 'Failed to apply gift card'), [runner, cartClient, wrapMutation]);
228
+ const removeGiftCard = useCallback((input) => wrapMutation('removeGiftCard', () => runner.execute({
229
+ name: 'removeGiftCard',
230
+ run: (cartId) => cartClient.removeGiftCard({ cartId, ...input }),
231
+ }), 'Failed to remove gift card'), [runner, cartClient, wrapMutation]);
232
+ const updateGiftCardRecipient = useCallback((input) => wrapMutation('updateGiftCardRecipient', () => runner.execute({
233
+ name: 'updateGiftCardRecipient',
234
+ run: (cartId) => cartClient.updateGiftCardRecipient({ cartId, ...input }),
235
+ }), 'Failed to update gift card recipient'), [runner, cartClient, wrapMutation]);
236
+ // --- Completion lifecycle ---
237
+ /**
238
+ * Bail-on-stale completion. On success the cart is CONVERTED/locked, so the
239
+ * hook auto-clears the cart cookie and resets status to `idle`. A follow-up
240
+ * `addItem` recreates a fresh cart through the standard recovery runner.
241
+ * `wrapMutation` is intentionally bypassed — its success path leaves status
242
+ * as `{ type: 'success', operation: 'complete' }`, but the cart no longer
243
+ * exists in the cookie state, so `idle` is the truthful representation.
244
+ */
245
+ const complete = useCallback(async (input) => {
246
+ setStatus({ type: 'loading', operation: 'complete' });
247
+ safeInvoke(() => lifecycleRef.current.onMutationStart?.('complete'));
248
+ try {
249
+ const result = await runner.execute({
250
+ name: 'complete',
251
+ run: (cartId) => cartClient.complete({ cartId, ...(input ?? {}) }),
252
+ });
253
+ cookieStore.clear();
254
+ setStatus({ type: 'idle' });
255
+ safeInvoke(() => lifecycleRef.current.onMutationSuccess?.('complete'));
256
+ return result;
257
+ }
258
+ catch (err) {
259
+ const error = err instanceof Error ? err : new Error('Failed to complete cart');
260
+ setStatus({ type: 'error', operation: 'complete', error });
261
+ if (!isDedicatedChannelError(error)) {
262
+ safeInvoke(() => lifecycleRef.current.onMutationError?.('complete', error));
263
+ }
264
+ throw err;
265
+ }
266
+ }, [runner, cartClient, cookieStore]);
267
+ /**
268
+ * Payment session creation. NOT a cart operation (works on `orderId` from
269
+ * `complete().order.id`) so the recovery runner is bypassed — there is no
270
+ * cart to recover from. Wrapped in `wrapMutation` only for status tracking
271
+ * so consumers can render a single `<Spinner label={status.operation} />`
272
+ * across the whole checkout lifecycle.
273
+ */
274
+ const createPayment = useCallback((input) => wrapMutation('createPayment', () => cartClient.createPayment(input), 'Failed to create payment'), [cartClient, wrapMutation]);
110
275
  // --- Lifecycle ---
111
276
  const clearCart = useCallback(() => {
112
277
  cookieStore.clear();
@@ -115,7 +280,11 @@ export function useCartManager() {
115
280
  // Backward-compatible derived selectors over the tagged-union status.
116
281
  const isLoading = status.type === 'loading';
117
282
  const error = status.type === 'error' ? status.error.message : null;
118
- return {
283
+ // Memoize the aggregate so the object identity changes only when `status`
284
+ // flips (the sole reactive field) — every method is already useCallback-stable.
285
+ // Keeps `<CartManagerProvider>`'s Context value referentially stable across
286
+ // unrelated re-renders, matching the sibling StorefrontClientProvider.
287
+ return useMemo(() => ({
119
288
  getCart,
120
289
  getCartId,
121
290
  addItem,
@@ -123,12 +292,47 @@ export function useCartManager() {
123
292
  setShippingAddress,
124
293
  updateDiscountCodes,
125
294
  updateNote,
295
+ updateAttributes,
126
296
  updateItem,
127
297
  removeItem,
298
+ setBillingAddress,
299
+ selectShippingMethod,
300
+ selectPaymentMethod,
301
+ clearPaymentSelection,
302
+ applyGiftCard,
303
+ removeGiftCard,
304
+ updateGiftCardRecipient,
305
+ complete,
306
+ createPayment,
128
307
  clearCart,
129
308
  onExpired,
130
309
  status,
131
310
  isLoading,
132
311
  error,
133
- };
312
+ }), [
313
+ getCart,
314
+ getCartId,
315
+ addItem,
316
+ updateBuyerIdentity,
317
+ setShippingAddress,
318
+ updateDiscountCodes,
319
+ updateNote,
320
+ updateAttributes,
321
+ updateItem,
322
+ removeItem,
323
+ setBillingAddress,
324
+ selectShippingMethod,
325
+ selectPaymentMethod,
326
+ clearPaymentSelection,
327
+ applyGiftCard,
328
+ removeGiftCard,
329
+ updateGiftCardRecipient,
330
+ complete,
331
+ createPayment,
332
+ clearCart,
333
+ onExpired,
334
+ status,
335
+ isLoading,
336
+ error,
337
+ ]);
134
338
  }
@@ -1 +1 @@
1
- {"version":3,"file":"use-login.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/use-login.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AASH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,gHAAgH;IAChH,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IACjE,iDAAiD;IACjD,WAAW,EAAE,OAAO,CAAC;IACrB,0GAA0G;IAC1G,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,wBAAgB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,cAAc,CA+DtE"}
1
+ {"version":3,"file":"use-login.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/use-login.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AASH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,gHAAgH;IAChH,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IACjE,iDAAiD;IACjD,WAAW,EAAE,OAAO,CAAC;IACrB,0GAA0G;IAC1G,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,wBAAgB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,cAAc,CAgEtE"}
@@ -40,14 +40,14 @@ export function useLogin(options = {}) {
40
40
  firstName: customer.firstName ?? undefined,
41
41
  lastName: customer.lastName ?? undefined,
42
42
  phone: customer.phone ?? undefined,
43
- }, result.accessToken);
43
+ }, result.accessToken, result.expiresAt);
44
44
  }
45
45
  else {
46
- setAuth({ id: '', email }, result.accessToken);
46
+ setAuth({ id: '', email }, result.accessToken, result.expiresAt);
47
47
  }
48
48
  }
49
49
  catch {
50
- setAuth({ id: '', email }, result.accessToken);
50
+ setAuth({ id: '', email }, result.accessToken, result.expiresAt);
51
51
  }
52
52
  return {
53
53
  success: true,
@@ -1 +1 @@
1
- {"version":3,"file":"use-refresh-token.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/use-refresh-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,MAAM,WAAW,sBAAsB;IACrC,qFAAqF;IACrF,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,yDAAyD;IACzD,YAAY,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAChD,mDAAmD;IACnD,iBAAiB,EAAE,OAAO,CAAC;IAC3B,yFAAyF;IACzF,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,qBAAqB,CA+C3F"}
1
+ {"version":3,"file":"use-refresh-token.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/use-refresh-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,MAAM,WAAW,sBAAsB;IACrC,qFAAqF;IACrF,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,yDAAyD;IACzD,YAAY,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAChD,mDAAmD;IACnD,iBAAiB,EAAE,OAAO,CAAC;IAC3B,yFAAyF;IACzF,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,qBAAqB,CAiD3F"}
@@ -36,10 +36,12 @@ export function useRefreshToken(options = {}) {
36
36
  if (options.onSetToken) {
37
37
  await options.onSetToken(result.accessToken);
38
38
  }
39
- const currentCustomer = authStore.getState().customer;
40
- if (currentCustomer) {
41
- setAuth(currentCustomer, result.accessToken);
42
- }
39
+ // Thread the new token + expiry into the store unconditionally — `setAuth`
40
+ // accepts a null customer, so a server-seeded session without a loaded
41
+ // profile (SSO callback / magic link / dev seed) still gets its refreshed
42
+ // `expiresAt`, keeping the proactive scheduler armed (parity with the
43
+ // in-provider refresh + scheduler, which also pass `getState().customer`).
44
+ setAuth(authStore.getState().customer, result.accessToken, result.expiresAt);
43
45
  return {
44
46
  success: true,
45
47
  userErrors: [],
@@ -0,0 +1,16 @@
1
+ /**
2
+ * useSessionExpired — subscribe to the global session-expired signal.
3
+ *
4
+ * Fired when the SDK can no longer keep the customer session alive: a proactive
5
+ * refresh failed on tab wake (R6.3), or a reactive refresh after a 401 also
6
+ * failed (R2.4). Use once near the app root to react globally — show a notice
7
+ * and redirect to sign-in (R14.2). No-op outside `StorefrontProvider`.
8
+ */
9
+ import type { SessionExpiredEmitter, SessionExpiredEvent } from '../../core/auth/session-events';
10
+ /**
11
+ * Context carrying the provider-scoped session-expired emitter. Created in
12
+ * `StorefrontProvider` via `useRef` (Inv-3 — never a module-level singleton).
13
+ */
14
+ export declare const SessionExpiredContext: import("react").Context<SessionExpiredEmitter | null>;
15
+ export declare function useSessionExpired(listener: (event: SessionExpiredEvent) => void): void;
16
+ //# sourceMappingURL=use-session-expired.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-session-expired.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/use-session-expired.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAEjG;;;GAGG;AACH,eAAO,MAAM,qBAAqB,uDAAoD,CAAC;AAEvF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,GAAG,IAAI,CAUtF"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * useSessionExpired — subscribe to the global session-expired signal.
3
+ *
4
+ * Fired when the SDK can no longer keep the customer session alive: a proactive
5
+ * refresh failed on tab wake (R6.3), or a reactive refresh after a 401 also
6
+ * failed (R2.4). Use once near the app root to react globally — show a notice
7
+ * and redirect to sign-in (R14.2). No-op outside `StorefrontProvider`.
8
+ */
9
+ 'use client';
10
+ import { createContext, useContext, useEffect, useRef } from 'react';
11
+ /**
12
+ * Context carrying the provider-scoped session-expired emitter. Created in
13
+ * `StorefrontProvider` via `useRef` (Inv-3 — never a module-level singleton).
14
+ */
15
+ export const SessionExpiredContext = createContext(null);
16
+ export function useSessionExpired(listener) {
17
+ const emitter = useContext(SessionExpiredContext);
18
+ // Keep the latest listener without re-subscribing on every render.
19
+ const ref = useRef(listener);
20
+ ref.current = listener;
21
+ useEffect(() => {
22
+ if (!emitter)
23
+ return;
24
+ return emitter.subscribe((event) => ref.current(event));
25
+ }, [emitter]);
26
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * useSessionRefresh — proactive, browser-only session-refresh scheduler.
3
+ *
4
+ * Renews the access token shortly *before* it expires so an active buyer is
5
+ * never logged out mid-session, reschedules from each new expiry, and never runs
6
+ * on the server. On tab wake after the token already lapsed it tries once and —
7
+ * if the session can no longer be recovered — emits `session-expired` and clears
8
+ * local auth.
9
+ *
10
+ * The refresh goes through the same-origin BFF route via
11
+ * `AuthClient.refreshSession()` (`POST {authBasePath}/refresh`). The route handler
12
+ * reads the httpOnly refresh cookie server-side, rotates it against the backend,
13
+ * and sets the new first-party cookies — so an ALREADY-EXPIRED access token still
14
+ * refreshes (the old GraphQL `customerRefreshToken` could not, as it needed a
15
+ * valid access token). No `setToken` round-trip and no consumer callback.
16
+ *
17
+ * The timer lives in the effect closure (provider lifecycle), never in module state.
18
+ */
19
+ import type { SessionExpiredEmitter } from '../../core/auth/session-events';
20
+ export interface UseSessionRefreshOptions {
21
+ /** Master switch. Defaults to `true` in the browser, `false` on the server. */
22
+ enabled?: boolean;
23
+ /** Refresh this many ms before the token's `expiresAt` (default 60_000). */
24
+ bufferMs?: number;
25
+ /**
26
+ * Emitter the scheduler notifies when a wake-time refresh cannot recover the
27
+ * session. Provided by `StorefrontProvider`; subscribe via `useSessionExpired`.
28
+ */
29
+ sessionExpiredEmitter?: SessionExpiredEmitter;
30
+ }
31
+ export declare function useSessionRefresh(options?: UseSessionRefreshOptions): void;
32
+ //# sourceMappingURL=use-session-refresh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-session-refresh.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/use-session-refresh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAE5E,MAAM,WAAW,wBAAwB;IACvC,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;CAC/C;AAYD,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,IAAI,CAkH9E"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * useSessionRefresh — proactive, browser-only session-refresh scheduler.
3
+ *
4
+ * Renews the access token shortly *before* it expires so an active buyer is
5
+ * never logged out mid-session, reschedules from each new expiry, and never runs
6
+ * on the server. On tab wake after the token already lapsed it tries once and —
7
+ * if the session can no longer be recovered — emits `session-expired` and clears
8
+ * local auth.
9
+ *
10
+ * The refresh goes through the same-origin BFF route via
11
+ * `AuthClient.refreshSession()` (`POST {authBasePath}/refresh`). The route handler
12
+ * reads the httpOnly refresh cookie server-side, rotates it against the backend,
13
+ * and sets the new first-party cookies — so an ALREADY-EXPIRED access token still
14
+ * refreshes (the old GraphQL `customerRefreshToken` could not, as it needed a
15
+ * valid access token). No `setToken` round-trip and no consumer callback.
16
+ *
17
+ * The timer lives in the effect closure (provider lifecycle), never in module state.
18
+ */
19
+ 'use client';
20
+ import { useEffect, useRef } from 'react';
21
+ import { useAuthStoreApi } from '../stores/store-context';
22
+ import { useStorefrontClientContext } from '../providers/storefront-client-provider';
23
+ const DEFAULT_BUFFER_MS = 60_000;
24
+ /** Backoff before retrying a proactive refresh that failed while the token was still valid. */
25
+ const PROACTIVE_RETRY_MS = 15_000;
26
+ /**
27
+ * When the token is already within the buffer window but still valid, space out
28
+ * refreshes by this much so a token whose lifetime is <= the buffer cannot
29
+ * busy-loop the scheduler.
30
+ */
31
+ const WITHIN_BUFFER_RETRY_MS = 5_000;
32
+ export function useSessionRefresh(options = {}) {
33
+ const { enabled, bufferMs = DEFAULT_BUFFER_MS, sessionExpiredEmitter } = options;
34
+ const isBrowser = typeof window !== 'undefined';
35
+ const active = (enabled ?? isBrowser) && isBrowser;
36
+ const { authClient } = useStorefrontClientContext();
37
+ const authStore = useAuthStoreApi();
38
+ // Moving parts in refs so the scheduling effect re-runs only on structural
39
+ // deps (active / bufferMs / authBasePath / store identity), not on every render.
40
+ const authClientRef = useRef(authClient);
41
+ authClientRef.current = authClient;
42
+ const emitterRef = useRef(sessionExpiredEmitter);
43
+ emitterRef.current = sessionExpiredEmitter;
44
+ useEffect(() => {
45
+ if (!active)
46
+ return;
47
+ let timer;
48
+ let disposed = false;
49
+ let inFlight = false;
50
+ // Tracks the expiry we last scheduled against, so the store subscription
51
+ // ignores our own writes (we reschedule explicitly after a refresh).
52
+ let lastExpiresAt = authStore.getState().expiresAt;
53
+ const clearTimer = () => {
54
+ if (timer !== undefined) {
55
+ clearTimeout(timer);
56
+ timer = undefined;
57
+ }
58
+ };
59
+ const doRefresh = async (tokenAlreadyExpired) => {
60
+ if (inFlight)
61
+ return;
62
+ inFlight = true;
63
+ try {
64
+ // Same-origin BFF refresh: the route reads the httpOnly refresh cookie
65
+ // server-side, rotates it against the backend, and sets the new
66
+ // first-party cookies. No `setToken` round-trip — the route owns the cookie.
67
+ const result = await authClientRef.current.refreshSession();
68
+ if (disposed)
69
+ return;
70
+ lastExpiresAt = result.expiresAt;
71
+ authStore.getState().setAuth(authStore.getState().customer, result.accessToken, result.expiresAt);
72
+ schedule();
73
+ }
74
+ catch (err) {
75
+ if (disposed)
76
+ return;
77
+ if (tokenAlreadyExpired) {
78
+ // The access token had already lapsed and the BFF refresh could not
79
+ // recover the session (refresh token expired/reused/revoked). Clear
80
+ // local auth and notify so the storefront can prompt re-login.
81
+ authStore.getState().clearAuth();
82
+ emitterRef.current?.emit({ reason: 'wake-refresh-failed', cause: err });
83
+ }
84
+ else {
85
+ // Token still valid — a proactive refresh failed transiently
86
+ // (network / server blip). Do NOT log the buyer out; retry shortly.
87
+ clearTimer();
88
+ timer = setTimeout(schedule, PROACTIVE_RETRY_MS);
89
+ }
90
+ }
91
+ finally {
92
+ inFlight = false;
93
+ }
94
+ };
95
+ const schedule = () => {
96
+ clearTimer();
97
+ const { expiresAt, isAuthenticated } = authStore.getState();
98
+ if (!expiresAt || !isAuthenticated)
99
+ return;
100
+ const expiryMs = new Date(expiresAt).getTime();
101
+ if (Number.isNaN(expiryMs))
102
+ return;
103
+ const now = Date.now();
104
+ let fireIn;
105
+ if (now >= expiryMs) {
106
+ // Already expired (e.g. tab slept past expiry) — recover ASAP.
107
+ fireIn = 0;
108
+ }
109
+ else {
110
+ const untilBuffer = expiryMs - bufferMs - now;
111
+ // Within the buffer but still valid — space retries so a token whose
112
+ // lifetime is <= the buffer cannot busy-loop.
113
+ fireIn = untilBuffer > 0 ? untilBuffer : WITHIN_BUFFER_RETRY_MS;
114
+ }
115
+ // ALWAYS arm a timer — never call doRefresh synchronously. A synchronous
116
+ // call can re-enter while a refresh is in flight and be dropped by the
117
+ // in-flight guard, leaving the scheduler permanently stalled; the timer
118
+ // fires after the current call stack, by which point `inFlight` has reset.
119
+ // `tokenAlreadyExpired` is re-derived at fire time (the clock has moved).
120
+ timer = setTimeout(() => void doRefresh(Date.now() >= expiryMs), fireIn);
121
+ };
122
+ // Reschedule when expiresAt changes from outside (login, manual refresh).
123
+ const unsubscribe = authStore.subscribe((state) => {
124
+ if (disposed)
125
+ return;
126
+ if (state.expiresAt !== lastExpiresAt) {
127
+ lastExpiresAt = state.expiresAt;
128
+ schedule();
129
+ }
130
+ });
131
+ // Wake-from-sleep: background tabs throttle/pause timers — on return,
132
+ // recompute (and refresh immediately if the token already lapsed).
133
+ const onVisibility = () => {
134
+ if (document.visibilityState === 'visible' && !disposed)
135
+ schedule();
136
+ };
137
+ document.addEventListener('visibilitychange', onVisibility);
138
+ schedule();
139
+ return () => {
140
+ disposed = true;
141
+ clearTimer();
142
+ unsubscribe();
143
+ document.removeEventListener('visibilitychange', onVisibility);
144
+ };
145
+ // eslint-disable-next-line react-hooks/exhaustive-deps
146
+ }, [active, bufferMs, authStore]);
147
+ }
@@ -15,11 +15,15 @@ export { StorefrontProvider, type StorefrontProviderProps } from './providers/st
15
15
  export { StorefrontClientProvider, type StorefrontClientProviderProps } from './providers/storefront-client-provider';
16
16
  export { CurrencyProvider, type CurrencyProviderProps } from './providers/currency-provider';
17
17
  export { LanguageProvider, type LanguageProviderProps } from './providers/language-provider';
18
+ export { CartManagerProvider, useCartManagerContext, type CartManagerProviderProps } from './providers/cart-manager-provider';
18
19
  export { useAuth, type UseAuthOptions, type LoginResult, type LogoutResult, type TokenRefreshResult } from './hooks/use-auth';
19
20
  export { useLogin, type UseLoginOptions, type UseLoginReturn } from './hooks/use-login';
20
21
  export { useLogout, type UseLogoutOptions, type UseLogoutReturn } from './hooks/use-logout';
21
22
  export { useRefreshToken, type UseRefreshTokenOptions, type UseRefreshTokenReturn } from './hooks/use-refresh-token';
22
- export { useCartManager, type CartManagerOperation, type CartManagerStatus, type UseCartManagerResult } from './hooks/use-cart-manager';
23
+ export { useSessionRefresh, type UseSessionRefreshOptions } from './hooks/use-session-refresh';
24
+ export { useSessionExpired } from './hooks/use-session-expired';
25
+ export type { SessionExpiredEvent, SessionExpiredReason, SessionExpiredEmitter } from '../core/auth/session-events';
26
+ export { useCartManager, type CartManagerOperation, type CartManagerStatus, type UseCartManagerResult, type UseCartManagerOptions, type CartManagerLifecycleCallbacks } from './hooks/use-cart-manager';
23
27
  export { useCart, type UseCartOptions, type UseCartResult, type ServerCartOperation } from './hooks/use-cart';
24
28
  export { useStorefrontClient } from './hooks/use-storefront-client';
25
29
  export { useCurrency } from './hooks/use-currency';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}