@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
|
@@ -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:
|
|
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
|
|
126
|
-
export declare const
|
|
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
|
|
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
|
|
75
|
-
|
|
76
|
-
|
|
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:
|
|
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
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
|
72
|
-
readonly
|
|
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
|
-
|
|
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;
|