@pistonite/pure 0.26.3 → 0.26.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pistonite/pure",
3
- "version": "0.26.3",
3
+ "version": "0.26.5",
4
4
  "type": "module",
5
5
  "description": "Pure TypeScript libraries for my projects",
6
6
  "homepage": "https://github.com/Pistonite/pure",
@@ -26,11 +26,11 @@
26
26
  "url": "git+https://github.com/Pistonite/pure.git",
27
27
  "directory": "packages/pure"
28
28
  },
29
- "dependencies": {
30
- "denque": "2.1.0"
31
- },
32
29
  "devDependencies": {
33
- "vitest": "^3.1.1",
34
- "mono-dev": "0.1.2"
30
+ "vitest": "^3.2.4",
31
+ "mono-dev": "0.2.2"
32
+ },
33
+ "dependencies": {
34
+ "denque": "^2.1.0"
35
35
  }
36
36
  }
package/src/log/index.ts CHANGED
@@ -1,56 +1,154 @@
1
1
  /**
2
2
  * Client side log util
3
3
  *
4
+ * This is rather simple logging stuff with the primary focus
5
+ * being easy to debug.
6
+ *
7
+ * Use {@link logger} to create a logger with a name and a color,
8
+ * then use one of the {@link LoggerFactory} methods to setup the logging level.
9
+ *
10
+ * There are 3 levels of logging:
11
+ * 1. (Default) Warnings and Errors only
12
+ * 2. Also log info messages
13
+ * 3. Also log debug messages.
14
+ *
15
+ * Each logger can turn on info and debug logging separately, or it can
16
+ * be turned on at the global level for debugging.
17
+ *
18
+ * You can also turn off each logger individually or at global level for debugging.
19
+ *
20
+ * Due to the nature of JS, all logging calls, even when turned off, will incur
21
+ * some small runtime overhead. While we could remove debug calls
22
+ * for release build, that's currently not done (and it would require
23
+ * bundler to inline the call to remove the call completely, which might
24
+ * not be the case)
25
+ *
4
26
  * @module
5
27
  */
6
28
 
7
- import Denque from "denque";
8
29
  import { errstr } from "../result/index.ts";
9
30
 
10
- const LIMIT = 500;
31
+ export const LogLevel = {
32
+ Off: 0,
33
+ High: 1,
34
+ Info: 2,
35
+ Debug: 3,
36
+ } as const;
37
+ export type LogLevel = (typeof LogLevel)[keyof typeof LogLevel];
11
38
 
12
- /** Global log queue */
13
- const LogQueue = new Denque<string>();
14
- function pushLog(msg: string) {
15
- if (LogQueue.length > LIMIT) {
16
- LogQueue.shift();
17
- }
18
- LogQueue.push(`[${new Date().toISOString()}]${msg}`);
19
- }
39
+ let globalLevel: LogLevel = LogLevel.High;
40
+ /**
41
+ * Suppress ALL logging.
42
+ *
43
+ * This overrides logger-level settings
44
+ */
45
+ export const globalLogOff = () => (globalLevel = 0);
46
+ /**
47
+ * Enable +info logging for ALL loggers
48
+ *
49
+ * This overrides logger-level settings
50
+ */
51
+ export const globalLogInfo = () => (globalLevel = 2);
52
+ /**
53
+ * Enable +debug logging for ALL loggers
54
+ *
55
+ * This overrides logger-level settings
56
+ */
57
+ export const globalLogDebug = () => (globalLevel = 3);
20
58
 
21
- /** Get the current log */
22
- export function getLogLines(): string[] {
23
- return LogQueue.toArray();
24
- }
59
+ /** Create a logger creator. Use the factory methods to finish making the logger */
60
+ export const logger = (name: string, color?: string): LoggerFactory => {
61
+ return {
62
+ default: () => new LoggerImpl(name, color, LogLevel.High),
63
+ debug: () => new LoggerImpl(name, color, LogLevel.Debug),
64
+ info: () => new LoggerImpl(name, color, LogLevel.Info),
65
+ off: () => new LoggerImpl(name, color, LogLevel.Off),
66
+ };
67
+ };
68
+
69
+ export type LoggerFactory = {
70
+ /** Standard important logger (warning and errors) */
71
+ default(): Logger;
72
+ /** Enable +info +debug logging for this logger */
73
+ debug(): Logger;
74
+ /** Enable +info logging for this logger */
75
+ info(): Logger;
76
+ /** Stop all logging, including warn and error */
77
+ off(): Logger;
78
+ };
79
+
80
+ export type Logger = {
81
+ /** Log a debug message */
82
+ debug(obj: unknown): void;
83
+ /** Log an info message */
84
+ info(obj: unknown): void;
85
+ /** Log a warning message */
86
+ warn(obj: unknown): void;
87
+ /** Log an error message */
88
+ error(obj: unknown): void;
89
+ };
25
90
 
26
- /** A general-purpose client side logger */
27
- export class Logger {
28
- /** The prefix of the logger */
29
- private prefix: string;
91
+ class LoggerImpl implements Logger {
92
+ name: string;
93
+ color: string | undefined;
94
+ level: LogLevel;
30
95
 
31
- constructor(prefix: string) {
32
- this.prefix = prefix;
96
+ constructor(name: string, color: string | undefined, level: LogLevel) {
97
+ this.name = name;
98
+ this.color =
99
+ "padding:0 3x;color:white" + (color ? `;background:${color}` : "");
100
+ this.level = level;
33
101
  }
34
102
 
35
- /** Log an info message */
36
- public info(msg: string) {
37
- const msgWithPrefix = `[${this.prefix}] ${msg}`;
38
- self.console.info(msgWithPrefix);
39
- pushLog(msgWithPrefix);
103
+ debug(obj: unknown) {
104
+ if (globalLevel !== LogLevel.Debug && this.level !== LogLevel.Debug) {
105
+ return;
106
+ }
107
+ console.log(
108
+ `%cDEBUG%c${this.name}%c ${obj}`,
109
+ "background:gray;color:white;padding:0 3px",
110
+ this.color,
111
+ "color:inherit;background:inherit",
112
+ );
40
113
  }
41
114
 
42
- /** Log a warning message */
43
- public warn(msg: string) {
44
- const msgWithPrefix = `[${this.prefix}] ${msg}`;
45
- self.console.warn(msgWithPrefix);
46
- pushLog(msgWithPrefix);
115
+ info(obj: unknown) {
116
+ if (globalLevel < LogLevel.Info && this.level < LogLevel.Info) {
117
+ return;
118
+ }
119
+ console.log(
120
+ `%cINFO%c${this.name}%c ${obj}`,
121
+ "background:green;color:white;padding:0 3px",
122
+ this.color,
123
+ "color:inherit;background:inherit",
124
+ );
47
125
  }
48
126
 
49
- /** Log an error message */
50
- public error(msg: unknown) {
51
- const msgWithPrefix = `[${this.prefix}] ${errstr(msg)}`;
52
- self.console.error(msgWithPrefix);
53
- self.console.error(msg);
54
- pushLog(msgWithPrefix);
127
+ warn(obj: unknown) {
128
+ if (globalLevel < LogLevel.High || this.level < LogLevel.High) {
129
+ return;
130
+ }
131
+ console.warn(
132
+ `%cWARN%c${this.name}%c ${obj}`,
133
+ "background:orange;color:white;padding:0 3px",
134
+ this.color,
135
+ "color:inherit;background:inherit",
136
+ );
137
+ }
138
+
139
+ error(obj: unknown) {
140
+ if (globalLevel < LogLevel.High || this.level < LogLevel.High) {
141
+ return;
142
+ }
143
+ const msg = errstr(obj);
144
+ console.error(
145
+ `%cERROR%c${this.name}%c ${msg}`,
146
+ "background:orange;color:white;padding:0 3px",
147
+ this.color,
148
+ "color:inherit;background:inherit",
149
+ );
150
+ if (msg !== obj) {
151
+ console.error(obj);
152
+ }
55
153
  }
56
154
  }
@@ -0,0 +1,26 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import { idgen, safeidgen } from "./idgen.ts";
4
+
5
+ describe("idgen", () => {
6
+ it("idgen generates ids", () => {
7
+ const idgen1 = idgen();
8
+ const idgen2 = idgen();
9
+ expect(idgen1()).toBe(2);
10
+ expect(idgen2()).toBe(2);
11
+ expect(idgen1()).toBe(3);
12
+ expect(idgen2()).toBe(3);
13
+ expect(idgen1()).toBe(4);
14
+ expect(idgen2()).toBe(4);
15
+ });
16
+ it("safeidgen wraps", () => {
17
+ const x = safeidgen(5);
18
+ expect(x()).toBe(2);
19
+ expect(x()).toBe(3);
20
+ expect(x()).toBe(4);
21
+ expect(x()).toBe(1);
22
+ expect(x()).toBe(2);
23
+ expect(x()).toBe(3);
24
+ expect(x()).toBe(4);
25
+ });
26
+ });
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Return an id generator that will generate ids in order
3
+ * from 1 to n, wrapping around to 1 when it's n
4
+ */
5
+ export const safeidgen = (n: number): (() => number) => {
6
+ let x = 1;
7
+ return () => {
8
+ x += 1;
9
+ if (x === n) {
10
+ x = 1;
11
+ }
12
+ return x;
13
+ };
14
+ };
15
+
16
+ /**
17
+ * Return an id generator that returns bigint,
18
+ * starting from 1n, and will always return a new bigint
19
+ */
20
+ export const bidgen = (): (() => bigint) => {
21
+ let x = 1n;
22
+ return () => {
23
+ x += 1n;
24
+ return x;
25
+ };
26
+ };
27
+
28
+ /**
29
+ * Returns an id generator that returns number staring from 1
30
+ * and always increasing. The number could become inaccurate
31
+ * (not integer) when exceeding Number.MAX_SAFE_INTEGER (which
32
+ * is 2^53 - 1
33
+ */
34
+ export const idgen = (): (() => number) => {
35
+ let x = 1;
36
+ return () => {
37
+ x += 1;
38
+ return x;
39
+ };
40
+ };
@@ -7,4 +7,5 @@
7
7
  export { cell, type CellConstructor, type Cell } from "./cell.ts";
8
8
  export { persist, type PersistConstructor, type Persist } from "./persist.ts";
9
9
  export * from "./erc.ts";
10
- export * from "./asyncerc.ts";
10
+ export * from "./async_erc.ts";
11
+ export * from "./idgen.ts";
package/src/pref/dark.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { persist } from "../memory/persist.ts";
2
- import { injectStyle } from "./injectStyle.ts";
2
+ import { injectStyle } from "./inject_style.ts";
3
3
 
4
4
  const dark = persist({
5
5
  initial: false,
package/src/pref/index.ts CHANGED
@@ -8,5 +8,5 @@
8
8
  * @module
9
9
  */
10
10
  export * from "./dark.ts";
11
- export * from "./injectStyle.ts";
11
+ export * from "./inject_style.ts";
12
12
  export * from "./locale.ts";
@@ -189,7 +189,7 @@ export const setLocale = (newLocale: string): boolean => {
189
189
  return true;
190
190
  }
191
191
  settingLocale = supported;
192
- onBeforeChangeHook(supported).then((result) => {
192
+ void onBeforeChangeHook(supported).then((result) => {
193
193
  if (result.err) {
194
194
  return;
195
195
  }
package/src/sync/batch.ts CHANGED
@@ -214,7 +214,7 @@ class BatchImpl<TFn extends AnyFn> {
214
214
  let done = this.disregardExecutionTime;
215
215
  setTimeout(() => {
216
216
  if (done) {
217
- this.scheduleNext();
217
+ void this.scheduleNext();
218
218
  } else {
219
219
  done = true;
220
220
  }
@@ -225,7 +225,7 @@ class BatchImpl<TFn extends AnyFn> {
225
225
  if (!this.disregardExecutionTime) {
226
226
  if (done) {
227
227
  // interval already passed, we need to call it
228
- this.scheduleNext();
228
+ void this.scheduleNext();
229
229
  } else {
230
230
  done = true;
231
231
  }
File without changes
File without changes