@flareapp/electron 0.1.0 → 2.5.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 +17 -130
- package/dist/main.cjs +1 -1
- package/dist/main.mjs +1 -1
- package/dist/renderer.cjs +1 -1
- package/dist/renderer.mjs +1 -1
- package/package.json +9 -5
package/README.md
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
# @flareapp/electron
|
|
2
2
|
|
|
3
|
-
> ⚠️ **Experimental (`0.1.0`).** This package is new and its API may change in a minor release. Feedback and bug reports are very welcome at https://github.com/spatie/flare-client-js/issues.
|
|
4
|
-
|
|
5
3
|
Electron SDK for [Flare](https://flareapp.io) error tracking. It captures JavaScript errors in **both** Electron processes and routes every report through the main process, so your API key lives in exactly one place.
|
|
6
4
|
|
|
7
5
|
## What it captures
|
|
8
6
|
|
|
9
7
|
- **Main process:** uncaught exceptions and unhandled promise rejections.
|
|
10
8
|
- **Renderer process:** `window.onerror` and `unhandledrejection`, plus anything you report manually.
|
|
11
|
-
- **Process crashes:** `render-process-gone` and `child-process-gone
|
|
9
|
+
- **Process crashes:** `render-process-gone` and `child-process-gone`, reported with the crash `reason` and `exitCode`.
|
|
12
10
|
|
|
13
11
|
It does **not** capture native crashes (C++/Crashpad minidumps). Only JavaScript-level errors are sent to Flare.
|
|
14
12
|
|
|
15
|
-
##
|
|
13
|
+
## Installation
|
|
16
14
|
|
|
17
15
|
```bash
|
|
18
16
|
npm install @flareapp/electron
|
|
@@ -20,154 +18,43 @@ npm install @flareapp/electron
|
|
|
20
18
|
|
|
21
19
|
`electron` is a peer dependency; this package expects your app to provide it.
|
|
22
20
|
|
|
23
|
-
##
|
|
24
|
-
|
|
25
|
-
Flare needs wiring in all three Electron contexts. The API key, `stage`, `version`, and sourcemap settings are configured **once, in the main process** — the renderer needs none of them.
|
|
21
|
+
## Quick start
|
|
26
22
|
|
|
27
|
-
|
|
23
|
+
Flare needs wiring in all three Electron contexts. The API key is configured **once, in the main process**.
|
|
28
24
|
|
|
29
25
|
```ts
|
|
30
26
|
// main.ts
|
|
31
|
-
import { app } from 'electron';
|
|
32
27
|
import { flare } from '@flareapp/electron/main';
|
|
33
28
|
|
|
34
|
-
flare.light('
|
|
35
|
-
|
|
36
|
-
// Optional: these are set ONCE here and applied to renderer reports too.
|
|
37
|
-
flare.configure({ stage: 'production', version: app.getVersion() });
|
|
38
|
-
|
|
39
|
-
// Optional: fatal-handler behavior and IPC trust policy.
|
|
40
|
-
flare.configureElectron({
|
|
41
|
-
uncaughtExceptionMode: 'report-and-exit', // 'report' | 'report-and-exit' | 'off'
|
|
42
|
-
unhandledRejectionMode: 'report-and-exit',
|
|
43
|
-
captureRenderProcessGone: true,
|
|
44
|
-
});
|
|
29
|
+
flare.light('YOUR_FLARE_API_KEY');
|
|
45
30
|
```
|
|
46
31
|
|
|
47
|
-
In `report-and-exit` mode, after a fatal error Flare reports it, flushes pending reports (up to `shutdownTimeoutMs`), then calls `app.exit(1)`.
|
|
48
|
-
|
|
49
|
-
### 2. Preload script
|
|
50
|
-
|
|
51
|
-
Because `contextIsolation` is on (the Electron default and the recommended setting), the renderer cannot reach `ipcRenderer` directly. The preload helper bridges reports over `contextBridge`. This step is **required** — without it, renderer reports are dropped.
|
|
52
|
-
|
|
53
32
|
```ts
|
|
54
|
-
// preload.ts
|
|
33
|
+
// preload.ts — required so renderer reports reach main over contextBridge
|
|
55
34
|
import { exposeFlare } from '@flareapp/electron/preload';
|
|
56
35
|
|
|
57
36
|
exposeFlare();
|
|
58
37
|
```
|
|
59
38
|
|
|
60
|
-
Make sure your `BrowserWindow` points at this preload script:
|
|
61
|
-
|
|
62
|
-
```ts
|
|
63
|
-
new BrowserWindow({
|
|
64
|
-
webPreferences: {
|
|
65
|
-
preload: path.join(__dirname, 'preload.js'),
|
|
66
|
-
contextIsolation: true,
|
|
67
|
-
},
|
|
68
|
-
});
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### 3. Renderer
|
|
72
|
-
|
|
73
|
-
Import the renderer entry once, as early as possible, to install the global error listeners:
|
|
74
|
-
|
|
75
39
|
```ts
|
|
76
|
-
// renderer entry, e.g. main.tsx / index.ts
|
|
40
|
+
// renderer entry, e.g. main.tsx / index.ts — installs the global listeners
|
|
77
41
|
import '@flareapp/electron/renderer';
|
|
78
42
|
```
|
|
79
43
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
```ts
|
|
83
|
-
import { flare } from '@flareapp/electron/renderer';
|
|
84
|
-
|
|
85
|
-
try {
|
|
86
|
-
doRiskyThing();
|
|
87
|
-
} catch (error) {
|
|
88
|
-
flare.report(error as Error);
|
|
89
|
-
}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
The renderer builds the full report (stack trace + source snippets + browser context) in its own context, then forwards it to the main process. No API key lives in the renderer.
|
|
44
|
+
Point your `BrowserWindow` at the preload script with `contextIsolation: true` (the default).
|
|
93
45
|
|
|
94
|
-
##
|
|
46
|
+
## Using a UI framework
|
|
95
47
|
|
|
96
|
-
|
|
97
|
-
renderer error
|
|
98
|
-
→ RendererFlare builds Report (stack + snippets + browser context)
|
|
99
|
-
→ renderer beforeSubmit → serialize → size-check
|
|
100
|
-
→ window.__flare.report(jsonString) [contextBridge]
|
|
101
|
-
→ ipcRenderer.invoke('flare:report') [IPC]
|
|
102
|
-
→ main: trust sender → size-check → parse → validate
|
|
103
|
-
→ overlay stage/version/sourcemap + app metadata + user
|
|
104
|
-
→ main beforeSubmit → sent to Flare
|
|
105
|
-
|
|
106
|
-
main-process error
|
|
107
|
-
→ process handlers → sent to Flare (app.exit on report-and-exit)
|
|
108
|
-
|
|
109
|
-
renderer / GPU crash
|
|
110
|
-
→ render-process-gone / child-process-gone → reported → sent to Flare
|
|
111
|
-
```
|
|
48
|
+
When your renderer uses React, Vue, or Svelte, inject the Electron Flare instance through the framework's `/inject` entry instead of the `@flareapp/js` web singleton. See the framework configuration guides:
|
|
112
49
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
`beforeSubmit` runs in **two stages**: once in the renderer (scrub close to the source) and once in main (the final gate before sending). Returning `null`/`false` from either drops the report.
|
|
118
|
-
|
|
119
|
-
```ts
|
|
120
|
-
// main
|
|
121
|
-
flare.configure({
|
|
122
|
-
beforeSubmit: (report) => {
|
|
123
|
-
// final scrub before sending
|
|
124
|
-
return report;
|
|
125
|
-
},
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
// renderer
|
|
129
|
-
import { flare } from '@flareapp/electron/renderer';
|
|
130
|
-
flare.configure({
|
|
131
|
-
beforeSubmit: (report) => {
|
|
132
|
-
delete report.attributes['context.custom'];
|
|
133
|
-
return report;
|
|
134
|
-
},
|
|
135
|
-
});
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
## Sender trust
|
|
139
|
-
|
|
140
|
-
The main process only accepts reports from frames it trusts. By **default** it accepts:
|
|
141
|
-
|
|
142
|
-
- `file:` URLs (packaged builds), and
|
|
143
|
-
- `http(s)` on `localhost` / `127.0.0.1` (dev servers).
|
|
144
|
-
|
|
145
|
-
It rejects everything else, including remote origins and custom protocols. If your app serves its renderer over a custom protocol or loads trusted remote content, opt in:
|
|
146
|
-
|
|
147
|
-
```ts
|
|
148
|
-
// Add a custom protocol scheme:
|
|
149
|
-
flare.configureElectron({ trustedProtocols: ['app'] });
|
|
150
|
-
|
|
151
|
-
// Or take full control:
|
|
152
|
-
flare.configureElectron({
|
|
153
|
-
trustSender: (frame) => new URL(frame.url).origin === 'https://app.example.com',
|
|
154
|
-
});
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## Attaching the current user
|
|
158
|
-
|
|
159
|
-
```ts
|
|
160
|
-
import { flare } from '@flareapp/electron/main';
|
|
161
|
-
|
|
162
|
-
flare.setUser({ id: 123, email: 'user@example.com', username: 'jane' });
|
|
163
|
-
flare.setUser(null); // clear on logout
|
|
164
|
-
```
|
|
50
|
+
- [Electron + React](https://flareapp.io/docs/react/electron/configuration)
|
|
51
|
+
- [Electron + Vue](https://flareapp.io/docs/vue/electron/configuration)
|
|
52
|
+
- [Electron + Svelte](https://flareapp.io/docs/svelte/electron/configuration)
|
|
165
53
|
|
|
166
|
-
|
|
54
|
+
## Documentation
|
|
167
55
|
|
|
168
|
-
|
|
56
|
+
Full documentation on the report flow, `beforeSubmit` filtering, sender trust, attaching users, and the framework integrations is available at [flareapp.io/docs/javascript/electron/how-it-works](https://flareapp.io/docs/javascript/electron/how-it-works).
|
|
169
57
|
|
|
170
|
-
|
|
171
|
-
- Errors that occur before `flare.light('your-key')` runs in the main process. The fatal process handlers are attached by `light()`, and no report is sent without a key, so call `light()` as early as possible in your main entry. Errors before that point (in any process) are not sent.
|
|
58
|
+
## License
|
|
172
59
|
|
|
173
|
-
|
|
60
|
+
The MIT License (MIT). Please see [License File](../../LICENSE.md) for more information.
|
package/dist/main.cjs
CHANGED
|
@@ -34,7 +34,7 @@ let node_fs_promises = require("node:fs/promises");
|
|
|
34
34
|
let node_url = require("node:url");
|
|
35
35
|
|
|
36
36
|
//#region src/env.ts
|
|
37
|
-
const CLIENT_VERSION = typeof process !== "undefined" && true ? "
|
|
37
|
+
const CLIENT_VERSION = typeof process !== "undefined" && true ? "2.5.0" : "?";
|
|
38
38
|
|
|
39
39
|
//#endregion
|
|
40
40
|
//#region src/types.ts
|
package/dist/main.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { readFile } from "node:fs/promises";
|
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
|
|
7
7
|
//#region src/env.ts
|
|
8
|
-
const CLIENT_VERSION = typeof process !== "undefined" && true ? "
|
|
8
|
+
const CLIENT_VERSION = typeof process !== "undefined" && true ? "2.5.0" : "?";
|
|
9
9
|
|
|
10
10
|
//#endregion
|
|
11
11
|
//#region src/types.ts
|
package/dist/renderer.cjs
CHANGED
|
@@ -8,7 +8,7 @@ const FLARE_BRIDGE_KEY = "__flare";
|
|
|
8
8
|
|
|
9
9
|
//#endregion
|
|
10
10
|
//#region src/env.ts
|
|
11
|
-
const CLIENT_VERSION = typeof process !== "undefined" && true ? "
|
|
11
|
+
const CLIENT_VERSION = typeof process !== "undefined" && true ? "2.5.0" : "?";
|
|
12
12
|
|
|
13
13
|
//#endregion
|
|
14
14
|
//#region src/renderer/RendererFlare.ts
|
package/dist/renderer.mjs
CHANGED
|
@@ -7,7 +7,7 @@ const FLARE_BRIDGE_KEY = "__flare";
|
|
|
7
7
|
|
|
8
8
|
//#endregion
|
|
9
9
|
//#region src/env.ts
|
|
10
|
-
const CLIENT_VERSION = typeof process !== "undefined" && true ? "
|
|
10
|
+
const CLIENT_VERSION = typeof process !== "undefined" && true ? "2.5.0" : "?";
|
|
11
11
|
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region src/renderer/RendererFlare.ts
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flareapp/electron",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.5.0",
|
|
4
|
+
"description": "Electron SDK for flareapp.io",
|
|
5
5
|
"homepage": "https://flareapp.io",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/spatie/flare-client-js/issues"
|
|
@@ -62,17 +62,21 @@
|
|
|
62
62
|
"release": "release-it"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
-
"@flareapp/core": "2.
|
|
66
|
-
"@flareapp/js": "2.
|
|
65
|
+
"@flareapp/core": "2.5.0",
|
|
66
|
+
"@flareapp/js": "2.5.0"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
69
|
"electron": ">=35"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
+
"@flareapp/react": "file:../react",
|
|
73
|
+
"@flareapp/vue": "file:../vue",
|
|
72
74
|
"electron": "^35.0.0",
|
|
75
|
+
"react": "^19.0.0",
|
|
73
76
|
"tsdown": "^0.20.3",
|
|
74
77
|
"typescript": "^5.7.0",
|
|
75
|
-
"vitest": "^4.0.18"
|
|
78
|
+
"vitest": "^4.0.18",
|
|
79
|
+
"vue": "^3.4.0"
|
|
76
80
|
},
|
|
77
81
|
"publishConfig": {
|
|
78
82
|
"access": "public"
|