@peassoft/web-logger 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alexey Gorokhov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9
+ of the Software, and to permit persons to whom the Software is furnished to do
10
+ so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # @peassoft/web-logger
2
+
3
+ Logger for web applications.
4
+
5
+ **Warning!** This is a module used in a private project. You definitely should not use it.
6
+
7
+ ## Intallation
8
+
9
+ ```shell
10
+ $ npm i -D @peassoft/web-logger
11
+ ```
12
+
13
+ ## Usage Example
14
+
15
+ ```ts
16
+ import { WebLogger, type WebLoggerConstructorOptions } from '@peassoft/web-logger';
17
+
18
+ const opts: WebLoggerConstructorOptions = {
19
+ appName: 'my-app-name',
20
+ url: '/logs',
21
+ };
22
+
23
+ const logger = new WebLogger(opts);
24
+
25
+ logger.error(new Error('foo'));
26
+ logger.warn(new Error('bar'));
27
+ logger.info('some message');
28
+ ```
29
+
30
+ ## API Reference
31
+
32
+ ### Constructor
33
+
34
+ ```ts
35
+ type WebLoggerConstructorOptions = {
36
+ /** Frontend application name which appears in a log entry. */
37
+ appName: string;
38
+ /** URL to send logs to. Passed to `fetch(url)` as is, so can be a fill URL or a path. */
39
+ url: string;
40
+ };
41
+ ```
42
+
43
+ ### Methods
44
+
45
+ ```ts
46
+ /**
47
+ * Log a log entry of "error" level.
48
+ */
49
+ error(err: Error | DOMException): void;
50
+ /**
51
+ * Log a log entry of "warn" level.
52
+ */
53
+ warn(err: Error | DOMException): void;
54
+ /**
55
+ * Log a log entry of "info" level.
56
+ */
57
+ info(message: string): void;
58
+ ```
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Logger for web applications.
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ export { default as WebLogger } from './web-logger.js';
7
+ export type { WebLoggerConstructorOptions } from './types.js';
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Logger for web applications.
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ export { default as WebLogger } from './web-logger.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Logger constructor options.
3
+ *
4
+ * @public
5
+ */
6
+ export type WebLoggerConstructorOptions = {
7
+ /** Frontend application name which appears in a log entry. */
8
+ appName: string;
9
+ /** URL to send logs to. Passed to `fetch(url)` as is, so can be a fill URL or a path. */
10
+ url: string;
11
+ };
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,31 @@
1
+ import type { WebLoggerConstructorOptions } from './types.js';
2
+ /**
3
+ * WebLogger class.
4
+ *
5
+ * @public
6
+ */
7
+ export default class WebLogger {
8
+ #private;
9
+ /**
10
+ * @public
11
+ */
12
+ constructor(opts: WebLoggerConstructorOptions);
13
+ /**
14
+ * Log a log entry of "error" level.
15
+ *
16
+ * @public
17
+ */
18
+ error(err: Error | DOMException): void;
19
+ /**
20
+ * Log a log entry of "warn" level.
21
+ *
22
+ * @public
23
+ */
24
+ warn(err: Error | DOMException): void;
25
+ /**
26
+ * Log a log entry of "info" level.
27
+ *
28
+ * @public
29
+ */
30
+ info(message: string): void;
31
+ }
@@ -0,0 +1,204 @@
1
+ import { stringifyError } from '@peassoft/error-stringify';
2
+ import { v4 as uuid } from 'uuid';
3
+ /**
4
+ * WebLogger class.
5
+ *
6
+ * @public
7
+ */
8
+ export default class WebLogger {
9
+ #DB_NAME = 'peassoft-web-logger';
10
+ // We MUST NOT change database version. A frontend application's parts might use different
11
+ // versions of this package. If we ever changed the database version:
12
+ // - some parts using an older version failed opening connections;
13
+ // - some parts trying to upgrade database version would be blocked by other open connections.
14
+ #DB_VER = 1;
15
+ #db = null;
16
+ #status = 'idle';
17
+ #DEBOUNCE_INTEVAL_MS = 2000;
18
+ #REGULAR_INTERVAL_MS = 5000;
19
+ #MAX_RETRY_INTERVAL_MS = 60000;
20
+ #retryCounter = 0;
21
+ #timer = undefined;
22
+ #appName;
23
+ #url;
24
+ /**
25
+ * @public
26
+ */
27
+ constructor(opts) {
28
+ const { appName, url, } = opts;
29
+ this.#appName = appName;
30
+ this.#url = url;
31
+ void this.#flush();
32
+ }
33
+ /**
34
+ * Log a log entry of "error" level.
35
+ *
36
+ * @public
37
+ */
38
+ error(err) {
39
+ const entry = {
40
+ timestamp: new Date().toISOString(),
41
+ app: this.#appName,
42
+ level: 'error',
43
+ error: stringifyError(err),
44
+ };
45
+ void this.#processLogEntry(entry);
46
+ }
47
+ /**
48
+ * Log a log entry of "warn" level.
49
+ *
50
+ * @public
51
+ */
52
+ warn(err) {
53
+ const entry = {
54
+ timestamp: new Date().toISOString(),
55
+ app: this.#appName,
56
+ level: 'warn',
57
+ error: stringifyError(err),
58
+ };
59
+ void this.#processLogEntry(entry);
60
+ }
61
+ /**
62
+ * Log a log entry of "info" level.
63
+ *
64
+ * @public
65
+ */
66
+ info(message) {
67
+ const entry = {
68
+ timestamp: new Date().toISOString(),
69
+ app: this.#appName,
70
+ level: 'info',
71
+ message,
72
+ };
73
+ void this.#processLogEntry(entry);
74
+ }
75
+ async #processLogEntry(logEntry) {
76
+ if (!this.#db) {
77
+ await this.#openDb();
78
+ if (!this.#db)
79
+ return;
80
+ }
81
+ const db = this.#db;
82
+ const dbRecord = {
83
+ id: uuid(),
84
+ logEntry,
85
+ };
86
+ return new Promise(resolve => {
87
+ const transaction = db.transaction(this.#appName, 'readwrite');
88
+ transaction.oncomplete = () => {
89
+ if (this.#status === 'idle') {
90
+ void this.#flush();
91
+ }
92
+ resolve();
93
+ };
94
+ transaction.onerror = () => {
95
+ console.error(transaction.error);
96
+ resolve();
97
+ };
98
+ const objectStore = transaction.objectStore(this.#appName);
99
+ objectStore.put(dbRecord);
100
+ });
101
+ }
102
+ #openDb() {
103
+ return new Promise(resolve => {
104
+ const openDbReq = window.indexedDB.open(this.#DB_NAME, this.#DB_VER);
105
+ openDbReq.addEventListener('success', () => {
106
+ this.#db = openDbReq.result;
107
+ resolve();
108
+ });
109
+ openDbReq.addEventListener('error', () => {
110
+ console.error(openDbReq.error);
111
+ resolve();
112
+ });
113
+ openDbReq.addEventListener('upgradeneeded', (e) => {
114
+ /* @ts-expect-error TS type IDBVersionChangeEvent is incomplete */
115
+ const db = e.target.result;
116
+ db.addEventListener('error', event => {
117
+ console.error(event);
118
+ });
119
+ if (e.oldVersion === 0) {
120
+ db.createObjectStore(this.#appName, { keyPath: 'id' });
121
+ }
122
+ });
123
+ // We don't register a listener for `blocked` event as this event is emitted when
124
+ // an open connection to a database is blocking a `versionchange` transaction on
125
+ // the same database. We never change the database version, thus `blocked` event
126
+ // will never be emitted.
127
+ });
128
+ }
129
+ async #flush() {
130
+ window.clearTimeout(this.#timer);
131
+ this.#status = 'inprogress';
132
+ const records = await this.#getAllRecords();
133
+ if (!records.length) {
134
+ this.#status = 'idle';
135
+ return;
136
+ }
137
+ try {
138
+ await this.#send(records.map(record => record.logEntry));
139
+ }
140
+ catch {
141
+ this.#retryCounter++;
142
+ this.#timer = window.setTimeout(() => void this.#flush(), Math.min(this.#REGULAR_INTERVAL_MS * 2 ** (this.#retryCounter - 1), this.#MAX_RETRY_INTERVAL_MS));
143
+ return;
144
+ }
145
+ this.#retryCounter = 0;
146
+ await this.#deleteRecords(records);
147
+ this.#status = 'debouncing';
148
+ this.#timer = window.setTimeout(() => void this.#flush(), this.#DEBOUNCE_INTEVAL_MS);
149
+ }
150
+ async #getAllRecords() {
151
+ if (!this.#db) {
152
+ await this.#openDb();
153
+ if (!this.#db)
154
+ return Promise.resolve([]);
155
+ }
156
+ const db = this.#db;
157
+ return new Promise(resolve => {
158
+ const req = db.transaction(this.#appName)
159
+ .objectStore(this.#appName)
160
+ .getAll();
161
+ req.addEventListener('success', () => {
162
+ resolve(req.result);
163
+ });
164
+ req.addEventListener('error', () => {
165
+ console.error(req.error);
166
+ resolve([]);
167
+ });
168
+ });
169
+ }
170
+ #deleteRecords(records) {
171
+ if (!this.#db)
172
+ return Promise.resolve();
173
+ const db = this.#db;
174
+ return new Promise(resolve => {
175
+ const transaction = db.transaction(this.#appName, 'readwrite');
176
+ const store = transaction.objectStore(this.#appName);
177
+ for (const record of records) {
178
+ store.delete(record.id);
179
+ }
180
+ transaction.addEventListener('complete', () => {
181
+ resolve();
182
+ });
183
+ transaction.addEventListener('error', () => {
184
+ console.error(transaction.error);
185
+ resolve();
186
+ });
187
+ });
188
+ }
189
+ async #send(logEntries) {
190
+ const res = await fetch(this.#url, {
191
+ method: 'POST',
192
+ headers: {
193
+ 'Content-Type': 'application/json',
194
+ },
195
+ body: JSON.stringify({
196
+ logs: logEntries,
197
+ }),
198
+ });
199
+ if (!res.ok) {
200
+ throw new Error('unexpected response status code');
201
+ }
202
+ }
203
+ }
204
+ //# sourceMappingURL=web-logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-logger.js","sourceRoot":"","sources":["../src/web-logger.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@peassoft/web-logger",
3
+ "version": "1.0.0",
4
+ "description": "Logger for web applications",
5
+ "type": "module",
6
+ "exports": "./dist/index.js",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "author": {
11
+ "name": "Alexey Gorokhov",
12
+ "email": "alexey.gorokhov@icloud.com"
13
+ },
14
+ "license": "MIT",
15
+ "scripts": {
16
+ "dev": "vite",
17
+ "test": "eslint ./ && npm run tsc",
18
+ "tsc": "tsc --noEmit",
19
+ "build": "del-cli dist && tsc -p tsconfig-build.json && api-extractor run --local --verbose"
20
+ },
21
+ "devDependencies": {
22
+ "@memnrev/eslint-v9-config": "^0.4.0",
23
+ "@microsoft/api-extractor": "^7.58.7",
24
+ "@peassoft/verror": "^1.0.0",
25
+ "@total-typescript/ts-reset": "^0.6.1",
26
+ "@types/react": "^19.2.14",
27
+ "@types/react-dom": "^19.2.3",
28
+ "del-cli": "^7.0.0",
29
+ "eslint": "^9.39.4",
30
+ "react": "^19.2.5",
31
+ "react-dom": "^19.2.5",
32
+ "typescript": "^6.0.3",
33
+ "vite": "^8.0.10"
34
+ },
35
+ "dependencies": {
36
+ "@peassoft/error-stringify": "^1.0.1",
37
+ "uuid": "^14.0.0"
38
+ }
39
+ }