@bazariodev/docket 0.0.0-stage → 1.0.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/CHANGELOG.md +37 -0
- package/LICENSE +21 -0
- package/README.md +985 -2
- package/dist/browser/constants.d.cts +14 -0
- package/dist/browser/constants.d.ts +14 -0
- package/dist/browser/index.cjs +192 -0
- package/dist/browser/index.cjs.map +1 -0
- package/dist/browser/index.d.cts +29 -0
- package/dist/browser/index.d.ts +29 -0
- package/dist/browser/index.js +187 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/chunk-7ld72rnl.js +376 -0
- package/dist/chunk-7ld72rnl.js.map +1 -0
- package/dist/chunk-BLf-eCDO.cjs +53 -0
- package/dist/chunk-BLf-eCDO.cjs.map +1 -0
- package/dist/chunk-CEhpwtwJ.cjs +379 -0
- package/dist/chunk-CEhpwtwJ.cjs.map +1 -0
- package/dist/chunk-CSS3f4_M.js +46 -0
- package/dist/chunk-CSS3f4_M.js.map +1 -0
- package/dist/chunk-CXZYNALm.cjs +124 -0
- package/dist/chunk-CXZYNALm.cjs.map +1 -0
- package/dist/chunk-DYcNnkOV.js +50 -0
- package/dist/chunk-DYcNnkOV.js.map +1 -0
- package/dist/chunk-DkvWLziD.js +437 -0
- package/dist/chunk-DkvWLziD.js.map +1 -0
- package/dist/chunk-DqK_3eFr.cjs +53 -0
- package/dist/chunk-DqK_3eFr.cjs.map +1 -0
- package/dist/chunk-LRCHwVuE.js +110 -0
- package/dist/chunk-LRCHwVuE.js.map +1 -0
- package/dist/chunk-ieB8yTEn.cjs +439 -0
- package/dist/chunk-ieB8yTEn.cjs.map +1 -0
- package/dist/client/index.cjs +167 -0
- package/dist/client/index.cjs.map +1 -0
- package/dist/client/index.d.cts +40 -0
- package/dist/client/index.d.ts +40 -0
- package/dist/client/index.js +165 -0
- package/dist/client/index.js.map +1 -0
- package/dist/constants.d.cts +4 -0
- package/dist/constants.d.ts +4 -0
- package/dist/core/constants.d.cts +43 -0
- package/dist/core/constants.d.ts +43 -0
- package/dist/devtools/index.cjs +37 -0
- package/dist/devtools/index.cjs.map +1 -0
- package/dist/devtools/index.d.cts +11 -0
- package/dist/devtools/index.d.ts +11 -0
- package/dist/devtools/index.js +35 -0
- package/dist/devtools/index.js.map +1 -0
- package/dist/export/index.cjs +139 -0
- package/dist/export/index.cjs.map +1 -0
- package/dist/export/index.d.cts +49 -0
- package/dist/export/index.d.ts +49 -0
- package/dist/export/index.js +137 -0
- package/dist/export/index.js.map +1 -0
- package/dist/history/index.cjs +30 -0
- package/dist/history/index.cjs.map +1 -0
- package/dist/history/index.d.cts +11 -0
- package/dist/history/index.d.ts +11 -0
- package/dist/history/index.js +28 -0
- package/dist/history/index.js.map +1 -0
- package/dist/index.cjs +14 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +159 -0
- package/dist/index.d.ts +159 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/indexeddb/index.cjs +26 -0
- package/dist/indexeddb/index.cjs.map +1 -0
- package/dist/indexeddb/index.d.cts +61 -0
- package/dist/indexeddb/index.d.ts +61 -0
- package/dist/indexeddb/index.js +23 -0
- package/dist/indexeddb/index.js.map +1 -0
- package/dist/redaction/index.cjs +154 -0
- package/dist/redaction/index.cjs.map +1 -0
- package/dist/redaction/index.d.cts +70 -0
- package/dist/redaction/index.d.ts +70 -0
- package/dist/redaction/index.js +152 -0
- package/dist/redaction/index.js.map +1 -0
- package/dist/sip/index.cjs +336 -0
- package/dist/sip/index.cjs.map +1 -0
- package/dist/sip/index.d.cts +34 -0
- package/dist/sip/index.d.ts +34 -0
- package/dist/sip/index.js +333 -0
- package/dist/sip/index.js.map +1 -0
- package/dist/storage/constants.d.cts +11 -0
- package/dist/storage/constants.d.ts +11 -0
- package/dist/storage/contracts.d.cts +31 -0
- package/dist/storage/contracts.d.ts +31 -0
- package/dist/upload/constants.d.cts +17 -0
- package/dist/upload/constants.d.ts +17 -0
- package/dist/upload/index.cjs +246 -0
- package/dist/upload/index.cjs.map +1 -0
- package/dist/upload/index.d.cts +51 -0
- package/dist/upload/index.d.ts +51 -0
- package/dist/upload/index.js +244 -0
- package/dist/upload/index.js.map +1 -0
- package/package.json +150 -3
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const ENVIRONMENT_FIELDS: Readonly<{
|
|
2
|
+
LANGUAGE: "language";
|
|
3
|
+
UTC_OFFSET_MINUTES: "utcOffsetMinutes";
|
|
4
|
+
DISPLAY_MODE: "displayMode";
|
|
5
|
+
ONLINE: "online";
|
|
6
|
+
USER_AGENT: "userAgent";
|
|
7
|
+
CLIENT_HINTS: "clientHints";
|
|
8
|
+
TIME_ZONE: "timeZone";
|
|
9
|
+
CONNECTION: "connection";
|
|
10
|
+
PERMISSIONS: "permissions";
|
|
11
|
+
DEVICE_COUNTS: "deviceCounts";
|
|
12
|
+
STORAGE: "storage";
|
|
13
|
+
SCREEN: "screen";
|
|
14
|
+
}>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const ENVIRONMENT_FIELDS: Readonly<{
|
|
2
|
+
LANGUAGE: "language";
|
|
3
|
+
UTC_OFFSET_MINUTES: "utcOffsetMinutes";
|
|
4
|
+
DISPLAY_MODE: "displayMode";
|
|
5
|
+
ONLINE: "online";
|
|
6
|
+
USER_AGENT: "userAgent";
|
|
7
|
+
CLIENT_HINTS: "clientHints";
|
|
8
|
+
TIME_ZONE: "timeZone";
|
|
9
|
+
CONNECTION: "connection";
|
|
10
|
+
PERMISSIONS: "permissions";
|
|
11
|
+
DEVICE_COUNTS: "deviceCounts";
|
|
12
|
+
STORAGE: "storage";
|
|
13
|
+
SCREEN: "screen";
|
|
14
|
+
}>;
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var common = require('../chunk-CXZYNALm.cjs');
|
|
4
|
+
require('../chunk-BLf-eCDO.cjs');
|
|
5
|
+
|
|
6
|
+
const ENVIRONMENT_FIELDS = /* @__PURE__ */ Object.freeze({
|
|
7
|
+
LANGUAGE: 'language',
|
|
8
|
+
UTC_OFFSET_MINUTES: 'utcOffsetMinutes',
|
|
9
|
+
DISPLAY_MODE: 'displayMode',
|
|
10
|
+
ONLINE: 'online',
|
|
11
|
+
USER_AGENT: 'userAgent',
|
|
12
|
+
CLIENT_HINTS: 'clientHints',
|
|
13
|
+
TIME_ZONE: 'timeZone',
|
|
14
|
+
CONNECTION: 'connection',
|
|
15
|
+
PERMISSIONS: 'permissions',
|
|
16
|
+
DEVICE_COUNTS: 'deviceCounts',
|
|
17
|
+
STORAGE: 'storage',
|
|
18
|
+
SCREEN: 'screen',
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const environmentFields = new Set(Object.values(ENVIRONMENT_FIELDS));
|
|
22
|
+
|
|
23
|
+
function captureGlobalErrors(
|
|
24
|
+
logger,
|
|
25
|
+
{ target = globalThis.window } = {},
|
|
26
|
+
) {
|
|
27
|
+
const onError = (event) =>
|
|
28
|
+
logger.error('browser.error', event.error ?? { message: event.message });
|
|
29
|
+
const onRejection = (event) =>
|
|
30
|
+
logger.error('browser.unhandledrejection', event.reason);
|
|
31
|
+
target?.addEventListener('error', onError);
|
|
32
|
+
target?.addEventListener('unhandledrejection', onRejection);
|
|
33
|
+
return () => {
|
|
34
|
+
target?.removeEventListener('error', onError);
|
|
35
|
+
target?.removeEventListener('unhandledrejection', onRejection);
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function flushOnPageHide(logging, options = {}) {
|
|
40
|
+
const window = options.window ?? globalThis.window;
|
|
41
|
+
const document = options.document ?? globalThis.document;
|
|
42
|
+
const flush = () => {
|
|
43
|
+
Promise.resolve()
|
|
44
|
+
.then(() => logging.flush())
|
|
45
|
+
.catch((error) => common.report(options.onError, error));
|
|
46
|
+
};
|
|
47
|
+
const visibility = () => {
|
|
48
|
+
if (document.visibilityState === 'hidden') flush();
|
|
49
|
+
};
|
|
50
|
+
window?.addEventListener('pagehide', flush);
|
|
51
|
+
document?.addEventListener('visibilitychange', visibility);
|
|
52
|
+
return () => {
|
|
53
|
+
window?.removeEventListener('pagehide', flush);
|
|
54
|
+
document?.removeEventListener('visibilitychange', visibility);
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function collectBrowserEnvironment({
|
|
59
|
+
fields = [
|
|
60
|
+
ENVIRONMENT_FIELDS.LANGUAGE,
|
|
61
|
+
ENVIRONMENT_FIELDS.UTC_OFFSET_MINUTES,
|
|
62
|
+
ENVIRONMENT_FIELDS.DISPLAY_MODE,
|
|
63
|
+
ENVIRONMENT_FIELDS.ONLINE,
|
|
64
|
+
],
|
|
65
|
+
deadlineMs = 500,
|
|
66
|
+
} = {}) {
|
|
67
|
+
if (
|
|
68
|
+
!Array.isArray(fields) ||
|
|
69
|
+
fields.some((field) => !environmentFields.has(field))
|
|
70
|
+
)
|
|
71
|
+
throw new TypeError('Unknown environment field');
|
|
72
|
+
const navigator = globalThis.navigator;
|
|
73
|
+
const result = {};
|
|
74
|
+
let active = true;
|
|
75
|
+
let timer;
|
|
76
|
+
const read = async (field) => {
|
|
77
|
+
try {
|
|
78
|
+
let value;
|
|
79
|
+
switch (field) {
|
|
80
|
+
case ENVIRONMENT_FIELDS.LANGUAGE:
|
|
81
|
+
value = navigator?.language;
|
|
82
|
+
break;
|
|
83
|
+
case ENVIRONMENT_FIELDS.UTC_OFFSET_MINUTES:
|
|
84
|
+
value = new Date().getTimezoneOffset();
|
|
85
|
+
break;
|
|
86
|
+
case ENVIRONMENT_FIELDS.DISPLAY_MODE:
|
|
87
|
+
value = globalThis.matchMedia
|
|
88
|
+
? globalThis.matchMedia('(display-mode: standalone)').matches
|
|
89
|
+
? 'standalone'
|
|
90
|
+
: 'browser'
|
|
91
|
+
: undefined;
|
|
92
|
+
break;
|
|
93
|
+
case ENVIRONMENT_FIELDS.ONLINE:
|
|
94
|
+
value = navigator?.onLine;
|
|
95
|
+
break;
|
|
96
|
+
case ENVIRONMENT_FIELDS.USER_AGENT:
|
|
97
|
+
value = navigator?.userAgent;
|
|
98
|
+
break;
|
|
99
|
+
case ENVIRONMENT_FIELDS.TIME_ZONE:
|
|
100
|
+
value = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
101
|
+
break;
|
|
102
|
+
case ENVIRONMENT_FIELDS.CLIENT_HINTS:
|
|
103
|
+
value = await navigator?.userAgentData?.getHighEntropyValues([
|
|
104
|
+
'architecture',
|
|
105
|
+
'bitness',
|
|
106
|
+
'model',
|
|
107
|
+
'platformVersion',
|
|
108
|
+
'fullVersionList',
|
|
109
|
+
]);
|
|
110
|
+
break;
|
|
111
|
+
case ENVIRONMENT_FIELDS.SCREEN:
|
|
112
|
+
value = globalThis.screen && {
|
|
113
|
+
width: screen.width,
|
|
114
|
+
height: screen.height,
|
|
115
|
+
pixelRatio: globalThis.devicePixelRatio,
|
|
116
|
+
};
|
|
117
|
+
break;
|
|
118
|
+
case ENVIRONMENT_FIELDS.STORAGE:
|
|
119
|
+
value = await navigator?.storage?.estimate();
|
|
120
|
+
break;
|
|
121
|
+
case ENVIRONMENT_FIELDS.PERMISSIONS: {
|
|
122
|
+
const permissions = {};
|
|
123
|
+
for (const name of ['camera', 'microphone', 'notifications']) {
|
|
124
|
+
if (!active) break;
|
|
125
|
+
try {
|
|
126
|
+
permissions[name] = (
|
|
127
|
+
await navigator?.permissions?.query({ name })
|
|
128
|
+
)?.state;
|
|
129
|
+
} catch {
|
|
130
|
+
/* Unsupported permission names are omitted. */
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
value = permissions;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
case ENVIRONMENT_FIELDS.CONNECTION: {
|
|
137
|
+
const connection = navigator?.connection;
|
|
138
|
+
if (connection)
|
|
139
|
+
value = {
|
|
140
|
+
effectiveType: connection.effectiveType,
|
|
141
|
+
downlink: connection.downlink,
|
|
142
|
+
rtt: connection.rtt,
|
|
143
|
+
saveData: connection.saveData,
|
|
144
|
+
};
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
case ENVIRONMENT_FIELDS.DEVICE_COUNTS: {
|
|
148
|
+
const devices = await navigator?.mediaDevices?.enumerateDevices();
|
|
149
|
+
if (devices) {
|
|
150
|
+
value = {};
|
|
151
|
+
for (const device of devices)
|
|
152
|
+
value[device.kind] = (value[device.kind] ?? 0) + 1;
|
|
153
|
+
}
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (active && value !== undefined)
|
|
158
|
+
result[field] = JSON.parse(JSON.stringify(value));
|
|
159
|
+
} catch {
|
|
160
|
+
/* Optional reads cannot stop environment collection. */
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
await Promise.race([
|
|
164
|
+
Promise.all(fields.map(read)),
|
|
165
|
+
new Promise((resolve) => {
|
|
166
|
+
timer = globalThis.setTimeout(resolve, Math.max(0, deadlineMs));
|
|
167
|
+
}),
|
|
168
|
+
]);
|
|
169
|
+
active = false;
|
|
170
|
+
globalThis.clearTimeout(timer);
|
|
171
|
+
return Object.freeze(result);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function downloadBlob(blob, fileName) {
|
|
175
|
+
const url = URL.createObjectURL(blob);
|
|
176
|
+
const link = document.createElement('a');
|
|
177
|
+
link.href = url;
|
|
178
|
+
link.download = fileName;
|
|
179
|
+
try {
|
|
180
|
+
document.body.append(link);
|
|
181
|
+
link.click();
|
|
182
|
+
} finally {
|
|
183
|
+
link.remove();
|
|
184
|
+
globalThis.setTimeout(() => URL.revokeObjectURL(url), 0);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
exports.captureGlobalErrors = captureGlobalErrors;
|
|
189
|
+
exports.collectBrowserEnvironment = collectBrowserEnvironment;
|
|
190
|
+
exports.downloadBlob = downloadBlob;
|
|
191
|
+
exports.flushOnPageHide = flushOnPageHide;
|
|
192
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/browser/constants.js","../../src/browser/index.js"],"sourcesContent":["export const ENVIRONMENT_FIELDS = /* @__PURE__ */ Object.freeze({\n LANGUAGE: 'language',\n UTC_OFFSET_MINUTES: 'utcOffsetMinutes',\n DISPLAY_MODE: 'displayMode',\n ONLINE: 'online',\n USER_AGENT: 'userAgent',\n CLIENT_HINTS: 'clientHints',\n TIME_ZONE: 'timeZone',\n CONNECTION: 'connection',\n PERMISSIONS: 'permissions',\n DEVICE_COUNTS: 'deviceCounts',\n STORAGE: 'storage',\n SCREEN: 'screen',\n});\n","import { report } from '../core/common.js';\nimport { ENVIRONMENT_FIELDS } from './constants.js';\n\nconst environmentFields = new Set(Object.values(ENVIRONMENT_FIELDS));\n\nexport function captureGlobalErrors(\n logger,\n { target = globalThis.window } = {},\n) {\n const onError = (event) =>\n logger.error('browser.error', event.error ?? { message: event.message });\n const onRejection = (event) =>\n logger.error('browser.unhandledrejection', event.reason);\n target?.addEventListener('error', onError);\n target?.addEventListener('unhandledrejection', onRejection);\n return () => {\n target?.removeEventListener('error', onError);\n target?.removeEventListener('unhandledrejection', onRejection);\n };\n}\n\nexport function flushOnPageHide(logging, options = {}) {\n const window = options.window ?? globalThis.window;\n const document = options.document ?? globalThis.document;\n const flush = () => {\n Promise.resolve()\n .then(() => logging.flush())\n .catch((error) => report(options.onError, error));\n };\n const visibility = () => {\n if (document.visibilityState === 'hidden') flush();\n };\n window?.addEventListener('pagehide', flush);\n document?.addEventListener('visibilitychange', visibility);\n return () => {\n window?.removeEventListener('pagehide', flush);\n document?.removeEventListener('visibilitychange', visibility);\n };\n}\n\nexport async function collectBrowserEnvironment({\n fields = [\n ENVIRONMENT_FIELDS.LANGUAGE,\n ENVIRONMENT_FIELDS.UTC_OFFSET_MINUTES,\n ENVIRONMENT_FIELDS.DISPLAY_MODE,\n ENVIRONMENT_FIELDS.ONLINE,\n ],\n deadlineMs = 500,\n} = {}) {\n if (\n !Array.isArray(fields) ||\n fields.some((field) => !environmentFields.has(field))\n )\n throw new TypeError('Unknown environment field');\n const navigator = globalThis.navigator;\n const result = {};\n let active = true;\n let timer;\n const read = async (field) => {\n try {\n let value;\n switch (field) {\n case ENVIRONMENT_FIELDS.LANGUAGE:\n value = navigator?.language;\n break;\n case ENVIRONMENT_FIELDS.UTC_OFFSET_MINUTES:\n value = new Date().getTimezoneOffset();\n break;\n case ENVIRONMENT_FIELDS.DISPLAY_MODE:\n value = globalThis.matchMedia\n ? globalThis.matchMedia('(display-mode: standalone)').matches\n ? 'standalone'\n : 'browser'\n : undefined;\n break;\n case ENVIRONMENT_FIELDS.ONLINE:\n value = navigator?.onLine;\n break;\n case ENVIRONMENT_FIELDS.USER_AGENT:\n value = navigator?.userAgent;\n break;\n case ENVIRONMENT_FIELDS.TIME_ZONE:\n value = Intl.DateTimeFormat().resolvedOptions().timeZone;\n break;\n case ENVIRONMENT_FIELDS.CLIENT_HINTS:\n value = await navigator?.userAgentData?.getHighEntropyValues([\n 'architecture',\n 'bitness',\n 'model',\n 'platformVersion',\n 'fullVersionList',\n ]);\n break;\n case ENVIRONMENT_FIELDS.SCREEN:\n value = globalThis.screen && {\n width: screen.width,\n height: screen.height,\n pixelRatio: globalThis.devicePixelRatio,\n };\n break;\n case ENVIRONMENT_FIELDS.STORAGE:\n value = await navigator?.storage?.estimate();\n break;\n case ENVIRONMENT_FIELDS.PERMISSIONS: {\n const permissions = {};\n for (const name of ['camera', 'microphone', 'notifications']) {\n if (!active) break;\n try {\n permissions[name] = (\n await navigator?.permissions?.query({ name })\n )?.state;\n } catch {\n /* Unsupported permission names are omitted. */\n }\n }\n value = permissions;\n break;\n }\n case ENVIRONMENT_FIELDS.CONNECTION: {\n const connection = navigator?.connection;\n if (connection)\n value = {\n effectiveType: connection.effectiveType,\n downlink: connection.downlink,\n rtt: connection.rtt,\n saveData: connection.saveData,\n };\n break;\n }\n case ENVIRONMENT_FIELDS.DEVICE_COUNTS: {\n const devices = await navigator?.mediaDevices?.enumerateDevices();\n if (devices) {\n value = {};\n for (const device of devices)\n value[device.kind] = (value[device.kind] ?? 0) + 1;\n }\n break;\n }\n }\n if (active && value !== undefined)\n result[field] = JSON.parse(JSON.stringify(value));\n } catch {\n /* Optional reads cannot stop environment collection. */\n }\n };\n await Promise.race([\n Promise.all(fields.map(read)),\n new Promise((resolve) => {\n timer = globalThis.setTimeout(resolve, Math.max(0, deadlineMs));\n }),\n ]);\n active = false;\n globalThis.clearTimeout(timer);\n return Object.freeze(result);\n}\n\nexport function downloadBlob(blob, fileName) {\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = fileName;\n try {\n document.body.append(link);\n link.click();\n } finally {\n link.remove();\n globalThis.setTimeout(() => URL.revokeObjectURL(url), 0);\n }\n}\n"],"names":["report"],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Logger, Logging, LogValue } from "../index.cjs";
|
|
2
|
+
import type { ENVIRONMENT_FIELDS } from "./constants.cjs";
|
|
3
|
+
|
|
4
|
+
export type BrowserListenerTarget = Pick<
|
|
5
|
+
EventTarget,
|
|
6
|
+
'addEventListener' | 'removeEventListener'
|
|
7
|
+
>;
|
|
8
|
+
export type BrowserEnvironmentField =
|
|
9
|
+
(typeof ENVIRONMENT_FIELDS)[keyof typeof ENVIRONMENT_FIELDS];
|
|
10
|
+
export declare function captureGlobalErrors(
|
|
11
|
+
logger: Logger,
|
|
12
|
+
options?: Readonly<{ target?: BrowserListenerTarget }>,
|
|
13
|
+
): () => void;
|
|
14
|
+
export declare function flushOnPageHide(
|
|
15
|
+
logging: Pick<Logging<string>, 'flush'>,
|
|
16
|
+
options?: Readonly<{
|
|
17
|
+
window?: BrowserListenerTarget;
|
|
18
|
+
document?: BrowserListenerTarget &
|
|
19
|
+
Readonly<{ visibilityState: DocumentVisibilityState }>;
|
|
20
|
+
onError?: (error: unknown) => void;
|
|
21
|
+
}>,
|
|
22
|
+
): () => void;
|
|
23
|
+
export declare function collectBrowserEnvironment(
|
|
24
|
+
options?: Readonly<{
|
|
25
|
+
fields?: readonly BrowserEnvironmentField[];
|
|
26
|
+
deadlineMs?: number;
|
|
27
|
+
}>,
|
|
28
|
+
): Promise<Readonly<Record<string, LogValue>>>;
|
|
29
|
+
export declare function downloadBlob(blob: Blob, fileName: string): void;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Logger, Logging, LogValue } from '../index.js';
|
|
2
|
+
import type { ENVIRONMENT_FIELDS } from './constants.js';
|
|
3
|
+
|
|
4
|
+
export type BrowserListenerTarget = Pick<
|
|
5
|
+
EventTarget,
|
|
6
|
+
'addEventListener' | 'removeEventListener'
|
|
7
|
+
>;
|
|
8
|
+
export type BrowserEnvironmentField =
|
|
9
|
+
(typeof ENVIRONMENT_FIELDS)[keyof typeof ENVIRONMENT_FIELDS];
|
|
10
|
+
export declare function captureGlobalErrors(
|
|
11
|
+
logger: Logger,
|
|
12
|
+
options?: Readonly<{ target?: BrowserListenerTarget }>,
|
|
13
|
+
): () => void;
|
|
14
|
+
export declare function flushOnPageHide(
|
|
15
|
+
logging: Pick<Logging<string>, 'flush'>,
|
|
16
|
+
options?: Readonly<{
|
|
17
|
+
window?: BrowserListenerTarget;
|
|
18
|
+
document?: BrowserListenerTarget &
|
|
19
|
+
Readonly<{ visibilityState: DocumentVisibilityState }>;
|
|
20
|
+
onError?: (error: unknown) => void;
|
|
21
|
+
}>,
|
|
22
|
+
): () => void;
|
|
23
|
+
export declare function collectBrowserEnvironment(
|
|
24
|
+
options?: Readonly<{
|
|
25
|
+
fields?: readonly BrowserEnvironmentField[];
|
|
26
|
+
deadlineMs?: number;
|
|
27
|
+
}>,
|
|
28
|
+
): Promise<Readonly<Record<string, LogValue>>>;
|
|
29
|
+
export declare function downloadBlob(blob: Blob, fileName: string): void;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { b as report } from '../chunk-LRCHwVuE.js';
|
|
2
|
+
import '../chunk-CSS3f4_M.js';
|
|
3
|
+
|
|
4
|
+
const ENVIRONMENT_FIELDS = /* @__PURE__ */ Object.freeze({
|
|
5
|
+
LANGUAGE: 'language',
|
|
6
|
+
UTC_OFFSET_MINUTES: 'utcOffsetMinutes',
|
|
7
|
+
DISPLAY_MODE: 'displayMode',
|
|
8
|
+
ONLINE: 'online',
|
|
9
|
+
USER_AGENT: 'userAgent',
|
|
10
|
+
CLIENT_HINTS: 'clientHints',
|
|
11
|
+
TIME_ZONE: 'timeZone',
|
|
12
|
+
CONNECTION: 'connection',
|
|
13
|
+
PERMISSIONS: 'permissions',
|
|
14
|
+
DEVICE_COUNTS: 'deviceCounts',
|
|
15
|
+
STORAGE: 'storage',
|
|
16
|
+
SCREEN: 'screen',
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const environmentFields = new Set(Object.values(ENVIRONMENT_FIELDS));
|
|
20
|
+
|
|
21
|
+
function captureGlobalErrors(
|
|
22
|
+
logger,
|
|
23
|
+
{ target = globalThis.window } = {},
|
|
24
|
+
) {
|
|
25
|
+
const onError = (event) =>
|
|
26
|
+
logger.error('browser.error', event.error ?? { message: event.message });
|
|
27
|
+
const onRejection = (event) =>
|
|
28
|
+
logger.error('browser.unhandledrejection', event.reason);
|
|
29
|
+
target?.addEventListener('error', onError);
|
|
30
|
+
target?.addEventListener('unhandledrejection', onRejection);
|
|
31
|
+
return () => {
|
|
32
|
+
target?.removeEventListener('error', onError);
|
|
33
|
+
target?.removeEventListener('unhandledrejection', onRejection);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function flushOnPageHide(logging, options = {}) {
|
|
38
|
+
const window = options.window ?? globalThis.window;
|
|
39
|
+
const document = options.document ?? globalThis.document;
|
|
40
|
+
const flush = () => {
|
|
41
|
+
Promise.resolve()
|
|
42
|
+
.then(() => logging.flush())
|
|
43
|
+
.catch((error) => report(options.onError, error));
|
|
44
|
+
};
|
|
45
|
+
const visibility = () => {
|
|
46
|
+
if (document.visibilityState === 'hidden') flush();
|
|
47
|
+
};
|
|
48
|
+
window?.addEventListener('pagehide', flush);
|
|
49
|
+
document?.addEventListener('visibilitychange', visibility);
|
|
50
|
+
return () => {
|
|
51
|
+
window?.removeEventListener('pagehide', flush);
|
|
52
|
+
document?.removeEventListener('visibilitychange', visibility);
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function collectBrowserEnvironment({
|
|
57
|
+
fields = [
|
|
58
|
+
ENVIRONMENT_FIELDS.LANGUAGE,
|
|
59
|
+
ENVIRONMENT_FIELDS.UTC_OFFSET_MINUTES,
|
|
60
|
+
ENVIRONMENT_FIELDS.DISPLAY_MODE,
|
|
61
|
+
ENVIRONMENT_FIELDS.ONLINE,
|
|
62
|
+
],
|
|
63
|
+
deadlineMs = 500,
|
|
64
|
+
} = {}) {
|
|
65
|
+
if (
|
|
66
|
+
!Array.isArray(fields) ||
|
|
67
|
+
fields.some((field) => !environmentFields.has(field))
|
|
68
|
+
)
|
|
69
|
+
throw new TypeError('Unknown environment field');
|
|
70
|
+
const navigator = globalThis.navigator;
|
|
71
|
+
const result = {};
|
|
72
|
+
let active = true;
|
|
73
|
+
let timer;
|
|
74
|
+
const read = async (field) => {
|
|
75
|
+
try {
|
|
76
|
+
let value;
|
|
77
|
+
switch (field) {
|
|
78
|
+
case ENVIRONMENT_FIELDS.LANGUAGE:
|
|
79
|
+
value = navigator?.language;
|
|
80
|
+
break;
|
|
81
|
+
case ENVIRONMENT_FIELDS.UTC_OFFSET_MINUTES:
|
|
82
|
+
value = new Date().getTimezoneOffset();
|
|
83
|
+
break;
|
|
84
|
+
case ENVIRONMENT_FIELDS.DISPLAY_MODE:
|
|
85
|
+
value = globalThis.matchMedia
|
|
86
|
+
? globalThis.matchMedia('(display-mode: standalone)').matches
|
|
87
|
+
? 'standalone'
|
|
88
|
+
: 'browser'
|
|
89
|
+
: undefined;
|
|
90
|
+
break;
|
|
91
|
+
case ENVIRONMENT_FIELDS.ONLINE:
|
|
92
|
+
value = navigator?.onLine;
|
|
93
|
+
break;
|
|
94
|
+
case ENVIRONMENT_FIELDS.USER_AGENT:
|
|
95
|
+
value = navigator?.userAgent;
|
|
96
|
+
break;
|
|
97
|
+
case ENVIRONMENT_FIELDS.TIME_ZONE:
|
|
98
|
+
value = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
99
|
+
break;
|
|
100
|
+
case ENVIRONMENT_FIELDS.CLIENT_HINTS:
|
|
101
|
+
value = await navigator?.userAgentData?.getHighEntropyValues([
|
|
102
|
+
'architecture',
|
|
103
|
+
'bitness',
|
|
104
|
+
'model',
|
|
105
|
+
'platformVersion',
|
|
106
|
+
'fullVersionList',
|
|
107
|
+
]);
|
|
108
|
+
break;
|
|
109
|
+
case ENVIRONMENT_FIELDS.SCREEN:
|
|
110
|
+
value = globalThis.screen && {
|
|
111
|
+
width: screen.width,
|
|
112
|
+
height: screen.height,
|
|
113
|
+
pixelRatio: globalThis.devicePixelRatio,
|
|
114
|
+
};
|
|
115
|
+
break;
|
|
116
|
+
case ENVIRONMENT_FIELDS.STORAGE:
|
|
117
|
+
value = await navigator?.storage?.estimate();
|
|
118
|
+
break;
|
|
119
|
+
case ENVIRONMENT_FIELDS.PERMISSIONS: {
|
|
120
|
+
const permissions = {};
|
|
121
|
+
for (const name of ['camera', 'microphone', 'notifications']) {
|
|
122
|
+
if (!active) break;
|
|
123
|
+
try {
|
|
124
|
+
permissions[name] = (
|
|
125
|
+
await navigator?.permissions?.query({ name })
|
|
126
|
+
)?.state;
|
|
127
|
+
} catch {
|
|
128
|
+
/* Unsupported permission names are omitted. */
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
value = permissions;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
case ENVIRONMENT_FIELDS.CONNECTION: {
|
|
135
|
+
const connection = navigator?.connection;
|
|
136
|
+
if (connection)
|
|
137
|
+
value = {
|
|
138
|
+
effectiveType: connection.effectiveType,
|
|
139
|
+
downlink: connection.downlink,
|
|
140
|
+
rtt: connection.rtt,
|
|
141
|
+
saveData: connection.saveData,
|
|
142
|
+
};
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
case ENVIRONMENT_FIELDS.DEVICE_COUNTS: {
|
|
146
|
+
const devices = await navigator?.mediaDevices?.enumerateDevices();
|
|
147
|
+
if (devices) {
|
|
148
|
+
value = {};
|
|
149
|
+
for (const device of devices)
|
|
150
|
+
value[device.kind] = (value[device.kind] ?? 0) + 1;
|
|
151
|
+
}
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (active && value !== undefined)
|
|
156
|
+
result[field] = JSON.parse(JSON.stringify(value));
|
|
157
|
+
} catch {
|
|
158
|
+
/* Optional reads cannot stop environment collection. */
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
await Promise.race([
|
|
162
|
+
Promise.all(fields.map(read)),
|
|
163
|
+
new Promise((resolve) => {
|
|
164
|
+
timer = globalThis.setTimeout(resolve, Math.max(0, deadlineMs));
|
|
165
|
+
}),
|
|
166
|
+
]);
|
|
167
|
+
active = false;
|
|
168
|
+
globalThis.clearTimeout(timer);
|
|
169
|
+
return Object.freeze(result);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function downloadBlob(blob, fileName) {
|
|
173
|
+
const url = URL.createObjectURL(blob);
|
|
174
|
+
const link = document.createElement('a');
|
|
175
|
+
link.href = url;
|
|
176
|
+
link.download = fileName;
|
|
177
|
+
try {
|
|
178
|
+
document.body.append(link);
|
|
179
|
+
link.click();
|
|
180
|
+
} finally {
|
|
181
|
+
link.remove();
|
|
182
|
+
globalThis.setTimeout(() => URL.revokeObjectURL(url), 0);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export { captureGlobalErrors, collectBrowserEnvironment, downloadBlob, flushOnPageHide };
|
|
187
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/browser/constants.js","../../src/browser/index.js"],"sourcesContent":["export const ENVIRONMENT_FIELDS = /* @__PURE__ */ Object.freeze({\n LANGUAGE: 'language',\n UTC_OFFSET_MINUTES: 'utcOffsetMinutes',\n DISPLAY_MODE: 'displayMode',\n ONLINE: 'online',\n USER_AGENT: 'userAgent',\n CLIENT_HINTS: 'clientHints',\n TIME_ZONE: 'timeZone',\n CONNECTION: 'connection',\n PERMISSIONS: 'permissions',\n DEVICE_COUNTS: 'deviceCounts',\n STORAGE: 'storage',\n SCREEN: 'screen',\n});\n","import { report } from '../core/common.js';\nimport { ENVIRONMENT_FIELDS } from './constants.js';\n\nconst environmentFields = new Set(Object.values(ENVIRONMENT_FIELDS));\n\nexport function captureGlobalErrors(\n logger,\n { target = globalThis.window } = {},\n) {\n const onError = (event) =>\n logger.error('browser.error', event.error ?? { message: event.message });\n const onRejection = (event) =>\n logger.error('browser.unhandledrejection', event.reason);\n target?.addEventListener('error', onError);\n target?.addEventListener('unhandledrejection', onRejection);\n return () => {\n target?.removeEventListener('error', onError);\n target?.removeEventListener('unhandledrejection', onRejection);\n };\n}\n\nexport function flushOnPageHide(logging, options = {}) {\n const window = options.window ?? globalThis.window;\n const document = options.document ?? globalThis.document;\n const flush = () => {\n Promise.resolve()\n .then(() => logging.flush())\n .catch((error) => report(options.onError, error));\n };\n const visibility = () => {\n if (document.visibilityState === 'hidden') flush();\n };\n window?.addEventListener('pagehide', flush);\n document?.addEventListener('visibilitychange', visibility);\n return () => {\n window?.removeEventListener('pagehide', flush);\n document?.removeEventListener('visibilitychange', visibility);\n };\n}\n\nexport async function collectBrowserEnvironment({\n fields = [\n ENVIRONMENT_FIELDS.LANGUAGE,\n ENVIRONMENT_FIELDS.UTC_OFFSET_MINUTES,\n ENVIRONMENT_FIELDS.DISPLAY_MODE,\n ENVIRONMENT_FIELDS.ONLINE,\n ],\n deadlineMs = 500,\n} = {}) {\n if (\n !Array.isArray(fields) ||\n fields.some((field) => !environmentFields.has(field))\n )\n throw new TypeError('Unknown environment field');\n const navigator = globalThis.navigator;\n const result = {};\n let active = true;\n let timer;\n const read = async (field) => {\n try {\n let value;\n switch (field) {\n case ENVIRONMENT_FIELDS.LANGUAGE:\n value = navigator?.language;\n break;\n case ENVIRONMENT_FIELDS.UTC_OFFSET_MINUTES:\n value = new Date().getTimezoneOffset();\n break;\n case ENVIRONMENT_FIELDS.DISPLAY_MODE:\n value = globalThis.matchMedia\n ? globalThis.matchMedia('(display-mode: standalone)').matches\n ? 'standalone'\n : 'browser'\n : undefined;\n break;\n case ENVIRONMENT_FIELDS.ONLINE:\n value = navigator?.onLine;\n break;\n case ENVIRONMENT_FIELDS.USER_AGENT:\n value = navigator?.userAgent;\n break;\n case ENVIRONMENT_FIELDS.TIME_ZONE:\n value = Intl.DateTimeFormat().resolvedOptions().timeZone;\n break;\n case ENVIRONMENT_FIELDS.CLIENT_HINTS:\n value = await navigator?.userAgentData?.getHighEntropyValues([\n 'architecture',\n 'bitness',\n 'model',\n 'platformVersion',\n 'fullVersionList',\n ]);\n break;\n case ENVIRONMENT_FIELDS.SCREEN:\n value = globalThis.screen && {\n width: screen.width,\n height: screen.height,\n pixelRatio: globalThis.devicePixelRatio,\n };\n break;\n case ENVIRONMENT_FIELDS.STORAGE:\n value = await navigator?.storage?.estimate();\n break;\n case ENVIRONMENT_FIELDS.PERMISSIONS: {\n const permissions = {};\n for (const name of ['camera', 'microphone', 'notifications']) {\n if (!active) break;\n try {\n permissions[name] = (\n await navigator?.permissions?.query({ name })\n )?.state;\n } catch {\n /* Unsupported permission names are omitted. */\n }\n }\n value = permissions;\n break;\n }\n case ENVIRONMENT_FIELDS.CONNECTION: {\n const connection = navigator?.connection;\n if (connection)\n value = {\n effectiveType: connection.effectiveType,\n downlink: connection.downlink,\n rtt: connection.rtt,\n saveData: connection.saveData,\n };\n break;\n }\n case ENVIRONMENT_FIELDS.DEVICE_COUNTS: {\n const devices = await navigator?.mediaDevices?.enumerateDevices();\n if (devices) {\n value = {};\n for (const device of devices)\n value[device.kind] = (value[device.kind] ?? 0) + 1;\n }\n break;\n }\n }\n if (active && value !== undefined)\n result[field] = JSON.parse(JSON.stringify(value));\n } catch {\n /* Optional reads cannot stop environment collection. */\n }\n };\n await Promise.race([\n Promise.all(fields.map(read)),\n new Promise((resolve) => {\n timer = globalThis.setTimeout(resolve, Math.max(0, deadlineMs));\n }),\n ]);\n active = false;\n globalThis.clearTimeout(timer);\n return Object.freeze(result);\n}\n\nexport function downloadBlob(blob, fileName) {\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = fileName;\n try {\n document.body.append(link);\n link.click();\n } finally {\n link.remove();\n globalThis.setTimeout(() => URL.revokeObjectURL(url), 0);\n }\n}\n"],"names":[],"mappings":"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"}
|