@qurvo/sdk-core 0.0.10 → 0.0.11

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.
@@ -1,7 +1,30 @@
1
1
  import type { Transport, SendOptions, CompressFn } from './types';
2
+ /**
3
+ * Default {@link Transport} implementation using the Fetch API.
4
+ *
5
+ * Sends event batches as HTTP POST requests with optional gzip
6
+ * compression. Compression is skipped for `keepalive` requests
7
+ * (browser unload) because the Compression Streams API may not
8
+ * complete before the page is destroyed.
9
+ *
10
+ * **Error classification**:
11
+ * - 2xx / 202: success.
12
+ * - 429 with `quota_limited` body: throws {@link QuotaExceededError}.
13
+ * - Other 4xx: throws {@link NonRetryableError} (batch should be dropped).
14
+ * - 5xx: throws a plain {@link Error} (batch should be retried by the queue).
15
+ */
2
16
  export declare class FetchTransport implements Transport {
3
17
  private readonly compress?;
18
+ /** @param compress - Optional gzip function (e.g. `compressGzip` from sdk-browser). */
4
19
  constructor(compress?: CompressFn | undefined);
20
+ /**
21
+ * Send a JSON-serialized payload to the ingest endpoint.
22
+ *
23
+ * @returns `true` on 2xx/202 (accepted).
24
+ * @throws {@link QuotaExceededError} on 429 + `quota_limited`.
25
+ * @throws {@link NonRetryableError} on 4xx client errors.
26
+ * @throws {@link Error} on 5xx server errors.
27
+ */
5
28
  send(endpoint: string, apiKey: string, payload: unknown, options?: SendOptions): Promise<boolean>;
6
29
  }
7
30
  //# sourceMappingURL=fetch-transport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-transport.d.ts","sourceRoot":"","sources":["../src/fetch-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGlE,qBAAa,cAAe,YAAW,SAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAT,QAAQ,CAAC,EAAE,UAAU,YAAA;IAE5C,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;CA2CxG"}
1
+ {"version":3,"file":"fetch-transport.d.ts","sourceRoot":"","sources":["../src/fetch-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGlE;;;;;;;;;;;;;GAaG;AACH,qBAAa,cAAe,YAAW,SAAS;IAElC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IADtC,uFAAuF;gBAC1D,QAAQ,CAAC,EAAE,UAAU,YAAA;IAElD;;;;;;;OAOG;IACG,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;CA2CxG"}
@@ -2,11 +2,34 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FetchTransport = void 0;
4
4
  const types_1 = require("./types");
5
+ /**
6
+ * Default {@link Transport} implementation using the Fetch API.
7
+ *
8
+ * Sends event batches as HTTP POST requests with optional gzip
9
+ * compression. Compression is skipped for `keepalive` requests
10
+ * (browser unload) because the Compression Streams API may not
11
+ * complete before the page is destroyed.
12
+ *
13
+ * **Error classification**:
14
+ * - 2xx / 202: success.
15
+ * - 429 with `quota_limited` body: throws {@link QuotaExceededError}.
16
+ * - Other 4xx: throws {@link NonRetryableError} (batch should be dropped).
17
+ * - 5xx: throws a plain {@link Error} (batch should be retried by the queue).
18
+ */
5
19
  class FetchTransport {
6
20
  compress;
21
+ /** @param compress - Optional gzip function (e.g. `compressGzip` from sdk-browser). */
7
22
  constructor(compress) {
8
23
  this.compress = compress;
9
24
  }
25
+ /**
26
+ * Send a JSON-serialized payload to the ingest endpoint.
27
+ *
28
+ * @returns `true` on 2xx/202 (accepted).
29
+ * @throws {@link QuotaExceededError} on 429 + `quota_limited`.
30
+ * @throws {@link NonRetryableError} on 4xx client errors.
31
+ * @throws {@link Error} on 5xx server errors.
32
+ */
10
33
  async send(endpoint, apiKey, payload, options) {
11
34
  const json = JSON.stringify(payload);
12
35
  const headers = {
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-transport.js","sourceRoot":"","sources":["../src/fetch-transport.ts"],"names":[],"mappings":";;;AACA,mCAAgE;AAEhE,MAAa,cAAc;IACI;IAA7B,YAA6B,QAAqB;QAArB,aAAQ,GAAR,QAAQ,CAAa;IAAG,CAAC;IAEtD,KAAK,CAAC,IAAI,CAAC,QAAgB,EAAE,MAAc,EAAE,OAAgB,EAAE,OAAqB;QAClF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,OAAO,GAA2B;YACtC,WAAW,EAAE,MAAM;SACpB,CAAC;QAEF,IAAI,IAAc,CAAC;QACnB,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC;YACzC,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACjC,OAAO,CAAC,cAAc,CAAC,GAAG,YAAY,CAAC;YACvC,OAAO,CAAC,kBAAkB,CAAC,GAAG,MAAM,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,IAAI,CAAC;YACZ,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;QAC/C,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;YACrC,MAAM,EAAE,MAAM;YACd,OAAO;YACP,IAAI;YACJ,SAAS,EAAE,OAAO,EAAE,SAAS;YAC7B,MAAM,EAAE,OAAO,EAAE,MAAM;SACxB,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAExD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC7D,IAAI,YAAY,EAAE,aAAa,EAAE,CAAC;gBAChC,MAAM,IAAI,0BAAkB,EAAE,CAAC;YACjC,CAAC;QACH,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAE3D,uEAAuE;QACvE,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YACpD,MAAM,IAAI,yBAAiB,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,QAAQ,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC,CAAC;QAC3F,CAAC;QAED,gCAAgC;QAChC,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC,CAAC;IAC9D,CAAC;CACF;AA9CD,wCA8CC"}
1
+ {"version":3,"file":"fetch-transport.js","sourceRoot":"","sources":["../src/fetch-transport.ts"],"names":[],"mappings":";;;AACA,mCAAgE;AAEhE;;;;;;;;;;;;;GAaG;AACH,MAAa,cAAc;IAEI;IAD7B,uFAAuF;IACvF,YAA6B,QAAqB;QAArB,aAAQ,GAAR,QAAQ,CAAa;IAAG,CAAC;IAEtD;;;;;;;OAOG;IACH,KAAK,CAAC,IAAI,CAAC,QAAgB,EAAE,MAAc,EAAE,OAAgB,EAAE,OAAqB;QAClF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,OAAO,GAA2B;YACtC,WAAW,EAAE,MAAM;SACpB,CAAC;QAEF,IAAI,IAAc,CAAC;QACnB,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC;YACzC,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACjC,OAAO,CAAC,cAAc,CAAC,GAAG,YAAY,CAAC;YACvC,OAAO,CAAC,kBAAkB,CAAC,GAAG,MAAM,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,IAAI,CAAC;YACZ,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;QAC/C,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;YACrC,MAAM,EAAE,MAAM;YACd,OAAO;YACP,IAAI;YACJ,SAAS,EAAE,OAAO,EAAE,SAAS;YAC7B,MAAM,EAAE,OAAO,EAAE,MAAM;SACxB,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAExD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC7D,IAAI,YAAY,EAAE,aAAa,EAAE,CAAC;gBAChC,MAAM,IAAI,0BAAkB,EAAE,CAAC;YACjC,CAAC;QACH,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAE3D,uEAAuE;QACvE,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YACpD,MAAM,IAAI,yBAAiB,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,QAAQ,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC,CAAC;QAC3F,CAAC;QAED,gCAAgC;QAChC,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC,CAAC;IAC9D,CAAC;CACF;AAvDD,wCAuDC"}
package/dist/queue.d.ts CHANGED
@@ -1,4 +1,24 @@
1
1
  import type { Transport, LogFn, QueuePersistence } from './types';
2
+ /**
3
+ * Buffered event queue with automatic flushing, exponential backoff, and
4
+ * optional persistence.
5
+ *
6
+ * **Lifecycle**: events are added via {@link enqueue}, accumulated in an
7
+ * in-memory buffer, and periodically sent to the ingest API by
8
+ * {@link flush}. Flushing is triggered either by a timer ({@link start})
9
+ * or when the buffer reaches `flushSize`.
10
+ *
11
+ * **Error handling**:
12
+ * - 5xx / network errors: the batch is re-queued and delivery retries
13
+ * with exponential backoff (up to 30 s).
14
+ * - 4xx ({@link NonRetryableError}): the batch is dropped permanently.
15
+ * - 429 + quota_limited ({@link QuotaExceededError}): the entire queue
16
+ * is drained and the timer is stopped.
17
+ *
18
+ * **Persistence**: when a {@link QueuePersistence} implementation is
19
+ * provided, the queue is saved to durable storage after every mutation
20
+ * and restored on construction.
21
+ */
2
22
  export declare class EventQueue {
3
23
  private readonly transport;
4
24
  private readonly endpoint;
@@ -16,15 +36,74 @@ export declare class EventQueue {
16
36
  private failureCount;
17
37
  private retryAfter;
18
38
  private readonly maxBackoffMs;
39
+ /**
40
+ * @param transport - Transport used to deliver batches (e.g. {@link FetchTransport}).
41
+ * @param endpoint - Full URL of the ingest endpoint.
42
+ * @param apiKey - Project API key for authentication.
43
+ * @param flushInterval - Milliseconds between automatic flushes. Default: `5000`.
44
+ * @param flushSize - Batch size that triggers an immediate flush. Default: `20`.
45
+ * @param maxQueueSize - Maximum events held in memory (FIFO eviction). Default: `1000`.
46
+ * @param sendTimeoutMs - Per-request abort timeout in milliseconds. Default: `30000`.
47
+ * @param logger - Optional debug logger.
48
+ * @param persistence - Optional durable storage backing for the queue.
49
+ */
19
50
  constructor(transport: Transport, endpoint: string, apiKey: string, flushInterval?: number, flushSize?: number, maxQueueSize?: number, sendTimeoutMs?: number, logger?: LogFn | undefined, persistence?: QueuePersistence | undefined);
51
+ /**
52
+ * Add an event to the queue.
53
+ *
54
+ * When the buffer is full (`maxQueueSize`), the **oldest** event is
55
+ * dropped (FIFO eviction) to make room. If the buffer reaches
56
+ * `flushSize` after insertion, an immediate {@link flush} is triggered.
57
+ */
20
58
  enqueue(event: unknown): void;
59
+ /** Start the periodic flush timer. No-op if already running. */
21
60
  start(): void;
61
+ /** Stop the periodic flush timer. Safe to call when already stopped. */
22
62
  stop(): void;
63
+ /**
64
+ * Send the next batch of events to the ingest API.
65
+ *
66
+ * No-op when a flush is already in progress, the queue is empty,
67
+ * or the backoff cooldown has not elapsed.
68
+ *
69
+ * **Retry logic**:
70
+ * - On 5xx or network error the batch is re-queued and delivery is
71
+ * retried with exponential backoff (1 s, 2 s, 4 s, ... up to 30 s).
72
+ * - On 4xx ({@link NonRetryableError}) the batch is **dropped**.
73
+ * - On 429 + quota_limited ({@link QuotaExceededError}) the queue is
74
+ * emptied and the flush timer is stopped.
75
+ */
23
76
  flush(): Promise<void>;
24
77
  private scheduleBackoff;
78
+ /**
79
+ * Drain the queue by flushing repeatedly until empty.
80
+ *
81
+ * Resets backoff state before starting so pending retries are not
82
+ * delayed. Stops early if a flush cycle makes no progress (e.g. all
83
+ * events are failing permanently).
84
+ */
25
85
  flushAll(): Promise<void>;
86
+ /**
87
+ * Gracefully shut down the queue.
88
+ *
89
+ * Stops the periodic timer and attempts to deliver all remaining
90
+ * events via {@link flushAll}. If delivery does not complete within
91
+ * `timeoutMs`, the promise resolves and outstanding events are lost.
92
+ *
93
+ * @param timeoutMs - Maximum time to wait for delivery. Default: `30000`.
94
+ */
26
95
  shutdown(timeoutMs?: number): Promise<void>;
96
+ /**
97
+ * Last-resort flush for page unload (`beforeunload` / `visibilitychange`).
98
+ *
99
+ * Sends all remaining events in a single fire-and-forget request with
100
+ * `keepalive: true` so the browser keeps the connection alive after the
101
+ * page is destroyed. If a regular {@link flush} is already in-flight,
102
+ * only the queued (not yet sent) events are included to avoid
103
+ * double-delivery.
104
+ */
27
105
  flushForUnload(): void;
106
+ /** Total number of events pending delivery (queued + in-flight). */
28
107
  get size(): number;
29
108
  private persist;
30
109
  }
@@ -1 +1 @@
1
- {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAGlE,qBAAa,UAAU;IAUnB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAjB/B,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAA0B;IAC/C,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;gBAGpB,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,aAAa,GAAE,MAAa,EAC5B,SAAS,GAAE,MAAW,EACtB,YAAY,GAAE,MAAa,EAC3B,aAAa,GAAE,MAAe,EAC9B,MAAM,CAAC,EAAE,KAAK,YAAA,EACd,WAAW,CAAC,EAAE,gBAAgB,YAAA;IAejD,OAAO,CAAC,KAAK,EAAE,OAAO;IAatB,KAAK;IAKL,IAAI;IAOE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiD5B,OAAO,CAAC,eAAe;IAMjB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAUzB,QAAQ,CAAC,SAAS,GAAE,MAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IASzD,cAAc,IAAI,IAAI;IAatB,IAAI,IAAI,WAEP;IAED,OAAO,CAAC,OAAO;CAOhB"}
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAGlE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,UAAU;IAqBnB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IA5B/B,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAA0B;IAC/C,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IAEvC;;;;;;;;;;OAUG;gBAEgB,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,aAAa,GAAE,MAAa,EAC5B,SAAS,GAAE,MAAW,EACtB,YAAY,GAAE,MAAa,EAC3B,aAAa,GAAE,MAAe,EAC9B,MAAM,CAAC,EAAE,KAAK,YAAA,EACd,WAAW,CAAC,EAAE,gBAAgB,YAAA;IAejD;;;;;;OAMG;IACH,OAAO,CAAC,KAAK,EAAE,OAAO;IAatB,gEAAgE;IAChE,KAAK;IAKL,wEAAwE;IACxE,IAAI;IAOJ;;;;;;;;;;;;OAYG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiD5B,OAAO,CAAC,eAAe;IAMvB;;;;;;OAMG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAU/B;;;;;;;;OAQG;IACG,QAAQ,CAAC,SAAS,GAAE,MAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IASzD;;;;;;;;OAQG;IACH,cAAc,IAAI,IAAI;IAatB,oEAAoE;IACpE,IAAI,IAAI,WAEP;IAED,OAAO,CAAC,OAAO;CAOhB"}
package/dist/queue.js CHANGED
@@ -2,6 +2,26 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EventQueue = void 0;
4
4
  const types_1 = require("./types");
5
+ /**
6
+ * Buffered event queue with automatic flushing, exponential backoff, and
7
+ * optional persistence.
8
+ *
9
+ * **Lifecycle**: events are added via {@link enqueue}, accumulated in an
10
+ * in-memory buffer, and periodically sent to the ingest API by
11
+ * {@link flush}. Flushing is triggered either by a timer ({@link start})
12
+ * or when the buffer reaches `flushSize`.
13
+ *
14
+ * **Error handling**:
15
+ * - 5xx / network errors: the batch is re-queued and delivery retries
16
+ * with exponential backoff (up to 30 s).
17
+ * - 4xx ({@link NonRetryableError}): the batch is dropped permanently.
18
+ * - 429 + quota_limited ({@link QuotaExceededError}): the entire queue
19
+ * is drained and the timer is stopped.
20
+ *
21
+ * **Persistence**: when a {@link QueuePersistence} implementation is
22
+ * provided, the queue is saved to durable storage after every mutation
23
+ * and restored on construction.
24
+ */
5
25
  class EventQueue {
6
26
  transport;
7
27
  endpoint;
@@ -19,6 +39,17 @@ class EventQueue {
19
39
  failureCount = 0;
20
40
  retryAfter = 0;
21
41
  maxBackoffMs = 30_000;
42
+ /**
43
+ * @param transport - Transport used to deliver batches (e.g. {@link FetchTransport}).
44
+ * @param endpoint - Full URL of the ingest endpoint.
45
+ * @param apiKey - Project API key for authentication.
46
+ * @param flushInterval - Milliseconds between automatic flushes. Default: `5000`.
47
+ * @param flushSize - Batch size that triggers an immediate flush. Default: `20`.
48
+ * @param maxQueueSize - Maximum events held in memory (FIFO eviction). Default: `1000`.
49
+ * @param sendTimeoutMs - Per-request abort timeout in milliseconds. Default: `30000`.
50
+ * @param logger - Optional debug logger.
51
+ * @param persistence - Optional durable storage backing for the queue.
52
+ */
22
53
  constructor(transport, endpoint, apiKey, flushInterval = 5000, flushSize = 20, maxQueueSize = 1000, sendTimeoutMs = 30_000, logger, persistence) {
23
54
  this.transport = transport;
24
55
  this.endpoint = endpoint;
@@ -42,6 +73,13 @@ class EventQueue {
42
73
  }
43
74
  }
44
75
  }
76
+ /**
77
+ * Add an event to the queue.
78
+ *
79
+ * When the buffer is full (`maxQueueSize`), the **oldest** event is
80
+ * dropped (FIFO eviction) to make room. If the buffer reaches
81
+ * `flushSize` after insertion, an immediate {@link flush} is triggered.
82
+ */
45
83
  enqueue(event) {
46
84
  if (this.queue.length >= this.maxQueueSize) {
47
85
  this.queue.shift();
@@ -53,17 +91,32 @@ class EventQueue {
53
91
  this.flush();
54
92
  }
55
93
  }
94
+ /** Start the periodic flush timer. No-op if already running. */
56
95
  start() {
57
96
  if (this.timer)
58
97
  return;
59
98
  this.timer = setInterval(() => this.flush(), this.flushInterval);
60
99
  }
100
+ /** Stop the periodic flush timer. Safe to call when already stopped. */
61
101
  stop() {
62
102
  if (this.timer) {
63
103
  clearInterval(this.timer);
64
104
  this.timer = null;
65
105
  }
66
106
  }
107
+ /**
108
+ * Send the next batch of events to the ingest API.
109
+ *
110
+ * No-op when a flush is already in progress, the queue is empty,
111
+ * or the backoff cooldown has not elapsed.
112
+ *
113
+ * **Retry logic**:
114
+ * - On 5xx or network error the batch is re-queued and delivery is
115
+ * retried with exponential backoff (1 s, 2 s, 4 s, ... up to 30 s).
116
+ * - On 4xx ({@link NonRetryableError}) the batch is **dropped**.
117
+ * - On 429 + quota_limited ({@link QuotaExceededError}) the queue is
118
+ * emptied and the flush timer is stopped.
119
+ */
67
120
  async flush() {
68
121
  if (this.flushing || this.queue.length === 0)
69
122
  return;
@@ -118,6 +171,13 @@ class EventQueue {
118
171
  const backoffMs = Math.min(1000 * Math.pow(2, this.failureCount - 1), this.maxBackoffMs);
119
172
  this.retryAfter = Date.now() + backoffMs;
120
173
  }
174
+ /**
175
+ * Drain the queue by flushing repeatedly until empty.
176
+ *
177
+ * Resets backoff state before starting so pending retries are not
178
+ * delayed. Stops early if a flush cycle makes no progress (e.g. all
179
+ * events are failing permanently).
180
+ */
121
181
  async flushAll() {
122
182
  this.retryAfter = 0;
123
183
  this.failureCount = 0;
@@ -128,6 +188,15 @@ class EventQueue {
128
188
  break;
129
189
  }
130
190
  }
191
+ /**
192
+ * Gracefully shut down the queue.
193
+ *
194
+ * Stops the periodic timer and attempts to deliver all remaining
195
+ * events via {@link flushAll}. If delivery does not complete within
196
+ * `timeoutMs`, the promise resolves and outstanding events are lost.
197
+ *
198
+ * @param timeoutMs - Maximum time to wait for delivery. Default: `30000`.
199
+ */
131
200
  async shutdown(timeoutMs = 30_000) {
132
201
  this.stop();
133
202
  if (this.size === 0)
@@ -137,6 +206,15 @@ class EventQueue {
137
206
  new Promise((resolve) => setTimeout(resolve, timeoutMs)),
138
207
  ]);
139
208
  }
209
+ /**
210
+ * Last-resort flush for page unload (`beforeunload` / `visibilitychange`).
211
+ *
212
+ * Sends all remaining events in a single fire-and-forget request with
213
+ * `keepalive: true` so the browser keeps the connection alive after the
214
+ * page is destroyed. If a regular {@link flush} is already in-flight,
215
+ * only the queued (not yet sent) events are included to avoid
216
+ * double-delivery.
217
+ */
140
218
  flushForUnload() {
141
219
  // If a flush() is already in-flight, don't re-send those events — they are
142
220
  // being delivered by the ongoing fetch. Only grab remaining queue items.
@@ -150,6 +228,7 @@ class EventQueue {
150
228
  return;
151
229
  this.transport.send(this.endpoint, this.apiKey, { events: batch, sent_at: new Date().toISOString() }, { keepalive: true }).catch(() => { });
152
230
  }
231
+ /** Total number of events pending delivery (queued + in-flight). */
153
232
  get size() {
154
233
  return this.queue.length + (this.inFlightBatch?.length || 0);
155
234
  }
package/dist/queue.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"queue.js","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,15 +1,33 @@
1
+ /**
2
+ * Configuration for the Qurvo SDK.
3
+ *
4
+ * Only `apiKey` is required. All other fields have sensible defaults
5
+ * set by the platform-specific SDK wrapper (sdk-browser / sdk-node).
6
+ */
1
7
  export interface SdkConfig {
8
+ /** Project API key used to authenticate ingest requests (`x-api-key` header). */
2
9
  apiKey: string;
10
+ /** Ingest endpoint URL. Defaults to `https://ingest.qurvo.pro/events/batch`. */
3
11
  endpoint?: string;
12
+ /** Interval in milliseconds between automatic flushes. Default: `5000`. */
4
13
  flushInterval?: number;
14
+ /** Number of events that triggers an immediate flush. Default: `20`. */
5
15
  flushSize?: number;
16
+ /** Maximum number of events held in memory. When exceeded, the oldest event is dropped (FIFO). Default: `1000`. */
6
17
  maxQueueSize?: number;
18
+ /** Optional logger function for debug output and error reporting. */
7
19
  logger?: LogFn;
8
20
  }
9
21
  export interface EventPayload {
10
22
  event: string;
11
23
  distinct_id: string;
12
24
  anonymous_id?: string;
25
+ /**
26
+ * Event properties. The browser SDK automatically merges UTM parameters
27
+ * (`utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, `utm_content`)
28
+ * from the page URL into this object. Explicitly provided properties
29
+ * take priority over auto-captured UTM values.
30
+ */
13
31
  properties?: Record<string, unknown>;
14
32
  user_properties?: Record<string, unknown>;
15
33
  context?: EventContext;
@@ -39,14 +57,49 @@ export interface SendOptions {
39
57
  signal?: AbortSignal;
40
58
  }
41
59
  export type LogFn = (message: string, error?: unknown) => void;
60
+ /**
61
+ * Persistence layer for the event queue.
62
+ *
63
+ * Implementations back the in-memory queue with durable storage (e.g.
64
+ * `localStorage` in browsers) so events survive page reloads or crashes.
65
+ * Persistence is best-effort: failures are silently ignored by {@link EventQueue}.
66
+ */
42
67
  export interface QueuePersistence {
68
+ /** Persist the current queue snapshot. Called after every enqueue and flush. */
43
69
  save(events: unknown[]): void;
70
+ /** Load previously persisted events. Called once during {@link EventQueue} construction. */
44
71
  load(): unknown[];
45
72
  }
46
73
  export type CompressFn = (data: string) => Promise<Blob>;
74
+ /**
75
+ * Transport contract for sending event batches to the ingest API.
76
+ *
77
+ * The default implementation is {@link FetchTransport}. Custom transports
78
+ * can be provided via SDK configuration for non-standard environments.
79
+ */
47
80
  export interface Transport {
81
+ /**
82
+ * Send a batch payload to the ingest endpoint.
83
+ *
84
+ * @param endpoint - Full URL of the ingest endpoint.
85
+ * @param apiKey - Project API key for the `x-api-key` header.
86
+ * @param payload - Serializable payload (`{ events, sent_at }`).
87
+ * @param options - Optional send options (abort signal, keepalive).
88
+ * @returns `true` if the server accepted the batch (2xx/202),
89
+ * `false` for retryable failures (e.g. network timeout handled internally).
90
+ * @throws {@link QuotaExceededError} when the server responds 429 with `quota_limited`.
91
+ * @throws {@link NonRetryableError} on 4xx client errors (bad data, auth failure).
92
+ * @throws {@link Error} on 5xx server errors (retryable by the queue).
93
+ */
48
94
  send(endpoint: string, apiKey: string, payload: unknown, options?: SendOptions): Promise<boolean>;
49
95
  }
96
+ /**
97
+ * Thrown when the ingest API responds with 429 and `quota_limited: true`,
98
+ * indicating the project has exceeded its monthly event quota.
99
+ *
100
+ * When caught by {@link EventQueue}, the queue is drained and stopped
101
+ * to prevent further network requests until the billing period resets.
102
+ */
50
103
  export declare class QuotaExceededError extends Error {
51
104
  constructor();
52
105
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,KAAK,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AAE/D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC9B,IAAI,IAAI,OAAO,EAAE,CAAC;CACnB;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEzD,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACnG;AAED,qBAAa,kBAAmB,SAAQ,KAAK;;CAK5C;AAED,uEAAuE;AACvE,qBAAa,iBAAkB,SAAQ,KAAK;aACd,UAAU,EAAE,MAAM;gBAAlB,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAIhE"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mHAAmH;IACnH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,MAAM,CAAC,EAAE,KAAK,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AAE/D;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gFAAgF;IAChF,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC9B,4FAA4F;IAC5F,IAAI,IAAI,OAAO,EAAE,CAAC;CACnB;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;;;;;;;;OAYG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACnG;AAED;;;;;;GAMG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;;CAK5C;AAED,uEAAuE;AACvE,qBAAa,iBAAkB,SAAQ,KAAK;aACd,UAAU,EAAE,MAAM;gBAAlB,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAIhE"}
package/dist/types.js CHANGED
@@ -1,6 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NonRetryableError = exports.QuotaExceededError = void 0;
4
+ /**
5
+ * Thrown when the ingest API responds with 429 and `quota_limited: true`,
6
+ * indicating the project has exceeded its monthly event quota.
7
+ *
8
+ * When caught by {@link EventQueue}, the queue is drained and stopped
9
+ * to prevent further network requests until the billing period resets.
10
+ */
4
11
  class QuotaExceededError extends Error {
5
12
  constructor() {
6
13
  super('Monthly event limit exceeded');
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AA0DA,MAAa,kBAAmB,SAAQ,KAAK;IAC3C;QACE,KAAK,CAAC,8BAA8B,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AALD,gDAKC;AAED,uEAAuE;AACvE,MAAa,iBAAkB,SAAQ,KAAK;IACd;IAA5B,YAA4B,UAAkB,EAAE,OAAe;QAC7D,KAAK,CAAC,OAAO,CAAC,CAAC;QADW,eAAU,GAAV,UAAU,CAAQ;QAE5C,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AALD,8CAKC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAwGA;;;;;;GAMG;AACH,MAAa,kBAAmB,SAAQ,KAAK;IAC3C;QACE,KAAK,CAAC,8BAA8B,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AALD,gDAKC;AAED,uEAAuE;AACvE,MAAa,iBAAkB,SAAQ,KAAK;IACd;IAA5B,YAA4B,UAAkB,EAAE,OAAe;QAC7D,KAAK,CAAC,OAAO,CAAC,CAAC;QADW,eAAU,GAAV,UAAU,CAAQ;QAE5C,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AALD,8CAKC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qurvo/sdk-core",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "description": "Core transport and event queue for Qurvo analytics SDKs",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",