@flareapp/js 2.8.0 → 2.10.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 CHANGED
@@ -37,6 +37,49 @@ flare.setUser({
37
37
 
38
38
  Recognised fields: `id` (→ `user.id`), `email` (→ `user.email`), `fullName` (→ `user.full_name`), `ipAddress` (→ `client.address`). Any extra keys are collected under `user.attributes`. Pass `null` to clear the user on logout: `flare.setUser(null)`.
39
39
 
40
+ ## Cookie consent and GDPR
41
+
42
+ The client can run behind a consent tool. When consent is off, it sends nothing. Before consent, it does not even assemble a report.
43
+
44
+ The switch is one method:
45
+
46
+ ```javascript
47
+ flare.setConsent(true); // allow sending
48
+ flare.setConsent(false); // stop sending, and drop anything captured earlier
49
+ ```
50
+
51
+ Recommended flow: do not call `flare.light(key)` until consent is granted. With no key, nothing sends, so this covers the moment before your consent code runs. Use `setConsent` for withdrawal and re-grant, because once the key is set it is the only clean off switch.
52
+
53
+ ```javascript
54
+ import { flare } from '@flareapp/js';
55
+
56
+ // Cookiebot example. OneTrust exposes OptanonWrapper; the idea is the same.
57
+ window.addEventListener('CookiebotOnAccept', () => {
58
+ flare.light('your-project-key'); // first grant: start the client
59
+ flare.setConsent(true); // and allow sending
60
+ });
61
+
62
+ window.addEventListener('CookiebotOnDecline', () => {
63
+ flare.setConsent(false); // withdrawal: stop all sends, drop buffers
64
+ });
65
+ ```
66
+
67
+ If you set the key at boot instead of waiting, start with consent off, then turn it on when the user accepts:
68
+
69
+ ```javascript
70
+ import { flare } from '@flareapp/js';
71
+
72
+ flare.configure({ hasConsent: false }); // start off, before anything can send
73
+ flare.light('your-project-key');
74
+
75
+ window.addEventListener('CookiebotOnAccept', () => flare.setConsent(true));
76
+ window.addEventListener('CookiebotOnDecline', () => flare.setConsent(false));
77
+ ```
78
+
79
+ Put `configure({ hasConsent: false })` first, right after the import, so the gate is off before an early uncaught error can assemble a report.
80
+
81
+ Consent defaults to on, so setups without a consent tool are unchanged. `setConsent(false)` stops data leaving the browser. It does not remove the `fetch` and `XHR` patches that tracing and breadcrumbs install, because those only read in memory and never send on their own. To remove those too, call `flare.configure({ enableTracing: false, enableBreadcrumbs: false })`.
82
+
40
83
  ## Logging
41
84
 
42
85
  Beyond errors, the client can send structured logs. Logs are opt-in: enable them with `enableLogs`, then call any of
package/dist/browser.cjs CHANGED
@@ -1,58 +1,71 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_componentProfiler = require('./componentProfiler-C6qY96Bt.cjs');
2
+ const require_catchWindowErrors = require('./catchWindowErrors-zf246a2G.cjs');
3
3
  let _flareapp_core = require("@flareapp/core");
4
4
 
5
5
  //#region src/browser.ts
6
6
  var Flare = class extends _flareapp_core.Flare {
7
- constructor(api = new _flareapp_core.Api(), contextCollector = require_componentProfiler.collectBrowser, fileReader = new require_componentProfiler.FetchFileReader(), scopeProvider = new _flareapp_core.GlobalScopeProvider()) {
8
- super(api, contextCollector, fileReader, scopeProvider, new require_componentProfiler.BrowserFlushScheduler());
7
+ constructor(api = new _flareapp_core.Api(), contextCollector = require_catchWindowErrors.collectBrowser, fileReader = new require_catchWindowErrors.FetchFileReader(), scopeProvider = new _flareapp_core.GlobalScopeProvider()) {
8
+ super(api, contextCollector, fileReader, scopeProvider, new require_catchWindowErrors.BrowserFlushScheduler());
9
9
  this.setSdkInfo({
10
10
  name: "@flareapp/js",
11
- version: require_componentProfiler.CLIENT_VERSION
11
+ version: require_catchWindowErrors.CLIENT_VERSION
12
12
  });
13
13
  this.setFramework({ name: _flareapp_core.FrameworkName.Js });
14
14
  }
15
+ /** Held so a later disable can give the mutation slot back. */
16
+ removeTracingSubscription = null;
17
+ stopBreadcrumbs = null;
15
18
  configure(config) {
16
19
  const wasTracing = this.config.enableTracing;
20
+ const wasBreadcrumbs = this.config.enableBreadcrumbs;
17
21
  super.configure(config);
18
22
  const nowTracing = this.config.enableTracing;
23
+ const nowBreadcrumbs = this.config.enableBreadcrumbs;
24
+ if (!wasBreadcrumbs && nowBreadcrumbs) this.stopBreadcrumbs = require_catchWindowErrors.startBreadcrumbs({
25
+ config: () => this.config,
26
+ record: (type, attributes, startTimeUnixNano) => this.addBreadcrumb(type, attributes, startTimeUnixNano)
27
+ });
28
+ else if (wasBreadcrumbs && !nowBreadcrumbs) {
29
+ this.stopBreadcrumbs?.();
30
+ this.stopBreadcrumbs = null;
31
+ }
19
32
  if (!wasTracing && nowTracing) {
20
- require_componentProfiler.instrumentFetch(this);
21
- require_componentProfiler.instrumentXHR(this);
22
- require_componentProfiler.startBrowserTracing(this);
33
+ this.removeTracingSubscription = require_catchWindowErrors.withRequestPatches(() => require_catchWindowErrors.traceRequests(this, require_catchWindowErrors.browserUrlContext()));
34
+ require_catchWindowErrors.startBrowserTracing(this);
23
35
  } else if (wasTracing && !nowTracing) {
24
- require_componentProfiler.stopBrowserTracing();
25
- require_componentProfiler.unpatchFetch();
26
- require_componentProfiler.unpatchXHR();
36
+ require_catchWindowErrors.stopBrowserTracing();
37
+ this.removeTracingSubscription?.();
38
+ this.removeTracingSubscription = null;
27
39
  }
28
40
  return this;
29
41
  }
30
42
  };
31
43
 
32
44
  //#endregion
33
- exports.BrowserFlushScheduler = require_componentProfiler.BrowserFlushScheduler;
45
+ exports.BrowserFlushScheduler = require_catchWindowErrors.BrowserFlushScheduler;
34
46
  Object.defineProperty(exports, 'BrowserSpanType', {
35
47
  enumerable: true,
36
48
  get: function () {
37
49
  return _flareapp_core.BrowserSpanType;
38
50
  }
39
51
  });
40
- exports.FetchFileReader = require_componentProfiler.FetchFileReader;
52
+ exports.FetchFileReader = require_catchWindowErrors.FetchFileReader;
41
53
  exports.Flare = Flare;
42
- exports.absoluteHref = require_componentProfiler.absoluteHref;
43
- exports.absoluteUrl = require_componentProfiler.absoluteUrl;
44
- exports.activeComponentRoot = require_componentProfiler.activeComponentRoot;
45
- exports.catchWindowErrors = require_componentProfiler.catchWindowErrors;
46
- exports.collectBrowser = require_componentProfiler.collectBrowser;
47
- exports.createFlareResolver = require_componentProfiler.createFlareResolver;
48
- exports.currentPath = require_componentProfiler.currentPath;
49
- exports.instrumentOnce = require_componentProfiler.instrumentOnce;
50
- exports.insulate = require_componentProfiler.insulate;
51
- exports.nowNano = require_componentProfiler.nowNano;
52
- exports.recordComponentSpan = require_componentProfiler.recordComponentSpan;
53
- exports.registerNavigationSource = require_componentProfiler.registerNavigationSource;
54
- exports.reserveSpanId = require_componentProfiler.reserveSpanId;
55
- exports.resolveComponentParent = require_componentProfiler.resolveComponentParent;
56
- exports.resolveHref = require_componentProfiler.resolveHref;
57
- exports.routeName = require_componentProfiler.routeName;
58
- exports.safeInvoke = require_componentProfiler.safeInvoke;
54
+ exports.absoluteHref = require_catchWindowErrors.absoluteHref;
55
+ exports.absoluteUrl = require_catchWindowErrors.absoluteUrl;
56
+ exports.activeComponentRoot = require_catchWindowErrors.activeComponentRoot;
57
+ exports.catchWindowErrors = require_catchWindowErrors.catchWindowErrors;
58
+ exports.collectBrowser = require_catchWindowErrors.collectBrowser;
59
+ exports.createFlareResolver = require_catchWindowErrors.createFlareResolver;
60
+ exports.currentHref = require_catchWindowErrors.currentHref;
61
+ exports.currentPath = require_catchWindowErrors.currentPath;
62
+ exports.instrumentOnce = require_catchWindowErrors.instrumentOnce;
63
+ exports.insulate = require_catchWindowErrors.insulate;
64
+ exports.nowNano = require_catchWindowErrors.nowNano;
65
+ exports.recordComponentSpan = require_catchWindowErrors.recordComponentSpan;
66
+ exports.registerNavigationSource = require_catchWindowErrors.registerNavigationSource;
67
+ exports.reserveSpanId = require_catchWindowErrors.reserveSpanId;
68
+ exports.resolveComponentParent = require_catchWindowErrors.resolveComponentParent;
69
+ exports.resolveHref = require_catchWindowErrors.resolveHref;
70
+ exports.routeName = require_catchWindowErrors.routeName;
71
+ exports.safeInvoke = require_catchWindowErrors.safeInvoke;
@@ -1,10 +1,13 @@
1
- import { C as collectBrowser, S as FetchFileReader, T as createFlareResolver, _ as RouteName, a as nowNano, b as routeName, c as resolveComponentParent, d as TrackTeardown, f as instrumentOnce, g as NavigationSource, h as registerNavigationSource, i as activeComponentRoot, l as absoluteHref, m as safeInvoke, n as ComponentSpanRecord, o as recordComponentSpan, p as insulate, r as ComponentTraceContext, s as reserveSpanId, t as BrowserSpanType, u as absoluteUrl, v as currentPath, w as catchWindowErrors, x as BrowserFlushScheduler, y as resolveHref } from "./spanTypes-iA1RdfLw.cjs";
1
+ import { C as FetchFileReader, E as createFlareResolver, S as BrowserFlushScheduler, T as catchWindowErrors, _ as currentPath, a as nowNano, b as NavigationSource, c as resolveComponentParent, d as insulate, f as safeInvoke, g as currentHref, h as registerNavigationSource, i as activeComponentRoot, l as TrackTeardown, m as absoluteUrl, n as ComponentSpanRecord, o as recordComponentSpan, p as absoluteHref, r as ComponentTraceContext, s as reserveSpanId, t as BrowserSpanType, u as instrumentOnce, v as resolveHref, w as collectBrowser, x as RouteName, y as routeName } from "./spanTypes-TMgJEZ7G.cjs";
2
2
  import { Api, Config, ContextCollector, FileReader, Flare as Flare$1, ScopeProvider } from "@flareapp/core";
3
3
 
4
4
  //#region src/browser.d.ts
5
5
  declare class Flare extends Flare$1 {
6
6
  constructor(api?: Api, contextCollector?: ContextCollector, fileReader?: FileReader, scopeProvider?: ScopeProvider);
7
+ /** Held so a later disable can give the mutation slot back. */
8
+ private removeTracingSubscription;
9
+ private stopBreadcrumbs;
7
10
  configure(config: Partial<Config>): this;
8
11
  }
9
12
  //#endregion
10
- export { BrowserFlushScheduler, BrowserSpanType, type ComponentSpanRecord, type ComponentTraceContext, FetchFileReader, Flare, type NavigationSource, type RouteName, type TrackTeardown, absoluteHref, absoluteUrl, activeComponentRoot, catchWindowErrors, collectBrowser, createFlareResolver, currentPath, instrumentOnce, insulate, nowNano, recordComponentSpan, registerNavigationSource, reserveSpanId, resolveComponentParent, resolveHref, routeName, safeInvoke };
13
+ export { BrowserFlushScheduler, BrowserSpanType, type ComponentSpanRecord, type ComponentTraceContext, FetchFileReader, Flare, type NavigationSource, type RouteName, type TrackTeardown, absoluteHref, absoluteUrl, activeComponentRoot, catchWindowErrors, collectBrowser, createFlareResolver, currentHref, currentPath, instrumentOnce, insulate, nowNano, recordComponentSpan, registerNavigationSource, reserveSpanId, resolveComponentParent, resolveHref, routeName, safeInvoke };
@@ -1,10 +1,13 @@
1
- import { C as collectBrowser, S as FetchFileReader, T as createFlareResolver, _ as RouteName, a as nowNano, b as routeName, c as resolveComponentParent, d as TrackTeardown, f as instrumentOnce, g as NavigationSource, h as registerNavigationSource, i as activeComponentRoot, l as absoluteHref, m as safeInvoke, n as ComponentSpanRecord, o as recordComponentSpan, p as insulate, r as ComponentTraceContext, s as reserveSpanId, t as BrowserSpanType, u as absoluteUrl, v as currentPath, w as catchWindowErrors, x as BrowserFlushScheduler, y as resolveHref } from "./spanTypes-CjF1_Uqi.mjs";
1
+ import { C as FetchFileReader, E as createFlareResolver, S as BrowserFlushScheduler, T as catchWindowErrors, _ as currentPath, a as nowNano, b as NavigationSource, c as resolveComponentParent, d as insulate, f as safeInvoke, g as currentHref, h as registerNavigationSource, i as activeComponentRoot, l as TrackTeardown, m as absoluteUrl, n as ComponentSpanRecord, o as recordComponentSpan, p as absoluteHref, r as ComponentTraceContext, s as reserveSpanId, t as BrowserSpanType, u as instrumentOnce, v as resolveHref, w as collectBrowser, x as RouteName, y as routeName } from "./spanTypes-7-nEycOc.mjs";
2
2
  import { Api, Config, ContextCollector, FileReader, Flare as Flare$1, ScopeProvider } from "@flareapp/core";
3
3
 
4
4
  //#region src/browser.d.ts
5
5
  declare class Flare extends Flare$1 {
6
6
  constructor(api?: Api, contextCollector?: ContextCollector, fileReader?: FileReader, scopeProvider?: ScopeProvider);
7
+ /** Held so a later disable can give the mutation slot back. */
8
+ private removeTracingSubscription;
9
+ private stopBreadcrumbs;
7
10
  configure(config: Partial<Config>): this;
8
11
  }
9
12
  //#endregion
10
- export { BrowserFlushScheduler, BrowserSpanType, type ComponentSpanRecord, type ComponentTraceContext, FetchFileReader, Flare, type NavigationSource, type RouteName, type TrackTeardown, absoluteHref, absoluteUrl, activeComponentRoot, catchWindowErrors, collectBrowser, createFlareResolver, currentPath, instrumentOnce, insulate, nowNano, recordComponentSpan, registerNavigationSource, reserveSpanId, resolveComponentParent, resolveHref, routeName, safeInvoke };
13
+ export { BrowserFlushScheduler, BrowserSpanType, type ComponentSpanRecord, type ComponentTraceContext, FetchFileReader, Flare, type NavigationSource, type RouteName, type TrackTeardown, absoluteHref, absoluteUrl, activeComponentRoot, catchWindowErrors, collectBrowser, createFlareResolver, currentHref, currentPath, instrumentOnce, insulate, nowNano, recordComponentSpan, registerNavigationSource, reserveSpanId, resolveComponentParent, resolveHref, routeName, safeInvoke };
package/dist/browser.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { C as safeInvoke, D as BrowserFlushScheduler, E as collectBrowser, S as insulate, T as FetchFileReader, _ as unpatchXHR, a as resolveComponentParent, b as BrowserSpanType, c as registerNavigationSource, d as currentPath, f as resolveHref, g as instrumentXHR, h as absoluteUrl, i as reserveSpanId, l as startBrowserTracing, m as absoluteHref, n as nowNano, o as catchWindowErrors, p as routeName, r as recordComponentSpan, s as createFlareResolver, t as activeComponentRoot, u as stopBrowserTracing, v as instrumentFetch, w as CLIENT_VERSION, x as instrumentOnce, y as unpatchFetch } from "./componentProfiler-CoH2m13n.mjs";
1
+ import { C as currentHref, D as absoluteHref, E as routeName, O as absoluteUrl, S as registerNavigationSource, T as resolveHref, _ as BrowserFlushScheduler, a as recordComponentSpan, b as browserUrlContext, c as startBrowserTracing, d as instrumentOnce, f as insulate, g as collectBrowser, h as FetchFileReader, i as nowNano, l as stopBrowserTracing, m as CLIENT_VERSION, n as createFlareResolver, o as reserveSpanId, p as safeInvoke, r as activeComponentRoot, s as resolveComponentParent, t as catchWindowErrors, u as BrowserSpanType, v as startBreadcrumbs, w as currentPath, x as withRequestPatches, y as traceRequests } from "./catchWindowErrors-CkFI5Vwv.mjs";
2
2
  import { Api, Flare as Flare$1, FrameworkName, GlobalScopeProvider } from "@flareapp/core";
3
3
 
4
4
  //#region src/browser.ts
@@ -11,22 +11,34 @@ var Flare = class extends Flare$1 {
11
11
  });
12
12
  this.setFramework({ name: FrameworkName.Js });
13
13
  }
14
+ /** Held so a later disable can give the mutation slot back. */
15
+ removeTracingSubscription = null;
16
+ stopBreadcrumbs = null;
14
17
  configure(config) {
15
18
  const wasTracing = this.config.enableTracing;
19
+ const wasBreadcrumbs = this.config.enableBreadcrumbs;
16
20
  super.configure(config);
17
21
  const nowTracing = this.config.enableTracing;
22
+ const nowBreadcrumbs = this.config.enableBreadcrumbs;
23
+ if (!wasBreadcrumbs && nowBreadcrumbs) this.stopBreadcrumbs = startBreadcrumbs({
24
+ config: () => this.config,
25
+ record: (type, attributes, startTimeUnixNano) => this.addBreadcrumb(type, attributes, startTimeUnixNano)
26
+ });
27
+ else if (wasBreadcrumbs && !nowBreadcrumbs) {
28
+ this.stopBreadcrumbs?.();
29
+ this.stopBreadcrumbs = null;
30
+ }
18
31
  if (!wasTracing && nowTracing) {
19
- instrumentFetch(this);
20
- instrumentXHR(this);
32
+ this.removeTracingSubscription = withRequestPatches(() => traceRequests(this, browserUrlContext()));
21
33
  startBrowserTracing(this);
22
34
  } else if (wasTracing && !nowTracing) {
23
35
  stopBrowserTracing();
24
- unpatchFetch();
25
- unpatchXHR();
36
+ this.removeTracingSubscription?.();
37
+ this.removeTracingSubscription = null;
26
38
  }
27
39
  return this;
28
40
  }
29
41
  };
30
42
 
31
43
  //#endregion
32
- export { BrowserFlushScheduler, BrowserSpanType, FetchFileReader, Flare, absoluteHref, absoluteUrl, activeComponentRoot, catchWindowErrors, collectBrowser, createFlareResolver, currentPath, instrumentOnce, insulate, nowNano, recordComponentSpan, registerNavigationSource, reserveSpanId, resolveComponentParent, resolveHref, routeName, safeInvoke };
44
+ export { BrowserFlushScheduler, BrowserSpanType, FetchFileReader, Flare, absoluteHref, absoluteUrl, activeComponentRoot, catchWindowErrors, collectBrowser, createFlareResolver, currentHref, currentPath, instrumentOnce, insulate, nowNano, recordComponentSpan, registerNavigationSource, reserveSpanId, resolveComponentParent, resolveHref, routeName, safeInvoke };