@viu/emporix-sdk-react 2.7.0 → 2.8.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/dist/hooks.cjs CHANGED
@@ -56,6 +56,36 @@ async function bootstrapCart(opts) {
56
56
  });
57
57
  }
58
58
 
59
+ // src/hooks/internal/customer-session-store.ts
60
+ var stores = /* @__PURE__ */ new WeakMap();
61
+ function getCustomerSessionStore(storage) {
62
+ const existing = stores.get(storage);
63
+ if (existing) return existing;
64
+ let state = {
65
+ token: storage.getCustomerToken(),
66
+ refreshToken: null,
67
+ saasToken: null
68
+ };
69
+ const listeners = /* @__PURE__ */ new Set();
70
+ const store = {
71
+ getSnapshot: () => state,
72
+ setState: (next) => {
73
+ const resolved = typeof next === "function" ? next(state) : next;
74
+ if (resolved === state) return;
75
+ state = resolved;
76
+ for (const listener of listeners) listener();
77
+ },
78
+ subscribe: (listener) => {
79
+ listeners.add(listener);
80
+ return () => {
81
+ listeners.delete(listener);
82
+ };
83
+ }
84
+ };
85
+ stores.set(storage, store);
86
+ return store;
87
+ }
88
+
59
89
  // src/hooks/use-customer-session.ts
60
90
  var EMPTY_SESSION = {
61
91
  token: null,
@@ -66,14 +96,12 @@ function useCustomerSession() {
66
96
  const { client, storage } = useEmporix();
67
97
  const qc = reactQuery.useQueryClient();
68
98
  const siteCtx = react.useContext(EmporixSiteContext);
69
- const [session, setSession] = react.useState(() => ({
70
- token: storage.getCustomerToken(),
71
- refreshToken: null,
72
- saasToken: null
73
- }));
99
+ const store = react.useMemo(() => getCustomerSessionStore(storage), [storage]);
100
+ const session = react.useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
101
+ const setSession = store.setState;
74
102
  react.useEffect(() => {
75
103
  return storage.subscribe?.((t) => setSession((s) => ({ ...s, token: t })));
76
- }, [storage]);
104
+ }, [storage, setSession]);
77
105
  const meQuery = reactQuery.useQuery({
78
106
  queryKey: ["emporix", "customer", "me", { tenant: client.tenant, hasToken: session.token !== null }],
79
107
  enabled: session.token !== null,
@@ -107,7 +135,7 @@ function useCustomerSession() {
107
135
  await qc.invalidateQueries({ queryKey: ["emporix", "customer"], refetchType: "none" });
108
136
  await qc.invalidateQueries({ queryKey: ["emporix", "cart"], refetchType: "none" });
109
137
  },
110
- [client, storage, qc, siteCtx]
138
+ [client, storage, qc, siteCtx, setSession]
111
139
  );
112
140
  const signup = react.useCallback(
113
141
  async (input) => {
@@ -139,7 +167,7 @@ function useCustomerSession() {
139
167
  await qc.invalidateQueries({ queryKey: ["emporix", "customer"], refetchType: "none" });
140
168
  await qc.invalidateQueries({ queryKey: ["emporix", "cart"], refetchType: "none" });
141
169
  },
142
- [client, storage, qc, siteCtx]
170
+ [client, storage, qc, siteCtx, setSession]
143
171
  );
144
172
  const socialLogin = react.useCallback(
145
173
  async (input) => {
@@ -163,10 +191,11 @@ function useCustomerSession() {
163
191
  storage.setCustomerToken(null);
164
192
  storage.setRefreshToken(null);
165
193
  storage.setActiveLegalEntityId(null);
194
+ storage.setCartId(null);
166
195
  setSession(EMPTY_SESSION);
167
196
  qc.removeQueries({ queryKey: ["emporix", "customer"] });
168
197
  qc.removeQueries({ queryKey: ["emporix", "cart"] });
169
- }, [client, session.token, storage, qc]);
198
+ }, [client, session.token, storage, qc, setSession]);
170
199
  const refresh = react.useCallback(async () => {
171
200
  await meQuery.refetch();
172
201
  }, [meQuery]);
@@ -185,10 +214,11 @@ function useCustomerSession() {
185
214
  }));
186
215
  await qc.invalidateQueries({ queryKey: ["emporix", "customer"] });
187
216
  await qc.invalidateQueries({ queryKey: ["emporix", "cart"] });
188
- }, [client, storage, qc, session.refreshToken, session.saasToken]);
217
+ }, [client, storage, qc, session.refreshToken, session.saasToken, setSession]);
189
218
  return {
190
219
  customerToken: session.token,
191
220
  refreshToken: session.refreshToken,
221
+ saasToken: session.saasToken,
192
222
  customer: meQuery.data ?? null,
193
223
  isAuthenticated: session.token !== null,
194
224
  isLoading: meQuery.isLoading && session.token !== null,
@@ -573,7 +603,12 @@ function useCartMutations(cartId) {
573
603
  if (c) qc.setQueryData(c.key, c.previous);
574
604
  },
575
605
  onSuccess: (cart, _v, c) => {
576
- if (c) qc.setQueryData(c.key, cart);
606
+ if (!c) return;
607
+ if (cart && Array.isArray(cart.items)) {
608
+ qc.setQueryData(c.key, cart);
609
+ } else {
610
+ void qc.invalidateQueries({ queryKey: c.key });
611
+ }
577
612
  }
578
613
  });
579
614
  }
@@ -592,7 +627,9 @@ function useCartMutations(cartId) {
592
627
  ]
593
628
  } : prev
594
629
  ),
595
- updateItem: make((id, v) => client.carts.updateItem(id, v.itemId, v.patch, ctx)),
630
+ updateItem: make(
631
+ (id, v) => client.carts.updateItem(id, v.itemId, v.patch, ctx, v.partial ? { partial: true } : {})
632
+ ),
596
633
  removeItem: make(
597
634
  (id, v) => client.carts.removeItem(id, v.itemId, ctx),
598
635
  (prev, v) => prev ? { ...prev, items: (prev.items ?? []).filter((i) => i.id !== v.itemId) } : prev
@@ -627,6 +664,14 @@ function useActiveCart(opts) {
627
664
  const { activeCompany } = useActiveCompany();
628
665
  const [cartId, setCartId] = react.useState(() => storage.getCartId());
629
666
  const effectiveLegalEntityId = opts?.legalEntityId ?? activeCompany?.id;
667
+ react.useEffect(() => {
668
+ if (!storage.subscribeAll) return;
669
+ return storage.subscribeAll((key) => {
670
+ if (key !== "cartId") return;
671
+ const next = storage.getCartId();
672
+ setCartId((prev) => prev === next ? prev : next);
673
+ });
674
+ }, [storage]);
630
675
  react.useEffect(() => {
631
676
  if (cartId !== null) return;
632
677
  if (!opts?.create) return;