@genn-inc/cluebase-frontend-sdk 0.0.6 → 0.0.9

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 (69) hide show
  1. package/dist/_generated/correlation-attribute-keys.d.ts +3 -0
  2. package/dist/_generated/correlation-attribute-keys.js +35 -0
  3. package/dist/_generated/diagnostic-codes.d.ts +4 -0
  4. package/dist/_generated/diagnostic-codes.js +48 -0
  5. package/dist/_generated/drop-reasons.d.ts +2 -0
  6. package/dist/_generated/drop-reasons.js +25 -0
  7. package/dist/_generated/ingest-routes.d.ts +5 -0
  8. package/dist/_generated/ingest-routes.js +12 -0
  9. package/dist/context/trace.js +2 -4
  10. package/dist/exporter/batch.d.ts +23 -26
  11. package/dist/exporter/batch.js +254 -289
  12. package/dist/exporter/browser-outbox-records.d.ts +7 -24
  13. package/dist/exporter/browser-outbox-records.js +6 -94
  14. package/dist/exporter/browser-outbox.d.ts +23 -28
  15. package/dist/exporter/browser-outbox.js +99 -211
  16. package/dist/exporter/client.d.ts +24 -34
  17. package/dist/exporter/client.js +107 -318
  18. package/dist/exporter/delivery-pipeline.d.ts +72 -0
  19. package/dist/exporter/delivery-pipeline.js +199 -0
  20. package/dist/exporter/delivery-response-contract.d.ts +5 -81
  21. package/dist/exporter/delivery-response-contract.js +4 -166
  22. package/dist/exporter/delivery-response.d.ts +8 -4
  23. package/dist/exporter/delivery-response.js +62 -133
  24. package/dist/exporter/diagnostics.d.ts +2 -1
  25. package/dist/exporter/diagnostics.js +1 -25
  26. package/dist/exporter/event-id.d.ts +1 -0
  27. package/dist/exporter/event-id.js +3 -0
  28. package/dist/exporter/observation-source-event-exporter.d.ts +1 -1
  29. package/dist/exporter/observation-source-event-exporter.js +2 -2
  30. package/dist/exporter/parameter-encryption.d.ts +10 -0
  31. package/dist/exporter/parameter-encryption.js +219 -0
  32. package/dist/exporter/parameter-snapshot.js +25 -3
  33. package/dist/exporter/sdk-core-delivery.d.ts +226 -0
  34. package/dist/exporter/sdk-core-delivery.js +97 -0
  35. package/dist/exporter/sdk-core-wasm.d.ts +24 -1
  36. package/dist/exporter/sdk-core-wasm.js +31 -3
  37. package/dist/exporter/source-event.d.ts +2 -0
  38. package/dist/exporter/source-event.js +17 -0
  39. package/dist/exporter/span-to-source-signal.d.ts +1 -1
  40. package/dist/exporter/span-to-source-signal.js +20 -140
  41. package/dist/index.d.ts +3 -3
  42. package/dist/index.js +5 -3
  43. package/dist/instrumentation/network.d.ts +1 -1
  44. package/dist/instrumentation/network.js +17 -0
  45. package/dist/provider/_version.d.ts +1 -1
  46. package/dist/provider/_version.js +1 -1
  47. package/dist/provider/config.js +16 -3
  48. package/dist/provider/constants.js +0 -1
  49. package/dist/provider/contracts.d.ts +2 -0
  50. package/dist/provider/contracts.js +2 -0
  51. package/dist/provider/lifecycle-event-dedup.d.ts +7 -0
  52. package/dist/provider/lifecycle-event-dedup.js +31 -0
  53. package/dist/provider/sdk-encryption-store.d.ts +7 -0
  54. package/dist/provider/sdk-encryption-store.js +15 -0
  55. package/dist/provider/sdk-event-pipeline.d.ts +1 -3
  56. package/dist/provider/sdk-event-pipeline.js +0 -15
  57. package/dist/provider/sdk-otel-pipeline.d.ts +2 -1
  58. package/dist/provider/sdk-otel-pipeline.js +2 -11
  59. package/dist/provider/sdk-runtime-surfaces.d.ts +3 -2
  60. package/dist/provider/sdk-runtime-surfaces.js +7 -6
  61. package/dist/provider/sdk.js +88 -54
  62. package/dist/provider/types.d.ts +14 -19
  63. package/dist/wasm/pkg-web/cluebase_sdk_core_wasm.d.ts +18 -9
  64. package/dist/wasm/pkg-web/cluebase_sdk_core_wasm.js +170 -29
  65. package/dist/wasm/pkg-web/cluebase_sdk_core_wasm_bg.wasm +0 -0
  66. package/dist/wasm/pkg-web/cluebase_sdk_core_wasm_bg.wasm.d.ts +10 -9
  67. package/package.json +1 -1
  68. package/dist/provider/usage-governor.d.ts +0 -7
  69. package/dist/provider/usage-governor.js +0 -114
@@ -1,14 +1,14 @@
1
1
  import { canonicalize as canonicalJsonStringify } from "json-canonicalize";
2
- import { addStorageListener, browserEventsByteLength, consentRecordKey, createConsentChannel, createConsentRecord, createDraft, createGeneration, createLegacyTombstone, createPending, draftRecordKey, hasLegacyTombstone, LEGACY_TOMBSTONE_LIMIT, largestFittingPrefix, nowIso, outboxEventCount, parseRecord, pendingRecordKey, readLocks, readStorage, recordBatchId, sha256Hex, splitPendingRecord, toHeadBatch, tombstoneRecordKey, UNANCHORED_COLLECTION_GENERATION, verifyHash, withChecksum, withoutChecksum, } from "./browser-outbox-records.js";
2
+ import { addStorageListener, consentRecordKey, createConsentChannel, createConsentRecord, createDraft, createGeneration, createLegacyTombstone, createPending, draftRecordKey, LEGACY_TOMBSTONE_LIMIT, nowIso, outboxEventCount, parseRecord, pendingRecordKey, readLocks, readStorage, sentByteLength, sha256Hex, tombstoneRecordKey, UNANCHORED_COLLECTION_GENERATION, verifyHash, } from "./browser-outbox-records.js";
3
3
  import { DiagnosticStore } from "./diagnostics.js";
4
4
  import { isBrowserSourceSignalEvent } from "./source-event.js";
5
5
  export class BrowserOutbox {
6
6
  constructor(options) {
7
7
  this.drafts = [];
8
8
  this.pending = [];
9
+ this.pendingByBatchId = new Map();
9
10
  this.tombstones = [];
10
11
  this.nextOrdinal = 1;
11
- this.nextPermitOrdinal = 1;
12
12
  this.legacyImportBlocked = false;
13
13
  this.consentAnchorEstablished = false;
14
14
  this.memoryOnly = false;
@@ -24,8 +24,6 @@ export class BrowserOutbox {
24
24
  this.storage =
25
25
  "storage" in options ? (options.storage ?? null) : readStorage();
26
26
  this.durableOutboxSupported = readLocks() !== null;
27
- this.maxBytes = Math.max(1024, options.maxBytes);
28
- this.maxEvents = Math.max(1, options.maxEvents);
29
27
  this.metrics = options.metrics ?? null;
30
28
  this.diagnostics = options.diagnostics ?? new DiagnosticStore();
31
29
  this.onConsentRevoked = options.onConsentRevoked ?? (() => undefined);
@@ -51,19 +49,10 @@ export class BrowserOutbox {
51
49
  currentConsent() {
52
50
  return this.consent;
53
51
  }
54
- capturePermit() {
55
- return Object.freeze({
56
- generation: this.consentAnchorEstablished
57
- ? this.generation
58
- : UNANCHORED_COLLECTION_GENERATION,
59
- permittedAtStart: this.consent !== "denied",
60
- captureOrdinal: this.nextPermitOrdinal++,
61
- });
62
- }
63
- permits(permit) {
64
- return (permit.permittedAtStart &&
65
- this.consent !== "denied" &&
66
- permit.generation === this.generation);
52
+ collectionGeneration() {
53
+ return this.consentAnchorEstablished
54
+ ? this.generation
55
+ : UNANCHORED_COLLECTION_GENERATION;
67
56
  }
68
57
  setConsent(next) {
69
58
  const recoveryExpectedRaw = this.consentStateUnavailable
@@ -185,152 +174,124 @@ export class BrowserOutbox {
185
174
  const purged = transition.purge ? this.purgeAll() : true;
186
175
  return persisted && purged;
187
176
  }
188
- addDraft(event, permit = this.capturePermit()) {
189
- const resolvedPermit = this.resolvePermit(permit);
190
- if (!resolvedPermit)
191
- return false;
177
+ holdDraft(event) {
178
+ if (this.consent === "denied" || !this.consentAnchorEstablished)
179
+ return null;
192
180
  const draft = createDraft({
193
181
  event,
194
- permit: resolvedPermit,
182
+ permit: { generation: this.generation, permittedAtStart: true },
195
183
  projectHash: this.projectHash,
196
184
  createdAt: nowIso(),
197
185
  });
198
186
  if (!draft)
199
- return false;
187
+ return null;
200
188
  const key = draftRecordKey(this.prefix, draft.eventKeyHash);
201
189
  const existing = this.readRecord(key);
202
190
  if (existing) {
203
191
  if (existing.kind === "draft" &&
204
192
  existing.recordVerifierSha256 === draft.recordVerifierSha256) {
205
- return true;
193
+ return draft;
206
194
  }
207
195
  this.diagnostics.record({ code: "outbox_key_collision" });
208
- return false;
196
+ return null;
209
197
  }
210
198
  this.drafts.push(draft);
211
- this.enforceCapacity();
212
199
  if (!this.writeRecord(key, draft)) {
213
200
  this.memoryOnly = true;
214
201
  this.warnDurableUnavailable();
215
202
  }
216
- return this.drafts.some((item) => item.eventId === draft.eventId);
217
- }
218
- estimatedDraftBytes(measure, metadata) {
219
- return measure(this.drafts.map((draft) => draft.event), metadata);
220
- }
221
- draftCount() {
222
- return this.drafts.length;
223
- }
224
- prepareFence(input) {
225
- const claimedEventKeyHashes = new Set(this.pending.flatMap((record) => record.eventKeyHashes));
226
- const candidates = this.drafts.filter((draft) => !claimedEventKeyHashes.has(draft.eventKeyHash) &&
227
- this.permits({
228
- generation: draft.collectionGeneration,
229
- permittedAtStart: draft.permittedAtStart,
230
- captureOrdinal: 0,
231
- }) &&
232
- (draft.origin !== "legacy_v1" ||
233
- hasLegacyTombstone(draft, this.tombstones)));
234
- let oversized = 0;
235
- let cursor = 0;
236
- let targetOrdinal = this.pending[this.pending.length - 1]?.ordinal ?? 0;
237
- while (cursor < candidates.length) {
238
- const remaining = candidates.slice(cursor);
239
- const metadata = input.createMetadata();
240
- const count = largestFittingPrefix(remaining, input.maxPayloadBytes, metadata, input.measure);
241
- if (count === 0) {
242
- const draft = remaining[0];
243
- if (draft) {
244
- this.removeDraft(draft);
245
- this.metrics?.increment("oversized_event_count");
246
- this.diagnostics.record({
247
- code: "event_oversize",
248
- event_fingerprint: this.diagnostics.eventFingerprint(canonicalJsonStringify(draft.event)),
249
- });
250
- }
251
- oversized += 1;
252
- cursor += 1;
253
- continue;
254
- }
255
- const selected = remaining.slice(0, count);
256
- const record = createPending({
203
+ return draft;
204
+ }
205
+ claimBatch(input) {
206
+ const held = this.pendingByBatchId.get(input.batchId);
207
+ if (held)
208
+ return { record: held, minted: false };
209
+ const drafts = input.eventKeys.flatMap((eventKey) => {
210
+ const draft = this.drafts.find((item) => item.eventKeyHash === eventKey);
211
+ return draft ? [draft] : [];
212
+ });
213
+ if (drafts.length !== input.eventKeys.length)
214
+ return null;
215
+ const record = createPending({
216
+ projectHash: this.projectHash,
217
+ metadata: input.createMetadata(),
218
+ drafts,
219
+ ordinal: this.nextOrdinal,
220
+ });
221
+ if (!this.writeRecord(pendingRecordKey(this.prefix, record.batchId), record))
222
+ return null;
223
+ this.nextOrdinal += 1;
224
+ this.pending.push(record);
225
+ this.pendingByBatchId.set(input.batchId, record);
226
+ for (const draft of drafts) {
227
+ this.removeRecord(draftRecordKey(this.prefix, draft.eventKeyHash));
228
+ }
229
+ this.drafts = this.drafts.filter((draft) => !drafts.includes(draft));
230
+ return { record, minted: true };
231
+ }
232
+ releaseBatch(batchId) {
233
+ const record = this.pendingByBatchId.get(batchId);
234
+ if (!record)
235
+ return;
236
+ this.pendingByBatchId.delete(batchId);
237
+ if (!this.removeClaimedDraftRecords(record))
238
+ return;
239
+ if (!this.removeRecord(pendingRecordKey(this.prefix, record.batchId)))
240
+ return;
241
+ this.pending = this.pending.filter((item) => item !== record);
242
+ }
243
+ reopenBatch(batchId) {
244
+ const record = this.pendingByBatchId.get(batchId);
245
+ if (!record)
246
+ return;
247
+ this.pendingByBatchId.delete(batchId);
248
+ this.pending = this.pending.filter((item) => item !== record);
249
+ this.removeRecord(pendingRecordKey(this.prefix, record.batchId));
250
+ for (const stored of record.events) {
251
+ const draft = createDraft({
252
+ event: stored.event,
253
+ permit: {
254
+ generation: record.collectionGeneration,
255
+ permittedAtStart: stored.permittedAtStart,
256
+ },
257
257
  projectHash: this.projectHash,
258
- metadata,
259
- drafts: selected,
260
- ordinal: this.nextOrdinal,
258
+ createdAt: nowIso(),
261
259
  });
262
- const key = pendingRecordKey(this.prefix, record.batchId);
263
- if (!this.writeRecord(key, record)) {
260
+ if (!draft)
261
+ continue;
262
+ this.drafts.push(draft);
263
+ if (!this.writeRecord(draftRecordKey(this.prefix, draft.eventKeyHash), draft)) {
264
264
  this.memoryOnly = true;
265
265
  this.warnDurableUnavailable();
266
- break;
267
- }
268
- this.pending.push(record);
269
- for (const draft of selected) {
270
- this.removeRecord(draftRecordKey(this.prefix, draft.eventKeyHash));
271
266
  }
272
- this.drafts = this.drafts.filter((draft) => !selected.includes(draft));
273
- targetOrdinal = record.ordinal;
274
- this.nextOrdinal += 1;
275
- cursor += count;
276
267
  }
277
- return { targetOrdinal, oversized };
278
268
  }
279
- headThrough(targetOrdinal) {
280
- const record = this.pending
281
- .sort((left, right) => left.ordinal - right.ordinal)
282
- .find((item) => item.ordinal <= targetOrdinal);
283
- if (!record)
284
- return null;
285
- return toHeadBatch(record, pendingRecordKey(this.prefix, record.batchId));
286
- }
287
- removeHead(expected) {
288
- const record = this.pending.find((item) => item.ordinal === expected.ordinal &&
289
- item.batchId === recordBatchId(expected));
290
- if (!record || !this.permitsBatch(expected))
291
- return false;
292
- const key = pendingRecordKey(this.prefix, record.batchId);
293
- if (record.kind === "pending" ||
294
- record.nextOrdinal === record.children.length - 1) {
295
- if (!this.removeClaimedDraftRecords(record))
296
- return false;
297
- if (!this.removeRecord(key))
298
- return false;
299
- this.pending = this.pending.filter((item) => item !== record);
300
- return true;
301
- }
302
- const progressed = withChecksum({
303
- ...withoutChecksum(record),
304
- nextOrdinal: record.nextOrdinal + 1,
305
- });
306
- if (!this.writeRecord(key, progressed))
307
- return false;
308
- this.pending = this.pending.map((item) => item === record ? progressed : item);
309
- return true;
310
- }
311
- retainHead(expected) {
312
- return (this.permitsBatch(expected) &&
313
- this.headThrough(expected.ordinal)?.recordKey === expected.recordKey);
314
- }
315
- splitHead(expected, createMetadata) {
316
- const record = this.pending.find((item) => item.ordinal === expected.ordinal &&
317
- item.batchId === recordBatchId(expected));
318
- if (!record)
319
- return false;
320
- const plan = splitPendingRecord(record, createMetadata);
321
- if (!plan)
322
- return false;
323
- const key = pendingRecordKey(this.prefix, record.batchId);
324
- if (!this.writeRecord(key, plan))
325
- return false;
326
- this.pending = this.pending.map((item) => (item === record ? plan : item));
327
- this.diagnostics.record({
328
- code: "batch_split",
329
- batch_fingerprint: expected.diagnosticCanonicalBytes
330
- ? this.diagnostics.batchFingerprint(expected.diagnosticCanonicalBytes)
331
- : undefined,
332
- });
333
- return true;
269
+ releaseEvents(eventKeys) {
270
+ for (const eventKey of eventKeys) {
271
+ this.removeRecord(draftRecordKey(this.prefix, eventKey));
272
+ }
273
+ this.drafts = this.drafts.filter((draft) => !eventKeys.includes(draft.eventKeyHash));
274
+ }
275
+ restorable() {
276
+ return {
277
+ batches: this.pending
278
+ .filter((record) => record.collectionGeneration === this.generation)
279
+ .map((record) => ({
280
+ ordinal: record.ordinal,
281
+ storedBatchId: record.batchId,
282
+ events: record.events.map((event) => ({
283
+ event_key: event.eventKeyHash,
284
+ byte_length: sentByteLength(event.event),
285
+ diagnostic_canonical_bytes: canonicalJsonStringify(event.event),
286
+ })),
287
+ })),
288
+ drafts: this.drafts.filter((draft) => draft.collectionGeneration === this.generation),
289
+ };
290
+ }
291
+ bindRestoredBatch(storedBatchId, batchId) {
292
+ const record = this.pending.find((item) => item.batchId === storedBatchId);
293
+ if (record)
294
+ this.pendingByBatchId.set(batchId, record);
334
295
  }
335
296
  clear() {
336
297
  let removed = true;
@@ -362,12 +323,6 @@ export class BrowserOutbox {
362
323
  pendingEventCount() {
363
324
  return outboxEventCount(this.drafts, this.pending);
364
325
  }
365
- pendingBytes() {
366
- return browserEventsByteLength([
367
- ...this.drafts.map((item) => item.event),
368
- ...this.pending.flatMap((item) => item.events.map((event) => event.event)),
369
- ]);
370
- }
371
326
  async withDeliveryLock(operation, options = {}) {
372
327
  const locks = readLocks();
373
328
  if (!locks) {
@@ -394,23 +349,6 @@ export class BrowserOutbox {
394
349
  }
395
350
  });
396
351
  }
397
- permitsBatch(batch) {
398
- return batch.events.every((event) => this.permits(event.permit));
399
- }
400
- resolvePermit(permit) {
401
- if (!permit.permittedAtStart || this.consent === "denied")
402
- return null;
403
- if (permit.generation === UNANCHORED_COLLECTION_GENERATION) {
404
- if (!this.consentAnchorEstablished)
405
- return null;
406
- return Object.freeze({
407
- generation: this.generation,
408
- permittedAtStart: true,
409
- captureOrdinal: permit.captureOrdinal,
410
- });
411
- }
412
- return this.permits(permit) ? permit : null;
413
- }
414
352
  initializeConsentForDelivery() {
415
353
  if (this.consentStateUnavailable) {
416
354
  this.consent = "denied";
@@ -441,50 +379,6 @@ export class BrowserOutbox {
441
379
  }
442
380
  this.restoreOutbox();
443
381
  }
444
- enforceCapacity() {
445
- while (this.pendingEventCount() > this.maxEvents ||
446
- this.pendingBytes() > this.maxBytes) {
447
- const dropped = this.drafts.shift();
448
- if (dropped) {
449
- this.removeRecord(draftRecordKey(this.prefix, dropped.eventKeyHash));
450
- this.metrics?.increment("dropped_count");
451
- this.diagnostics.record({
452
- code: "queue_overflow",
453
- event_fingerprint: this.diagnostics.eventFingerprint(canonicalJsonStringify(dropped.event)),
454
- });
455
- continue;
456
- }
457
- if (!this.dropOldestPendingForCapacity())
458
- return;
459
- }
460
- }
461
- dropOldestPendingForCapacity() {
462
- if (this.pending.length === 0)
463
- return false;
464
- const oldest = this.pending.reduce((oldestSoFar, item) => item.ordinal < oldestSoFar.ordinal ? item : oldestSoFar);
465
- const headBatch = toHeadBatch(oldest, pendingRecordKey(this.prefix, oldest.batchId));
466
- const droppedCount = oldest.events.length;
467
- this.forciblyRemovePendingRecord(oldest);
468
- if (droppedCount > 0) {
469
- this.metrics?.increment("dropped_count", droppedCount);
470
- }
471
- this.diagnostics.record({
472
- code: "queue_overflow",
473
- count: droppedCount,
474
- batch_fingerprint: headBatch
475
- ? this.diagnostics.batchFingerprint(headBatch.diagnosticCanonicalBytes)
476
- : undefined,
477
- });
478
- return true;
479
- }
480
- forciblyRemovePendingRecord(record) {
481
- let removed = this.removeClaimedDraftRecords(record);
482
- removed =
483
- this.removeRecord(pendingRecordKey(this.prefix, record.batchId)) &&
484
- removed;
485
- this.pending = this.pending.filter((item) => item !== record);
486
- return removed;
487
- }
488
382
  purgeAll() {
489
383
  const count = this.pendingEventCount();
490
384
  let removed = this.clear();
@@ -686,7 +580,7 @@ export class BrowserOutbox {
686
580
  const draft = existingDraft ??
687
581
  createDraft({
688
582
  event,
689
- permit: this.capturePermit(),
583
+ permit: { generation: this.generation, permittedAtStart: true },
690
584
  projectHash: this.projectHash,
691
585
  createdAt: nowIso(),
692
586
  origin: "legacy_v1",
@@ -807,12 +701,6 @@ export class BrowserOutbox {
807
701
  return false;
808
702
  }
809
703
  }
810
- removeDraft(draft) {
811
- if (!this.removeRecord(draftRecordKey(this.prefix, draft.eventKeyHash)))
812
- return false;
813
- this.drafts = this.drafts.filter((item) => item !== draft);
814
- return true;
815
- }
816
704
  removeClaimedDraftRecords(record) {
817
705
  let removed = true;
818
706
  for (const eventKeyHash of record.eventKeyHashes) {
@@ -1,15 +1,13 @@
1
1
  import type { InternalMetricsStore } from "../internal/metrics.js";
2
- import type { IngestUsageGovernorFeedback } from "../provider/types.js";
3
2
  import { type IngestRetryStrategy } from "./delivery-response.js";
4
3
  import type { DiagnosticStore } from "./diagnostics.js";
4
+ import type { TransportAbortCause, TransportOutcome, TransportRequest } from "./sdk-core-delivery.js";
5
+ import { type IngestEndpointDescription } from "./sdk-core-wasm.js";
5
6
  import { type BrowserSourceEvent } from "./source-event.js";
6
7
  export declare const CLUEBASE_SDK_REQUEST_HEADER = "x-cluebase-sdk-request";
7
8
  export declare const CLUEBASE_SDK_VERSION_HEADER = "x-cluebase-sdk-version";
8
9
  export declare const CLUEBASE_SOURCE_SCHEMA_VERSION_HEADER = "x-cluebase-source-schema-version";
9
10
  export declare const CLUEBASE_BROWSER_TOKEN_HEADER = "x-cluebase-browser-token";
10
- export declare const CANONICAL_BROWSER_INGEST_PATH = "/api/v1/ingest/browser";
11
- export declare const CANONICAL_BROWSER_TOKEN_PATH = "/api/v1/ingest/browser-tokens";
12
- export declare const resolveCanonicalIngestEndpoint: (endpoint: string) => string;
13
11
  export type IngestClientOptions = {
14
12
  endpoint: string;
15
13
  projectKey: string;
@@ -18,27 +16,14 @@ export type IngestClientOptions = {
18
16
  schemaVersion: number;
19
17
  metrics?: InternalMetricsStore;
20
18
  diagnostics?: DiagnosticStore;
19
+ onEndpointsResolved?: (endpoints: IngestEndpointDescription) => void;
21
20
  };
22
- export declare const resolveBrowserTokenEndpoint: (endpoint: string) => string;
23
- export type SendEventsOptions = {
24
- keepalive?: boolean;
25
- useBeacon?: boolean;
26
- signal?: AbortSignal;
27
- requireCachedBrowserToken?: boolean;
28
- maxPayloadBytes?: number;
29
- metadata?: BatchEnvelopeMetadata;
30
- deadlineAt?: number;
31
- };
32
- export type SendEventsResult = {
33
- ok: boolean;
34
- status: number | null;
35
- attempts: number;
36
- governor: IngestUsageGovernorFeedback | null;
37
- retryStrategy: IngestRetryStrategy | null;
38
- observationIngestBatchId?: string;
39
- partial?: boolean;
40
- droppedEventCount?: number;
41
- reason?: string | null;
21
+ export type DeliveryTokenResult = {
22
+ readonly ok: true;
23
+ readonly token: string;
24
+ } | {
25
+ readonly ok: false;
26
+ readonly retryStrategy?: IngestRetryStrategy;
42
27
  };
43
28
  export type BatchEnvelopeMetadata = {
44
29
  batch_id: string;
@@ -47,30 +32,35 @@ export type BatchEnvelopeMetadata = {
47
32
  };
48
33
  export type { IngestRetryStrategy } from "./delivery-response.js";
49
34
  export declare class IngestClient {
50
- private readonly endpoint;
51
- private readonly browserTokenEndpoint;
35
+ private readonly configuredEndpoint;
36
+ private describedEndpoint;
37
+ private describePromise;
52
38
  private readonly projectKey;
53
- private readonly sourceIdentifier;
54
39
  private readonly producerId;
55
40
  private readonly sdkType;
56
41
  private readonly sdkVersion;
57
42
  private readonly schemaVersion;
58
43
  private readonly metrics;
59
44
  private readonly diagnostics;
45
+ private readonly onEndpointsResolved;
60
46
  private cachedToken;
61
47
  private pendingTokenRequest;
48
+ private inFlight;
62
49
  constructor(options: IngestClientOptions);
63
- send(events: BrowserSourceEvent[], options?: SendEventsOptions): Promise<SendEventsResult>;
50
+ private endpoints;
51
+ knownEndpoints(): IngestEndpointDescription | null;
52
+ perform(request: TransportRequest): Promise<TransportOutcome>;
53
+ abortAttempt(cause: TransportAbortCause): void;
64
54
  measurePayloadBytes(events: BrowserSourceEvent[], metadata?: BatchEnvelopeMetadata): number;
65
- private stringifyPayload;
66
- private withSourceEvidence;
55
+ stringifyPayload(events: BrowserSourceEvent[], metadata: BatchEnvelopeMetadata): string;
67
56
  createBatchEnvelopeMetadata(): BatchEnvelopeMetadata;
57
+ diagnosticCanonicalPayload(payload: string): string;
58
+ ensureDeliveryToken(options?: {
59
+ readonly requireCachedToken?: boolean;
60
+ readonly signal?: AbortSignal;
61
+ }): Promise<DeliveryTokenResult>;
68
62
  hasUsableBrowserToken(nowMs?: number): boolean;
69
63
  warmupBrowserToken(signal?: AbortSignal): Promise<boolean>;
70
- private failedSend;
71
- private recordDecision;
72
- private postBatch;
73
- private createId;
74
64
  private getUsableCachedBrowserToken;
75
65
  private ensureBrowserToken;
76
66
  private safeEnsureBrowserToken;