@flareapp/electron 0.1.0 → 2.5.1

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 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` (renderer/GPU/utility), reported as structured errors with the crash `reason` and `exitCode`.
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
- ## Install
13
+ ## Installation
16
14
 
17
15
  ```bash
18
16
  npm install @flareapp/electron
@@ -20,154 +18,55 @@ npm install @flareapp/electron
20
18
 
21
19
  `electron` is a peer dependency; this package expects your app to provide it.
22
20
 
23
- ## Setup
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
- ### 1. Main process
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('your-flare-api-key');
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
39
  ```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
- ```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
- For manual reporting, use the exported instance:
44
+ Point your `BrowserWindow` at the preload script with `contextIsolation: true` (the default).
81
45
 
82
- ```ts
83
- import { flare } from '@flareapp/electron/renderer';
46
+ ## Using a UI framework
84
47
 
85
- try {
86
- doRiskyThing();
87
- } catch (error) {
88
- flare.report(error as Error);
89
- }
90
- ```
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:
91
49
 
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.
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)
93
53
 
94
- ## How reports flow
54
+ ## Identifying users
95
55
 
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
- ```
112
-
113
- The API key is held only in the main process because that is the single egress point: every report, wherever it originates, is sent from main.
114
-
115
- ## Filtering reports (`beforeSubmit`)
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
56
+ Set the user in the main process; it is stamped on main-origin reports and on forwarded renderer reports:
158
57
 
159
58
  ```ts
160
59
  import { flare } from '@flareapp/electron/main';
161
60
 
162
- flare.setUser({ id: 123, email: 'user@example.com', username: 'jane' });
163
- flare.setUser(null); // clear on logout
61
+ flare.setUser({ id: 123, email: 'jane@example.com', fullName: 'Jane Doe' });
164
62
  ```
165
63
 
166
- The user is attached to main-process reports and to forwarded renderer reports.
64
+ Recognised fields: `id`, `email`, `fullName`, `ipAddress`; extra keys land in `user.attributes`. Pass `null` to clear. The main-process user is authoritative for forwarded renderer reports.
65
+
66
+ ## Documentation
167
67
 
168
- ## Not captured
68
+ 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
69
 
170
- - Native crashes / Crashpad minidumps.
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.
70
+ ## License
172
71
 
173
- This is an experimental release see the note at the top.
72
+ 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 ? "0.1.0" : "?";
37
+ const CLIENT_VERSION = typeof process !== "undefined" && true ? "2.5.1" : "?";
38
38
 
39
39
  //#endregion
40
40
  //#region src/types.ts
@@ -76,23 +76,12 @@ function collectElectronAppAttributes(app) {
76
76
  } catch {}
77
77
  return attrs;
78
78
  }
79
- /** Project a user into OTel enduser.* / client.address keys. */
80
- function projectUser(user) {
81
- const attrs = {};
82
- if (!user) return attrs;
83
- if (user.id !== void 0) attrs["enduser.id"] = String(user.id);
84
- if (user.email !== void 0) attrs["enduser.email"] = user.email;
85
- if (user.username !== void 0) attrs["enduser.username"] = user.username;
86
- if (user.ipAddress !== void 0) attrs["client.address"] = user.ipAddress;
87
- return attrs;
88
- }
89
79
  /** Build the ContextCollector core calls on every main-process report. */
90
- function makeElectronContextCollector(app, getUser) {
80
+ function makeElectronContextCollector(app) {
91
81
  return (_config) => ({
92
82
  "flare.entry_point.type": "server",
93
83
  "process.type": process.type ?? "browser",
94
- ...collectElectronAppAttributes(app),
95
- ...projectUser(getUser())
84
+ ...collectElectronAppAttributes(app)
96
85
  });
97
86
  }
98
87
 
@@ -293,7 +282,7 @@ var ElectronFlare = class extends _flareapp_core.Flare {
293
282
  app;
294
283
  ipcMain;
295
284
  options = { ...DEFAULT_ELECTRON_OPTIONS };
296
- user = null;
285
+ mainScope;
297
286
  isLit = false;
298
287
  handlerManager;
299
288
  renderGoneHandler = null;
@@ -305,9 +294,11 @@ var ElectronFlare = class extends _flareapp_core.Flare {
305
294
  mainSourcemapVersionId = "";
306
295
  constructor(deps) {
307
296
  const app = deps.app;
308
- const collector = makeElectronContextCollector(app, () => this.user);
297
+ const collector = makeElectronContextCollector(app);
309
298
  const flushScheduler = new ElectronFlushScheduler(app);
310
- super(new _flareapp_core.Api(), collector, new ElectronDiskFileReader(), new _flareapp_core.GlobalScopeProvider(), flushScheduler);
299
+ const mainScope = new _flareapp_core.GlobalScopeProvider();
300
+ super(new _flareapp_core.Api(), collector, new ElectronDiskFileReader(), mainScope, flushScheduler);
301
+ this.mainScope = mainScope;
311
302
  this.app = app;
312
303
  this.ipcMain = deps.ipcMain;
313
304
  this.flushScheduler = flushScheduler;
@@ -346,9 +337,6 @@ var ElectronFlare = class extends _flareapp_core.Flare {
346
337
  this.reconcileCrashListeners();
347
338
  return this;
348
339
  }
349
- setUser(user) {
350
- this.user = user;
351
- }
352
340
  dispose() {
353
341
  this.handlerManager.detach();
354
342
  this.detachCrashListeners();
@@ -409,9 +397,10 @@ var ElectronFlare = class extends _flareapp_core.Flare {
409
397
  });
410
398
  });
411
399
  }
412
- /** Overlay main-authoritative config + Electron metadata + user onto a forwarded report, then send. */
400
+ /** Overlay main-authoritative config + Electron metadata + user identity (from the main scope) onto a forwarded report, then send. */
413
401
  receiveRendererReport(report) {
414
- Object.assign(report.attributes, collectElectronAppAttributes(this.app), projectUser(this.user));
402
+ for (const key of _flareapp_core.USER_IDENTITY_KEYS) delete report.attributes[key];
403
+ Object.assign(report.attributes, collectElectronAppAttributes(this.app), (0, _flareapp_core.userIdentityAttributes)(this.mainScope.active()));
415
404
  overlayOrDelete(report.attributes, "service.stage", this.mainStage);
416
405
  overlayOrDelete(report.attributes, "service.version", this.mainVersion);
417
406
  if (this.mainSourcemapVersionId) report.sourcemapVersionId = this.mainSourcemapVersionId;
package/dist/main.d.cts CHANGED
@@ -1,14 +1,8 @@
1
- import { AttributeValue, Attributes, Config, Config as Config$1, DEFAULT_URL_DENYLIST, Flare, GlobalScopeProvider, Glow, Logger, MessageLevel, NullFileReader, Report, Scope, SdkInfo, StackFrame, convertToError, redactUrlQuery, resolveDenylist } from "@flareapp/core";
1
+ import { AttributeValue, Attributes, Config, Config as Config$1, DEFAULT_URL_DENYLIST, Flare, GlobalScopeProvider, Glow, Logger, MessageLevel, NullFileReader, Report, Scope, SdkInfo, StackFrame, User, convertToError, redactUrlQuery, resolveDenylist } from "@flareapp/core";
2
2
  import { App, IpcMain } from "electron";
3
3
 
4
4
  //#region src/types.d.ts
5
5
  type ElectronFatalMode = 'off' | 'report' | 'report-and-exit';
6
- type ElectronUser = {
7
- id?: string | number;
8
- email?: string;
9
- username?: string;
10
- ipAddress?: string;
11
- };
12
6
  /** A frame the IPC receiver evaluates for trust. Mirrors Electron's WebFrameMain shape we use. */
13
7
  type SenderFrame = {
14
8
  url: string;
@@ -35,7 +29,7 @@ declare class ElectronFlare extends Flare {
35
29
  private app;
36
30
  private ipcMain;
37
31
  private options;
38
- private user;
32
+ private mainScope;
39
33
  private isLit;
40
34
  private handlerManager;
41
35
  private renderGoneHandler;
@@ -49,7 +43,6 @@ declare class ElectronFlare extends Flare {
49
43
  configure(config: Partial<Config$1>): this;
50
44
  light(key?: string, debug?: boolean): this;
51
45
  configureElectron(partial: ElectronOptions): this;
52
- setUser(user: ElectronUser | null): void;
53
46
  dispose(): void;
54
47
  /** Attach or detach the process-gone listeners to match options.captureRenderProcessGone. Idempotent. */
55
48
  private reconcileCrashListeners;
@@ -61,7 +54,7 @@ declare class ElectronFlare extends Flare {
61
54
  * first, so the event loop is not kept alive unnecessarily.
62
55
  */
63
56
  flush(timeoutMs?: number): Promise<void>;
64
- /** Overlay main-authoritative config + Electron metadata + user onto a forwarded report, then send. */
57
+ /** Overlay main-authoritative config + Electron metadata + user identity (from the main scope) onto a forwarded report, then send. */
65
58
  private receiveRendererReport;
66
59
  }
67
60
  //#endregion
@@ -74,4 +67,4 @@ declare const FLARE_BRIDGE_KEY = "__flare";
74
67
  //#region src/main.d.ts
75
68
  declare const flare: ElectronFlare;
76
69
  //#endregion
77
- export { type AttributeValue, type Attributes, type Config, DEFAULT_URL_DENYLIST, type ElectronFatalMode, ElectronFlare, type ElectronOptions, type ElectronUser, FLARE_BRIDGE_KEY, FLARE_IPC_CHANNEL, GlobalScopeProvider, type Glow, Logger, type MessageLevel, NullFileReader, type Report, Scope, type SdkInfo, type SenderFrame, type StackFrame, convertToError, flare, redactUrlQuery, resolveDenylist };
70
+ export { type AttributeValue, type Attributes, type Config, DEFAULT_URL_DENYLIST, type ElectronFatalMode, ElectronFlare, type ElectronOptions, FLARE_BRIDGE_KEY, FLARE_IPC_CHANNEL, GlobalScopeProvider, type Glow, Logger, type MessageLevel, NullFileReader, type Report, Scope, type SdkInfo, type SenderFrame, type StackFrame, type User, convertToError, flare, redactUrlQuery, resolveDenylist };
package/dist/main.d.mts CHANGED
@@ -1,14 +1,8 @@
1
1
  import { App, IpcMain } from "electron";
2
- import { AttributeValue, Attributes, Config, Config as Config$1, DEFAULT_URL_DENYLIST, Flare, GlobalScopeProvider, Glow, Logger, MessageLevel, NullFileReader, Report, Scope, SdkInfo, StackFrame, convertToError, redactUrlQuery, resolveDenylist } from "@flareapp/core";
2
+ import { AttributeValue, Attributes, Config, Config as Config$1, DEFAULT_URL_DENYLIST, Flare, GlobalScopeProvider, Glow, Logger, MessageLevel, NullFileReader, Report, Scope, SdkInfo, StackFrame, User, convertToError, redactUrlQuery, resolveDenylist } from "@flareapp/core";
3
3
 
4
4
  //#region src/types.d.ts
5
5
  type ElectronFatalMode = 'off' | 'report' | 'report-and-exit';
6
- type ElectronUser = {
7
- id?: string | number;
8
- email?: string;
9
- username?: string;
10
- ipAddress?: string;
11
- };
12
6
  /** A frame the IPC receiver evaluates for trust. Mirrors Electron's WebFrameMain shape we use. */
13
7
  type SenderFrame = {
14
8
  url: string;
@@ -35,7 +29,7 @@ declare class ElectronFlare extends Flare {
35
29
  private app;
36
30
  private ipcMain;
37
31
  private options;
38
- private user;
32
+ private mainScope;
39
33
  private isLit;
40
34
  private handlerManager;
41
35
  private renderGoneHandler;
@@ -49,7 +43,6 @@ declare class ElectronFlare extends Flare {
49
43
  configure(config: Partial<Config$1>): this;
50
44
  light(key?: string, debug?: boolean): this;
51
45
  configureElectron(partial: ElectronOptions): this;
52
- setUser(user: ElectronUser | null): void;
53
46
  dispose(): void;
54
47
  /** Attach or detach the process-gone listeners to match options.captureRenderProcessGone. Idempotent. */
55
48
  private reconcileCrashListeners;
@@ -61,7 +54,7 @@ declare class ElectronFlare extends Flare {
61
54
  * first, so the event loop is not kept alive unnecessarily.
62
55
  */
63
56
  flush(timeoutMs?: number): Promise<void>;
64
- /** Overlay main-authoritative config + Electron metadata + user onto a forwarded report, then send. */
57
+ /** Overlay main-authoritative config + Electron metadata + user identity (from the main scope) onto a forwarded report, then send. */
65
58
  private receiveRendererReport;
66
59
  }
67
60
  //#endregion
@@ -74,4 +67,4 @@ declare const FLARE_BRIDGE_KEY = "__flare";
74
67
  //#region src/main.d.ts
75
68
  declare const flare: ElectronFlare;
76
69
  //#endregion
77
- export { type AttributeValue, type Attributes, type Config, DEFAULT_URL_DENYLIST, type ElectronFatalMode, ElectronFlare, type ElectronOptions, type ElectronUser, FLARE_BRIDGE_KEY, FLARE_IPC_CHANNEL, GlobalScopeProvider, type Glow, Logger, type MessageLevel, NullFileReader, type Report, Scope, type SdkInfo, type SenderFrame, type StackFrame, convertToError, flare, redactUrlQuery, resolveDenylist };
70
+ export { type AttributeValue, type Attributes, type Config, DEFAULT_URL_DENYLIST, type ElectronFatalMode, ElectronFlare, type ElectronOptions, FLARE_BRIDGE_KEY, FLARE_IPC_CHANNEL, GlobalScopeProvider, type Glow, Logger, type MessageLevel, NullFileReader, type Report, Scope, type SdkInfo, type SenderFrame, type StackFrame, type User, convertToError, flare, redactUrlQuery, resolveDenylist };
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, convertToError, redactUrlQuery, resolveDenylist } from "@flareapp/core";
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";
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 ? "0.1.0" : "?";
8
+ const CLIENT_VERSION = typeof process !== "undefined" && true ? "2.5.1" : "?";
9
9
 
10
10
  //#endregion
11
11
  //#region src/types.ts
@@ -47,23 +47,12 @@ function collectElectronAppAttributes(app) {
47
47
  } catch {}
48
48
  return attrs;
49
49
  }
50
- /** Project a user into OTel enduser.* / client.address keys. */
51
- function projectUser(user) {
52
- const attrs = {};
53
- if (!user) return attrs;
54
- if (user.id !== void 0) attrs["enduser.id"] = String(user.id);
55
- if (user.email !== void 0) attrs["enduser.email"] = user.email;
56
- if (user.username !== void 0) attrs["enduser.username"] = user.username;
57
- if (user.ipAddress !== void 0) attrs["client.address"] = user.ipAddress;
58
- return attrs;
59
- }
60
50
  /** Build the ContextCollector core calls on every main-process report. */
61
- function makeElectronContextCollector(app, getUser) {
51
+ function makeElectronContextCollector(app) {
62
52
  return (_config) => ({
63
53
  "flare.entry_point.type": "server",
64
54
  "process.type": process.type ?? "browser",
65
- ...collectElectronAppAttributes(app),
66
- ...projectUser(getUser())
55
+ ...collectElectronAppAttributes(app)
67
56
  });
68
57
  }
69
58
 
@@ -264,7 +253,7 @@ var ElectronFlare = class extends Flare {
264
253
  app;
265
254
  ipcMain;
266
255
  options = { ...DEFAULT_ELECTRON_OPTIONS };
267
- user = null;
256
+ mainScope;
268
257
  isLit = false;
269
258
  handlerManager;
270
259
  renderGoneHandler = null;
@@ -276,9 +265,11 @@ var ElectronFlare = class extends Flare {
276
265
  mainSourcemapVersionId = "";
277
266
  constructor(deps) {
278
267
  const app = deps.app;
279
- const collector = makeElectronContextCollector(app, () => this.user);
268
+ const collector = makeElectronContextCollector(app);
280
269
  const flushScheduler = new ElectronFlushScheduler(app);
281
- super(new Api(), collector, new ElectronDiskFileReader(), new GlobalScopeProvider$1(), flushScheduler);
270
+ const mainScope = new GlobalScopeProvider$1();
271
+ super(new Api(), collector, new ElectronDiskFileReader(), mainScope, flushScheduler);
272
+ this.mainScope = mainScope;
282
273
  this.app = app;
283
274
  this.ipcMain = deps.ipcMain;
284
275
  this.flushScheduler = flushScheduler;
@@ -317,9 +308,6 @@ var ElectronFlare = class extends Flare {
317
308
  this.reconcileCrashListeners();
318
309
  return this;
319
310
  }
320
- setUser(user) {
321
- this.user = user;
322
- }
323
311
  dispose() {
324
312
  this.handlerManager.detach();
325
313
  this.detachCrashListeners();
@@ -380,9 +368,10 @@ var ElectronFlare = class extends Flare {
380
368
  });
381
369
  });
382
370
  }
383
- /** Overlay main-authoritative config + Electron metadata + user onto a forwarded report, then send. */
371
+ /** Overlay main-authoritative config + Electron metadata + user identity (from the main scope) onto a forwarded report, then send. */
384
372
  receiveRendererReport(report) {
385
- Object.assign(report.attributes, collectElectronAppAttributes(this.app), projectUser(this.user));
373
+ for (const key of USER_IDENTITY_KEYS) delete report.attributes[key];
374
+ Object.assign(report.attributes, collectElectronAppAttributes(this.app), userIdentityAttributes(this.mainScope.active()));
386
375
  overlayOrDelete(report.attributes, "service.stage", this.mainStage);
387
376
  overlayOrDelete(report.attributes, "service.version", this.mainVersion);
388
377
  if (this.mainSourcemapVersionId) report.sourcemapVersionId = this.mainSourcemapVersionId;
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 ? "0.1.0" : "?";
11
+ const CLIENT_VERSION = typeof process !== "undefined" && true ? "2.5.1" : "?";
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 ? "0.1.0" : "?";
10
+ const CLIENT_VERSION = typeof process !== "undefined" && true ? "2.5.1" : "?";
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": "0.1.0",
4
- "description": "Experimental Electron SDK for flareapp.io",
3
+ "version": "2.5.1",
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.4.0",
66
- "@flareapp/js": "2.4.0"
65
+ "@flareapp/core": "2.5.1",
66
+ "@flareapp/js": "2.5.1"
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"