@aranova/tracking-react 0.22.3 → 0.22.4

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/index.mjs CHANGED
@@ -1043,6 +1043,9 @@ function formatMoney(cents, currency, locale) {
1043
1043
  // ../tracking-core/src/resources/tracking-config-runtime.ts
1044
1044
  var CACHE_PREFIX2 = "_aranova_cfg_runtime_";
1045
1045
  var AUTHORITY_TTL_MS = 6e4;
1046
+ var MAX_QUEUE_LENGTH = 50;
1047
+ var RETRY_BASE_MS = 5e3;
1048
+ var RETRY_MAX_MS = 5 * 6e4;
1046
1049
  var runtimes = /* @__PURE__ */ new Map();
1047
1050
  var configuredIds = /* @__PURE__ */ new Set();
1048
1051
  var scriptLoad = null;
@@ -1050,6 +1053,10 @@ var jsInitialized = false;
1050
1053
  function cacheKey2(url) {
1051
1054
  return `${CACHE_PREFIX2}${url}`;
1052
1055
  }
1056
+ function pushBounded(queue, item) {
1057
+ queue.push(item);
1058
+ if (queue.length > MAX_QUEUE_LENGTH) queue.splice(0, queue.length - MAX_QUEUE_LENGTH);
1059
+ }
1053
1060
  function readCache2(url) {
1054
1061
  if (typeof window === "undefined") return null;
1055
1062
  try {
@@ -1130,6 +1137,10 @@ var TrackingConfigRuntime = class {
1130
1137
  this.flushRequested = false;
1131
1138
  this.retryTimer = null;
1132
1139
  this.started = false;
1140
+ /** Consecutive failed authority attempts — drives the revalidate backoff. */
1141
+ this.authorityFailures = 0;
1142
+ /** Epoch ms before which `ensureAuthority` must not issue another request. */
1143
+ this.nextAuthorityAttemptAt = 0;
1133
1144
  this.conversionQueue = [];
1134
1145
  this.automaticQueue = [];
1135
1146
  this.pageQueue = [];
@@ -1168,6 +1179,15 @@ var TrackingConfigRuntime = class {
1168
1179
  }
1169
1180
  __unsafeExpireAuthorityForTests() {
1170
1181
  this.confirmedAt = Number.NEGATIVE_INFINITY;
1182
+ this.nextAuthorityAttemptAt = 0;
1183
+ }
1184
+ /** Queue depths — asserted by tests to pin the bound. */
1185
+ __queueDepthsForTests() {
1186
+ return {
1187
+ conversions: this.conversionQueue.length,
1188
+ automatic: this.automaticQueue.length,
1189
+ pages: this.pageQueue.length
1190
+ };
1171
1191
  }
1172
1192
  subscribe(listener) {
1173
1193
  this.listeners.add(listener);
@@ -1177,10 +1197,12 @@ var TrackingConfigRuntime = class {
1177
1197
  if (this.stateValue !== "unconfirmed" && Date.now() - this.confirmedAt < AUTHORITY_TTL_MS) {
1178
1198
  return true;
1179
1199
  }
1200
+ if (Date.now() < this.nextAuthorityAttemptAt) return false;
1180
1201
  await this.revalidateAuthority();
1181
1202
  return this.stateValue !== "unconfirmed" && Date.now() - this.confirmedAt < AUTHORITY_TTL_MS;
1182
1203
  }
1183
1204
  async revalidate() {
1205
+ this.nextAuthorityAttemptAt = 0;
1184
1206
  await this.revalidateAuthority();
1185
1207
  await this.flush();
1186
1208
  }
@@ -1194,15 +1216,20 @@ var TrackingConfigRuntime = class {
1194
1216
  }
1195
1217
  queuePageView(snapshot = pageViewSnapshot()) {
1196
1218
  if (!snapshot) return;
1197
- this.pageQueue.push(snapshot);
1219
+ pushBounded(this.pageQueue, snapshot);
1198
1220
  void this.flush();
1199
1221
  }
1200
1222
  fireConversion(key, options) {
1201
- this.conversionQueue.push({ key, ...options });
1223
+ pushBounded(this.conversionQueue, { key, ...options });
1202
1224
  void this.flush();
1203
1225
  }
1204
1226
  queueAutomaticEvent(eventType, metadata, transactionPath, transactionScope) {
1205
- this.automaticQueue.push({ eventType, metadata, transactionPath, transactionScope });
1227
+ pushBounded(this.automaticQueue, {
1228
+ eventType,
1229
+ metadata,
1230
+ transactionPath,
1231
+ transactionScope
1232
+ });
1206
1233
  void this.flush();
1207
1234
  }
1208
1235
  listGoals() {
@@ -1242,12 +1269,17 @@ var TrackingConfigRuntime = class {
1242
1269
  expireAuthority() {
1243
1270
  this.authorityGeneration += 1;
1244
1271
  if (this.stateValue !== "unconfirmed") this.stateValue = "unconfirmed";
1272
+ this.authorityFailures += 1;
1273
+ const delay = Math.min(RETRY_MAX_MS, RETRY_BASE_MS * 2 ** (this.authorityFailures - 1));
1274
+ this.nextAuthorityAttemptAt = Date.now() + delay;
1245
1275
  }
1246
1276
  confirm(config, etag) {
1247
1277
  this.authorityGeneration += 1;
1248
1278
  this.current = config;
1249
1279
  this.etag = etag;
1250
1280
  this.confirmedAt = Date.now();
1281
+ this.authorityFailures = 0;
1282
+ this.nextAuthorityAttemptAt = 0;
1251
1283
  this.stateValue = isTombstone(config) ? "tombstone" : "active";
1252
1284
  writeCache2(this.ref.cdnUrl, { etag, config });
1253
1285
  if (this.stateValue === "tombstone") {
@@ -1328,7 +1360,7 @@ var TrackingConfigRuntime = class {
1328
1360
  for (const goal of config.goals) {
1329
1361
  if (goal.kind !== "event" || !goal.firing) continue;
1330
1362
  if (!automaticThresholdMet(goal, event.eventType, event.metadata)) continue;
1331
- this.conversionQueue.push({
1363
+ pushBounded(this.conversionQueue, {
1332
1364
  key: goal.key,
1333
1365
  transactionId: getAutomaticTransactionId(
1334
1366
  event.transactionScope,
@@ -3701,7 +3733,7 @@ function GoogleAdsTracking(props) {
3701
3733
  import { createContext as createContext2, useContext as useContext2, useEffect as useEffect5, useMemo as useMemo4 } from "react";
3702
3734
 
3703
3735
  // package.json
3704
- var version = "0.22.3";
3736
+ var version = "0.22.4";
3705
3737
 
3706
3738
  // ../tracking-core/src/phone-react.tsx
3707
3739
  import {