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