@formo/analytics-react-native 1.0.2 → 1.1.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.
Files changed (77) hide show
  1. package/lib/commonjs/lib/event/EventQueue.js +367 -57
  2. package/lib/commonjs/lib/event/EventQueue.js.map +1 -1
  3. package/lib/commonjs/utils/sanitize.js +260 -0
  4. package/lib/commonjs/utils/sanitize.js.map +1 -0
  5. package/lib/commonjs/utils/trafficSource.js +10 -1
  6. package/lib/commonjs/utils/trafficSource.js.map +1 -1
  7. package/lib/commonjs/version.js +1 -1
  8. package/lib/module/lib/event/EventQueue.js +368 -57
  9. package/lib/module/lib/event/EventQueue.js.map +1 -1
  10. package/lib/module/utils/sanitize.js +253 -0
  11. package/lib/module/utils/sanitize.js.map +1 -0
  12. package/lib/module/utils/trafficSource.js +10 -1
  13. package/lib/module/utils/trafficSource.js.map +1 -1
  14. package/lib/module/version.js +1 -1
  15. package/lib/typescript/commonjs/lib/event/EventQueue.d.ts +55 -0
  16. package/lib/typescript/commonjs/lib/event/EventQueue.d.ts.map +1 -1
  17. package/lib/typescript/commonjs/utils/sanitize.d.ts +31 -0
  18. package/lib/typescript/commonjs/utils/sanitize.d.ts.map +1 -0
  19. package/lib/typescript/commonjs/utils/trafficSource.d.ts +3 -0
  20. package/lib/typescript/commonjs/utils/trafficSource.d.ts.map +1 -1
  21. package/lib/typescript/commonjs/version.d.ts +1 -1
  22. package/lib/typescript/module/FormoAnalytics.d.ts +2 -2
  23. package/lib/typescript/module/FormoAnalytics.d.ts.map +1 -1
  24. package/lib/typescript/module/FormoAnalyticsProvider.d.ts +1 -1
  25. package/lib/typescript/module/FormoAnalyticsProvider.d.ts.map +1 -1
  26. package/lib/typescript/module/constants/index.d.ts +3 -3
  27. package/lib/typescript/module/constants/index.d.ts.map +1 -1
  28. package/lib/typescript/module/index.d.ts +5 -5
  29. package/lib/typescript/module/index.d.ts.map +1 -1
  30. package/lib/typescript/module/lib/event/EventFactory.d.ts +2 -2
  31. package/lib/typescript/module/lib/event/EventFactory.d.ts.map +1 -1
  32. package/lib/typescript/module/lib/event/EventManager.d.ts +2 -2
  33. package/lib/typescript/module/lib/event/EventManager.d.ts.map +1 -1
  34. package/lib/typescript/module/lib/event/EventQueue.d.ts +57 -2
  35. package/lib/typescript/module/lib/event/EventQueue.d.ts.map +1 -1
  36. package/lib/typescript/module/lib/event/index.d.ts +4 -4
  37. package/lib/typescript/module/lib/event/index.d.ts.map +1 -1
  38. package/lib/typescript/module/lib/event/types.d.ts +1 -1
  39. package/lib/typescript/module/lib/event/types.d.ts.map +1 -1
  40. package/lib/typescript/module/lib/session/index.d.ts +1 -1
  41. package/lib/typescript/module/lib/session/index.d.ts.map +1 -1
  42. package/lib/typescript/module/lib/storage/AsyncStorageAdapter.d.ts +2 -2
  43. package/lib/typescript/module/lib/storage/AsyncStorageAdapter.d.ts.map +1 -1
  44. package/lib/typescript/module/lib/storage/MemoryStorage.d.ts +1 -1
  45. package/lib/typescript/module/lib/storage/MemoryStorage.d.ts.map +1 -1
  46. package/lib/typescript/module/lib/storage/StorageBlueprint.d.ts +1 -1
  47. package/lib/typescript/module/lib/storage/StorageBlueprint.d.ts.map +1 -1
  48. package/lib/typescript/module/lib/storage/StorageManager.d.ts +1 -1
  49. package/lib/typescript/module/lib/storage/StorageManager.d.ts.map +1 -1
  50. package/lib/typescript/module/lib/storage/index.d.ts +4 -4
  51. package/lib/typescript/module/lib/storage/index.d.ts.map +1 -1
  52. package/lib/typescript/module/lib/wagmi/WagmiEventHandler.d.ts +2 -2
  53. package/lib/typescript/module/lib/wagmi/WagmiEventHandler.d.ts.map +1 -1
  54. package/lib/typescript/module/lib/wagmi/index.d.ts +2 -2
  55. package/lib/typescript/module/lib/wagmi/index.d.ts.map +1 -1
  56. package/lib/typescript/module/solana/address.d.ts +1 -1
  57. package/lib/typescript/module/solana/address.d.ts.map +1 -1
  58. package/lib/typescript/module/solana/index.d.ts +2 -2
  59. package/lib/typescript/module/solana/index.d.ts.map +1 -1
  60. package/lib/typescript/module/types/base.d.ts +3 -3
  61. package/lib/typescript/module/types/base.d.ts.map +1 -1
  62. package/lib/typescript/module/types/events.d.ts +2 -2
  63. package/lib/typescript/module/types/events.d.ts.map +1 -1
  64. package/lib/typescript/module/types/index.d.ts +2 -2
  65. package/lib/typescript/module/types/index.d.ts.map +1 -1
  66. package/lib/typescript/module/utils/index.d.ts +5 -5
  67. package/lib/typescript/module/utils/index.d.ts.map +1 -1
  68. package/lib/typescript/module/utils/sanitize.d.ts +31 -0
  69. package/lib/typescript/module/utils/sanitize.d.ts.map +1 -0
  70. package/lib/typescript/module/utils/trafficSource.d.ts +4 -1
  71. package/lib/typescript/module/utils/trafficSource.d.ts.map +1 -1
  72. package/lib/typescript/module/version.d.ts +1 -1
  73. package/package.json +2 -2
  74. package/src/lib/event/EventQueue.ts +402 -61
  75. package/src/utils/sanitize.ts +274 -0
  76. package/src/utils/trafficSource.ts +19 -1
  77. package/src/version.ts +1 -1
@@ -10,6 +10,14 @@ var _index2 = require("../../utils/index.js");
10
10
  var _hash = require("../../utils/hash.js");
11
11
  var _timestamp = require("../../utils/timestamp.js");
12
12
  var _index3 = require("../logger/index.js");
13
+ /**
14
+ * A send failure tagged with whether another attempt could ever succeed.
15
+ * `retryable: false` means the API rejected the payload itself (4xx other
16
+ * than 429) — re-posting the identical batch will fail identically forever.
17
+ * Left undefined for unexpected errors, which are treated as retryable so an
18
+ * unrecognised fault never silently discards events.
19
+ */
20
+
13
21
  const DEFAULT_RETRY = 3;
14
22
  const MAX_RETRY = 5;
15
23
  const MIN_RETRY = 1;
@@ -20,12 +28,37 @@ const DEFAULT_QUEUE_SIZE = 1_024 * 500; // 500kB
20
28
  const MAX_QUEUE_SIZE = 1_024 * 500; // 500kB
21
29
  const MIN_QUEUE_SIZE = 200; // 200 bytes
22
30
 
31
+ // How long cleanup() waits for an already-in-flight send before abandoning it.
32
+ // Teardown must finish promptly: the provider blocks re-initialization on the
33
+ // pending cleanup, so an unbounded wait would strand the SDK.
34
+ const CLEANUP_FLUSH_WAIT = 1_000 * 5; // 5 seconds
35
+
23
36
  const DEFAULT_FLUSH_INTERVAL = 1_000 * 30; // 30 seconds
24
37
  const MAX_FLUSH_INTERVAL = 1_000 * 300; // 5 minutes
25
38
  const MIN_FLUSH_INTERVAL = 1_000 * 10; // 10 seconds
26
39
 
27
40
  const noop = () => {};
28
41
 
42
+ /**
43
+ * Invoke a consumer-supplied callback without letting it escape the SDK.
44
+ * These callbacks are arbitrary app code; a throw from one must not surface
45
+ * as an unhandled rejection from flush() or abort the remaining callbacks.
46
+ */
47
+ const safeCall = (fn, ...args) => {
48
+ try {
49
+ const result = fn(...args);
50
+ // An `async` callback signals failure by returning a rejected promise
51
+ // rather than throwing, which the catch below would never see.
52
+ if (result && typeof result.then === "function") {
53
+ Promise.resolve(result).catch(error => {
54
+ _index3.logger.error("EventQueue: Async callback rejected, ignoring", error);
55
+ });
56
+ }
57
+ } catch (error) {
58
+ _index3.logger.error("EventQueue: Callback threw, ignoring", error);
59
+ }
60
+ };
61
+
29
62
  /**
30
63
  * Event queue for React Native
31
64
  * Handles batching, flushing, and retries with app lifecycle awareness
@@ -36,6 +69,35 @@ class EventQueue {
36
69
  payloadHashes = new Set();
37
70
  flushMutex = Promise.resolve();
38
71
  appStateSubscription = null;
72
+ /**
73
+ * Whether anything has been flushed yet this app session. Starts false so
74
+ * the first event is sent immediately (see enqueue). A cold start opened
75
+ * from an ad click or deep link produces its attribution events right away,
76
+ * and those are exactly the events lost if the process is killed before the
77
+ * batch timer fires or AppState reports background — a force-quit from the
78
+ * app switcher, an OS memory kill, or a crash never gives us that chance.
79
+ */
80
+ flushed = false;
81
+ /**
82
+ * Set once cleanup starts. A flush already in flight can fail and re-queue
83
+ * its items after teardown has begun; without this it would arm a timer on
84
+ * an instance that is going away, firing network calls post-cleanup.
85
+ */
86
+ closed = false;
87
+ /**
88
+ * Bumped by clear(). flush() splices its batch out of the queue before
89
+ * sending, so a clear() during opt-out cannot see those items; without this
90
+ * a later send failure would unshift them back and they would be delivered
91
+ * after consent was withdrawn.
92
+ */
93
+ generation = 0;
94
+ /**
95
+ * The in-progress teardown, if any. cleanup() is public and the provider can
96
+ * call it more than once; a second run would start its own drain flush that
97
+ * is exempt from the closed check, splice the events the first run had just
98
+ * re-queued, and send them after the first cleanup() had already resolved.
99
+ */
100
+ cleanupPromise = null;
39
101
  constructor(writeKey, options) {
40
102
  this.writeKey = writeKey;
41
103
  this.apiHost = options.apiHost;
@@ -59,6 +121,11 @@ class EventQueue {
59
121
  * Handle app state changes
60
122
  */
61
123
  handleAppStateChange(nextAppState) {
124
+ // Teardown is already draining the queue. A flush queued here would wait
125
+ // on the mutex and could run — and re-queue on failure — after cleanup()
126
+ // has returned, leaving network work with no owner.
127
+ if (this.closed) return;
128
+
62
129
  // Flush when app goes to background or becomes inactive
63
130
  if (nextAppState === "background" || nextAppState === "inactive") {
64
131
  _index3.logger.debug("EventQueue: App going to background, flushing events");
@@ -94,9 +161,31 @@ class EventQueue {
94
161
  * Add event to queue
95
162
  */
96
163
  async enqueue(event, callback) {
164
+ if (this.closed) {
165
+ _index3.logger.debug("EventQueue: Ignoring event enqueued after cleanup");
166
+ return;
167
+ }
97
168
  callback = callback || noop;
169
+ const generation = this.generation;
98
170
  const message_id = await this.generateMessageId(event);
99
171
 
172
+ // Hashing is async, so cleanup() can complete while this call is suspended
173
+ // above. Re-check, or a caller that did not await enqueue() would resume
174
+ // after teardown, push onto a queue nobody will drain, and — if this is the
175
+ // session's first event — fire a network request on a torn-down instance.
176
+ if (this.closed) {
177
+ _index3.logger.debug("EventQueue: Ignoring event enqueued after cleanup");
178
+ return;
179
+ }
180
+
181
+ // Same window, but for opt-out: clear() cannot see an event that has not
182
+ // reached the queue yet, so an enqueue suspended across it would land
183
+ // afterwards and be delivered despite consent having been withdrawn.
184
+ if (this.generation !== generation) {
185
+ _index3.logger.debug("EventQueue: Ignoring event enqueued before opt-out");
186
+ return;
187
+ }
188
+
100
189
  // Check for duplicate
101
190
  if (this.isDuplicate(message_id)) {
102
191
  _index3.logger.warn(`Event already enqueued, try again after ${(0, _index2.millisecondsToSecond)(this.flushIntervalMs)} seconds.`);
@@ -124,21 +213,47 @@ class EventQueue {
124
213
  }));
125
214
  const hasReachedFlushAt = this.queue.length >= this.flushAt;
126
215
  const hasReachedQueueSize = this.queue.reduce((acc, item) => acc + JSON.stringify(item).length, 0) >= this.maxQueueSize;
127
- if (hasReachedFlushAt || hasReachedQueueSize) {
216
+
217
+ // Ship the first event of the app session as a batch of one rather than
218
+ // holding it for flushAt/flushInterval; subsequent events keep batching.
219
+ if (hasReachedFlushAt || hasReachedQueueSize || !this.flushed) {
128
220
  // Clear timer to prevent double flush
129
221
  if (this.timer) {
130
222
  clearTimeout(this.timer);
131
223
  this.timer = null;
132
224
  }
225
+ this.flushed = true;
133
226
  // Flush uses internal mutex to serialize operations
227
+ // A failed flush re-queues its items and re-arms the interval itself, so
228
+ // a cold start whose immediate flush fails — the likeliest case, since
229
+ // the radio may still be waking — still retries the attribution event.
134
230
  this.flush().catch(error => {
135
231
  _index3.logger.error("EventQueue: Failed to flush on threshold", error);
136
232
  });
137
233
  return;
138
234
  }
139
- if (this.flushIntervalMs && !this.timer) {
140
- this.timer = setTimeout(this.flush.bind(this), this.flushIntervalMs);
141
- }
235
+ this.scheduleFlush();
236
+ }
237
+
238
+ /**
239
+ * Arm the batch-interval timer, if there is queued work and nothing is
240
+ * already scheduled. Safe to call repeatedly; it never stacks timers.
241
+ */
242
+ scheduleFlush() {
243
+ if (this.closed) return;
244
+ if (!this.flushIntervalMs || this.timer || !this.queue.length) return;
245
+ this.timer = setTimeout(() => {
246
+ // flush() rethrows once sendWithRetry is exhausted. Passing it to
247
+ // setTimeout bare left that rejection unhandled, surfacing in the host
248
+ // app as an "Uncaught (in promise)" on every failed interval flush —
249
+ // observed against a 4xx from the events API. The threshold and
250
+ // background paths already log and swallow; this one has to as well.
251
+ // flush() re-arms on failure, so a queue that outlives a transient
252
+ // outage keeps retrying and drains once connectivity returns.
253
+ this.flush().catch(error => {
254
+ _index3.logger.error("EventQueue: Failed to flush on interval", error);
255
+ });
256
+ }, this.flushIntervalMs);
142
257
  }
143
258
 
144
259
  /**
@@ -147,6 +262,18 @@ class EventQueue {
147
262
  * preventing race conditions with re-queued items on failure.
148
263
  */
149
264
  async flush(callback) {
265
+ return this.runFlush(callback, false);
266
+ }
267
+
268
+ /**
269
+ * The flush body. `duringCleanup` marks the calls teardown makes itself, so
270
+ * they are exempt from the closed check below — every other flush must be
271
+ * abandoned once teardown has begun. It has to identify the specific call
272
+ * rather than a window of time, because cleanup spends most of its drain
273
+ * loop awaiting one of these, and a concurrent flush arriving then would
274
+ * look internal.
275
+ */
276
+ async runFlush(callback, duringCleanup) {
150
277
  callback = callback || noop;
151
278
  if (this.timer) {
152
279
  clearTimeout(this.timer);
@@ -162,36 +289,90 @@ class EventQueue {
162
289
  try {
163
290
  // Wait for any previous flush to complete
164
291
  await previousMutex;
292
+
293
+ // Teardown began while this flush was waiting its turn. The instant the
294
+ // flush ahead released the mutex it would otherwise splice and send —
295
+ // before cleanup() had even observed that flush finishing — delivering
296
+ // events after teardown resolved.
297
+ if (this.closed && !duringCleanup) {
298
+ // Deliberately no callback: this resumes only once the flush ahead
299
+ // settles, which can be long after cleanup() resolved, and nothing may
300
+ // call back into a torn-down instance. The returned promise still
301
+ // resolves, so an awaiting caller is never left hanging.
302
+ _index3.logger.debug("EventQueue: Abandoning flush that outlived cleanup");
303
+ return;
304
+ }
165
305
  if (!this.queue.length) {
166
- callback();
306
+ safeCall(callback);
167
307
  return;
168
308
  }
169
309
  const items = this.queue.splice(0, this.flushAt);
310
+ // Snapshot after the splice: from here on these items live only in this
311
+ // closure, so a clear() cannot reach them and we have to detect it.
312
+ const generation = this.generation;
170
313
  const sentAt = new Date().toISOString();
171
314
  const data = items.map(item => ({
172
315
  ...item.message,
173
316
  sent_at: sentAt
174
317
  }));
175
318
  const done = err => {
319
+ // A batch cleanup() abandoned must not call back into an app that has
320
+ // already torn the SDK down: its request has no timeout, so it can
321
+ // settle long after cleanup() resolved and the provider moved on to a
322
+ // replacement instance. A plain clear() (opt-out) still notifies, so
323
+ // the consumer does learn those events were dropped.
324
+ if (this.closed && this.generation !== generation) return;
176
325
  items.forEach(({
177
326
  message,
178
327
  callback: itemCallback
179
- }) => itemCallback(err, message, data));
180
- callback(err, data);
328
+ }) => safeCall(itemCallback, err, message, data));
329
+ safeCall(callback, err, data);
181
330
  };
182
331
  try {
183
- await this.sendWithRetry(data);
184
- // Only remove hashes after successful send
185
- items.forEach(item => this.payloadHashes.delete(item.hash));
332
+ await this.sendWithRetry(data, generation);
333
+ // Only remove hashes after successful send, and only if clear() has
334
+ // not run meanwhile: it already emptied the set, so an identical event
335
+ // may have been enqueued since and now owns that hash. Deleting it
336
+ // here would strip the new item's dedup entry and let a duplicate
337
+ // through.
338
+ if (this.generation === generation) {
339
+ items.forEach(item => this.payloadHashes.delete(item.hash));
340
+ }
186
341
  done();
187
342
  _index3.logger.info(`Events sent successfully: ${data.length} events`);
188
343
  } catch (err) {
189
- // Re-add items to the front of the queue for retry on next flush
190
- // Note: We intentionally keep hashes in payloadHashes to prevent duplicate
191
- // events from being enqueued while these items are pending retry.
192
- this.queue.unshift(...items);
193
- done(err);
194
- _index3.logger.error("Error sending events, re-queued for retry:", err);
344
+ if (this.generation !== generation) {
345
+ // clear() ran while this batch was in flight the consumer opted
346
+ // out. Putting these back would deliver events after consent was
347
+ // withdrawn, and clear() already emptied payloadHashes, so a
348
+ // resurrected item would also no longer be deduped.
349
+ done(err);
350
+ _index3.logger.debug(`EventQueue: Discarding ${items.length} in-flight event(s) cleared mid-flush`);
351
+ } else if (err?.retryable === false) {
352
+ // The API rejected this payload itself, so the identical batch can
353
+ // never succeed. Keeping it queued would re-post it every interval
354
+ // forever, re-invoking callbacks and burning the user's battery and
355
+ // data. Drop it, and release the hashes so equivalent events are not
356
+ // blocked from being enqueued again later. The web SDK likewise does
357
+ // not re-queue a failed batch.
358
+ items.forEach(item => this.payloadHashes.delete(item.hash));
359
+ done(err);
360
+ _index3.logger.error(`Dropping ${items.length} event(s), permanently rejected by the API:`, err);
361
+ } else {
362
+ // Re-add items to the front of the queue for retry on next flush
363
+ // Note: We intentionally keep hashes in payloadHashes to prevent duplicate
364
+ // events from being enqueued while these items are pending retry.
365
+ this.queue.unshift(...items);
366
+ done(err);
367
+ _index3.logger.error("Error sending events, re-queued for retry:", err);
368
+ }
369
+
370
+ // Re-arm here rather than in each caller's catch, so EVERY entry point
371
+ // is covered — the background AppState flush and a consumer's manual
372
+ // flush() included. flush() clears the timer on entry, so without this
373
+ // a failed background flush would re-queue its items and leave nothing
374
+ // scheduled to retry them. No-ops when the queue is empty or closed.
375
+ this.scheduleFlush();
195
376
  throw err;
196
377
  }
197
378
  } finally {
@@ -199,10 +380,24 @@ class EventQueue {
199
380
  }
200
381
  }
201
382
 
383
+ /**
384
+ * Abort a batch whose events were cleared while it sat in retry backoff.
385
+ * Retries span seconds, so a consumer can opt out between attempts; posting
386
+ * the next one would deliver events after consent was withdrawn.
387
+ */
388
+ assertNotCleared(generation) {
389
+ if (this.generation !== generation) {
390
+ const error = new Error("EventQueue: batch cleared during retry backoff");
391
+ // Never re-queue: these events were explicitly discarded.
392
+ error.retryable = false;
393
+ throw error;
394
+ }
395
+ }
396
+
202
397
  /**
203
398
  * Send events with retry logic
204
399
  */
205
- async sendWithRetry(data, attempt = 0) {
400
+ async sendWithRetry(data, generation, attempt = 0) {
206
401
  try {
207
402
  const response = await fetch(this.apiHost, {
208
403
  method: "POST",
@@ -214,16 +409,27 @@ class EventQueue {
214
409
  if (shouldRetry && attempt < this.retryCount) {
215
410
  const delay = Math.pow(2, attempt) * 1000;
216
411
  await new Promise(resolve => setTimeout(() => resolve(), delay));
217
- return this.sendWithRetry(data, attempt + 1);
412
+ this.assertNotCleared(generation);
413
+ return this.sendWithRetry(data, generation, attempt + 1);
218
414
  }
219
- throw new Error(`HTTP error! status: ${response.status}`);
415
+ const error = new Error(`HTTP error! status: ${response.status}`);
416
+ // A 4xx that is not 429 rejects this payload permanently — an invalid
417
+ // write key or a malformed batch. Tag it so flush() drops the batch
418
+ // instead of re-posting it on every interval for the process lifetime.
419
+ error.retryable = shouldRetry;
420
+ throw error;
220
421
  }
221
422
  } catch (error) {
222
- if ((0, _index2.isNetworkError)(error) && attempt < this.retryCount) {
223
- const delay = Math.pow(2, attempt) * 1000;
224
- _index3.logger.warn(`Network error, retrying in ${delay}ms...`);
225
- await new Promise(resolve => setTimeout(() => resolve(), delay));
226
- return this.sendWithRetry(data, attempt + 1);
423
+ if ((0, _index2.isNetworkError)(error)) {
424
+ if (attempt < this.retryCount) {
425
+ const delay = Math.pow(2, attempt) * 1000;
426
+ _index3.logger.warn(`Network error, retrying in ${delay}ms...`);
427
+ await new Promise(resolve => setTimeout(() => resolve(), delay));
428
+ this.assertNotCleared(generation);
429
+ return this.sendWithRetry(data, generation, attempt + 1);
430
+ }
431
+ // Connectivity comes back; keep these for a later attempt.
432
+ error.retryable = true;
227
433
  }
228
434
  throw error;
229
435
  }
@@ -233,8 +439,11 @@ class EventQueue {
233
439
  * Check if error should be retried
234
440
  */
235
441
  shouldRetry(status) {
236
- // Retry on server errors (5xx) and rate limiting (429)
237
- return status >= 500 && status <= 599 || status === 429;
442
+ // Retry on server errors (5xx), rate limiting (429) and request timeout
443
+ // (408). 408 matters now that a non-retryable status drops the batch: a
444
+ // proxy or server timing out a request is transient, and treating it as
445
+ // permanent would silently lose those events.
446
+ return status >= 500 && status <= 599 || status === 429 || status === 408;
238
447
  }
239
448
 
240
449
  /**
@@ -243,6 +452,9 @@ class EventQueue {
243
452
  * from being sent after consent is revoked.
244
453
  */
245
454
  clear() {
455
+ // Invalidate any batch already in flight so a later send failure cannot
456
+ // unshift it back onto the queue we are emptying here.
457
+ this.generation++;
246
458
  this.queue = [];
247
459
  this.payloadHashes.clear();
248
460
  if (this.timer) {
@@ -252,49 +464,147 @@ class EventQueue {
252
464
  _index3.logger.debug("EventQueue: Cleared all pending events");
253
465
  }
254
466
 
467
+ /**
468
+ * Give up on the events still queued at teardown, and make sure a send that
469
+ * is still holding a batch cannot put them back.
470
+ */
471
+ abandonQueuedEvents(reason) {
472
+ _index3.logger.warn(`EventQueue: ${reason}, abandoning ${this.queue.length} event(s)`);
473
+ // clear() rather than emptying the queue by hand: it also bumps the
474
+ // generation, which is what actually invalidates a batch a stalled flush
475
+ // is still holding. Without the bump that flush would later fail, unshift
476
+ // its items back onto the queue we just emptied, and a flush chained
477
+ // behind it would send them and invoke their callbacks a second time —
478
+ // after teardown had already returned.
479
+ this.clear();
480
+ }
481
+
255
482
  /**
256
483
  * Clean up resources, flushing any pending events first
257
484
  */
258
485
  async cleanup() {
259
- // Flush all remaining queued events before teardown
260
- // Loop until queue is empty since flush() only sends flushAt events per call
261
- // Safety limit prevents infinite loops if flush silently fails
262
- const maxAttempts = Math.ceil(this.queue.length / this.flushAt) + 3;
263
- let attempts = 0;
264
- const initialQueueLength = this.queue.length;
265
- while (this.queue.length > 0 && attempts < maxAttempts) {
266
- const queueLengthBefore = this.queue.length;
267
- try {
268
- await this.flush();
269
- } catch (error) {
270
- _index3.logger.error("EventQueue: Failed to flush during cleanup", error);
271
- // Break on error to avoid infinite loop if flush keeps failing
272
- break;
273
- }
274
-
275
- // If queue length didn't decrease, flush is silently failing
276
- if (this.queue.length >= queueLengthBefore) {
277
- _index3.logger.warn("EventQueue: Flush did not reduce queue size, aborting cleanup");
278
- break;
279
- }
280
- attempts++;
281
- }
282
- if (attempts >= maxAttempts && this.queue.length > 0) {
283
- _index3.logger.warn(`EventQueue: Cleanup safety limit reached. Discarding ${this.queue.length} events.`);
284
- this.queue = [];
285
- this.payloadHashes.clear();
286
- }
287
- if (initialQueueLength > 0) {
288
- _index3.logger.debug(`EventQueue: Cleanup completed, flushed ${initialQueueLength - this.queue.length} events`);
486
+ // Teardown is idempotent: a caller that asks twice joins the run already
487
+ // under way rather than starting a competing one.
488
+ if (!this.cleanupPromise) {
489
+ // Teardown is best-effort and must always settle: a rejection here would
490
+ // be memoised, so every later cleanup() would return the same rejected
491
+ // promise and never retry — and the provider, which awaits the pending
492
+ // cleanup before building a replacement, would reject with it forever.
493
+ this.cleanupPromise = this.runCleanup().catch(error => {
494
+ _index3.logger.error("EventQueue: Cleanup failed", error);
495
+ // Whatever failed, the instance is going away: make sure nothing is
496
+ // left queued for a straggling flush to pick up.
497
+ this.clear();
498
+ });
289
499
  }
500
+ return this.cleanupPromise;
501
+ }
502
+ async runCleanup() {
503
+ // Stop anything from arming a new timer for the rest of teardown.
504
+ this.closed = true;
290
505
  if (this.timer) {
291
506
  clearTimeout(this.timer);
292
507
  this.timer = null;
293
508
  }
509
+
510
+ // Detach up front rather than at the end: while the drain loop below is
511
+ // awaiting a send, a backgrounding app would otherwise queue a flush that
512
+ // outlives cleanup(). The closed check in the handler covers the same
513
+ // window; removing the listener means the event never reaches it at all.
294
514
  if (this.appStateSubscription) {
295
- this.appStateSubscription.remove();
515
+ try {
516
+ this.appStateSubscription.remove();
517
+ } catch (error) {
518
+ // A native-module failure here must not abort teardown before the
519
+ // queue has been drained or invalidated below.
520
+ _index3.logger.error("EventQueue: Failed to remove AppState listener", error);
521
+ }
296
522
  this.appStateSubscription = null;
297
523
  }
524
+
525
+ // One deadline for the whole of teardown, not per wait.
526
+ //
527
+ // `fetch` here has no request timeout, so any send this method waits on —
528
+ // a flush already in flight, or one the drain loop starts itself — can
529
+ // stall forever. Bounding only the first would leave the ordinary case
530
+ // unbounded: with nothing in flight the first wait returns immediately and
531
+ // the drain loop then opens a fresh request. A single deadline also keeps
532
+ // total teardown bounded rather than 5s per flush attempt.
533
+ //
534
+ // This matters beyond a stuck cleanup(): FormoAnalyticsProvider awaits the
535
+ // pending cleanup before constructing a replacement instance, so a hang
536
+ // here means the SDK can never be reconfigured again.
537
+ let deadlineTimer;
538
+ const deadline = new Promise(resolve => {
539
+ deadlineTimer = setTimeout(() => resolve("timeout"), CLEANUP_FLUSH_WAIT);
540
+ });
541
+ const withinDeadline = work => Promise.race([work, deadline]);
542
+ const timedOut = `Teardown exceeded ${(0, _index2.millisecondsToSecond)(CLEANUP_FLUSH_WAIT)}s`;
543
+ try {
544
+ // A flush may already be in flight with its items spliced out of the
545
+ // queue, which would make the drain loop below see an empty queue and
546
+ // return before delivery finished. Wait for it to settle first — on a
547
+ // transient failure it puts those items back, and the loop then retries
548
+ // them.
549
+ if ((await withinDeadline(this.flushMutex.then(() => "settled"))) === "timeout") {
550
+ this.abandonQueuedEvents(timedOut);
551
+ return;
552
+ }
553
+
554
+ // Flush all remaining queued events before teardown
555
+ // Loop until queue is empty since flush() only sends flushAt events per call
556
+ // Safety limit prevents infinite loops if flush silently fails
557
+ const maxAttempts = Math.ceil(this.queue.length / this.flushAt) + 3;
558
+ let attempts = 0;
559
+ const initialQueueLength = this.queue.length;
560
+ while (this.queue.length > 0 && attempts < maxAttempts) {
561
+ const queueLengthBefore = this.queue.length;
562
+ const outcome = await withinDeadline(
563
+ // Settle rather than reject, so only the deadline can win the race
564
+ // on an error and a rejection cannot escape unhandled.
565
+ this.runFlush(undefined, true).then(() => "flushed", error => {
566
+ _index3.logger.error("EventQueue: Failed to flush during cleanup", error);
567
+ return "failed";
568
+ }));
569
+ if (outcome === "timeout") {
570
+ this.abandonQueuedEvents(timedOut);
571
+ return;
572
+ }
573
+ // Break on error to avoid infinite loop if flush keeps failing
574
+ if (outcome === "failed") break;
575
+
576
+ // If queue length didn't decrease, flush is silently failing
577
+ if (this.queue.length >= queueLengthBefore) {
578
+ _index3.logger.warn("EventQueue: Flush did not reduce queue size, aborting cleanup");
579
+ break;
580
+ }
581
+ attempts++;
582
+ }
583
+ if (initialQueueLength > 0) {
584
+ _index3.logger.debug(`EventQueue: Cleanup completed, flushed ${initialQueueLength - this.queue.length} events`);
585
+ }
586
+
587
+ // Teardown always ends with an empty, invalidated queue — not only when
588
+ // the safety limit is hit. Each `break` above (a failed flush, a flush
589
+ // that did not shrink the queue) otherwise left events behind with the
590
+ // generation unchanged, and a flush queued behind cleanup's own — a
591
+ // concurrent public flush(), or a second cleanup() — would then send
592
+ // them and invoke their callbacks after this call had resolved.
593
+ if (this.queue.length > 0) {
594
+ this.abandonQueuedEvents(attempts >= maxAttempts ? "Cleanup safety limit reached" : "Teardown finished with events still queued");
595
+ }
596
+ } finally {
597
+ if (deadlineTimer) clearTimeout(deadlineTimer);
598
+
599
+ // The AppState listener was already detached at the top of cleanup, and
600
+ // `closed` stops anything arming a timer, so nothing can have been
601
+ // scheduled since. This is the last-resort clear for a timer that a flush
602
+ // in the drain loop above might have left behind.
603
+ if (this.timer) {
604
+ clearTimeout(this.timer);
605
+ this.timer = null;
606
+ }
607
+ }
298
608
  }
299
609
  }
300
610
  exports.EventQueue = EventQueue;
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","_index","_index2","_hash","_timestamp","_index3","DEFAULT_RETRY","MAX_RETRY","MIN_RETRY","DEFAULT_FLUSH_AT","MAX_FLUSH_AT","MIN_FLUSH_AT","DEFAULT_QUEUE_SIZE","MAX_QUEUE_SIZE","MIN_QUEUE_SIZE","DEFAULT_FLUSH_INTERVAL","MAX_FLUSH_INTERVAL","MIN_FLUSH_INTERVAL","noop","EventQueue","queue","timer","payloadHashes","Set","flushMutex","Promise","resolve","appStateSubscription","constructor","writeKey","options","apiHost","retryCount","clampNumber","flushAt","maxQueueSize","flushIntervalMs","flushInterval","setupAppStateListener","AppState","addEventListener","handleAppStateChange","bind","nextAppState","logger","debug","flush","catch","error","generateMessageId","event","formattedTimestamp","toDateHourMinute","Date","original_timestamp","eventForHashing","eventString","JSON","stringify","hash","isDuplicate","eventId","has","add","enqueue","callback","message_id","warn","millisecondsToSecond","push","message","log","getActionDescriptor","type","properties","ctx","context","session_id","anonymous_id","user_agent","page_url","hasReachedFlushAt","length","hasReachedQueueSize","reduce","acc","item","clearTimeout","setTimeout","previousMutex","resolveMutex","items","splice","sentAt","toISOString","data","map","sent_at","done","err","forEach","itemCallback","sendWithRetry","delete","info","unshift","attempt","response","fetch","method","headers","EVENTS_API_REQUEST_HEADER","body","ok","shouldRetry","status","delay","Math","pow","Error","isNetworkError","clear","cleanup","maxAttempts","ceil","attempts","initialQueueLength","queueLengthBefore","remove","exports"],"sourceRoot":"../../../../src","sources":["lib/event/EventQueue.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","_index","_index2","_hash","_timestamp","_index3","DEFAULT_RETRY","MAX_RETRY","MIN_RETRY","DEFAULT_FLUSH_AT","MAX_FLUSH_AT","MIN_FLUSH_AT","DEFAULT_QUEUE_SIZE","MAX_QUEUE_SIZE","MIN_QUEUE_SIZE","CLEANUP_FLUSH_WAIT","DEFAULT_FLUSH_INTERVAL","MAX_FLUSH_INTERVAL","MIN_FLUSH_INTERVAL","noop","safeCall","fn","args","result","then","Promise","resolve","catch","error","logger","EventQueue","queue","timer","payloadHashes","Set","flushMutex","appStateSubscription","flushed","closed","generation","cleanupPromise","constructor","writeKey","options","apiHost","retryCount","clampNumber","flushAt","maxQueueSize","flushIntervalMs","flushInterval","setupAppStateListener","AppState","addEventListener","handleAppStateChange","bind","nextAppState","debug","flush","generateMessageId","event","formattedTimestamp","toDateHourMinute","Date","original_timestamp","eventForHashing","eventString","JSON","stringify","hash","isDuplicate","eventId","has","add","enqueue","callback","message_id","warn","millisecondsToSecond","push","message","log","getActionDescriptor","type","properties","ctx","context","session_id","anonymous_id","user_agent","page_url","hasReachedFlushAt","length","hasReachedQueueSize","reduce","acc","item","clearTimeout","scheduleFlush","setTimeout","runFlush","duringCleanup","previousMutex","resolveMutex","items","splice","sentAt","toISOString","data","map","sent_at","done","err","forEach","itemCallback","sendWithRetry","delete","info","retryable","unshift","assertNotCleared","Error","attempt","response","fetch","method","headers","EVENTS_API_REQUEST_HEADER","body","ok","shouldRetry","status","delay","Math","pow","isNetworkError","clear","abandonQueuedEvents","reason","cleanup","runCleanup","remove","deadlineTimer","deadline","withinDeadline","work","race","timedOut","maxAttempts","ceil","attempts","initialQueueLength","queueLengthBefore","outcome","undefined","exports"],"sourceRoot":"../../../../src","sources":["lib/event/EventQueue.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEA,IAAAC,MAAA,GAAAD,OAAA;AACA,IAAAE,OAAA,GAAAF,OAAA;AAMA,IAAAG,KAAA,GAAAH,OAAA;AACA,IAAAI,UAAA,GAAAJ,OAAA;AACA,IAAAK,OAAA,GAAAL,OAAA;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;;AAWA,MAAMM,aAAa,GAAG,CAAC;AACvB,MAAMC,SAAS,GAAG,CAAC;AACnB,MAAMC,SAAS,GAAG,CAAC;AAEnB,MAAMC,gBAAgB,GAAG,EAAE;AAC3B,MAAMC,YAAY,GAAG,EAAE;AACvB,MAAMC,YAAY,GAAG,CAAC;AAEtB,MAAMC,kBAAkB,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC;AACxC,MAAMC,cAAc,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC;AACpC,MAAMC,cAAc,GAAG,GAAG,CAAC,CAAC;;AAE5B;AACA;AACA;AACA,MAAMC,kBAAkB,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC;;AAEtC,MAAMC,sBAAsB,GAAG,KAAK,GAAG,EAAE,CAAC,CAAC;AAC3C,MAAMC,kBAAkB,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC;AACxC,MAAMC,kBAAkB,GAAG,KAAK,GAAG,EAAE,CAAC,CAAC;;AAEvC,MAAMC,IAAI,GAAGA,CAAA,KAAM,CAAC,CAAC;;AAErB;AACA;AACA;AACA;AACA;AACA,MAAMC,QAAQ,GAAGA,CAACC,EAAmC,EAAE,GAAGC,IAAe,KAAK;EAC5E,IAAI;IACF,MAAMC,MAAM,GAAGF,EAAE,CAAC,GAAGC,IAAI,CAAC;IAC1B;IACA;IACA,IAAIC,MAAM,IAAI,OAAQA,MAAM,CAA0BC,IAAI,KAAK,UAAU,EAAE;MACzEC,OAAO,CAACC,OAAO,CAACH,MAAM,CAAC,CAACI,KAAK,CAAEC,KAAK,IAAK;QACvCC,cAAM,CAACD,KAAK,CAAC,+CAA+C,EAAEA,KAAK,CAAC;MACtE,CAAC,CAAC;IACJ;EACF,CAAC,CAAC,OAAOA,KAAK,EAAE;IACdC,cAAM,CAACD,KAAK,CAAC,sCAAsC,EAAEA,KAAK,CAAC;EAC7D;AACF,CAAC;;AAED;AACA;AACA;AACA;AACO,MAAME,UAAU,CAAwB;EAGrCC,KAAK,GAAgB,EAAE;EACvBC,KAAK,GAAyC,IAAI;EAKlDC,aAAa,GAAgB,IAAIC,GAAG,CAAC,CAAC;EACtCC,UAAU,GAAkBV,OAAO,CAACC,OAAO,CAAC,CAAC;EAC7CU,oBAAoB,GAAkC,IAAI;EAClE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACUC,OAAO,GAAG,KAAK;EACvB;AACF;AACA;AACA;AACA;EACUC,MAAM,GAAG,KAAK;EACtB;AACF;AACA;AACA;AACA;AACA;EACUC,UAAU,GAAG,CAAC;EACtB;AACF;AACA;AACA;AACA;AACA;EACUC,cAAc,GAAyB,IAAI;EAEnDC,WAAWA,CAACC,QAAgB,EAAEC,OAAgB,EAAE;IAC9C,IAAI,CAACD,QAAQ,GAAGA,QAAQ;IACxB,IAAI,CAACE,OAAO,GAAGD,OAAO,CAACC,OAAO;IAC9B,IAAI,CAACC,UAAU,GAAG,IAAAC,mBAAW,EAC3BH,OAAO,CAACE,UAAU,IAAIvC,aAAa,EACnCC,SAAS,EACTC,SACF,CAAC;IACD,IAAI,CAACuC,OAAO,GAAG,IAAAD,mBAAW,EACxBH,OAAO,CAACI,OAAO,IAAItC,gBAAgB,EACnCC,YAAY,EACZC,YACF,CAAC;IACD,IAAI,CAACqC,YAAY,GAAG,IAAAF,mBAAW,EAC7BH,OAAO,CAACK,YAAY,IAAIpC,kBAAkB,EAC1CC,cAAc,EACdC,cACF,CAAC;IACD,IAAI,CAACmC,eAAe,GAAG,IAAAH,mBAAW,EAChCH,OAAO,CAACO,aAAa,IAAIlC,sBAAsB,EAC/CC,kBAAkB,EAClBC,kBACF,CAAC;IACD;IACA,IAAI,CAACiC,qBAAqB,CAAC,CAAC;EAC9B;;EAEA;AACF;AACA;AACA;EACUA,qBAAqBA,CAAA,EAAS;IACpC,IAAI,CAACf,oBAAoB,GAAGgB,qBAAQ,CAACC,gBAAgB,CACnD,QAAQ,EACR,IAAI,CAACC,oBAAoB,CAACC,IAAI,CAAC,IAAI,CACrC,CAAC;EACH;;EAEA;AACF;AACA;EACUD,oBAAoBA,CAACE,YAA4B,EAAQ;IAC/D;IACA;IACA;IACA,IAAI,IAAI,CAAClB,MAAM,EAAE;;IAEjB;IACA,IAAIkB,YAAY,KAAK,YAAY,IAAIA,YAAY,KAAK,UAAU,EAAE;MAChE3B,cAAM,CAAC4B,KAAK,CAAC,sDAAsD,CAAC;MACpE,IAAI,CAACC,KAAK,CAAC,CAAC,CAAC/B,KAAK,CAAEC,KAAK,IAAK;QAC5BC,cAAM,CAACD,KAAK,CAAC,2CAA2C,EAAEA,KAAK,CAAC;MAClE,CAAC,CAAC;IACJ;EACF;;EAEA;AACF;AACA;EACE,MAAc+B,iBAAiBA,CAACC,KAAkB,EAAmB;IACnE,MAAMC,kBAAkB,GAAG,IAAAC,2BAAgB,EACzC,IAAIC,IAAI,CAACH,KAAK,CAACI,kBAAkB,CACnC,CAAC;IACD,MAAMC,eAAe,GAAG;MAAE,GAAGL,KAAK;MAAEI,kBAAkB,EAAEH;IAAmB,CAAC;IAC5E,MAAMK,WAAW,GAAGC,IAAI,CAACC,SAAS,CAACH,eAAe,CAAC;IACnD,OAAO,IAAAI,UAAI,EAACH,WAAW,CAAC;EAC1B;;EAEA;AACF;AACA;EACUI,WAAWA,CAACC,OAAe,EAAW;IAC5C,IAAI,IAAI,CAACtC,aAAa,CAACuC,GAAG,CAACD,OAAO,CAAC,EAAE,OAAO,IAAI;IAChD,IAAI,CAACtC,aAAa,CAACwC,GAAG,CAACF,OAAO,CAAC;IAC/B,OAAO,KAAK;EACd;;EAEA;AACF;AACA;EACE,MAAMG,OAAOA,CACXd,KAAkB,EAClBe,QAAuC,EACxB;IACf,IAAI,IAAI,CAACrC,MAAM,EAAE;MACfT,cAAM,CAAC4B,KAAK,CAAC,mDAAmD,CAAC;MACjE;IACF;IAEAkB,QAAQ,GAAGA,QAAQ,IAAIxD,IAAI;IAE3B,MAAMoB,UAAU,GAAG,IAAI,CAACA,UAAU;IAClC,MAAMqC,UAAU,GAAG,MAAM,IAAI,CAACjB,iBAAiB,CAACC,KAAK,CAAC;;IAEtD;IACA;IACA;IACA;IACA,IAAI,IAAI,CAACtB,MAAM,EAAE;MACfT,cAAM,CAAC4B,KAAK,CAAC,mDAAmD,CAAC;MACjE;IACF;;IAEA;IACA;IACA;IACA,IAAI,IAAI,CAAClB,UAAU,KAAKA,UAAU,EAAE;MAClCV,cAAM,CAAC4B,KAAK,CAAC,oDAAoD,CAAC;MAClE;IACF;;IAEA;IACA,IAAI,IAAI,CAACa,WAAW,CAACM,UAAU,CAAC,EAAE;MAChC/C,cAAM,CAACgD,IAAI,CACT,2CAA2C,IAAAC,4BAAoB,EAC7D,IAAI,CAAC7B,eACP,CAAC,WACH,CAAC;MACD;IACF;IAEA,IAAI,CAAClB,KAAK,CAACgD,IAAI,CAAC;MACdC,OAAO,EAAE;QAAE,GAAGpB,KAAK;QAAEgB;MAAW,CAAC;MACjCD,QAAQ;MACRN,IAAI,EAAEO;IACR,CAAC,CAAC;IAEF/C,cAAM,CAACoD,GAAG,CACR,mBAAmB,IAAAC,2BAAmB,EAACtB,KAAK,CAACuB,IAAI,EAAEvB,KAAK,CAACwB,UAAU,CAAC,EACtE,CAAC;;IAED;IACA,MAAMC,GAAG,GAAIzB,KAAK,CAAC0B,OAAO,IAAI,CAAC,CAA6B;IAC5DzD,cAAM,CAAC4B,KAAK,CACV,eAAe,EACfU,IAAI,CAACC,SAAS,CAAC;MACbe,IAAI,EAAEvB,KAAK,CAACuB,IAAI;MAChBvB,KAAK,EAAEA,KAAK,CAACA,KAAK;MAClB2B,UAAU,EAAE3B,KAAK,CAAC2B,UAAU;MAC5BC,YAAY,EAAE5B,KAAK,CAAC4B,YAAY;MAChCC,UAAU,EAAEJ,GAAG,CAACI,UAAU;MAC1BC,QAAQ,EAAEL,GAAG,CAACK;IAChB,CAAC,CACH,CAAC;IAED,MAAMC,iBAAiB,GAAG,IAAI,CAAC5D,KAAK,CAAC6D,MAAM,IAAI,IAAI,CAAC7C,OAAO;IAC3D,MAAM8C,mBAAmB,GACvB,IAAI,CAAC9D,KAAK,CAAC+D,MAAM,CACf,CAACC,GAAG,EAAEC,IAAI,KAAKD,GAAG,GAAG5B,IAAI,CAACC,SAAS,CAAC4B,IAAI,CAAC,CAACJ,MAAM,EAChD,CACF,CAAC,IAAI,IAAI,CAAC5C,YAAY;;IAExB;IACA;IACA,IAAI2C,iBAAiB,IAAIE,mBAAmB,IAAI,CAAC,IAAI,CAACxD,OAAO,EAAE;MAC7D;MACA,IAAI,IAAI,CAACL,KAAK,EAAE;QACdiE,YAAY,CAAC,IAAI,CAACjE,KAAK,CAAC;QACxB,IAAI,CAACA,KAAK,GAAG,IAAI;MACnB;MACA,IAAI,CAACK,OAAO,GAAG,IAAI;MACnB;MACA;MACA;MACA;MACA,IAAI,CAACqB,KAAK,CAAC,CAAC,CAAC/B,KAAK,CAAEC,KAAK,IAAK;QAC5BC,cAAM,CAACD,KAAK,CAAC,0CAA0C,EAAEA,KAAK,CAAC;MACjE,CAAC,CAAC;MACF;IACF;IAEA,IAAI,CAACsE,aAAa,CAAC,CAAC;EACtB;;EAEA;AACF;AACA;AACA;EACUA,aAAaA,CAAA,EAAS;IAC5B,IAAI,IAAI,CAAC5D,MAAM,EAAE;IACjB,IAAI,CAAC,IAAI,CAACW,eAAe,IAAI,IAAI,CAACjB,KAAK,IAAI,CAAC,IAAI,CAACD,KAAK,CAAC6D,MAAM,EAAE;IAE/D,IAAI,CAAC5D,KAAK,GAAGmE,UAAU,CAAC,MAAM;MAC5B;MACA;MACA;MACA;MACA;MACA;MACA;MACA,IAAI,CAACzC,KAAK,CAAC,CAAC,CAAC/B,KAAK,CAAEC,KAAK,IAAK;QAC5BC,cAAM,CAACD,KAAK,CAAC,yCAAyC,EAAEA,KAAK,CAAC;MAChE,CAAC,CAAC;IACJ,CAAC,EAAE,IAAI,CAACqB,eAAe,CAAC;EAC1B;;EAEA;AACF;AACA;AACA;AACA;EACE,MAAMS,KAAKA,CAACiB,QAAuC,EAAiB;IAClE,OAAO,IAAI,CAACyB,QAAQ,CAACzB,QAAQ,EAAE,KAAK,CAAC;EACvC;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACE,MAAcyB,QAAQA,CACpBzB,QAAoD,EACpD0B,aAAsB,EACP;IACf1B,QAAQ,GAAGA,QAAQ,IAAIxD,IAAI;IAE3B,IAAI,IAAI,CAACa,KAAK,EAAE;MACdiE,YAAY,CAAC,IAAI,CAACjE,KAAK,CAAC;MACxB,IAAI,CAACA,KAAK,GAAG,IAAI;IACnB;;IAEA;IACA,MAAMsE,aAAa,GAAG,IAAI,CAACnE,UAAU;IACrC,IAAIoE,YAAwB;IAC5B,IAAI,CAACpE,UAAU,GAAG,IAAIV,OAAO,CAAEC,OAAO,IAAK;MACzC6E,YAAY,GAAG7E,OAAO;IACxB,CAAC,CAAC;IAEF,IAAI;MACF;MACA,MAAM4E,aAAa;;MAEnB;MACA;MACA;MACA;MACA,IAAI,IAAI,CAAChE,MAAM,IAAI,CAAC+D,aAAa,EAAE;QACjC;QACA;QACA;QACA;QACAxE,cAAM,CAAC4B,KAAK,CAAC,oDAAoD,CAAC;QAClE;MACF;MAEA,IAAI,CAAC,IAAI,CAAC1B,KAAK,CAAC6D,MAAM,EAAE;QACtBxE,QAAQ,CAACuD,QAAQ,CAAC;QAClB;MACF;MAEA,MAAM6B,KAAK,GAAG,IAAI,CAACzE,KAAK,CAAC0E,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC1D,OAAO,CAAC;MAChD;MACA;MACA,MAAMR,UAAU,GAAG,IAAI,CAACA,UAAU;MAElC,MAAMmE,MAAM,GAAG,IAAI3C,IAAI,CAAC,CAAC,CAAC4C,WAAW,CAAC,CAAC;MACvC,MAAMC,IAA+B,GAAGJ,KAAK,CAACK,GAAG,CAAEb,IAAI,KAAM;QAC3D,GAAGA,IAAI,CAAChB,OAAO;QACf8B,OAAO,EAAEJ;MACX,CAAC,CAAC,CAAC;MAEH,MAAMK,IAAI,GAAIC,GAAW,IAAK;QAC5B;QACA;QACA;QACA;QACA;QACA,IAAI,IAAI,CAAC1E,MAAM,IAAI,IAAI,CAACC,UAAU,KAAKA,UAAU,EAAE;QAEnDiE,KAAK,CAACS,OAAO,CAAC,CAAC;UAAEjC,OAAO;UAAEL,QAAQ,EAAEuC;QAAa,CAAC,KAChD9F,QAAQ,CAAC8F,YAAY,EAAEF,GAAG,EAAEhC,OAAO,EAAE4B,IAAI,CAC3C,CAAC;QACDxF,QAAQ,CAACuD,QAAQ,EAAGqC,GAAG,EAAEJ,IAAI,CAAC;MAChC,CAAC;MAED,IAAI;QACF,MAAM,IAAI,CAACO,aAAa,CAACP,IAAI,EAAErE,UAAU,CAAC;QAC1C;QACA;QACA;QACA;QACA;QACA,IAAI,IAAI,CAACA,UAAU,KAAKA,UAAU,EAAE;UAClCiE,KAAK,CAACS,OAAO,CAAEjB,IAAI,IAAK,IAAI,CAAC/D,aAAa,CAACmF,MAAM,CAACpB,IAAI,CAAC3B,IAAI,CAAC,CAAC;QAC/D;QACA0C,IAAI,CAAC,CAAC;QACNlF,cAAM,CAACwF,IAAI,CAAC,6BAA6BT,IAAI,CAAChB,MAAM,SAAS,CAAC;MAChE,CAAC,CAAC,OAAOoB,GAAG,EAAE;QACZ,IAAI,IAAI,CAACzE,UAAU,KAAKA,UAAU,EAAE;UAClC;UACA;UACA;UACA;UACAwE,IAAI,CAACC,GAAY,CAAC;UAClBnF,cAAM,CAAC4B,KAAK,CACV,0BAA0B+C,KAAK,CAACZ,MAAM,uCACxC,CAAC;QACH,CAAC,MAAM,IAAKoB,GAAG,EAAgBM,SAAS,KAAK,KAAK,EAAE;UAClD;UACA;UACA;UACA;UACA;UACA;UACAd,KAAK,CAACS,OAAO,CAAEjB,IAAI,IAAK,IAAI,CAAC/D,aAAa,CAACmF,MAAM,CAACpB,IAAI,CAAC3B,IAAI,CAAC,CAAC;UAC7D0C,IAAI,CAACC,GAAY,CAAC;UAClBnF,cAAM,CAACD,KAAK,CACV,YAAY4E,KAAK,CAACZ,MAAM,6CAA6C,EACrEoB,GACF,CAAC;QACH,CAAC,MAAM;UACL;UACA;UACA;UACA,IAAI,CAACjF,KAAK,CAACwF,OAAO,CAAC,GAAGf,KAAK,CAAC;UAC5BO,IAAI,CAACC,GAAY,CAAC;UAClBnF,cAAM,CAACD,KAAK,CAAC,4CAA4C,EAAEoF,GAAG,CAAC;QACjE;;QAEA;QACA;QACA;QACA;QACA;QACA,IAAI,CAACd,aAAa,CAAC,CAAC;QACpB,MAAMc,GAAG;MACX;IACF,CAAC,SAAS;MACRT,YAAY,CAAE,CAAC;IACjB;EACF;;EAEA;AACF;AACA;AACA;AACA;EACUiB,gBAAgBA,CAACjF,UAAkB,EAAQ;IACjD,IAAI,IAAI,CAACA,UAAU,KAAKA,UAAU,EAAE;MAClC,MAAMX,KAAgB,GAAG,IAAI6F,KAAK,CAChC,gDACF,CAAC;MACD;MACA7F,KAAK,CAAC0F,SAAS,GAAG,KAAK;MACvB,MAAM1F,KAAK;IACb;EACF;;EAEA;AACF;AACA;EACE,MAAcuF,aAAaA,CACzBP,IAA+B,EAC/BrE,UAAkB,EAClBmF,OAAO,GAAG,CAAC,EACI;IACf,IAAI;MACF,MAAMC,QAAQ,GAAG,MAAMC,KAAK,CAAC,IAAI,CAAChF,OAAO,EAAE;QACzCiF,MAAM,EAAE,MAAM;QACdC,OAAO,EAAE,IAAAC,gCAAyB,EAAC,IAAI,CAACrF,QAAQ,CAAC;QACjDsF,IAAI,EAAE7D,IAAI,CAACC,SAAS,CAACwC,IAAI;MAC3B,CAAC,CAAC;MAEF,IAAI,CAACe,QAAQ,CAACM,EAAE,EAAE;QAChB,MAAMC,WAAW,GAAG,IAAI,CAACA,WAAW,CAACP,QAAQ,CAACQ,MAAM,CAAC;QACrD,IAAID,WAAW,IAAIR,OAAO,GAAG,IAAI,CAAC7E,UAAU,EAAE;UAC5C,MAAMuF,KAAK,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC,EAAEZ,OAAO,CAAC,GAAG,IAAI;UACzC,MAAM,IAAIjG,OAAO,CAAQC,OAAO,IAAKyE,UAAU,CAAC,MAAMzE,OAAO,CAAC,CAAC,EAAE0G,KAAK,CAAC,CAAC;UACxE,IAAI,CAACZ,gBAAgB,CAACjF,UAAU,CAAC;UACjC,OAAO,IAAI,CAAC4E,aAAa,CAACP,IAAI,EAAErE,UAAU,EAAEmF,OAAO,GAAG,CAAC,CAAC;QAC1D;QACA,MAAM9F,KAAgB,GAAG,IAAI6F,KAAK,CAChC,uBAAuBE,QAAQ,CAACQ,MAAM,EACxC,CAAC;QACD;QACA;QACA;QACAvG,KAAK,CAAC0F,SAAS,GAAGY,WAAW;QAC7B,MAAMtG,KAAK;MACb;IACF,CAAC,CAAC,OAAOA,KAAK,EAAE;MACd,IAAI,IAAA2G,sBAAc,EAAC3G,KAAK,CAAC,EAAE;QACzB,IAAI8F,OAAO,GAAG,IAAI,CAAC7E,UAAU,EAAE;UAC7B,MAAMuF,KAAK,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC,EAAEZ,OAAO,CAAC,GAAG,IAAI;UACzC7F,cAAM,CAACgD,IAAI,CAAC,8BAA8BuD,KAAK,OAAO,CAAC;UACvD,MAAM,IAAI3G,OAAO,CAAQC,OAAO,IAAKyE,UAAU,CAAC,MAAMzE,OAAO,CAAC,CAAC,EAAE0G,KAAK,CAAC,CAAC;UACxE,IAAI,CAACZ,gBAAgB,CAACjF,UAAU,CAAC;UACjC,OAAO,IAAI,CAAC4E,aAAa,CAACP,IAAI,EAAErE,UAAU,EAAEmF,OAAO,GAAG,CAAC,CAAC;QAC1D;QACA;QACC9F,KAAK,CAAe0F,SAAS,GAAG,IAAI;MACvC;MACA,MAAM1F,KAAK;IACb;EACF;;EAEA;AACF;AACA;EACUsG,WAAWA,CAACC,MAAc,EAAW;IAC3C;IACA;IACA;IACA;IACA,OAAQA,MAAM,IAAI,GAAG,IAAIA,MAAM,IAAI,GAAG,IAAKA,MAAM,KAAK,GAAG,IAAIA,MAAM,KAAK,GAAG;EAC7E;;EAEA;AACF;AACA;AACA;AACA;EACSK,KAAKA,CAAA,EAAS;IACnB;IACA;IACA,IAAI,CAACjG,UAAU,EAAE;IACjB,IAAI,CAACR,KAAK,GAAG,EAAE;IACf,IAAI,CAACE,aAAa,CAACuG,KAAK,CAAC,CAAC;IAE1B,IAAI,IAAI,CAACxG,KAAK,EAAE;MACdiE,YAAY,CAAC,IAAI,CAACjE,KAAK,CAAC;MACxB,IAAI,CAACA,KAAK,GAAG,IAAI;IACnB;IAEAH,cAAM,CAAC4B,KAAK,CAAC,wCAAwC,CAAC;EACxD;;EAEA;AACF;AACA;AACA;EACUgF,mBAAmBA,CAACC,MAAc,EAAQ;IAChD7G,cAAM,CAACgD,IAAI,CACT,eAAe6D,MAAM,gBAAgB,IAAI,CAAC3G,KAAK,CAAC6D,MAAM,WACxD,CAAC;IACD;IACA;IACA;IACA;IACA;IACA;IACA,IAAI,CAAC4C,KAAK,CAAC,CAAC;EACd;;EAEA;AACF;AACA;EACE,MAAaG,OAAOA,CAAA,EAAkB;IACpC;IACA;IACA,IAAI,CAAC,IAAI,CAACnG,cAAc,EAAE;MACxB;MACA;MACA;MACA;MACA,IAAI,CAACA,cAAc,GAAG,IAAI,CAACoG,UAAU,CAAC,CAAC,CAACjH,KAAK,CAAEC,KAAK,IAAK;QACvDC,cAAM,CAACD,KAAK,CAAC,4BAA4B,EAAEA,KAAK,CAAC;QACjD;QACA;QACA,IAAI,CAAC4G,KAAK,CAAC,CAAC;MACd,CAAC,CAAC;IACJ;IACA,OAAO,IAAI,CAAChG,cAAc;EAC5B;EAEA,MAAcoG,UAAUA,CAAA,EAAkB;IACxC;IACA,IAAI,CAACtG,MAAM,GAAG,IAAI;IAClB,IAAI,IAAI,CAACN,KAAK,EAAE;MACdiE,YAAY,CAAC,IAAI,CAACjE,KAAK,CAAC;MACxB,IAAI,CAACA,KAAK,GAAG,IAAI;IACnB;;IAEA;IACA;IACA;IACA;IACA,IAAI,IAAI,CAACI,oBAAoB,EAAE;MAC7B,IAAI;QACF,IAAI,CAACA,oBAAoB,CAACyG,MAAM,CAAC,CAAC;MACpC,CAAC,CAAC,OAAOjH,KAAK,EAAE;QACd;QACA;QACAC,cAAM,CAACD,KAAK,CAAC,gDAAgD,EAAEA,KAAK,CAAC;MACvE;MACA,IAAI,CAACQ,oBAAoB,GAAG,IAAI;IAClC;;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,IAAI0G,aAAwD;IAC5D,MAAMC,QAAQ,GAAG,IAAItH,OAAO,CAAaC,OAAO,IAAK;MACnDoH,aAAa,GAAG3C,UAAU,CAAC,MAAMzE,OAAO,CAAC,SAAS,CAAC,EAAEX,kBAAkB,CAAC;IAC1E,CAAC,CAAC;IACF,MAAMiI,cAAc,GAAOC,IAAgB,IACzCxH,OAAO,CAACyH,IAAI,CAAC,CAACD,IAAI,EAAEF,QAAQ,CAAC,CAAC;IAChC,MAAMI,QAAQ,GAAG,qBAAqB,IAAArE,4BAAoB,EACxD/D,kBACF,CAAC,GAAG;IAEJ,IAAI;MACF;MACA;MACA;MACA;MACA;MACA,IACE,CAAC,MAAMiI,cAAc,CAAC,IAAI,CAAC7G,UAAU,CAACX,IAAI,CAAC,MAAM,SAAkB,CAAC,CAAC,MACrE,SAAS,EACT;QACA,IAAI,CAACiH,mBAAmB,CAACU,QAAQ,CAAC;QAClC;MACF;;MAEA;MACA;MACA;MACA,MAAMC,WAAW,GAAGf,IAAI,CAACgB,IAAI,CAAC,IAAI,CAACtH,KAAK,CAAC6D,MAAM,GAAG,IAAI,CAAC7C,OAAO,CAAC,GAAG,CAAC;MACnE,IAAIuG,QAAQ,GAAG,CAAC;MAChB,MAAMC,kBAAkB,GAAG,IAAI,CAACxH,KAAK,CAAC6D,MAAM;MAE5C,OAAO,IAAI,CAAC7D,KAAK,CAAC6D,MAAM,GAAG,CAAC,IAAI0D,QAAQ,GAAGF,WAAW,EAAE;QACtD,MAAMI,iBAAiB,GAAG,IAAI,CAACzH,KAAK,CAAC6D,MAAM;QAE3C,MAAM6D,OAAO,GAAG,MAAMT,cAAc;QAClC;QACA;QACA,IAAI,CAAC5C,QAAQ,CAACsD,SAAS,EAAE,IAAI,CAAC,CAAClI,IAAI,CACjC,MAAM,SAAkB,EACvBI,KAAK,IAAK;UACTC,cAAM,CAACD,KAAK,CAAC,4CAA4C,EAAEA,KAAK,CAAC;UACjE,OAAO,QAAQ;QACjB,CACF,CACF,CAAC;QAED,IAAI6H,OAAO,KAAK,SAAS,EAAE;UACzB,IAAI,CAAChB,mBAAmB,CAACU,QAAQ,CAAC;UAClC;QACF;QACA;QACA,IAAIM,OAAO,KAAK,QAAQ,EAAE;;QAE1B;QACA,IAAI,IAAI,CAAC1H,KAAK,CAAC6D,MAAM,IAAI4D,iBAAiB,EAAE;UAC1C3H,cAAM,CAACgD,IAAI,CAAC,+DAA+D,CAAC;UAC5E;QACF;QAEAyE,QAAQ,EAAE;MACZ;MAEA,IAAIC,kBAAkB,GAAG,CAAC,EAAE;QAC1B1H,cAAM,CAAC4B,KAAK,CAAC,0CAA0C8F,kBAAkB,GAAG,IAAI,CAACxH,KAAK,CAAC6D,MAAM,SAAS,CAAC;MACzG;;MAEA;MACA;MACA;MACA;MACA;MACA;MACA,IAAI,IAAI,CAAC7D,KAAK,CAAC6D,MAAM,GAAG,CAAC,EAAE;QACzB,IAAI,CAAC6C,mBAAmB,CACtBa,QAAQ,IAAIF,WAAW,GACnB,8BAA8B,GAC9B,4CACN,CAAC;MACH;IACF,CAAC,SAAS;MACR,IAAIN,aAAa,EAAE7C,YAAY,CAAC6C,aAAa,CAAC;;MAE9C;MACA;MACA;MACA;MACA,IAAI,IAAI,CAAC9G,KAAK,EAAE;QACdiE,YAAY,CAAC,IAAI,CAACjE,KAAK,CAAC;QACxB,IAAI,CAACA,KAAK,GAAG,IAAI;MACnB;IACF;EACF;AACF;AAAC2H,OAAA,CAAA7H,UAAA,GAAAA,UAAA","ignoreList":[]}