@allstak/react 0.3.2 → 0.3.4
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 +97 -324
- package/dist/build/{chunk-ZY4H5AN4.mjs → chunk-3JRNQSVX.mjs} +2 -2
- package/dist/build/{chunk-G6VPGDP6.mjs → chunk-DURAJQ3M.mjs} +28 -4
- package/dist/build/{chunk-G6VPGDP6.mjs.map → chunk-DURAJQ3M.mjs.map} +1 -1
- package/dist/build/next.js +27 -3
- package/dist/build/next.js.map +1 -1
- package/dist/build/next.mjs +2 -2
- package/dist/build/sourcemaps.js +27 -3
- package/dist/build/sourcemaps.js.map +1 -1
- package/dist/build/sourcemaps.mjs +1 -1
- package/dist/build/vite.js +27 -3
- package/dist/build/vite.js.map +1 -1
- package/dist/build/vite.mjs +1 -1
- package/dist/build/webpack.js +27 -3
- package/dist/build/webpack.js.map +1 -1
- package/dist/build/webpack.mjs +2 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- /package/dist/build/{chunk-ZY4H5AN4.mjs.map → chunk-3JRNQSVX.mjs.map} +0 -0
package/README.md
CHANGED
|
@@ -1,392 +1,165 @@
|
|
|
1
1
|
# @allstak/react
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
AllStak React SDK for browser error capture, component error boundaries, breadcrumbs, user context, HTTP metadata, traces, Web Vitals, and source-map release support.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
[](https://github.com/AllStak/allstak-react/actions)
|
|
7
|
-
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
Stability: stable SDK runtime, beta live certification. Live dashboard proof is not claimed until you run a project with real AllStak credentials.
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
## 1. Automatic Setup With Wizard
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
Recommended flow:
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
## Features
|
|
18
|
-
|
|
19
|
-
- **One-wrapper setup** — `<AllStakProvider>` initializes everything
|
|
20
|
-
- React error boundary with custom fallback UI + `resetError`
|
|
21
|
-
- `window.onerror` + `unhandledrejection` capture
|
|
22
|
-
- `console.warn` + `console.error` capture by default; `log`/`info` opt-in
|
|
23
|
-
- `fetch` and `XMLHttpRequest` breadcrumbs (200 / 4xx / 5xx / network failure)
|
|
24
|
-
- Full HTTP request events with `enableHttpTracking: true` + privacy-first redaction
|
|
25
|
-
- Auto navigation breadcrumbs (history.pushState patch + popstate)
|
|
26
|
-
- Web Vitals via PerformanceObserver (CLS / LCP / INP / FCP / TTFB)
|
|
27
|
-
- React Router + Next.js helpers
|
|
28
|
-
- `useAllStak()` hook with stable identity
|
|
29
|
-
- Full TypeScript types
|
|
30
|
-
|
|
31
|
-
## Quick Start
|
|
32
|
-
|
|
33
|
-
> **Time to first event: under 2 minutes.**
|
|
34
|
-
> Create a project at [app.allstak.sa](https://app.allstak.sa) to get your API key.
|
|
11
|
+
```bash
|
|
12
|
+
npx @allstak/wizard setup --integration react
|
|
13
|
+
```
|
|
35
14
|
|
|
36
|
-
|
|
15
|
+
The only value you may need to enter is the AllStak ingest API key. The wizard detects Vite React, CRA-style React, React Router, JavaScript, and TypeScript entry files. If the project is Next.js, use `@allstak/next` instead:
|
|
37
16
|
|
|
38
17
|
```bash
|
|
39
|
-
|
|
18
|
+
npx @allstak/wizard setup --integration next
|
|
40
19
|
```
|
|
41
20
|
|
|
42
|
-
|
|
21
|
+
## 2. What The Wizard Changes
|
|
43
22
|
|
|
44
|
-
|
|
45
|
-
import { AllStakProvider } from '@allstak/react';
|
|
23
|
+
The wizard:
|
|
46
24
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
</AllStakProvider>
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
```
|
|
25
|
+
- Installs `@allstak/react`.
|
|
26
|
+
- Writes managed env vars to `.env.local` for Vite or `.env` for non-Vite React.
|
|
27
|
+
- Detects `src/main.tsx`, `src/main.jsx`, `src/index.tsx`, or `src/index.jsx`.
|
|
28
|
+
- Wraps the existing render tree with `AllStakProvider`.
|
|
29
|
+
- Preserves `React.StrictMode`, React Router, and existing providers.
|
|
30
|
+
- Enables provider-managed component error boundary capture.
|
|
31
|
+
- Wires Vite source-map upload hooks when a Vite config is present.
|
|
32
|
+
- Prints the changed files.
|
|
33
|
+
- Supports dry-run, repair, idempotent re-runs, and uninstall.
|
|
60
34
|
|
|
61
|
-
|
|
35
|
+
## 3. Verification
|
|
62
36
|
|
|
63
|
-
|
|
64
|
-
import { AllStak } from '@allstak/react';
|
|
37
|
+
After setup:
|
|
65
38
|
|
|
66
|
-
|
|
67
|
-
|
|
39
|
+
```bash
|
|
40
|
+
npm run build
|
|
41
|
+
npx @allstak/wizard doctor --integration react
|
|
68
42
|
```
|
|
69
43
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
Open [app.allstak.sa](https://app.allstak.sa) — the error appears within seconds.
|
|
73
|
-
|
|
74
|
-
When `debug` is enabled you'll see `[AllStak] Initialized — session <id>` and `[AllStak] Navigation auto-instrumentation enabled` in your browser console.
|
|
75
|
-
|
|
76
|
-
`AllStakProvider` handles everything:
|
|
77
|
-
- Initializes the SDK
|
|
78
|
-
- Wraps your app in an `AllStakErrorBoundary`
|
|
79
|
-
- Hooks `window.onerror`, `unhandledrejection`, `console.*`, `fetch`, `history.*`
|
|
80
|
-
- Starts Web Vitals collection
|
|
81
|
-
- Tags every event with `platform: 'browser'`, sdk name + version
|
|
82
|
-
|
|
83
|
-
## Automatic Capture Matrix
|
|
84
|
-
|
|
85
|
-
Status legend:
|
|
86
|
-
- ✅ **Auto by default** — works the moment the provider mounts
|
|
87
|
-
- ⚙️ **Auto when enabled by config** — set the listed prop
|
|
88
|
-
- 🛠 **Manual only** — call the listed function yourself
|
|
89
|
-
- 🟡 **Implemented but not browser-verified end-to-end yet**
|
|
90
|
-
- ❌ **Not supported yet** (roadmap)
|
|
91
|
-
|
|
92
|
-
| Capability | Status | Config / API | Wire form |
|
|
93
|
-
|---|---|---|---|
|
|
94
|
-
| Render errors via `<AllStakProvider>` boundary | ✅ | always-on inside the provider | `POST /ingest/v1/errors` with `metadata.source = 'AllStakProvider.ErrorBoundary'` + `componentStack` |
|
|
95
|
-
| `window.onerror` global handler | ✅ | `autoCaptureBrowserErrors` (default `true`) | `POST /ingest/v1/errors` with `metadata.source = 'window.onerror'` |
|
|
96
|
-
| `window.unhandledrejection` | ✅ | `autoCaptureBrowserErrors` | `POST /ingest/v1/errors` with `metadata.source = 'window.unhandledrejection'` |
|
|
97
|
-
| Manual `AllStak.captureException` | 🛠 | `AllStak.captureException(err, ctx?)` | `POST /ingest/v1/errors` |
|
|
98
|
-
| Manual `AllStak.captureMessage` | 🛠 | `AllStak.captureMessage(msg, level)` | `/ingest/v1/logs` (`info`/`warn`); both `errors` + `logs` for `error`/`fatal` |
|
|
99
|
-
| `console.warn` / `console.error` | ✅ | `autoBreadcrumbsConsole` (default `true`); per-method via `captureConsole={ warn: true, error: true }` | `breadcrumb` of `type: 'log'`, `level: 'warn'` / `'error'`, `data.category: 'console'` |
|
|
100
|
-
| `console.log` / `console.info` | ⚙️ | `captureConsole={{ log: true, info: true }}` (default `false` to avoid spam) | `breadcrumb` of `type: 'log'`, `level: 'info'`, `data.method: 'log'` / `'info'` |
|
|
101
|
-
| HTTP `fetch` breadcrumbs (success) | ✅ | `autoBreadcrumbsFetch` (default `true`) | `breadcrumb` of `type: 'http'`, `level: 'info'` |
|
|
102
|
-
| HTTP `fetch` 4xx / 5xx breadcrumbs | ✅ | `autoBreadcrumbsFetch` | `breadcrumb` of `type: 'http'`, `level: 'error'` when status ≥ 400 |
|
|
103
|
-
| HTTP `fetch` network failure | ✅ | `autoBreadcrumbsFetch` | `breadcrumb` with `data.error`; original error rethrown |
|
|
104
|
-
| HTTP `XMLHttpRequest` breadcrumbs | ✅ | `enableHttpTracking` (also covers fetch full events) | breadcrumb same shape |
|
|
105
|
-
| Full HTTP request events (method / URL / headers / body) | ⚙️ | `enableHttpTracking: true` (default `false`); `httpTracking: { ... }` for redaction control | `POST /ingest/v1/http-requests` |
|
|
106
|
-
| Recent failed HTTP attached to next exception | ⚙️ | `enableHttpTracking: true` | `metadata['http.recentFailed']` (last 5 failed requests) |
|
|
107
|
-
| Auto navigation breadcrumbs (pushState / popstate) | ✅ | `autoBreadcrumbsNavigation` (default `true`) | `breadcrumb` of `type: 'navigation'`, `data.from`/`data.to` |
|
|
108
|
-
| React Router integration | 🛠 | `instrumentReactRouter(useLocation())` in a `useEffect` | same shape |
|
|
109
|
-
| Next.js Pages Router | 🛠 | `instrumentNextRouter(url)` from `Router.events.on('routeChangeComplete')` | same shape |
|
|
110
|
-
| **Web Vitals (CLS / LCP / INP / FCP / TTFB)** | ✅ | `autoWebVitals` (default `true`) | `POST /ingest/v1/logs` with `metadata.category = 'web-vital'`, `metadata.name`, `metadata.value` |
|
|
111
|
-
| User context | 🛠 | `AllStak.setUser({ id, email })` | `payload.user` |
|
|
112
|
-
| Custom tags / extras / contexts | 🛠 | `AllStak.setTag` / `setExtra` / `setContext` | `payload.metadata.<key>` |
|
|
113
|
-
| `release`, `environment`, `dist` | 🛠 via init | `<AllStakProvider release="web@1.0.0">` etc. | top-level fields on every payload |
|
|
114
|
-
| Source maps | 🛠 build-time | `@allstak/js/sourcemaps` plugin (Vite / Webpack / Next) | injected `debugId` per chunk |
|
|
115
|
-
| Session replay (DOM-mutation) | ⚙️ | `replay={ sampleRate: 0.1, maskAllInputs: true }` (default OFF) | `POST /ingest/v1/replay` |
|
|
116
|
-
| Offline event queue (in-memory only — see roadmap) | ✅ | n/a; configured via transport (max 100 in-RAM, drops oldest) | retried on next successful send; lost on page navigation |
|
|
117
|
-
|
|
118
|
-
### Roadmap
|
|
119
|
-
|
|
120
|
-
- Persistent offline queue (currently RAM-only; lost on page navigation)
|
|
121
|
-
- React Query / SWR breadcrumbs
|
|
122
|
-
- Vue / Svelte / Solid sister packages
|
|
123
|
-
|
|
124
|
-
## Verification status
|
|
125
|
-
|
|
126
|
-
The capabilities marked ✅ in the matrix above were verified live in
|
|
127
|
-
Chrome against the SDK's own wire format (see
|
|
128
|
-
[docs/reports/react-sdk-production-readiness.md](docs/reports/react-sdk-production-readiness.md)
|
|
129
|
-
for command-by-command details). 156 error events, 84 logs (including
|
|
130
|
-
5 web vitals), 9 full HTTP events, and a working render-error → fallback
|
|
131
|
-
→ resetError → recovery cycle were all observed end-to-end.
|
|
132
|
-
|
|
133
|
-
The live-backend round-trip is documented in the report. The wire format
|
|
134
|
-
is identical to `@allstak/react-native`, which was fully round-trip
|
|
135
|
-
verified against the same backend in
|
|
136
|
-
`../../allstak-react-native/docs/reports/react-native-backend-ingestion-verification.md`.
|
|
137
|
-
|
|
138
|
-
## Manual setup (advanced)
|
|
139
|
-
|
|
140
|
-
If you need full control over initialization order, you can skip
|
|
141
|
-
`AllStakProvider` and set up manually:
|
|
44
|
+
With live credentials, send a test event from your app:
|
|
142
45
|
|
|
143
46
|
```ts
|
|
144
|
-
import { AllStak
|
|
47
|
+
import { AllStak } from '@allstak/react';
|
|
145
48
|
|
|
146
|
-
AllStak.
|
|
147
|
-
|
|
148
|
-
environment: 'production',
|
|
49
|
+
AllStak.captureMessage('AllStak React setup verification', {
|
|
50
|
+
source: 'manual-verification',
|
|
149
51
|
});
|
|
150
|
-
|
|
151
|
-
AllStak.captureException(new Error('test'));
|
|
152
|
-
|
|
153
|
-
export function App() {
|
|
154
|
-
return (
|
|
155
|
-
<AllStakErrorBoundary fallback={<p>Something went wrong.</p>}>
|
|
156
|
-
<Routes />
|
|
157
|
-
</AllStakErrorBoundary>
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
52
|
```
|
|
161
53
|
|
|
162
|
-
|
|
54
|
+
Dashboard appearance is not guaranteed by local tests. Confirm the event in AllStak before claiming live certification.
|
|
163
55
|
|
|
164
|
-
|
|
165
|
-
2. Create a project
|
|
166
|
-
3. Copy your API key from **Project Settings → API Keys**
|
|
167
|
-
4. Export it as `ALLSTAK_API_KEY` or pass it to `AllStak.init(...)`
|
|
56
|
+
## 4. Rollback / Uninstall
|
|
168
57
|
|
|
169
|
-
|
|
58
|
+
```bash
|
|
59
|
+
npx @allstak/wizard uninstall --integration react
|
|
60
|
+
```
|
|
170
61
|
|
|
171
|
-
|
|
172
|
-
|---|---|---|---|---|
|
|
173
|
-
| `apiKey` | `string` | yes | — | Project API key (`ask_live_…`) |
|
|
174
|
-
| `environment` | `string` | no | — | Deployment env |
|
|
175
|
-
| `release` | `string` | no | — | Version or git SHA |
|
|
176
|
-
| `host` | `string` | no | `https://api.allstak.sa` | Ingest host override |
|
|
177
|
-
| `user` | `{ id?, email? }` | no | — | Default user context |
|
|
178
|
-
| `tags` | `Record<string,string>` | no | — | Default tags |
|
|
62
|
+
Uninstall removes wizard-managed env blocks, source-map config, imports, and provider wrappers. User-owned code outside wizard markers is preserved.
|
|
179
63
|
|
|
180
|
-
##
|
|
64
|
+
## 5. Manual Setup Fallback
|
|
181
65
|
|
|
182
|
-
|
|
66
|
+
Use manual setup only when the wizard cannot safely patch a custom entry file:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm install @allstak/react
|
|
70
|
+
```
|
|
183
71
|
|
|
184
72
|
```tsx
|
|
185
|
-
import {
|
|
73
|
+
import { AllStakProvider } from '@allstak/react';
|
|
186
74
|
|
|
187
|
-
function
|
|
188
|
-
const allstak = useAllStak();
|
|
75
|
+
export function Root({ children }: { children: React.ReactNode }) {
|
|
189
76
|
return (
|
|
190
|
-
<
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
77
|
+
<AllStakProvider
|
|
78
|
+
apiKey={import.meta.env.VITE_ALLSTAK_API_KEY}
|
|
79
|
+
host={import.meta.env.VITE_ALLSTAK_HOST}
|
|
80
|
+
environment={import.meta.env.VITE_ALLSTAK_ENVIRONMENT ?? 'production'}
|
|
81
|
+
release={import.meta.env.VITE_ALLSTAK_RELEASE}
|
|
82
|
+
enableHttpTracking
|
|
83
|
+
>
|
|
84
|
+
{children}
|
|
85
|
+
</AllStakProvider>
|
|
194
86
|
);
|
|
195
87
|
}
|
|
196
88
|
```
|
|
197
89
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
```tsx
|
|
201
|
-
import { withAllStakProfiler } from '@allstak/react';
|
|
202
|
-
export default withAllStakProfiler(Dashboard, 'Dashboard');
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
Set user context on login:
|
|
206
|
-
|
|
207
|
-
```tsx
|
|
208
|
-
import { AllStak } from '@allstak/react';
|
|
209
|
-
AllStak.setUser({ id: user.id, email: user.email });
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
## HTTP tracking
|
|
213
|
-
|
|
214
|
-
Setting `enableHttpTracking: true` (off by default) auto-wraps `fetch`,
|
|
215
|
-
`XMLHttpRequest`, and `axios` (when installed) so every outbound HTTP
|
|
216
|
-
call is recorded as an `http_request` event.
|
|
217
|
-
|
|
218
|
-
**Privacy defaults are aggressive:**
|
|
219
|
-
|
|
220
|
-
- request/response bodies are **not** captured
|
|
221
|
-
- headers are **not** captured
|
|
222
|
-
- `Authorization`, `Cookie`, `Set-Cookie`, `X-API-Key`, `X-Auth-Token`,
|
|
223
|
-
`Proxy-Authorization` are **always** redacted
|
|
224
|
-
- query params named `token`, `password`, `api_key`, `apikey`,
|
|
225
|
-
`authorization`, `auth`, `secret`, `access_token`, `refresh_token`,
|
|
226
|
-
`session`, `sessionid`, `jwt` are **always** redacted in the URL
|
|
227
|
-
|
|
228
|
-
To enable richer capture (only on routes you control):
|
|
90
|
+
For manual capture:
|
|
229
91
|
|
|
230
92
|
```ts
|
|
231
|
-
AllStak
|
|
232
|
-
apiKey: '...',
|
|
233
|
-
enableHttpTracking: true,
|
|
234
|
-
httpTracking: {
|
|
235
|
-
captureRequestBody: true,
|
|
236
|
-
captureResponseBody: true,
|
|
237
|
-
captureHeaders: true, // auth headers still hard-redacted
|
|
238
|
-
redactHeaders: ['x-tenant'],
|
|
239
|
-
redactQueryParams: ['custom_id'],
|
|
240
|
-
ignoredUrls: [/health/i, '/metrics'],
|
|
241
|
-
allowedUrls: [],
|
|
242
|
-
maxBodyBytes: 4096,
|
|
243
|
-
},
|
|
244
|
-
});
|
|
93
|
+
import { AllStak } from '@allstak/react';
|
|
245
94
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
95
|
+
AllStak.captureException(new Error('checkout failed'));
|
|
96
|
+
AllStak.captureMessage('user opened checkout');
|
|
97
|
+
AllStak.setUser({ id: 'user_123' });
|
|
98
|
+
AllStak.addBreadcrumb({ type: 'navigation', message: 'Checkout' });
|
|
249
99
|
```
|
|
250
100
|
|
|
251
|
-
|
|
252
|
-
HTTP requests (last 10) are automatically attached to the error
|
|
253
|
-
metadata under `http.recentFailed` for easy triage.
|
|
101
|
+
## 6. Configuration
|
|
254
102
|
|
|
255
|
-
|
|
103
|
+
Provider props include:
|
|
256
104
|
|
|
257
|
-
|
|
105
|
+
| Option | Default | Notes |
|
|
106
|
+
| --- | --- | --- |
|
|
107
|
+
| `apiKey` | required | Public browser ingest key. |
|
|
108
|
+
| `host` | `https://api.allstak.sa` | Override for self-hosted ingest. |
|
|
109
|
+
| `environment` | `production` | Release environment tag. |
|
|
110
|
+
| `release` | unset | Use app version or commit SHA. |
|
|
111
|
+
| `debug` | `false` | Enables SDK diagnostic logs. |
|
|
112
|
+
| `enableHttpTracking` | `false` | Captures HTTP metadata with redaction. |
|
|
113
|
+
| `autoCaptureBrowserErrors` | `true` | Captures `window.onerror` and `unhandledrejection`. |
|
|
114
|
+
| `autoBreadcrumbsFetch` | `true` | Adds fetch/XHR breadcrumbs. |
|
|
115
|
+
| `autoBreadcrumbsConsole` | `true` | Captures `warn`/`error`; `log`/`info` stay off by default. |
|
|
116
|
+
| `beforeSend` | unset | Last-chance event scrub/drop hook. |
|
|
258
117
|
|
|
259
|
-
|
|
260
|
-
AllStak.init({ apiKey: '...', host: 'https://allstak.mycorp.com' });
|
|
261
|
-
```
|
|
118
|
+
## 7. Privacy / PII / Redaction
|
|
262
119
|
|
|
263
|
-
|
|
120
|
+
Privacy defaults are conservative:
|
|
264
121
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
122
|
+
- Authorization, cookie, API key, token, and secret headers are always redacted.
|
|
123
|
+
- Sensitive query parameters are redacted.
|
|
124
|
+
- Request/response bodies are disabled unless explicitly enabled.
|
|
125
|
+
- Console `log` and `info` breadcrumbs are off by default.
|
|
126
|
+
- Use `beforeSend` for app-specific PII removal.
|
|
270
127
|
|
|
271
|
-
|
|
272
|
-
token is present) upload the matching `.map` to the AllStak ingest. The
|
|
273
|
-
runtime resolver in `@allstak/react` reads `globalThis._allstakDebugIds`
|
|
274
|
-
at capture time and attaches the right debug-id to each frame, so the
|
|
275
|
-
symbolicator picks the correct map even after long-tail caching of
|
|
276
|
-
bundles.
|
|
128
|
+
Do not send passwords, payment data, national IDs, raw tokens, or raw request/response bodies unless you have verified redaction in your app.
|
|
277
129
|
|
|
278
|
-
|
|
130
|
+
## 8. Source Maps / Releases
|
|
131
|
+
|
|
132
|
+
For Vite, the wizard wires the AllStak source-map plugin automatically when possible. Manual fallback:
|
|
279
133
|
|
|
280
134
|
```ts
|
|
281
|
-
// vite.config.ts
|
|
282
135
|
import { defineConfig } from 'vite';
|
|
283
136
|
import react from '@vitejs/plugin-react';
|
|
284
137
|
import { allstakSourcemaps } from '@allstak/react/vite';
|
|
285
138
|
|
|
286
139
|
export default defineConfig({
|
|
287
|
-
build: { sourcemap: true },
|
|
288
140
|
plugins: [
|
|
289
141
|
react(),
|
|
290
142
|
allstakSourcemaps({
|
|
291
|
-
release: process.env.
|
|
292
|
-
token: process.env.
|
|
293
|
-
dist: 'web',
|
|
294
|
-
}),
|
|
295
|
-
],
|
|
296
|
-
});
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
### Webpack
|
|
300
|
-
|
|
301
|
-
```js
|
|
302
|
-
// webpack.config.js
|
|
303
|
-
const { AllStakWebpackPlugin } = require('@allstak/react/webpack');
|
|
304
|
-
|
|
305
|
-
module.exports = {
|
|
306
|
-
devtool: 'source-map',
|
|
307
|
-
plugins: [
|
|
308
|
-
new AllStakWebpackPlugin({
|
|
309
|
-
release: process.env.ALLSTAK_RELEASE,
|
|
310
|
-
token: process.env.ALLSTAK_UPLOAD_TOKEN,
|
|
311
|
-
dist: 'web',
|
|
143
|
+
release: process.env.VITE_ALLSTAK_RELEASE,
|
|
144
|
+
token: process.env.ALLSTAK_SOURCEMAP_TOKEN,
|
|
312
145
|
}),
|
|
313
146
|
],
|
|
314
|
-
};
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
### Next.js
|
|
318
|
-
|
|
319
|
-
```js
|
|
320
|
-
// next.config.js
|
|
321
|
-
const { withAllStak } = require('@allstak/react/next');
|
|
322
|
-
|
|
323
|
-
module.exports = withAllStak(
|
|
324
|
-
{
|
|
325
|
-
release: process.env.ALLSTAK_RELEASE,
|
|
326
|
-
token: process.env.ALLSTAK_UPLOAD_TOKEN,
|
|
327
|
-
dist: 'web',
|
|
328
|
-
},
|
|
329
|
-
{
|
|
330
|
-
reactStrictMode: true,
|
|
331
|
-
// …rest of your Next config…
|
|
332
|
-
}
|
|
333
|
-
);
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
The `withAllStak` wrapper sets `productionBrowserSourceMaps: true` for
|
|
337
|
-
you and only attaches the plugin to the client bundle (Node-side stack
|
|
338
|
-
traces are already symbolicated).
|
|
339
|
-
|
|
340
|
-
### Other bundlers / programmatic use
|
|
341
|
-
|
|
342
|
-
```ts
|
|
343
|
-
import { processBuildOutput } from '@allstak/react/sourcemaps';
|
|
344
|
-
|
|
345
|
-
await processBuildOutput({
|
|
346
|
-
dir: 'dist',
|
|
347
|
-
release: process.env.ALLSTAK_RELEASE!,
|
|
348
|
-
token: process.env.ALLSTAK_UPLOAD_TOKEN!,
|
|
349
|
-
dist: 'web',
|
|
350
|
-
});
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
### What gets sent
|
|
354
|
-
|
|
355
|
-
Each map is POSTed as `multipart/form-data` to
|
|
356
|
-
`POST /api/v1/artifacts/upload` with these fields:
|
|
357
|
-
|
|
358
|
-
- `debugId` — UUID injected into the bundle and the map (matching across both)
|
|
359
|
-
- `type` — `"sourcemap"` (and `"bundle"` if `uploadBundles: true`)
|
|
360
|
-
- `release` — your release identifier (e.g. `web@1.4.2`)
|
|
361
|
-
- `dist` — your distribution tag (e.g. `web`)
|
|
362
|
-
- `file` — the map content as a Blob
|
|
363
|
-
|
|
364
|
-
Auth uses `X-AllStak-Upload-Token` (a project-scoped upload token, NOT
|
|
365
|
-
the runtime API key). Generate one in **Project Settings → Upload Tokens**.
|
|
366
|
-
|
|
367
|
-
### Privacy
|
|
368
|
-
|
|
369
|
-
By default the map is uploaded as-is, which includes embedded
|
|
370
|
-
`sourcesContent`. To strip it (smaller payloads, no source code stored
|
|
371
|
-
on AllStak's side), set `stripSources: true`:
|
|
372
|
-
|
|
373
|
-
```ts
|
|
374
|
-
allstakSourcemaps({
|
|
375
|
-
release: '…',
|
|
376
|
-
token: '…',
|
|
377
|
-
stripSources: true,
|
|
378
147
|
});
|
|
379
148
|
```
|
|
380
149
|
|
|
381
|
-
|
|
382
|
-
contains `sourcesContent` — the SDK side surfaces a clear error.
|
|
150
|
+
Use the same `release` value in the provider and source-map upload.
|
|
383
151
|
|
|
384
|
-
##
|
|
152
|
+
## 9. Troubleshooting
|
|
385
153
|
|
|
386
|
-
-
|
|
387
|
-
-
|
|
388
|
-
-
|
|
154
|
+
- No events: verify `VITE_ALLSTAK_API_KEY` exists and the provider is present once.
|
|
155
|
+
- Duplicate events: rerun `npx @allstak/wizard doctor --integration react` and check for multiple providers.
|
|
156
|
+
- Next.js detected: use `@allstak/next`.
|
|
157
|
+
- Build fails after setup: run `npx @allstak/wizard uninstall --integration react`, then rerun with `--dry-run` and inspect the planned diff.
|
|
158
|
+
- Source maps missing: confirm `ALLSTAK_SOURCEMAP_TOKEN` and matching `release`.
|
|
389
159
|
|
|
390
|
-
##
|
|
160
|
+
## 10. Limitations
|
|
391
161
|
|
|
392
|
-
|
|
162
|
+
- Live dashboard delivery is not proven by local tests.
|
|
163
|
+
- Session replay is privacy-first and limited compared with full DOM replay tools.
|
|
164
|
+
- Edge runtimes should use framework-specific packages.
|
|
165
|
+
- Stable production launch requires live certification against your dashboard.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
processBuildOutput
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-DURAJQ3M.mjs";
|
|
4
4
|
|
|
5
5
|
// src/build/webpack.ts
|
|
6
6
|
var AllStakWebpackPlugin = class {
|
|
@@ -29,4 +29,4 @@ var AllStakWebpackPlugin = class {
|
|
|
29
29
|
export {
|
|
30
30
|
AllStakWebpackPlugin
|
|
31
31
|
};
|
|
32
|
-
//# sourceMappingURL=chunk-
|
|
32
|
+
//# sourceMappingURL=chunk-3JRNQSVX.mjs.map
|
|
@@ -155,6 +155,7 @@ async function uploadAll(pairs, opts) {
|
|
|
155
155
|
|
|
156
156
|
// src/build/sourcemaps.ts
|
|
157
157
|
import { resolve } from "path";
|
|
158
|
+
import { existsSync, readFileSync as readFileSync3 } from "fs";
|
|
158
159
|
async function processBuildOutput(opts) {
|
|
159
160
|
const dir = resolve(opts.dir);
|
|
160
161
|
const pairs = findPairs(dir);
|
|
@@ -172,8 +173,11 @@ async function processBuildOutput(opts) {
|
|
|
172
173
|
for (const i of injected) {
|
|
173
174
|
log(` ${i.bundleName} ${i.debugId} ${i.reused ? "(reused)" : "(new)"}`);
|
|
174
175
|
}
|
|
175
|
-
const
|
|
176
|
-
const
|
|
176
|
+
const env = loadAllStakEnv();
|
|
177
|
+
const token = opts.token ?? env.ALLSTAK_UPLOAD_TOKEN;
|
|
178
|
+
const release = opts.release ?? env.ALLSTAK_RELEASE;
|
|
179
|
+
const host = opts.host ?? env.ALLSTAK_HOST;
|
|
180
|
+
const dist = opts.dist ?? env.ALLSTAK_DIST;
|
|
177
181
|
if (opts.injectOnly || !token) {
|
|
178
182
|
if (!opts.injectOnly && !token) {
|
|
179
183
|
log("skipping upload \u2014 no token (set ALLSTAK_UPLOAD_TOKEN or pass `token`)");
|
|
@@ -187,7 +191,9 @@ async function processBuildOutput(opts) {
|
|
|
187
191
|
const uploaded = await uploadAll(pairs, {
|
|
188
192
|
...opts,
|
|
189
193
|
release,
|
|
190
|
-
token
|
|
194
|
+
token,
|
|
195
|
+
host,
|
|
196
|
+
dist
|
|
191
197
|
});
|
|
192
198
|
for (const u of uploaded) {
|
|
193
199
|
if (u.ok) {
|
|
@@ -199,6 +205,24 @@ async function processBuildOutput(opts) {
|
|
|
199
205
|
}
|
|
200
206
|
return { dir, pairs: pairs.length, injected, uploaded };
|
|
201
207
|
}
|
|
208
|
+
function loadAllStakEnv() {
|
|
209
|
+
const out = { ...process.env };
|
|
210
|
+
for (const file of [".env.local", ".env"]) {
|
|
211
|
+
const full = resolve(process.cwd(), file);
|
|
212
|
+
if (!existsSync(full)) continue;
|
|
213
|
+
const text = readFileSync3(full, "utf8");
|
|
214
|
+
for (const line of text.split(/\r?\n/)) {
|
|
215
|
+
const trimmed = line.trim();
|
|
216
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
217
|
+
const match = /^([A-Z0-9_]+)\s*=\s*(.*)$/.exec(trimmed);
|
|
218
|
+
if (!match) continue;
|
|
219
|
+
const key = match[1];
|
|
220
|
+
if (out[key] !== void 0) continue;
|
|
221
|
+
out[key] = match[2].replace(/^['"]|['"]$/g, "");
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return out;
|
|
225
|
+
}
|
|
202
226
|
|
|
203
227
|
export {
|
|
204
228
|
walk,
|
|
@@ -211,4 +235,4 @@ export {
|
|
|
211
235
|
uploadAll,
|
|
212
236
|
processBuildOutput
|
|
213
237
|
};
|
|
214
|
-
//# sourceMappingURL=chunk-
|
|
238
|
+
//# sourceMappingURL=chunk-DURAJQ3M.mjs.map
|