halua 0.0.5 → 1.1.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/lib/index.js CHANGED
@@ -1,177 +1,685 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- Level: () => Level,
24
- halua: () => halua
25
- });
26
- module.exports = __toCommonJS(index_exports);
27
-
28
- // types.ts
1
+ // src/handlers/types.ts
29
2
  var Level = /* @__PURE__ */ ((Level2) => {
3
+ Level2["Trace"] = "TRACE";
30
4
  Level2["Debug"] = "DEBUG";
31
5
  Level2["Info"] = "INFO";
6
+ Level2["Notice"] = "NOTICE";
32
7
  Level2["Warn"] = "WARN";
33
- Level2["Error"] = "ERR";
8
+ Level2["Error"] = "ERROR";
9
+ Level2["Fatal"] = "FATAL";
34
10
  return Level2;
35
11
  })(Level || {});
36
12
 
37
- // loggerCore.ts
38
- var LoggerCore = class _LoggerCore {
39
- handler = self?.console || window?.console;
40
- dateGetter = null;
41
- options = {};
42
- levelMapping = /* @__PURE__ */ new Map([
43
- ["debug", "DEBUG" /* Debug */],
44
- ["info", "INFO" /* Info */],
45
- ["warn", "WARN" /* Warn */],
46
- ["error", "ERR" /* Error */]
47
- ]);
48
- constructor(handler, options = {}) {
49
- if (handler) {
50
- this.handler = handler;
51
- }
52
- if (options.dateGetter) {
53
- this.dateGetter = options.dateGetter;
54
- delete options.dateGetter;
55
- }
56
- this.options = {
57
- ...this.options,
58
- ...options
59
- };
13
+ // src/util/level.ts
14
+ function toLevel(v) {
15
+ return {
16
+ trace: "TRACE" /* Trace */,
17
+ debug: "DEBUG" /* Debug */,
18
+ info: "INFO" /* Info */,
19
+ warn: "WARN" /* Warn */,
20
+ notice: "NOTICE" /* Notice */,
21
+ error: "ERROR" /* Error */,
22
+ fatal: "FATAL" /* Fatal */,
23
+ assert: "ERROR" /* Error */
24
+ }[v];
25
+ }
26
+
27
+ // src/util/string.ts
28
+ var defaultIgnored = /* @__PURE__ */ new Set();
29
+ function stringMatchesVar(str, ignoredStrings = defaultIgnored) {
30
+ return !ignoredStrings.has(str) && str.trim().indexOf(" ") === -1;
31
+ }
32
+ var messageFormatExcludes = /* @__PURE__ */ new Set([" ", "%a", "%w", "%t", "%l"]);
33
+ function extractNonFormatChars(f) {
34
+ let total = /* @__PURE__ */ new Set();
35
+ for (let char of f) {
36
+ if (!messageFormatExcludes.has(char)) {
37
+ total.add(char);
38
+ }
39
+ }
40
+ return total;
41
+ }
42
+ function extractTaken(f) {
43
+ let total = [];
44
+ let seq = "";
45
+ for (let rune of f) {
46
+ if (seq && (rune === "%" || rune === " ")) {
47
+ total.push(seq);
48
+ seq = "";
49
+ if (rune === "%") {
50
+ seq += rune;
51
+ }
52
+ continue;
53
+ }
54
+ seq += rune;
55
+ }
56
+ if (seq) {
57
+ total.push(seq);
58
+ }
59
+ return total;
60
+ }
61
+ function removeTailingUndefinedValues(format, log) {
62
+ if (!argsInDisposition(format) || log.withArgs) {
63
+ return format;
64
+ }
65
+ let argsIndex = format.indexOf("%a");
66
+ let withArgsIndex = format.indexOf("%w");
67
+ if (withArgsIndex < argsIndex) {
68
+ return format;
69
+ }
70
+ return format.slice(0, argsIndex + 2);
71
+ }
72
+ function argsInDisposition(format) {
73
+ let indexOfArgs = format.indexOf("%a");
74
+ let indexOfWithArgs = format.indexOf("%w");
75
+ let indexOfTimestamp = format.indexOf("%t");
76
+ let indexOfLevel = format.indexOf("l");
77
+ return Math.max(indexOfTimestamp, indexOfLevel) < Math.min(indexOfArgs, indexOfWithArgs);
78
+ }
79
+ function getConvertStartingIndex(format) {
80
+ let sum = format.indexOf("%t") + format.indexOf("%l");
81
+ if (sum === -2) {
82
+ return 0;
60
83
  }
61
- New(handler = this.handler, options = this.options) {
62
- return new _LoggerCore(handler, options);
84
+ if (sum === 0) {
85
+ return 1;
63
86
  }
64
- With(msg, ...args) {
65
- let postfix = this.options.postfix ? `${this.options.postfix} ${this.composeMsgWithArgs(msg, ...args)}` : this.composeMsgWithArgs(msg, ...args);
66
- return new _LoggerCore(this.handler, {
67
- postfix,
68
- dateGetter: this.dateGetter,
69
- minLevel: this.options.minLevel
70
- });
87
+ return 2;
88
+ }
89
+ function extractLevels(level) {
90
+ if (typeof level !== "string") {
91
+ return ["INFO" /* Info */, 0];
71
92
  }
72
- debug(msg, ...args) {
73
- if (this.canLogByMinLevelRestriction("DEBUG" /* Debug */)) {
74
- this.log("debug", msg, ...args);
93
+ let data = level.split("+");
94
+ if (data.length !== 2) {
95
+ let levels = ["TRACE" /* Trace */, "DEBUG" /* Debug */, "INFO" /* Info */, "WARN" /* Warn */, "NOTICE" /* Notice */, "ERROR" /* Error */, "FATAL" /* Fatal */];
96
+ for (let l of levels) {
97
+ if (level.includes(l)) {
98
+ return [l, Math.trunc(level.split(l)[1])];
99
+ }
75
100
  }
76
101
  }
77
- info(msg, ...args) {
78
- if (this.canLogByMinLevelRestriction("INFO" /* Info */)) {
79
- this.log("info", msg, ...args);
102
+ return [data[0], Math.trunc(data[1]) || 0];
103
+ }
104
+
105
+ // src/errors.ts
106
+ var FailedToCallHandlerLog = class extends Error {
107
+ };
108
+
109
+ // src/HandlersBalancer.ts
110
+ var MajorLevelMap = /* @__PURE__ */ new Map([
111
+ ["FATAL" /* Fatal */, /* @__PURE__ */ new Set(["FATAL" /* Fatal */])],
112
+ ["ERROR" /* Error */, /* @__PURE__ */ new Set(["FATAL" /* Fatal */, "ERROR" /* Error */])],
113
+ ["WARN" /* Warn */, /* @__PURE__ */ new Set(["FATAL" /* Fatal */, "ERROR" /* Error */, "WARN" /* Warn */])],
114
+ ["NOTICE" /* Notice */, /* @__PURE__ */ new Set(["FATAL" /* Fatal */, "ERROR" /* Error */, "WARN" /* Warn */, "NOTICE" /* Notice */])],
115
+ ["INFO" /* Info */, /* @__PURE__ */ new Set(["FATAL" /* Fatal */, "ERROR" /* Error */, "WARN" /* Warn */, "NOTICE" /* Notice */, "INFO" /* Info */])],
116
+ ["DEBUG" /* Debug */, /* @__PURE__ */ new Set(["FATAL" /* Fatal */, "ERROR" /* Error */, "WARN" /* Warn */, "NOTICE" /* Notice */, "INFO" /* Info */, "DEBUG" /* Debug */])],
117
+ ["TRACE" /* Trace */, /* @__PURE__ */ new Set(["FATAL" /* Fatal */, "ERROR" /* Error */, "WARN" /* Warn */, "NOTICE" /* Notice */, "INFO" /* Info */, "DEBUG" /* Debug */, "TRACE" /* Trace */])]
118
+ ]);
119
+ var HandlersBalancer = class {
120
+ constructor(level, handlers) {
121
+ this.level = level;
122
+ this.handlers = handlers;
123
+ }
124
+ map = /* @__PURE__ */ new Map();
125
+ sendLog(log) {
126
+ this.discover(log.level);
127
+ this.send(log);
128
+ }
129
+ reset() {
130
+ this.map.clear();
131
+ }
132
+ discover(level) {
133
+ if (this.map.get(level)) {
134
+ return;
135
+ }
136
+ let discovered = [];
137
+ this.map.set(level, discovered);
138
+ for (let h of this.handlers) {
139
+ if (h.exact) {
140
+ if (h.exact.some((l) => l === level)) {
141
+ discovered.push(h);
142
+ }
143
+ continue;
144
+ }
145
+ if (this.canSend(extractLevels(level), h.level)) {
146
+ discovered.push(h);
147
+ }
80
148
  }
81
149
  }
82
- warn(msg, ...args) {
83
- if (this.canLogByMinLevelRestriction("WARN" /* Warn */)) {
84
- this.log("warn", msg, ...args);
150
+ send(log) {
151
+ try {
152
+ for (let h of this.map.get(log.level) || []) {
153
+ h.skipDeepCopyWhenSendingLog ? h.log(log) : h.log(structuredClone(log));
154
+ }
155
+ } catch (e) {
156
+ throw new FailedToCallHandlerLog(`Unable to call .log method of a handler, ${e}`, { cause: e });
85
157
  }
86
158
  }
87
- err(msg, ...args) {
88
- this.log("error", msg, ...args);
159
+ canSend(l, to = this.level || "TRACE" /* Trace */) {
160
+ let tol = extractLevels(to);
161
+ return this.majorLevelCheck(l[0], tol[0]) + this.minorLevelCheck(l[1], tol[1]) > 0;
89
162
  }
90
- assert(value, msg, ...args) {
91
- if (!value) {
92
- this.log("error", `assertion failed: ${msg}`, ...args);
163
+ majorLevelCheck(l, to) {
164
+ if (!MajorLevelMap.get(to).has(l)) {
165
+ return -1;
93
166
  }
167
+ return l === to ? 0 : 1;
168
+ }
169
+ minorLevelCheck(l, to) {
170
+ return l >= to ? 1 : 0;
171
+ }
172
+ };
173
+
174
+ // src/main.ts
175
+ var Halua = class _Halua {
176
+ constructor(passed, options = {}) {
177
+ this.options = options;
178
+ this.passedHandlers = passed;
179
+ this.options.messageFormat ??= "%t %l %a | %w";
180
+ this.validateHandlers(this.buildHandlers(passed));
181
+ this.handlers = this.buildHandlers(passed);
182
+ this.balancer = new HandlersBalancer(this.options.level || "TRACE" /* Trace */, this.handlers);
183
+ }
184
+ handlers = [];
185
+ passedHandlers;
186
+ balancer;
187
+ New(arg1 = this.passedHandlers, arg2 = this.options) {
188
+ if (Array.isArray(arg1)) {
189
+ this.validateHandlers(this.buildHandlers(arg1));
190
+ return new _Halua(arg1, { ...arg2 });
191
+ }
192
+ if (this.supposeIsHandler(arg1)) {
193
+ return new _Halua(arg1, { ...arg2 });
194
+ }
195
+ if (Object.keys(arg1).length) {
196
+ return new _Halua(this.passedHandlers, { ...arg1 });
197
+ }
198
+ this.validateHandlers(this.buildHandlers(arg1));
199
+ return new _Halua(arg1, { ...arg2 });
200
+ }
201
+ With(...args) {
202
+ return new _Halua(this.passedHandlers, { ...this.options, withArgs: (this.options.withArgs || []).concat(args) });
203
+ }
204
+ withMessageFormat(f) {
205
+ this.unlinkInheritance();
206
+ this.options.messageFormat = f;
207
+ return this;
94
208
  }
95
209
  setHandler(handler) {
96
- this.handler = handler;
97
- }
98
- setDateGetter(getter) {
99
- this.dateGetter = getter;
100
- }
101
- log(to, msg, ...args) {
102
- let value = msg;
103
- value = this.composeMsgWithArgs(value, ...args);
104
- if (this.options.postfix) {
105
- value = this.appendValue(this.options.postfix, value);
106
- }
107
- let level = this.levelMapping.get(to);
108
- value = this.formatWithDate(this.formatWithLevel(level, value));
109
- this.handler[to](value);
110
- }
111
- composeMsgWithArgs(msg, ...args) {
112
- if (args.length === 1) {
113
- return this.appendValue(args[0], msg);
114
- }
115
- let totalMsg = msg;
116
- let key = "";
117
- for (let arg of args) {
118
- if (!key) {
119
- key = arg;
120
- continue;
210
+ this.validateHandlers(this.buildHandlers(handler));
211
+ this.handlers = this.buildHandlers(handler);
212
+ this.updateBalancer();
213
+ }
214
+ appendHandler(handler) {
215
+ this.validateHandlers(this.buildHandlers(handler));
216
+ this.handlers.push(...this.buildHandlers(handler));
217
+ this.updateBalancer();
218
+ }
219
+ logTo(level, ...args) {
220
+ this.balancer.sendLog(this.composeLog(level, true, ...args));
221
+ }
222
+ trace(...args) {
223
+ this.sendToHandler("trace", true, ...args);
224
+ }
225
+ debug(...args) {
226
+ this.sendToHandler("debug", true, ...args);
227
+ }
228
+ info(...args) {
229
+ this.sendToHandler("info", true, ...args);
230
+ }
231
+ warn(...args) {
232
+ this.sendToHandler("warn", true, ...args);
233
+ }
234
+ notice(...args) {
235
+ this.sendToHandler("notice", true, ...args);
236
+ }
237
+ error(...args) {
238
+ this.sendToHandler("error", true, ...args);
239
+ }
240
+ fatal(...args) {
241
+ this.sendToHandler("fatal", true, ...args);
242
+ }
243
+ assert(assertion, ...args) {
244
+ if (assertion) {
245
+ return;
246
+ }
247
+ this.sendToHandler("assert", assertion, ...args);
248
+ }
249
+ updateBalancer() {
250
+ this.balancer = new HandlersBalancer(this.options.level || "TRACE" /* Trace */, this.handlers);
251
+ }
252
+ sendToHandler(field, assertion = true, ...args) {
253
+ this.balancer.sendLog(this.composeLog(toLevel(field), assertion, ...args));
254
+ }
255
+ composeLog(level, assertion, ...args) {
256
+ return {
257
+ timestamp: Date.now(),
258
+ args: args || [],
259
+ withArgs: this.options?.withArgs || null,
260
+ messageFormat: this.options.messageFormat,
261
+ assertion,
262
+ level,
263
+ leveling: extractLevels(level)
264
+ };
265
+ }
266
+ validateHandlers(v) {
267
+ let handlers = Array.isArray(v) ? v : [v];
268
+ if (this.options.errorPolicy === "throw") {
269
+ for (let h of handlers) {
270
+ if (!this.supposeIsHandler(h)) {
271
+ throw new Error("Passed handlers does not satisfy Handler interface");
272
+ }
273
+ }
274
+ }
275
+ }
276
+ supposeIsHandler(v) {
277
+ return Object.prototype.hasOwnProperty.call(v.__proto__, "log") || Object.prototype.hasOwnProperty.call(v, "log");
278
+ }
279
+ unlinkInheritance() {
280
+ this.options = structuredClone(this.options);
281
+ }
282
+ buildHandlers(passed) {
283
+ let entries = Array.isArray(passed) ? passed : [passed];
284
+ return entries.map((v) => v());
285
+ }
286
+ };
287
+
288
+ // src/handlers/WebConsoleHandler/webConsoleUtils.ts
289
+ function getColorKey(level) {
290
+ return {
291
+ ["TRACE" /* Trace */]: "grey",
292
+ ["DEBUG" /* Debug */]: "purple",
293
+ ["INFO" /* Info */]: "blue",
294
+ ["WARN" /* Warn */]: "orange",
295
+ ["NOTICE" /* Notice */]: "orange",
296
+ ["ERROR" /* Error */]: "red",
297
+ ["FATAL" /* Fatal */]: "red"
298
+ }[level];
299
+ }
300
+
301
+ // src/util/array.ts
302
+ function arrayed(v) {
303
+ return Array.isArray(v) ? v : typeof v === "undefined" ? [] : [v];
304
+ }
305
+
306
+ // src/util/date.ts
307
+ function getPrettyDate(t) {
308
+ let d = new Date(t);
309
+ return `${d.toLocaleDateString()} ${d.toLocaleTimeString()}`;
310
+ }
311
+
312
+ // src/handlers/WebConsoleHandler/WebConsoleHandler.ts
313
+ function NewWebConsoleHandler(c = console, options = {}) {
314
+ return () => new class WebConsoleLog {
315
+ constructor(options2) {
316
+ this.options = options2;
317
+ this.level = options2.level;
318
+ this.exact = options2.exact ? arrayed(options2.exact) : void 0;
319
+ this.options = options2 || {};
320
+ this.options.fetchBrowserThemeOnInstanceCreation ??= true;
321
+ this.messageFormatRaw = options2.messageFormat ?? this.messageFormatRaw;
322
+ this.messageFormat = Array.from(extractTaken(this.messageFormatRaw));
323
+ if (!this.options.pretty) {
324
+ return;
121
325
  }
122
- totalMsg = this.appendValue(`${key}="${arg}"`, totalMsg);
123
- key = "";
326
+ if (this.options.fetchBrowserThemeOnInstanceCreation) {
327
+ if (window?.matchMedia && window?.matchMedia("(prefers-color-scheme: dark)").matches) {
328
+ this.colors = new Map(this.darkColors);
329
+ } else {
330
+ this.colors = new Map(this.lightColors);
331
+ }
332
+ delete this.options.fetchBrowserThemeOnInstanceCreation;
333
+ } else {
334
+ this.colors = new Map(this.lightColors);
335
+ }
336
+ }
337
+ skipDeepCopyWhenSendingLog = false;
338
+ messageFormat = [];
339
+ level;
340
+ exact;
341
+ messageFormatRaw = "%t %l %a | %w";
342
+ colors = /* @__PURE__ */ new Map([]);
343
+ // bg chrome #fefbff
344
+ lightColors = /* @__PURE__ */ new Map([
345
+ ["grey", "#565656"],
346
+ ["green", "#224912"],
347
+ ["blue", "#195367"],
348
+ ["purple", "#8A228A"],
349
+ ["orange", "#7F3E1E"],
350
+ ["red", "#A51818"]
351
+ ]);
352
+ // bg chrome #27242a
353
+ darkColors = /* @__PURE__ */ new Map([
354
+ ["grey", "#C9C9C9"],
355
+ ["green", "#73CE73"],
356
+ ["blue", "#93B9E7"],
357
+ ["purple", "#DCA4E9"],
358
+ ["orange", "#EEC5A8"],
359
+ ["red", "#FC9292"]
360
+ ]);
361
+ get linkArguments() {
362
+ return this.options.linkArguments !== void 0 && !this.options.linkArguments;
363
+ }
364
+ log(log) {
365
+ this.sendLog(log);
366
+ }
367
+ setDateGetter(dateGetter) {
368
+ this.options.dateGetter = dateGetter;
124
369
  }
125
- if (key) {
126
- totalMsg = this.appendValue(`${key}=${void 0}`, totalMsg);
370
+ sendLog(log) {
371
+ let args = this.insertInternalEntries(log);
372
+ if (log.level === "DEBUG" /* Debug */) {
373
+ c.debug(this.composeConsoleSubstitution(args), ...args);
374
+ return;
375
+ }
376
+ if (log.level === "WARN" /* Warn */ && this.options.useWarn) {
377
+ c.warn(this.composeConsoleSubstitution(args), ...args);
378
+ return;
379
+ }
380
+ if (log.level === "ERROR" /* Error */ && this.options.useError) {
381
+ c.error(this.composeConsoleSubstitution(args), ...args);
382
+ return;
383
+ }
384
+ c.info(this.composeConsoleSubstitution(args), ...args);
127
385
  }
128
- return totalMsg;
386
+ insertInternalEntries(log) {
387
+ if (this.options.pretty) {
388
+ return this.prepareMessagePretty(log);
389
+ }
390
+ return this.prepareMessage(log);
391
+ }
392
+ composeConsoleSubstitution(data, startingVarConvertIndex = 2) {
393
+ let str = "";
394
+ startingVarConvertIndex = getConvertStartingIndex(this.messageFormatRaw);
395
+ if (this.options.pretty) {
396
+ startingVarConvertIndex = 3;
397
+ }
398
+ for (let i = this.options.pretty ? startingVarConvertIndex : 0; i < data.length; i++) {
399
+ let last = i === data.length - 1;
400
+ let v = data[i];
401
+ let takenNames = extractTaken(this.messageFormatRaw);
402
+ let vWithEqualSign = typeof v === "string" && stringMatchesVar(v, /* @__PURE__ */ new Set([]));
403
+ let nextVWithEqualSign = !last && typeof data[i + 1] === "string" && stringMatchesVar(data[i + 1], /* @__PURE__ */ new Set([]));
404
+ if (nextVWithEqualSign) {
405
+ startingVarConvertIndex = Math.max(startingVarConvertIndex, i);
406
+ }
407
+ if (!this.linkArguments && !takenNames.includes(v) && !last && i > startingVarConvertIndex && vWithEqualSign) {
408
+ data[i] = `${v} =`;
409
+ }
410
+ if (typeof v === "string") {
411
+ str += `%s${last ? "" : " "}`;
412
+ continue;
413
+ }
414
+ if (typeof v === "number") {
415
+ str += `%d${last ? "" : " "}`;
416
+ continue;
417
+ }
418
+ str += `%o${last ? "" : " "}`;
419
+ }
420
+ return str;
421
+ }
422
+ prepareMessagePretty(log) {
423
+ let format = [...this.messageFormat];
424
+ if (!log.withArgs) {
425
+ format = format.slice(0, format.indexOf("%a") + 1);
426
+ }
427
+ let message = [];
428
+ let colors = "";
429
+ let colorKeys = [];
430
+ for (let i = 0; i <= format.length - 1; i++) {
431
+ if (format[i] === "%w") {
432
+ message.push(...log.withArgs || []);
433
+ continue;
434
+ }
435
+ if (format[i] === "%t") {
436
+ colors += `%c${this.prepareDate(log.timestamp)} `;
437
+ colorKeys.push(`color:${this.options.customColors?.get("grey") || this.colors.get("grey")}`);
438
+ continue;
439
+ }
440
+ if (format[i] === "%a") {
441
+ colors += "%c";
442
+ colorKeys.push(`color:${this.options.customColors?.get("green") || this.colors.get("green")}`);
443
+ message.push(...log.args);
444
+ continue;
445
+ }
446
+ if (format[i] === "%l") {
447
+ colors += `%c${log.level}`;
448
+ let colorKey = getColorKey(log.leveling[0]);
449
+ colorKeys.push(`color:${this.options.customColors?.get(colorKey) || this.colors.get(colorKey)}`);
450
+ continue;
451
+ }
452
+ message.push(format[i]);
453
+ }
454
+ return [colors, ...colorKeys, ...message];
455
+ }
456
+ prepareMessage(log) {
457
+ let format = [...this.messageFormat];
458
+ if (!log.withArgs) {
459
+ format = format.slice(0, format.indexOf("%a") + 1);
460
+ }
461
+ let message = [];
462
+ for (let i = 0; i <= format.length - 1; i++) {
463
+ if (format[i] === "%w") {
464
+ message.push(...log.withArgs || []);
465
+ continue;
466
+ }
467
+ if (format[i] === "%t") {
468
+ message.push(this.prepareDate(log.timestamp));
469
+ continue;
470
+ }
471
+ if (format[i] === "%a") {
472
+ message.push(...log.args);
473
+ continue;
474
+ }
475
+ if (format[i] === "%l") {
476
+ message.push(log.level);
477
+ continue;
478
+ }
479
+ message.push(format[i]);
480
+ }
481
+ return message;
482
+ }
483
+ prepareDate(t) {
484
+ if (this.options.dateGetter) {
485
+ return this.options.dateGetter(t);
486
+ }
487
+ return getPrettyDate(t);
488
+ }
489
+ }(options);
490
+ }
491
+
492
+ // src/util/dataReplacer.ts
493
+ function replaceDataBeforeStringify(value) {
494
+ if (typeof value === "symbol") {
495
+ return value.toString();
129
496
  }
130
- formatWithLevel(level, msg) {
131
- return this.shiftValue(level, msg);
497
+ if (value instanceof Set) {
498
+ return Array.from(value);
132
499
  }
133
- formatWithDate(msg) {
134
- if (this.dateGetter) {
500
+ if (value instanceof Map) {
501
+ let obj = {};
502
+ for (let key of value.keys()) {
503
+ obj[key] = value.get(key);
504
+ }
505
+ return obj;
506
+ }
507
+ if (value instanceof Error) {
508
+ return value.toString();
509
+ }
510
+ return value;
511
+ }
512
+
513
+ // src/handlers/JSONHandler/JSONHandler.ts
514
+ function NewJSONHandler(send, options = {}) {
515
+ return () => new class JSONLog {
516
+ constructor(options2) {
517
+ this.options = options2;
518
+ this.level = options2.level;
519
+ this.exact = options2.exact ? arrayed(options2.exact) : void 0;
520
+ this.options = options2 || {};
521
+ }
522
+ level;
523
+ exact;
524
+ takenNames = /* @__PURE__ */ new Set(["timestamp", "level", "args"]);
525
+ log(log) {
526
+ this.sendLog(log);
527
+ }
528
+ setDateGetter(getter) {
529
+ this.options.dateGetter = getter;
530
+ }
531
+ sendLog(log) {
135
532
  try {
136
- return this.shiftValue(this.dateGetter().toString(), msg);
137
- } catch (_) {
138
- this.err("date getter catches an error, check your date getter func");
533
+ delete log.assertion;
534
+ delete log.messageFormat;
535
+ delete log.leveling;
536
+ log.timestamp = this.formatDate(log.timestamp);
537
+ send(JSON.stringify(this.flattenLinkedArguments(log), this.replacer.bind(this)));
538
+ } catch (err) {
539
+ if (log.level !== "ERROR" /* Error */) {
540
+ this.log({
541
+ args: [`err while trying to stringify JSON ${err}`],
542
+ timestamp: log.timestamp,
543
+ level: "ERROR" /* Error */,
544
+ leveling: ["ERROR" /* Error */, 0]
545
+ });
546
+ }
547
+ }
548
+ }
549
+ formatDate(timestamp) {
550
+ if (this.options?.dateGetter) {
551
+ return this.options.dateGetter(timestamp);
552
+ }
553
+ return new Date(timestamp).toISOString();
554
+ }
555
+ flattenLinkedArguments(log) {
556
+ if (this.options?.linkArguments !== void 0 && this.options?.linkArguments === false) {
557
+ return log;
558
+ }
559
+ if (log.withArgs) {
560
+ this.composeLogWithArgsFlattened(log);
561
+ }
562
+ delete log.withArgs;
563
+ return log;
564
+ }
565
+ composeLogWithArgsFlattened(log) {
566
+ let composedLog = log;
567
+ let name = "";
568
+ for (let arg of log.withArgs) {
569
+ if (typeof arg === "string" && stringMatchesVar(arg)) {
570
+ name = arg;
571
+ continue;
572
+ }
573
+ if (name && !this.takenNames.has(name)) {
574
+ composedLog[name] = arg;
575
+ name = "";
576
+ continue;
577
+ }
578
+ log.args?.push(arg);
139
579
  }
580
+ return log;
140
581
  }
141
- return this.shiftValue(this.getDateInLocaleString(), msg);
582
+ replacer(_, value) {
583
+ if (this.options.replaceBeforeStringify) {
584
+ let v = this.options.replaceBeforeStringify(value);
585
+ if (v !== null) {
586
+ return v;
587
+ }
588
+ }
589
+ return replaceDataBeforeStringify(value);
590
+ }
591
+ }(options);
592
+ }
593
+
594
+ // src/util/stringify.ts
595
+ function stringifyValue(value, stringifier = JSON.stringify) {
596
+ if (typeof value === "symbol") {
597
+ return value.toString();
598
+ }
599
+ if (value instanceof Set) {
600
+ return `Set[${Array.from(value)}]`;
142
601
  }
143
- shiftValue(value, to) {
144
- return `${value} ${to}`;
602
+ if (value instanceof Error) {
603
+ return value.toString();
145
604
  }
146
- appendValue(value, to) {
147
- return `${to} ${value}`;
605
+ if (Array.isArray(value)) {
606
+ return `[${value}]`;
148
607
  }
149
- getDateInLocaleString() {
150
- let d = /* @__PURE__ */ new Date();
151
- return `${d.toLocaleDateString()} ${d.toLocaleTimeString()}`;
608
+ if (typeof value === "string") {
609
+ return `${value}`;
152
610
  }
153
- canLogByMinLevelRestriction(level) {
154
- const { minLevel } = this.options;
155
- if (!minLevel || level === "ERR" /* Error */) {
156
- return true;
611
+ return stringifier(value, (_, data) => replaceDataBeforeStringify(data));
612
+ }
613
+
614
+ // src/handlers/TextHandler/TextHandler.ts
615
+ function NewTextHandler(send, options = {}) {
616
+ return () => new class TextLog {
617
+ constructor(options2) {
618
+ this.options = options2;
619
+ this.level = options2.level;
620
+ this.exact = options2.exact ? arrayed(options2.exact) : void 0;
621
+ }
622
+ skipDeepCopyWhenSendingLog = true;
623
+ level;
624
+ exact;
625
+ get linkArguments() {
626
+ return this.options.linkArguments !== void 0 && !this.options.linkArguments;
627
+ }
628
+ log(log) {
629
+ this.sendLog(log);
157
630
  }
158
- if (level === "WARN" /* Warn */) {
159
- return minLevel !== "ERR" /* Error */;
631
+ sendLog(log) {
632
+ let args = "";
633
+ let withArgs = "";
634
+ let msg = this.options.messageFormat || log.messageFormat;
635
+ if (log.args) {
636
+ args = this.composeVariablesString(msg, log.args);
637
+ }
638
+ if (log.withArgs) {
639
+ withArgs = this.composeVariablesString(msg, log.withArgs);
640
+ }
641
+ msg = removeTailingUndefinedValues(msg, log);
642
+ send(
643
+ msg.replace("%w", withArgs).replace("%a", args).replace("%l", log.level).replace(
644
+ "%t",
645
+ this.options.dateGetter?.(log.timestamp) ?? getPrettyDate(log.timestamp)
646
+ )
647
+ );
160
648
  }
161
- if (level === "INFO" /* Info */) {
162
- return minLevel !== "WARN" /* Warn */ && minLevel !== "ERR" /* Error */;
649
+ composeVariablesString(format, data) {
650
+ let str = "";
651
+ let excluded = extractNonFormatChars(format);
652
+ for (let i = 0; i < data.length; i++) {
653
+ let last = i === data.length - 1;
654
+ let nextIsNotLinked = typeof data[i + 1] === "string" && stringMatchesVar(data[i + 1], excluded);
655
+ let v = data[i];
656
+ if (!this.linkArguments && !last && typeof v === "string" && stringMatchesVar(v, excluded) && !nextIsNotLinked) {
657
+ str += `${v}=${this.formatValue(data[i + 1])} `;
658
+ i += 1;
659
+ continue;
660
+ }
661
+ str += `${this.formatValue(v)}${last ? "" : " "}`;
662
+ }
663
+ return str.trim();
163
664
  }
164
- if (level === "DEBUG" /* Debug */) {
165
- return minLevel === "DEBUG" /* Debug */;
665
+ formatValue(v) {
666
+ if (this.options.replaceBeforeStringify) {
667
+ let val = this.options.replaceBeforeStringify(v);
668
+ if (val !== null) {
669
+ return val;
670
+ }
671
+ }
672
+ return stringifyValue(v, this.options.stringifier);
166
673
  }
167
- return true;
168
- }
169
- };
674
+ }(options);
675
+ }
170
676
 
171
- // index.ts
172
- var halua = new LoggerCore();
173
- // Annotate the CommonJS export names for ESM import in node:
174
- 0 && (module.exports = {
677
+ // src/index.ts
678
+ var halua = new Halua(NewWebConsoleHandler());
679
+ export {
175
680
  Level,
681
+ NewJSONHandler,
682
+ NewTextHandler,
683
+ NewWebConsoleHandler,
176
684
  halua
177
- });
685
+ };