@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.
- package/dist/_generated/correlation-attribute-keys.d.ts +3 -0
- package/dist/_generated/correlation-attribute-keys.js +35 -0
- package/dist/_generated/diagnostic-codes.d.ts +4 -0
- package/dist/_generated/diagnostic-codes.js +48 -0
- package/dist/_generated/drop-reasons.d.ts +2 -0
- package/dist/_generated/drop-reasons.js +25 -0
- package/dist/_generated/ingest-routes.d.ts +5 -0
- package/dist/_generated/ingest-routes.js +12 -0
- package/dist/context/trace.js +2 -4
- package/dist/exporter/batch.d.ts +23 -26
- package/dist/exporter/batch.js +254 -289
- package/dist/exporter/browser-outbox-records.d.ts +7 -24
- package/dist/exporter/browser-outbox-records.js +6 -94
- package/dist/exporter/browser-outbox.d.ts +23 -28
- package/dist/exporter/browser-outbox.js +99 -211
- package/dist/exporter/client.d.ts +24 -34
- package/dist/exporter/client.js +107 -318
- package/dist/exporter/delivery-pipeline.d.ts +72 -0
- package/dist/exporter/delivery-pipeline.js +199 -0
- package/dist/exporter/delivery-response-contract.d.ts +5 -81
- package/dist/exporter/delivery-response-contract.js +4 -166
- package/dist/exporter/delivery-response.d.ts +8 -4
- package/dist/exporter/delivery-response.js +62 -133
- package/dist/exporter/diagnostics.d.ts +2 -1
- package/dist/exporter/diagnostics.js +1 -25
- package/dist/exporter/event-id.d.ts +1 -0
- package/dist/exporter/event-id.js +3 -0
- package/dist/exporter/observation-source-event-exporter.d.ts +1 -1
- package/dist/exporter/observation-source-event-exporter.js +2 -2
- package/dist/exporter/parameter-encryption.d.ts +10 -0
- package/dist/exporter/parameter-encryption.js +219 -0
- package/dist/exporter/parameter-snapshot.js +25 -3
- package/dist/exporter/sdk-core-delivery.d.ts +226 -0
- package/dist/exporter/sdk-core-delivery.js +97 -0
- package/dist/exporter/sdk-core-wasm.d.ts +24 -1
- package/dist/exporter/sdk-core-wasm.js +31 -3
- package/dist/exporter/source-event.d.ts +2 -0
- package/dist/exporter/source-event.js +17 -0
- package/dist/exporter/span-to-source-signal.d.ts +1 -1
- package/dist/exporter/span-to-source-signal.js +20 -140
- package/dist/index.d.ts +3 -3
- package/dist/index.js +5 -3
- package/dist/instrumentation/network.d.ts +1 -1
- package/dist/instrumentation/network.js +17 -0
- package/dist/provider/_version.d.ts +1 -1
- package/dist/provider/_version.js +1 -1
- package/dist/provider/config.js +16 -3
- package/dist/provider/constants.js +0 -1
- package/dist/provider/contracts.d.ts +2 -0
- package/dist/provider/contracts.js +2 -0
- package/dist/provider/lifecycle-event-dedup.d.ts +7 -0
- package/dist/provider/lifecycle-event-dedup.js +31 -0
- package/dist/provider/sdk-encryption-store.d.ts +7 -0
- package/dist/provider/sdk-encryption-store.js +15 -0
- package/dist/provider/sdk-event-pipeline.d.ts +1 -3
- package/dist/provider/sdk-event-pipeline.js +0 -15
- package/dist/provider/sdk-otel-pipeline.d.ts +2 -1
- package/dist/provider/sdk-otel-pipeline.js +2 -11
- package/dist/provider/sdk-runtime-surfaces.d.ts +3 -2
- package/dist/provider/sdk-runtime-surfaces.js +7 -6
- package/dist/provider/sdk.js +88 -54
- package/dist/provider/types.d.ts +14 -19
- package/dist/wasm/pkg-web/cluebase_sdk_core_wasm.d.ts +18 -9
- package/dist/wasm/pkg-web/cluebase_sdk_core_wasm.js +170 -29
- package/dist/wasm/pkg-web/cluebase_sdk_core_wasm_bg.wasm +0 -0
- package/dist/wasm/pkg-web/cluebase_sdk_core_wasm_bg.wasm.d.ts +10 -9
- package/package.json +1 -1
- package/dist/provider/usage-governor.d.ts +0 -7
- package/dist/provider/usage-governor.js +0 -114
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { canonicalize as canonicalJsonStringify } from "json-canonicalize";
|
|
2
|
-
import { addStorageListener,
|
|
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
|
-
|
|
55
|
-
return
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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:
|
|
182
|
+
permit: { generation: this.generation, permittedAtStart: true },
|
|
195
183
|
projectHash: this.projectHash,
|
|
196
184
|
createdAt: nowIso(),
|
|
197
185
|
});
|
|
198
186
|
if (!draft)
|
|
199
|
-
return
|
|
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
|
|
193
|
+
return draft;
|
|
206
194
|
}
|
|
207
195
|
this.diagnostics.record({ code: "outbox_key_collision" });
|
|
208
|
-
return
|
|
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
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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
|
-
|
|
259
|
-
drafts: selected,
|
|
260
|
-
ordinal: this.nextOrdinal,
|
|
258
|
+
createdAt: nowIso(),
|
|
261
259
|
});
|
|
262
|
-
|
|
263
|
-
|
|
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
|
-
|
|
280
|
-
const
|
|
281
|
-
.
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
const
|
|
303
|
-
|
|
304
|
-
|
|
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.
|
|
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
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
|
51
|
-
private
|
|
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
|
-
|
|
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
|
-
|
|
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;
|