@ozura/elements 1.3.0-next.62 → 1.3.0-next.63

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.
@@ -1669,6 +1669,7 @@ class OzVault {
1669
1669
  const hiddenMs = this._hiddenAt !== null ? Date.now() - this._hiddenAt : 0;
1670
1670
  const willRefresh = (this._hiddenAt !== null &&
1671
1671
  hiddenMs >= REFRESH_THRESHOLD_MS &&
1672
+ this.tokenizerReady &&
1672
1673
  Boolean(this._storedFetchWaxKey) &&
1673
1674
  !this._tokenizing &&
1674
1675
  !this._waxRefreshing);
@@ -2161,8 +2162,12 @@ class OzVault {
2161
2162
  // names the wax/tokenization session mechanism. A bare "session" match
2162
2163
  // was too broad — any message mentioning "session" (e.g. a merchant
2163
2164
  // session field error) would trigger a spurious re-mint.
2165
+ // Match wax-key/session expiry messages (e.g. "Token has expired",
2166
+ // "Wax key expired") while explicitly excluding card-level validation
2167
+ // errors (e.g. "Card has expired", "Card expiry date invalid") that share
2168
+ // the 'expired' keyword but should NOT trigger a session refresh.
2164
2169
  return (msg.includes('wax') ||
2165
- msg.includes('expired') ||
2170
+ (msg.includes('expired') && !msg.includes('card')) ||
2166
2171
  msg.includes('consumed') ||
2167
2172
  msg.includes('invalid key') ||
2168
2173
  msg.includes('key not found') ||
@@ -2252,6 +2257,16 @@ function OzElements({ sessionUrl, getSessionKey, fetchWaxKey, pubKey, frameBaseU
2252
2257
  // Priority mirrors OzVault.create(): sessionUrl > getSessionKey > fetchWaxKey.
2253
2258
  const getSessionKeyRef = useRef(getSessionKey !== null && getSessionKey !== void 0 ? getSessionKey : fetchWaxKey);
2254
2259
  getSessionKeyRef.current = getSessionKey !== null && getSessionKey !== void 0 ? getSessionKey : fetchWaxKey;
2260
+ // Capture session-scoped options via refs so that runtime changes (e.g.
2261
+ // toggling debug mode or adjusting session limits) don't destroy and recreate
2262
+ // the vault mid-checkout. These values are only consumed at vault creation time;
2263
+ // the vault ignores updates to them after initialization anyway.
2264
+ const debugRef = useRef(debug);
2265
+ debugRef.current = debug;
2266
+ const sessionLimitRef = useRef(sessionLimit);
2267
+ sessionLimitRef.current = sessionLimit;
2268
+ const maxTokenizeCallsRef = useRef(maxTokenizeCalls);
2269
+ maxTokenizeCallsRef.current = maxTokenizeCalls;
2255
2270
  const appearanceKey = useMemo(() => appearance ? JSON.stringify(appearance) : '', [appearance]);
2256
2271
  const fontsKey = useMemo(() => fonts ? JSON.stringify(fonts) : '', [fonts]);
2257
2272
  useEffect(() => {
@@ -2308,8 +2323,8 @@ function OzElements({ sessionUrl, getSessionKey, fetchWaxKey, pubKey, frameBaseU
2308
2323
  var _a;
2309
2324
  Promise.resolve().then(() => setTokenizeCount(0));
2310
2325
  (_a = onWaxRefreshRef.current) === null || _a === void 0 ? void 0 : _a.call(onWaxRefreshRef);
2311
- }, onReady: () => { var _a; return (_a = onReadyRef.current) === null || _a === void 0 ? void 0 : _a.call(onReadyRef); } }), (sessionLimit !== undefined ? { sessionLimit }
2312
- : maxTokenizeCalls !== undefined ? { maxTokenizeCalls } : {})), (debug ? { debug: true } : {})), abortController.signal).then(v => {
2326
+ }, onReady: () => { var _a; return (_a = onReadyRef.current) === null || _a === void 0 ? void 0 : _a.call(onReadyRef); } }), (sessionLimitRef.current !== undefined ? { sessionLimit: sessionLimitRef.current }
2327
+ : maxTokenizeCallsRef.current !== undefined ? { maxTokenizeCalls: maxTokenizeCallsRef.current } : {})), (debugRef.current ? { debug: true } : {})), abortController.signal).then(v => {
2313
2328
  if (cancelled) {
2314
2329
  v.destroy();
2315
2330
  return;
@@ -2342,7 +2357,11 @@ function OzElements({ sessionUrl, getSessionKey, fetchWaxKey, pubKey, frameBaseU
2342
2357
  setVault(null);
2343
2358
  setInitError(null);
2344
2359
  };
2345
- }, [pubKey, sessionUrl, frameBaseUrl, loadTimeoutMs, appearanceKey, fontsKey, sessionLimit, maxTokenizeCalls, debug]);
2360
+ // debug, sessionLimit, and maxTokenizeCalls are intentionally excluded from
2361
+ // this dep array — they are captured via refs above and do not need to
2362
+ // recreate the vault when changed after mount.
2363
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2364
+ }, [pubKey, sessionUrl, frameBaseUrl, loadTimeoutMs, appearanceKey, fontsKey]);
2346
2365
  const notifyMount = useCallback(() => setMountedCount(n => n + 1), []);
2347
2366
  const notifyReady = useCallback(() => setReadyCount(n => n + 1), []);
2348
2367
  const notifyUnmount = useCallback(() => {