@reopt-ai/data-sdk-client 0.1.5 → 0.2.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.
- package/README.md +141 -7
- package/dist/client-B1GlWwVq.d.ts +744 -0
- package/dist/client-B1GlWwVq.d.ts.map +1 -0
- package/dist/client-BCrui21p.d.cts +744 -0
- package/dist/client-BCrui21p.d.cts.map +1 -0
- package/dist/exceptions-C9Fh0BIR.js +285 -0
- package/dist/exceptions-C9Fh0BIR.js.map +1 -0
- package/dist/exceptions-CuhGo9A5.cjs +289 -0
- package/dist/exceptions-CuhGo9A5.cjs.map +1 -0
- package/dist/index.cjs +75 -1874
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +83 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +35 -33
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -70
- package/dist/index.js.map +1 -1
- package/dist/next.cjs +51 -1919
- package/dist/next.cjs.map +1 -1
- package/dist/next.d.cts +31 -0
- package/dist/next.d.cts.map +1 -0
- package/dist/next.d.ts +8 -10
- package/dist/next.d.ts.map +1 -0
- package/dist/next.js +36 -49
- package/dist/next.js.map +1 -1
- package/dist/observe-D-BHMwrO.cjs +54 -0
- package/dist/observe-D-BHMwrO.cjs.map +1 -0
- package/dist/observe-D1pNg1qL.js +54 -0
- package/dist/observe-D1pNg1qL.js.map +1 -0
- package/dist/react.cjs +105 -1863
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +80 -0
- package/dist/react.d.cts.map +1 -0
- package/dist/react.d.ts +53 -47
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +118 -23
- package/dist/react.js.map +1 -1
- package/dist/registry-BPhiH_l9.js +1775 -0
- package/dist/registry-BPhiH_l9.js.map +1 -0
- package/dist/registry-CGqrOtf4.cjs +1810 -0
- package/dist/registry-CGqrOtf4.cjs.map +1 -0
- package/dist/tracing-DAhaKkl0.cjs +93 -0
- package/dist/tracing-DAhaKkl0.cjs.map +1 -0
- package/dist/tracing-Dt1RVuQ9.js +93 -0
- package/dist/tracing-Dt1RVuQ9.js.map +1 -0
- package/package.json +31 -16
- package/dist/chunk-2UPF3C7D.js +0 -106
- package/dist/chunk-2UPF3C7D.js.map +0 -1
- package/dist/chunk-4MTDZBRS.js +0 -57
- package/dist/chunk-4MTDZBRS.js.map +0 -1
- package/dist/chunk-BJGIHFDA.js +0 -1627
- package/dist/chunk-BJGIHFDA.js.map +0 -1
- package/dist/client-TesmBLXd.d.ts +0 -581
- package/dist/exceptions-NQHZUDYO.js +0 -9
- package/dist/exceptions-NQHZUDYO.js.map +0 -1
- package/dist/tracing-LC3NZND7.js +0 -91
- package/dist/tracing-LC3NZND7.js.map +0 -1
|
@@ -0,0 +1,744 @@
|
|
|
1
|
+
import "@reopt-ai/data-contract/ingest";
|
|
2
|
+
import { ExceptionEntry, ExceptionLevel, ExceptionStep } from "@reopt-ai/data-contract/events";
|
|
3
|
+
import { ConsentCookieState, DeviceCookieState, ReoptBootstrap } from "@reopt-ai/data-contract/identity";
|
|
4
|
+
//#region ../data-sdk-core/src/types.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Types shared by every runtime. Nothing here refers to `window`, `document`
|
|
7
|
+
* or a Node built-in — the runtime-specific pieces are injected through
|
|
8
|
+
* {@link ReoptRuntime}.
|
|
9
|
+
*/
|
|
10
|
+
/** Consent categories. `analytics` is the one whose refusal stops everything. */
|
|
11
|
+
type ConsentCategory = "analytics" | "marketing" | "functional" | "performance";
|
|
12
|
+
interface ConsentConfig {
|
|
13
|
+
/** Default decision for every configured category. Default: `true` (opt-out model). */
|
|
14
|
+
defaultConsent?: boolean | undefined;
|
|
15
|
+
/** Categories the integration recognises. Default: `["analytics"]`. */
|
|
16
|
+
categories?: ConsentCategory[] | undefined;
|
|
17
|
+
/** Persist decisions through the runtime's storage. Default: `true`. */
|
|
18
|
+
persist?: boolean | undefined;
|
|
19
|
+
}
|
|
20
|
+
/** Minimal synchronous key/value store — `localStorage`-shaped on purpose. */
|
|
21
|
+
interface StorageBackend {
|
|
22
|
+
getItem(key: string): string | null;
|
|
23
|
+
setItem(key: string, value: string): void;
|
|
24
|
+
removeItem(key: string): void;
|
|
25
|
+
}
|
|
26
|
+
interface RetryConfig {
|
|
27
|
+
/** Attempts after the first. Default: 3. */
|
|
28
|
+
maxRetries?: number | undefined;
|
|
29
|
+
/** First back-off, milliseconds. Default: 1000. */
|
|
30
|
+
baseDelay?: number | undefined;
|
|
31
|
+
/** Back-off ceiling, milliseconds. Default: 30000. */
|
|
32
|
+
maxDelay?: number | undefined;
|
|
33
|
+
/** ± fraction of the delay. Default: 0.1. */
|
|
34
|
+
jitter?: number | undefined;
|
|
35
|
+
}
|
|
36
|
+
interface CircuitBreakerConfig {
|
|
37
|
+
/** Consecutive transient failures before the circuit opens. Default: 5. */
|
|
38
|
+
failureThreshold?: number | undefined;
|
|
39
|
+
/** How long the circuit stays open before one probe is allowed. Default: 60000. */
|
|
40
|
+
recoveryTimeout?: number | undefined;
|
|
41
|
+
}
|
|
42
|
+
interface BatchConfig {
|
|
43
|
+
/** Events per request. Default: 100. */
|
|
44
|
+
size?: number | undefined;
|
|
45
|
+
/** Milliseconds to wait for a batch to fill before sending. Default: 1000. */
|
|
46
|
+
intervalMs?: number | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Serialized bytes per request. Default: 400 000, under the server's
|
|
49
|
+
* 512 000 hard cap with room for the JSON envelope. A 413 is a 4xx, and 4xx
|
|
50
|
+
* drops the batch — so overshooting the cap loses every event in it.
|
|
51
|
+
*/
|
|
52
|
+
maxBytes?: number | undefined;
|
|
53
|
+
}
|
|
54
|
+
/** Browser credentials — public, ships in the page. */
|
|
55
|
+
interface WriteKeyAuth {
|
|
56
|
+
writeKey: string;
|
|
57
|
+
}
|
|
58
|
+
/** Server credentials — must never reach a client bundle. */
|
|
59
|
+
interface ClientCredentialsAuth {
|
|
60
|
+
clientId: string;
|
|
61
|
+
clientSecret: string;
|
|
62
|
+
}
|
|
63
|
+
type ReoptAuth = WriteKeyAuth | ClientCredentialsAuth;
|
|
64
|
+
type FetchLike = (input: string, init: FetchInit) => Promise<FetchResponseLike>;
|
|
65
|
+
interface FetchInit {
|
|
66
|
+
method: string;
|
|
67
|
+
headers: Record<string, string>;
|
|
68
|
+
body: string;
|
|
69
|
+
keepalive?: boolean | undefined;
|
|
70
|
+
}
|
|
71
|
+
interface FetchResponseLike {
|
|
72
|
+
ok: boolean;
|
|
73
|
+
status: number;
|
|
74
|
+
headers: {
|
|
75
|
+
get(name: string): string | null;
|
|
76
|
+
};
|
|
77
|
+
text(): Promise<string>;
|
|
78
|
+
}
|
|
79
|
+
/** Context the runtime fills in for a `$pageview` when the caller does not. */
|
|
80
|
+
interface PageContext {
|
|
81
|
+
path?: string | undefined;
|
|
82
|
+
origin?: string | undefined;
|
|
83
|
+
title?: string | undefined;
|
|
84
|
+
referrer?: string | undefined;
|
|
85
|
+
utm?: UTMParams | undefined;
|
|
86
|
+
/** Extra properties the runtime derived from the page, e.g. a `normalizePath` hook's output. */
|
|
87
|
+
properties?: Record<string, unknown> | undefined;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Everything the engine needs from the world around it. The browser package
|
|
91
|
+
* fills this from cookies, `localStorage` and `window`; the server package
|
|
92
|
+
* from request cookies and headers; tests from plain objects.
|
|
93
|
+
*/
|
|
94
|
+
interface ReoptRuntime {
|
|
95
|
+
/** Resolved device id. Identity resolution is the runtime's job, not the engine's. */
|
|
96
|
+
deviceId: string;
|
|
97
|
+
/**
|
|
98
|
+
* Value for the `reopt-session-id` header — the `"<id>.<token>"` credential
|
|
99
|
+
* ingest handed back, if the runtime kept it. Unsigned values are ignored
|
|
100
|
+
* by ingest, so only send what came from `onSession`.
|
|
101
|
+
*/
|
|
102
|
+
getSessionId?: (() => string | null | undefined) | undefined;
|
|
103
|
+
/** Ingest assigned (or confirmed) a session for this batch. The runtime persists it. */
|
|
104
|
+
onSession?: ((credential: {
|
|
105
|
+
id: string;
|
|
106
|
+
token: string;
|
|
107
|
+
}) => void) | undefined | undefined;
|
|
108
|
+
/** Durable store for the offline queue and consent. Absent = memory only. */
|
|
109
|
+
storage?: StorageBackend | undefined;
|
|
110
|
+
/** Clock. Defaults to `Date.now`; the browser package corrects for server skew. */
|
|
111
|
+
now?: (() => number) | undefined | undefined;
|
|
112
|
+
/** Id generator. Defaults to monotonic UUIDv7. */
|
|
113
|
+
createId?: (() => string) | undefined | undefined;
|
|
114
|
+
/** `fetch` implementation. Defaults to `globalThis.fetch`. */
|
|
115
|
+
fetch?: FetchLike | undefined;
|
|
116
|
+
/**
|
|
117
|
+
* Subscribe to "the process is about to go away" signals (pagehide,
|
|
118
|
+
* visibilitychange, SIGTERM). The engine flushes on each signal. Returns
|
|
119
|
+
* the unsubscribe function.
|
|
120
|
+
*/
|
|
121
|
+
onFlushSignal?: (flush: () => void) => () => void | undefined | undefined;
|
|
122
|
+
/**
|
|
123
|
+
* Last-chance delivery used when a flush signal fires, e.g. `sendBeacon`.
|
|
124
|
+
* Return `true` if the runtime accepted the payload; `false` falls back to
|
|
125
|
+
* keepalive fetch.
|
|
126
|
+
*/
|
|
127
|
+
sendLastChance?: ((url: string, body: string, headers: Record<string, string>) => boolean) | undefined | undefined;
|
|
128
|
+
/** Defaults for `$pageview` properties. */
|
|
129
|
+
getPageContext?: (() => PageContext) | undefined | undefined;
|
|
130
|
+
/**
|
|
131
|
+
* Mint and persist a fresh device id. Called by `reset()`; without it a
|
|
132
|
+
* reset keeps the old device, which is wrong on a shared machine.
|
|
133
|
+
*/
|
|
134
|
+
regenerateDeviceId?: (() => string) | undefined | undefined;
|
|
135
|
+
}
|
|
136
|
+
interface ReoptCoreConfig {
|
|
137
|
+
auth: ReoptAuth;
|
|
138
|
+
/** Origin of the reopt-data deployment, or a same-origin proxy prefix like `/ingest`. */
|
|
139
|
+
baseUrl: string;
|
|
140
|
+
runtime: ReoptRuntime;
|
|
141
|
+
debug?: boolean | undefined;
|
|
142
|
+
batch?: BatchConfig | undefined;
|
|
143
|
+
/** Upper bound on queued events; the oldest are dropped past it. Default: 10000. */
|
|
144
|
+
maxQueueSize?: number | undefined;
|
|
145
|
+
retry?: RetryConfig | undefined;
|
|
146
|
+
circuitBreaker?: CircuitBreakerConfig | undefined;
|
|
147
|
+
consent?: ConsentConfig | undefined;
|
|
148
|
+
/** Prefix for storage keys. Default: `reopt_`. */
|
|
149
|
+
storagePrefix?: string | undefined;
|
|
150
|
+
/** Persist the queue through `runtime.storage`. Default: `true` when storage exists. */
|
|
151
|
+
enableOfflineBuffer?: boolean | undefined;
|
|
152
|
+
/** Flush on runtime flush signals. Default: `true` when the runtime provides them. */
|
|
153
|
+
autoFlushOnUnload?: boolean | undefined;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Identity a single event was recorded under, when it differs from the
|
|
157
|
+
* runtime's. The server SDK uses this to file events from many requests
|
|
158
|
+
* through one engine: each request's device travels with its events and
|
|
159
|
+
* becomes that batch's `reopt-device-id`.
|
|
160
|
+
*/
|
|
161
|
+
interface EventIdentity {
|
|
162
|
+
deviceId?: string | undefined;
|
|
163
|
+
sessionId?: string | null | undefined;
|
|
164
|
+
}
|
|
165
|
+
interface TrackEventOptions {
|
|
166
|
+
/** File this event under another visitor than the runtime's. Server SDK use. */
|
|
167
|
+
identity?: EventIdentity | undefined;
|
|
168
|
+
name: string;
|
|
169
|
+
properties?: Record<string, unknown> | undefined;
|
|
170
|
+
profileId?: string | number | undefined;
|
|
171
|
+
/** Consent category this event belongs to. Default: `analytics`. */
|
|
172
|
+
consentCategory?: ConsentCategory | undefined;
|
|
173
|
+
}
|
|
174
|
+
interface IdentifyOptions {
|
|
175
|
+
/** File this event under another visitor than the runtime's. Server SDK use. */
|
|
176
|
+
identity?: EventIdentity | undefined;
|
|
177
|
+
profileId: string | number;
|
|
178
|
+
firstName?: string | undefined;
|
|
179
|
+
lastName?: string | undefined;
|
|
180
|
+
email?: string | undefined;
|
|
181
|
+
avatar?: string | undefined;
|
|
182
|
+
properties?: Record<string, unknown> | undefined;
|
|
183
|
+
consentCategory?: ConsentCategory | undefined;
|
|
184
|
+
}
|
|
185
|
+
interface IncrementOptions {
|
|
186
|
+
/** File this event under another visitor than the runtime's. Server SDK use. */
|
|
187
|
+
identity?: EventIdentity | undefined;
|
|
188
|
+
profileId: string | number;
|
|
189
|
+
property: string;
|
|
190
|
+
value?: number | undefined;
|
|
191
|
+
consentCategory?: ConsentCategory | undefined;
|
|
192
|
+
}
|
|
193
|
+
interface DecrementOptions {
|
|
194
|
+
/** File this event under another visitor than the runtime's. Server SDK use. */
|
|
195
|
+
identity?: EventIdentity | undefined;
|
|
196
|
+
profileId: string | number;
|
|
197
|
+
property: string;
|
|
198
|
+
value?: number | undefined;
|
|
199
|
+
consentCategory?: ConsentCategory | undefined;
|
|
200
|
+
}
|
|
201
|
+
interface UTMParams {
|
|
202
|
+
utm_source?: string | undefined;
|
|
203
|
+
utm_medium?: string | undefined;
|
|
204
|
+
utm_campaign?: string | undefined;
|
|
205
|
+
utm_term?: string | undefined;
|
|
206
|
+
utm_content?: string | undefined;
|
|
207
|
+
}
|
|
208
|
+
interface PageViewOptions {
|
|
209
|
+
/** File this event under another visitor than the runtime's. Server SDK use. */
|
|
210
|
+
identity?: EventIdentity | undefined;
|
|
211
|
+
path?: string | undefined;
|
|
212
|
+
/** Scheme + host. */
|
|
213
|
+
origin?: string | undefined;
|
|
214
|
+
title?: string | undefined;
|
|
215
|
+
referrer?: string | undefined;
|
|
216
|
+
properties?: Record<string, unknown> | undefined;
|
|
217
|
+
utm?: UTMParams | undefined;
|
|
218
|
+
consentCategory?: ConsentCategory | undefined;
|
|
219
|
+
}
|
|
220
|
+
type EventPayload = {
|
|
221
|
+
type: "track";
|
|
222
|
+
eventId: string;
|
|
223
|
+
timestamp: number;
|
|
224
|
+
payload: {
|
|
225
|
+
name: string;
|
|
226
|
+
properties?: Record<string, unknown> | undefined;
|
|
227
|
+
profileId?: string | number | undefined;
|
|
228
|
+
};
|
|
229
|
+
} | {
|
|
230
|
+
type: "identify";
|
|
231
|
+
eventId: string;
|
|
232
|
+
timestamp: number;
|
|
233
|
+
payload: {
|
|
234
|
+
profileId: string | number;
|
|
235
|
+
firstName?: string | undefined;
|
|
236
|
+
lastName?: string | undefined;
|
|
237
|
+
email?: string | undefined;
|
|
238
|
+
avatar?: string | undefined;
|
|
239
|
+
properties?: Record<string, unknown> | undefined;
|
|
240
|
+
};
|
|
241
|
+
} | {
|
|
242
|
+
type: "increment";
|
|
243
|
+
eventId: string;
|
|
244
|
+
timestamp: number;
|
|
245
|
+
payload: {
|
|
246
|
+
profileId: string | number;
|
|
247
|
+
property: string;
|
|
248
|
+
value?: number;
|
|
249
|
+
};
|
|
250
|
+
} | {
|
|
251
|
+
type: "decrement";
|
|
252
|
+
eventId: string;
|
|
253
|
+
timestamp: number;
|
|
254
|
+
payload: {
|
|
255
|
+
profileId: string | number;
|
|
256
|
+
property: string;
|
|
257
|
+
value?: number;
|
|
258
|
+
};
|
|
259
|
+
};
|
|
260
|
+
type QueueDropReason = "tracking_paused" | "consent_denied" | "validation_failed" | "payload_too_large";
|
|
261
|
+
interface QueueResult {
|
|
262
|
+
eventId: string;
|
|
263
|
+
queued: boolean;
|
|
264
|
+
reason?: QueueDropReason | undefined;
|
|
265
|
+
errors?: Array<{
|
|
266
|
+
field: string;
|
|
267
|
+
message: string;
|
|
268
|
+
}> | undefined;
|
|
269
|
+
}
|
|
270
|
+
interface FlushResult {
|
|
271
|
+
status: "idle" | "success" | "failed" | "skipped";
|
|
272
|
+
sent: number;
|
|
273
|
+
failed: number;
|
|
274
|
+
pending: number;
|
|
275
|
+
}
|
|
276
|
+
interface FlushOptions {
|
|
277
|
+
/** Ask the transport to outlive the page (keepalive fetch / beacon). */
|
|
278
|
+
keepalive?: boolean | undefined;
|
|
279
|
+
/** Keep sending until the queue is empty or no progress is made. */
|
|
280
|
+
drain?: boolean | undefined;
|
|
281
|
+
}
|
|
282
|
+
//#endregion
|
|
283
|
+
//#region ../data-sdk-core/src/consent.d.ts
|
|
284
|
+
type ConsentState = Record<string, boolean>;
|
|
285
|
+
//#endregion
|
|
286
|
+
//#region ../data-sdk-core/src/transport.d.ts
|
|
287
|
+
interface BatchDelivery {
|
|
288
|
+
sent: number;
|
|
289
|
+
failed: number;
|
|
290
|
+
/** The signed session credential ingest returned, when it did. */
|
|
291
|
+
session?: {
|
|
292
|
+
id: string;
|
|
293
|
+
token: string;
|
|
294
|
+
} | undefined;
|
|
295
|
+
}
|
|
296
|
+
interface SendOptions {
|
|
297
|
+
keepalive?: boolean | undefined;
|
|
298
|
+
/** Overrides the runtime's device/session for this request only. */
|
|
299
|
+
identity?: EventIdentity | undefined;
|
|
300
|
+
}
|
|
301
|
+
interface Transport {
|
|
302
|
+
readonly url: string;
|
|
303
|
+
headers(identity?: EventIdentity): Record<string, string>;
|
|
304
|
+
send(batch: EventPayload[], options?: SendOptions): Promise<BatchDelivery>;
|
|
305
|
+
}
|
|
306
|
+
//#endregion
|
|
307
|
+
//#region ../data-sdk-core/src/client.d.ts
|
|
308
|
+
/**
|
|
309
|
+
* The engine: queue → batch → transport, with retry, a circuit breaker and
|
|
310
|
+
* consent gates. Everything that differs between browser and server comes in
|
|
311
|
+
* through {@link ReoptRuntime}; the engine itself never touches `window`,
|
|
312
|
+
* `document`, `process` or a Node built-in.
|
|
313
|
+
*/
|
|
314
|
+
declare class ReoptCore {
|
|
315
|
+
protected readonly runtime: ReoptRuntime;
|
|
316
|
+
protected readonly transport: Transport;
|
|
317
|
+
private readonly queue;
|
|
318
|
+
private readonly consent;
|
|
319
|
+
private readonly breaker;
|
|
320
|
+
private readonly retry;
|
|
321
|
+
private readonly batch;
|
|
322
|
+
private readonly factory;
|
|
323
|
+
private readonly debug;
|
|
324
|
+
private deviceId;
|
|
325
|
+
private profileId;
|
|
326
|
+
private globalProperties;
|
|
327
|
+
private activeFlush;
|
|
328
|
+
private flushTimeout;
|
|
329
|
+
private removeFlushSignal;
|
|
330
|
+
private closed;
|
|
331
|
+
/** Bumped by `reset()`; a batch from an older generation is never requeued. */
|
|
332
|
+
private generation;
|
|
333
|
+
private lastFlushRequeued;
|
|
334
|
+
constructor(config: ReoptCoreConfig);
|
|
335
|
+
protected log(...args: unknown[]): void;
|
|
336
|
+
getDeviceId(): string;
|
|
337
|
+
/** Swap the device id, e.g. after a server bootstrap or a `reset()`. */
|
|
338
|
+
setDeviceId(deviceId: string): void;
|
|
339
|
+
setProfileId(profileId: string | number | null): void;
|
|
340
|
+
getProfileId(): string | number | null;
|
|
341
|
+
setConsent(category: ConsentCategory, allowed: boolean): void;
|
|
342
|
+
getConsent(category: ConsentCategory): boolean;
|
|
343
|
+
setAllConsent(allowed: boolean): void;
|
|
344
|
+
getConsentState(): ConsentState;
|
|
345
|
+
replaceConsentState(state: ConsentState): void;
|
|
346
|
+
pauseTracking(): void;
|
|
347
|
+
resumeTracking(): void;
|
|
348
|
+
/**
|
|
349
|
+
* Properties attached to every `track` event (and so every automatic
|
|
350
|
+
* event) from now on. An event's own properties win on conflict. This is
|
|
351
|
+
* how a host adds its breakdown axis — a `page_id`, a tenant — to
|
|
352
|
+
* `$web_vitals` and `$pageleave`, which the SDK otherwise stamps with
|
|
353
|
+
* only a path.
|
|
354
|
+
*/
|
|
355
|
+
register(properties: Record<string, unknown>): void;
|
|
356
|
+
unregister(...keys: string[]): void;
|
|
357
|
+
getGlobalProperties(): Record<string, unknown>;
|
|
358
|
+
/**
|
|
359
|
+
* `options.identity` files the event under another visitor than the
|
|
360
|
+
* runtime's — the server SDK's way of serving many requests from one
|
|
361
|
+
* engine. Such an event never reads or writes the engine's own profile:
|
|
362
|
+
* that belongs to the runtime's visitor, not the request's.
|
|
363
|
+
*/
|
|
364
|
+
track(options: TrackEventOptions): QueueResult;
|
|
365
|
+
identify(options: IdentifyOptions): QueueResult;
|
|
366
|
+
increment(options: IncrementOptions): QueueResult;
|
|
367
|
+
decrement(options: DecrementOptions): QueueResult;
|
|
368
|
+
pageView(options?: PageViewOptions): QueueResult;
|
|
369
|
+
screenView(screenName: string, properties?: Record<string, unknown>, identity?: EventIdentity): QueueResult;
|
|
370
|
+
get pending(): number;
|
|
371
|
+
private enqueue;
|
|
372
|
+
private scheduleFlush;
|
|
373
|
+
private clearScheduledFlush;
|
|
374
|
+
flush(options?: FlushOptions): Promise<FlushResult>;
|
|
375
|
+
/**
|
|
376
|
+
* The page (or process) is going away. Persist first so nothing is lost if
|
|
377
|
+
* the request never completes, then send what can be sent with keepalive.
|
|
378
|
+
*/
|
|
379
|
+
private flushOnSignal;
|
|
380
|
+
/**
|
|
381
|
+
* The identity a batch is sent under, fixed when it leaves the queue. A
|
|
382
|
+
* `reset()` during a retry must not re-address the previous visitor's
|
|
383
|
+
* events to the new device.
|
|
384
|
+
*/
|
|
385
|
+
private identityFor;
|
|
386
|
+
private flushExclusive;
|
|
387
|
+
private flushAll;
|
|
388
|
+
private flushOnce;
|
|
389
|
+
private continueOrSettle;
|
|
390
|
+
/**
|
|
391
|
+
* Forget who this is: profile, queued events and — when the runtime can
|
|
392
|
+
* mint one — the device id. A shared computer that logs out must not keep
|
|
393
|
+
* attributing the next person to the previous one.
|
|
394
|
+
*/
|
|
395
|
+
reset(): void;
|
|
396
|
+
close(): Promise<FlushResult>;
|
|
397
|
+
}
|
|
398
|
+
//#endregion
|
|
399
|
+
//#region src/steps.d.ts
|
|
400
|
+
type ExceptionStepInput = {
|
|
401
|
+
category: ExceptionStep["category"];
|
|
402
|
+
message: string;
|
|
403
|
+
data?: Record<string, unknown> | undefined;
|
|
404
|
+
};
|
|
405
|
+
//#endregion
|
|
406
|
+
//#region src/capture/web-vitals.d.ts
|
|
407
|
+
/**
|
|
408
|
+
* The shape `next/web-vitals`' `useReportWebVitals` and the `web-vitals`
|
|
409
|
+
* package both produce. Declared here so the vanilla entry does not have to
|
|
410
|
+
* import either.
|
|
411
|
+
*/
|
|
412
|
+
interface WebVitalMetric {
|
|
413
|
+
id: string;
|
|
414
|
+
name: string;
|
|
415
|
+
value: number;
|
|
416
|
+
delta?: number | undefined;
|
|
417
|
+
rating?: "good" | "needs-improvement" | "poor" | undefined;
|
|
418
|
+
navigationType?: string | undefined;
|
|
419
|
+
}
|
|
420
|
+
type WebVitalProperties = {
|
|
421
|
+
metric_name: string;
|
|
422
|
+
metric_id: string;
|
|
423
|
+
value: number;
|
|
424
|
+
delta?: number | undefined;
|
|
425
|
+
rating?: string | undefined;
|
|
426
|
+
navigation_type?: string | undefined;
|
|
427
|
+
path: string;
|
|
428
|
+
};
|
|
429
|
+
//#endregion
|
|
430
|
+
//#region src/config.d.ts
|
|
431
|
+
type ReoptObservedEventType = "track" | "identify" | "increment" | "decrement";
|
|
432
|
+
/**
|
|
433
|
+
* Observation-only lifecycle facts for local tooling. The callback is never
|
|
434
|
+
* part of delivery: throwing from it is ignored and cannot block the SDK.
|
|
435
|
+
*/
|
|
436
|
+
type ReoptClientObservation = {
|
|
437
|
+
type: "config";
|
|
438
|
+
at: number;
|
|
439
|
+
disabled: boolean;
|
|
440
|
+
baseUrl: string;
|
|
441
|
+
writeKeyPresent: boolean;
|
|
442
|
+
debug: boolean;
|
|
443
|
+
capture: ResolvedCaptureConfig;
|
|
444
|
+
consentPersisted: boolean;
|
|
445
|
+
batchIntervalMs: number;
|
|
446
|
+
} | {
|
|
447
|
+
type: "event";
|
|
448
|
+
at: number;
|
|
449
|
+
phase: "queued" | "dropped";
|
|
450
|
+
eventId: string;
|
|
451
|
+
eventType: ReoptObservedEventType;
|
|
452
|
+
name: string;
|
|
453
|
+
pending: number;
|
|
454
|
+
reason?: string | undefined;
|
|
455
|
+
errors?: Array<{
|
|
456
|
+
field: string;
|
|
457
|
+
message: string;
|
|
458
|
+
}> | undefined;
|
|
459
|
+
} | {
|
|
460
|
+
type: "identity";
|
|
461
|
+
at: number;
|
|
462
|
+
action: "initialized" | "identified" | "profile_changed" | "reset";
|
|
463
|
+
deviceId: string;
|
|
464
|
+
profileId: string | number | null;
|
|
465
|
+
storage: IdentityStorageKind;
|
|
466
|
+
} | {
|
|
467
|
+
type: "consent";
|
|
468
|
+
at: number;
|
|
469
|
+
category: ConsentCategory | "all";
|
|
470
|
+
allowed: boolean;
|
|
471
|
+
} | {
|
|
472
|
+
type: "tracking";
|
|
473
|
+
at: number;
|
|
474
|
+
paused: boolean;
|
|
475
|
+
};
|
|
476
|
+
type ReoptClientObserver = (observation: ReoptClientObservation) => void;
|
|
477
|
+
/**
|
|
478
|
+
* Rewrites a pathname before it is attached to an event, and may lift the
|
|
479
|
+
* parts it removed into properties so they stay available for breakdowns:
|
|
480
|
+
* `/workspace/8f3…/crm/customers/2a1…` → `{ path: "/workspace/:id/crm/customers/:id",
|
|
481
|
+
* properties: { workspace_id: "8f3…" } }`.
|
|
482
|
+
*
|
|
483
|
+
* Applied wherever the SDK fills in a path itself — the default `$pageview`
|
|
484
|
+
* path, `$pageleave`, `$web_vitals`, `$exception`. A `path` you pass to
|
|
485
|
+
* `pageView()` explicitly is used as-is, so run the same function on it
|
|
486
|
+
* yourself; two different rules would give one visit two different paths.
|
|
487
|
+
* Must be synchronous and pure. If it throws, the raw pathname is used.
|
|
488
|
+
*/
|
|
489
|
+
type NormalizePath = (pathname: string) => string | {
|
|
490
|
+
path: string;
|
|
491
|
+
properties?: Record<string, unknown>;
|
|
492
|
+
};
|
|
493
|
+
type IdentityStorageKind = "auto" | "cookie" | "localStorage" | "memory";
|
|
494
|
+
interface IdentityConfig {
|
|
495
|
+
/**
|
|
496
|
+
* Where the device id lives. `auto` (default) prefers a cookie: Safari
|
|
497
|
+
* expires script-written `localStorage` after seven days of inactivity,
|
|
498
|
+
* which turns every returning visitor into a new device. A cookie the
|
|
499
|
+
* server also reads survives that, and lets server-side events join the
|
|
500
|
+
* same device.
|
|
501
|
+
*/
|
|
502
|
+
storage?: IdentityStorageKind | undefined;
|
|
503
|
+
/** Cookie `Domain`; omit for host-only. Set to share across subdomains. */
|
|
504
|
+
cookieDomain?: string | undefined;
|
|
505
|
+
/** Cookie lifetime. Default 400 days (the longest Chrome honours). */
|
|
506
|
+
cookieMaxAgeSeconds?: number | undefined;
|
|
507
|
+
}
|
|
508
|
+
interface CaptureConfig {
|
|
509
|
+
/**
|
|
510
|
+
* Send `$pageview` on `init()`. Default `true` for the vanilla entry.
|
|
511
|
+
* The Next entry sets it to `false` because `<ReoptPageView />` owns page
|
|
512
|
+
* views there — including the first one.
|
|
513
|
+
*/
|
|
514
|
+
pageview?: boolean | undefined;
|
|
515
|
+
/** Send `$pageleave` with time-on-page when the page is hidden or the route changes. Default `true`. */
|
|
516
|
+
pageleave?: boolean | undefined;
|
|
517
|
+
/** Attach max scroll depth to `$pageleave`. Default `true`. */
|
|
518
|
+
scrollDepth?: boolean | undefined;
|
|
519
|
+
/** Send `$exception` for uncaught errors and unhandled rejections. Default `false`. */
|
|
520
|
+
exceptions?: boolean | undefined;
|
|
521
|
+
/**
|
|
522
|
+
* Throttle automatic exception capture, per exception type. Default on
|
|
523
|
+
* (10 events, one token back every 10s). `false` reports everything — only
|
|
524
|
+
* useful when you are deliberately measuring an error storm.
|
|
525
|
+
*
|
|
526
|
+
* Never applies to `captureException()`: a report you asked for explicitly is
|
|
527
|
+
* not noise the SDK gets to drop.
|
|
528
|
+
*/
|
|
529
|
+
exceptionRateLimit?: {
|
|
530
|
+
bucketSize?: number;
|
|
531
|
+
refillSeconds?: number;
|
|
532
|
+
} | false | undefined;
|
|
533
|
+
/**
|
|
534
|
+
* Record breadcrumbs (`$exception_steps`) leading up to an exception.
|
|
535
|
+
* Default `false` — it puts navigation history on every error, which is a
|
|
536
|
+
* privacy decision the host makes, not the SDK.
|
|
537
|
+
*/
|
|
538
|
+
exceptionSteps?: boolean | undefined;
|
|
539
|
+
}
|
|
540
|
+
interface ReoptClientConfig {
|
|
541
|
+
writeKey: string;
|
|
542
|
+
/** reopt-data origin, or the same-origin proxy prefix (e.g. `/ingest`) the Next.js proxy rewrites. */
|
|
543
|
+
baseUrl: string;
|
|
544
|
+
/** What the server already knows about this visitor. `null` = nothing. */
|
|
545
|
+
bootstrap?: ReoptBootstrap | null | undefined;
|
|
546
|
+
identity?: IdentityConfig | undefined;
|
|
547
|
+
capture?: CaptureConfig | undefined;
|
|
548
|
+
/**
|
|
549
|
+
* Hosts that receive the `reopt-device-id` header on outgoing `fetch`/XHR,
|
|
550
|
+
* so a server-side `track()` lands on the same device. `true` = the page's
|
|
551
|
+
* own hostname. **Default: off** — the trusted path is passing
|
|
552
|
+
* `getDeviceId()` to your server call explicitly; this patches `fetch`
|
|
553
|
+
* and loads as a separate chunk only when enabled.
|
|
554
|
+
*/
|
|
555
|
+
tracingHeaders?: boolean | string[] | undefined;
|
|
556
|
+
/** See {@link NormalizePath}. */
|
|
557
|
+
normalizePath?: NormalizePath | undefined;
|
|
558
|
+
/**
|
|
559
|
+
* Properties attached to every event from the very first one. Same as
|
|
560
|
+
* calling `register()` right after `init()`, except that nothing can
|
|
561
|
+
* slip out in between: web vitals arrive from a buffered
|
|
562
|
+
* `PerformanceObserver` and can fire the instant the client exists.
|
|
563
|
+
* Pass the page context the server already knows here; update it on
|
|
564
|
+
* client-side navigation with `register()`.
|
|
565
|
+
*/
|
|
566
|
+
properties?: Record<string, unknown> | undefined;
|
|
567
|
+
/**
|
|
568
|
+
* The build this page is running, sent on every event as `$release_id`.
|
|
569
|
+
*
|
|
570
|
+
* What lets error tracking say an issue first appeared in 1.4.0, and whether
|
|
571
|
+
* the fix shipped in 1.4.1 held. A string the host chooses — a version, a
|
|
572
|
+
* commit sha, a build id — not something the server issues, and an unknown
|
|
573
|
+
* one is never rejected.
|
|
574
|
+
*
|
|
575
|
+
* Falls back to `globalThis.__REOPT_RELEASE__`, which is where a build step
|
|
576
|
+
* writes the version the app's own config cannot know:
|
|
577
|
+
*
|
|
578
|
+
* ```js
|
|
579
|
+
* // vite.config.js / next.config.js
|
|
580
|
+
* define: { __REOPT_RELEASE__: JSON.stringify(process.env.GIT_SHA) }
|
|
581
|
+
* ```
|
|
582
|
+
*
|
|
583
|
+
* Sugar over `properties: { $release_id }`, which still works and costs
|
|
584
|
+
* nothing — the option exists because threading a build constant through a
|
|
585
|
+
* properties bag is the part hosts get wrong.
|
|
586
|
+
*/
|
|
587
|
+
release?: string | undefined;
|
|
588
|
+
consent?: ConsentConfig | undefined;
|
|
589
|
+
batch?: BatchConfig | undefined;
|
|
590
|
+
retry?: RetryConfig | undefined;
|
|
591
|
+
circuitBreaker?: CircuitBreakerConfig | undefined;
|
|
592
|
+
/** Upper bound on queued events. Default 10 000. */
|
|
593
|
+
maxQueueSize?: number | undefined;
|
|
594
|
+
/** Overrides the store for the offline queue. Default `localStorage`. */
|
|
595
|
+
queueStorage?: StorageBackend | undefined;
|
|
596
|
+
/** Prefix for storage keys. Default `reopt_`. */
|
|
597
|
+
storagePrefix?: string | undefined;
|
|
598
|
+
/**
|
|
599
|
+
* Transport override. Tests hand in a recording function so a Playwright
|
|
600
|
+
* spec can assert on the exact payload the SDK built, without intercepting
|
|
601
|
+
* the network. Defaults to the page's `fetch` (captured at init, before the
|
|
602
|
+
* tracing patch, so the SDK's own requests are never tagged twice).
|
|
603
|
+
*/
|
|
604
|
+
fetch?: FetchLike | undefined;
|
|
605
|
+
/**
|
|
606
|
+
* Observation-only lifecycle hook for devtools. It receives no credentials
|
|
607
|
+
* and is ignored when it throws. Facts are buffered in order while the
|
|
608
|
+
* opt-in observer chunk loads; delivery never depends on this callback.
|
|
609
|
+
*/
|
|
610
|
+
observe?: ReoptClientObserver | undefined;
|
|
611
|
+
debug?: boolean | undefined;
|
|
612
|
+
}
|
|
613
|
+
interface ResolvedCaptureConfig {
|
|
614
|
+
pageview: boolean;
|
|
615
|
+
pageleave: boolean;
|
|
616
|
+
scrollDepth: boolean;
|
|
617
|
+
exceptions: boolean;
|
|
618
|
+
/**
|
|
619
|
+
* `false` disables throttling; otherwise the host's overrides, if any.
|
|
620
|
+
*
|
|
621
|
+
* Deliberately not defaulted here: the defaults live beside the limiter in
|
|
622
|
+
* the lazily-loaded exception chunk, so the main bundle carries the option
|
|
623
|
+
* but not the numbers.
|
|
624
|
+
*/
|
|
625
|
+
exceptionRateLimit: {
|
|
626
|
+
bucketSize?: number;
|
|
627
|
+
refillSeconds?: number;
|
|
628
|
+
} | false;
|
|
629
|
+
exceptionSteps: boolean;
|
|
630
|
+
}
|
|
631
|
+
//#endregion
|
|
632
|
+
//#region src/identity/device.d.ts
|
|
633
|
+
interface IdentityStore {
|
|
634
|
+
readonly kind: Exclude<IdentityStorageKind, "auto">;
|
|
635
|
+
readDevice(): DeviceCookieState | null;
|
|
636
|
+
writeDevice(state: DeviceCookieState): void;
|
|
637
|
+
clearDevice(): void;
|
|
638
|
+
readConsent(): ConsentCookieState | null;
|
|
639
|
+
writeConsent(state: ConsentCookieState): void;
|
|
640
|
+
/** Engine-facing backend for the consent key, so consent decisions land in the same place. */
|
|
641
|
+
consentBackend(): StorageBackend;
|
|
642
|
+
}
|
|
643
|
+
//#endregion
|
|
644
|
+
//#region src/client.d.ts
|
|
645
|
+
interface ReoptClientDefaults {
|
|
646
|
+
/** Whether `init()` sends the first `$pageview`. The Next entry says no. */
|
|
647
|
+
pageview: boolean;
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* The browser client: the shared engine plus everything that only makes
|
|
651
|
+
* sense in a document — cookie identity, tracing headers, page leave,
|
|
652
|
+
* scroll depth, exception capture, and a clock corrected against the
|
|
653
|
+
* server's.
|
|
654
|
+
*/
|
|
655
|
+
/**
|
|
656
|
+
* What to attach to a manual `captureException`.
|
|
657
|
+
*
|
|
658
|
+
* The second argument used to be a bare properties bag. That shape is still
|
|
659
|
+
* accepted, so no existing call site has to change — see
|
|
660
|
+
* {@link readCaptureExceptionOptions} for how the two are told apart.
|
|
661
|
+
*/
|
|
662
|
+
interface CaptureExceptionOptions {
|
|
663
|
+
/** Group this error yourself instead of letting the server fingerprint it. */
|
|
664
|
+
fingerprint?: string | undefined;
|
|
665
|
+
level?: ExceptionLevel | undefined;
|
|
666
|
+
properties?: Record<string, unknown> | undefined;
|
|
667
|
+
}
|
|
668
|
+
declare class ReoptClient extends ReoptCore {
|
|
669
|
+
readonly writeKey: string;
|
|
670
|
+
readonly capture: ResolvedCaptureConfig;
|
|
671
|
+
private readonly store;
|
|
672
|
+
private readonly pageLeave;
|
|
673
|
+
private readonly scroll;
|
|
674
|
+
private readonly uninstallers;
|
|
675
|
+
private torndown;
|
|
676
|
+
/** The lazily-loaded exception chunk, once it has resolved. */
|
|
677
|
+
private exceptionChunk;
|
|
678
|
+
private exceptionChunkPromise;
|
|
679
|
+
private readonly session;
|
|
680
|
+
private readonly optedOut;
|
|
681
|
+
private readonly normalize;
|
|
682
|
+
private readonly observer;
|
|
683
|
+
/** True when `writeKey` or `baseUrl` was missing: every call is a silent no-op. */
|
|
684
|
+
readonly disabled: boolean;
|
|
685
|
+
constructor(config: ReoptClientConfig, defaults?: ReoptClientDefaults);
|
|
686
|
+
/** Which store identity ended up in — `cookie`, `localStorage` or `memory`. */
|
|
687
|
+
get identityStorage(): IdentityStore["kind"];
|
|
688
|
+
private observe;
|
|
689
|
+
private observeIdentity;
|
|
690
|
+
private observeEvent;
|
|
691
|
+
track(options: TrackEventOptions): QueueResult;
|
|
692
|
+
pageView(options?: PageViewOptions): QueueResult;
|
|
693
|
+
setConsent(category: ConsentCategory, allowed: boolean): void;
|
|
694
|
+
setAllConsent(allowed: boolean): void;
|
|
695
|
+
replaceConsentState(state: Record<string, boolean>): void;
|
|
696
|
+
pauseTracking(): void;
|
|
697
|
+
resumeTracking(): void;
|
|
698
|
+
setProfileId(profileId: string | number | null): void;
|
|
699
|
+
/**
|
|
700
|
+
* Refusing `analytics` removes the stored identity (the proxy does the
|
|
701
|
+
* same on its side); granting it again writes the current device through
|
|
702
|
+
* so the visit is attributable from that point on.
|
|
703
|
+
*/
|
|
704
|
+
private syncOptOut;
|
|
705
|
+
identify(options: IdentifyOptions): QueueResult;
|
|
706
|
+
increment(options: IncrementOptions): QueueResult;
|
|
707
|
+
decrement(options: DecrementOptions): QueueResult;
|
|
708
|
+
/** Feed a Web Vitals metric (from `next/web-vitals` or the `web-vitals` package). */
|
|
709
|
+
captureWebVital(metric: WebVitalMetric): QueueResult;
|
|
710
|
+
/** The page's path through `normalizePath`, for events the SDK stamps itself. */
|
|
711
|
+
private currentPath;
|
|
712
|
+
/**
|
|
713
|
+
* Report an error you caught yourself.
|
|
714
|
+
*
|
|
715
|
+
* The stack parsers live in a lazily-loaded chunk — they are several times
|
|
716
|
+
* the size budget's remaining headroom, and a page that never throws should
|
|
717
|
+
* not pay for them. So the first call before that chunk resolves reports the
|
|
718
|
+
* flat keys only (name, message, raw stack) and starts the load; every call
|
|
719
|
+
* after it carries the structured `$exception_list` too. The server groups
|
|
720
|
+
* both: without a list it falls back to V1 fingerprinting on the flat keys.
|
|
721
|
+
*/
|
|
722
|
+
captureException(error: unknown, optionsOrProperties?: CaptureExceptionOptions | Record<string, unknown>): QueueResult;
|
|
723
|
+
/**
|
|
724
|
+
* Record a breadcrumb for the next exception.
|
|
725
|
+
*
|
|
726
|
+
* Always available, whether or not automatic steps are on: a host that wants
|
|
727
|
+
* to leave its own trail should not have to opt into the SDK leaving one too.
|
|
728
|
+
*/
|
|
729
|
+
addExceptionStep(step: ExceptionStepInput): void;
|
|
730
|
+
/** Loads the exception chunk once and remembers it, so manual captures can use the parsers. */
|
|
731
|
+
private loadExceptionChunk;
|
|
732
|
+
private trackException;
|
|
733
|
+
private emitPageLeave;
|
|
734
|
+
/**
|
|
735
|
+
* Log out: forget the profile and the queue, and become a new device.
|
|
736
|
+
* On a shared computer the next person must not inherit this one's
|
|
737
|
+
* history.
|
|
738
|
+
*/
|
|
739
|
+
reset(): void;
|
|
740
|
+
close(): Promise<FlushResult>;
|
|
741
|
+
}
|
|
742
|
+
//#endregion
|
|
743
|
+
export { QueueDropReason as A, FetchInit as C, IdentifyOptions as D, FlushResult as E, UTMParams as F, RetryConfig as M, StorageBackend as N, IncrementOptions as O, TrackEventOptions as P, EventPayload as S, FetchResponseLike as T, CircuitBreakerConfig as _, IdentityConfig as a, DecrementOptions as b, ReoptBootstrap as c, ReoptClientObserver as d, ReoptObservedEventType as f, BatchConfig as g, ExceptionStepInput as h, CaptureConfig as i, QueueResult as j, PageViewOptions as k, ReoptClientConfig as l, WebVitalProperties as m, ReoptClient as n, IdentityStorageKind as o, WebVitalMetric as p, ReoptClientDefaults as r, NormalizePath as s, CaptureExceptionOptions as t, ReoptClientObservation as u, ConsentCategory as v, FetchLike as w, EventIdentity as x, ConsentConfig as y };
|
|
744
|
+
//# sourceMappingURL=client-BCrui21p.d.cts.map
|