@genn-inc/cluebase-frontend-sdk 0.0.1 → 0.0.2
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 +11 -9
- package/dist/_generated/correlation-attribute-keys.js +4 -0
- package/dist/_generated/otel-span-conversion.d.ts +0 -34
- package/dist/_generated/otel-span-conversion.js +0 -32
- package/dist/context/action-context.d.ts +39 -0
- package/dist/context/action-context.js +298 -0
- package/dist/context/browser-storage.d.ts +0 -12
- package/dist/context/browser-storage.js +0 -13
- package/dist/context/identity.js +0 -4
- package/dist/context/organization.d.ts +0 -4
- package/dist/context/organization.js +0 -7
- package/dist/context/session.js +0 -3
- package/dist/context/tab.js +0 -5
- package/dist/context/trace.d.ts +13 -1
- package/dist/context/trace.js +119 -21
- package/dist/exporter/batch.d.ts +0 -12
- package/dist/exporter/batch.js +0 -27
- package/dist/exporter/browser-outbox.js +0 -17
- package/dist/exporter/client.d.ts +0 -15
- package/dist/exporter/client.js +0 -43
- package/dist/exporter/delivery-response-contract.js +0 -6
- package/dist/exporter/delivery-response.d.ts +0 -16
- package/dist/exporter/delivery-response.js +0 -19
- package/dist/exporter/frontend-resource.d.ts +0 -9
- package/dist/exporter/frontend-resource.js +0 -9
- package/dist/exporter/observation-source-event-exporter.d.ts +0 -28
- package/dist/exporter/observation-source-event-exporter.js +0 -18
- package/dist/exporter/parameter-snapshot.js +1 -24
- package/dist/exporter/raw-event-to-source-signal.js +18 -11
- package/dist/exporter/sanitize.d.ts +1 -12
- package/dist/exporter/sanitize.js +6 -39
- package/dist/exporter/source-event.d.ts +2 -0
- package/dist/exporter/span-to-source-signal.js +7 -3
- package/dist/exporter/text-fingerprint.d.ts +0 -8
- package/dist/exporter/text-fingerprint.js +0 -8
- package/dist/index.d.ts +0 -4
- package/dist/index.js +9 -39
- package/dist/instrumentation/action.js +3 -2
- package/dist/instrumentation/cluebase-authored-attributes.d.ts +0 -2
- package/dist/instrumentation/cluebase-authored-attributes.js +0 -23
- package/dist/instrumentation/common.d.ts +0 -63
- package/dist/instrumentation/common.js +0 -48
- package/dist/instrumentation/dom.d.ts +0 -25
- package/dist/instrumentation/dom.js +5 -41
- package/dist/instrumentation/drag.js +1 -2
- package/dist/instrumentation/form.js +1 -2
- package/dist/instrumentation/input.js +10 -8
- package/dist/instrumentation/naming-evidence.d.ts +0 -12
- package/dist/instrumentation/navigation.js +0 -2
- package/dist/instrumentation/network-request.d.ts +2 -2
- package/dist/instrumentation/network-request.js +1 -2
- package/dist/instrumentation/network-span-attributes.d.ts +0 -7
- package/dist/instrumentation/network-span-attributes.js +1 -3
- package/dist/instrumentation/network.js +6 -1
- package/dist/instrumentation/page.js +0 -2
- package/dist/instrumentation/performance.js +0 -7
- package/dist/integrations/react-router.js +0 -3
- package/dist/internal/internal-log.d.ts +0 -7
- package/dist/internal/internal-log.js +0 -11
- package/dist/provider/_version.d.ts +1 -1
- package/dist/provider/_version.js +1 -1
- package/dist/provider/config.d.ts +0 -7
- package/dist/provider/config.js +3 -16
- package/dist/provider/constants.d.ts +1 -17
- package/dist/provider/constants.js +1 -31
- package/dist/provider/privacy-policy-store.d.ts +0 -12
- package/dist/provider/privacy-policy-store.js +0 -12
- package/dist/provider/sdk-event-pipeline.d.ts +1 -1
- package/dist/provider/sdk-event-pipeline.js +41 -54
- package/dist/provider/sdk-otel-pipeline.js +50 -4
- package/dist/provider/sdk-runtime-surfaces.js +3 -1
- package/dist/provider/sdk.js +3 -23
- package/dist/provider/types.d.ts +3 -39
- package/dist/provider/usage-governor.js +0 -2
- package/package.json +3 -6
package/dist/provider/sdk.js
CHANGED
|
@@ -47,10 +47,6 @@ class CluebaseBrowserSdkImpl {
|
|
|
47
47
|
this.traceManager = null;
|
|
48
48
|
this.diagnostics = new DiagnosticStore();
|
|
49
49
|
this.transport = null;
|
|
50
|
-
// OTel TracerProvider wired with the source-signal exporter so every span
|
|
51
|
-
// produced by `@opentelemetry/api`'s global tracer flows through
|
|
52
|
-
// `ObservationSourceEventExporter` → `BatchTransport.enqueue` →
|
|
53
|
-
// Cluebase ingest endpoint.
|
|
54
50
|
this.tracerProvider = null;
|
|
55
51
|
this.logger = logger;
|
|
56
52
|
this.internalMetrics = new InternalMetricsStore();
|
|
@@ -120,6 +116,7 @@ class CluebaseBrowserSdkImpl {
|
|
|
120
116
|
this.tabManager = new TabManager();
|
|
121
117
|
this.organizationManager = new OrganizationManager();
|
|
122
118
|
this.traceManager = new TraceManager();
|
|
119
|
+
this.traceManager.enableAsyncContext();
|
|
123
120
|
this.environmentManager = new EnvironmentManager({
|
|
124
121
|
frontendRelease: resolved.release.frontendRelease,
|
|
125
122
|
contextTraitsProvider: resolved.contextTraitsProvider,
|
|
@@ -168,9 +165,6 @@ class CluebaseBrowserSdkImpl {
|
|
|
168
165
|
if (this.consent !== "denied") {
|
|
169
166
|
this.warmupBrowserToken(ingestClient);
|
|
170
167
|
}
|
|
171
|
-
// Wire WebTracerProvider with the canonical exporter. The provider is
|
|
172
|
-
// registered globally so OTel-instrumented code and capture modules
|
|
173
|
-
// converge on the same transport buffer.
|
|
174
168
|
this.tracerProvider = createCluebaseOtelPipeline({
|
|
175
169
|
resolved,
|
|
176
170
|
getTransport: () => this.transport,
|
|
@@ -214,8 +208,6 @@ class CluebaseBrowserSdkImpl {
|
|
|
214
208
|
return;
|
|
215
209
|
}
|
|
216
210
|
try {
|
|
217
|
-
// Capture the pre-identify anonymous id so the worker can fuse the
|
|
218
|
-
// anonymous → identified subject as a single resolution chain.
|
|
219
211
|
const normalizedUserId = normalizePublicIdentityId(userId);
|
|
220
212
|
if (!normalizedUserId) {
|
|
221
213
|
this.warnPublicDrop("identify", "userId must be a non-empty string");
|
|
@@ -380,7 +372,6 @@ class CluebaseBrowserSdkImpl {
|
|
|
380
372
|
},
|
|
381
373
|
});
|
|
382
374
|
}
|
|
383
|
-
// SDK は observation source event だけを送り、ingest core が意味付けを行う。
|
|
384
375
|
setConsent(consent) {
|
|
385
376
|
this.consent = consent;
|
|
386
377
|
if (!this.initialized) {
|
|
@@ -421,7 +412,6 @@ class CluebaseBrowserSdkImpl {
|
|
|
421
412
|
}
|
|
422
413
|
}
|
|
423
414
|
catch {
|
|
424
|
-
// Public warnings must never break the host app.
|
|
425
415
|
}
|
|
426
416
|
}
|
|
427
417
|
warnPublicFieldDrop(operation, field, _reason) {
|
|
@@ -436,7 +426,6 @@ class CluebaseBrowserSdkImpl {
|
|
|
436
426
|
}
|
|
437
427
|
}
|
|
438
428
|
catch {
|
|
439
|
-
// Public warnings must never break the host app.
|
|
440
429
|
}
|
|
441
430
|
}
|
|
442
431
|
sanitizeIdentifyTraits(traits) {
|
|
@@ -479,7 +468,6 @@ class CluebaseBrowserSdkImpl {
|
|
|
479
468
|
flushLifecycleEvents() {
|
|
480
469
|
void this.transport?.flush();
|
|
481
470
|
}
|
|
482
|
-
// 内部 transport の即時 flush を要求する。SPA navigation や明示的 shutdown シナリオ用。
|
|
483
471
|
async flush() {
|
|
484
472
|
const deadline = this.transport?.beginFlushDeadline();
|
|
485
473
|
try {
|
|
@@ -491,7 +479,6 @@ class CluebaseBrowserSdkImpl {
|
|
|
491
479
|
this.transport?.endFlushDeadline(deadline);
|
|
492
480
|
}
|
|
493
481
|
}
|
|
494
|
-
// 残バッファを flush した上で SDK を停止する。テスト / 明示的 shutdown 用。
|
|
495
482
|
async close() {
|
|
496
483
|
const closeSignal = this.transport?.beginClose();
|
|
497
484
|
await awaitUntilDeadline(this.flushCaptureSummaries("close"), closeSignal);
|
|
@@ -499,7 +486,7 @@ class CluebaseBrowserSdkImpl {
|
|
|
499
486
|
await forceFlushCluebaseOtelProvider(this.tracerProvider, closeSignal ?? undefined);
|
|
500
487
|
await this.transport?.close();
|
|
501
488
|
if (this.transport?.getDiagnostics().lifecycle === "closing_failed") {
|
|
502
|
-
this.
|
|
489
|
+
await this.shutdownAsync();
|
|
503
490
|
return;
|
|
504
491
|
}
|
|
505
492
|
await this.shutdownAsync();
|
|
@@ -544,14 +531,6 @@ class CluebaseBrowserSdkImpl {
|
|
|
544
531
|
refreshSessionCaptureEligibility() {
|
|
545
532
|
this.eventPipeline.refreshSessionCaptureEligibility();
|
|
546
533
|
}
|
|
547
|
-
/**
|
|
548
|
-
* Sanitize an identity value (userId / organizationId) before publishing.
|
|
549
|
-
* If the caller passed an email / phone / credit-card / SSN-shaped
|
|
550
|
-
* value, hash it deterministically and warn via the internal logger.
|
|
551
|
-
* This prevents raw PII from landing in canonical span attributes
|
|
552
|
-
* (`cluebase.actor.user_id`) and raw observation storage.
|
|
553
|
-
*
|
|
554
|
-
*/
|
|
555
534
|
sanitizeIdentityValue(field, raw) {
|
|
556
535
|
if (typeof raw !== "string")
|
|
557
536
|
return raw;
|
|
@@ -587,6 +566,7 @@ class CluebaseBrowserSdkImpl {
|
|
|
587
566
|
this.transport.dispose();
|
|
588
567
|
this.transport = null;
|
|
589
568
|
}
|
|
569
|
+
this.traceManager?.disableAsyncContext();
|
|
590
570
|
this.traceManager = null;
|
|
591
571
|
this.initialized = false;
|
|
592
572
|
this.initSignature = null;
|
package/dist/provider/types.d.ts
CHANGED
|
@@ -3,11 +3,6 @@ import type { DiagnosticsSnapshot } from "../exporter/diagnostics.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
|
-
/**
|
|
7
|
-
* MVP group taxonomy. Public `cluebase.group(...)` accepts only the customer
|
|
8
|
-
* company concept. `account` / `workspace` are future concepts and are not
|
|
9
|
-
* exposed as MVP group inputs.
|
|
10
|
-
*/
|
|
11
6
|
export type CluebaseGroupType = "organization";
|
|
12
7
|
export type CanonicalJsonValue = string | number | boolean | null | CanonicalJsonValue[] | {
|
|
13
8
|
[key: string]: CanonicalJsonValue;
|
|
@@ -37,14 +32,8 @@ export type DiagnosticCollectionConfig = {
|
|
|
37
32
|
reason?: string;
|
|
38
33
|
enabledBy?: string;
|
|
39
34
|
};
|
|
40
|
-
/**
|
|
41
|
-
* Public bootstrap options accepted by `cluebase.init`.
|
|
42
|
-
*
|
|
43
|
-
* The SDK derives dev/prod from the `projectKey` prefix. Browser ingest obtains
|
|
44
|
-
* short-lived tokens from `POST <endpoint>/api/v1/ingest/browser-tokens`.
|
|
45
|
-
*/
|
|
46
35
|
export type CluebaseInitOptions = {
|
|
47
|
-
endpoint
|
|
36
|
+
endpoint?: string;
|
|
48
37
|
projectKey: string;
|
|
49
38
|
autocapture?: boolean;
|
|
50
39
|
captureNetwork?: boolean;
|
|
@@ -70,23 +59,6 @@ export type CluebaseInitOptions = {
|
|
|
70
59
|
frontendRelease?: string;
|
|
71
60
|
};
|
|
72
61
|
contextTraitsProvider?: () => CluebaseTrackProperties;
|
|
73
|
-
/**
|
|
74
|
-
* Controls how the SDK's internal ``WebTracerProvider`` interacts with
|
|
75
|
-
* the page's global OTel context.
|
|
76
|
-
*
|
|
77
|
-
* - ``"register"`` (default for SDKs initialised on pages without
|
|
78
|
-
* pre-existing OTel): call ``WebTracerProvider#register()`` so any
|
|
79
|
-
* ``trace.getTracer(...)`` call in the page routes through Cluebase's
|
|
80
|
-
* exporter, including Cluebase's own runtime span emissions.
|
|
81
|
-
* - ``"standalone"``: do not register globally. Cluebase's pipeline is
|
|
82
|
-
* private; only spans created via the SDK's own internal tracer
|
|
83
|
-
* reach the exporter. Use this when the host app already manages an
|
|
84
|
-
* OTel TracerProvider (Sentry, Datadog, Honeycomb, etc.) and Cluebase
|
|
85
|
-
* must not hijack it.
|
|
86
|
-
* - ``"detect"`` (recommended): inspect ``trace.getTracerProvider()``;
|
|
87
|
-
* if a non-proxy provider is already installed, behave as
|
|
88
|
-
* ``standalone``; otherwise behave as ``register``.
|
|
89
|
-
*/
|
|
90
62
|
otelProviderMode?: "register" | "standalone" | "detect";
|
|
91
63
|
};
|
|
92
64
|
export type ResolvedCluebaseConfig = {
|
|
@@ -195,6 +167,7 @@ export type CluebaseContext = {
|
|
|
195
167
|
trace_id: string;
|
|
196
168
|
request_id: string;
|
|
197
169
|
request_span_id: string;
|
|
170
|
+
action_id: string | null;
|
|
198
171
|
interaction_id: string;
|
|
199
172
|
correlation_id: string | null;
|
|
200
173
|
sdk_collection_mode: SdkCollectionMode;
|
|
@@ -255,16 +228,6 @@ export type CluebaseSubjectProfile = {
|
|
|
255
228
|
contact_identity_hash: string | null;
|
|
256
229
|
contact_domain: string | null;
|
|
257
230
|
};
|
|
258
|
-
/**
|
|
259
|
-
* Customer-facing trait dict accepted by `cluebase.identify` /
|
|
260
|
-
* `cluebase.setOrganization`.
|
|
261
|
-
*
|
|
262
|
-
* Customers use the camelCase form on every SDK. The ingest core normalizes
|
|
263
|
-
* these values after receiving the SDK source signal.
|
|
264
|
-
*
|
|
265
|
-
* `displayName`, `email`, and `emailAddress` are accepted alternate keys.
|
|
266
|
-
* Email traits are transported only as privacy-safe contact-derived fields.
|
|
267
|
-
*/
|
|
268
231
|
export type CluebaseSubjectTraits = {
|
|
269
232
|
name?: string | null;
|
|
270
233
|
email?: string | null;
|
|
@@ -315,6 +278,7 @@ export type CaptureModuleContext = {
|
|
|
315
278
|
interactionScopeKey?: string | null;
|
|
316
279
|
nowMs?: number;
|
|
317
280
|
}) => string | null;
|
|
281
|
+
bindEventContext?: (event: Event) => void;
|
|
318
282
|
requestFlush?: () => void;
|
|
319
283
|
};
|
|
320
284
|
export type CaptureStopHandle = {
|
|
@@ -4,8 +4,6 @@ export const DEFAULT_INGEST_USAGE_GOVERNOR_FEEDBACK = {
|
|
|
4
4
|
limitReasons: [],
|
|
5
5
|
retryAfterAt: null,
|
|
6
6
|
};
|
|
7
|
-
// 正本から生成した一覧をそのまま使います。ここへ書き写していたため
|
|
8
|
-
// `replay_storage` が抜け、受付側が「止めよ」と言っても画面側が捨てていました。
|
|
9
7
|
const COST_CAPABILITIES = new Set(GENERATED_COST_CAPABILITIES);
|
|
10
8
|
const LIMIT_KINDS = new Set(GENERATED_LIMIT_KINDS);
|
|
11
9
|
const THRESHOLD_STAGES = new Set(GENERATED_THRESHOLD_STAGES);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genn-inc/cluebase-frontend-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/genn-inc/cluebase.git"
|
|
@@ -27,11 +27,8 @@
|
|
|
27
27
|
"lint": "pnpm exec biome lint src",
|
|
28
28
|
"test:package-import": "pnpm build && node ../../../tests/distribution/frontend-sdk/check-package-import.mjs",
|
|
29
29
|
"typecheck": "tsc -p tsconfig.typecheck.json",
|
|
30
|
-
"
|
|
31
|
-
"test": "vitest run --config ../../../tests/config/vitest/frontend-sdk.config.ts --
|
|
32
|
-
"test:cov": "vitest run --config ../../../tests/config/vitest/frontend-sdk.config.ts --coverage --exclude \"../../../tests/integration/frontend-sdk/**/*-live.test.ts\"",
|
|
33
|
-
"_comment_test_live": "実環境がある段だけがここを呼びます。**vitest の位置引数は glob ではなく道筋への部分一致です** — 実測 (2026-08-21): `vitest run \"src/**/*-live.test.ts\"` は `No test files found` で 0 件、`vitest run live.test.ts` は 1 件。綴りを CI ではなくここに置くので、CI 側は script 名を呼ぶだけになります。",
|
|
34
|
-
"test:live": "vitest run --config ../../../tests/config/vitest/frontend-sdk.config.ts ../../../tests/integration/frontend-sdk"
|
|
30
|
+
"test": "vitest run --config ../../../tests/config/vitest/frontend-sdk.config.ts",
|
|
31
|
+
"test:cov": "vitest run --config ../../../tests/config/vitest/frontend-sdk.config.ts --coverage"
|
|
35
32
|
},
|
|
36
33
|
"devDependencies": {
|
|
37
34
|
"@cluebase/schema": "workspace:*",
|