@debugkit/sdk 0.1.0 → 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 +55 -3
- package/dist/{chunk-3UN5VMQU.js → chunk-3WRI3DI2.js} +5 -5
- package/dist/chunk-3WRI3DI2.js.map +1 -0
- package/dist/chunk-5C7KJJNO.js +651 -0
- package/dist/chunk-5C7KJJNO.js.map +1 -0
- package/dist/chunk-EGCXLOFH.cjs +663 -0
- package/dist/chunk-EGCXLOFH.cjs.map +1 -0
- package/dist/{chunk-BD2FNVCP.js → chunk-HO3JW55K.js} +15 -7
- package/dist/chunk-HO3JW55K.js.map +1 -0
- package/dist/{chunk-NSWUGBA2.cjs → chunk-NJ6DTUVX.cjs} +20 -12
- package/dist/chunk-NJ6DTUVX.cjs.map +1 -0
- package/dist/{chunk-KUJ4EW3D.cjs → chunk-YELZOB7J.cjs} +10 -10
- package/dist/chunk-YELZOB7J.cjs.map +1 -0
- package/dist/client-ekzlpWIR.d.cts +220 -0
- package/dist/client-ekzlpWIR.d.ts +220 -0
- package/dist/expo-router.cjs +4 -4
- package/dist/expo-router.d.cts +1 -1
- package/dist/expo-router.d.ts +1 -1
- package/dist/expo-router.js +2 -2
- package/dist/expo.cjs +13 -13
- package/dist/expo.d.cts +1 -1
- package/dist/expo.d.ts +1 -1
- package/dist/expo.js +5 -5
- package/dist/index.cjs +12 -8
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/node.cjs +69 -14
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +4 -7
- package/dist/node.d.ts +4 -7
- package/dist/node.js +55 -5
- package/dist/node.js.map +1 -1
- package/dist/react-native.cjs +10 -10
- package/dist/react-native.d.cts +1 -1
- package/dist/react-native.d.ts +1 -1
- package/dist/react-native.js +3 -3
- package/dist/react.cjs +6 -6
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +2 -2
- package/package.json +2 -2
- package/dist/chunk-3UN5VMQU.js.map +0 -1
- package/dist/chunk-BD2FNVCP.js.map +0 -1
- package/dist/chunk-KUJ4EW3D.cjs.map +0 -1
- package/dist/chunk-NSWUGBA2.cjs.map +0 -1
- package/dist/chunk-VIJ5USKQ.js +0 -300
- package/dist/chunk-VIJ5USKQ.js.map +0 -1
- package/dist/chunk-XEFWRCN4.cjs +0 -311
- package/dist/chunk-XEFWRCN4.cjs.map +0 -1
- package/dist/client-drmb0n15.d.cts +0 -103
- package/dist/client-drmb0n15.d.ts +0 -103
package/README.md
CHANGED
|
@@ -4,11 +4,13 @@ Log errors and events from your app into **your own** cloud. This is the client
|
|
|
4
4
|
[deBug](https://github.com/Abantu-Digital/deBug): events go to an ingest function you deploy
|
|
5
5
|
in Firebase or AWS, and a dashboard you run yourself tells you what is failing and why.
|
|
6
6
|
|
|
7
|
-
- About
|
|
7
|
+
- About 6 KB gzipped, with no runtime dependencies in your bundle.
|
|
8
8
|
- Works with React, React Native (bare and Expo), Expo Router, TanStack Start/Router, Next.js
|
|
9
9
|
and plain Node.
|
|
10
|
-
-
|
|
11
|
-
|
|
10
|
+
- **Works on its own once initialised:** crashes, failed requests, sessions and the steps
|
|
11
|
+
leading up to each error are recorded without any extra code. See
|
|
12
|
+
[What it records by itself](#what-it-records-by-itself).
|
|
13
|
+
- Batches, retries, rate-limits, and queues events while offline.
|
|
12
14
|
|
|
13
15
|
## Install
|
|
14
16
|
|
|
@@ -32,6 +34,56 @@ hooks, and they all share the same `deBug` client.
|
|
|
32
34
|
Your ingest endpoint and key come from your deBug deployment. During development, point at a
|
|
33
35
|
dashboard running in demo mode: `http://localhost:4400/api/ingest` with key `pk_local`.
|
|
34
36
|
|
|
37
|
+
## What it records by itself
|
|
38
|
+
|
|
39
|
+
Calling `init()` (or `initExpo`, `initReactNative`, `initNode`) turns on everything in this
|
|
40
|
+
table. The manual API below is for what only you know: which part of the app a step belongs to,
|
|
41
|
+
and whether it succeeded.
|
|
42
|
+
|
|
43
|
+
| | Browser | React Native / Expo | Node |
|
|
44
|
+
|---|---|---|---|
|
|
45
|
+
| Uncaught errors and unhandled rejections | ✓ | ✓ (fatal crashes marked critical) | ✓ (flushes, then exits like Node) |
|
|
46
|
+
| Render errors | with `DebugErrorBoundary` | with `DebugErrorBoundary` | |
|
|
47
|
+
| **Failed requests** (5xx, timeouts, network failures) as errors, every request as a breadcrumb | fetch, XHR | fetch, XHR (axios too) | fetch, `node:http` (axios, SDKs), plus 5xx your server sends |
|
|
48
|
+
| **Sessions**: crash-free and error-free rates per release | one per page load | new session after 30 min in the background | one per process |
|
|
49
|
+
| Navigation breadcrumbs | any router (History API) | add `useDebugExpoRouter` or `trackReactNavigation` | |
|
|
50
|
+
| Clicks on buttons and links, by their label | ✓ | | |
|
|
51
|
+
| `console.warn` / `console.error` as breadcrumbs | ✓ | ✓ | off by default |
|
|
52
|
+
| Foreground/background, online/offline | ✓ | foreground/background | |
|
|
53
|
+
| Device, OS, app version, network type on every event | ✓ | ✓ | ✓ |
|
|
54
|
+
|
|
55
|
+
Every error carries the last 30 breadcrumbs, so the dashboard shows what happened just
|
|
56
|
+
before it: the screen, the click, the request that failed.
|
|
57
|
+
|
|
58
|
+
**Privacy.** Query strings and fragments are dropped from every URL before anything is
|
|
59
|
+
recorded, and ids in paths become `:id` (`/v1/orders/8812?token=…` becomes `/v1/orders/:id`).
|
|
60
|
+
Request and response bodies, headers and what users type are never read. Use `beforeSend` to
|
|
61
|
+
scrub anything else.
|
|
62
|
+
|
|
63
|
+
**Noise control.** At most 60 errors a minute are sent (`maxErrorsPerMinute`), and one repeating
|
|
64
|
+
error gets at most a sixth of that. Breadcrumbs that repeat are collapsed into one. `sampleRate`
|
|
65
|
+
keeps a fraction of errors and events. Sessions and fatal crashes are never sampled out, so
|
|
66
|
+
crash-free rates stay accurate.
|
|
67
|
+
|
|
68
|
+
### Tuning it
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
deBug.init({
|
|
72
|
+
endpoint, ingestKey, app: { id: "your-app", version: "2.4.0" },
|
|
73
|
+
autoCapture: { console: false, clicks: false }, // or `false` to turn everything off
|
|
74
|
+
network: {
|
|
75
|
+
flows: [["/v2/auth/", "auth.login"], [/\/payments\//, "checkout.payment"]], // tag requests by URL
|
|
76
|
+
ignoreUrls: ["analytics.example.com"],
|
|
77
|
+
isFailure: (status) => status >= 500 || status === 429, // default: 500 and above
|
|
78
|
+
slowMs: 3000, // slower requests get a warning breadcrumb
|
|
79
|
+
},
|
|
80
|
+
sampleRate: 1,
|
|
81
|
+
maxErrorsPerMinute: 60,
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Requests to your ingest endpoint and to the Metro and Expo dev servers are never recorded.
|
|
86
|
+
|
|
35
87
|
## Expo
|
|
36
88
|
|
|
37
89
|
```tsx
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { deBug, __publicField } from './chunk-
|
|
1
|
+
import { deBug, __publicField } from './chunk-5C7KJJNO.js';
|
|
2
2
|
import { Component, useEffect } from 'react';
|
|
3
3
|
|
|
4
4
|
var DebugErrorBoundary = class extends Component {
|
|
@@ -29,13 +29,13 @@ var DebugErrorBoundary = class extends Component {
|
|
|
29
29
|
};
|
|
30
30
|
function useDebugNavigation(path, client = deBug) {
|
|
31
31
|
useEffect(() => {
|
|
32
|
-
if (path) client.
|
|
32
|
+
if (path) client.navigated(path);
|
|
33
33
|
}, [path, client]);
|
|
34
34
|
}
|
|
35
35
|
function trackTanStackRouter(router, client = deBug) {
|
|
36
|
-
return router.subscribe("onResolved", ({ toLocation }) => client.
|
|
36
|
+
return router.subscribe("onResolved", ({ toLocation }) => client.navigated(toLocation.pathname));
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export { DebugErrorBoundary, trackTanStackRouter, useDebugNavigation };
|
|
40
|
-
//# sourceMappingURL=chunk-
|
|
41
|
-
//# sourceMappingURL=chunk-
|
|
40
|
+
//# sourceMappingURL=chunk-3WRI3DI2.js.map
|
|
41
|
+
//# sourceMappingURL=chunk-3WRI3DI2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react.tsx"],"names":[],"mappings":";;;AAqBO,IAAM,kBAAA,GAAN,cAAiC,SAAA,CAA0C;AAAA,EAA3E,WAAA,GAAA;AAAA,IAAA,KAAA,CAAA,GAAA,SAAA,CAAA;AACL,IAAA,aAAA,CAAA,IAAA,EAAA,OAAA,EAAe,EAAE,OAAO,IAAA,EAAK,CAAA;AAgB7B,IAAA,aAAA,CAAA,IAAA,EAAA,OAAA,EAAQ,MAAM,IAAA,CAAK,QAAA,CAAS,EAAE,KAAA,EAAO,MAAM,CAAA,CAAA;AAAA,EAAA;AAAA,EAd3C,OAAO,yBAAyB,KAAA,EAAqB;AACnD,IAAA,OAAO,EAAE,KAAA,EAAM;AAAA,EACjB;AAAA,EAEA,iBAAA,CAAkB,OAAc,IAAA,EAAiB;AA5BnD,IAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA6BI,IAAA,MAAM,MAAA,GAAA,CAAS,EAAA,GAAA,IAAA,CAAK,KAAA,CAAM,MAAA,KAAX,IAAA,GAAA,EAAA,GAAqB,KAAA;AACpC,IAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,MAAA,MAAA,CAAO,UAAA,CAAW,IAAA,EAAM,oBAAA,EAAsB,EAAE,gBAAgB,IAAA,CAAK,cAAA,CAAe,IAAA,EAAK,CAAE,KAAA,CAAM,CAAA,EAAG,IAAI,CAAA,IAAK,OAAO,CAAA;AAAA,IACtH;AACA,IAAA,MAAA,CAAO,KAAA,CAAM,KAAA,EAAO,EAAE,IAAA,EAAM,KAAK,KAAA,CAAM,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,IAAA,EAAM,EAAE,MAAA,EAAQ,gBAAA,IAAoB,CAAA;AACjG,IAAA,KAAK,OAAO,KAAA,EAAM;AAClB,IAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,IAAA,CAAK,KAAA,EAAM,OAAA,KAAX,IAAA,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,CAAA,EAAA,EAAqB,KAAA,EAAO,IAAA,CAAA;AAAA,EAC9B;AAAA,EAIA,MAAA,GAAS;AACP,IAAA,MAAM,EAAE,KAAA,EAAM,GAAI,IAAA,CAAK,KAAA;AACvB,IAAA,IAAI,CAAC,KAAA,EAAO,OAAO,IAAA,CAAK,KAAA,CAAM,QAAA;AAC9B,IAAA,MAAM,EAAE,QAAA,EAAS,GAAI,IAAA,CAAK,KAAA;AAC1B,IAAA,OAAO,OAAO,QAAA,KAAa,UAAA,GAAa,QAAA,CAAS,EAAE,KAAA,EAAO,KAAA,EAAO,IAAA,CAAK,KAAA,EAAO,CAAA,GAAK,QAAA,IAAA,IAAA,GAAA,QAAA,GAAY,IAAA;AAAA,EAChG;AACF;AAGO,SAAS,kBAAA,CAAmB,IAAA,EAA0B,MAAA,GAAsB,KAAA,EAAO;AACxF,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,IAAA,EAAM,MAAA,CAAO,SAAA,CAAU,IAAI,CAAA;AAAA,EACjC,CAAA,EAAG,CAAC,IAAA,EAAM,MAAM,CAAC,CAAA;AACnB;AAYO,SAAS,mBAAA,CAAoB,MAAA,EAAoB,MAAA,GAAsB,KAAA,EAAO;AACnF,EAAA,OAAO,MAAA,CAAO,SAAA,CAAU,YAAA,EAAc,CAAC,EAAE,UAAA,EAAW,KAAM,MAAA,CAAO,SAAA,CAAU,UAAA,CAAW,QAAQ,CAAC,CAAA;AACjG","file":"chunk-3WRI3DI2.js","sourcesContent":["import { Component, useEffect, type ErrorInfo, type ReactNode } from \"react\";\nimport { deBug, type DebugClient } from \"./index\";\n\nexport interface DebugErrorBoundaryProps {\n children?: ReactNode;\n /** What to render after a crash. A function gets the error and a reset callback. */\n fallback?: ReactNode | ((props: { error: Error; reset: () => void }) => ReactNode);\n /** Part of the app this boundary protects, e.g. \"checkout\". */\n flow?: string;\n client?: DebugClient;\n onError?: (error: Error, info: ErrorInfo) => void;\n}\n\ninterface State {\n error: Error | null;\n}\n\n/**\n * Catches render errors that React would otherwise swallow (or turn into a white/red screen)\n * and reports them. Works in React DOM and React Native.\n */\nexport class DebugErrorBoundary extends Component<DebugErrorBoundaryProps, State> {\n state: State = { error: null };\n\n static getDerivedStateFromError(error: Error): State {\n return { error };\n }\n\n componentDidCatch(error: Error, info: ErrorInfo) {\n const client = this.props.client ?? deBug;\n if (info.componentStack) {\n client.breadcrumb(\"ui\", \"React render error\", { componentStack: info.componentStack.trim().slice(0, 1500) }, \"error\");\n }\n client.error(error, { flow: this.props.flow, handled: false, tags: { source: \"error-boundary\" } });\n void client.flush();\n this.props.onError?.(error, info);\n }\n\n reset = () => this.setState({ error: null });\n\n render() {\n const { error } = this.state;\n if (!error) return this.props.children;\n const { fallback } = this.props;\n return typeof fallback === \"function\" ? fallback({ error, reset: this.reset }) : (fallback ?? null);\n }\n}\n\n/** Adds a navigation breadcrumb whenever `path` changes. Works with any router. */\nexport function useDebugNavigation(path: string | undefined, client: DebugClient = deBug) {\n useEffect(() => {\n if (path) client.navigated(path);\n }, [path, client]);\n}\n\n/** Minimal shape of a TanStack Router instance (avoids a hard dependency). */\ninterface RouterLike {\n subscribe(event: \"onResolved\", fn: (e: { toLocation: { pathname: string; href?: string } }) => void): () => void;\n}\n\n/**\n * Records a breadcrumb for every navigation in a TanStack Router app:\n * const router = createRouter({ routeTree }); trackTanStackRouter(router);\n * Returns an unsubscribe function.\n */\nexport function trackTanStackRouter(router: RouterLike, client: DebugClient = deBug) {\n return router.subscribe(\"onResolved\", ({ toLocation }) => client.navigated(toLocation.pathname));\n}\n\nexport { deBug } from \"./index\";\n"]}
|