@squasher-ai/browser-logger 0.1.1 → 0.2.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/LICENSE +21 -21
- package/README.md +1 -1
- package/dist/browser-logger.d.ts +2 -2
- package/dist/browser-logger.d.ts.map +1 -1
- package/dist/browser-logger.js +5 -5
- package/dist/browser-logger.umd.js +597 -130
- package/dist/global.d.ts +1 -1
- package/dist/global.d.ts.map +1 -1
- package/dist/global.js +7 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/serializer.d.ts +1 -1
- package/dist/serializer.d.ts.map +1 -1
- package/dist/serializer.js +61 -74
- package/dist/transport.d.ts +21 -4
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +45 -42
- package/package.json +19 -7
package/dist/global.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BrowserLogger, closeBrowserLogger, flushBrowserLogger, getBrowserLogger, initBrowserLogger } from "./index";
|
|
1
|
+
import { BrowserLogger, closeBrowserLogger, flushBrowserLogger, getBrowserLogger, initBrowserLogger } from "./index.js";
|
|
2
2
|
declare const browserLoggerGlobal: {
|
|
3
3
|
BrowserLogger: typeof BrowserLogger;
|
|
4
4
|
close: typeof closeBrowserLogger;
|
package/dist/global.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global.d.ts","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,
|
|
1
|
+
{"version":3,"file":"global.d.ts","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAEpB,QAAA,MAAM,mBAAmB;;;;;;;;;CASxB,CAAC;AASF,eAAe,mBAAmB,CAAC;AACnC,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,GAClB,CAAC"}
|
package/dist/global.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BrowserLogger, closeBrowserLogger, flushBrowserLogger, getBrowserLogger, initBrowserLogger, } from "./index";
|
|
1
|
+
import { BrowserLogger, closeBrowserLogger, flushBrowserLogger, getBrowserLogger, initBrowserLogger, } from "./index.js";
|
|
2
2
|
const browserLoggerGlobal = {
|
|
3
3
|
BrowserLogger,
|
|
4
4
|
close: closeBrowserLogger,
|
|
@@ -9,6 +9,11 @@ const browserLoggerGlobal = {
|
|
|
9
9
|
init: initBrowserLogger,
|
|
10
10
|
initBrowserLogger,
|
|
11
11
|
};
|
|
12
|
-
globalThis
|
|
12
|
+
Object.defineProperty(globalThis, "SquasherBrowserLogger", {
|
|
13
|
+
configurable: true,
|
|
14
|
+
enumerable: true,
|
|
15
|
+
value: browserLoggerGlobal,
|
|
16
|
+
writable: true,
|
|
17
|
+
});
|
|
13
18
|
export default browserLoggerGlobal;
|
|
14
19
|
export { BrowserLogger, closeBrowserLogger, flushBrowserLogger, getBrowserLogger, initBrowserLogger, };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { BrowserLogger } from "./browser-logger";
|
|
2
|
-
export type { BrowserLoggerConfig, BrowserLoggerEvent, IngestBatchPayload, JsonArray, JsonObject, JsonValue, Level, } from "./types";
|
|
3
|
-
import { BrowserLogger } from "./browser-logger";
|
|
4
|
-
import type { BrowserLoggerConfig } from "./types";
|
|
1
|
+
export { BrowserLogger } from "./browser-logger.js";
|
|
2
|
+
export type { BrowserLoggerConfig, BrowserLoggerEvent, IngestBatchPayload, JsonArray, JsonObject, JsonValue, Level, } from "./types.js";
|
|
3
|
+
import { BrowserLogger } from "./browser-logger.js";
|
|
4
|
+
import type { BrowserLoggerConfig } from "./types.js";
|
|
5
5
|
export declare function initBrowserLogger(config: BrowserLoggerConfig): BrowserLogger;
|
|
6
6
|
export declare function getBrowserLogger(): BrowserLogger;
|
|
7
7
|
export declare function flushBrowserLogger(): Promise<void>;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,SAAS,EACT,UAAU,EACV,SAAS,EACT,KAAK,GACN,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAItD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CAO5E;AAED,wBAAgB,gBAAgB,IAAI,aAAa,CAMhD;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAExD;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAQxD;AAED,OAAO,EAAE,kBAAkB,IAAI,KAAK,EAAE,kBAAkB,IAAI,KAAK,EAAE,iBAAiB,IAAI,IAAI,EAAE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { BrowserLogger } from "./browser-logger";
|
|
2
|
-
import { BrowserLogger } from "./browser-logger";
|
|
1
|
+
export { BrowserLogger } from "./browser-logger.js";
|
|
2
|
+
import { BrowserLogger } from "./browser-logger.js";
|
|
3
3
|
let browserLogger = null;
|
|
4
4
|
export function initBrowserLogger(config) {
|
|
5
5
|
if (browserLogger) {
|
package/dist/serializer.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BrowserLoggerEvent, Level } from "./types";
|
|
1
|
+
import type { BrowserLoggerEvent, Level } from "./types.js";
|
|
2
2
|
type ConsoleArgs = Parameters<typeof console.error>;
|
|
3
3
|
export declare function buildConsoleEvent(args: ConsoleArgs, level: Level): BrowserLoggerEvent;
|
|
4
4
|
export {};
|
package/dist/serializer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAyB,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAyB,KAAK,EAAE,MAAM,YAAY,CAAC;AAYnF,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;AAGpD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,GAAG,kBAAkB,CA0BrF"}
|
package/dist/serializer.js
CHANGED
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
const SDK_NAME = "@squasher-ai/browser-logger";
|
|
2
2
|
const SDK_VERSION = "0.1.0";
|
|
3
|
+
const BOOLEAN_TAG = "[object Boolean]";
|
|
4
|
+
const FUNCTION_TAG = "[object Function]";
|
|
5
|
+
const NUMBER_TAG = "[object Number]";
|
|
6
|
+
const STRING_TAG = "[object String]";
|
|
7
|
+
const BIGINT_TAG = "[object BigInt]";
|
|
8
|
+
const SYMBOL_TAG = "[object Symbol]";
|
|
9
|
+
const UNDEFINED_TAG = "[object Undefined]";
|
|
3
10
|
export function buildConsoleEvent(args, level) {
|
|
4
11
|
const error = findError(args);
|
|
5
|
-
const pageUrl =
|
|
6
|
-
const userAgent =
|
|
12
|
+
const pageUrl = globalThis.location?.href;
|
|
13
|
+
const userAgent = globalThis.navigator?.userAgent;
|
|
7
14
|
const extra = {
|
|
8
15
|
console_arguments: Array.from(args, (arg) => toJsonValue(arg)),
|
|
9
16
|
console_method: level === "warning" ? "warn" : "error",
|
|
10
17
|
};
|
|
11
|
-
if (pageUrl)
|
|
18
|
+
if (pageUrl)
|
|
12
19
|
extra.page_url = pageUrl;
|
|
13
|
-
|
|
14
|
-
if (userAgent) {
|
|
20
|
+
if (userAgent)
|
|
15
21
|
extra.user_agent = userAgent;
|
|
16
|
-
}
|
|
17
22
|
return {
|
|
18
23
|
message: buildMessage(args, error),
|
|
19
24
|
type: error?.name,
|
|
@@ -29,120 +34,102 @@ export function buildConsoleEvent(args, level) {
|
|
|
29
34
|
};
|
|
30
35
|
}
|
|
31
36
|
function buildMessage(args, error) {
|
|
32
|
-
if (args.length === 0)
|
|
37
|
+
if (args.length === 0)
|
|
33
38
|
return "console.error";
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (parts.length > 0) {
|
|
39
|
+
const parts = Array.from(args, formatMessagePart).filter((part) => part.length > 0);
|
|
40
|
+
if (parts.length > 0)
|
|
37
41
|
return parts.join(" ");
|
|
38
|
-
|
|
39
|
-
if (error?.message) {
|
|
40
|
-
return error.message;
|
|
41
|
-
}
|
|
42
|
-
return "console.error";
|
|
42
|
+
return error?.message || "console.error";
|
|
43
43
|
}
|
|
44
44
|
function formatMessagePart(value) {
|
|
45
|
-
if (value instanceof Error)
|
|
45
|
+
if (value instanceof Error)
|
|
46
46
|
return value.message || value.name || "Error";
|
|
47
|
-
|
|
48
|
-
if (typeof value === "string") {
|
|
49
|
-
return value;
|
|
50
|
-
}
|
|
51
|
-
if (typeof value === "number" ||
|
|
52
|
-
typeof value === "boolean" ||
|
|
53
|
-
typeof value === "bigint" ||
|
|
54
|
-
typeof value === "symbol") {
|
|
55
|
-
return String(value);
|
|
56
|
-
}
|
|
57
|
-
if (value === null) {
|
|
47
|
+
if (value === null)
|
|
58
48
|
return "null";
|
|
59
|
-
|
|
60
|
-
if (
|
|
49
|
+
const tag = valueTag(value);
|
|
50
|
+
if (tag === UNDEFINED_TAG)
|
|
61
51
|
return "undefined";
|
|
52
|
+
if (tag === STRING_TAG ||
|
|
53
|
+
tag === NUMBER_TAG ||
|
|
54
|
+
tag === BOOLEAN_TAG ||
|
|
55
|
+
tag === BIGINT_TAG ||
|
|
56
|
+
tag === SYMBOL_TAG) {
|
|
57
|
+
return String(value);
|
|
62
58
|
}
|
|
63
59
|
return stringifyJsonValue(toJsonValue(value));
|
|
64
60
|
}
|
|
65
61
|
function findError(args) {
|
|
66
62
|
return Array.from(args).find((arg) => arg instanceof Error);
|
|
67
63
|
}
|
|
68
|
-
function getPageUrl() {
|
|
69
|
-
if (typeof location === "undefined") {
|
|
70
|
-
return undefined;
|
|
71
|
-
}
|
|
72
|
-
return location.href;
|
|
73
|
-
}
|
|
74
|
-
function getUserAgent() {
|
|
75
|
-
if (typeof navigator === "undefined") {
|
|
76
|
-
return undefined;
|
|
77
|
-
}
|
|
78
|
-
return navigator.userAgent;
|
|
79
|
-
}
|
|
80
64
|
function stringifyJsonValue(value) {
|
|
81
|
-
|
|
82
|
-
return value;
|
|
83
|
-
}
|
|
84
|
-
return JSON.stringify(value);
|
|
65
|
+
return valueTag(value) === STRING_TAG ? String(value) : JSON.stringify(value);
|
|
85
66
|
}
|
|
86
67
|
function toJsonValue(value) {
|
|
87
|
-
if (value === null)
|
|
68
|
+
if (value === null)
|
|
88
69
|
return null;
|
|
89
|
-
|
|
90
|
-
if (
|
|
91
|
-
return value;
|
|
92
|
-
}
|
|
93
|
-
if (typeof value === "bigint" || typeof value === "symbol") {
|
|
70
|
+
const tag = valueTag(value);
|
|
71
|
+
if (tag === STRING_TAG)
|
|
94
72
|
return String(value);
|
|
95
|
-
|
|
96
|
-
|
|
73
|
+
if (tag === NUMBER_TAG)
|
|
74
|
+
return Number(value);
|
|
75
|
+
if (tag === BOOLEAN_TAG)
|
|
76
|
+
return Boolean(value);
|
|
77
|
+
if (tag === BIGINT_TAG || tag === SYMBOL_TAG)
|
|
78
|
+
return String(value);
|
|
79
|
+
if (tag === UNDEFINED_TAG)
|
|
97
80
|
return "undefined";
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return `[Function ${value.name || "anonymous"}]`;
|
|
101
|
-
}
|
|
81
|
+
if (tag === FUNCTION_TAG)
|
|
82
|
+
return functionLabel(value);
|
|
102
83
|
if (value instanceof Error) {
|
|
103
84
|
const serializedError = {
|
|
104
85
|
name: value.name,
|
|
105
86
|
message: value.message,
|
|
106
87
|
};
|
|
107
|
-
if (value.stack)
|
|
88
|
+
if (value.stack)
|
|
108
89
|
serializedError.stack = value.stack;
|
|
109
|
-
}
|
|
110
90
|
return serializedError;
|
|
111
91
|
}
|
|
112
|
-
if (Array.isArray(value))
|
|
92
|
+
if (Array.isArray(value))
|
|
113
93
|
return value.map((item) => toJsonValue(item));
|
|
114
|
-
}
|
|
115
94
|
return serializeObject(value);
|
|
116
95
|
}
|
|
117
96
|
function serializeObject(value) {
|
|
118
97
|
const seen = new WeakSet();
|
|
119
98
|
const json = JSON.stringify(value, (_key, nestedValue) => {
|
|
120
|
-
|
|
99
|
+
const tag = valueTag(nestedValue);
|
|
100
|
+
if (tag === BIGINT_TAG || tag === SYMBOL_TAG)
|
|
121
101
|
return String(nestedValue);
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
return `[Function ${nestedValue.name || "anonymous"}]`;
|
|
125
|
-
}
|
|
102
|
+
if (tag === FUNCTION_TAG)
|
|
103
|
+
return functionLabel(nestedValue);
|
|
126
104
|
if (nestedValue instanceof Error) {
|
|
127
105
|
const serializedError = {
|
|
128
106
|
name: nestedValue.name,
|
|
129
107
|
message: nestedValue.message,
|
|
130
108
|
};
|
|
131
|
-
if (nestedValue.stack)
|
|
109
|
+
if (nestedValue.stack)
|
|
132
110
|
serializedError.stack = nestedValue.stack;
|
|
133
|
-
}
|
|
134
111
|
return serializedError;
|
|
135
112
|
}
|
|
136
|
-
if (
|
|
137
|
-
if (seen.has(nestedValue))
|
|
113
|
+
if (isReferenceTag(tag) && nestedValue !== null) {
|
|
114
|
+
if (seen.has(nestedValue))
|
|
138
115
|
return "[Circular]";
|
|
139
|
-
}
|
|
140
116
|
seen.add(nestedValue);
|
|
141
117
|
}
|
|
142
118
|
return nestedValue;
|
|
143
119
|
});
|
|
144
|
-
if (!json)
|
|
120
|
+
if (!json)
|
|
145
121
|
return String(value);
|
|
146
|
-
|
|
147
|
-
return
|
|
122
|
+
const parsed = JSON.parse(json);
|
|
123
|
+
return parsed;
|
|
124
|
+
}
|
|
125
|
+
function valueTag(value) {
|
|
126
|
+
return Object.prototype.toString.call(value);
|
|
127
|
+
}
|
|
128
|
+
function isReferenceTag(tag) {
|
|
129
|
+
return ![BIGINT_TAG, BOOLEAN_TAG, NUMBER_TAG, STRING_TAG, SYMBOL_TAG, UNDEFINED_TAG].includes(tag);
|
|
130
|
+
}
|
|
131
|
+
function functionLabel(value) {
|
|
132
|
+
const source = String(value);
|
|
133
|
+
const match = source.match(/^(?:async\s+)?function\s*([^\s(]*)/);
|
|
134
|
+
return `[Function ${match?.[1] || "anonymous"}]`;
|
|
148
135
|
}
|
package/dist/transport.d.ts
CHANGED
|
@@ -1,19 +1,36 @@
|
|
|
1
|
-
import type { BrowserLoggerEvent } from "./types";
|
|
1
|
+
import type { BrowserLoggerEvent } from "./types.js";
|
|
2
2
|
export interface BrowserLoggerTransportConfig {
|
|
3
3
|
apiKey: string;
|
|
4
4
|
projectId: string;
|
|
5
5
|
endpoint?: string;
|
|
6
6
|
}
|
|
7
|
+
export interface BrowserLifecycleTarget {
|
|
8
|
+
addEventListener(name: string, listener: () => void): void;
|
|
9
|
+
removeEventListener(name: string, listener: () => void): void;
|
|
10
|
+
}
|
|
11
|
+
export interface BrowserDocumentTarget extends BrowserLifecycleTarget {
|
|
12
|
+
visibilityState: string;
|
|
13
|
+
}
|
|
14
|
+
export interface BrowserNavigatorTarget {
|
|
15
|
+
sendBeacon?: (url: string, data?: BodyInit | null) => boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface BrowserLoggerRuntime {
|
|
18
|
+
document?: BrowserDocumentTarget;
|
|
19
|
+
fetcher: typeof fetch;
|
|
20
|
+
navigator?: BrowserNavigatorTarget;
|
|
21
|
+
window?: BrowserLifecycleTarget;
|
|
22
|
+
}
|
|
7
23
|
export declare class BrowserLoggerTransport {
|
|
24
|
+
private readonly runtime;
|
|
8
25
|
private readonly apiKey;
|
|
9
26
|
private readonly projectId;
|
|
10
27
|
private readonly endpoint;
|
|
11
|
-
|
|
12
|
-
|
|
28
|
+
protected readonly queue: BrowserLoggerEvent[];
|
|
29
|
+
protected flushTimer: ReturnType<typeof setInterval> | null;
|
|
13
30
|
private closed;
|
|
14
31
|
private readonly handlePageHide;
|
|
15
32
|
private readonly handleVisibilityChange;
|
|
16
|
-
constructor(config: BrowserLoggerTransportConfig);
|
|
33
|
+
constructor(config: BrowserLoggerTransportConfig, runtime?: BrowserLoggerRuntime);
|
|
17
34
|
enqueue(event: BrowserLoggerEvent): void;
|
|
18
35
|
flush(): Promise<void>;
|
|
19
36
|
close(): Promise<void>;
|
package/dist/transport.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAsB,MAAM,
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAsB,MAAM,YAAY,CAAC;AAOzE,MAAM,WAAW,4BAA4B;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC3D,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CAC/D;AAED,MAAM,WAAW,qBAAsB,SAAQ,sBAAsB;IACnE,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,KAAK,OAAO,CAAC;CAC/D;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,OAAO,EAAE,OAAO,KAAK,CAAC;IACtB,SAAS,CAAC,EAAE,sBAAsB,CAAC;IACnC,MAAM,CAAC,EAAE,sBAAsB,CAAC;CACjC;AAED,qBAAa,sBAAsB;IAoB/B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAnB1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,EAAE,CAAM;IACpD,SAAS,CAAC,UAAU,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,GAAG,IAAI,CAAQ;IACnE,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAE7B;IAEF,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAIrC;gBAGA,MAAM,EAAE,4BAA4B,EACnB,OAAO,GAAE,oBAAoD;IAahF,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAWlC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IActB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB5B,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,aAAa;YAaP,SAAS;IAmBvB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,YAAY;CAGrB"}
|
package/dist/transport.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { attempt, attemptAsync } from "@squasher-ai/result-utils";
|
|
2
|
+
import { DEFAULT_INGEST_ENDPOINT } from "@squasher-ai/sdk-core";
|
|
2
3
|
const DEFAULT_BATCH_SIZE = 10;
|
|
3
4
|
const DEFAULT_FLUSH_INTERVAL_MS = 5_000;
|
|
4
5
|
export class BrowserLoggerTransport {
|
|
6
|
+
runtime;
|
|
5
7
|
apiKey;
|
|
6
8
|
projectId;
|
|
7
9
|
endpoint;
|
|
@@ -12,14 +14,15 @@ export class BrowserLoggerTransport {
|
|
|
12
14
|
this.flushOnPageHide();
|
|
13
15
|
};
|
|
14
16
|
handleVisibilityChange = () => {
|
|
15
|
-
if (
|
|
17
|
+
if (this.runtime.document?.visibilityState === "hidden") {
|
|
16
18
|
this.flushOnPageHide();
|
|
17
19
|
}
|
|
18
20
|
};
|
|
19
|
-
constructor(config) {
|
|
21
|
+
constructor(config, runtime = defaultBrowserLoggerRuntime()) {
|
|
22
|
+
this.runtime = runtime;
|
|
20
23
|
this.apiKey = config.apiKey;
|
|
21
24
|
this.projectId = config.projectId;
|
|
22
|
-
this.endpoint = normalizeEndpoint(config.endpoint ??
|
|
25
|
+
this.endpoint = normalizeEndpoint(config.endpoint ?? DEFAULT_INGEST_ENDPOINT);
|
|
23
26
|
this.flushTimer = setInterval(() => {
|
|
24
27
|
void this.flush();
|
|
25
28
|
}, DEFAULT_FLUSH_INTERVAL_MS);
|
|
@@ -73,51 +76,43 @@ export class BrowserLoggerTransport {
|
|
|
73
76
|
});
|
|
74
77
|
}
|
|
75
78
|
installListeners() {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (typeof window !== "undefined") {
|
|
80
|
-
window.addEventListener("pagehide", this.handlePageHide);
|
|
81
|
-
window.addEventListener("beforeunload", this.handlePageHide);
|
|
82
|
-
}
|
|
79
|
+
this.runtime.document?.addEventListener("visibilitychange", this.handleVisibilityChange);
|
|
80
|
+
this.runtime.window?.addEventListener("pagehide", this.handlePageHide);
|
|
81
|
+
this.runtime.window?.addEventListener("beforeunload", this.handlePageHide);
|
|
83
82
|
}
|
|
84
83
|
removeListeners() {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (typeof window !== "undefined") {
|
|
89
|
-
window.removeEventListener("pagehide", this.handlePageHide);
|
|
90
|
-
window.removeEventListener("beforeunload", this.handlePageHide);
|
|
91
|
-
}
|
|
84
|
+
this.runtime.document?.removeEventListener("visibilitychange", this.handleVisibilityChange);
|
|
85
|
+
this.runtime.window?.removeEventListener("pagehide", this.handlePageHide);
|
|
86
|
+
this.runtime.window?.removeEventListener("beforeunload", this.handlePageHide);
|
|
92
87
|
}
|
|
93
88
|
trySendBeacon(body) {
|
|
94
|
-
|
|
89
|
+
const sendBeacon = this.runtime.navigator?.sendBeacon;
|
|
90
|
+
if (!sendBeacon)
|
|
95
91
|
return false;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
92
|
+
return attempt({
|
|
93
|
+
try: () => {
|
|
94
|
+
const blob = new Blob([body], { type: "application/json" });
|
|
95
|
+
return sendBeacon.call(this.runtime.navigator, this.getBeaconUrl(), blob);
|
|
96
|
+
},
|
|
97
|
+
catch: () => false,
|
|
98
|
+
});
|
|
104
99
|
}
|
|
105
100
|
async sendFetch(body) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
101
|
+
return attemptAsync({
|
|
102
|
+
try: async () => {
|
|
103
|
+
const response = await this.runtime.fetcher(this.getIngestUrl(), {
|
|
104
|
+
method: "POST",
|
|
105
|
+
headers: {
|
|
106
|
+
"Content-Type": "application/json",
|
|
107
|
+
"x-squasher-key": this.apiKey,
|
|
108
|
+
},
|
|
109
|
+
body,
|
|
110
|
+
keepalive: true,
|
|
111
|
+
});
|
|
112
|
+
return response.ok;
|
|
113
|
+
},
|
|
114
|
+
catch: () => false,
|
|
115
|
+
});
|
|
121
116
|
}
|
|
122
117
|
getIngestUrl() {
|
|
123
118
|
return `${this.endpoint}/v1/ingest/${this.projectId}`;
|
|
@@ -126,6 +121,14 @@ export class BrowserLoggerTransport {
|
|
|
126
121
|
return `${this.getIngestUrl()}?key=${encodeURIComponent(this.apiKey)}`;
|
|
127
122
|
}
|
|
128
123
|
}
|
|
124
|
+
function defaultBrowserLoggerRuntime() {
|
|
125
|
+
return {
|
|
126
|
+
document: globalThis.document,
|
|
127
|
+
fetcher: (...args) => fetch(...args),
|
|
128
|
+
navigator: globalThis.navigator,
|
|
129
|
+
window: globalThis.window,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
129
132
|
function normalizeEndpoint(endpoint) {
|
|
130
133
|
return endpoint.replace(/\/+$/, "");
|
|
131
134
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@squasher-ai/browser-logger",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Squasher browser console transport",
|
|
5
|
-
"homepage": "https://
|
|
5
|
+
"homepage": "https://squasher.ai",
|
|
6
6
|
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/squasher-ai/squasher.git",
|
|
10
|
+
"directory": "packages/public/browser-logger"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/squasher-ai/squasher/issues"
|
|
14
|
+
},
|
|
7
15
|
"publishConfig": {
|
|
8
16
|
"access": "public"
|
|
9
17
|
},
|
|
@@ -17,11 +25,15 @@
|
|
|
17
25
|
}
|
|
18
26
|
},
|
|
19
27
|
"keywords": [
|
|
20
|
-
"squasher",
|
|
21
28
|
"browser",
|
|
22
|
-
"logger",
|
|
23
29
|
"console",
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
|
|
30
|
+
"error-monitoring",
|
|
31
|
+
"logger",
|
|
32
|
+
"squasher",
|
|
33
|
+
"transport"
|
|
34
|
+
],
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@squasher-ai/result-utils": "0.2.0",
|
|
37
|
+
"@squasher-ai/sdk-core": "0.2.0"
|
|
38
|
+
}
|
|
27
39
|
}
|