@viu/emporix-sdk-react 2.13.1 → 2.15.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.
- package/CHANGELOG.md +26 -0
- package/dist/{chunk-VMDBYVWG.js → chunk-62GKMVS3.js} +30 -4
- package/dist/chunk-62GKMVS3.js.map +1 -0
- package/dist/{chunk-SXZCM2LE.js → chunk-IREROKYI.js} +658 -311
- package/dist/chunk-IREROKYI.js.map +1 -0
- package/dist/{chunk-4YDWCA7A.js → chunk-ZNE3J25W.js} +165 -107
- package/dist/chunk-ZNE3J25W.js.map +1 -0
- package/dist/hooks.cjs +751 -430
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.cts +2 -2
- package/dist/hooks.d.ts +2 -2
- package/dist/hooks.js +185 -4
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +950 -551
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -6
- package/dist/index.d.ts +40 -6
- package/dist/index.js +240 -8
- package/dist/index.js.map +1 -1
- package/dist/{provider-Bcb-tOpS.d.ts → provider-Cgm9QVoo.d.ts} +1 -1
- package/dist/{provider-Ddo7aSOI.d.cts → provider-DGjmBPMr.d.cts} +1 -1
- package/dist/provider.cjs +193 -123
- package/dist/provider.cjs.map +1 -1
- package/dist/provider.d.cts +1 -1
- package/dist/provider.d.ts +1 -1
- package/dist/provider.js +12 -3
- package/dist/provider.js.map +1 -1
- package/dist/ssr.cjs +36 -5
- package/dist/ssr.cjs.map +1 -1
- package/dist/ssr.d.cts +22 -6
- package/dist/ssr.d.ts +22 -6
- package/dist/ssr.js +54 -1
- package/dist/ssr.js.map +1 -1
- package/dist/storage.cjs +58 -9
- package/dist/storage.cjs.map +1 -1
- package/dist/storage.d.cts +8 -2
- package/dist/storage.d.ts +8 -2
- package/dist/storage.js +15 -2
- package/dist/storage.js.map +1 -1
- package/dist/{use-returns-uZJiO46w.d.ts → use-returns-DrqdwizU.d.ts} +1 -1
- package/dist/{use-returns-DT98Ptod.d.cts → use-returns-fKPIgjmU.d.cts} +1 -1
- package/package.json +5 -4
- package/dist/chunk-4YDWCA7A.js.map +0 -1
- package/dist/chunk-SXZCM2LE.js.map +0 -1
- package/dist/chunk-TIS4BKHK.js +0 -25
- package/dist/chunk-TIS4BKHK.js.map +0 -1
- package/dist/chunk-VMDBYVWG.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @viu/emporix-sdk-react
|
|
2
2
|
|
|
3
|
+
## 2.15.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#131](https://github.com/viuteam/emporix-sdk/pull/131) [`4c2862c`](https://github.com/viuteam/emporix-sdk/commit/4c2862c2a3394b04bbca8dfa2abafb529023920a) Thanks [@amnael1](https://github.com/amnael1)! - fix multiple checkouts per session: `useCheckout().placeOrder`/`placeOrderFromQuote` now reset the cart on success — they clear `storage.cartId` and drop the `["emporix","cart-bootstrap"]` query cache (held with `staleTime: Infinity`). Previously a placed order closed its cart server-side, but the bootstrap cache still re-served that closed cart on the next `useActiveCart({ create: true })`, so the second checkout re-adopted the dead cart and failed (cart reads 404, `placeOrder` 401). The next checkout now bootstraps a fresh cart.
|
|
8
|
+
|
|
9
|
+
- [#131](https://github.com/viuteam/emporix-sdk/pull/131) [`bcb35c4`](https://github.com/viuteam/emporix-sdk/commit/bcb35c41397a1c90b23ab866bb6f111159f02fef) Thanks [@amnael1](https://github.com/amnael1)! - fix customer checkout after a page reload: the `saasToken` (checkout `saas-token` header) is now persisted by the storage adapters (`getSaasToken`/`setSaasToken`, key `emporix.saasToken`) and re-hydrated into the customer-session store on load — alongside the already-persisted `refreshToken`. Previously it lived in memory only, so a reload mid-session dropped it and customer checkout 401'd with `"Saas TOKEN is invalid"` (the refresh endpoint cannot re-mint it). The storage methods are optional, so custom adapters are unaffected; the bundled memory/localStorage/cookie adapters all persist it.
|
|
10
|
+
|
|
11
|
+
- [#128](https://github.com/viuteam/emporix-sdk/pull/128) [`2d8a6cb`](https://github.com/viuteam/emporix-sdk/commit/2d8a6cb715e004cad3ab1a0652b4c77e330eb810) Thanks [@amnael1](https://github.com/amnael1)! - internal refactor: the standard read hooks now share a single `useEmporixQuery` factory that encapsulates auth-context resolution, site discriminators, query-key assembly, and default options. No observable behavior or API change — query keys, `enabled` gates, and `staleTime` values are identical; the existing hook test suites pass unchanged. Hooks with a non-standard auth shape (`useCustomerOnlyCtx` throw-on-missing — approvals/returns; caller-supplied `authCtx` — sales-order) and all infinite/bespoke-key hooks are intentionally left as-is.
|
|
12
|
+
|
|
13
|
+
## 2.14.0
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [#127](https://github.com/viuteam/emporix-sdk/pull/127) [`93e3b76`](https://github.com/viuteam/emporix-sdk/commit/93e3b76131abe9f8cdc29e010b99ddc92e575e91) Thanks [@amnael1](https://github.com/amnael1)! - default the cookie storage adapter's `Secure` attribute to on for https origins. Token cookies no longer ride plain http in production by default; localhost/http dev is unaffected (protocol-sniffed). Pass `secure: false` explicitly only for non-https deployments.
|
|
18
|
+
|
|
19
|
+
- [#125](https://github.com/viuteam/emporix-sdk/pull/125) [`c5f7a7d`](https://github.com/viuteam/emporix-sdk/commit/c5f7a7d89bdd6ac44ff92719f732fbd5d95b55ee) Thanks [@amnael1](https://github.com/amnael1)! - fix logout to purge the entire `["emporix"]` query-cache namespace. Previously only the `customer` and `cart` keys were removed, so customer-scoped caches without a user discriminator (payment modes, order lists) survived logout and could be served to the next logged-in customer straight from cache.
|
|
20
|
+
|
|
21
|
+
- [#125](https://github.com/viuteam/emporix-sdk/pull/125) [`48fed7a`](https://github.com/viuteam/emporix-sdk/commit/48fed7afccb3b7146dabfa3e7d86e384b2171689) Thanks [@amnael1](https://github.com/amnael1)! - ship a `"use client"` directive in the built client entries (`.`, `./provider`, `./hooks`, `./storage`) so they load as Client Components under the Next.js App Router without every consumer having to add their own `"use client"` wrapper file. `./ssr` stays directive-free and remains importable from Server Components — in server code, import `prefetchProduct`/`prefetchCart`/`prefetchOrder` from `@viu/emporix-sdk-react/ssr`, not from the package root.
|
|
22
|
+
|
|
23
|
+
- [#127](https://github.com/viuteam/emporix-sdk/pull/127) [`1a5e1f3`](https://github.com/viuteam/emporix-sdk/commit/1a5e1f3fb6b048b9732066ba2c02dfc871e47f3b) Thanks [@amnael1](https://github.com/amnael1)! - make auth/cart state reads reactive: all render-time `storage.getCustomerToken()`/`getCartId()` reads now go through `useSyncExternalStore`-backed snapshots. Login/logout and cart-id writes immediately re-render dependent hooks — previously `enabled` gates (e.g. `usePaymentModes`, `useMyCompanies`, order hooks) stayed stale until an unrelated re-render, and sibling components could tear under concurrent rendering. Storage adapters without `subscribe`/`subscribeAll` behave as before (non-reactive).
|
|
24
|
+
|
|
25
|
+
- [#127](https://github.com/viuteam/emporix-sdk/pull/127) [`31a8183`](https://github.com/viuteam/emporix-sdk/commit/31a8183329d17fe5247f62c9c39a74beb7a1a45e) Thanks [@amnael1](https://github.com/amnael1)! - apply the provider's balanced query defaults (`staleTime: 30s`, no focus refetch, `retry: 1`) to the `["emporix"]` namespace of any QueryClient — including consumer-supplied ones, which previously ran SDK queries with React-Query factory defaults (focus-refetch storms + retry amplification against the live tenant). The provider only fills gaps: a consumer's explicit defaults win, whether set globally (`defaultOptions.queries`) or emporix-scoped (`setQueryDefaults(["emporix"], …)`), and per-hook options always win; host-app queries outside the namespace are untouched.
|
|
26
|
+
|
|
27
|
+
- [#127](https://github.com/viuteam/emporix-sdk/pull/127) [`124532f`](https://github.com/viuteam/emporix-sdk/commit/124532fef11b1a4aadf2f80e979005b036168e1c) Thanks [@amnael1](https://github.com/amnael1)! - fix the RSC/SSR prefetch pipeline and StrictMode safety: `prefetchProduct`/`prefetchCart`/`prefetchOrder` now build their query keys through the same `emporixKey` builder the hooks use (previously the keys never matched — `siteCode`/`language`/company discriminators were missing — so hydration was always a cache miss and the client refetched); new `siteCode`/`language`/`activeCompanyId` options mirror the client context. The provider's anonymous-store wiring and `initialCustomerToken` seed now re-run when the `client`/`storage` props change and no longer execute inside `useMemo`; the fallback QueryClient is held in state (a dropped memo cache could previously discard the whole query cache). CompanyContext bootstrap is cancellation-safe under StrictMode and company switches are serialized — the token-rotating refresh can no longer double-fire with the same refresh token.
|
|
28
|
+
|
|
3
29
|
## 2.13.1
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
// src/storage/memory.ts
|
|
2
4
|
function createMemoryStorage(opts = {}) {
|
|
3
5
|
let token = opts.initial ?? null;
|
|
@@ -7,6 +9,7 @@ function createMemoryStorage(opts = {}) {
|
|
|
7
9
|
let language = null;
|
|
8
10
|
let activeLegalEntityId = null;
|
|
9
11
|
let refreshToken = null;
|
|
12
|
+
let saasToken = null;
|
|
10
13
|
const tokenListeners = /* @__PURE__ */ new Set();
|
|
11
14
|
const all = createListenerSet();
|
|
12
15
|
return {
|
|
@@ -50,6 +53,11 @@ function createMemoryStorage(opts = {}) {
|
|
|
50
53
|
refreshToken = t;
|
|
51
54
|
all.notify("refreshToken");
|
|
52
55
|
},
|
|
56
|
+
getSaasToken: () => saasToken,
|
|
57
|
+
setSaasToken: (t) => {
|
|
58
|
+
saasToken = t;
|
|
59
|
+
all.notify("saasToken");
|
|
60
|
+
},
|
|
53
61
|
subscribeAll: (l) => all.add(l)
|
|
54
62
|
};
|
|
55
63
|
}
|
|
@@ -62,6 +70,7 @@ var SITE_KEY = "emporix.siteCode";
|
|
|
62
70
|
var LANGUAGE_KEY = "emporix.language";
|
|
63
71
|
var ACTIVE_LE_KEY = "emporix.activeLegalEntityId";
|
|
64
72
|
var REFRESH_KEY = "emporix.refreshToken";
|
|
73
|
+
var SAAS_KEY = "emporix.saasToken";
|
|
65
74
|
function createLocalStorageStorage(opts = {}) {
|
|
66
75
|
const tokenKey = opts.key ?? DEFAULT_TOKEN_KEY;
|
|
67
76
|
const available = typeof globalThis !== "undefined" && typeof globalThis.localStorage !== "undefined";
|
|
@@ -120,6 +129,12 @@ function createLocalStorageStorage(opts = {}) {
|
|
|
120
129
|
else ls.setItem(REFRESH_KEY, t);
|
|
121
130
|
all.notify("refreshToken");
|
|
122
131
|
},
|
|
132
|
+
getSaasToken: () => ls.getItem(SAAS_KEY),
|
|
133
|
+
setSaasToken: (t) => {
|
|
134
|
+
if (t === null) ls.removeItem(SAAS_KEY);
|
|
135
|
+
else ls.setItem(SAAS_KEY, t);
|
|
136
|
+
all.notify("saasToken");
|
|
137
|
+
},
|
|
123
138
|
subscribeAll: (l) => all.add(l)
|
|
124
139
|
};
|
|
125
140
|
}
|
|
@@ -132,10 +147,11 @@ var SITE_NAME = "emporix.siteCode";
|
|
|
132
147
|
var LANGUAGE_NAME = "emporix.language";
|
|
133
148
|
var ACTIVE_LE_NAME = "emporix.activeLegalEntityId";
|
|
134
149
|
var REFRESH_NAME = "emporix.refreshToken";
|
|
150
|
+
var SAAS_NAME = "emporix.saasToken";
|
|
135
151
|
function createCookieStorage(opts = {}) {
|
|
136
152
|
const tokenName = opts.name ?? DEFAULT_TOKEN_NAME;
|
|
137
153
|
const sameSite = opts.sameSite ?? "lax";
|
|
138
|
-
const secure = opts.secure ??
|
|
154
|
+
const secure = opts.secure ?? (typeof location !== "undefined" && location.protocol === "https:");
|
|
139
155
|
if (typeof document === "undefined") {
|
|
140
156
|
console.warn("[emporix] document unavailable; cookie storage falling back to in-memory");
|
|
141
157
|
return createMemoryStorage();
|
|
@@ -191,6 +207,11 @@ function createCookieStorage(opts = {}) {
|
|
|
191
207
|
writeCookie(REFRESH_NAME, t);
|
|
192
208
|
all.notify("refreshToken");
|
|
193
209
|
},
|
|
210
|
+
getSaasToken: () => readCookie(SAAS_NAME),
|
|
211
|
+
setSaasToken: (t) => {
|
|
212
|
+
writeCookie(SAAS_NAME, t);
|
|
213
|
+
all.notify("saasToken");
|
|
214
|
+
},
|
|
194
215
|
subscribeAll: (l) => all.add(l)
|
|
195
216
|
};
|
|
196
217
|
}
|
|
@@ -226,6 +247,11 @@ function parseAnonymousSession(raw) {
|
|
|
226
247
|
}
|
|
227
248
|
}
|
|
228
249
|
|
|
229
|
-
export {
|
|
230
|
-
|
|
231
|
-
|
|
250
|
+
export {
|
|
251
|
+
createLocalStorageStorage,
|
|
252
|
+
createCookieStorage,
|
|
253
|
+
createListenerSet,
|
|
254
|
+
parseAnonymousSession,
|
|
255
|
+
createMemoryStorage
|
|
256
|
+
};
|
|
257
|
+
//# sourceMappingURL=chunk-62GKMVS3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/storage/memory.ts","../src/storage/local-storage.ts","../src/storage/cookie.ts","../src/storage/index.ts"],"sourcesContent":["import {\n createListenerSet,\n type EmporixStorage,\n type EmporixStorageKey,\n type PersistedAnonymousSession,\n} from \"./index\";\n\n/** In-memory token store. Default, SSR-safe, no persistence. */\nexport function createMemoryStorage(opts: { initial?: string } = {}): EmporixStorage {\n let token: string | null = opts.initial ?? null;\n let cartId: string | null = null;\n let anon: PersistedAnonymousSession | null = null;\n let siteCode: string | null = null;\n let language: string | null = null;\n let activeLegalEntityId: string | null = null;\n let refreshToken: string | null = null;\n let saasToken: string | null = null;\n const tokenListeners = new Set<(t: string | null) => void>();\n const all = createListenerSet<EmporixStorageKey>();\n return {\n getCustomerToken: () => token,\n setCustomerToken: (t) => {\n token = t;\n for (const l of tokenListeners) l(token);\n all.notify(\"customerToken\");\n },\n subscribe: (l) => {\n tokenListeners.add(l);\n return () => tokenListeners.delete(l);\n },\n getCartId: () => cartId,\n setCartId: (id) => {\n cartId = id;\n all.notify(\"cartId\");\n },\n getAnonymousSession: () => anon,\n setAnonymousSession: (s) => {\n anon = s;\n all.notify(\"anonymousSession\");\n },\n getSiteCode: () => siteCode,\n setSiteCode: (code) => {\n siteCode = code;\n all.notify(\"siteCode\");\n },\n getLanguage: () => language,\n setLanguage: (l) => {\n language = l;\n all.notify(\"language\");\n },\n getActiveLegalEntityId: () => activeLegalEntityId,\n setActiveLegalEntityId: (id) => {\n activeLegalEntityId = id;\n all.notify(\"activeLegalEntityId\");\n },\n getRefreshToken: () => refreshToken,\n setRefreshToken: (t) => {\n refreshToken = t;\n all.notify(\"refreshToken\");\n },\n getSaasToken: () => saasToken,\n setSaasToken: (t) => {\n saasToken = t;\n all.notify(\"saasToken\");\n },\n subscribeAll: (l) => all.add(l),\n };\n}\n","import {\n createListenerSet,\n parseAnonymousSession,\n type EmporixStorage,\n type EmporixStorageKey,\n} from \"./index\";\nimport { createMemoryStorage } from \"./memory\";\n\nconst DEFAULT_TOKEN_KEY = \"emporix.customerToken\";\nconst CART_KEY = \"emporix.cartId\";\nconst ANON_KEY = \"emporix.anonymousSession\";\nconst SITE_KEY = \"emporix.siteCode\";\nconst LANGUAGE_KEY = \"emporix.language\";\nconst ACTIVE_LE_KEY = \"emporix.activeLegalEntityId\";\nconst REFRESH_KEY = \"emporix.refreshToken\";\nconst SAAS_KEY = \"emporix.saasToken\";\n\n/** Browser `localStorage`-backed store. Falls back to memory on the server. */\nexport function createLocalStorageStorage(opts: { key?: string } = {}): EmporixStorage {\n const tokenKey = opts.key ?? DEFAULT_TOKEN_KEY;\n const available =\n typeof globalThis !== \"undefined\" &&\n typeof (globalThis as { localStorage?: Storage }).localStorage !== \"undefined\";\n if (!available) {\n // eslint-disable-next-line no-console\n console.warn(\"[emporix] localStorage unavailable; falling back to in-memory storage\");\n return createMemoryStorage();\n }\n const ls = (globalThis as unknown as { localStorage: Storage }).localStorage;\n const tokenListeners = new Set<(t: string | null) => void>();\n const all = createListenerSet<EmporixStorageKey>();\n return {\n getCustomerToken: () => ls.getItem(tokenKey),\n setCustomerToken: (t) => {\n if (t === null) ls.removeItem(tokenKey);\n else ls.setItem(tokenKey, t);\n for (const l of tokenListeners) l(t);\n all.notify(\"customerToken\");\n },\n subscribe: (l) => {\n tokenListeners.add(l);\n return () => tokenListeners.delete(l);\n },\n getCartId: () => ls.getItem(CART_KEY),\n setCartId: (id) => {\n if (id === null) ls.removeItem(CART_KEY);\n else ls.setItem(CART_KEY, id);\n all.notify(\"cartId\");\n },\n getAnonymousSession: () => parseAnonymousSession(ls.getItem(ANON_KEY)),\n setAnonymousSession: (s) => {\n if (s === null) ls.removeItem(ANON_KEY);\n else ls.setItem(ANON_KEY, JSON.stringify({ refreshToken: s.refreshToken, sessionId: s.sessionId }));\n all.notify(\"anonymousSession\");\n },\n getSiteCode: () => ls.getItem(SITE_KEY),\n setSiteCode: (code) => {\n if (code === null) ls.removeItem(SITE_KEY);\n else ls.setItem(SITE_KEY, code);\n all.notify(\"siteCode\");\n },\n getLanguage: () => ls.getItem(LANGUAGE_KEY),\n setLanguage: (l) => {\n if (l === null) ls.removeItem(LANGUAGE_KEY);\n else ls.setItem(LANGUAGE_KEY, l);\n all.notify(\"language\");\n },\n getActiveLegalEntityId: () => ls.getItem(ACTIVE_LE_KEY),\n setActiveLegalEntityId: (id) => {\n if (id === null) ls.removeItem(ACTIVE_LE_KEY);\n else ls.setItem(ACTIVE_LE_KEY, id);\n all.notify(\"activeLegalEntityId\");\n },\n getRefreshToken: () => ls.getItem(REFRESH_KEY),\n setRefreshToken: (t) => {\n if (t === null) ls.removeItem(REFRESH_KEY);\n else ls.setItem(REFRESH_KEY, t);\n all.notify(\"refreshToken\");\n },\n getSaasToken: () => ls.getItem(SAAS_KEY),\n setSaasToken: (t) => {\n if (t === null) ls.removeItem(SAAS_KEY);\n else ls.setItem(SAAS_KEY, t);\n all.notify(\"saasToken\");\n },\n subscribeAll: (l) => all.add(l),\n };\n}\n","import {\n createListenerSet,\n parseAnonymousSession,\n type EmporixStorage,\n type EmporixStorageKey,\n} from \"./index\";\nimport { createMemoryStorage } from \"./memory\";\n\nconst DEFAULT_TOKEN_NAME = \"emporix.customerToken\";\nconst CART_NAME = \"emporix.cartId\";\nconst ANON_NAME = \"emporix.anonymousSession\";\nconst SITE_NAME = \"emporix.siteCode\";\nconst LANGUAGE_NAME = \"emporix.language\";\nconst ACTIVE_LE_NAME = \"emporix.activeLegalEntityId\";\nconst REFRESH_NAME = \"emporix.refreshToken\";\nconst SAAS_NAME = \"emporix.saasToken\";\n\n/**\n * Cookie-backed store. `Secure` defaults to on for https origins; override\n * with `secure: false` only for non-https dev setups. Consumer must still pick\n * an appropriate `sameSite` for CSRF safety.\n */\nexport function createCookieStorage(\n opts: { name?: string; secure?: boolean; sameSite?: \"lax\" | \"strict\" | \"none\" } = {},\n): EmporixStorage {\n const tokenName = opts.name ?? DEFAULT_TOKEN_NAME;\n const sameSite = opts.sameSite ?? \"lax\";\n // Default: Secure on https origins. Tokens must not ride plain-http\n // cookies in production; localhost/http dev keeps working without opts.\n const secure =\n opts.secure ?? (typeof location !== \"undefined\" && location.protocol === \"https:\");\n if (typeof document === \"undefined\") {\n // eslint-disable-next-line no-console\n console.warn(\"[emporix] document unavailable; cookie storage falling back to in-memory\");\n return createMemoryStorage();\n }\n const attrs = `path=/; SameSite=${sameSite}${secure ? \"; Secure\" : \"\"}`;\n const readCookie = (name: string): string | null => {\n for (const part of document.cookie.split(\"; \")) {\n const [k, ...v] = part.split(\"=\");\n if (k === name) return decodeURIComponent(v.join(\"=\")) || null;\n }\n return null;\n };\n const writeCookie = (name: string, value: string | null): void => {\n document.cookie =\n value === null\n ? `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; ${attrs}`\n : `${name}=${encodeURIComponent(value)}; ${attrs}`;\n };\n const all = createListenerSet<EmporixStorageKey>();\n return {\n getCustomerToken: () => readCookie(tokenName),\n setCustomerToken: (t) => {\n writeCookie(tokenName, t);\n all.notify(\"customerToken\");\n },\n getCartId: () => readCookie(CART_NAME),\n setCartId: (id) => {\n writeCookie(CART_NAME, id);\n all.notify(\"cartId\");\n },\n getAnonymousSession: () => parseAnonymousSession(readCookie(ANON_NAME)),\n setAnonymousSession: (s) => {\n writeCookie(\n ANON_NAME,\n s === null\n ? null\n : JSON.stringify({ refreshToken: s.refreshToken, sessionId: s.sessionId }),\n );\n all.notify(\"anonymousSession\");\n },\n getSiteCode: () => readCookie(SITE_NAME),\n setSiteCode: (code) => {\n writeCookie(SITE_NAME, code);\n all.notify(\"siteCode\");\n },\n getLanguage: () => readCookie(LANGUAGE_NAME),\n setLanguage: (l) => {\n writeCookie(LANGUAGE_NAME, l);\n all.notify(\"language\");\n },\n getActiveLegalEntityId: () => readCookie(ACTIVE_LE_NAME),\n setActiveLegalEntityId: (id) => {\n writeCookie(ACTIVE_LE_NAME, id);\n all.notify(\"activeLegalEntityId\");\n },\n getRefreshToken: () => readCookie(REFRESH_NAME),\n setRefreshToken: (t) => {\n writeCookie(REFRESH_NAME, t);\n all.notify(\"refreshToken\");\n },\n getSaasToken: () => readCookie(SAAS_NAME),\n setSaasToken: (t) => {\n writeCookie(SAAS_NAME, t);\n all.notify(\"saasToken\");\n },\n subscribeAll: (l) => all.add(l),\n };\n}\n","/** Pluggable persistence for SDK session state. SSR-safe by default (memory). */\nexport interface EmporixStorage {\n // Customer token (unchanged).\n getCustomerToken(): string | null;\n setCustomerToken(token: string | null): void;\n subscribe?(listener: (token: string | null) => void): () => void;\n\n // Active guest / customer cart id.\n getCartId(): string | null;\n setCartId(id: string | null): void;\n\n // Anonymous session — used by DefaultTokenProvider (via EmporixProvider\n // wiring) to preserve sessionId across page reloads.\n getAnonymousSession(): PersistedAnonymousSession | null;\n setAnonymousSession(session: PersistedAnonymousSession | null): void;\n\n // Active site code (MS-2). `null` = no site bound yet.\n getSiteCode(): string | null;\n setSiteCode(code: string | null): void;\n\n // Active language (Accept-Language). `null` = use the site/tenant default.\n getLanguage(): string | null;\n setLanguage(language: string | null): void;\n\n // Active legal entity id (B2B). `null` = B2C mode.\n getActiveLegalEntityId(): string | null;\n setActiveLegalEntityId(id: string | null): void;\n\n // Refresh token — optional persistence. When absent, B2B company-switch\n // falls back to a local-state-only update (no server-side token rescope).\n getRefreshToken(): string | null;\n setRefreshToken(token: string | null): void;\n\n // SaaS token (the checkout `saas-token` header). Persisted so a logged-in\n // customer can still complete checkout after a page reload — the refresh\n // endpoint does not re-mint it. Optional: a custom adapter may omit these,\n // in which case the saasToken stays in-memory only (lost on reload, as\n // before — no regression).\n getSaasToken?(): string | null;\n setSaasToken?(token: string | null): void;\n\n /**\n * Subscribe to any storage write. The listener receives the key that\n * changed. Returns an unsubscribe function. Optional — backends may no-op.\n * Used by the telemetry layer to emit `storage.write` events.\n */\n subscribeAll?(\n listener: (key: EmporixStorageKey) => void,\n ): () => void;\n}\n\n/** Minimal subset of `AnonymousSession` that needs to outlive a page load. */\nexport interface PersistedAnonymousSession {\n refreshToken: string;\n sessionId: string;\n}\n\n/** Backward-compat alias. New code should prefer `EmporixStorage`. */\nexport type TokenStorage = EmporixStorage;\n\n/** Keys that participate in {@link EmporixStorage.subscribeAll}. */\nexport type EmporixStorageKey =\n | \"customerToken\"\n | \"cartId\"\n | \"siteCode\"\n | \"language\"\n | \"anonymousSession\"\n | \"activeLegalEntityId\"\n | \"refreshToken\"\n | \"saasToken\";\n\n/**\n * Internal: create a swallow-on-throw listener set used by all three storage\n * backends for `subscribeAll`. Centralizes the try/catch wrapper so a buggy\n * telemetry handler never breaks a storage write.\n */\nexport function createListenerSet<T>(): {\n add(l: (value: T) => void): () => void;\n notify(value: T): void;\n} {\n const listeners = new Set<(v: T) => void>();\n return {\n add(l) {\n listeners.add(l);\n return () => listeners.delete(l);\n },\n notify(value) {\n for (const l of listeners) {\n try {\n l(value);\n } catch {\n // Swallow handler errors; telemetry must never break writes.\n }\n }\n },\n };\n}\n\n/**\n * Internal: parses a raw `anonymousSession` JSON payload (from localStorage\n * or a cookie) into a {@link PersistedAnonymousSession}. Returns `null` for\n * any malformed or missing input.\n */\nexport function parseAnonymousSession(raw: string | null): PersistedAnonymousSession | null {\n if (!raw) return null;\n try {\n const parsed = JSON.parse(raw) as Partial<PersistedAnonymousSession>;\n if (typeof parsed.refreshToken === \"string\" && typeof parsed.sessionId === \"string\") {\n return { refreshToken: parsed.refreshToken, sessionId: parsed.sessionId };\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport { createMemoryStorage } from \"./memory\";\nexport { createLocalStorageStorage } from \"./local-storage\";\nexport { createCookieStorage } from \"./cookie\";\n"],"mappings":"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","names":[]}
|