@catdoes/watch 1.3.0 → 2.0.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/dist/index.d.mts CHANGED
@@ -1,431 +1,202 @@
1
1
  export { WatchErrorBoundary, WatchErrorBoundaryProps, withWatchErrorBoundary } from './react.mjs';
2
2
  import 'react';
3
3
 
4
- /**
5
- * CatDoes Watch SDK - Type Definitions
6
- *
7
- * These types define the structure of error events, configuration,
8
- * and other data used by the Watch SDK.
9
- */
10
- /**
11
- * Minimal async key-value storage used to persist the event queue across
12
- * launches. Compatible with `@react-native-async-storage/async-storage`'s
13
- * default export and `window.localStorage`-style wrappers.
14
- *
15
- * The SDK never imports a storage module itself — dynamic `require()` of
16
- * optional dependencies is reported as a fatal error by Metro in release
17
- * builds. Pass an implementation explicitly:
18
- *
19
- * ```ts
20
- * import AsyncStorage from "@react-native-async-storage/async-storage";
21
- * initCatDoesWatch({ apiKey, storage: AsyncStorage });
22
- * ```
23
- */
24
- interface WatchStorage {
25
- getItem(key: string): Promise<string | null>;
26
- setItem(key: string, value: string): Promise<void>;
27
- removeItem(key: string): Promise<void>;
4
+ interface QueueStore {
5
+ read(): string | null;
6
+ write(value: string): void;
7
+ remove(): void;
28
8
  }
29
- /**
30
- * Configuration options for initializing the Watch client.
31
- */
9
+
32
10
  interface WatchConfig {
33
- /**
34
- * The API key for authenticating with CatDoes Watch.
35
- * Format: cd_watch_xxxxx
36
- */
37
11
  apiKey: string;
38
- /**
39
- * The endpoint URL for the ingestion API.
40
- * @default "https://app.catdoes.com/api/watch/ingest"
41
- */
42
12
  endpoint?: string;
43
- /**
44
- * The environment to report errors for.
45
- * Auto-detected from __DEV__ if not specified.
46
- * @default Auto-detected
47
- */
48
13
  environment?: "development" | "production";
49
- /**
50
- * Whether to capture console.error calls as errors.
51
- * This can be noisy and is disabled by default.
52
- * @default false
53
- */
14
+ debug?: boolean;
15
+ installGlobalHandlers?: boolean;
54
16
  captureConsoleErrors?: boolean;
55
- /**
56
- * Maximum number of breadcrumbs to store.
57
- * @default 20
58
- */
17
+ captureHttpBreadcrumbs?: boolean;
59
18
  maxBreadcrumbs?: number;
60
- /**
61
- * Maximum number of events to buffer before flushing.
62
- * @default 10
63
- */
64
19
  maxBufferSize?: number;
65
- /**
66
- * Interval in milliseconds between automatic flushes.
67
- * @default 5000
68
- */
69
20
  flushInterval?: number;
70
- /**
71
- * Callback invoked before sending an event.
72
- * Return null to drop the event, or modify and return it.
73
- */
21
+ fatalFlushTimeoutMs?: number;
74
22
  beforeSend?: (event: WatchEvent) => WatchEvent | null;
75
- /**
76
- * Enable debug logging to console.
77
- * @default false
78
- */
79
- debug?: boolean;
80
- /**
81
- * Initial context to attach to all events.
82
- */
83
23
  initialContext?: Record<string, unknown>;
84
- /**
85
- * Time window in milliseconds to consider errors as duplicates.
86
- * Errors with the same key occurring within this window will be deduplicated.
87
- * @default 5000
88
- */
89
24
  dedupWindowMs?: number;
90
- /**
91
- * Maximum number of recent error keys to keep in memory for deduplication.
92
- * When exceeded, the oldest keys will be evicted.
93
- * @default 500
94
- */
95
25
  dedupMaxEntries?: number;
96
- /**
97
- * Storage implementation used to persist queued events across launches
98
- * (e.g. AsyncStorage). Persistence is disabled when omitted.
99
- */
100
- storage?: WatchStorage;
26
+ storage?: QueueStore;
101
27
  }
102
- /**
103
- * Required configuration with defaults applied.
104
- */
105
28
  interface WatchConfigResolved {
106
29
  apiKey: string;
107
30
  endpoint: string;
108
31
  environment: "development" | "production";
32
+ debug: boolean;
33
+ installGlobalHandlers: boolean;
109
34
  captureConsoleErrors: boolean;
35
+ captureHttpBreadcrumbs: boolean;
110
36
  maxBreadcrumbs: number;
111
37
  maxBufferSize: number;
112
38
  flushInterval: number;
39
+ fatalFlushTimeoutMs: number;
113
40
  beforeSend: (event: WatchEvent) => WatchEvent | null;
114
- debug: boolean;
115
41
  dedupWindowMs: number;
116
42
  dedupMaxEntries: number;
117
- storage: WatchStorage | null;
43
+ storage?: QueueStore;
118
44
  }
119
- /**
120
- * Device and environment information collected automatically.
121
- */
122
45
  interface DeviceInfo {
123
- deviceModel?: string;
124
- deviceName?: string;
125
- deviceType?: string;
126
46
  brand?: string;
127
47
  manufacturer?: string;
128
48
  modelName?: string;
49
+ modelId?: string;
50
+ designName?: string;
51
+ productName?: string;
52
+ deviceName?: string;
53
+ deviceType?: "unknown" | "phone" | "tablet" | "desktop" | "tv";
54
+ deviceYearClass?: number;
55
+ memoryTotal?: number;
56
+ supportedCpuArchitectures?: string[];
129
57
  isDevice?: boolean;
130
- isEmulator?: boolean;
131
- isTablet?: boolean;
132
58
  osName?: string;
133
59
  osVersion?: string;
134
60
  osBuildId?: string;
61
+ osInternalBuildId?: string;
62
+ osBuildFingerprint?: string;
135
63
  platformApiLevel?: number;
64
+ appName?: string;
65
+ appSlug?: string;
136
66
  appVersion?: string;
137
67
  appBuildNumber?: string;
138
- appName?: string;
139
68
  bundleId?: string;
69
+ expoSdkVersion?: string;
140
70
  runtimeVersion?: string;
71
+ expoRuntimeVersion?: string;
141
72
  expoVersion?: string;
142
- nativeAppVersion?: string;
143
- nativeBuildVersion?: string;
73
+ executionEnvironment?: string;
74
+ jsEngine?: "hermes" | "jsc" | "unknown";
144
75
  screenWidth?: number;
145
76
  screenHeight?: number;
146
77
  screenScale?: number;
78
+ fontScale?: number;
147
79
  locale?: string;
148
80
  timezone?: string;
149
- networkType?: string;
150
- isConnected?: boolean;
151
81
  browserName?: string;
152
82
  browserVersion?: string;
153
83
  userAgent?: string;
154
84
  }
155
- /**
156
- * A breadcrumb representing an action or event before an error.
157
- */
158
85
  interface Breadcrumb {
159
- /**
160
- * The type of breadcrumb.
161
- */
162
86
  type: "navigation" | "ui" | "http" | "console" | "custom";
163
- /**
164
- * A human-readable message describing the breadcrumb.
165
- */
166
87
  message: string;
167
- /**
168
- * ISO 8601 timestamp of when the breadcrumb was created.
169
- */
170
88
  timestamp: string;
171
- /**
172
- * Additional data associated with the breadcrumb.
173
- */
174
89
  data?: Record<string, unknown>;
175
90
  }
176
- /**
177
- * An error event to be sent to CatDoes Watch.
178
- */
179
91
  interface WatchEvent {
180
- /**
181
- * The error message.
182
- */
92
+ eventId?: string;
183
93
  message: string;
184
- /**
185
- * The stack trace of the error.
186
- */
187
94
  stack?: string;
188
- /**
189
- * React component stack trace.
190
- */
191
95
  componentStack?: string;
192
- /**
193
- * The filename where the error occurred.
194
- */
195
96
  filename?: string;
196
- /**
197
- * The line number where the error occurred.
198
- */
199
97
  lineno?: number;
200
- /**
201
- * The column number where the error occurred.
202
- */
203
98
  colno?: number;
204
- /**
205
- * ISO 8601 timestamp of when the error occurred.
206
- */
207
99
  timestamp: string;
208
- /**
209
- * The environment where the error occurred.
210
- */
211
100
  environment: "development" | "production";
212
- /**
213
- * The platform where the error occurred.
214
- */
215
101
  platform: "ios" | "android" | "web";
216
- /**
217
- * A unique identifier for the current session.
218
- */
219
102
  sessionId: string;
220
- /**
221
- * Device and environment information.
222
- */
223
103
  deviceInfo?: DeviceInfo;
224
- /**
225
- * Additional context data.
226
- */
227
104
  extra?: Record<string, unknown>;
228
- /**
229
- * Breadcrumbs leading up to the error.
230
- */
231
105
  breadcrumbs?: Breadcrumb[];
232
- /**
233
- * SDK version for debugging. Helps correlate reports across SDK releases.
234
- */
235
106
  sdkVersion?: string;
236
107
  }
237
- /**
238
- * Input for adding a breadcrumb (timestamp is auto-generated).
239
- */
240
108
  type BreadcrumbInput = Omit<Breadcrumb, "timestamp">;
241
- /**
242
- * Response from the ingestion API.
243
- */
244
109
  interface IngestResponse {
245
110
  accepted?: number;
246
111
  filtered?: boolean;
247
112
  error?: string;
248
113
  retryAfter?: number;
249
114
  }
250
-
251
- /**
252
- * CatDoes Watch SDK - Transport Layer
253
- *
254
- * Handles HTTP communication with the CatDoes Watch ingestion API.
255
- * Features:
256
- * - Batching: Groups multiple events into single requests
257
- * - Retry with exponential backoff on failures
258
- * - Respects rate limiting (429 responses)
259
- * - Silent failures (never throws to avoid breaking the app)
260
- */
115
+ interface LastFlush {
116
+ at: string;
117
+ status: number | null;
118
+ accepted: number | null;
119
+ error?: string;
120
+ }
121
+ interface TransportStats {
122
+ disabledReason: "auth" | "failures" | null;
123
+ backoffUntil: number | null;
124
+ consecutiveFailures: number;
125
+ lastFlush: LastFlush | null;
126
+ }
127
+ interface WatchStats {
128
+ queueSize: number;
129
+ sessionId: string;
130
+ transport: TransportStats;
131
+ }
261
132
 
262
133
  interface FlushOptions {
263
- /**
264
- * Hint browsers to allow the request to outlive the page lifecycle.
265
- */
266
134
  keepalive?: boolean;
267
135
  }
268
136
 
269
- /**
270
- * CatDoes Watch SDK - Main Client
271
- *
272
- * The primary interface for the CatDoes Watch error tracking SDK.
273
- * Implements a singleton pattern for ease of use.
274
- */
275
-
276
- /**
277
- * The main CatDoes Watch client class.
278
- */
279
137
  declare class WatchClient {
280
- private static instance;
281
- private config;
282
- private transport;
283
- private breadcrumbs;
138
+ private readonly config;
139
+ private readonly transport;
140
+ private readonly breadcrumbs;
284
141
  private context;
285
142
  private user;
286
- private isInitialized;
287
- private recentErrors;
143
+ private readonly recentErrors;
288
144
  private recentErrorsCleanupTimer;
289
145
  private constructor();
290
- /**
291
- * Initializes the Watch client with the given configuration.
292
- */
293
146
  static init(config: WatchConfig): WatchClient;
294
- /**
295
- * Gets the existing Watch client instance, or null if not initialized.
296
- */
297
147
  static getInstance(): WatchClient | null;
298
- /**
299
- * Captures an error and sends it to CatDoes Watch.
300
- */
301
- captureError(error: Error, extra?: Record<string, unknown>): void;
302
- /**
303
- * Captures a message as an error.
304
- */
148
+ captureError(error: unknown, extra?: Record<string, unknown>): void;
305
149
  captureMessage(message: string, level?: "info" | "warning" | "error"): void;
306
- /**
307
- * Adds a breadcrumb to the trail.
308
- */
309
150
  addBreadcrumb(breadcrumb: BreadcrumbInput): void;
310
- /**
311
- * Sets a context value that will be attached to all future events.
312
- */
313
151
  setContext(key: string, value: unknown): void;
314
- /**
315
- * Clears a context value.
316
- */
317
152
  clearContext(key: string): void;
318
- /**
319
- * Sets user information to attach to events.
320
- */
321
153
  setUser(user: {
322
154
  id?: string;
323
155
  [key: string]: unknown;
324
156
  } | null): void;
325
- /**
326
- * Flushes all queued events immediately.
327
- */
328
157
  flush(options?: FlushOptions): Promise<void>;
329
- /**
330
- * Gets the current configuration.
331
- */
158
+ flushWithTimeout(timeoutMs: number): Promise<void>;
159
+ commit(): void;
160
+ getStats(): WatchStats;
332
161
  getConfig(): Readonly<WatchConfigResolved>;
333
- /**
334
- * Checks if the client is initialized and ready to capture events.
335
- */
336
162
  get initialized(): boolean;
337
163
  private buildEvent;
338
- private shouldCapture;
339
164
  private ensureStack;
340
165
  private getErrorKey;
341
- private markErrorAsSeen;
342
166
  private hasSeenErrorRecently;
167
+ private markErrorAsSeen;
343
168
  private scheduleRecentErrorsCleanup;
344
- private pruneRecentErrors;
345
169
  }
346
- /**
347
- * Static interface for convenience methods.
348
- */
349
170
  declare const Watch: {
350
171
  init(config: WatchConfig): WatchClient;
351
172
  getInstance(): WatchClient | null;
352
- captureError(error: Error, extra?: Record<string, unknown>): void;
173
+ captureError(error: unknown, extra?: Record<string, unknown>): void;
353
174
  captureMessage(message: string, level?: "info" | "warning" | "error"): void;
354
175
  addBreadcrumb(breadcrumb: BreadcrumbInput): void;
355
176
  setContext(key: string, value: unknown): void;
177
+ clearContext(key: string): void;
356
178
  setUser(user: {
357
179
  id?: string;
358
180
  [key: string]: unknown;
359
181
  } | null): void;
360
182
  flush(options?: FlushOptions): Promise<void>;
183
+ flushWithTimeout(timeoutMs: number): Promise<void>;
184
+ getStats(): WatchStats | null;
361
185
  };
362
186
 
363
- /**
364
- * CatDoes Watch SDK - Global Error Handlers
365
- *
366
- * Sets up global error handlers to automatically capture unhandled errors.
367
- * Supports both web (window.onerror) and React Native (ErrorUtils).
368
- */
369
-
370
- /**
371
- * Sets up global error handlers for the given Watch client.
372
- */
373
187
  declare function setupGlobalHandlers(client: WatchClient): void;
374
- /**
375
- * Sets up console.error interception (optional, can be noisy).
376
- */
377
- declare function setupConsoleErrorCapture(client: WatchClient): void;
378
- /**
379
- * Removes all installed global handlers.
380
- */
381
188
  declare function removeGlobalHandlers(): void;
382
189
 
383
- /**
384
- * CatDoes Watch SDK - Session Management
385
- *
386
- * Generates and manages a unique session ID for the current app session.
387
- * The session ID is used to group errors from the same user session.
388
- */
389
- /**
390
- * Gets the current session ID, generating one if it doesn't exist.
391
- * The session ID persists for the lifetime of the app process.
392
- */
190
+ declare function installHttpBreadcrumbs(client: WatchClient): void;
191
+ declare function removeHttpBreadcrumbs(): void;
192
+
393
193
  declare function getSessionId(): string;
394
- /**
395
- * Resets the session ID, forcing a new one to be generated.
396
- * This can be called when a user logs out or the app wants to start fresh.
397
- */
398
194
  declare function resetSession(): void;
399
- /**
400
- * Sets a specific session ID (useful for testing or migration).
401
- */
402
195
  declare function setSessionId(sessionId: string): void;
403
196
 
404
- /**
405
- * CatDoes Watch SDK - Context Collection
406
- *
407
- * Collects device and environment information to attach to error events.
408
- * Uses Expo and React Native APIs where available.
409
- */
410
-
411
- /**
412
- * Gets the current platform: 'ios', 'android', or 'web'.
413
- */
414
197
  declare function getPlatform(): "ios" | "android" | "web";
415
- /**
416
- * Gets the current environment based on __DEV__ flag.
417
- */
418
198
  declare function getEnvironment(): "development" | "production";
419
- /**
420
- * Collects device and environment information.
421
- * Only includes fields that are in the server's allowlist.
422
- */
423
- declare function collectDeviceInfo(): DeviceInfo;
424
- declare function getCachedDeviceInfo(): DeviceInfo;
425
- /**
426
- * Clears the cached device info, forcing re-collection on next call.
427
- */
428
- declare function clearDeviceInfoCache(): void;
199
+ declare function getDeviceInfo(): DeviceInfo;
429
200
 
430
201
  /**
431
202
  * CatDoes Watch SDK - Breadcrumb Management
@@ -484,28 +255,11 @@ declare function createConsoleBreadcrumb(level: "log" | "warn" | "error" | "info
484
255
  */
485
256
  declare function createCustomBreadcrumb(message: string, data?: Record<string, unknown>): BreadcrumbInput;
486
257
 
487
- /**
488
- * CatDoes Watch SDK - Symbolication Helpers
489
- *
490
- * Utilities for processing stack traces and file paths.
491
- */
492
- /**
493
- * Produces a readable file path from a Metro/URL-style file reference.
494
- * - Strips query params
495
- * - Prefers repo-relative paths like app/... or src/...
496
- * - Falls back to URL pathname
497
- */
498
- declare function deriveReadableFile(file: string): string;
499
- /**
500
- * Checks if a derived filename is usable (not a noisy bundle/node_modules path)
501
- */
502
- declare function isUsableFilename(filename: string): boolean;
503
-
504
258
  /**
505
259
  * CatDoes Watch SDK - Version
506
260
  *
507
261
  * Keep this value updated when making SDK changes.
508
262
  */
509
- declare const SDK_VERSION = "1.3.0";
263
+ declare const SDK_VERSION = "2.0.0";
510
264
 
511
- export { type Breadcrumb, type BreadcrumbInput, BreadcrumbManager, type DeviceInfo, type IngestResponse, SDK_VERSION, Watch, WatchClient, type WatchConfig, type WatchConfigResolved, type WatchEvent, type WatchStorage, clearDeviceInfoCache, collectDeviceInfo, createConsoleBreadcrumb, createCustomBreadcrumb, createHttpBreadcrumb, createNavigationBreadcrumb, createUIBreadcrumb, deriveReadableFile, getCachedDeviceInfo, getEnvironment, getPlatform, getSessionId, isUsableFilename, removeGlobalHandlers, resetSession, setSessionId, setupConsoleErrorCapture, setupGlobalHandlers };
265
+ export { type Breadcrumb, type BreadcrumbInput, BreadcrumbManager, type DeviceInfo, type IngestResponse, type QueueStore, SDK_VERSION, Watch, WatchClient, type WatchConfig, type WatchConfigResolved, type WatchEvent, type WatchStats, createConsoleBreadcrumb, createCustomBreadcrumb, createHttpBreadcrumb, createNavigationBreadcrumb, createUIBreadcrumb, getDeviceInfo, getEnvironment, getPlatform, getSessionId, installHttpBreadcrumbs, removeGlobalHandlers, removeHttpBreadcrumbs, resetSession, setSessionId, setupGlobalHandlers };