@genn-inc/cluebase-frontend-sdk 0.0.3 → 0.0.8
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/README.md +21 -0
- package/dist/_generated/correlation-attribute-keys.d.ts +3 -0
- package/dist/_generated/correlation-attribute-keys.js +34 -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/{identity-pii-policy.d.ts → identity-pii-policy-text-contains.d.ts} +1 -1
- package/dist/_generated/{identity-pii-policy.js → identity-pii-policy-text-contains.js} +1 -1
- package/dist/_generated/identity-pii-policy-whole-value.d.ts +37 -0
- package/dist/_generated/identity-pii-policy-whole-value.js +106 -0
- package/dist/_generated/ingest-routes.d.ts +5 -0
- package/dist/_generated/ingest-routes.js +12 -0
- package/dist/_generated/otel-span-conversion.js +1 -9
- package/dist/context/browser-storage.js +1 -2
- package/dist/context/environment.js +5 -3
- package/dist/context/identity.js +5 -9
- package/dist/context/organization.d.ts +1 -1
- package/dist/context/organization.js +6 -8
- package/dist/context/session.js +6 -8
- package/dist/context/tab.js +8 -12
- package/dist/context/trace.js +4 -5
- package/dist/exporter/batch.d.ts +26 -27
- package/dist/exporter/batch.js +248 -294
- package/dist/exporter/browser-outbox-records.d.ts +8 -25
- package/dist/exporter/browser-outbox-records.js +21 -100
- package/dist/exporter/browser-outbox.d.ts +23 -25
- package/dist/exporter/browser-outbox.js +106 -181
- package/dist/exporter/client.d.ts +25 -35
- package/dist/exporter/client.js +107 -335
- package/dist/exporter/delivery-pipeline.d.ts +71 -0
- package/dist/exporter/delivery-pipeline.js +196 -0
- package/dist/exporter/delivery-response-contract.d.ts +1 -81
- package/dist/exporter/delivery-response-contract.js +0 -118
- package/dist/exporter/delivery-response.d.ts +9 -4
- package/dist/exporter/delivery-response.js +59 -122
- package/dist/exporter/diagnostics.d.ts +3 -2
- package/dist/exporter/diagnostics.js +5 -26
- package/dist/exporter/event-id.d.ts +1 -0
- package/dist/exporter/event-id.js +4 -3
- package/dist/exporter/frontend-resource.js +5 -4
- package/dist/exporter/observation-source-event-exporter.d.ts +2 -1
- package/dist/exporter/observation-source-event-exporter.js +7 -4
- package/dist/exporter/path-template.js +3 -1
- package/dist/exporter/raw-event-to-source-signal.js +4 -2
- package/dist/exporter/sanitize.d.ts +3 -2
- package/dist/exporter/sanitize.js +4 -3
- package/dist/exporter/sdk-core-delivery.d.ts +225 -0
- package/dist/exporter/sdk-core-delivery.js +97 -0
- package/dist/exporter/sdk-core-wasm.d.ts +11 -0
- package/dist/exporter/sdk-core-wasm.js +39 -0
- package/dist/exporter/source-event.d.ts +3 -0
- package/dist/exporter/source-event.js +17 -0
- package/dist/exporter/span-to-source-signal.d.ts +2 -2
- package/dist/exporter/span-to-source-signal.js +45 -125
- package/dist/index.d.ts +5 -4
- package/dist/index.js +18 -6
- package/dist/instrumentation/action.js +9 -8
- package/dist/instrumentation/dom.js +13 -21
- package/dist/instrumentation/drag.js +0 -3
- package/dist/instrumentation/error.js +3 -1
- package/dist/instrumentation/form.js +5 -6
- package/dist/instrumentation/input.js +4 -8
- package/dist/instrumentation/location.js +3 -1
- package/dist/instrumentation/network-request.js +1 -1
- package/dist/instrumentation/network-span-attributes.js +2 -2
- package/dist/instrumentation/network.d.ts +1 -1
- package/dist/instrumentation/network.js +24 -3
- package/dist/instrumentation/performance.js +1 -2
- package/dist/internal/internal-log.js +2 -1
- package/dist/provider/_version.d.ts +1 -1
- package/dist/provider/_version.js +1 -1
- package/dist/provider/config.js +16 -4
- package/dist/provider/constants.d.ts +1 -1
- package/dist/provider/constants.js +0 -2
- package/dist/provider/lifecycle-event-dedup.d.ts +7 -0
- package/dist/provider/lifecycle-event-dedup.js +31 -0
- package/dist/provider/sdk-event-pipeline.d.ts +3 -4
- package/dist/provider/sdk-event-pipeline.js +5 -17
- package/dist/provider/sdk-input-normalization.js +2 -2
- package/dist/provider/sdk-otel-pipeline.d.ts +2 -1
- package/dist/provider/sdk-otel-pipeline.js +7 -15
- package/dist/provider/sdk-runtime-surfaces.d.ts +17 -13
- package/dist/provider/sdk-runtime-surfaces.js +15 -13
- package/dist/provider/sdk.js +137 -48
- package/dist/provider/types.d.ts +18 -24
- package/dist/wasm/pkg-web/cluebase_sdk_core_wasm.d.ts +44 -0
- package/dist/wasm/pkg-web/cluebase_sdk_core_wasm.js +355 -0
- 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 +11 -0
- package/dist/wasm/pkg-web/package.json +15 -0
- package/package.json +62 -53
- package/dist/provider/usage-governor.d.ts +0 -7
- package/dist/provider/usage-governor.js +0 -114
package/dist/provider/sdk.js
CHANGED
|
@@ -7,15 +7,17 @@ import { TraceManager } from "../context/trace.js";
|
|
|
7
7
|
import { BatchTransport } from "../exporter/batch.js";
|
|
8
8
|
import { IngestClient } from "../exporter/client.js";
|
|
9
9
|
import { DiagnosticStore } from "../exporter/diagnostics.js";
|
|
10
|
-
import {
|
|
10
|
+
import { detectWholeValuePII, hashIdentityValue, isDeniedKey, } from "../exporter/sanitize.js";
|
|
11
|
+
import { initSdkCoreWasm } from "../exporter/sdk-core-wasm.js";
|
|
11
12
|
import { InternalMetricsStore } from "../internal/metrics.js";
|
|
12
13
|
import { isConfigValid, resolveConfig, validateConfig } from "./config.js";
|
|
13
14
|
import { DEFAULT_BATCH_FLUSH_THRESHOLD_BYTES, DEFAULT_CONSENT, DEFAULT_MAX_BATCH_QUEUE_BYTES, DEFAULT_MAX_BATCH_QUEUE_ITEMS, SDK_VERSION, } from "./constants.js";
|
|
14
|
-
import {
|
|
15
|
+
import { LifecycleEventDedup } from "./lifecycle-event-dedup.js";
|
|
16
|
+
import { getSdkErrorDetails, reportSdkError } from "./sdk-error.js";
|
|
15
17
|
import { OFFICIAL_CUSTOM_EVENT_NAME, ProviderEventPipeline, readCurrentLifecycleUrl, } from "./sdk-event-pipeline.js";
|
|
18
|
+
import { isValidPublicCustomEventName, normalizeProfileAvatarUrl, normalizePublicIdentityId, toStringOrNull, } from "./sdk-input-normalization.js";
|
|
16
19
|
import { createCluebaseOtelPipeline, forceFlushCluebaseOtelProvider, shutdownCluebaseOtelProvider, shutdownCluebaseOtelProviderAsync, } from "./sdk-otel-pipeline.js";
|
|
17
20
|
import { ProviderRuntimeSurfaces } from "./sdk-runtime-surfaces.js";
|
|
18
|
-
import { getSdkErrorDetails, reportSdkError } from "./sdk-error.js";
|
|
19
21
|
const createNoopLogger = () => {
|
|
20
22
|
return {
|
|
21
23
|
debug: () => undefined,
|
|
@@ -47,6 +49,8 @@ class CluebaseBrowserSdkImpl {
|
|
|
47
49
|
this.environmentManager = null;
|
|
48
50
|
this.traceManager = null;
|
|
49
51
|
this.diagnostics = new DiagnosticStore();
|
|
52
|
+
this.lifecycleDedup = new LifecycleEventDedup();
|
|
53
|
+
this.ingestUrlPrefixes = [];
|
|
50
54
|
this.transport = null;
|
|
51
55
|
this.tracerProvider = null;
|
|
52
56
|
this.logger = logger;
|
|
@@ -58,9 +62,8 @@ class CluebaseBrowserSdkImpl {
|
|
|
58
62
|
enqueueRawEvent: (event) => {
|
|
59
63
|
this.enqueueRawEvent(event);
|
|
60
64
|
},
|
|
61
|
-
|
|
65
|
+
eventPipeline: this.eventPipeline,
|
|
62
66
|
getConsent: () => this.consent,
|
|
63
|
-
getObservationContext: () => this.eventPipeline.getObservationContext(),
|
|
64
67
|
getTraceManager: () => this.traceManager,
|
|
65
68
|
getTransport: () => this.transport,
|
|
66
69
|
getTracerProvider: () => this.tracerProvider,
|
|
@@ -72,6 +75,19 @@ class CluebaseBrowserSdkImpl {
|
|
|
72
75
|
getDiagnostics() {
|
|
73
76
|
return this.diagnostics.snapshot();
|
|
74
77
|
}
|
|
78
|
+
withActionContext(callback) {
|
|
79
|
+
let snapshot = null;
|
|
80
|
+
try {
|
|
81
|
+
snapshot = this.traceManager?.getCurrentActionContext() ?? null;
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
reportSdkError("withActionContext", error);
|
|
85
|
+
}
|
|
86
|
+
if (!snapshot || !this.traceManager) {
|
|
87
|
+
return callback();
|
|
88
|
+
}
|
|
89
|
+
return this.traceManager.runWithActionContext(snapshot, callback);
|
|
90
|
+
}
|
|
75
91
|
init(options) {
|
|
76
92
|
try {
|
|
77
93
|
const resolved = resolveConfig(options);
|
|
@@ -86,10 +102,8 @@ class CluebaseBrowserSdkImpl {
|
|
|
86
102
|
const nextSignature = JSON.stringify({
|
|
87
103
|
endpoint: resolved.endpoint,
|
|
88
104
|
originalEndpoint: resolved.originalEndpoint,
|
|
89
|
-
localSetupCheckEndpoint: resolved.localSetupCheckEndpoint,
|
|
90
105
|
projectKey: resolved.projectKey,
|
|
91
106
|
producerId: resolved.producerId,
|
|
92
|
-
transportProfile: resolved.transportProfile,
|
|
93
107
|
autocapture: resolved.autocapture,
|
|
94
108
|
captureNetwork: resolved.captureNetwork,
|
|
95
109
|
captureErrors: resolved.captureErrors,
|
|
@@ -110,6 +124,7 @@ class CluebaseBrowserSdkImpl {
|
|
|
110
124
|
this.shutdown();
|
|
111
125
|
this.internalMetrics.reset();
|
|
112
126
|
this.diagnostics = new DiagnosticStore();
|
|
127
|
+
this.lifecycleDedup.clear();
|
|
113
128
|
this.config = resolved;
|
|
114
129
|
this.initSignature = nextSignature;
|
|
115
130
|
this.identityManager = new IdentityManager();
|
|
@@ -131,22 +146,27 @@ class CluebaseBrowserSdkImpl {
|
|
|
131
146
|
schemaVersion: 1,
|
|
132
147
|
metrics: this.internalMetrics,
|
|
133
148
|
diagnostics: this.diagnostics,
|
|
149
|
+
onEndpointsResolved: (endpoints) => {
|
|
150
|
+
this.adoptIngestUrlPrefixes(endpoints);
|
|
151
|
+
},
|
|
134
152
|
});
|
|
135
153
|
this.transport = new BatchTransport({
|
|
136
154
|
client: ingestClient,
|
|
137
155
|
enabled: effectiveBatch.enabled,
|
|
138
156
|
flushIntervalMs: effectiveBatch.flushIntervalMs,
|
|
157
|
+
maxSize: effectiveBatch.maxSize,
|
|
139
158
|
maxPayloadBytes: effectiveBatch.maxPayloadBytes,
|
|
140
159
|
flushThresholdBytes: DEFAULT_BATCH_FLUSH_THRESHOLD_BYTES,
|
|
141
160
|
queueMaxBytes: DEFAULT_MAX_BATCH_QUEUE_BYTES,
|
|
142
161
|
queueMaxItems: DEFAULT_MAX_BATCH_QUEUE_ITEMS,
|
|
143
162
|
projectKey: resolved.projectKey,
|
|
163
|
+
endpoint: resolved.endpoint,
|
|
164
|
+
sdkVersion: SDK_VERSION,
|
|
165
|
+
sourceSchemaVersion: "1",
|
|
166
|
+
sdkRequest: "browser",
|
|
144
167
|
initialConsent: this.consent,
|
|
145
168
|
metrics: this.internalMetrics,
|
|
146
169
|
diagnostics: this.diagnostics,
|
|
147
|
-
onGovernorFeedback: (feedback) => {
|
|
148
|
-
this.applyUsageGovernorFeedback(feedback);
|
|
149
|
-
},
|
|
150
170
|
});
|
|
151
171
|
this.consent = this.transport.currentConsent();
|
|
152
172
|
this.transport.start();
|
|
@@ -166,10 +186,14 @@ class CluebaseBrowserSdkImpl {
|
|
|
166
186
|
if (this.consent !== "denied") {
|
|
167
187
|
this.warmupBrowserToken(ingestClient);
|
|
168
188
|
}
|
|
189
|
+
void initSdkCoreWasm().catch((error) => {
|
|
190
|
+
reportSdkError("init sdk core wasm", error);
|
|
191
|
+
});
|
|
169
192
|
this.tracerProvider = createCluebaseOtelPipeline({
|
|
170
193
|
resolved,
|
|
171
194
|
getTransport: () => this.transport,
|
|
172
195
|
getContext: () => this.buildContext(),
|
|
196
|
+
ignoreUrlPrefixes: this.ingestUrlPrefixes,
|
|
173
197
|
});
|
|
174
198
|
this.initialized = true;
|
|
175
199
|
this.refreshSessionCaptureEligibility();
|
|
@@ -232,6 +256,16 @@ class CluebaseBrowserSdkImpl {
|
|
|
232
256
|
const sanitizedTraits = this.sanitizeIdentifyTraits(traits);
|
|
233
257
|
const subjectProfileKeys = safeProfileKeys(traits, this.config?.privacy.deniedKeys ?? []);
|
|
234
258
|
this.identityManager.identify(sanitizedUserId, sanitizedTraits);
|
|
259
|
+
if (!this.lifecycleDedup.shouldEmit({
|
|
260
|
+
action: "identify",
|
|
261
|
+
userId: sanitizedUserId,
|
|
262
|
+
anonymousId: previousAnonymousId,
|
|
263
|
+
organizationId: this.organizationManager?.getContext().organizationId ?? null,
|
|
264
|
+
subjectTraits: this.identityManager.getContext().traits,
|
|
265
|
+
profileKeys: subjectProfileKeys,
|
|
266
|
+
})) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
235
269
|
this.enqueueOfficialCustomEvent(OFFICIAL_CUSTOM_EVENT_NAME.identityIdentified, {
|
|
236
270
|
identity_action: "identify",
|
|
237
271
|
profile_keys: subjectProfileKeys,
|
|
@@ -263,9 +297,20 @@ class CluebaseBrowserSdkImpl {
|
|
|
263
297
|
return;
|
|
264
298
|
}
|
|
265
299
|
const sanitizedOrgId = this.sanitizeIdentityValue("organizationId", normalizedOrganizationId);
|
|
266
|
-
const
|
|
300
|
+
const identityBeforeGroup = this.identityManager?.getContext();
|
|
301
|
+
const previousUserId = identityBeforeGroup?.userId ?? null;
|
|
267
302
|
const organizationProfileKeys = safeProfileKeys(traits, this.config?.privacy.deniedKeys ?? []);
|
|
268
303
|
this.organizationManager.setOrganization(sanitizedOrgId, traits);
|
|
304
|
+
if (!this.lifecycleDedup.shouldEmit({
|
|
305
|
+
action: "associate_organization",
|
|
306
|
+
userId: previousUserId,
|
|
307
|
+
anonymousId: identityBeforeGroup?.anonymousId ?? null,
|
|
308
|
+
organizationId: sanitizedOrgId,
|
|
309
|
+
organizationTraits: this.organizationManager.getContext().traits,
|
|
310
|
+
profileKeys: organizationProfileKeys,
|
|
311
|
+
})) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
269
314
|
this.enqueueOfficialCustomEvent(OFFICIAL_CUSTOM_EVENT_NAME.organizationAssociated, {
|
|
270
315
|
organization_action: "associate",
|
|
271
316
|
profile_keys: organizationProfileKeys,
|
|
@@ -282,31 +327,72 @@ class CluebaseBrowserSdkImpl {
|
|
|
282
327
|
});
|
|
283
328
|
}
|
|
284
329
|
}
|
|
285
|
-
|
|
286
|
-
if (!this.
|
|
330
|
+
link(input) {
|
|
331
|
+
if (!this.ensureInitializedForPublicCall("link")) {
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
const subject = input?.subject;
|
|
335
|
+
if (subject?.type !== "organization") {
|
|
336
|
+
this.warnPublicDrop("link", "subject.type must be 'organization'");
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
const organizationId = normalizePublicIdentityId(subject.id);
|
|
340
|
+
if (!organizationId) {
|
|
341
|
+
this.warnPublicDrop("link", "subject.id must be a non-empty string");
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
this.emitExternalLink("link", organizationId, input?.external?.namespace, input?.external?.id);
|
|
345
|
+
}
|
|
346
|
+
linkExternalAccount(namespace, externalId) {
|
|
347
|
+
if (!this.ensureInitializedForPublicCall("linkExternalAccount")) {
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
if (!this.organizationManager) {
|
|
351
|
+
this.warnPublicDrop("linkExternalAccount", "organization manager is unavailable");
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
const organizationId = this.organizationManager.getContext().organizationId;
|
|
355
|
+
if (!organizationId) {
|
|
356
|
+
this.warnPublicDrop("linkExternalAccount", "setOrganization must be called before linkExternalAccount");
|
|
287
357
|
return;
|
|
288
358
|
}
|
|
359
|
+
this.emitExternalLink("linkExternalAccount", organizationId, namespace, externalId);
|
|
360
|
+
}
|
|
361
|
+
emitExternalLink(publicCallName, organizationId, namespace, externalId) {
|
|
289
362
|
try {
|
|
290
|
-
const
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
363
|
+
const normalizedNamespace = normalizePublicIdentityId(namespace);
|
|
364
|
+
const normalizedExternalId = normalizePublicIdentityId(externalId);
|
|
365
|
+
if (!normalizedNamespace || !normalizedExternalId) {
|
|
366
|
+
this.warnPublicDrop(publicCallName, "namespace and externalId must be non-empty strings");
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
const sanitizedExternalId = this.sanitizeIdentityValue("externalId", normalizedExternalId);
|
|
370
|
+
if (!this.lifecycleDedup.shouldEmit({
|
|
371
|
+
action: "link",
|
|
372
|
+
organizationId,
|
|
373
|
+
externalNamespace: normalizedNamespace,
|
|
374
|
+
externalId: sanitizedExternalId,
|
|
375
|
+
})) {
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
this.enqueueOfficialCustomEvent(OFFICIAL_CUSTOM_EVENT_NAME.externalAccountLinked, {
|
|
379
|
+
identity_action: "link",
|
|
380
|
+
external_namespace: normalizedNamespace,
|
|
294
381
|
}, false, {
|
|
295
|
-
link_type: "
|
|
296
|
-
|
|
297
|
-
|
|
382
|
+
link_type: "canonical_subject_to_external",
|
|
383
|
+
organization_id: organizationId,
|
|
384
|
+
external_namespace: normalizedNamespace,
|
|
385
|
+
external_id: sanitizedExternalId,
|
|
298
386
|
});
|
|
387
|
+
this.flushLifecycleEvents();
|
|
299
388
|
}
|
|
300
389
|
catch {
|
|
301
|
-
this.logger.error(
|
|
390
|
+
this.logger.error(`${publicCallName} failed`, {
|
|
302
391
|
error_code: "sdk_operation_failed",
|
|
303
392
|
});
|
|
304
393
|
}
|
|
305
|
-
finally {
|
|
306
|
-
this.resetSessionState();
|
|
307
|
-
}
|
|
308
394
|
}
|
|
309
|
-
|
|
395
|
+
reset() {
|
|
310
396
|
if (!this.initialized) {
|
|
311
397
|
return;
|
|
312
398
|
}
|
|
@@ -322,7 +408,7 @@ class CluebaseBrowserSdkImpl {
|
|
|
322
408
|
});
|
|
323
409
|
}
|
|
324
410
|
catch {
|
|
325
|
-
this.logger.error("
|
|
411
|
+
this.logger.error("reset failed", {
|
|
326
412
|
error_code: "sdk_operation_failed",
|
|
327
413
|
});
|
|
328
414
|
}
|
|
@@ -387,6 +473,9 @@ class CluebaseBrowserSdkImpl {
|
|
|
387
473
|
});
|
|
388
474
|
}
|
|
389
475
|
setConsent(consent) {
|
|
476
|
+
if (this.consent !== consent) {
|
|
477
|
+
this.lifecycleDedup.clear();
|
|
478
|
+
}
|
|
390
479
|
this.consent = consent;
|
|
391
480
|
if (!this.initialized) {
|
|
392
481
|
return;
|
|
@@ -425,8 +514,7 @@ class CluebaseBrowserSdkImpl {
|
|
|
425
514
|
});
|
|
426
515
|
}
|
|
427
516
|
}
|
|
428
|
-
catch {
|
|
429
|
-
}
|
|
517
|
+
catch { }
|
|
430
518
|
}
|
|
431
519
|
warnPublicFieldDrop(operation, field, _reason) {
|
|
432
520
|
this.logger.warn(`Cluebase Frontend SDK ${operation} field dropped`, {
|
|
@@ -436,11 +524,13 @@ class CluebaseBrowserSdkImpl {
|
|
|
436
524
|
try {
|
|
437
525
|
if (typeof console !== "undefined" &&
|
|
438
526
|
typeof console.warn === "function") {
|
|
439
|
-
console.warn(`[cluebase] ${operation} field dropped`, {
|
|
527
|
+
console.warn(`[cluebase] ${operation} field dropped`, {
|
|
528
|
+
field,
|
|
529
|
+
error_code: "sdk_field_drop",
|
|
530
|
+
});
|
|
440
531
|
}
|
|
441
532
|
}
|
|
442
|
-
catch {
|
|
443
|
-
}
|
|
533
|
+
catch { }
|
|
444
534
|
}
|
|
445
535
|
sanitizeIdentifyTraits(traits) {
|
|
446
536
|
if (!traits) {
|
|
@@ -483,21 +573,15 @@ class CluebaseBrowserSdkImpl {
|
|
|
483
573
|
void this.transport?.flush();
|
|
484
574
|
}
|
|
485
575
|
async flush() {
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
await forceFlushCluebaseOtelProvider(this.tracerProvider, deadline?.signal);
|
|
490
|
-
await this.transport?.flush(deadline);
|
|
491
|
-
}
|
|
492
|
-
finally {
|
|
493
|
-
this.transport?.endFlushDeadline(deadline);
|
|
494
|
-
}
|
|
576
|
+
await this.flushCaptureSummaries("manual_flush");
|
|
577
|
+
await forceFlushCluebaseOtelProvider(this.tracerProvider);
|
|
578
|
+
await this.transport?.flush();
|
|
495
579
|
}
|
|
496
580
|
async close() {
|
|
497
|
-
|
|
498
|
-
await
|
|
581
|
+
this.transport?.beginClose();
|
|
582
|
+
await this.flushCaptureSummaries("close");
|
|
499
583
|
this.stopCaptureModules();
|
|
500
|
-
await forceFlushCluebaseOtelProvider(this.tracerProvider
|
|
584
|
+
await forceFlushCluebaseOtelProvider(this.tracerProvider);
|
|
501
585
|
await this.transport?.close();
|
|
502
586
|
if (this.transport?.getDiagnostics().lifecycle === "closing_failed") {
|
|
503
587
|
await this.shutdownAsync();
|
|
@@ -508,11 +592,19 @@ class CluebaseBrowserSdkImpl {
|
|
|
508
592
|
warmupBrowserToken(client) {
|
|
509
593
|
this.runtimeSurfaces.warmupBrowserToken(client);
|
|
510
594
|
}
|
|
595
|
+
adoptIngestUrlPrefixes(endpoints) {
|
|
596
|
+
for (const url of [endpoints.ingestBatchUrl, endpoints.browserTokenUrl]) {
|
|
597
|
+
if (url.length > 0 && !this.ingestUrlPrefixes.includes(url)) {
|
|
598
|
+
this.ingestUrlPrefixes.push(url);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
this.runtimeSurfaces.refreshIgnoreUrlPrefixes();
|
|
602
|
+
}
|
|
511
603
|
startCaptureModules() {
|
|
512
604
|
if (!this.config) {
|
|
513
605
|
return;
|
|
514
606
|
}
|
|
515
|
-
this.runtimeSurfaces.startCaptureModules(this.config);
|
|
607
|
+
this.runtimeSurfaces.startCaptureModules(this.config, this.ingestUrlPrefixes);
|
|
516
608
|
}
|
|
517
609
|
stopCaptureModules() {
|
|
518
610
|
this.runtimeSurfaces.stopCaptureModules();
|
|
@@ -520,9 +612,6 @@ class CluebaseBrowserSdkImpl {
|
|
|
520
612
|
async flushCaptureSummaries(reason) {
|
|
521
613
|
await this.runtimeSurfaces.flushCaptureSummaries(reason);
|
|
522
614
|
}
|
|
523
|
-
applyUsageGovernorFeedback(feedback) {
|
|
524
|
-
this.eventPipeline.applyUsageGovernorFeedback(feedback);
|
|
525
|
-
}
|
|
526
615
|
buildContext() {
|
|
527
616
|
return this.eventPipeline.buildContext();
|
|
528
617
|
}
|
|
@@ -551,7 +640,7 @@ class CluebaseBrowserSdkImpl {
|
|
|
551
640
|
const trimmed = raw.trim();
|
|
552
641
|
if (!trimmed)
|
|
553
642
|
return trimmed;
|
|
554
|
-
const piiCategory =
|
|
643
|
+
const piiCategory = detectWholeValuePII(trimmed);
|
|
555
644
|
if (piiCategory === null)
|
|
556
645
|
return trimmed;
|
|
557
646
|
const hashed = hashIdentityValue(trimmed);
|
package/dist/provider/types.d.ts
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
|
-
import type { InternalMetricsSnapshot } from "../internal/metrics.js";
|
|
2
1
|
import type { DiagnosticsSnapshot } from "../exporter/diagnostics.js";
|
|
2
|
+
import type { InternalMetricsSnapshot } from "../internal/metrics.js";
|
|
3
3
|
import type { FrontendEventName, ParameterCaptureMode, SdkCollectionMode } from "./contracts.js";
|
|
4
4
|
export type { FrontendEventCategory, FrontendEventName, FrontendEventStatus, ParameterCaptureMode, SdkCollectionMode, } from "./contracts.js";
|
|
5
5
|
export type CluebaseConsentState = "granted" | "denied" | "unknown";
|
|
6
6
|
export type CluebaseGroupType = "organization";
|
|
7
|
+
export type CluebaseLinkInput = {
|
|
8
|
+
subject: {
|
|
9
|
+
type: CluebaseGroupType;
|
|
10
|
+
id: string;
|
|
11
|
+
};
|
|
12
|
+
external: {
|
|
13
|
+
namespace: string;
|
|
14
|
+
id: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
7
17
|
export type CanonicalJsonValue = string | number | boolean | null | CanonicalJsonValue[] | {
|
|
8
18
|
[key: string]: CanonicalJsonValue;
|
|
9
19
|
};
|
|
@@ -19,7 +29,6 @@ export type CluebaseGroupTraits = {
|
|
|
19
29
|
} & {
|
|
20
30
|
[traitName: string]: CanonicalJsonInputValue;
|
|
21
31
|
};
|
|
22
|
-
export type TransportProfile = "standard";
|
|
23
32
|
export type RequestLifecycleOutcome = "completed" | "failed" | "aborted" | "unknown";
|
|
24
33
|
export type DiagnosticCollectionConfig = {
|
|
25
34
|
enabledCollectors?: string[];
|
|
@@ -64,10 +73,8 @@ export type CluebaseInitOptions = {
|
|
|
64
73
|
export type ResolvedCluebaseConfig = {
|
|
65
74
|
endpoint: string;
|
|
66
75
|
originalEndpoint: string;
|
|
67
|
-
localSetupCheckEndpoint: string | null;
|
|
68
76
|
projectKey: string;
|
|
69
77
|
producerId: string;
|
|
70
|
-
transportProfile: TransportProfile;
|
|
71
78
|
autocapture: boolean;
|
|
72
79
|
captureNetwork: boolean;
|
|
73
80
|
captureErrors: boolean;
|
|
@@ -112,7 +119,8 @@ export type CluebaseBrowserSdk = {
|
|
|
112
119
|
init(options: CluebaseInitOptions): void;
|
|
113
120
|
identify(userId: string, traits?: CluebaseSubjectTraits): void;
|
|
114
121
|
setOrganization(organizationId: string, traits?: CluebaseGroupTraits): void;
|
|
115
|
-
|
|
122
|
+
link(input: CluebaseLinkInput): void;
|
|
123
|
+
linkExternalAccount(namespace: string, externalId: string): void;
|
|
116
124
|
reset(): void;
|
|
117
125
|
track(eventName: string, properties?: CluebaseTrackProperties, metrics?: CluebaseTrackMetrics): void;
|
|
118
126
|
setConsent(consent: CluebaseConsentState): void;
|
|
@@ -120,23 +128,7 @@ export type CluebaseBrowserSdk = {
|
|
|
120
128
|
flush(): Promise<void>;
|
|
121
129
|
close(): Promise<void>;
|
|
122
130
|
getDiagnostics(): DiagnosticsSnapshot;
|
|
123
|
-
|
|
124
|
-
export type { CostCapability } from "../_generated/usage-governor-tables.js";
|
|
125
|
-
import type { CostCapability } from "../_generated/usage-governor-tables.js";
|
|
126
|
-
export type LimitKind = "monthly_overage_amount_limit" | "internal_cost_limit" | "internal_limit" | "operator_global_monthly_cost_limit";
|
|
127
|
-
export type ThresholdStage = "info" | "warning" | "urgent" | "reached";
|
|
128
|
-
export type LimitReason = {
|
|
129
|
-
limitKind: LimitKind;
|
|
130
|
-
meterKey: string;
|
|
131
|
-
thresholdStage: ThresholdStage;
|
|
132
|
-
currentValue: number;
|
|
133
|
-
limitValue: number;
|
|
134
|
-
retryAfterAt: string | null;
|
|
135
|
-
};
|
|
136
|
-
export type IngestUsageGovernorFeedback = {
|
|
137
|
-
disabledCapabilities: CostCapability[];
|
|
138
|
-
limitReasons: LimitReason[];
|
|
139
|
-
retryAfterAt: string | null;
|
|
131
|
+
withActionContext<T>(callback: () => T): T;
|
|
140
132
|
};
|
|
141
133
|
export type ParameterSnapshotLeafType = "string" | "number" | "boolean" | "null" | "object" | "array";
|
|
142
134
|
export type ParameterSnapshotLeaf = {
|
|
@@ -149,12 +141,14 @@ export type ParameterSnapshotLeaf = {
|
|
|
149
141
|
export type ParameterSnapshotValue = ParameterSnapshotLeaf | ParameterSnapshotValue[] | {
|
|
150
142
|
[key: string]: ParameterSnapshotValue;
|
|
151
143
|
};
|
|
152
|
-
export type SdkIdentityLinkType = "anonymous_to_user" | "user_to_organization" | "logout";
|
|
144
|
+
export type SdkIdentityLinkType = "anonymous_to_user" | "user_to_organization" | "logout" | "canonical_subject_to_external";
|
|
153
145
|
export type SdkIdentityLinkHint = {
|
|
154
146
|
link_type: SdkIdentityLinkType;
|
|
155
147
|
anonymous_id?: string | null;
|
|
156
148
|
user_id?: string | null;
|
|
157
149
|
organization_id?: string | null;
|
|
150
|
+
external_namespace?: string | null;
|
|
151
|
+
external_id?: string | null;
|
|
158
152
|
};
|
|
159
153
|
export type CluebaseContext = {
|
|
160
154
|
producer_id: string | null;
|
|
@@ -267,7 +261,6 @@ export type CaptureModuleContext = {
|
|
|
267
261
|
sessionId: string | null;
|
|
268
262
|
tabId: string | null;
|
|
269
263
|
};
|
|
270
|
-
shouldIgnoreElement?: (element: Element) => boolean;
|
|
271
264
|
startInteraction?: (input: {
|
|
272
265
|
interactionId?: string | null;
|
|
273
266
|
interactionInitiator?: string | null;
|
|
@@ -284,4 +277,5 @@ export type CaptureModuleContext = {
|
|
|
284
277
|
export type CaptureStopHandle = {
|
|
285
278
|
stop: () => void;
|
|
286
279
|
flush?: (reason: string) => void | Promise<void>;
|
|
280
|
+
refreshIgnoreUrlPrefixes?: () => void;
|
|
287
281
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
export function deliveryCommandJson(request_json: string): string;
|
|
5
|
+
|
|
6
|
+
export function spanToObservationSourceEventJson(span_json: string, options_json: string): string;
|
|
7
|
+
|
|
8
|
+
export function spanToSdkSignalJson(span_json: string, options_json: string): string;
|
|
9
|
+
|
|
10
|
+
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
11
|
+
|
|
12
|
+
export interface InitOutput {
|
|
13
|
+
readonly memory: WebAssembly.Memory;
|
|
14
|
+
readonly deliveryCommandJson: (a: number, b: number, c: number) => void;
|
|
15
|
+
readonly spanToObservationSourceEventJson: (a: number, b: number, c: number, d: number, e: number) => void;
|
|
16
|
+
readonly spanToSdkSignalJson: (a: number, b: number, c: number, d: number, e: number) => void;
|
|
17
|
+
readonly __wbindgen_export: (a: number) => void;
|
|
18
|
+
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
|
|
19
|
+
readonly __wbindgen_export2: (a: number, b: number) => number;
|
|
20
|
+
readonly __wbindgen_export3: (a: number, b: number, c: number, d: number) => number;
|
|
21
|
+
readonly __wbindgen_export4: (a: number, b: number, c: number) => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Instantiates the given `module`, which can either be bytes or
|
|
28
|
+
* a precompiled `WebAssembly.Module`.
|
|
29
|
+
*
|
|
30
|
+
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
|
|
31
|
+
*
|
|
32
|
+
* @returns {InitOutput}
|
|
33
|
+
*/
|
|
34
|
+
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
|
38
|
+
* for everything else, calls `WebAssembly.instantiate` directly.
|
|
39
|
+
*
|
|
40
|
+
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
|
|
41
|
+
*
|
|
42
|
+
* @returns {Promise<InitOutput>}
|
|
43
|
+
*/
|
|
44
|
+
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
|