@ozura/elements 1.0.2-next.16 → 1.0.2-next.18

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.
@@ -879,7 +879,7 @@ class OzVault {
879
879
  * @internal
880
880
  */
881
881
  constructor(options, waxKey, tokenizationSessionId) {
882
- var _a, _b, _c;
882
+ var _a, _b, _c, _d;
883
883
  this.elements = new Map();
884
884
  this.elementsByType = new Map();
885
885
  this.bankElementsByType = new Map();
@@ -892,6 +892,9 @@ class OzVault {
892
892
  this.tokenizerReady = false;
893
893
  this._tokenizing = null;
894
894
  this._destroyed = false;
895
+ // Incremented every time reset() cancels an active tokenization so that
896
+ // any in-flight wax-key refresh retry can detect it was superseded.
897
+ this._resetCount = 0;
895
898
  // Tracks successful tokenizations against the per-key call budget so the SDK
896
899
  // can proactively refresh the wax key after it has been consumed rather than
897
900
  // waiting for the next createToken() call to fail.
@@ -911,13 +914,14 @@ class OzVault {
911
914
  this.resolvedAppearance = resolveAppearance(options.appearance);
912
915
  this.vaultId = `vault-${uuid()}`;
913
916
  this._maxTokenizeCalls = (_b = options.maxTokenizeCalls) !== null && _b !== void 0 ? _b : 3;
917
+ this._debug = (_c = options.debug) !== null && _c !== void 0 ? _c : false;
914
918
  this.boundHandleMessage = this.handleMessage.bind(this);
915
919
  window.addEventListener('message', this.boundHandleMessage);
916
920
  this.boundHandleVisibility = this.handleVisibilityChange.bind(this);
917
921
  document.addEventListener('visibilitychange', this.boundHandleVisibility);
918
922
  this.mountTokenizerFrame();
919
923
  if (options.onLoadError) {
920
- const timeout = (_c = options.loadTimeoutMs) !== null && _c !== void 0 ? _c : 10000;
924
+ const timeout = (_d = options.loadTimeoutMs) !== null && _d !== void 0 ? _d : 10000;
921
925
  this.loadErrorTimeoutId = setTimeout(() => {
922
926
  this.loadErrorTimeoutId = null;
923
927
  if (!this._destroyed && !this.tokenizerReady) {
@@ -927,6 +931,7 @@ class OzVault {
927
931
  }
928
932
  this._onWaxRefresh = options.onWaxRefresh;
929
933
  this._onReady = options.onReady;
934
+ this.log('vault created', { vaultId: this.vaultId, frameBaseUrl: this.frameBaseUrl, maxTokenizeCalls: this._maxTokenizeCalls });
930
935
  }
931
936
  /**
932
937
  * Creates and returns a ready `OzVault` instance.
@@ -996,6 +1001,7 @@ class OzVault {
996
1001
  if (vault.tokenizerReady) {
997
1002
  vault.sendToTokenizer({ type: 'OZ_INIT', frameId: '__tokenizer__', waxKey });
998
1003
  }
1004
+ vault.log('wax key received — vault ready');
999
1005
  return vault;
1000
1006
  }
1001
1007
  /**
@@ -1137,8 +1143,13 @@ class OzVault {
1137
1143
  const readyBankElements = [accountEl, routingEl];
1138
1144
  this._tokenizing = 'bank';
1139
1145
  const requestId = `req-${uuid()}`;
1146
+ this.log('createBankToken() called');
1140
1147
  return new Promise((resolve, reject) => {
1141
- const cleanup = () => { this._tokenizing = null; };
1148
+ const resetCountAtStart = this._resetCount;
1149
+ const cleanup = () => {
1150
+ if (this._resetCount === resetCountAtStart)
1151
+ this._tokenizing = null;
1152
+ };
1142
1153
  this.bankTokenizeResolvers.set(requestId, {
1143
1154
  resolve: (v) => { cleanup(); resolve(v); },
1144
1155
  reject: (e) => { cleanup(); reject(e); },
@@ -1149,6 +1160,7 @@ class OzVault {
1149
1160
  });
1150
1161
  try {
1151
1162
  const bankChannels = readyBankElements.map(() => new MessageChannel());
1163
+ const bankTokenizeStartMs = Date.now();
1152
1164
  this.sendToTokenizer({
1153
1165
  type: 'OZ_BANK_TOKENIZE',
1154
1166
  requestId,
@@ -1159,6 +1171,7 @@ class OzVault {
1159
1171
  lastName: options.lastName.trim(),
1160
1172
  fieldCount: readyBankElements.length,
1161
1173
  }, bankChannels.map(ch => ch.port1));
1174
+ this.log('OZ_BANK_TOKENIZE sent', { requestIdPrefix: `${requestId.slice(0, 12)}...`, fieldCount: readyBankElements.length });
1162
1175
  readyBankElements.forEach((el, i) => el.beginCollect(requestId, bankChannels[i].port2));
1163
1176
  const bankTimeoutId = setTimeout(() => {
1164
1177
  if (this.bankTokenizeResolvers.has(requestId)) {
@@ -1169,8 +1182,10 @@ class OzVault {
1169
1182
  }
1170
1183
  }, 30000);
1171
1184
  const bankPendingEntry = this.bankTokenizeResolvers.get(requestId);
1172
- if (bankPendingEntry)
1185
+ if (bankPendingEntry) {
1173
1186
  bankPendingEntry.timeoutId = bankTimeoutId;
1187
+ bankPendingEntry.tokenizeStartMs = bankTokenizeStartMs;
1188
+ }
1174
1189
  }
1175
1190
  catch (err) {
1176
1191
  this.bankTokenizeResolvers.delete(requestId);
@@ -1241,8 +1256,15 @@ class OzVault {
1241
1256
  }
1242
1257
  this._tokenizing = 'card';
1243
1258
  const requestId = `req-${uuid()}`;
1259
+ this.log('createToken() called');
1244
1260
  return new Promise((resolve, reject) => {
1245
- const cleanup = () => { this._tokenizing = null; };
1261
+ // Capture the reset generation so cleanup() only zeros _tokenizing when it
1262
+ // still belongs to this invocation — not a newer one that started after a reset.
1263
+ const resetCountAtStart = this._resetCount;
1264
+ const cleanup = () => {
1265
+ if (this._resetCount === resetCountAtStart)
1266
+ this._tokenizing = null;
1267
+ };
1246
1268
  this.tokenizeResolvers.set(requestId, {
1247
1269
  resolve: (v) => { cleanup(); resolve(v); },
1248
1270
  reject: (e) => { cleanup(); reject(e); },
@@ -1255,6 +1277,7 @@ class OzVault {
1255
1277
  try {
1256
1278
  // Tell tokenizer frame to expect N field values, then tokenize
1257
1279
  const cardChannels = readyElements.map(() => new MessageChannel());
1280
+ const tokenizeStartMs = Date.now();
1258
1281
  this.sendToTokenizer({
1259
1282
  type: 'OZ_TOKENIZE',
1260
1283
  requestId,
@@ -1265,6 +1288,11 @@ class OzVault {
1265
1288
  lastName,
1266
1289
  fieldCount: readyElements.length,
1267
1290
  }, cardChannels.map(ch => ch.port1));
1291
+ this.log('OZ_TOKENIZE sent', { requestIdPrefix: `${requestId.slice(0, 12)}...`, fieldCount: readyElements.length });
1292
+ // Store start time for elapsed-ms logging on result
1293
+ const cardEntry = this.tokenizeResolvers.get(requestId);
1294
+ if (cardEntry)
1295
+ cardEntry.tokenizeStartMs = tokenizeStartMs;
1268
1296
  // Tell each ready element frame to send its raw value to the tokenizer
1269
1297
  readyElements.forEach((el, i) => el.beginCollect(requestId, cardChannels[i].port2));
1270
1298
  const cardTimeoutId = setTimeout(() => {
@@ -1311,8 +1339,11 @@ class OzVault {
1311
1339
  reset() {
1312
1340
  if (this._destroyed)
1313
1341
  return;
1342
+ const cancelling = Boolean(this._tokenizing);
1343
+ this.log('reset() called', { tokenizing: this._tokenizing, cancelling });
1314
1344
  if (this._tokenizing) {
1315
1345
  this._tokenizing = null;
1346
+ this._resetCount++;
1316
1347
  this.tokenizeResolvers.forEach(({ reject, timeoutId }, requestId) => {
1317
1348
  if (timeoutId != null)
1318
1349
  clearTimeout(timeoutId);
@@ -1350,6 +1381,7 @@ class OzVault {
1350
1381
  if (this._destroyed)
1351
1382
  return;
1352
1383
  this._destroyed = true;
1384
+ this.log('destroy() called');
1353
1385
  window.removeEventListener('message', this.boundHandleMessage);
1354
1386
  document.removeEventListener('visibilitychange', this.boundHandleVisibility);
1355
1387
  if (this._pendingMount) {
@@ -1404,13 +1436,17 @@ class OzVault {
1404
1436
  const REFRESH_THRESHOLD_MS = 20 * 60 * 1000; // 20 minutes
1405
1437
  if (document.hidden) {
1406
1438
  this._hiddenAt = Date.now();
1439
+ this.log('tab hidden');
1407
1440
  }
1408
1441
  else {
1409
- if (this._hiddenAt !== null &&
1410
- Date.now() - this._hiddenAt >= REFRESH_THRESHOLD_MS &&
1411
- this._storedFetchWaxKey &&
1442
+ const hiddenMs = this._hiddenAt !== null ? Date.now() - this._hiddenAt : 0;
1443
+ const willRefresh = (this._hiddenAt !== null &&
1444
+ hiddenMs >= REFRESH_THRESHOLD_MS &&
1445
+ Boolean(this._storedFetchWaxKey) &&
1412
1446
  !this._tokenizing &&
1413
- !this._waxRefreshing) {
1447
+ !this._waxRefreshing);
1448
+ this.log('tab visible', { hiddenMs, willRefresh });
1449
+ if (willRefresh) {
1414
1450
  this.refreshWaxKey().catch((err) => {
1415
1451
  // Proactive refresh failure is non-fatal — the reactive path on the
1416
1452
  // next createToken() call will handle it, including the auth retry.
@@ -1420,6 +1456,56 @@ class OzVault {
1420
1456
  this._hiddenAt = null;
1421
1457
  }
1422
1458
  }
1459
+ // ─── Debug ───────────────────────────────────────────────────────────────
1460
+ /**
1461
+ * Emits a `[OzVault]`-prefixed entry to `console.log`. No-op when `debug` is
1462
+ * not set. Never called with sensitive values — callers use presence flags only.
1463
+ */
1464
+ log(message, data) {
1465
+ if (!this._debug)
1466
+ return;
1467
+ if (data !== undefined) {
1468
+ console.log(`[OzVault] ${message}`, data);
1469
+ }
1470
+ else {
1471
+ console.log(`[OzVault] ${message}`);
1472
+ }
1473
+ }
1474
+ /**
1475
+ * Returns a plain-object snapshot of the vault's current internal state.
1476
+ * Safe to attach to bug reports — no wax keys, tokens, or billing data included.
1477
+ *
1478
+ * Available on all vault instances regardless of whether `debug` was enabled.
1479
+ *
1480
+ * @example
1481
+ * console.log(vault.debugState());
1482
+ * // {
1483
+ * // vaultId: 'vault-abc123',
1484
+ * // isReady: true,
1485
+ * // tokenizing: null,
1486
+ * // destroyed: false,
1487
+ * // waxKeyPresent: true,
1488
+ * // elements: ['cardNumber', 'expirationDate', 'cvv'],
1489
+ * // ...
1490
+ * // }
1491
+ */
1492
+ debugState() {
1493
+ return {
1494
+ vaultId: this.vaultId,
1495
+ isReady: this.tokenizerReady,
1496
+ tokenizing: this._tokenizing,
1497
+ destroyed: this._destroyed,
1498
+ waxKeyPresent: Boolean(this.waxKey),
1499
+ tokenizeSuccessCount: this._tokenizeSuccessCount,
1500
+ maxTokenizeCalls: this._maxTokenizeCalls,
1501
+ resetCount: this._resetCount,
1502
+ elements: [...this.elementsByType.keys()],
1503
+ bankElements: [...this.bankElementsByType.keys()],
1504
+ completionState: Object.fromEntries([...this.completionState.entries()].map(([id, v]) => [id.slice(0, 8), v])),
1505
+ pendingTokenizations: this.tokenizeResolvers.size,
1506
+ pendingBankTokenizations: this.bankTokenizeResolvers.size,
1507
+ };
1508
+ }
1423
1509
  mountTokenizerFrame() {
1424
1510
  const mount = () => {
1425
1511
  this._pendingMount = null;
@@ -1431,6 +1517,7 @@ class OzVault {
1431
1517
  iframe.src = `${this.frameBaseUrl}/frame/tokenizer-frame.html#vaultId=${encodeURIComponent(this.vaultId)}${parentOrigin ? `&parentOrigin=${encodeURIComponent(parentOrigin)}` : ''}`;
1432
1518
  document.body.appendChild(iframe);
1433
1519
  this.tokenizerFrame = iframe;
1520
+ this.log('mounting tokenizer iframe');
1434
1521
  };
1435
1522
  if (document.readyState === 'loading') {
1436
1523
  this._pendingMount = mount;
@@ -1471,6 +1558,7 @@ class OzVault {
1471
1558
  `SDK expects v${PROTOCOL_VERSION}, frame reported v${typeof msg.__ozVersion === 'number' ? msg.__ozVersion : '(none)'}. ` +
1472
1559
  'Deploy the matching frame assets to elements.ozura.com and purge the Azure CDN cache.');
1473
1560
  }
1561
+ this.log('element iframe ready', { type: el.type, frameIdPrefix: frameId.slice(0, 8) });
1474
1562
  }
1475
1563
  // Intercept OZ_CHANGE before forwarding — handle auto-advance and CVV sync
1476
1564
  if (msg.type === 'OZ_CHANGE') {
@@ -1494,6 +1582,7 @@ class OzVault {
1494
1582
  // Require valid too — avoids advancing at 13 digits for unknown-brand cards
1495
1583
  // where isComplete() fires before the user has finished typing.
1496
1584
  const justCompleted = complete && valid && !wasComplete;
1585
+ this.log('field changed', { type: el.type, complete, valid, justCompleted });
1497
1586
  // Sync CVV length when card brand changes
1498
1587
  if (el.type === 'cardNumber') {
1499
1588
  const brand = msg.cardBrand;
@@ -1505,15 +1594,17 @@ class OzVault {
1505
1594
  // Auto-advance focus on completion
1506
1595
  if (justCompleted) {
1507
1596
  if (el.type === 'cardNumber') {
1597
+ this.log('auto-advance', { from: 'cardNumber', to: 'expirationDate' });
1508
1598
  (_b = this.elementsByType.get('expirationDate')) === null || _b === void 0 ? void 0 : _b.focus();
1509
1599
  }
1510
1600
  else if (el.type === 'expirationDate') {
1601
+ this.log('auto-advance', { from: 'expirationDate', to: 'cvv' });
1511
1602
  (_c = this.elementsByType.get('cvv')) === null || _c === void 0 ? void 0 : _c.focus();
1512
1603
  }
1513
1604
  }
1514
1605
  }
1515
1606
  handleTokenizerMessage(msg) {
1516
- var _a, _b, _c;
1607
+ var _a, _b, _c, _d;
1517
1608
  switch (msg.type) {
1518
1609
  case 'OZ_FRAME_READY':
1519
1610
  if (msg.__ozVersion !== PROTOCOL_VERSION) {
@@ -1533,6 +1624,7 @@ class OzVault {
1533
1624
  // sent again from create() once the key is available.
1534
1625
  this.sendToTokenizer(Object.assign({ type: 'OZ_INIT', frameId: '__tokenizer__' }, (this.waxKey ? { waxKey: this.waxKey } : {})));
1535
1626
  (_c = this._onReady) === null || _c === void 0 ? void 0 : _c.call(this);
1627
+ this.log('tokenizer iframe ready', { protocolVersion: (_d = msg.__ozVersion) !== null && _d !== void 0 ? _d : null });
1536
1628
  break;
1537
1629
  case 'OZ_TOKEN_RESULT': {
1538
1630
  if (typeof msg.requestId !== 'string' || !msg.requestId) {
@@ -1557,11 +1649,18 @@ class OzVault {
1557
1649
  }
1558
1650
  pending.resolve(Object.assign(Object.assign({ token,
1559
1651
  cvcSession }, (card ? { card } : {})), (pending.billing ? { billing: pending.billing } : {})));
1652
+ this.log('token received', {
1653
+ elapsedMs: pending.tokenizeStartMs != null ? Date.now() - pending.tokenizeStartMs : null,
1654
+ tokenPresent: true,
1655
+ cvcSessionPresent: true,
1656
+ cardMetadataPresent: Boolean(card),
1657
+ });
1560
1658
  // Increment the per-key success counter and proactively refresh once
1561
1659
  // the budget is exhausted so the next createToken() call uses a fresh
1562
1660
  // key without waiting for a vault rejection.
1563
1661
  this._tokenizeSuccessCount++;
1564
1662
  if (this._tokenizeSuccessCount >= this._maxTokenizeCalls) {
1663
+ this.log('proactive wax key refresh triggered', { tokenizeSuccessCount: this._tokenizeSuccessCount, maxTokenizeCalls: this._maxTokenizeCalls });
1565
1664
  this.refreshWaxKey().catch((err) => {
1566
1665
  console.warn('[OzVault] Post-budget wax key refresh failed:', err instanceof Error ? err.message : err);
1567
1666
  });
@@ -1581,14 +1680,25 @@ class OzVault {
1581
1680
  this.tokenizeResolvers.delete(msg.requestId);
1582
1681
  if (pending.timeoutId != null)
1583
1682
  clearTimeout(pending.timeoutId);
1683
+ const willRefresh = this.isRefreshableAuthError(errorCode, raw) && !pending.retried && Boolean(this._storedFetchWaxKey);
1684
+ this.log('token error', { errorCode, willRefresh });
1584
1685
  // Auto-refresh: if the wax key expired or was consumed and we haven't
1585
1686
  // already retried for this request, transparently re-mint and retry.
1586
- if (this.isRefreshableAuthError(errorCode, raw) && !pending.retried && this._storedFetchWaxKey) {
1687
+ if (willRefresh) {
1688
+ const resetCountAtRetry = this._resetCount;
1587
1689
  this.refreshWaxKey().then(() => {
1588
1690
  if (this._destroyed) {
1589
1691
  pending.reject(new OzError('Vault destroyed during wax key refresh.'));
1590
1692
  return;
1591
1693
  }
1694
+ if (this._resetCount !== resetCountAtRetry) {
1695
+ // reset() was called while the wax key was refreshing — the fields
1696
+ // have been cleared and _tokenizing was zeroed. Reject the original
1697
+ // promise so it doesn't stay pending, and bail out without starting
1698
+ // a new retry (which would tokenize against empty fields).
1699
+ pending.reject(new OzError('Vault was reset while tokenization was in progress.'));
1700
+ return;
1701
+ }
1592
1702
  const newRequestId = `req-${uuid()}`;
1593
1703
  // _tokenizing is still 'card' (cleanup() hasn't been called yet)
1594
1704
  this.tokenizeResolvers.set(newRequestId, Object.assign(Object.assign({}, pending), { retried: true }));
@@ -1635,11 +1745,16 @@ class OzVault {
1635
1745
  if (bankPending.timeoutId != null)
1636
1746
  clearTimeout(bankPending.timeoutId);
1637
1747
  if (this.isRefreshableAuthError(errorCode, raw) && !bankPending.retried && this._storedFetchWaxKey) {
1748
+ const resetCountAtRetry = this._resetCount;
1638
1749
  this.refreshWaxKey().then(() => {
1639
1750
  if (this._destroyed) {
1640
1751
  bankPending.reject(new OzError('Vault destroyed during wax key refresh.'));
1641
1752
  return;
1642
1753
  }
1754
+ if (this._resetCount !== resetCountAtRetry) {
1755
+ bankPending.reject(new OzError('Vault was reset while tokenization was in progress.'));
1756
+ return;
1757
+ }
1643
1758
  const newRequestId = `req-${uuid()}`;
1644
1759
  this.bankTokenizeResolvers.set(newRequestId, Object.assign(Object.assign({}, bankPending), { retried: true }));
1645
1760
  try {
@@ -1697,9 +1812,15 @@ class OzVault {
1697
1812
  }
1698
1813
  const bank = isBankAccountMetadata(msg.bank) ? msg.bank : undefined;
1699
1814
  pending.resolve(Object.assign({ token }, (bank ? { bank } : {})));
1815
+ this.log('bank token received', {
1816
+ elapsedMs: pending.tokenizeStartMs != null ? Date.now() - pending.tokenizeStartMs : null,
1817
+ tokenPresent: true,
1818
+ bankMetadataPresent: Boolean(bank),
1819
+ });
1700
1820
  // Same proactive refresh logic as card tokenization.
1701
1821
  this._tokenizeSuccessCount++;
1702
1822
  if (this._tokenizeSuccessCount >= this._maxTokenizeCalls) {
1823
+ this.log('proactive wax key refresh triggered', { tokenizeSuccessCount: this._tokenizeSuccessCount, maxTokenizeCalls: this._maxTokenizeCalls });
1703
1824
  this.refreshWaxKey().catch((err) => {
1704
1825
  console.warn('[OzVault] Post-budget wax key refresh failed:', err instanceof Error ? err.message : err);
1705
1826
  });
@@ -1755,6 +1876,7 @@ class OzVault {
1755
1876
  }
1756
1877
  const newSessionId = uuid();
1757
1878
  (_a = this._onWaxRefresh) === null || _a === void 0 ? void 0 : _a.call(this);
1879
+ this.log('wax key refresh started');
1758
1880
  this._waxRefreshing = this._storedFetchWaxKey(newSessionId)
1759
1881
  .then(newWaxKey => {
1760
1882
  if (typeof newWaxKey !== 'string' || !newWaxKey.trim()) {
@@ -1768,6 +1890,11 @@ class OzVault {
1768
1890
  if (!this._destroyed && this.tokenizerReady) {
1769
1891
  this.sendToTokenizer({ type: 'OZ_INIT', frameId: '__tokenizer__', waxKey: newWaxKey });
1770
1892
  }
1893
+ this.log('wax key refresh succeeded');
1894
+ })
1895
+ .catch((err) => {
1896
+ this.log('wax key refresh failed', { error: err instanceof Error ? err.message : String(err) });
1897
+ throw err;
1771
1898
  })
1772
1899
  .finally(() => {
1773
1900
  this._waxRefreshing = null;
@@ -1875,7 +2002,7 @@ const OzContext = react.createContext({
1875
2002
  * All `<OzCardNumber />`, `<OzExpiry />`, and `<OzCvv />` children must be
1876
2003
  * rendered inside this provider.
1877
2004
  */
1878
- function OzElements({ fetchWaxKey, pubKey, frameBaseUrl, fonts, onLoadError, loadTimeoutMs, onWaxRefresh, onReady, appearance, maxTokenizeCalls, children }) {
2005
+ function OzElements({ fetchWaxKey, pubKey, frameBaseUrl, fonts, onLoadError, loadTimeoutMs, onWaxRefresh, onReady, appearance, maxTokenizeCalls, debug, children }) {
1879
2006
  const [vault, setVault] = react.useState(null);
1880
2007
  const [initError, setInitError] = react.useState(null);
1881
2008
  const [mountedCount, setMountedCount] = react.useState(0);
@@ -1916,7 +2043,7 @@ function OzElements({ fetchWaxKey, pubKey, frameBaseUrl, fonts, onLoadError, loa
1916
2043
  // synchronously rather than waiting for the promise to settle. Without this,
1917
2044
  // two hidden iframes and two window listeners briefly coexist.
1918
2045
  const abortController = new AbortController();
1919
- OzVault.create(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ pubKey, fetchWaxKey: (sessionId) => fetchWaxKeyRef.current(sessionId) }, (frameBaseUrl ? { frameBaseUrl } : {})), (parsedFonts ? { fonts: parsedFonts } : {})), (parsedAppearance ? { appearance: parsedAppearance } : {})), (onLoadErrorRef.current ? { onLoadError: fireLoadError, loadTimeoutMs } : {})), {
2046
+ OzVault.create(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ pubKey, fetchWaxKey: (sessionId) => fetchWaxKeyRef.current(sessionId) }, (frameBaseUrl ? { frameBaseUrl } : {})), (parsedFonts ? { fonts: parsedFonts } : {})), (parsedAppearance ? { appearance: parsedAppearance } : {})), (onLoadErrorRef.current ? { onLoadError: fireLoadError, loadTimeoutMs } : {})), {
1920
2047
  // Always install onWaxRefresh internally so we can reset tokenizeCount
1921
2048
  // when any wax key refresh occurs (reactive TTL expiry, post-budget
1922
2049
  // proactive, or visibility-change proactive). Without this the React
@@ -1942,7 +2069,7 @@ function OzElements({ fetchWaxKey, pubKey, frameBaseUrl, fonts, onLoadError, loa
1942
2069
  var _a;
1943
2070
  Promise.resolve().then(() => setTokenizeCount(0));
1944
2071
  (_a = onWaxRefreshRef.current) === null || _a === void 0 ? void 0 : _a.call(onWaxRefreshRef);
1945
- }, onReady: () => { var _a; return (_a = onReadyRef.current) === null || _a === void 0 ? void 0 : _a.call(onReadyRef); } }), (maxTokenizeCalls !== undefined ? { maxTokenizeCalls } : {})), abortController.signal).then(v => {
2072
+ }, onReady: () => { var _a; return (_a = onReadyRef.current) === null || _a === void 0 ? void 0 : _a.call(onReadyRef); } }), (maxTokenizeCalls !== undefined ? { maxTokenizeCalls } : {})), (debug ? { debug: true } : {})), abortController.signal).then(v => {
1946
2073
  if (cancelled) {
1947
2074
  v.destroy();
1948
2075
  return;