crumbtrail-react-native 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/LICENSE +21 -0
- package/README.md +212 -0
- package/dist/index.cjs +799 -0
- package/dist/index.d.cts +231 -0
- package/dist/index.d.ts +231 -0
- package/dist/index.js +766 -0
- package/package.json +68 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Crumbtrail
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# crumbtrail-react-native
|
|
2
|
+
|
|
3
|
+
React Native / Expo SDK for Crumbtrail session capture. Same event pipeline as
|
|
4
|
+
the browser SDK (`crumbtrail-core`) — errors, network, console, app-state,
|
|
5
|
+
navigation, environment, and a replay-lite view-tree snapshot — wired for a
|
|
6
|
+
React Native runtime instead of the DOM.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
### Fastest path: the setup wizard
|
|
11
|
+
|
|
12
|
+
From your app's root:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npx crumbtrail
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
(Pre-npm-publish, the same wizard runs via `curl -fsSL https://app.crumbtrail.dev/install.sh | sh`,
|
|
19
|
+
which resolves to `npx --yes <cli-tarball-url>` — the identical wizard, just
|
|
20
|
+
fetched from the deploy instead of the npm registry.)
|
|
21
|
+
|
|
22
|
+
The wizard detects a React Native / Expo app by the presence of a `react-native`
|
|
23
|
+
or `expo` dependency, installs `crumbtrail-core` + `crumbtrail-react-native`
|
|
24
|
+
with your project's package manager, and prepends a
|
|
25
|
+
`createReactNativeCrumbtrail(...)` init block to the first entry file it finds,
|
|
26
|
+
in this order:
|
|
27
|
+
|
|
28
|
+
1. `app/_layout.{tsx,jsx,js}` — the Expo Router root layout
|
|
29
|
+
2. `src/app/_layout.{tsx,jsx,js}` — the same layout under a `src/` dir (where
|
|
30
|
+
`create-expo-app`'s current default template puts it)
|
|
31
|
+
3. `App.{tsx,jsx,ts,js}` — the classic Expo / bare-RN root component
|
|
32
|
+
4. `index.{js,ts}` — the bare-RN `AppRegistry` entry
|
|
33
|
+
|
|
34
|
+
If none of those exist, the wizard prints the snippet in [Setup](#setup) below
|
|
35
|
+
for you to wire in by hand instead of guessing at a file.
|
|
36
|
+
|
|
37
|
+
**Registry-install fallback.** If `<package manager> add crumbtrail-core
|
|
38
|
+
crumbtrail-react-native` fails against the npm registry (these SDK packages are
|
|
39
|
+
not guaranteed to be public yet, and a self-hosted deploy has no public
|
|
40
|
+
registry mirror at all), the wizard automatically re-installs from the deploy's
|
|
41
|
+
own packed tarballs — discovered via `GET <base>/install/manifest.json` and
|
|
42
|
+
fetched from `GET <base>/install/<package>-<version>.tgz` — with no separate
|
|
43
|
+
step required. `crumbtrail-react-native` is packed as an **optional** SDK
|
|
44
|
+
channel (alongside `crumbtrail-react` and `crumbtrail-tauri`): a broken/missing
|
|
45
|
+
pack for it only disables that fallback, it never blocks the core install.
|
|
46
|
+
|
|
47
|
+
### Manual install
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npm i crumbtrail-core crumbtrail-react-native
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
If that fails because the packages aren't on the registry yet (or you're on a
|
|
54
|
+
self-hosted deploy), install the same tarballs the wizard's fallback uses,
|
|
55
|
+
directly:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
curl -fsSL <your-deploy-base-url>/install/manifest.json # lists the current tarball filenames
|
|
59
|
+
npm i <your-deploy-base-url>/install/crumbtrail-core-<version>.tgz \
|
|
60
|
+
<your-deploy-base-url>/install/crumbtrail-react-native-<version>.tgz
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Working from a local checkout of this repo instead of a deploy, pack and
|
|
64
|
+
install from the checkout:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pnpm pack:local --out ./packed
|
|
68
|
+
npm i ./packed/crumbtrail-core-0.1.0.tgz ./packed/crumbtrail-react-native-0.1.0.tgz
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Peer dependencies
|
|
72
|
+
|
|
73
|
+
Required: `react` >=18, `react-native` >=0.72.
|
|
74
|
+
|
|
75
|
+
Optional — each is capability-detected at runtime and its collector degrades
|
|
76
|
+
cleanly (reported in the `rn.capabilities` event) rather than throwing when
|
|
77
|
+
absent:
|
|
78
|
+
|
|
79
|
+
| Package | Version | Enables |
|
|
80
|
+
| ------------------------------------------- | ------: | ----------------------------------------------- |
|
|
81
|
+
| `@react-native-async-storage/async-storage` | >=1.17 | Session persistence across app restarts |
|
|
82
|
+
| `@react-navigation/native` | >=6 | Route-change (navigation) events |
|
|
83
|
+
| `react-native-view-shot` | >=3 | Crash screenshot for replay-lite view snapshots |
|
|
84
|
+
|
|
85
|
+
## Setup
|
|
86
|
+
|
|
87
|
+
### What the wizard writes
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
import { createReactNativeCrumbtrail } from "crumbtrail-react-native";
|
|
91
|
+
|
|
92
|
+
createReactNativeCrumbtrail({
|
|
93
|
+
config: {
|
|
94
|
+
httpEndpoint: "https://app.crumbtrail.dev", // or your self-host endpoint
|
|
95
|
+
httpAuthToken: "<project api key>",
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
This is the full setup, not a subset: `createReactNativeCrumbtrail` calls
|
|
101
|
+
`Crumbtrail.init`, installs the global `ErrorUtils` crash handler, and starts
|
|
102
|
+
every capability-gated collector. It is prepended imperatively (no
|
|
103
|
+
`<Provider>` wrapper) because the wizard's injector only ever prepends a block
|
|
104
|
+
or creates a file — it cannot transform JSX.
|
|
105
|
+
|
|
106
|
+
### Manual setup (self-host)
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
import { createReactNativeCrumbtrail } from "crumbtrail-react-native";
|
|
110
|
+
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
111
|
+
|
|
112
|
+
createReactNativeCrumbtrail({
|
|
113
|
+
config: { httpEndpoint: "http://127.0.0.1:9898" }, // local crumbtrail-server
|
|
114
|
+
asyncStorage: AsyncStorage, // optional — enables session persistence
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
If you pass `asyncStorage`, prefer `createReactNativeCrumbtrailAsync` instead
|
|
119
|
+
so the session store hydrates before the logger starts:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import { createReactNativeCrumbtrailAsync } from "crumbtrail-react-native";
|
|
123
|
+
|
|
124
|
+
const { logger } = await createReactNativeCrumbtrailAsync({
|
|
125
|
+
config: { httpEndpoint: "http://127.0.0.1:9898" },
|
|
126
|
+
asyncStorage: AsyncStorage,
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### React context (optional)
|
|
131
|
+
|
|
132
|
+
To read the logger from components via a hook instead of module-level state:
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
import {
|
|
136
|
+
CrumbtrailReactNativeProvider,
|
|
137
|
+
useCrumbtrailReactNative,
|
|
138
|
+
} from "crumbtrail-react-native";
|
|
139
|
+
|
|
140
|
+
function Root() {
|
|
141
|
+
return (
|
|
142
|
+
<CrumbtrailReactNativeProvider
|
|
143
|
+
config={{ httpEndpoint: "http://127.0.0.1:9898" }}
|
|
144
|
+
asyncStorage={AsyncStorage}
|
|
145
|
+
>
|
|
146
|
+
<App />
|
|
147
|
+
</CrumbtrailReactNativeProvider>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function SomeScreen() {
|
|
152
|
+
const { logger, capabilities } = useCrumbtrailReactNative();
|
|
153
|
+
// ...
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Error boundary + component state
|
|
158
|
+
|
|
159
|
+
```tsx
|
|
160
|
+
import {
|
|
161
|
+
CrumbtrailReactNativeErrorBoundary,
|
|
162
|
+
useBugState,
|
|
163
|
+
} from "crumbtrail-react-native";
|
|
164
|
+
|
|
165
|
+
function Screen({ logger, cart }) {
|
|
166
|
+
useBugState(logger, "cart", cart); // redacted state snapshot on the next event
|
|
167
|
+
|
|
168
|
+
return (
|
|
169
|
+
<CrumbtrailReactNativeErrorBoundary logger={logger}>
|
|
170
|
+
<ScreenContent />
|
|
171
|
+
</CrumbtrailReactNativeErrorBoundary>
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
`useBugState` and the error boundary both redact sensitive-looking keys/values
|
|
177
|
+
(tokens, passwords, cookies, etc.) before the snapshot is recorded.
|
|
178
|
+
|
|
179
|
+
## What gets captured
|
|
180
|
+
|
|
181
|
+
RN-specific collectors, each capability-gated and independently toggleable via
|
|
182
|
+
`createReactNativeCrumbtrail({ collectors: { ... } })`:
|
|
183
|
+
|
|
184
|
+
- `console` — console patch
|
|
185
|
+
- `errors` — `ErrorUtils` global handler + the error boundary above
|
|
186
|
+
- `network` — `fetch` / `XMLHttpRequest` patch
|
|
187
|
+
- `appState` — foreground/background/terminate transitions
|
|
188
|
+
- `environment` — platform, dimensions, device/OS/app version
|
|
189
|
+
- `navigation` — route changes (requires `@react-navigation/native`)
|
|
190
|
+
- `replayLite` — periodic serialized view-tree snapshot + touch overlay
|
|
191
|
+
(crash screenshot requires `react-native-view-shot`)
|
|
192
|
+
|
|
193
|
+
`crumbtrail-core`'s own DOM-bound collectors (interactions, keystrokes, scroll,
|
|
194
|
+
clipboard, cookies, storage, performance, video, audio, widget) are disabled by
|
|
195
|
+
default in the React Native preset — there is no DOM to instrument.
|
|
196
|
+
|
|
197
|
+
## Verify
|
|
198
|
+
|
|
199
|
+
Point the same `crumbtrail-server doctor` used for the browser/node SDK at
|
|
200
|
+
your self-host server after reproducing an issue in the app:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
crumbtrail-server doctor --port 9898
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
On the cloud path, the wizard itself polls for the first real event after
|
|
207
|
+
setup (skip with `--skip-verify`).
|
|
208
|
+
|
|
209
|
+
## Requirements
|
|
210
|
+
|
|
211
|
+
- React Native >=0.72 (bare or Expo, managed or bare workflow)
|
|
212
|
+
- React >=18
|