@flareapp/js 2.2.1 → 2.3.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
@@ -1,7 +1,8 @@
1
1
  # @flareapp/js
2
2
 
3
- The core JavaScript/TypeScript client for [Flare](https://flareapp.io) error tracking. Captures frontend errors, parses
4
- stack traces, collects browser context, and reports everything to the Flare backend.
3
+ The core JavaScript/TypeScript client for [Flare](https://flareapp.io) error tracking and logging. Captures frontend
4
+ errors, parses stack traces, collects browser context, sends structured logs, and reports everything to the Flare
5
+ backend.
5
6
 
6
7
  ## Installation
7
8
 
@@ -20,6 +21,20 @@ flare.light('YOUR_FLARE_API_KEY');
20
21
  That is all you need. The client automatically listens for uncaught exceptions and unhandled promise rejections,
21
22
  collects browser context, and sends error reports to Flare.
22
23
 
24
+ ## Logging
25
+
26
+ Beyond errors, the client can send structured logs. Logs are opt-in: enable them with `enableLogs`, then call any of
27
+ the eight syslog levels (`debug`, `info`, `notice`, `warning`, `error`, `critical`, `alert`, `emergency`).
28
+
29
+ ```js
30
+ flare.configure({ enableLogs: true });
31
+
32
+ flare.logger.info('Checkout started', { cartId: cart.id, total: cart.total });
33
+ ```
34
+
35
+ Logs are buffered and batched, and flushed when the tab is hidden so buffered logs survive a page unload. The optional
36
+ second argument is structured, searchable attributes.
37
+
23
38
  ## Documentation
24
39
 
25
40
  Full documentation on configuration, hooks, context, breadcrumbs, solution providers, and more is available
package/dist/index.cjs CHANGED
@@ -43,6 +43,17 @@ function hasStack(value) {
43
43
  return typeof value === "object" && value !== null && "stack" in value && typeof value.stack === "string";
44
44
  }
45
45
 
46
+ //#endregion
47
+ //#region src/browser/BrowserFlushScheduler.ts
48
+ var BrowserFlushScheduler = class {
49
+ register(flush) {
50
+ if (typeof document === "undefined" || !document) return;
51
+ document.addEventListener("visibilitychange", () => {
52
+ if (document.visibilityState === "hidden") flush({ keepalive: true });
53
+ });
54
+ }
55
+ };
56
+
46
57
  //#endregion
47
58
  //#region src/browser/context/cookie.ts
48
59
  function cookie() {
@@ -90,6 +101,7 @@ const collectBrowser = (config) => {
90
101
  attrs["flare.entry_point.handler.type"] = "browser";
91
102
  }
92
103
  }
104
+ if (window?.location?.hostname) attrs["host.name"] = window.location.hostname;
93
105
  Object.assign(attrs, request(config.urlDenylist));
94
106
  Object.assign(attrs, requestData(config.urlDenylist));
95
107
  Object.assign(attrs, cookie());
@@ -134,13 +146,13 @@ var FetchFileReader = class {
134
146
 
135
147
  //#endregion
136
148
  //#region src/env/index.ts
137
- const CLIENT_VERSION = typeof process !== "undefined" && true ? "2.2.1" : "?";
149
+ const CLIENT_VERSION = typeof process !== "undefined" && true ? "2.3.0" : "?";
138
150
 
139
151
  //#endregion
140
152
  //#region src/index.ts
141
153
  var Flare = class extends _flareapp_core.Flare {
142
154
  constructor(api = new _flareapp_core.Api(), contextCollector = collectBrowser, fileReader = new FetchFileReader(), scopeProvider = new _flareapp_core.GlobalScopeProvider()) {
143
- super(api, contextCollector, fileReader, scopeProvider);
155
+ super(api, contextCollector, fileReader, scopeProvider, new BrowserFlushScheduler());
144
156
  this.setSdkInfo({
145
157
  name: "@flareapp/js",
146
158
  version: CLIENT_VERSION
@@ -167,6 +179,12 @@ Object.defineProperty(exports, 'GlobalScopeProvider', {
167
179
  return _flareapp_core.GlobalScopeProvider;
168
180
  }
169
181
  });
182
+ Object.defineProperty(exports, 'Logger', {
183
+ enumerable: true,
184
+ get: function () {
185
+ return _flareapp_core.Logger;
186
+ }
187
+ });
170
188
  Object.defineProperty(exports, 'NullFileReader', {
171
189
  enumerable: true,
172
190
  get: function () {
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { Api, AttributeValue, Attributes, Config, ContextCollector, ContextCollector as ContextCollector$1, DEFAULT_URL_DENYLIST, EntryPointHandler, FileReader, FileReader as FileReader$1, Flare as Flare$1, Framework, GlobalScopeProvider, Glow, MessageLevel, NullFileReader, OverriddenGrouping, Report, Scope, ScopeProvider, ScopeProvider as ScopeProvider$1, SdkInfo, SpanEvent, StackFrame, convertToError, redactUrlQuery, redactUrlQuery as redactFullPath, resolveDenylist } from "@flareapp/core";
1
+ import { Api, AttributeValue, Attributes, Config, ContextCollector, ContextCollector as ContextCollector$1, DEFAULT_URL_DENYLIST, EntryPointHandler, FileReader, FileReader as FileReader$1, Flare as Flare$1, FlushFn, FlushScheduler, Framework, GlobalScopeProvider, Glow, Logger, MessageLevel, NullFileReader, OverriddenGrouping, Report, Scope, ScopeProvider, ScopeProvider as ScopeProvider$1, SdkInfo, SpanEvent, StackFrame, convertToError, redactUrlQuery, redactUrlQuery as redactFullPath, resolveDenylist } from "@flareapp/core";
2
2
 
3
3
  //#region src/index.d.ts
4
4
  declare class Flare extends Flare$1 {
@@ -6,4 +6,4 @@ declare class Flare extends Flare$1 {
6
6
  }
7
7
  declare const flare: Flare;
8
8
  //#endregion
9
- export { type AttributeValue, type Attributes, type Config, type ContextCollector, DEFAULT_URL_DENYLIST, type EntryPointHandler, type FileReader, Flare, type Framework, GlobalScopeProvider, type Glow, type MessageLevel, NullFileReader, type OverriddenGrouping, type Report, Scope, type ScopeProvider, type SdkInfo, type SpanEvent, type StackFrame, convertToError, flare, redactFullPath, redactUrlQuery, resolveDenylist };
9
+ export { type AttributeValue, type Attributes, type Config, type ContextCollector, DEFAULT_URL_DENYLIST, type EntryPointHandler, type FileReader, Flare, type FlushFn, type FlushScheduler, type Framework, GlobalScopeProvider, type Glow, Logger, type MessageLevel, NullFileReader, type OverriddenGrouping, type Report, Scope, type ScopeProvider, type SdkInfo, type SpanEvent, type StackFrame, convertToError, flare, redactFullPath, redactUrlQuery, resolveDenylist };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { Api, AttributeValue, Attributes, Config, ContextCollector, ContextCollector as ContextCollector$1, DEFAULT_URL_DENYLIST, EntryPointHandler, FileReader, FileReader as FileReader$1, Flare as Flare$1, Framework, GlobalScopeProvider, Glow, MessageLevel, NullFileReader, OverriddenGrouping, Report, Scope, ScopeProvider, ScopeProvider as ScopeProvider$1, SdkInfo, SpanEvent, StackFrame, convertToError, redactUrlQuery, redactUrlQuery as redactFullPath, resolveDenylist } from "@flareapp/core";
1
+ import { Api, AttributeValue, Attributes, Config, ContextCollector, ContextCollector as ContextCollector$1, DEFAULT_URL_DENYLIST, EntryPointHandler, FileReader, FileReader as FileReader$1, Flare as Flare$1, FlushFn, FlushScheduler, Framework, GlobalScopeProvider, Glow, Logger, MessageLevel, NullFileReader, OverriddenGrouping, Report, Scope, ScopeProvider, ScopeProvider as ScopeProvider$1, SdkInfo, SpanEvent, StackFrame, convertToError, redactUrlQuery, redactUrlQuery as redactFullPath, resolveDenylist } from "@flareapp/core";
2
2
 
3
3
  //#region src/index.d.ts
4
4
  declare class Flare extends Flare$1 {
@@ -6,4 +6,4 @@ declare class Flare extends Flare$1 {
6
6
  }
7
7
  declare const flare: Flare;
8
8
  //#endregion
9
- export { type AttributeValue, type Attributes, type Config, type ContextCollector, DEFAULT_URL_DENYLIST, type EntryPointHandler, type FileReader, Flare, type Framework, GlobalScopeProvider, type Glow, type MessageLevel, NullFileReader, type OverriddenGrouping, type Report, Scope, type ScopeProvider, type SdkInfo, type SpanEvent, type StackFrame, convertToError, flare, redactFullPath, redactUrlQuery, resolveDenylist };
9
+ export { type AttributeValue, type Attributes, type Config, type ContextCollector, DEFAULT_URL_DENYLIST, type EntryPointHandler, type FileReader, Flare, type FlushFn, type FlushScheduler, type Framework, GlobalScopeProvider, type Glow, Logger, type MessageLevel, NullFileReader, type OverriddenGrouping, type Report, Scope, type ScopeProvider, type SdkInfo, type SpanEvent, type StackFrame, convertToError, flare, redactFullPath, redactUrlQuery, resolveDenylist };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { Api, DEFAULT_URL_DENYLIST, Flare as Flare$1, GlobalScopeProvider, GlobalScopeProvider as GlobalScopeProvider$1, NullFileReader, Scope, convertToError, redactUrlQuery, redactUrlQuery as redactFullPath, redactUrlQuery as redactUrlQuery$1, resolveDenylist } from "@flareapp/core";
1
+ import { Api, DEFAULT_URL_DENYLIST, Flare as Flare$1, GlobalScopeProvider, GlobalScopeProvider as GlobalScopeProvider$1, Logger, NullFileReader, Scope, convertToError, redactUrlQuery, redactUrlQuery as redactFullPath, redactUrlQuery as redactUrlQuery$1, resolveDenylist } from "@flareapp/core";
2
2
 
3
3
  //#region src/browser/catchWindowErrors.ts
4
4
  function catchWindowErrors() {
@@ -42,6 +42,17 @@ function hasStack(value) {
42
42
  return typeof value === "object" && value !== null && "stack" in value && typeof value.stack === "string";
43
43
  }
44
44
 
45
+ //#endregion
46
+ //#region src/browser/BrowserFlushScheduler.ts
47
+ var BrowserFlushScheduler = class {
48
+ register(flush) {
49
+ if (typeof document === "undefined" || !document) return;
50
+ document.addEventListener("visibilitychange", () => {
51
+ if (document.visibilityState === "hidden") flush({ keepalive: true });
52
+ });
53
+ }
54
+ };
55
+
45
56
  //#endregion
46
57
  //#region src/browser/context/cookie.ts
47
58
  function cookie() {
@@ -89,6 +100,7 @@ const collectBrowser = (config) => {
89
100
  attrs["flare.entry_point.handler.type"] = "browser";
90
101
  }
91
102
  }
103
+ if (window?.location?.hostname) attrs["host.name"] = window.location.hostname;
92
104
  Object.assign(attrs, request(config.urlDenylist));
93
105
  Object.assign(attrs, requestData(config.urlDenylist));
94
106
  Object.assign(attrs, cookie());
@@ -133,13 +145,13 @@ var FetchFileReader = class {
133
145
 
134
146
  //#endregion
135
147
  //#region src/env/index.ts
136
- const CLIENT_VERSION = typeof process !== "undefined" && true ? "2.2.1" : "?";
148
+ const CLIENT_VERSION = typeof process !== "undefined" && true ? "2.3.0" : "?";
137
149
 
138
150
  //#endregion
139
151
  //#region src/index.ts
140
152
  var Flare = class extends Flare$1 {
141
153
  constructor(api = new Api(), contextCollector = collectBrowser, fileReader = new FetchFileReader(), scopeProvider = new GlobalScopeProvider$1()) {
142
- super(api, contextCollector, fileReader, scopeProvider);
154
+ super(api, contextCollector, fileReader, scopeProvider, new BrowserFlushScheduler());
143
155
  this.setSdkInfo({
144
156
  name: "@flareapp/js",
145
157
  version: CLIENT_VERSION
@@ -153,4 +165,4 @@ if (typeof window !== "undefined" && window) {
153
165
  }
154
166
 
155
167
  //#endregion
156
- export { DEFAULT_URL_DENYLIST, Flare, GlobalScopeProvider, NullFileReader, Scope, convertToError, flare, redactFullPath, redactUrlQuery, resolveDenylist };
168
+ export { DEFAULT_URL_DENYLIST, Flare, GlobalScopeProvider, Logger, NullFileReader, Scope, convertToError, flare, redactFullPath, redactUrlQuery, resolveDenylist };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flareapp/js",
3
- "version": "2.2.1",
3
+ "version": "2.3.0",
4
4
  "description": "JavaScript client for flareapp.io",
5
5
  "homepage": "https://flareapp.io",
6
6
  "bugs": {
@@ -49,7 +49,7 @@
49
49
  "release": "release-it"
50
50
  },
51
51
  "dependencies": {
52
- "@flareapp/core": "2.2.1"
52
+ "@flareapp/core": "2.3.0"
53
53
  },
54
54
  "devDependencies": {
55
55
  "error-stack-parser": "^2.0.2",