@flareapp/electron 2.6.0 → 2.8.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/dist/main.cjs +42 -34
- package/dist/main.d.cts +2 -1
- package/dist/main.d.mts +2 -1
- package/dist/main.mjs +43 -35
- package/dist/renderer.cjs +1 -1
- package/dist/renderer.mjs +1 -1
- package/package.json +7 -3
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 ? "2.
|
|
37
|
+
const CLIENT_VERSION = typeof process !== "undefined" && true ? "2.8.0" : "?";
|
|
38
38
|
|
|
39
39
|
//#endregion
|
|
40
40
|
//#region src/types.ts
|
|
@@ -51,11 +51,9 @@ const DEFAULT_ELECTRON_OPTIONS = {
|
|
|
51
51
|
//#endregion
|
|
52
52
|
//#region src/main/collectElectron.ts
|
|
53
53
|
/**
|
|
54
|
-
* App + runtime attributes
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* Intentionally does NOT include per-process fields like `flare.entry_point.type` or `process.type`
|
|
58
|
-
* so that forwarded renderer reports keep their own `flare.entry_point.type: 'web'` intact.
|
|
54
|
+
* App + runtime attributes safe to overlay onto any report regardless of origin. Reused by both
|
|
55
|
+
* the collector (main errors) and the IPC receiver (forwarded renderer reports). Excludes per-process
|
|
56
|
+
* fields like `flare.entry_point.type` / `process.type` so forwarded renderer reports keep their own.
|
|
59
57
|
*/
|
|
60
58
|
function collectElectronAppAttributes(app) {
|
|
61
59
|
const versions = process.versions;
|
|
@@ -79,7 +77,7 @@ function collectElectronAppAttributes(app) {
|
|
|
79
77
|
/** Build the ContextCollector core calls on every main-process report. */
|
|
80
78
|
function makeElectronContextCollector(app) {
|
|
81
79
|
return (_config) => ({
|
|
82
|
-
"flare.entry_point.type": "
|
|
80
|
+
"flare.entry_point.type": "web",
|
|
83
81
|
"process.type": process.type ?? "browser",
|
|
84
82
|
...collectElectronAppAttributes(app)
|
|
85
83
|
});
|
|
@@ -158,10 +156,9 @@ function isTrusted(frame, opts) {
|
|
|
158
156
|
return defaultTrustPolicy(frame, opts);
|
|
159
157
|
}
|
|
160
158
|
/**
|
|
161
|
-
* Minimal top-level structural guard for a parsed report
|
|
162
|
-
* validator
|
|
163
|
-
*
|
|
164
|
-
* is the sender-trust check plus the byte-size cap; this guard only rejects obviously-wrong payloads.
|
|
159
|
+
* Minimal top-level structural guard for a parsed report, not an exhaustive StackFrame/SpanEvent
|
|
160
|
+
* validator: a compromised renderer could forge any valid-looking shape anyway. The security boundary
|
|
161
|
+
* is the sender-trust check plus the byte-size cap; this only rejects obviously-wrong payloads.
|
|
165
162
|
*/
|
|
166
163
|
function isReportShape(value) {
|
|
167
164
|
if (typeof value !== "object" || value === null) return false;
|
|
@@ -196,9 +193,9 @@ function disposeIpcReceiver(ipcMain, owner) {
|
|
|
196
193
|
//#endregion
|
|
197
194
|
//#region src/main/processHandlers.ts
|
|
198
195
|
/**
|
|
199
|
-
* Fatal callbacks for Electron main. Mirrors @flareapp/node's buildFatalCallbacks but exits via
|
|
200
|
-
*
|
|
201
|
-
*
|
|
196
|
+
* Fatal callbacks for Electron main. Mirrors @flareapp/node's buildFatalCallbacks but exits via the
|
|
197
|
+
* injected `exit` (app.exit at the call site), which is immediate and skips before-quit/will-quit,
|
|
198
|
+
* correct after an uncaught exception.
|
|
202
199
|
*/
|
|
203
200
|
function buildFatalCallbacks(flare, getOpts, exit) {
|
|
204
201
|
return {
|
|
@@ -229,9 +226,13 @@ function buildFatalCallbacks(flare, getOpts, exit) {
|
|
|
229
226
|
};
|
|
230
227
|
}
|
|
231
228
|
/**
|
|
232
|
-
* Owns the lifecycle of the two process-level error listeners for the Electron main process
|
|
233
|
-
*
|
|
234
|
-
*
|
|
229
|
+
* Owns the lifecycle of the two process-level error listeners for the Electron main process,
|
|
230
|
+
* reconciling attach/detach against the desired modes. Mirrors node's ProcessHandlerManager.
|
|
231
|
+
*
|
|
232
|
+
* Deliberately a copy, not a shared module. @flareapp/electron does not depend on @flareapp/node, and
|
|
233
|
+
* the only package both import is @flareapp/core, which ships in every browser bundle and touches
|
|
234
|
+
* `process` only behind a typeof guard. A shared manager belongs in a new package, not in core, and
|
|
235
|
+
* one method does not pay for one.
|
|
235
236
|
*/
|
|
236
237
|
var ProcessHandlerManager = class {
|
|
237
238
|
uncaughtHandler = null;
|
|
@@ -260,13 +261,14 @@ var ProcessHandlerManager = class {
|
|
|
260
261
|
reconcileOne(event, mode, get, set, impl) {
|
|
261
262
|
const current = get();
|
|
262
263
|
const wants = mode !== "off";
|
|
263
|
-
if (wants
|
|
264
|
-
|
|
265
|
-
process.on(event, impl);
|
|
266
|
-
} else if (!wants && current) {
|
|
264
|
+
if (wants === (current !== null)) return;
|
|
265
|
+
if (!wants) {
|
|
267
266
|
process.off(event, current);
|
|
268
267
|
set(null);
|
|
268
|
+
return;
|
|
269
269
|
}
|
|
270
|
+
set(impl);
|
|
271
|
+
process.on(event, impl);
|
|
270
272
|
}
|
|
271
273
|
};
|
|
272
274
|
|
|
@@ -306,6 +308,7 @@ var ElectronFlare = class extends _flareapp_core.Flare {
|
|
|
306
308
|
name: SDK_NAME,
|
|
307
309
|
version: CLIENT_VERSION
|
|
308
310
|
});
|
|
311
|
+
this.setFramework({ name: _flareapp_core.FrameworkName.NodeElectron });
|
|
309
312
|
this.handlerManager = new ProcessHandlerManager(buildFatalCallbacks(this, () => this.options, (code) => this.app.exit(code)));
|
|
310
313
|
registerIpcReceiver(this.ipcMain, this, {
|
|
311
314
|
getOptions: () => this.options,
|
|
@@ -343,20 +346,25 @@ var ElectronFlare = class extends _flareapp_core.Flare {
|
|
|
343
346
|
disposeIpcReceiver(this.ipcMain, this);
|
|
344
347
|
this.flushScheduler.dispose();
|
|
345
348
|
}
|
|
346
|
-
/** Attach
|
|
349
|
+
/** Attach/detach the process-gone listeners to match options.captureRenderProcessGone. Idempotent. */
|
|
347
350
|
reconcileCrashListeners() {
|
|
348
|
-
const want = this.options.captureRenderProcessGone;
|
|
349
|
-
|
|
350
|
-
if (want
|
|
351
|
-
this.
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
this.
|
|
359
|
-
}
|
|
351
|
+
const want = Boolean(this.options.captureRenderProcessGone);
|
|
352
|
+
if (want === (this.renderGoneHandler !== null)) return;
|
|
353
|
+
if (!want) {
|
|
354
|
+
this.detachCrashListeners();
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
this.attachCrashListeners();
|
|
358
|
+
}
|
|
359
|
+
attachCrashListeners() {
|
|
360
|
+
this.renderGoneHandler = (_event, webContents, details) => {
|
|
361
|
+
return this.reportProcessGone("renderer", details, webContents?.id);
|
|
362
|
+
};
|
|
363
|
+
this.childGoneHandler = (_event, details) => {
|
|
364
|
+
return this.reportProcessGone("child", details);
|
|
365
|
+
};
|
|
366
|
+
this.app.on("render-process-gone", this.renderGoneHandler);
|
|
367
|
+
this.app.on("child-process-gone", this.childGoneHandler);
|
|
360
368
|
}
|
|
361
369
|
detachCrashListeners() {
|
|
362
370
|
if (this.renderGoneHandler) {
|
package/dist/main.d.cts
CHANGED
|
@@ -44,8 +44,9 @@ declare class ElectronFlare extends Flare {
|
|
|
44
44
|
light(key?: string, debug?: boolean): this;
|
|
45
45
|
configureElectron(partial: ElectronOptions): this;
|
|
46
46
|
dispose(): void;
|
|
47
|
-
/** Attach
|
|
47
|
+
/** Attach/detach the process-gone listeners to match options.captureRenderProcessGone. Idempotent. */
|
|
48
48
|
private reconcileCrashListeners;
|
|
49
|
+
private attachCrashListeners;
|
|
49
50
|
private detachCrashListeners;
|
|
50
51
|
private reportProcessGone;
|
|
51
52
|
/**
|
package/dist/main.d.mts
CHANGED
|
@@ -44,8 +44,9 @@ declare class ElectronFlare extends Flare {
|
|
|
44
44
|
light(key?: string, debug?: boolean): this;
|
|
45
45
|
configureElectron(partial: ElectronOptions): this;
|
|
46
46
|
dispose(): void;
|
|
47
|
-
/** Attach
|
|
47
|
+
/** Attach/detach the process-gone listeners to match options.captureRenderProcessGone. Idempotent. */
|
|
48
48
|
private reconcileCrashListeners;
|
|
49
|
+
private attachCrashListeners;
|
|
49
50
|
private detachCrashListeners;
|
|
50
51
|
private reportProcessGone;
|
|
51
52
|
/**
|
package/dist/main.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { app, ipcMain } from "electron";
|
|
2
|
-
import { Api, DEFAULT_URL_DENYLIST, Flare, GlobalScopeProvider, GlobalScopeProvider as GlobalScopeProvider$1, Logger, NullFileReader, Scope, USER_IDENTITY_KEYS, convertToError, redactUrlQuery, resolveDenylist, userIdentityAttributes } from "@flareapp/core";
|
|
2
|
+
import { Api, DEFAULT_URL_DENYLIST, Flare, FrameworkName, GlobalScopeProvider, GlobalScopeProvider as GlobalScopeProvider$1, Logger, NullFileReader, Scope, USER_IDENTITY_KEYS, convertToError, redactUrlQuery, resolveDenylist, userIdentityAttributes } from "@flareapp/core";
|
|
3
3
|
import os from "node:os";
|
|
4
4
|
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 ? "2.
|
|
8
|
+
const CLIENT_VERSION = typeof process !== "undefined" && true ? "2.8.0" : "?";
|
|
9
9
|
|
|
10
10
|
//#endregion
|
|
11
11
|
//#region src/types.ts
|
|
@@ -22,11 +22,9 @@ const DEFAULT_ELECTRON_OPTIONS = {
|
|
|
22
22
|
//#endregion
|
|
23
23
|
//#region src/main/collectElectron.ts
|
|
24
24
|
/**
|
|
25
|
-
* App + runtime attributes
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* Intentionally does NOT include per-process fields like `flare.entry_point.type` or `process.type`
|
|
29
|
-
* so that forwarded renderer reports keep their own `flare.entry_point.type: 'web'` intact.
|
|
25
|
+
* App + runtime attributes safe to overlay onto any report regardless of origin. Reused by both
|
|
26
|
+
* the collector (main errors) and the IPC receiver (forwarded renderer reports). Excludes per-process
|
|
27
|
+
* fields like `flare.entry_point.type` / `process.type` so forwarded renderer reports keep their own.
|
|
30
28
|
*/
|
|
31
29
|
function collectElectronAppAttributes(app) {
|
|
32
30
|
const versions = process.versions;
|
|
@@ -50,7 +48,7 @@ function collectElectronAppAttributes(app) {
|
|
|
50
48
|
/** Build the ContextCollector core calls on every main-process report. */
|
|
51
49
|
function makeElectronContextCollector(app) {
|
|
52
50
|
return (_config) => ({
|
|
53
|
-
"flare.entry_point.type": "
|
|
51
|
+
"flare.entry_point.type": "web",
|
|
54
52
|
"process.type": process.type ?? "browser",
|
|
55
53
|
...collectElectronAppAttributes(app)
|
|
56
54
|
});
|
|
@@ -129,10 +127,9 @@ function isTrusted(frame, opts) {
|
|
|
129
127
|
return defaultTrustPolicy(frame, opts);
|
|
130
128
|
}
|
|
131
129
|
/**
|
|
132
|
-
* Minimal top-level structural guard for a parsed report
|
|
133
|
-
* validator
|
|
134
|
-
*
|
|
135
|
-
* is the sender-trust check plus the byte-size cap; this guard only rejects obviously-wrong payloads.
|
|
130
|
+
* Minimal top-level structural guard for a parsed report, not an exhaustive StackFrame/SpanEvent
|
|
131
|
+
* validator: a compromised renderer could forge any valid-looking shape anyway. The security boundary
|
|
132
|
+
* is the sender-trust check plus the byte-size cap; this only rejects obviously-wrong payloads.
|
|
136
133
|
*/
|
|
137
134
|
function isReportShape(value) {
|
|
138
135
|
if (typeof value !== "object" || value === null) return false;
|
|
@@ -167,9 +164,9 @@ function disposeIpcReceiver(ipcMain, owner) {
|
|
|
167
164
|
//#endregion
|
|
168
165
|
//#region src/main/processHandlers.ts
|
|
169
166
|
/**
|
|
170
|
-
* Fatal callbacks for Electron main. Mirrors @flareapp/node's buildFatalCallbacks but exits via
|
|
171
|
-
*
|
|
172
|
-
*
|
|
167
|
+
* Fatal callbacks for Electron main. Mirrors @flareapp/node's buildFatalCallbacks but exits via the
|
|
168
|
+
* injected `exit` (app.exit at the call site), which is immediate and skips before-quit/will-quit,
|
|
169
|
+
* correct after an uncaught exception.
|
|
173
170
|
*/
|
|
174
171
|
function buildFatalCallbacks(flare, getOpts, exit) {
|
|
175
172
|
return {
|
|
@@ -200,9 +197,13 @@ function buildFatalCallbacks(flare, getOpts, exit) {
|
|
|
200
197
|
};
|
|
201
198
|
}
|
|
202
199
|
/**
|
|
203
|
-
* Owns the lifecycle of the two process-level error listeners for the Electron main process
|
|
204
|
-
*
|
|
205
|
-
*
|
|
200
|
+
* Owns the lifecycle of the two process-level error listeners for the Electron main process,
|
|
201
|
+
* reconciling attach/detach against the desired modes. Mirrors node's ProcessHandlerManager.
|
|
202
|
+
*
|
|
203
|
+
* Deliberately a copy, not a shared module. @flareapp/electron does not depend on @flareapp/node, and
|
|
204
|
+
* the only package both import is @flareapp/core, which ships in every browser bundle and touches
|
|
205
|
+
* `process` only behind a typeof guard. A shared manager belongs in a new package, not in core, and
|
|
206
|
+
* one method does not pay for one.
|
|
206
207
|
*/
|
|
207
208
|
var ProcessHandlerManager = class {
|
|
208
209
|
uncaughtHandler = null;
|
|
@@ -231,13 +232,14 @@ var ProcessHandlerManager = class {
|
|
|
231
232
|
reconcileOne(event, mode, get, set, impl) {
|
|
232
233
|
const current = get();
|
|
233
234
|
const wants = mode !== "off";
|
|
234
|
-
if (wants
|
|
235
|
-
|
|
236
|
-
process.on(event, impl);
|
|
237
|
-
} else if (!wants && current) {
|
|
235
|
+
if (wants === (current !== null)) return;
|
|
236
|
+
if (!wants) {
|
|
238
237
|
process.off(event, current);
|
|
239
238
|
set(null);
|
|
239
|
+
return;
|
|
240
240
|
}
|
|
241
|
+
set(impl);
|
|
242
|
+
process.on(event, impl);
|
|
241
243
|
}
|
|
242
244
|
};
|
|
243
245
|
|
|
@@ -277,6 +279,7 @@ var ElectronFlare = class extends Flare {
|
|
|
277
279
|
name: SDK_NAME,
|
|
278
280
|
version: CLIENT_VERSION
|
|
279
281
|
});
|
|
282
|
+
this.setFramework({ name: FrameworkName.NodeElectron });
|
|
280
283
|
this.handlerManager = new ProcessHandlerManager(buildFatalCallbacks(this, () => this.options, (code) => this.app.exit(code)));
|
|
281
284
|
registerIpcReceiver(this.ipcMain, this, {
|
|
282
285
|
getOptions: () => this.options,
|
|
@@ -314,20 +317,25 @@ var ElectronFlare = class extends Flare {
|
|
|
314
317
|
disposeIpcReceiver(this.ipcMain, this);
|
|
315
318
|
this.flushScheduler.dispose();
|
|
316
319
|
}
|
|
317
|
-
/** Attach
|
|
320
|
+
/** Attach/detach the process-gone listeners to match options.captureRenderProcessGone. Idempotent. */
|
|
318
321
|
reconcileCrashListeners() {
|
|
319
|
-
const want = this.options.captureRenderProcessGone;
|
|
320
|
-
|
|
321
|
-
if (want
|
|
322
|
-
this.
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
this.
|
|
330
|
-
}
|
|
322
|
+
const want = Boolean(this.options.captureRenderProcessGone);
|
|
323
|
+
if (want === (this.renderGoneHandler !== null)) return;
|
|
324
|
+
if (!want) {
|
|
325
|
+
this.detachCrashListeners();
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
this.attachCrashListeners();
|
|
329
|
+
}
|
|
330
|
+
attachCrashListeners() {
|
|
331
|
+
this.renderGoneHandler = (_event, webContents, details) => {
|
|
332
|
+
return this.reportProcessGone("renderer", details, webContents?.id);
|
|
333
|
+
};
|
|
334
|
+
this.childGoneHandler = (_event, details) => {
|
|
335
|
+
return this.reportProcessGone("child", details);
|
|
336
|
+
};
|
|
337
|
+
this.app.on("render-process-gone", this.renderGoneHandler);
|
|
338
|
+
this.app.on("child-process-gone", this.childGoneHandler);
|
|
331
339
|
}
|
|
332
340
|
detachCrashListeners() {
|
|
333
341
|
if (this.renderGoneHandler) {
|
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 ? "2.
|
|
11
|
+
const CLIENT_VERSION = typeof process !== "undefined" && true ? "2.8.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 ? "2.
|
|
10
|
+
const CLIENT_VERSION = typeof process !== "undefined" && true ? "2.8.0" : "?";
|
|
11
11
|
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region src/renderer/RendererFlare.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flareapp/electron",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"description": "Electron SDK for flareapp.io",
|
|
5
5
|
"homepage": "https://flareapp.io",
|
|
6
6
|
"bugs": {
|
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
"name": "Spatie",
|
|
16
16
|
"email": "info@spatie.be"
|
|
17
17
|
},
|
|
18
|
+
"contributors": [
|
|
19
|
+
"Dries Heyninck <dries@spatie.be>"
|
|
20
|
+
],
|
|
18
21
|
"files": [
|
|
19
22
|
"dist"
|
|
20
23
|
],
|
|
@@ -62,14 +65,15 @@
|
|
|
62
65
|
"release": "release-it"
|
|
63
66
|
},
|
|
64
67
|
"dependencies": {
|
|
65
|
-
"@flareapp/core": "2.
|
|
66
|
-
"@flareapp/js": "2.
|
|
68
|
+
"@flareapp/core": "2.8.0",
|
|
69
|
+
"@flareapp/js": "2.8.0"
|
|
67
70
|
},
|
|
68
71
|
"peerDependencies": {
|
|
69
72
|
"electron": ">=35"
|
|
70
73
|
},
|
|
71
74
|
"devDependencies": {
|
|
72
75
|
"@flareapp/react": "file:../react",
|
|
76
|
+
"@flareapp/test-helpers": "*",
|
|
73
77
|
"@flareapp/vue": "file:../vue",
|
|
74
78
|
"electron": "^35.0.0",
|
|
75
79
|
"react": "^19.0.0",
|