@paroicms/ui-logger 1.14.2 → 1.15.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/dist/ui-logger.d.ts +3 -2
- package/dist/ui-logger.js +52 -19
- package/package.json +6 -3
package/dist/ui-logger.d.ts
CHANGED
|
@@ -24,12 +24,13 @@ export interface UiLoggerOptions {
|
|
|
24
24
|
}
|
|
25
25
|
export interface SendToServerOptions {
|
|
26
26
|
minLevel?: UiLoggerLevels;
|
|
27
|
-
sendToServer?(lines: FrontLogLine[]): Promise<
|
|
27
|
+
sendToServer?(lines: FrontLogLine[]): Promise<SendStatus>;
|
|
28
28
|
}
|
|
29
29
|
export interface FrontLogLine {
|
|
30
|
-
message: string
|
|
30
|
+
message: string;
|
|
31
31
|
level: UiLoggerStrictLevels;
|
|
32
32
|
}
|
|
33
|
+
export type SendStatus = "NOT_READY" | "DONE" | "CANCEL";
|
|
33
34
|
export declare function createNoUiLogger(): FullUiLogger;
|
|
34
35
|
export declare function createUiLogger(mainOptions?: UiLoggerOptions): FullUiLogger;
|
|
35
36
|
type WrapAsync = <T extends (...args: any[]) => Promise<any>>(fn: T) => (...args: Parameters<T>) => void;
|
package/dist/ui-logger.js
CHANGED
|
@@ -79,6 +79,7 @@ function makeToServer(send, consoleLog) {
|
|
|
79
79
|
}
|
|
80
80
|
function createSendMiddleware(options) {
|
|
81
81
|
const logErrorFromBackend = toLevelNum(options.minLevel ?? "none") >= toLevelNum("error");
|
|
82
|
+
const sendMinLevel = options.minLevel ?? "none";
|
|
82
83
|
const postLog = options.sendToServer
|
|
83
84
|
? new PostLogToBackend({
|
|
84
85
|
sendToServer: options.sendToServer,
|
|
@@ -87,7 +88,7 @@ function createSendMiddleware(options) {
|
|
|
87
88
|
: undefined;
|
|
88
89
|
return (level, cb) => (...message) => {
|
|
89
90
|
cb(...message);
|
|
90
|
-
if (postLog) {
|
|
91
|
+
if (postLog && toLevelNum(level) <= toLevelNum(sendMinLevel)) {
|
|
91
92
|
postLog.addLogLineToPost({
|
|
92
93
|
message,
|
|
93
94
|
level,
|
|
@@ -117,6 +118,8 @@ class PostLogToBackend {
|
|
|
117
118
|
options;
|
|
118
119
|
lines = [];
|
|
119
120
|
timeoutId;
|
|
121
|
+
sending = false;
|
|
122
|
+
retryDelayMs = 500;
|
|
120
123
|
constructor(options) {
|
|
121
124
|
this.options = options;
|
|
122
125
|
}
|
|
@@ -126,44 +129,69 @@ class PostLogToBackend {
|
|
|
126
129
|
}
|
|
127
130
|
delayedSend() {
|
|
128
131
|
if (this.timeoutId !== undefined) {
|
|
129
|
-
if (this.lines.length >= 20)
|
|
130
|
-
return;
|
|
131
132
|
clearTimeout(this.timeoutId);
|
|
133
|
+
this.timeoutId = undefined;
|
|
134
|
+
if (this.lines.length >= 20) {
|
|
135
|
+
void this.#flush();
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
132
138
|
}
|
|
133
139
|
this.timeoutId = setTimeout(() => {
|
|
134
140
|
this.timeoutId = undefined;
|
|
135
|
-
|
|
136
|
-
void postLogFromFrontend({
|
|
137
|
-
...this.options,
|
|
138
|
-
lines: this.lines,
|
|
139
|
-
});
|
|
140
|
-
this.lines = [];
|
|
141
|
-
}
|
|
141
|
+
void this.#flush();
|
|
142
142
|
}, 50);
|
|
143
143
|
}
|
|
144
|
+
async #flush() {
|
|
145
|
+
if (this.sending || this.lines.length === 0)
|
|
146
|
+
return;
|
|
147
|
+
const batch = this.lines;
|
|
148
|
+
this.lines = [];
|
|
149
|
+
this.sending = true;
|
|
150
|
+
const status = await postLogFromFrontend({
|
|
151
|
+
...this.options,
|
|
152
|
+
lines: batch,
|
|
153
|
+
});
|
|
154
|
+
this.sending = false;
|
|
155
|
+
if (status === "NOT_READY") {
|
|
156
|
+
this.lines = batch.concat(this.lines);
|
|
157
|
+
setTimeout(() => this.delayedSend(), this.retryDelayMs);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
// On CANCEL: do nothing further; messages already went to console via cb
|
|
161
|
+
if (this.lines.length > 0)
|
|
162
|
+
this.delayedSend();
|
|
163
|
+
}
|
|
144
164
|
}
|
|
145
165
|
async function postLogFromFrontend({ lines, sendToServer, logErrorFromBackend, }) {
|
|
146
166
|
try {
|
|
147
167
|
for (const line of lines)
|
|
148
|
-
line.message = line.message.map(anyMessageToStringifiable);
|
|
149
|
-
await sendToServer(lines.map((line) => ({
|
|
150
|
-
message: line.message.map(messageOf),
|
|
168
|
+
line.message = line.message.map((msg) => anyMessageToStringifiable(msg));
|
|
169
|
+
const status = await sendToServer(lines.map((line) => ({
|
|
170
|
+
message: line.message.map(messageOf).join(" "),
|
|
151
171
|
level: line.level,
|
|
152
172
|
})));
|
|
173
|
+
return status;
|
|
153
174
|
}
|
|
154
175
|
catch (err) {
|
|
155
176
|
if (logErrorFromBackend && window.console?.error) {
|
|
156
177
|
console.error("Cannot send log to backend:", err);
|
|
157
178
|
}
|
|
179
|
+
return "CANCEL";
|
|
158
180
|
}
|
|
159
181
|
}
|
|
160
|
-
function anyMessageToStringifiable(message) {
|
|
182
|
+
function anyMessageToStringifiable(message, seen = new WeakSet()) {
|
|
161
183
|
if (message === null)
|
|
162
184
|
return null;
|
|
163
185
|
if (Number.isNaN(message))
|
|
164
186
|
return "[NaN]";
|
|
165
|
-
if (Array.isArray(message))
|
|
166
|
-
|
|
187
|
+
if (Array.isArray(message)) {
|
|
188
|
+
if (seen.has(message))
|
|
189
|
+
return "[Circular Array]";
|
|
190
|
+
seen.add(message);
|
|
191
|
+
const result = message.map((item) => anyMessageToStringifiable(item, seen));
|
|
192
|
+
seen.delete(message);
|
|
193
|
+
return result;
|
|
194
|
+
}
|
|
167
195
|
if (message instanceof Error)
|
|
168
196
|
return message.message ?? message.name ?? "[Error]";
|
|
169
197
|
switch (typeof message) {
|
|
@@ -176,13 +204,18 @@ function anyMessageToStringifiable(message) {
|
|
|
176
204
|
case "bigint":
|
|
177
205
|
return `${message.toString()}n`;
|
|
178
206
|
case "function":
|
|
179
|
-
return "[Function]";
|
|
207
|
+
return message.name ? `[Function: ${message.name}]` : "[Function]";
|
|
180
208
|
case "symbol":
|
|
181
209
|
return "[Symbol]";
|
|
182
210
|
case "object": {
|
|
211
|
+
if (seen.has(message))
|
|
212
|
+
return "[Circular]";
|
|
213
|
+
seen.add(message);
|
|
183
214
|
const obj = {};
|
|
184
|
-
for (const key of Object.keys(message))
|
|
185
|
-
obj[key] = anyMessageToStringifiable(message[key]);
|
|
215
|
+
for (const key of Object.keys(message)) {
|
|
216
|
+
obj[key] = anyMessageToStringifiable(message[key], seen);
|
|
217
|
+
}
|
|
218
|
+
seen.delete(message);
|
|
186
219
|
return obj;
|
|
187
220
|
}
|
|
188
221
|
default:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paroicms/ui-logger",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.0",
|
|
4
4
|
"description": "Logger for the Admin UI front of a Paroi CMS.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"paroicms",
|
|
@@ -20,7 +20,9 @@
|
|
|
20
20
|
"scripts": {
|
|
21
21
|
"build": "tsc",
|
|
22
22
|
"clear": "rimraf dist/*",
|
|
23
|
-
"dev": "tsc --watch --preserveWatchOutput"
|
|
23
|
+
"dev": "tsc --watch --preserveWatchOutput",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"test:watch": "vitest"
|
|
24
26
|
},
|
|
25
27
|
"dependencies": {
|
|
26
28
|
"@paroicms/public-anywhere-lib": "0.37.0"
|
|
@@ -28,7 +30,8 @@
|
|
|
28
30
|
"devDependencies": {
|
|
29
31
|
"rimraf": "~6.0.1",
|
|
30
32
|
"typescript": "~5.9.2",
|
|
31
|
-
"react": "~19.1.0"
|
|
33
|
+
"react": "~19.1.0",
|
|
34
|
+
"vitest": "~3.2.3"
|
|
32
35
|
},
|
|
33
36
|
"files": [
|
|
34
37
|
"dist"
|