@probemap/browser 0.1.0

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.
@@ -0,0 +1,17 @@
1
+ import type { ProbeMapEventType, ProbeStatus } from "@probemap/shared";
2
+ export interface AutoCaptureOptions {
3
+ actions: boolean;
4
+ network: boolean;
5
+ errors: boolean;
6
+ navigation: boolean;
7
+ console: boolean;
8
+ highFrequencySampleMs: number;
9
+ }
10
+ export interface AutoCaptureRecorder {
11
+ collectorUrl: string;
12
+ record(type: ProbeMapEventType, name: string, payload: unknown, status?: ProbeStatus): void;
13
+ diagnostic(error: unknown): void;
14
+ }
15
+ export declare function sanitizeCapturedUrl(value: string): string;
16
+ export declare function installBrowserAutoCapture(recorder: AutoCaptureRecorder, options: AutoCaptureOptions): () => void;
17
+ //# sourceMappingURL=auto-capture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-capture.d.ts","sourceRoot":"","sources":["../src/auto-capture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEvE,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5F,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CAClC;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUzD;AAaD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,mBAAmB,EAAE,OAAO,EAAE,kBAAkB,GAAG,MAAM,IAAI,CAgEhH"}
@@ -0,0 +1,100 @@
1
+ export function sanitizeCapturedUrl(value) {
2
+ try {
3
+ const url = new URL(value, globalThis.location?.href ?? "http://localhost/");
4
+ for (const key of [...url.searchParams.keys()]) {
5
+ if (/token|key|secret|password|auth/iu.test(key))
6
+ url.searchParams.set(key, "[REDACTED]");
7
+ }
8
+ return `${url.origin}${url.pathname}${url.search}`.slice(0, 2_048);
9
+ }
10
+ catch {
11
+ return value.slice(0, 2_048);
12
+ }
13
+ }
14
+ function targetDescriptor(target) {
15
+ if (!(target instanceof Element))
16
+ return {};
17
+ return {
18
+ tag: target.tagName.toLowerCase(),
19
+ id: target.id || null,
20
+ name: target.getAttribute("name"),
21
+ role: target.getAttribute("role"),
22
+ probeName: target.getAttribute("data-probemap-name"),
23
+ };
24
+ }
25
+ export function installBrowserAutoCapture(recorder, options) {
26
+ if (typeof window === "undefined" || typeof document === "undefined")
27
+ return () => undefined;
28
+ const cleanups = [];
29
+ const listen = (target, type, listener) => {
30
+ target.addEventListener(type, listener, { capture: true });
31
+ cleanups.push(() => target.removeEventListener(type, listener, { capture: true }));
32
+ };
33
+ const safely = (work) => { try {
34
+ work();
35
+ }
36
+ catch (error) {
37
+ recorder.diagnostic(error);
38
+ } };
39
+ if (options.actions) {
40
+ listen(document, "click", (event) => safely(() => recorder.record("action.click", "browser.click", targetDescriptor(event.target))));
41
+ listen(document, "dblclick", (event) => safely(() => recorder.record("action.double_click", "browser.double_click", targetDescriptor(event.target))));
42
+ listen(document, "input", (event) => safely(() => recorder.record("action.input", "browser.input", { ...targetDescriptor(event.target), value: "[REDACTED]" })));
43
+ listen(document, "keydown", (event) => safely(() => recorder.record("action.keypress", "browser.keypress", { ...targetDescriptor(event.target), key: ["Enter", "Escape", "Tab", "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].includes(event.key) ? event.key : "other", modifiers: { alt: event.altKey, ctrl: event.ctrlKey, meta: event.metaKey, shift: event.shiftKey } })));
44
+ listen(document, "dragstart", (event) => safely(() => recorder.record("action.drag_start", "browser.drag_start", targetDescriptor(event.target))));
45
+ let lastDragMove = 0;
46
+ listen(document, "drag", (event) => safely(() => {
47
+ const now = globalThis.performance?.now() ?? Date.now();
48
+ if (now - lastDragMove < options.highFrequencySampleMs)
49
+ return;
50
+ lastDragMove = now;
51
+ recorder.record("action.drag_move", "browser.drag_move", { ...targetDescriptor(event.target), x: event.clientX, y: event.clientY });
52
+ }));
53
+ listen(document, "dragend", (event) => safely(() => recorder.record("action.drag_end", "browser.drag_end", { ...targetDescriptor(event.target), x: event.clientX, y: event.clientY })));
54
+ listen(document, "drop", (event) => safely(() => recorder.record("action.drop", "browser.drop", { ...targetDescriptor(event.target), x: event.clientX, y: event.clientY })));
55
+ }
56
+ if (options.navigation) {
57
+ const navigation = () => safely(() => recorder.record("action.navigation", "browser.navigation", { url: sanitizeCapturedUrl(globalThis.location.href) }));
58
+ listen(window, "popstate", navigation);
59
+ listen(window, "hashchange", navigation);
60
+ }
61
+ if (options.errors) {
62
+ listen(window, "error", (event) => safely(() => recorder.record("runtime.exception", event.error instanceof Error ? event.error.name : "window.error", { message: String(event.message).slice(0, 2_000), stack: event.error instanceof Error ? event.error.stack?.slice(0, 8_000) : undefined }, "fail")));
63
+ listen(window, "unhandledrejection", (event) => safely(() => recorder.record("runtime.exception", "unhandledrejection", { message: event.reason instanceof Error ? event.reason.message.slice(0, 2_000) : String(event.reason).slice(0, 2_000), stack: event.reason instanceof Error ? event.reason.stack?.slice(0, 8_000) : undefined }, "fail")));
64
+ }
65
+ if (options.console) {
66
+ for (const level of ["log", "warn", "error"]) {
67
+ const original = globalThis.console[level].bind(globalThis.console);
68
+ globalThis.console[level] = (...args) => {
69
+ original(...args);
70
+ if (typeof args[0] === "string" && args[0].startsWith("[ProbeMap]"))
71
+ return;
72
+ safely(() => recorder.record(`console.${level}`, `console.${level}`, { arguments: args.slice(0, 20) }, level === "error" ? "fail" : level === "warn" ? "warn" : undefined));
73
+ };
74
+ cleanups.push(() => { globalThis.console[level] = original; });
75
+ }
76
+ }
77
+ if (options.network && typeof globalThis.fetch === "function") {
78
+ const originalFetch = globalThis.fetch.bind(globalThis);
79
+ globalThis.fetch = async (input, init) => {
80
+ const url = typeof input === "string" || input instanceof URL ? String(input) : input.url;
81
+ if (url.startsWith(recorder.collectorUrl))
82
+ return originalFetch(input, init);
83
+ const method = init?.method ?? (input instanceof Request ? input.method : "GET");
84
+ safely(() => recorder.record("network.request", `${method.toUpperCase()} ${new URL(url, globalThis.location.href).pathname}`, { method, url: sanitizeCapturedUrl(url) }));
85
+ try {
86
+ const response = await originalFetch(input, init);
87
+ safely(() => recorder.record("network.response", `${method.toUpperCase()} ${new URL(url, globalThis.location.href).pathname}`, { method, url: sanitizeCapturedUrl(url), status: response.status }, response.ok ? "pass" : "fail"));
88
+ return response;
89
+ }
90
+ catch (error) {
91
+ safely(() => recorder.record("network.error", `${method.toUpperCase()} ${new URL(url, globalThis.location.href).pathname}`, { method, url: sanitizeCapturedUrl(url), message: error instanceof Error ? error.message.slice(0, 2_000) : String(error).slice(0, 2_000) }, "fail"));
92
+ throw error;
93
+ }
94
+ };
95
+ cleanups.push(() => { globalThis.fetch = originalFetch; });
96
+ }
97
+ return () => { for (const cleanup of cleanups.reverse())
98
+ cleanup(); };
99
+ }
100
+ //# sourceMappingURL=auto-capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-capture.js","sourceRoot":"","sources":["../src/auto-capture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import { type TraceHeaders } from "@probemap/shared";
2
+ import type { AssertInput, AssertionRecordResult, BrowserProbeConfig, BrowserProbeStatus, FlowHandle, FlowStartOptions, ObserveOptions, ProbeEventOptions } from "./types.js";
3
+ export declare class BrowserProbeClient {
4
+ private initialized;
5
+ private enabled;
6
+ private config;
7
+ private transport;
8
+ private sessionInput;
9
+ private sessionReady;
10
+ private sessionPromise;
11
+ private readonly readyFlowIds;
12
+ private readonly flowPromises;
13
+ private readonly flowDefinitions;
14
+ private readonly flows;
15
+ private readonly activeFlowIds;
16
+ private queue;
17
+ private timer;
18
+ private flushPromise;
19
+ private clientSequence;
20
+ private droppedEvents;
21
+ private consecutiveFailures;
22
+ private lastError;
23
+ private sessionTraceId;
24
+ private autoCaptureCleanup;
25
+ readonly flow: {
26
+ start: (name: string, options?: FlowStartOptions) => FlowHandle | undefined;
27
+ end: (handle: FlowHandle | undefined) => void;
28
+ };
29
+ init(input: BrowserProbeConfig): {
30
+ sessionId: string;
31
+ runtimeId: string;
32
+ };
33
+ status(): BrowserProbeStatus;
34
+ getTraceHeaders(handle?: FlowHandle): TraceHeaders | undefined;
35
+ ready(): Promise<void>;
36
+ step(name: string, payload?: unknown, options?: ProbeEventOptions): string | undefined;
37
+ observe(name: string, value: unknown, options?: ObserveOptions): string | undefined;
38
+ assert(name: string, assertion: AssertInput): AssertionRecordResult;
39
+ /** @deprecated Use assert(). */
40
+ check(name: string, assertion: AssertInput): AssertionRecordResult;
41
+ captureException(error: unknown, options?: ProbeEventOptions): string | undefined;
42
+ flush(): Promise<void>;
43
+ destroy(): Promise<void>;
44
+ private reset;
45
+ private startFlow;
46
+ private endFlow;
47
+ private recordEvent;
48
+ private createEvent;
49
+ private enqueue;
50
+ private scheduleFlush;
51
+ private clearTimer;
52
+ private flushInternal;
53
+ private ensureSession;
54
+ private ensureFlows;
55
+ private recordFailure;
56
+ private emitDiagnostic;
57
+ }
58
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,YAAY,EAClB,MAAM,kBAAkB,CAAC;AAK1B,OAAO,KAAK,EACV,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAElB,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EAElB,MAAM,YAAY,CAAC;AAyCpB,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoC;IACjE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAsC;IACtE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmC;IACzD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,KAAK,CAA4C;IACzD,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,kBAAkB,CAA2B;IAErD,SAAgB,IAAI;QAClB,KAAK,SAAS,MAAM,YAAW,gBAAgB,KAAQ,UAAU,GAAG,SAAS;QAE7E,GAAG,WAAW,UAAU,GAAG,SAAS,KAAG,IAAI;MAC3C;IAEK,IAAI,CAAC,KAAK,EAAE,kBAAkB,GAAG;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CA2E/E;IAEM,MAAM,IAAI,kBAAkB,CASlC;IAEM,eAAe,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,SAAS,CAgCpE;IAEY,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAUlC;IAEM,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,OAAY,EAAE,OAAO,GAAE,iBAAsB,GAAG,MAAM,GAAG,SAAS,CAEpG;IAEM,OAAO,CACZ,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,cAAmB,GAC3B,MAAM,GAAG,SAAS,CAOpB;IAEM,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,GAAG,qBAAqB,CA0BzE;IAED,gCAAgC;IACzB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,GAAG,qBAAqB,CAExE;IAEM,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,iBAAsB,GAAG,MAAM,GAAG,SAAS,CAK3F;IAEY,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAelC;IAEY,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAgBpC;IAED,OAAO,CAAC,KAAK;IAwBb,OAAO,CAAC,SAAS;IAwDjB,OAAO,CAAC,OAAO;IAgBf,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,WAAW;IA6DnB,OAAO,CAAC,OAAO;IAmBf,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,UAAU;YAOJ,aAAa;YA2Cb,aAAa;YAqBb,WAAW;IA2BzB,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,cAAc;CAevB"}
package/dist/client.js ADDED
@@ -0,0 +1,516 @@
1
+ import { PROTOCOL_VERSION, createTraceHeaders, evaluateBuiltIn, } from "@probemap/shared";
2
+ import { HttpProbeTransport } from "./http-transport.js";
3
+ import { installBrowserAutoCapture } from "./auto-capture.js";
4
+ import { safeSnapshot } from "./safe-snapshot.js";
5
+ const browserSdkVersion = "0.1.0";
6
+ function randomHex(byteLength) {
7
+ const bytes = new Uint8Array(byteLength);
8
+ globalThis.crypto.getRandomValues(bytes);
9
+ return [...bytes].map((byte) => byte.toString(16).padStart(2, "0")).join("");
10
+ }
11
+ function monotonicNow() {
12
+ return globalThis.performance?.now() ?? Date.now();
13
+ }
14
+ function messageFromError(error) {
15
+ return error instanceof Error ? error.message : String(error);
16
+ }
17
+ export class BrowserProbeClient {
18
+ initialized = false;
19
+ enabled = false;
20
+ config;
21
+ transport;
22
+ sessionInput;
23
+ sessionReady = false;
24
+ sessionPromise;
25
+ readyFlowIds = new Set();
26
+ flowPromises = new Map();
27
+ flowDefinitions = new Map();
28
+ flows = new Map();
29
+ activeFlowIds = [];
30
+ queue = [];
31
+ timer;
32
+ flushPromise;
33
+ clientSequence = 0;
34
+ droppedEvents = 0;
35
+ consecutiveFailures = 0;
36
+ lastError;
37
+ sessionTraceId = "";
38
+ autoCaptureCleanup;
39
+ flow = {
40
+ start: (name, options = {}) => this.startFlow(name, options),
41
+ end: (handle) => this.endFlow(handle),
42
+ };
43
+ init(input) {
44
+ this.reset();
45
+ const sessionId = input.sessionId ?? globalThis.crypto.randomUUID();
46
+ const runtimeId = input.runtimeId ?? globalThis.crypto.randomUUID();
47
+ const environment = input.environment ?? "development";
48
+ const productionBlocked = environment === "production" && input.allowProduction !== true;
49
+ this.config = {
50
+ projectId: input.projectId,
51
+ environmentId: input.environmentId,
52
+ collectorUrl: input.collectorUrl,
53
+ appVersion: input.appVersion,
54
+ environment,
55
+ branch: input.branch,
56
+ commitHash: input.commitHash,
57
+ sessionId,
58
+ runtimeId,
59
+ maxEventsPerBatch: Math.max(1, input.batching?.maxEventsPerBatch ?? 100),
60
+ batchIntervalMs: Math.max(10, input.batching?.batchIntervalMs ?? 300),
61
+ maxBufferedEvents: Math.max(1, input.batching?.maxBufferedEvents ?? 2_000),
62
+ maxRetryDelayMs: Math.max(100, input.batching?.maxRetryDelayMs ?? 5_000),
63
+ debug: input.debug ?? false,
64
+ onDiagnostic: input.onDiagnostic,
65
+ };
66
+ this.initialized = true;
67
+ this.enabled = input.enabled && !productionBlocked;
68
+ this.sessionTraceId = randomHex(16);
69
+ if (productionBlocked) {
70
+ this.emitDiagnostic({
71
+ level: "warning",
72
+ code: "production_disabled",
73
+ message: "ProbeMap browser SDK is disabled in production unless allowProduction is true.",
74
+ });
75
+ }
76
+ if (!this.enabled) {
77
+ return { sessionId, runtimeId };
78
+ }
79
+ this.transport = input.transport ?? new HttpProbeTransport(input.collectorUrl, undefined, input.auth);
80
+ this.sessionInput = {
81
+ id: sessionId,
82
+ projectId: input.projectId,
83
+ ...(input.environmentId === undefined ? {} : { environmentId: input.environmentId }),
84
+ environment,
85
+ ...(input.appVersion === undefined ? {} : { appVersion: input.appVersion }),
86
+ ...(input.branch === undefined ? {} : { branch: input.branch }),
87
+ ...(input.commitHash === undefined ? {} : { commitHash: input.commitHash }),
88
+ ...(input.integration === undefined ? {} : { integration: input.integration }),
89
+ };
90
+ this.enqueue(this.createEvent("session.start", "session.start", {
91
+ appVersion: input.appVersion ?? null,
92
+ environment,
93
+ }));
94
+ const autoCapture = typeof input.autoCapture === "object" ? input.autoCapture : {};
95
+ if (input.autoCapture === true || typeof input.autoCapture === "object") {
96
+ this.autoCaptureCleanup = installBrowserAutoCapture({
97
+ collectorUrl: input.collectorUrl,
98
+ record: (type, name, payload, status) => { this.recordEvent(type, name, payload, {}, status); },
99
+ diagnostic: (error) => this.emitDiagnostic({ level: "warning", code: "auto_capture_failed", message: "A browser auto-capture hook failed safely.", error }),
100
+ }, {
101
+ actions: autoCapture.actions ?? true,
102
+ network: autoCapture.network ?? true,
103
+ errors: autoCapture.errors ?? true,
104
+ navigation: autoCapture.navigation ?? true,
105
+ console: autoCapture.console ?? true,
106
+ highFrequencySampleMs: Math.max(16, autoCapture.highFrequencySampleMs ?? 100),
107
+ });
108
+ }
109
+ return { sessionId, runtimeId };
110
+ }
111
+ status() {
112
+ return {
113
+ initialized: this.initialized,
114
+ enabled: this.enabled,
115
+ pendingEvents: this.queue.length,
116
+ droppedEvents: this.droppedEvents,
117
+ consecutiveFailures: this.consecutiveFailures,
118
+ ...(this.lastError === undefined ? {} : { lastError: this.lastError }),
119
+ };
120
+ }
121
+ getTraceHeaders(handle) {
122
+ if (!this.enabled || this.config === undefined) {
123
+ return undefined;
124
+ }
125
+ const requestedFlow = handle === undefined ? undefined : this.flows.get(handle.id);
126
+ const activeFlowId = this.activeFlowIds.at(-1);
127
+ const flow = requestedFlow ?? (activeFlowId === undefined ? undefined : this.flows.get(activeFlowId));
128
+ const parentSpanId = flow?.lastSpanId;
129
+ if (flow === undefined || parentSpanId === undefined) {
130
+ return undefined;
131
+ }
132
+ try {
133
+ return createTraceHeaders({
134
+ projectId: this.config.projectId,
135
+ sessionId: this.config.sessionId,
136
+ flowId: flow.id,
137
+ traceId: flow.traceId,
138
+ parentSpanId,
139
+ sampled: true,
140
+ });
141
+ }
142
+ catch (error) {
143
+ this.emitDiagnostic({
144
+ level: "warning",
145
+ code: "trace_header_generation_failed",
146
+ message: "ProbeMap could not create trace propagation headers.",
147
+ error,
148
+ });
149
+ return undefined;
150
+ }
151
+ }
152
+ async ready() {
153
+ if (!this.enabled) {
154
+ return;
155
+ }
156
+ try {
157
+ await this.ensureSession();
158
+ }
159
+ catch (error) {
160
+ this.recordFailure("session_bootstrap_failed", error);
161
+ }
162
+ }
163
+ step(name, payload = {}, options = {}) {
164
+ return this.recordEvent("probe.step", name, payload, options);
165
+ }
166
+ observe(name, value, options = {}) {
167
+ return this.recordEvent("probe.observe", name, { value: safeSnapshot(value), schema: options.schema ?? null }, options);
168
+ }
169
+ assert(name, assertion) {
170
+ let evaluation;
171
+ try {
172
+ const result = evaluateBuiltIn(assertion.evaluator, assertion.input, assertion.expected);
173
+ evaluation = { status: result.status, message: result.message };
174
+ }
175
+ catch (error) {
176
+ evaluation = {
177
+ status: "unknown",
178
+ message: `Evaluator failed safely: ${messageFromError(error)}`,
179
+ };
180
+ }
181
+ const eventId = this.recordEvent("probe.assert", name, {
182
+ evaluator: assertion.evaluator,
183
+ input: safeSnapshot(assertion.input),
184
+ expected: safeSnapshot(assertion.expected),
185
+ result: evaluation,
186
+ }, assertion, evaluation.status);
187
+ return { ...evaluation, ...(eventId === undefined ? {} : { eventId }) };
188
+ }
189
+ /** @deprecated Use assert(). */
190
+ check(name, assertion) {
191
+ return this.assert(name, assertion);
192
+ }
193
+ captureException(error, options = {}) {
194
+ const normalized = error instanceof Error
195
+ ? { name: error.name, message: error.message.slice(0, 2_000), stack: error.stack?.slice(0, 8_000) }
196
+ : { message: String(error).slice(0, 2_000) };
197
+ return this.recordEvent("runtime.exception", error instanceof Error ? error.name : "browser.exception", normalized, options, "fail");
198
+ }
199
+ async flush() {
200
+ if (!this.enabled || this.queue.length === 0) {
201
+ this.clearTimer();
202
+ return;
203
+ }
204
+ if (this.flushPromise !== undefined) {
205
+ await this.flushPromise;
206
+ return;
207
+ }
208
+ this.clearTimer();
209
+ this.flushPromise = this.flushInternal().finally(() => {
210
+ this.flushPromise = undefined;
211
+ });
212
+ await this.flushPromise;
213
+ }
214
+ async destroy() {
215
+ if (!this.initialized) {
216
+ return;
217
+ }
218
+ for (const flowId of [...this.activeFlowIds].reverse()) {
219
+ this.endFlow(this.flows.get(flowId));
220
+ }
221
+ if (this.enabled) {
222
+ this.enqueue(this.createEvent("session.end", "session.end", {}));
223
+ await this.flush();
224
+ }
225
+ this.clearTimer();
226
+ this.initialized = false;
227
+ this.enabled = false;
228
+ }
229
+ reset() {
230
+ this.autoCaptureCleanup?.();
231
+ this.autoCaptureCleanup = undefined;
232
+ this.clearTimer();
233
+ this.initialized = false;
234
+ this.enabled = false;
235
+ this.config = undefined;
236
+ this.transport = undefined;
237
+ this.sessionInput = undefined;
238
+ this.sessionReady = false;
239
+ this.sessionPromise = undefined;
240
+ this.readyFlowIds.clear();
241
+ this.flowPromises.clear();
242
+ this.flowDefinitions.clear();
243
+ this.flows.clear();
244
+ this.activeFlowIds.length = 0;
245
+ this.queue = [];
246
+ this.flushPromise = undefined;
247
+ this.clientSequence = 0;
248
+ this.droppedEvents = 0;
249
+ this.consecutiveFailures = 0;
250
+ this.lastError = undefined;
251
+ }
252
+ startFlow(name, options) {
253
+ if (!this.enabled || this.config === undefined) {
254
+ return undefined;
255
+ }
256
+ try {
257
+ const flowId = globalThis.crypto.randomUUID();
258
+ const traceId = randomHex(16);
259
+ const rootSpanId = randomHex(8);
260
+ const flow = {
261
+ id: flowId,
262
+ name,
263
+ traceId,
264
+ rootSpanId,
265
+ lastSpanId: rootSpanId,
266
+ ended: false,
267
+ ...(options.contract === undefined ? {} : { contract: options.contract }),
268
+ };
269
+ const metadata = {
270
+ ...(options.metadata ?? {}),
271
+ ...(options.contract === undefined ? {} : { contract: options.contract }),
272
+ };
273
+ this.flows.set(flowId, flow);
274
+ this.activeFlowIds.push(flowId);
275
+ this.flowDefinitions.set(flowId, {
276
+ id: flowId,
277
+ projectId: this.config.projectId,
278
+ sessionId: this.config.sessionId,
279
+ name,
280
+ metadata,
281
+ });
282
+ this.enqueue(this.createEvent("flow.start", name, { contract: options.contract ?? null }, undefined, undefined, flow, rootSpanId));
283
+ return flow;
284
+ }
285
+ catch (error) {
286
+ this.emitDiagnostic({
287
+ level: "error",
288
+ code: "flow_start_failed",
289
+ message: "ProbeMap could not start a flow.",
290
+ error,
291
+ });
292
+ return undefined;
293
+ }
294
+ }
295
+ endFlow(handle) {
296
+ if (!this.enabled || handle === undefined) {
297
+ return;
298
+ }
299
+ const flow = this.flows.get(handle.id);
300
+ if (flow === undefined || flow.ended) {
301
+ return;
302
+ }
303
+ const event = this.createEvent("flow.end", flow.name, {}, { flow }, undefined);
304
+ flow.ended = true;
305
+ this.activeFlowIds.splice(this.activeFlowIds.lastIndexOf(flow.id), 1);
306
+ this.enqueue(event);
307
+ }
308
+ recordEvent(type, name, payload, options, status) {
309
+ if (!this.enabled) {
310
+ return undefined;
311
+ }
312
+ try {
313
+ const event = this.createEvent(type, name, payload, options, status);
314
+ this.enqueue(event);
315
+ return event.id;
316
+ }
317
+ catch (error) {
318
+ this.emitDiagnostic({
319
+ level: "error",
320
+ code: "event_record_failed",
321
+ message: `ProbeMap safely ignored a failed ${type} event.`,
322
+ error,
323
+ });
324
+ return undefined;
325
+ }
326
+ }
327
+ createEvent(type, name, payload, options, status, explicitFlow, explicitSpanId) {
328
+ const config = this.config;
329
+ if (config === undefined) {
330
+ throw new Error("ProbeMap browser SDK is not initialized.");
331
+ }
332
+ const requestedFlowId = options?.flow?.id;
333
+ const activeFlowId = this.activeFlowIds.at(-1);
334
+ const flow = explicitFlow ??
335
+ (requestedFlowId === undefined
336
+ ? activeFlowId === undefined
337
+ ? undefined
338
+ : this.flows.get(activeFlowId)
339
+ : this.flows.get(requestedFlowId));
340
+ const spanId = explicitSpanId ?? randomHex(8);
341
+ const parentSpanId = explicitSpanId !== undefined ? undefined : options?.parentSpanId ?? flow?.lastSpanId;
342
+ const event = {
343
+ id: globalThis.crypto.randomUUID(),
344
+ protocolVersion: PROTOCOL_VERSION,
345
+ sdkVersion: browserSdkVersion,
346
+ projectId: config.projectId,
347
+ sessionId: config.sessionId,
348
+ ...(flow === undefined ? {} : { flowId: flow.id }),
349
+ traceId: flow?.traceId ?? this.sessionTraceId,
350
+ spanId,
351
+ ...(parentSpanId === undefined ? {} : { parentSpanId }),
352
+ ...(options?.linkedSpanIds === undefined ? {} : { linkedSpanIds: options.linkedSpanIds }),
353
+ runtimeId: config.runtimeId,
354
+ clientSequence: ++this.clientSequence,
355
+ clientTimestamp: new Date().toISOString(),
356
+ monotonicTime: monotonicNow(),
357
+ type,
358
+ source: "browser-sdk",
359
+ ...(status === undefined ? {} : { status }),
360
+ name,
361
+ payload: safeSnapshot(payload),
362
+ ...(options?.tags === undefined ? {} : { tags: options.tags }),
363
+ ...(options?.relatedObjectIds === undefined
364
+ ? {}
365
+ : { relatedObjectIds: options.relatedObjectIds }),
366
+ ...(options?.fileHints === undefined ? {} : { fileHints: options.fileHints }),
367
+ privacyLevel: options?.privacyLevel ?? "safe",
368
+ };
369
+ if (flow !== undefined && explicitSpanId === undefined) {
370
+ flow.lastSpanId = spanId;
371
+ }
372
+ return event;
373
+ }
374
+ enqueue(event) {
375
+ const config = this.config;
376
+ if (!this.enabled || config === undefined) {
377
+ return;
378
+ }
379
+ if (this.queue.length >= config.maxBufferedEvents) {
380
+ this.queue.shift();
381
+ this.droppedEvents += 1;
382
+ this.emitDiagnostic({
383
+ level: "warning",
384
+ code: "buffer_overflow",
385
+ message: "ProbeMap dropped the oldest buffered event because the ring buffer is full.",
386
+ });
387
+ }
388
+ this.queue.push(event);
389
+ this.scheduleFlush(config.batchIntervalMs);
390
+ }
391
+ scheduleFlush(delayMs) {
392
+ if (this.timer !== undefined || !this.enabled) {
393
+ return;
394
+ }
395
+ this.timer = setTimeout(() => {
396
+ this.timer = undefined;
397
+ void this.flush();
398
+ }, delayMs);
399
+ }
400
+ clearTimer() {
401
+ if (this.timer !== undefined) {
402
+ clearTimeout(this.timer);
403
+ this.timer = undefined;
404
+ }
405
+ }
406
+ async flushInternal() {
407
+ const config = this.config;
408
+ const transport = this.transport;
409
+ if (config === undefined || transport === undefined) {
410
+ return;
411
+ }
412
+ while (this.queue.length > 0) {
413
+ const batchEvents = this.queue.splice(0, config.maxEventsPerBatch);
414
+ try {
415
+ await this.ensureSession();
416
+ await this.ensureFlows(batchEvents);
417
+ const batch = {
418
+ projectId: config.projectId,
419
+ sessionId: config.sessionId,
420
+ events: batchEvents,
421
+ };
422
+ const response = await transport.sendBatch(batch);
423
+ if (response.accepted + response.duplicates !== batchEvents.length) {
424
+ this.emitDiagnostic({
425
+ level: "warning",
426
+ code: "partial_batch_acknowledgement",
427
+ message: "Collector acknowledgement count does not match the sent event batch.",
428
+ });
429
+ }
430
+ this.consecutiveFailures = 0;
431
+ this.lastError = undefined;
432
+ }
433
+ catch (error) {
434
+ const combined = [...batchEvents, ...this.queue];
435
+ const overflow = Math.max(0, combined.length - config.maxBufferedEvents);
436
+ this.queue = combined.slice(-config.maxBufferedEvents);
437
+ this.droppedEvents += overflow;
438
+ this.recordFailure("batch_send_failed", error);
439
+ const retryDelay = Math.min(config.batchIntervalMs * 2 ** Math.min(this.consecutiveFailures, 6), config.maxRetryDelayMs);
440
+ this.scheduleFlush(retryDelay);
441
+ return;
442
+ }
443
+ }
444
+ }
445
+ async ensureSession() {
446
+ if (this.sessionReady) {
447
+ return;
448
+ }
449
+ if (this.sessionPromise !== undefined) {
450
+ await this.sessionPromise;
451
+ return;
452
+ }
453
+ if (this.transport === undefined || this.sessionInput === undefined) {
454
+ throw new Error("ProbeMap session transport is not configured.");
455
+ }
456
+ this.sessionPromise = this.transport.bootstrapSession(this.sessionInput);
457
+ try {
458
+ await this.sessionPromise;
459
+ this.sessionReady = true;
460
+ }
461
+ finally {
462
+ this.sessionPromise = undefined;
463
+ }
464
+ }
465
+ async ensureFlows(events) {
466
+ const flowIds = new Set(events.flatMap((event) => (event.flowId === undefined ? [] : [event.flowId])));
467
+ for (const flowId of flowIds) {
468
+ if (this.readyFlowIds.has(flowId)) {
469
+ continue;
470
+ }
471
+ let promise = this.flowPromises.get(flowId);
472
+ if (promise === undefined) {
473
+ const definition = this.flowDefinitions.get(flowId);
474
+ if (definition === undefined || this.transport === undefined) {
475
+ throw new Error(`Flow ${flowId} has no bootstrap definition.`);
476
+ }
477
+ promise = this.transport.bootstrapFlow(definition);
478
+ this.flowPromises.set(flowId, promise);
479
+ }
480
+ try {
481
+ await promise;
482
+ this.readyFlowIds.add(flowId);
483
+ }
484
+ finally {
485
+ this.flowPromises.delete(flowId);
486
+ }
487
+ }
488
+ }
489
+ recordFailure(code, error) {
490
+ this.consecutiveFailures += 1;
491
+ this.lastError = messageFromError(error);
492
+ this.emitDiagnostic({
493
+ level: "warning",
494
+ code,
495
+ message: "ProbeMap retained the event batch and will retry without interrupting the host app.",
496
+ error,
497
+ });
498
+ }
499
+ emitDiagnostic(diagnostic) {
500
+ try {
501
+ this.config?.onDiagnostic?.(diagnostic);
502
+ }
503
+ catch {
504
+ // Diagnostics must never affect the host application.
505
+ }
506
+ if (this.config?.debug === true) {
507
+ try {
508
+ console.warn(`[ProbeMap] ${diagnostic.code}: ${diagnostic.message}`);
509
+ }
510
+ catch {
511
+ // Console implementations can be patched by host applications.
512
+ }
513
+ }
514
+ }
515
+ }
516
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type EventBatch, type EventIngestResponse, type FlowCreateInput, type SessionCreateInput, type ProbeAuth } from "@probemap/shared";
2
+ import type { ProbeTransport } from "./types.js";
3
+ export type FetchFunction = typeof globalThis.fetch;
4
+ export declare class HttpProbeTransport implements ProbeTransport {
5
+ private readonly fetchFunction;
6
+ private readonly auth?;
7
+ private readonly baseUrl;
8
+ constructor(collectorUrl: string, fetchFunction?: FetchFunction, auth?: ProbeAuth | undefined);
9
+ private post;
10
+ bootstrapSession(input: SessionCreateInput): Promise<void>;
11
+ bootstrapFlow(input: FlowCreateInput): Promise<void>;
12
+ sendBatch(batch: EventBatch): Promise<EventIngestResponse>;
13
+ }
14
+ //# sourceMappingURL=http-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-transport.d.ts","sourceRoot":"","sources":["../src/http-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EAEvB,KAAK,SAAS,EACf,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,MAAM,aAAa,GAAG,OAAO,UAAU,CAAC,KAAK,CAAC;AAEpD,qBAAa,kBAAmB,YAAW,cAAc;IAKrD,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;IALxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,YACE,YAAY,EAAE,MAAM,EACH,aAAa,GAAE,aAAiD,EAChE,IAAI,CAAC,EAAE,SAAS,YAAA,EAGlC;YAEa,IAAI;IAkBL,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtE;IAEY,aAAa,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhE;IAEY,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAGtE;CACF"}
@@ -0,0 +1,35 @@
1
+ import { eventIngestResponseSchema, resolveProbeAuthToken, } from "@probemap/shared";
2
+ export class HttpProbeTransport {
3
+ fetchFunction;
4
+ auth;
5
+ baseUrl;
6
+ constructor(collectorUrl, fetchFunction = globalThis.fetch.bind(globalThis), auth) {
7
+ this.fetchFunction = fetchFunction;
8
+ this.auth = auth;
9
+ this.baseUrl = collectorUrl.replace(/\/$/, "");
10
+ }
11
+ async post(path, body) {
12
+ const token = await resolveProbeAuthToken(this.auth);
13
+ const response = await this.fetchFunction(`${this.baseUrl}${path}`, {
14
+ method: "POST",
15
+ headers: { "content-type": "application/json", ...(token === undefined ? {} : { authorization: `Bearer ${token}` }) },
16
+ body: JSON.stringify(body),
17
+ });
18
+ if (!response.ok) {
19
+ const responseBody = (await response.text()).slice(0, 2_000);
20
+ throw new Error(`ProbeMap collector returned ${response.status} for ${path}: ${responseBody}`);
21
+ }
22
+ return response;
23
+ }
24
+ async bootstrapSession(input) {
25
+ await this.post("/api/sessions", input);
26
+ }
27
+ async bootstrapFlow(input) {
28
+ await this.post("/api/flows", input);
29
+ }
30
+ async sendBatch(batch) {
31
+ const response = await this.post("/api/events/batch", batch);
32
+ return eventIngestResponseSchema.parse(await response.json());
33
+ }
34
+ }
35
+ //# sourceMappingURL=http-transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-transport.js","sourceRoot":"","sources":["../src/http-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EAKzB,qBAAqB,GAEtB,MAAM,kBAAkB,CAAC;AAM1B,MAAM,OAAO,kBAAkB;IAKV,aAAa;IACb,IAAI;IALN,OAAO,CAAS;IAEjC,YACE,YAAoB,EACH,aAAa,GAAkB,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,EAChE,IAAgB;6BADhB,aAAa;oBACb,IAAI;QAErB,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACjD,CAAC;IAEO,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,IAAa;QAC5C,MAAM,KAAK,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;YAClE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC,EAAE;YACrH,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,YAAY,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YAC7D,MAAM,IAAI,KAAK,CACb,+BAA+B,QAAQ,CAAC,MAAM,QAAQ,IAAI,KAAK,YAAY,EAAE,CAC9E,CAAC;QACJ,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEM,KAAK,CAAC,gBAAgB,CAAC,KAAyB;QACrD,MAAM,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC;IAEM,KAAK,CAAC,aAAa,CAAC,KAAsB;QAC/C,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IACvC,CAAC;IAEM,KAAK,CAAC,SAAS,CAAC,KAAiB;QACtC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;QAC7D,OAAO,yBAAyB,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ export * from "./client.js";
2
+ export * from "./auto-capture.js";
3
+ export * from "./http-transport.js";
4
+ export * from "./safe-snapshot.js";
5
+ export * from "./types.js";
6
+ import { BrowserProbeClient } from "./client.js";
7
+ export declare const probe: BrowserProbeClient;
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,eAAO,MAAM,KAAK,oBAA2B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export * from "./client.js";
2
+ export * from "./auto-capture.js";
3
+ export * from "./http-transport.js";
4
+ export * from "./safe-snapshot.js";
5
+ export * from "./types.js";
6
+ import { BrowserProbeClient } from "./client.js";
7
+ export const probe = new BrowserProbeClient();
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,CAAC,MAAM,KAAK,GAAG,IAAI,kBAAkB,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { safeSnapshot } from "@probemap/shared";
2
+ //# sourceMappingURL=safe-snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-snapshot.d.ts","sourceRoot":"","sources":["../src/safe-snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { safeSnapshot } from "@probemap/shared";
2
+ //# sourceMappingURL=safe-snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-snapshot.js","sourceRoot":"","sources":["../src/safe-snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,90 @@
1
+ import type { EvaluatorReference, EventBatch, EventIngestResponse, FileHint, FlowCreateInput, IntegrationIdentity, ProbeAuth, ProbeMapEvent, ProbeStatus, SessionCreateInput } from "@probemap/shared";
2
+ export interface ProbeTransport {
3
+ bootstrapSession(input: SessionCreateInput): Promise<void>;
4
+ bootstrapFlow(input: FlowCreateInput): Promise<void>;
5
+ sendBatch(batch: EventBatch): Promise<EventIngestResponse>;
6
+ }
7
+ export interface BrowserProbeDiagnostic {
8
+ level: "warning" | "error";
9
+ code: string;
10
+ message: string;
11
+ error?: unknown;
12
+ }
13
+ export interface BrowserProbeConfig {
14
+ projectId: string;
15
+ environmentId?: string;
16
+ collectorUrl: string;
17
+ enabled: boolean;
18
+ allowProduction?: boolean;
19
+ appVersion?: string;
20
+ environment?: string;
21
+ branch?: string;
22
+ commitHash?: string;
23
+ sessionId?: string;
24
+ runtimeId?: string;
25
+ integration?: IntegrationIdentity;
26
+ auth?: ProbeAuth;
27
+ transport?: ProbeTransport;
28
+ batching?: {
29
+ maxEventsPerBatch?: number;
30
+ batchIntervalMs?: number;
31
+ maxBufferedEvents?: number;
32
+ maxRetryDelayMs?: number;
33
+ };
34
+ debug?: boolean;
35
+ autoCapture?: boolean | {
36
+ actions?: boolean;
37
+ network?: boolean;
38
+ errors?: boolean;
39
+ navigation?: boolean;
40
+ console?: boolean;
41
+ highFrequencySampleMs?: number;
42
+ };
43
+ onDiagnostic?: (diagnostic: BrowserProbeDiagnostic) => void;
44
+ }
45
+ export interface ProbeEventOptions {
46
+ flow?: FlowHandle;
47
+ parentSpanId?: string;
48
+ linkedSpanIds?: string[];
49
+ tags?: string[];
50
+ relatedObjectIds?: string[];
51
+ fileHints?: FileHint[];
52
+ privacyLevel?: ProbeMapEvent["privacyLevel"];
53
+ }
54
+ export interface ObserveOptions extends ProbeEventOptions {
55
+ schema?: string;
56
+ }
57
+ export interface AssertInput extends ProbeEventOptions {
58
+ evaluator: EvaluatorReference;
59
+ input: unknown;
60
+ expected?: unknown;
61
+ }
62
+ export interface FlowContractReference {
63
+ key: string;
64
+ version: number;
65
+ }
66
+ export interface FlowStartOptions {
67
+ contract?: FlowContractReference;
68
+ metadata?: Record<string, unknown>;
69
+ }
70
+ export interface FlowHandle {
71
+ readonly id: string;
72
+ readonly name: string;
73
+ readonly traceId: string;
74
+ readonly rootSpanId: string;
75
+ readonly contract?: FlowContractReference;
76
+ }
77
+ export interface BrowserProbeStatus {
78
+ initialized: boolean;
79
+ enabled: boolean;
80
+ pendingEvents: number;
81
+ droppedEvents: number;
82
+ consecutiveFailures: number;
83
+ lastError?: string;
84
+ }
85
+ export interface AssertionRecordResult {
86
+ eventId?: string;
87
+ status: Extract<ProbeStatus, "pass" | "fail" | "unknown">;
88
+ message: string;
89
+ }
90
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@probemap/browser",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "import": "./dist/index.js"
9
+ }
10
+ },
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "dependencies": {
18
+ "@probemap/shared": "^0.1.0"
19
+ },
20
+ "devDependencies": {
21
+ "drizzle-orm": "0.45.2",
22
+ "@probemap/collector": "0.0.0",
23
+ "@probemap/storage": "0.0.0"
24
+ },
25
+ "scripts": {
26
+ "build": "tsc -p tsconfig.json",
27
+ "typecheck": "tsc -p tsconfig.json --noEmit",
28
+ "test": "vitest run --passWithNoTests"
29
+ }
30
+ }