@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
@@ -4,27 +4,11 @@ import { type BrowserSourceEvent } from "./source-event.js";
4
4
  export type StorageLike = Pick<Storage, "getItem" | "setItem" | "removeItem" | "key"> & {
5
5
  readonly length: number;
6
6
  };
7
- export type CollectionPermit = {
8
- readonly generation: string;
9
- readonly permittedAtStart: boolean;
10
- readonly captureOrdinal: number;
11
- };
12
7
  export type OwnedBrowserEvent = {
13
8
  readonly byteLength: number;
14
- readonly permit: CollectionPermit;
15
9
  readonly diagnosticCanonicalBytes: string;
16
10
  value(): BrowserSourceEvent;
17
11
  };
18
- export type PendingBrowserBatch = {
19
- readonly events: readonly OwnedBrowserEvent[];
20
- readonly metadata: BatchEnvelopeMetadata;
21
- readonly generation: string;
22
- readonly ordinal: number;
23
- readonly diagnosticCanonicalBytes: string;
24
- readonly recordKey: string;
25
- readonly ownerBatchId: string;
26
- readonly planOrdinal: number | null;
27
- };
28
12
  type RecordBase = {
29
13
  readonly storageVersion: 2;
30
14
  readonly projectHash: string;
@@ -98,9 +82,13 @@ export type PendingRecordLike = PendingRecord | SplitPlanRecord;
98
82
  type StoredWithoutChecksum = Omit<OutboxRecord, "checksumSha256">;
99
83
  export declare const UNANCHORED_COLLECTION_GENERATION = "__cluebase_unanchored_generation__";
100
84
  export declare const LEGACY_TOMBSTONE_LIMIT = 10000;
85
+ export type DraftPermit = {
86
+ readonly generation: string;
87
+ readonly permittedAtStart: boolean;
88
+ };
101
89
  export declare const createDraft: (input: {
102
90
  readonly event: BrowserSourceEvent;
103
- readonly permit: CollectionPermit;
91
+ readonly permit: DraftPermit;
104
92
  readonly projectHash: string;
105
93
  readonly createdAt: string;
106
94
  readonly origin?: "v2" | "legacy_v1";
@@ -122,13 +110,8 @@ export declare const createPending: (input: {
122
110
  readonly drafts: readonly DraftRecord[];
123
111
  readonly ordinal: number;
124
112
  }) => PendingRecord;
125
- export declare const toPendingBatch: (record: PendingRecordLike, recordKey: string, events: readonly OwnedStoredEvent[], metadata: BatchEnvelopeMetadata, planOrdinal: number | null) => PendingBrowserBatch;
126
- export declare const toHeadBatch: (record: PendingRecordLike, recordKey: string) => PendingBrowserBatch | null;
127
- export declare const splitPendingRecord: (record: PendingRecordLike, createMetadata: () => BatchEnvelopeMetadata) => SplitPlanRecord | null;
128
- export declare const largestFittingPrefix: (drafts: readonly DraftRecord[], maxBytes: number, metadata: BatchEnvelopeMetadata, measure: (events: readonly BrowserSourceEvent[], metadata: BatchEnvelopeMetadata) => number) => number;
129
- export declare const ownEvent: (event: BrowserSourceEvent, permit: CollectionPermit) => OwnedBrowserEvent | null;
130
- export declare const isOwnedEvent: (value: OwnedBrowserEvent | null) => value is OwnedBrowserEvent;
131
- export declare const recordBatchId: (batch: PendingBrowserBatch) => string;
113
+ export declare const sentByteLength: (event: BrowserSourceEvent) => number;
114
+ export declare const ownEvent: (event: BrowserSourceEvent) => OwnedBrowserEvent | null;
132
115
  export declare const withChecksum: <T extends StoredWithoutChecksum>(record: T) => T & {
133
116
  readonly checksumSha256: string;
134
117
  };
@@ -1,11 +1,11 @@
1
1
  import { sha256 } from "@noble/hashes/sha256";
2
2
  import { bytesToHex, utf8ToBytes } from "@noble/hashes/utils";
3
3
  import { canonicalize as canonicalJsonStringify } from "json-canonicalize";
4
- import { isBrowserSourceSignalEvent, } from "./source-event.js";
4
+ import { isBrowserSourceSignalEvent, withSourceEvidence, } from "./source-event.js";
5
5
  export const UNANCHORED_COLLECTION_GENERATION = "__cluebase_unanchored_generation__";
6
6
  export const LEGACY_TOMBSTONE_LIMIT = 10000;
7
7
  export const createDraft = (input) => {
8
- const owned = ownEvent(input.event, input.permit);
8
+ const owned = ownEvent(input.event);
9
9
  if (!owned)
10
10
  return null;
11
11
  const event = owned.value();
@@ -71,102 +71,16 @@ export const createPending = (input) => {
71
71
  ordinal: input.ordinal,
72
72
  });
73
73
  };
74
- export const toPendingBatch = (record, recordKey, events, metadata, planOrdinal) => {
75
- const owned = events
76
- .map((event) => ownEvent(event.event, {
77
- generation: record.collectionGeneration,
78
- permittedAtStart: event.permittedAtStart,
79
- captureOrdinal: 0,
80
- }))
81
- .filter(isOwnedEvent);
82
- return Object.freeze({
83
- events: Object.freeze(owned),
84
- metadata: Object.freeze({ ...metadata }),
85
- generation: record.collectionGeneration,
86
- ordinal: record.ordinal,
87
- diagnosticCanonicalBytes: canonicalJsonStringify({
88
- sourceType: "frontend_sdk",
89
- sourceSchemaVersion: "1",
90
- batchId: metadata.batch_id,
91
- idempotencyKey: metadata.idempotency_key,
92
- sentAt: metadata.sent_at,
93
- events: owned.map((event) => event.value()),
94
- }),
95
- recordKey,
96
- ownerBatchId: record.batchId,
97
- planOrdinal,
98
- });
99
- };
100
- export const toHeadBatch = (record, recordKey) => {
101
- if (record.kind === "pending") {
102
- return toPendingBatch(record, recordKey, record.events, {
103
- batch_id: record.batchId,
104
- idempotency_key: record.idempotencyKey,
105
- sent_at: record.sentAt,
106
- }, null);
107
- }
108
- const child = record.children[record.nextOrdinal];
109
- if (!child)
110
- return null;
111
- return toPendingBatch(record, recordKey, record.events.slice(child.start, child.end), child.metadata, record.nextOrdinal);
112
- };
113
- export const splitPendingRecord = (record, createMetadata) => {
114
- const child = record.kind === "pending"
115
- ? {
116
- start: 0,
117
- end: record.events.length,
118
- metadata: {
119
- batch_id: record.batchId,
120
- idempotency_key: record.idempotencyKey,
121
- sent_at: record.sentAt,
122
- },
123
- }
124
- : record.children[record.nextOrdinal];
125
- if (!child || child.end - child.start < 2)
126
- return null;
127
- const boundary = child.start + Math.ceil((child.end - child.start) / 2);
128
- const replacements = [
129
- { start: child.start, end: boundary, metadata: createMetadata() },
130
- { start: boundary, end: child.end, metadata: createMetadata() },
131
- ];
132
- return withChecksum({
133
- ...withoutChecksum(record),
134
- kind: "split_plan",
135
- children: record.kind === "pending"
136
- ? replacements
137
- : [
138
- ...record.children.slice(0, record.nextOrdinal),
139
- ...replacements,
140
- ...record.children.slice(record.nextOrdinal + 1),
141
- ],
142
- nextOrdinal: record.kind === "pending" ? 0 : record.nextOrdinal,
143
- });
144
- };
145
- export const largestFittingPrefix = (drafts, maxBytes, metadata, measure) => {
146
- let low = 1;
147
- let high = drafts.length;
148
- let largest = 0;
149
- while (low <= high) {
150
- const count = Math.floor((low + high) / 2);
151
- if (measure(drafts.slice(0, count).map((draft) => draft.event), metadata) <= maxBytes) {
152
- largest = count;
153
- low = count + 1;
154
- }
155
- else {
156
- high = count - 1;
157
- }
158
- }
159
- return largest;
160
- };
161
- export const ownEvent = (event, permit) => {
74
+ export const sentByteLength = (event) => new TextEncoder().encode(JSON.stringify(withSourceEvidence(event)))
75
+ .byteLength;
76
+ export const ownEvent = (event) => {
162
77
  try {
163
78
  const json = JSON.stringify(event);
164
79
  const parsed = JSON.parse(json);
165
80
  if (!isBrowserSourceSignalEvent(parsed))
166
81
  return null;
167
82
  return Object.freeze({
168
- byteLength: new TextEncoder().encode(json).byteLength,
169
- permit: Object.freeze({ ...permit }),
83
+ byteLength: sentByteLength(parsed),
170
84
  diagnosticCanonicalBytes: canonicalJsonStringify(parsed),
171
85
  value: () => JSON.parse(json),
172
86
  });
@@ -175,8 +89,6 @@ export const ownEvent = (event, permit) => {
175
89
  return null;
176
90
  }
177
91
  };
178
- export const isOwnedEvent = (value) => value !== null;
179
- export const recordBatchId = (batch) => batch.ownerBatchId;
180
92
  export const withChecksum = (record) => ({
181
93
  ...record,
182
94
  checksumSha256: sha256Hex(canonicalJsonStringify(record)),
@@ -1,10 +1,11 @@
1
1
  import type { InternalMetricsStore } from "../internal/metrics.js";
2
2
  import type { CluebaseConsentState } from "../provider/types.js";
3
- import { type CollectionPermit, type PendingBrowserBatch, type StorageLike } from "./browser-outbox-records.js";
3
+ import { type DraftRecord, type PendingRecordLike, type StorageLike } from "./browser-outbox-records.js";
4
4
  import type { BatchEnvelopeMetadata } from "./client.js";
5
5
  import { DiagnosticStore } from "./diagnostics.js";
6
+ import type { RestoredEvent } from "./sdk-core-delivery.js";
6
7
  import type { BrowserSourceEvent } from "./source-event.js";
7
- export type { CollectionPermit, OwnedBrowserEvent, PendingBrowserBatch, } from "./browser-outbox-records.js";
8
+ export type { OwnedBrowserEvent } from "./browser-outbox-records.js";
8
9
  export type ConsentTransition = {
9
10
  readonly state: CluebaseConsentState;
10
11
  readonly generation: string;
@@ -21,17 +22,15 @@ export declare class BrowserOutbox {
21
22
  private readonly lockName;
22
23
  private readonly storage;
23
24
  private readonly durableOutboxSupported;
24
- private readonly maxBytes;
25
- private readonly maxEvents;
26
25
  private readonly metrics;
27
26
  private readonly diagnostics;
28
27
  private drafts;
29
28
  private pending;
29
+ private readonly pendingByBatchId;
30
30
  private tombstones;
31
31
  private nextOrdinal;
32
32
  private consent;
33
33
  private generation;
34
- private nextPermitOrdinal;
35
34
  private legacyImportBlocked;
36
35
  private consentAnchorEstablished;
37
36
  private initialDenialPending;
@@ -47,47 +46,44 @@ export declare class BrowserOutbox {
47
46
  constructor(options: {
48
47
  readonly projectKey: string;
49
48
  readonly initialConsent: CluebaseConsentState;
50
- readonly maxBytes: number;
51
- readonly maxEvents: number;
52
49
  readonly metrics?: InternalMetricsStore;
53
50
  readonly diagnostics?: DiagnosticStore;
54
51
  readonly storage?: StorageLike | null;
55
52
  readonly onConsentRevoked?: () => void;
56
53
  });
57
54
  currentConsent(): CluebaseConsentState;
58
- capturePermit(): CollectionPermit;
59
- permits(permit: CollectionPermit): boolean;
55
+ collectionGeneration(): string;
60
56
  setConsent(next: CluebaseConsentState): ConsentTransition;
61
57
  commitConsentTransition(transition: ConsentTransition): void;
62
58
  private persistCommittedConsent;
63
- addDraft(event: BrowserSourceEvent, permit?: CollectionPermit): boolean;
64
- estimatedDraftBytes(measure: (events: readonly BrowserSourceEvent[], metadata: BatchEnvelopeMetadata) => number, metadata: BatchEnvelopeMetadata): number;
65
- draftCount(): number;
66
- prepareFence(input: {
67
- readonly maxPayloadBytes: number;
59
+ holdDraft(event: BrowserSourceEvent): DraftRecord | null;
60
+ claimBatch(input: {
61
+ readonly batchId: number;
62
+ readonly eventKeys: readonly string[];
68
63
  readonly createMetadata: () => BatchEnvelopeMetadata;
69
- readonly measure: (events: readonly BrowserSourceEvent[], metadata: BatchEnvelopeMetadata) => number;
70
64
  }): {
71
- readonly targetOrdinal: number;
72
- readonly oversized: number;
65
+ readonly record: PendingRecordLike;
66
+ readonly minted: boolean;
67
+ } | null;
68
+ releaseBatch(batchId: number): void;
69
+ reopenBatch(batchId: number): void;
70
+ releaseEvents(eventKeys: readonly string[]): void;
71
+ restorable(): {
72
+ readonly batches: readonly {
73
+ readonly ordinal: number;
74
+ readonly storedBatchId: string;
75
+ readonly events: readonly RestoredEvent[];
76
+ }[];
77
+ readonly drafts: readonly DraftRecord[];
73
78
  };
74
- headThrough(targetOrdinal: number): PendingBrowserBatch | null;
75
- removeHead(expected: PendingBrowserBatch): boolean;
76
- retainHead(expected: PendingBrowserBatch): boolean;
77
- splitHead(expected: PendingBrowserBatch, createMetadata: () => BatchEnvelopeMetadata): boolean;
79
+ bindRestoredBatch(storedBatchId: string, batchId: number): void;
78
80
  clear(): boolean;
79
81
  close(): void;
80
82
  pendingEventCount(): number;
81
- pendingBytes(): number;
82
83
  withDeliveryLock<T>(operation: () => Promise<T>, options?: {
83
84
  readonly restore?: boolean;
84
85
  }): Promise<T>;
85
- private permitsBatch;
86
- private resolvePermit;
87
86
  private initializeConsentForDelivery;
88
- private enforceCapacity;
89
- private dropOldestPendingForCapacity;
90
- private forciblyRemovePendingRecord;
91
87
  private purgeAll;
92
88
  clearMemory(): void;
93
89
  private restore;
@@ -104,7 +100,6 @@ export declare class BrowserOutbox {
104
100
  private persistConsent;
105
101
  private writeRecord;
106
102
  private removeRecord;
107
- private removeDraft;
108
103
  private removeClaimedDraftRecords;
109
104
  private readRecord;
110
105
  private failClosedConsentState;