@debugkit/sdk 0.0.0-stage → 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.
Files changed (57) hide show
  1. package/README.md +228 -2
  2. package/dist/chunk-3WRI3DI2.js +41 -0
  3. package/dist/chunk-3WRI3DI2.js.map +1 -0
  4. package/dist/chunk-5C7KJJNO.js +651 -0
  5. package/dist/chunk-5C7KJJNO.js.map +1 -0
  6. package/dist/chunk-EGCXLOFH.cjs +663 -0
  7. package/dist/chunk-EGCXLOFH.cjs.map +1 -0
  8. package/dist/chunk-HO3JW55K.js +79 -0
  9. package/dist/chunk-HO3JW55K.js.map +1 -0
  10. package/dist/chunk-NJ6DTUVX.cjs +83 -0
  11. package/dist/chunk-NJ6DTUVX.cjs.map +1 -0
  12. package/dist/chunk-YELZOB7J.cjs +45 -0
  13. package/dist/chunk-YELZOB7J.cjs.map +1 -0
  14. package/dist/client-ekzlpWIR.d.cts +220 -0
  15. package/dist/client-ekzlpWIR.d.ts +220 -0
  16. package/dist/expo-router.cjs +13 -0
  17. package/dist/expo-router.cjs.map +1 -0
  18. package/dist/expo-router.d.cts +10 -0
  19. package/dist/expo-router.d.ts +10 -0
  20. package/dist/expo-router.js +11 -0
  21. package/dist/expo-router.js.map +1 -0
  22. package/dist/expo.cjs +97 -0
  23. package/dist/expo.cjs.map +1 -0
  24. package/dist/expo.d.cts +14 -0
  25. package/dist/expo.d.ts +14 -0
  26. package/dist/expo.js +47 -0
  27. package/dist/expo.js.map +1 -0
  28. package/dist/index.cjs +40 -0
  29. package/dist/index.cjs.map +1 -0
  30. package/dist/index.d.cts +11 -0
  31. package/dist/index.d.ts +11 -0
  32. package/dist/index.js +3 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/node.cjs +140 -0
  35. package/dist/node.cjs.map +1 -0
  36. package/dist/node.d.cts +20 -0
  37. package/dist/node.d.ts +20 -0
  38. package/dist/node.js +100 -0
  39. package/dist/node.js.map +1 -0
  40. package/dist/react-native.cjs +38 -0
  41. package/dist/react-native.cjs.map +1 -0
  42. package/dist/react-native.d.cts +51 -0
  43. package/dist/react-native.d.ts +51 -0
  44. package/dist/react-native.js +5 -0
  45. package/dist/react-native.js.map +1 -0
  46. package/dist/react.cjs +25 -0
  47. package/dist/react.cjs.map +1 -0
  48. package/dist/react.d.cts +50 -0
  49. package/dist/react.d.ts +50 -0
  50. package/dist/react.js +4 -0
  51. package/dist/react.js.map +1 -0
  52. package/expo/package.json +6 -0
  53. package/expo-router/package.json +6 -0
  54. package/node/package.json +6 -0
  55. package/package.json +121 -3
  56. package/react/package.json +6 -0
  57. package/react-native/package.json +6 -0
@@ -0,0 +1,220 @@
1
+ import { ContextInput, EventInput, Breadcrumb, Severity, parseStack } from '@debugkit/schema/core';
2
+
3
+ type Shallow<T> = {
4
+ [K in keyof T]?: T[K] extends object ? Partial<T[K]> : T[K];
5
+ };
6
+ type ContextPatch = Shallow<ContextInput>;
7
+ /** Merge two context patches one level deep (os, device, app ... are merged field by field). */
8
+ declare function mergeContext(a: ContextPatch, b: ContextPatch): ContextPatch;
9
+ /**
10
+ * Best-effort context for browsers (React, TanStack Start/Router client, Next client ...).
11
+ * Safe to call in any runtime: it never touches globals that might not exist.
12
+ */
13
+ declare function browserContext(): ContextPatch;
14
+
15
+ /**
16
+ * Automatic instrumentation installed by `init()`: network requests, console, navigation,
17
+ * clicks and page lifecycle. Every installer is a no-op on platforms that lack the global it
18
+ * patches, and returns a function that undoes the patch.
19
+ */
20
+ interface RequestInfo {
21
+ method: string;
22
+ url: string;
23
+ status?: number;
24
+ error?: unknown;
25
+ aborted?: boolean;
26
+ timedOut?: boolean;
27
+ durationMs: number;
28
+ /** Stack captured where the request was made, so a failure points at the calling code. */
29
+ stack?: string;
30
+ }
31
+ /** What the instrumentation needs from the client. */
32
+ interface AutoSink {
33
+ request(info: RequestInfo): void;
34
+ crumb(category: "navigation" | "network" | "ui" | "log", message: string, level?: "debug" | "info" | "warning" | "error", data?: Record<string, string | number | boolean | null>): void;
35
+ navigated(to: string): void;
36
+ lifecycle(state: "foreground" | "background"): void;
37
+ ignored(url: string): boolean;
38
+ }
39
+ /**
40
+ * "https://api.x.com/v1/orders/8812?token=abc" → "api.x.com/v1/orders/:id". Query strings and
41
+ * fragments never leave the device (they often carry tokens and personal data), and ids are
42
+ * replaced so requests group by endpoint. Same-origin URLs keep only the path.
43
+ */
44
+ declare function normaliseUrl(raw: string): string;
45
+
46
+ declare const SDK_NAME = "@debugkit/sdk";
47
+ declare const SDK_VERSION = "0.2.0";
48
+ /** Optional persistence so events survive app restarts / offline. e.g. AsyncStorage. */
49
+ interface QueueStorage {
50
+ getItem(key: string): Promise<string | null>;
51
+ setItem(key: string, value: string): Promise<void>;
52
+ }
53
+ interface InitOptions {
54
+ /** URL of the ingest function deployed in your cloud. */
55
+ endpoint: string;
56
+ /** Public, write-only key. Safe to ship in the app. */
57
+ ingestKey: string;
58
+ app: {
59
+ id: string;
60
+ version?: string;
61
+ build?: string;
62
+ environment?: string;
63
+ };
64
+ /**
65
+ * Platform context. Defaults to browserContext() in browsers. The framework entry points
66
+ * (`/expo`, `/react-native`, `/node`) fill this in for you.
67
+ */
68
+ context?: ContextPatch;
69
+ /**
70
+ * What deBug records on its own once initialised. Everything is on by default; pass `false`
71
+ * to turn it all off, or switch parts off: `autoCapture: { console: false }`.
72
+ */
73
+ autoCapture?: boolean | AutoCaptureOptions;
74
+ /** Network capture settings. */
75
+ network?: NetworkOptions;
76
+ /** Fraction of errors and events to keep, 0 to 1. Sessions are never sampled. Default 1. */
77
+ sampleRate?: number;
78
+ /** At most this many errors are sent per minute, and at most a sixth of that for one repeating error. Default 60. */
79
+ maxErrorsPerMinute?: number;
80
+ /** @deprecated Use `autoCapture: { errors: false }`. */
81
+ captureGlobalErrors?: boolean;
82
+ storage?: QueueStorage;
83
+ /** How often queued events are sent. 0 disables the timer (edge runtimes): call flush() yourself. Default 5000. */
84
+ flushIntervalMs?: number;
85
+ maxBatch?: number;
86
+ maxBreadcrumbs?: number;
87
+ /** Drop or edit events before they are sent (PII scrubbing). Return null to drop. */
88
+ beforeSend?: (e: EventInput) => EventInput | null;
89
+ fetch?: typeof fetch;
90
+ debug?: boolean;
91
+ }
92
+ interface AutoCaptureOptions {
93
+ /** Uncaught errors and unhandled promise rejections. */
94
+ errors?: boolean;
95
+ /** fetch and XMLHttpRequest: a breadcrumb for every request, an error for each failed one. */
96
+ network?: boolean;
97
+ /** console.warn and console.error as breadcrumbs. */
98
+ console?: boolean;
99
+ /** Page changes in browsers (History API), so any router is covered. */
100
+ navigation?: boolean;
101
+ /** Clicks on buttons, links and other controls in browsers, by their label. */
102
+ clicks?: boolean;
103
+ /** Foreground/background and online/offline as breadcrumbs; flushes when the app is hidden. */
104
+ lifecycle?: boolean;
105
+ /** Session start, errored and crashed markers, for crash-free rates per release. */
106
+ sessions?: boolean;
107
+ }
108
+ interface NetworkOptions {
109
+ /** URLs never recorded (substring or regex). The ingest endpoint is always skipped. */
110
+ ignoreUrls?: (string | RegExp)[];
111
+ /**
112
+ * Tag requests with a flow by URL, first match wins:
113
+ * `flows: [["/v2/auth/", "auth.login"], [/\/payments\//, "checkout.payment"]]`.
114
+ */
115
+ flows?: [string | RegExp, string][];
116
+ /** Which HTTP statuses count as failures. Default: 500 and above. Network failures and timeouts always count. */
117
+ isFailure?: (status: number, url: string) => boolean;
118
+ /** Requests slower than this get a warning breadcrumb. Default 3000ms. */
119
+ slowMs?: number;
120
+ }
121
+ interface EventMeta {
122
+ flow?: string;
123
+ step?: string;
124
+ tags?: Record<string, string>;
125
+ }
126
+ declare class DebugClient {
127
+ private opts;
128
+ private queue;
129
+ private crumbs;
130
+ private session;
131
+ private user;
132
+ private timer;
133
+ private flushing;
134
+ private backoffUntil;
135
+ private failures;
136
+ private ready;
137
+ private handlersInstalled;
138
+ private auto;
139
+ private restores;
140
+ private sessionState;
141
+ private lastNav;
142
+ private limits;
143
+ /** fetch as it was before instrumentation, so our own uploads are never recorded. */
144
+ private rawFetch;
145
+ init(options: InitOptions): this;
146
+ /** Which automatic captures are on, after defaults. */
147
+ get autoCapture(): Readonly<Required<AutoCaptureOptions>>;
148
+ /**
149
+ * Begin a new session: a fresh id and a "started" marker. Called by `init()`, and by the
150
+ * React Native entry when the app returns after 30 minutes in the background.
151
+ */
152
+ startSession(): void;
153
+ /** Record a navigation breadcrumb ("from → to"). Repeated paths are ignored. */
154
+ navigated(to: string): void;
155
+ get initialized(): boolean;
156
+ /** Merge extra context (e.g. after an async device lookup). Applies to events sent from now on. */
157
+ setContext(patch: ContextPatch): void;
158
+ setUser(id: string | undefined): void;
159
+ breadcrumb(category: Breadcrumb["category"], message: string, data?: Record<string, string | number | boolean | null>, level?: Breadcrumb["level"]): void;
160
+ /** Log an error. `flow` is the part of the app it belongs to, e.g. "auth.login". */
161
+ error(err: unknown, meta?: EventMeta & {
162
+ severity?: Severity;
163
+ handled?: boolean;
164
+ fatal?: boolean;
165
+ }): void;
166
+ /** Log a custom event. Use outcome to let deBug compute failure rates per flow. */
167
+ event(name: string, meta?: EventMeta & {
168
+ outcome?: "success" | "failure" | "abandoned";
169
+ props?: Record<string, string | number | boolean | null>;
170
+ }): void;
171
+ /**
172
+ * Wraps an async step: logs a success or failure outcome for the flow, plus the error.
173
+ * Pass `{ captureError: false }` when the error is already reported elsewhere, e.g. a
174
+ * server function wrapped in withDebug, so it isn't counted twice.
175
+ */
176
+ track<T>(flow: string, step: string, fn: () => Promise<T>, opts?: {
177
+ captureError?: boolean;
178
+ }): Promise<T>;
179
+ flush(): Promise<void>;
180
+ /** Stop the flush timer, undo automatic instrumentation and send what is queued. */
181
+ close(): Promise<void>;
182
+ /** @internal Used by the platform entry points for errors that have no thrown value. */
183
+ captureError(e: {
184
+ name: string;
185
+ message: string;
186
+ stack?: string;
187
+ frames?: ReturnType<typeof parseStack>;
188
+ }, meta: EventMeta & {
189
+ severity?: Severity;
190
+ handled?: boolean;
191
+ fatal?: boolean;
192
+ }, request?: {
193
+ method: string;
194
+ url: string;
195
+ status?: number;
196
+ durationMs?: number;
197
+ }): void;
198
+ /** Per-minute limits: one runaway error can't flood the queue, the network or your database. */
199
+ private allowError;
200
+ private sampled;
201
+ private enqueue;
202
+ /** Queue without sampling (sessions must be complete for crash-free rates to be right). */
203
+ private push;
204
+ private buildContext;
205
+ /** Set when the ingest rejects 0.2 fields: it predates them, so send what it understands. */
206
+ private legacyIngest;
207
+ private send;
208
+ private persist;
209
+ private restore;
210
+ private installGlobalHandlers;
211
+ private instrument;
212
+ private uninstrument;
213
+ /** The bridge the instrumentation (./auto, and the platform entry points) reports through. */
214
+ sink(): AutoSink;
215
+ private isIgnored;
216
+ private recordRequest;
217
+ private log;
218
+ }
219
+
220
+ export { type AutoCaptureOptions as A, type ContextPatch as C, DebugClient as D, type EventMeta as E, type InitOptions as I, type NetworkOptions as N, type QueueStorage as Q, SDK_NAME as S, SDK_VERSION as a, browserContext as b, mergeContext as m, normaliseUrl as n };
@@ -0,0 +1,220 @@
1
+ import { ContextInput, EventInput, Breadcrumb, Severity, parseStack } from '@debugkit/schema/core';
2
+
3
+ type Shallow<T> = {
4
+ [K in keyof T]?: T[K] extends object ? Partial<T[K]> : T[K];
5
+ };
6
+ type ContextPatch = Shallow<ContextInput>;
7
+ /** Merge two context patches one level deep (os, device, app ... are merged field by field). */
8
+ declare function mergeContext(a: ContextPatch, b: ContextPatch): ContextPatch;
9
+ /**
10
+ * Best-effort context for browsers (React, TanStack Start/Router client, Next client ...).
11
+ * Safe to call in any runtime: it never touches globals that might not exist.
12
+ */
13
+ declare function browserContext(): ContextPatch;
14
+
15
+ /**
16
+ * Automatic instrumentation installed by `init()`: network requests, console, navigation,
17
+ * clicks and page lifecycle. Every installer is a no-op on platforms that lack the global it
18
+ * patches, and returns a function that undoes the patch.
19
+ */
20
+ interface RequestInfo {
21
+ method: string;
22
+ url: string;
23
+ status?: number;
24
+ error?: unknown;
25
+ aborted?: boolean;
26
+ timedOut?: boolean;
27
+ durationMs: number;
28
+ /** Stack captured where the request was made, so a failure points at the calling code. */
29
+ stack?: string;
30
+ }
31
+ /** What the instrumentation needs from the client. */
32
+ interface AutoSink {
33
+ request(info: RequestInfo): void;
34
+ crumb(category: "navigation" | "network" | "ui" | "log", message: string, level?: "debug" | "info" | "warning" | "error", data?: Record<string, string | number | boolean | null>): void;
35
+ navigated(to: string): void;
36
+ lifecycle(state: "foreground" | "background"): void;
37
+ ignored(url: string): boolean;
38
+ }
39
+ /**
40
+ * "https://api.x.com/v1/orders/8812?token=abc" → "api.x.com/v1/orders/:id". Query strings and
41
+ * fragments never leave the device (they often carry tokens and personal data), and ids are
42
+ * replaced so requests group by endpoint. Same-origin URLs keep only the path.
43
+ */
44
+ declare function normaliseUrl(raw: string): string;
45
+
46
+ declare const SDK_NAME = "@debugkit/sdk";
47
+ declare const SDK_VERSION = "0.2.0";
48
+ /** Optional persistence so events survive app restarts / offline. e.g. AsyncStorage. */
49
+ interface QueueStorage {
50
+ getItem(key: string): Promise<string | null>;
51
+ setItem(key: string, value: string): Promise<void>;
52
+ }
53
+ interface InitOptions {
54
+ /** URL of the ingest function deployed in your cloud. */
55
+ endpoint: string;
56
+ /** Public, write-only key. Safe to ship in the app. */
57
+ ingestKey: string;
58
+ app: {
59
+ id: string;
60
+ version?: string;
61
+ build?: string;
62
+ environment?: string;
63
+ };
64
+ /**
65
+ * Platform context. Defaults to browserContext() in browsers. The framework entry points
66
+ * (`/expo`, `/react-native`, `/node`) fill this in for you.
67
+ */
68
+ context?: ContextPatch;
69
+ /**
70
+ * What deBug records on its own once initialised. Everything is on by default; pass `false`
71
+ * to turn it all off, or switch parts off: `autoCapture: { console: false }`.
72
+ */
73
+ autoCapture?: boolean | AutoCaptureOptions;
74
+ /** Network capture settings. */
75
+ network?: NetworkOptions;
76
+ /** Fraction of errors and events to keep, 0 to 1. Sessions are never sampled. Default 1. */
77
+ sampleRate?: number;
78
+ /** At most this many errors are sent per minute, and at most a sixth of that for one repeating error. Default 60. */
79
+ maxErrorsPerMinute?: number;
80
+ /** @deprecated Use `autoCapture: { errors: false }`. */
81
+ captureGlobalErrors?: boolean;
82
+ storage?: QueueStorage;
83
+ /** How often queued events are sent. 0 disables the timer (edge runtimes): call flush() yourself. Default 5000. */
84
+ flushIntervalMs?: number;
85
+ maxBatch?: number;
86
+ maxBreadcrumbs?: number;
87
+ /** Drop or edit events before they are sent (PII scrubbing). Return null to drop. */
88
+ beforeSend?: (e: EventInput) => EventInput | null;
89
+ fetch?: typeof fetch;
90
+ debug?: boolean;
91
+ }
92
+ interface AutoCaptureOptions {
93
+ /** Uncaught errors and unhandled promise rejections. */
94
+ errors?: boolean;
95
+ /** fetch and XMLHttpRequest: a breadcrumb for every request, an error for each failed one. */
96
+ network?: boolean;
97
+ /** console.warn and console.error as breadcrumbs. */
98
+ console?: boolean;
99
+ /** Page changes in browsers (History API), so any router is covered. */
100
+ navigation?: boolean;
101
+ /** Clicks on buttons, links and other controls in browsers, by their label. */
102
+ clicks?: boolean;
103
+ /** Foreground/background and online/offline as breadcrumbs; flushes when the app is hidden. */
104
+ lifecycle?: boolean;
105
+ /** Session start, errored and crashed markers, for crash-free rates per release. */
106
+ sessions?: boolean;
107
+ }
108
+ interface NetworkOptions {
109
+ /** URLs never recorded (substring or regex). The ingest endpoint is always skipped. */
110
+ ignoreUrls?: (string | RegExp)[];
111
+ /**
112
+ * Tag requests with a flow by URL, first match wins:
113
+ * `flows: [["/v2/auth/", "auth.login"], [/\/payments\//, "checkout.payment"]]`.
114
+ */
115
+ flows?: [string | RegExp, string][];
116
+ /** Which HTTP statuses count as failures. Default: 500 and above. Network failures and timeouts always count. */
117
+ isFailure?: (status: number, url: string) => boolean;
118
+ /** Requests slower than this get a warning breadcrumb. Default 3000ms. */
119
+ slowMs?: number;
120
+ }
121
+ interface EventMeta {
122
+ flow?: string;
123
+ step?: string;
124
+ tags?: Record<string, string>;
125
+ }
126
+ declare class DebugClient {
127
+ private opts;
128
+ private queue;
129
+ private crumbs;
130
+ private session;
131
+ private user;
132
+ private timer;
133
+ private flushing;
134
+ private backoffUntil;
135
+ private failures;
136
+ private ready;
137
+ private handlersInstalled;
138
+ private auto;
139
+ private restores;
140
+ private sessionState;
141
+ private lastNav;
142
+ private limits;
143
+ /** fetch as it was before instrumentation, so our own uploads are never recorded. */
144
+ private rawFetch;
145
+ init(options: InitOptions): this;
146
+ /** Which automatic captures are on, after defaults. */
147
+ get autoCapture(): Readonly<Required<AutoCaptureOptions>>;
148
+ /**
149
+ * Begin a new session: a fresh id and a "started" marker. Called by `init()`, and by the
150
+ * React Native entry when the app returns after 30 minutes in the background.
151
+ */
152
+ startSession(): void;
153
+ /** Record a navigation breadcrumb ("from → to"). Repeated paths are ignored. */
154
+ navigated(to: string): void;
155
+ get initialized(): boolean;
156
+ /** Merge extra context (e.g. after an async device lookup). Applies to events sent from now on. */
157
+ setContext(patch: ContextPatch): void;
158
+ setUser(id: string | undefined): void;
159
+ breadcrumb(category: Breadcrumb["category"], message: string, data?: Record<string, string | number | boolean | null>, level?: Breadcrumb["level"]): void;
160
+ /** Log an error. `flow` is the part of the app it belongs to, e.g. "auth.login". */
161
+ error(err: unknown, meta?: EventMeta & {
162
+ severity?: Severity;
163
+ handled?: boolean;
164
+ fatal?: boolean;
165
+ }): void;
166
+ /** Log a custom event. Use outcome to let deBug compute failure rates per flow. */
167
+ event(name: string, meta?: EventMeta & {
168
+ outcome?: "success" | "failure" | "abandoned";
169
+ props?: Record<string, string | number | boolean | null>;
170
+ }): void;
171
+ /**
172
+ * Wraps an async step: logs a success or failure outcome for the flow, plus the error.
173
+ * Pass `{ captureError: false }` when the error is already reported elsewhere, e.g. a
174
+ * server function wrapped in withDebug, so it isn't counted twice.
175
+ */
176
+ track<T>(flow: string, step: string, fn: () => Promise<T>, opts?: {
177
+ captureError?: boolean;
178
+ }): Promise<T>;
179
+ flush(): Promise<void>;
180
+ /** Stop the flush timer, undo automatic instrumentation and send what is queued. */
181
+ close(): Promise<void>;
182
+ /** @internal Used by the platform entry points for errors that have no thrown value. */
183
+ captureError(e: {
184
+ name: string;
185
+ message: string;
186
+ stack?: string;
187
+ frames?: ReturnType<typeof parseStack>;
188
+ }, meta: EventMeta & {
189
+ severity?: Severity;
190
+ handled?: boolean;
191
+ fatal?: boolean;
192
+ }, request?: {
193
+ method: string;
194
+ url: string;
195
+ status?: number;
196
+ durationMs?: number;
197
+ }): void;
198
+ /** Per-minute limits: one runaway error can't flood the queue, the network or your database. */
199
+ private allowError;
200
+ private sampled;
201
+ private enqueue;
202
+ /** Queue without sampling (sessions must be complete for crash-free rates to be right). */
203
+ private push;
204
+ private buildContext;
205
+ /** Set when the ingest rejects 0.2 fields: it predates them, so send what it understands. */
206
+ private legacyIngest;
207
+ private send;
208
+ private persist;
209
+ private restore;
210
+ private installGlobalHandlers;
211
+ private instrument;
212
+ private uninstrument;
213
+ /** The bridge the instrumentation (./auto, and the platform entry points) reports through. */
214
+ sink(): AutoSink;
215
+ private isIgnored;
216
+ private recordRequest;
217
+ private log;
218
+ }
219
+
220
+ export { type AutoCaptureOptions as A, type ContextPatch as C, DebugClient as D, type EventMeta as E, type InitOptions as I, type NetworkOptions as N, type QueueStorage as Q, SDK_NAME as S, SDK_VERSION as a, browserContext as b, mergeContext as m, normaliseUrl as n };
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ var chunkYELZOB7J_cjs = require('./chunk-YELZOB7J.cjs');
4
+ var chunkEGCXLOFH_cjs = require('./chunk-EGCXLOFH.cjs');
5
+ var expoRouter = require('expo-router');
6
+
7
+ function useDebugExpoRouter(client = chunkEGCXLOFH_cjs.deBug) {
8
+ chunkYELZOB7J_cjs.useDebugNavigation(expoRouter.usePathname(), client);
9
+ }
10
+
11
+ exports.useDebugExpoRouter = useDebugExpoRouter;
12
+ //# sourceMappingURL=expo-router.cjs.map
13
+ //# sourceMappingURL=expo-router.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/expo-router.ts"],"names":["deBug","useDebugNavigation","usePathname"],"mappings":";;;;;;AAQO,SAAS,kBAAA,CAAmB,SAAsBA,uBAAA,EAAO;AAC9D,EAAAC,oCAAA,CAAmBC,sBAAA,IAAe,MAAM,CAAA;AAC1C","file":"expo-router.cjs","sourcesContent":["import { usePathname } from \"expo-router\";\nimport { deBug, type DebugClient } from \"./index\";\nimport { useDebugNavigation } from \"./react\";\n\n/**\n * Navigation breadcrumbs for Expo Router. Call once in your root layout:\n * export default function RootLayout() { useDebugExpoRouter(); return <Stack />; }\n */\nexport function useDebugExpoRouter(client: DebugClient = deBug) {\n useDebugNavigation(usePathname(), client);\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import { D as DebugClient } from './client-ekzlpWIR.cjs';
2
+ import '@debugkit/schema/core';
3
+
4
+ /**
5
+ * Navigation breadcrumbs for Expo Router. Call once in your root layout:
6
+ * export default function RootLayout() { useDebugExpoRouter(); return <Stack />; }
7
+ */
8
+ declare function useDebugExpoRouter(client?: DebugClient): void;
9
+
10
+ export { useDebugExpoRouter };
@@ -0,0 +1,10 @@
1
+ import { D as DebugClient } from './client-ekzlpWIR.js';
2
+ import '@debugkit/schema/core';
3
+
4
+ /**
5
+ * Navigation breadcrumbs for Expo Router. Call once in your root layout:
6
+ * export default function RootLayout() { useDebugExpoRouter(); return <Stack />; }
7
+ */
8
+ declare function useDebugExpoRouter(client?: DebugClient): void;
9
+
10
+ export { useDebugExpoRouter };
@@ -0,0 +1,11 @@
1
+ import { useDebugNavigation } from './chunk-3WRI3DI2.js';
2
+ import { deBug } from './chunk-5C7KJJNO.js';
3
+ import { usePathname } from 'expo-router';
4
+
5
+ function useDebugExpoRouter(client = deBug) {
6
+ useDebugNavigation(usePathname(), client);
7
+ }
8
+
9
+ export { useDebugExpoRouter };
10
+ //# sourceMappingURL=expo-router.js.map
11
+ //# sourceMappingURL=expo-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/expo-router.ts"],"names":[],"mappings":";;;;AAQO,SAAS,kBAAA,CAAmB,SAAsB,KAAA,EAAO;AAC9D,EAAA,kBAAA,CAAmB,WAAA,IAAe,MAAM,CAAA;AAC1C","file":"expo-router.js","sourcesContent":["import { usePathname } from \"expo-router\";\nimport { deBug, type DebugClient } from \"./index\";\nimport { useDebugNavigation } from \"./react\";\n\n/**\n * Navigation breadcrumbs for Expo Router. Call once in your root layout:\n * export default function RootLayout() { useDebugExpoRouter(); return <Stack />; }\n */\nexport function useDebugExpoRouter(client: DebugClient = deBug) {\n useDebugNavigation(usePathname(), client);\n}\n"]}
package/dist/expo.cjs ADDED
@@ -0,0 +1,97 @@
1
+ 'use strict';
2
+
3
+ var chunkNJ6DTUVX_cjs = require('./chunk-NJ6DTUVX.cjs');
4
+ var chunkYELZOB7J_cjs = require('./chunk-YELZOB7J.cjs');
5
+ var chunkEGCXLOFH_cjs = require('./chunk-EGCXLOFH.cjs');
6
+ var Application = require('expo-application');
7
+ var Device = require('expo-device');
8
+
9
+ function _interopNamespace(e) {
10
+ if (e && e.__esModule) return e;
11
+ var n = Object.create(null);
12
+ if (e) {
13
+ Object.keys(e).forEach(function (k) {
14
+ if (k !== 'default') {
15
+ var d = Object.getOwnPropertyDescriptor(e, k);
16
+ Object.defineProperty(n, k, d.get ? d : {
17
+ enumerable: true,
18
+ get: function () { return e[k]; }
19
+ });
20
+ }
21
+ });
22
+ }
23
+ n.default = e;
24
+ return Object.freeze(n);
25
+ }
26
+
27
+ var Application__namespace = /*#__PURE__*/_interopNamespace(Application);
28
+ var Device__namespace = /*#__PURE__*/_interopNamespace(Device);
29
+
30
+ function osName2(raw) {
31
+ const n = (raw != null ? raw : "").toLowerCase();
32
+ if (n.includes("android")) return "android";
33
+ if (n === "ios" || n === "ipados") return "ios";
34
+ return n || "unknown";
35
+ }
36
+ var DEVICE_TYPES = { 1: "phone", 2: "tablet", 3: "desktop", 4: "tv" };
37
+ function expoContext() {
38
+ var _a, _b, _c, _d, _e, _f, _g;
39
+ return {
40
+ os: Device__namespace.osVersion ? { name: osName2(Device__namespace.osName), version: Device__namespace.osVersion } : void 0,
41
+ device: {
42
+ model: (_a = Device__namespace.modelName) != null ? _a : void 0,
43
+ manufacturer: (_b = Device__namespace.manufacturer) != null ? _b : void 0,
44
+ brand: (_c = Device__namespace.brand) != null ? _c : void 0,
45
+ isEmulator: !Device__namespace.isDevice,
46
+ memoryMb: Device__namespace.totalMemory ? Math.round(Device__namespace.totalMemory / 1024 / 1024) : void 0,
47
+ type: (_e = DEVICE_TYPES[(_d = Device__namespace.deviceType) != null ? _d : 0]) != null ? _e : "unknown"
48
+ },
49
+ app: {
50
+ version: (_f = Application__namespace.nativeApplicationVersion) != null ? _f : void 0,
51
+ build: (_g = Application__namespace.nativeBuildVersion) != null ? _g : void 0
52
+ }
53
+ };
54
+ }
55
+ function initExpo(options, client = chunkEGCXLOFH_cjs.deBug) {
56
+ var _a;
57
+ const ctx = expoContext();
58
+ const merged = chunkEGCXLOFH_cjs.mergeContext(ctx, (_a = options.context) != null ? _a : {});
59
+ if (!ctx.os) delete merged.os;
60
+ return chunkNJ6DTUVX_cjs.initReactNative(
61
+ { ...options, app: { ...ctx.app, ...options.app }, context: merged },
62
+ client
63
+ );
64
+ }
65
+
66
+ Object.defineProperty(exports, "initReactNative", {
67
+ enumerable: true,
68
+ get: function () { return chunkNJ6DTUVX_cjs.initReactNative; }
69
+ });
70
+ Object.defineProperty(exports, "nativeContext", {
71
+ enumerable: true,
72
+ get: function () { return chunkNJ6DTUVX_cjs.nativeContext; }
73
+ });
74
+ Object.defineProperty(exports, "trackReactNavigation", {
75
+ enumerable: true,
76
+ get: function () { return chunkNJ6DTUVX_cjs.trackReactNavigation; }
77
+ });
78
+ Object.defineProperty(exports, "DebugErrorBoundary", {
79
+ enumerable: true,
80
+ get: function () { return chunkYELZOB7J_cjs.DebugErrorBoundary; }
81
+ });
82
+ Object.defineProperty(exports, "trackTanStackRouter", {
83
+ enumerable: true,
84
+ get: function () { return chunkYELZOB7J_cjs.trackTanStackRouter; }
85
+ });
86
+ Object.defineProperty(exports, "useDebugNavigation", {
87
+ enumerable: true,
88
+ get: function () { return chunkYELZOB7J_cjs.useDebugNavigation; }
89
+ });
90
+ Object.defineProperty(exports, "deBug", {
91
+ enumerable: true,
92
+ get: function () { return chunkEGCXLOFH_cjs.deBug; }
93
+ });
94
+ exports.expoContext = expoContext;
95
+ exports.initExpo = initExpo;
96
+ //# sourceMappingURL=expo.cjs.map
97
+ //# sourceMappingURL=expo.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/expo.ts"],"names":["osName","Device","Application","deBug","mergeContext","initReactNative"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,SAASA,QAAO,GAAA,EAA4B;AAC1C,EAAA,MAAM,CAAA,GAAA,CAAK,GAAA,IAAA,IAAA,GAAA,GAAA,GAAO,EAAA,EAAI,WAAA,EAAY;AAClC,EAAA,IAAI,CAAA,CAAE,QAAA,CAAS,SAAS,CAAA,EAAG,OAAO,SAAA;AAClC,EAAA,IAAI,CAAA,KAAM,KAAA,IAAS,CAAA,KAAM,QAAA,EAAU,OAAO,KAAA;AAC1C,EAAA,OAAO,CAAA,IAAK,SAAA;AACd;AAEA,IAAM,YAAA,GAAe,EAAE,CAAA,EAAG,OAAA,EAAS,GAAG,QAAA,EAAU,CAAA,EAAG,SAAA,EAAW,CAAA,EAAG,IAAA,EAAK;AAG/D,SAAS,WAAA,GAA4B;AAlB5C,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAmBE,EAAA,OAAO;AAAA,IACL,EAAA,EAAWC,8BAAY,EAAE,IAAA,EAAMD,QAAcC,iBAAA,CAAA,MAAM,CAAA,EAAG,OAAA,EAAgBA,iBAAA,CAAA,SAAA,EAAU,GAAI,MAAA;AAAA,IACpF,MAAA,EAAQ;AAAA,MACN,KAAA,EAAA,CAAO,EAAA,GAAOA,iBAAA,CAAA,SAAA,KAAP,IAAA,GAAA,EAAA,GAAoB,MAAA;AAAA,MAC3B,YAAA,EAAA,CAAc,EAAA,GAAOA,iBAAA,CAAA,YAAA,KAAP,IAAA,GAAA,EAAA,GAAuB,MAAA;AAAA,MACrC,KAAA,EAAA,CAAO,EAAA,GAAOA,iBAAA,CAAA,KAAA,KAAP,IAAA,GAAA,EAAA,GAAgB,MAAA;AAAA,MACvB,YAAY,CAAQA,iBAAA,CAAA,QAAA;AAAA,MACpB,UAAiBA,iBAAA,CAAA,WAAA,GAAc,IAAA,CAAK,MAAaA,iBAAA,CAAA,WAAA,GAAc,IAAA,GAAO,IAAI,CAAA,GAAI,MAAA;AAAA,MAC9E,OAAM,EAAA,GAAA,YAAA,CAAA,CAAc,EAAA,GAAOA,iCAAP,IAAA,GAAA,EAAA,GAAqB,CAA+B,MAAlE,IAAA,GAAA,EAAA,GAAuE;AAAA,KAC/E;AAAA,IACA,GAAA,EAAK;AAAA,MACH,OAAA,EAAA,CAAS,EAAA,GAAYC,sBAAA,CAAA,wBAAA,KAAZ,IAAA,GAAA,EAAA,GAAwC,MAAA;AAAA,MACjD,KAAA,EAAA,CAAO,EAAA,GAAYA,sBAAA,CAAA,kBAAA,KAAZ,IAAA,GAAA,EAAA,GAAkC;AAAA;AAC3C,GACF;AACF;AAGO,SAAS,QAAA,CAAS,OAAA,EAAqD,MAAA,GAAsBC,uBAAA,EAAoB;AArCxH,EAAA,IAAA,EAAA;AAsCE,EAAA,MAAM,MAAM,WAAA,EAAY;AACxB,EAAA,MAAM,SAASC,8BAAA,CAAa,GAAA,EAAA,CAAK,aAAQ,OAAA,KAAR,IAAA,GAAA,EAAA,GAAmB,EAAE,CAAA;AAEtD,EAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAQ,MAAA,CAA4B,EAAA;AACjD,EAAA,OAAOC,iCAAA;AAAA,IACL,EAAE,GAAG,OAAA,EAAS,GAAA,EAAK,EAAE,GAAI,GAAA,CAAI,GAAA,EAAgB,GAAG,OAAA,CAAQ,GAAA,EAAI,EAAoC,SAAS,MAAA,EAAO;AAAA,IAChH;AAAA,GACF;AACF","file":"expo.cjs","sourcesContent":["import * as Application from \"expo-application\";\nimport * as Device from \"expo-device\";\nimport { deBug, type DebugClient } from \"./index\";\nimport { mergeContext, type ContextPatch } from \"./context\";\nimport { initReactNative, type ReactNativeInitOptions } from \"./react-native\";\n\nexport * from \"./react-native\";\n\nfunction osName(raw: string | null): string {\n const n = (raw ?? \"\").toLowerCase();\n if (n.includes(\"android\")) return \"android\";\n if (n === \"ios\" || n === \"ipados\") return \"ios\";\n return n || \"unknown\"; // web: the browser's OS, e.g. \"mac os\"\n}\n\nconst DEVICE_TYPES = { 1: \"phone\", 2: \"tablet\", 3: \"desktop\", 4: \"tv\" } as const;\n\n/** Device and app context from expo-device and expo-application. */\nexport function expoContext(): ContextPatch {\n return {\n os: Device.osVersion ? { name: osName(Device.osName), version: Device.osVersion } : undefined,\n device: {\n model: Device.modelName ?? undefined,\n manufacturer: Device.manufacturer ?? undefined,\n brand: Device.brand ?? undefined,\n isEmulator: !Device.isDevice,\n memoryMb: Device.totalMemory ? Math.round(Device.totalMemory / 1024 / 1024) : undefined,\n type: DEVICE_TYPES[(Device.deviceType ?? 0) as keyof typeof DEVICE_TYPES] ?? \"unknown\",\n },\n app: {\n version: Application.nativeApplicationVersion ?? undefined,\n build: Application.nativeBuildVersion ?? undefined,\n } as ContextPatch[\"app\"],\n };\n}\n\n/** Initialise deBug in an Expo app. Device, OS and app version are filled in automatically. */\nexport function initExpo(options: Omit<ReactNativeInitOptions, \"deviceInfo\">, client: DebugClient = deBug): DebugClient {\n const ctx = expoContext();\n const merged = mergeContext(ctx, options.context ?? {});\n // Drop undefined os so the react-native fallback is kept when expo-device has no data (e.g. web).\n if (!ctx.os) delete (merged as { os?: unknown }).os;\n return initReactNative(\n { ...options, app: { ...(ctx.app as object), ...options.app } as ReactNativeInitOptions[\"app\"], context: merged },\n client,\n );\n}\n"]}
@@ -0,0 +1,14 @@
1
+ export { deBug } from './index.cjs';
2
+ import { C as ContextPatch, D as DebugClient } from './client-ekzlpWIR.cjs';
3
+ import { ReactNativeInitOptions } from './react-native.cjs';
4
+ export { DeviceInfoModule, initReactNative, nativeContext, trackReactNavigation } from './react-native.cjs';
5
+ export { DebugErrorBoundary, DebugErrorBoundaryProps, trackTanStackRouter, useDebugNavigation } from './react.cjs';
6
+ import '@debugkit/schema/core';
7
+ import 'react';
8
+
9
+ /** Device and app context from expo-device and expo-application. */
10
+ declare function expoContext(): ContextPatch;
11
+ /** Initialise deBug in an Expo app. Device, OS and app version are filled in automatically. */
12
+ declare function initExpo(options: Omit<ReactNativeInitOptions, "deviceInfo">, client?: DebugClient): DebugClient;
13
+
14
+ export { ReactNativeInitOptions, expoContext, initExpo };
package/dist/expo.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ export { deBug } from './index.js';
2
+ import { C as ContextPatch, D as DebugClient } from './client-ekzlpWIR.js';
3
+ import { ReactNativeInitOptions } from './react-native.js';
4
+ export { DeviceInfoModule, initReactNative, nativeContext, trackReactNavigation } from './react-native.js';
5
+ export { DebugErrorBoundary, DebugErrorBoundaryProps, trackTanStackRouter, useDebugNavigation } from './react.js';
6
+ import '@debugkit/schema/core';
7
+ import 'react';
8
+
9
+ /** Device and app context from expo-device and expo-application. */
10
+ declare function expoContext(): ContextPatch;
11
+ /** Initialise deBug in an Expo app. Device, OS and app version are filled in automatically. */
12
+ declare function initExpo(options: Omit<ReactNativeInitOptions, "deviceInfo">, client?: DebugClient): DebugClient;
13
+
14
+ export { ReactNativeInitOptions, expoContext, initExpo };