@gesslar/toolkit 0.0.5 → 0.0.7
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 +1 -1
- package/src/index.js +1 -0
- package/src/lib/Data.js +31 -3
- package/src/lib/Glog.js +119 -0
- package/src/lib/Util.js +89 -0
- package/src/types/Data.d.ts +7 -1
- package/src/types/Glog.d.ts +72 -0
- package/src/types/Util.d.ts +27 -0
- package/src/types/index.d.ts +1 -0
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export {default as File} from "./lib/File.js"
|
|
|
6
6
|
// Utility classes
|
|
7
7
|
export {default as Cache} from "./lib/Cache.js"
|
|
8
8
|
export {default as Data} from "./lib/Data.js"
|
|
9
|
+
export {default as Glog} from "./lib/Glog.js"
|
|
9
10
|
export {default as Sass} from "./lib/Sass.js"
|
|
10
11
|
export {default as Term} from "./lib/Term.js"
|
|
11
12
|
export {default as Type} from "./lib/Type.js"
|
package/src/lib/Data.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @file Data utility functions for type checking, object manipulation, and
|
|
3
|
-
*
|
|
2
|
+
* @file Data utility functions for type checking, object manipulation, and
|
|
3
|
+
* array operations.
|
|
4
|
+
*
|
|
5
|
+
* Provides comprehensive utilities for working with JavaScript data types and
|
|
6
|
+
* structures.
|
|
4
7
|
*/
|
|
5
8
|
|
|
6
9
|
import Sass from "./Sass.js"
|
|
@@ -54,7 +57,9 @@ export default class Data {
|
|
|
54
57
|
])
|
|
55
58
|
|
|
56
59
|
/**
|
|
57
|
-
* Combined array of all supported data types (primitives and constructors in
|
|
60
|
+
* Combined array of all supported data types (primitives and constructors in
|
|
61
|
+
* lowercase).
|
|
62
|
+
*
|
|
58
63
|
* Used for type validation throughout the utility functions.
|
|
59
64
|
*
|
|
60
65
|
* @type {Array<string>}
|
|
@@ -530,4 +535,27 @@ export default class Data {
|
|
|
530
535
|
return arr.filter((_, index) => results[index])
|
|
531
536
|
}
|
|
532
537
|
|
|
538
|
+
/**
|
|
539
|
+
* Ensures a value is within a specified range.
|
|
540
|
+
*
|
|
541
|
+
* @param {number} val - The value to check.
|
|
542
|
+
* @param {number} min - The minimum value.
|
|
543
|
+
* @param {number} max - The maximum value.
|
|
544
|
+
* @returns {number} The value, constrained within the range of `min` to `max`.
|
|
545
|
+
*/
|
|
546
|
+
static clamp(val, min, max) {
|
|
547
|
+
return val >= min ? val <= max ? val : max : min
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Checks if a value is within a specified range (inclusive).
|
|
552
|
+
*
|
|
553
|
+
* @param {number} val - The value to check.
|
|
554
|
+
* @param {number} min - The minimum value (inclusive).
|
|
555
|
+
* @param {number} max - The maximum value (inclusive).
|
|
556
|
+
* @returns {boolean} True if the value is within the range, false otherwise.
|
|
557
|
+
*/
|
|
558
|
+
static clamped(val, min, max) {
|
|
559
|
+
return val >= min && val <= max
|
|
560
|
+
}
|
|
533
561
|
}
|
package/src/lib/Glog.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import Data from "./Data.js"
|
|
2
|
+
import console from "node:console"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Global logging utility with configurable log levels and prefixes.
|
|
6
|
+
* Provides a flexible logging system that can be used as both a class and
|
|
7
|
+
* a callable function, with support for log level filtering and custom
|
|
8
|
+
* prefixes for better log organization.
|
|
9
|
+
*
|
|
10
|
+
* The Glog class uses a proxy to enable both class-style and function-style
|
|
11
|
+
* usage patterns, making it convenient for different coding preferences.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* // Set up logging configuration
|
|
15
|
+
* Glog.setLogLevel(3).setLogPrefix('[MyApp]')
|
|
16
|
+
*
|
|
17
|
+
* // Log messages with different levels
|
|
18
|
+
* Glog(0, 'Critical error') // Always shown
|
|
19
|
+
* Glog(2, 'Debug info') // Shown if logLevel >= 2
|
|
20
|
+
* Glog('Simple message') // Level 0 by default
|
|
21
|
+
*/
|
|
22
|
+
class Glog {
|
|
23
|
+
/** @type {number} Current log level threshold (0-5) */
|
|
24
|
+
logLevel = 0
|
|
25
|
+
/** @type {string} Prefix to prepend to all log messages */
|
|
26
|
+
logPrefix = ""
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Sets the log prefix for all subsequent log messages.
|
|
30
|
+
* The prefix helps identify the source of log messages in complex
|
|
31
|
+
* applications with multiple components.
|
|
32
|
+
*
|
|
33
|
+
* @param {string} prefix - The prefix string to prepend to log messages
|
|
34
|
+
* @returns {typeof Glog} Returns the Glog class for method chaining
|
|
35
|
+
* @example
|
|
36
|
+
* Glog.setLogPrefix('[Database]')
|
|
37
|
+
* Glog('Connection established') // Output: [Database] Connection established
|
|
38
|
+
*/
|
|
39
|
+
static setLogPrefix(prefix) {
|
|
40
|
+
this.logPrefix = prefix
|
|
41
|
+
|
|
42
|
+
return Glog
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Sets the minimum log level for messages to be displayed.
|
|
47
|
+
* Messages with a level higher than this threshold will be filtered out.
|
|
48
|
+
* Log levels range from 0 (critical) to 5 (verbose debug).
|
|
49
|
+
*
|
|
50
|
+
* @param {number} level - The minimum log level (0-5, clamped to range)
|
|
51
|
+
* @returns {typeof Glog} Returns the Glog class for method chaining
|
|
52
|
+
* @example
|
|
53
|
+
* Glog.setLogLevel(2) // Only show messages with level 0, 1, or 2
|
|
54
|
+
* Glog(1, 'Important') // Shown
|
|
55
|
+
* Glog(3, 'Verbose') // Hidden
|
|
56
|
+
*/
|
|
57
|
+
static setLogLevel(level) {
|
|
58
|
+
this.logLevel = Data.clamp(level, 0, 5)
|
|
59
|
+
|
|
60
|
+
return Glog
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Internal logging method that handles message formatting and level
|
|
65
|
+
* filtering.
|
|
66
|
+
*
|
|
67
|
+
* Parses arguments to determine log level and message content, then outputs
|
|
68
|
+
* the message if it meets the current log level threshold.
|
|
69
|
+
*
|
|
70
|
+
* @private
|
|
71
|
+
* @param {...unknown} args - Variable arguments: either (level, ...messages) or (...messages)
|
|
72
|
+
* @returns {void}
|
|
73
|
+
*/
|
|
74
|
+
static #log(...args) {
|
|
75
|
+
let level, rest
|
|
76
|
+
|
|
77
|
+
if(args.length === 0) {
|
|
78
|
+
;[level=0, rest=[""]] = null
|
|
79
|
+
} else if(args.length === 1) {
|
|
80
|
+
;[rest, level=0] = [args, 0]
|
|
81
|
+
} else {
|
|
82
|
+
;[level, ...rest] = args
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if(level > this.logLevel)
|
|
86
|
+
return
|
|
87
|
+
|
|
88
|
+
if(this.logPrefix)
|
|
89
|
+
console.log(this.logPrefix, ...rest)
|
|
90
|
+
else
|
|
91
|
+
console.log(...rest)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Executes a log operation with the provided arguments.
|
|
96
|
+
* This method serves as the entry point for all logging operations,
|
|
97
|
+
* delegating to the private #log method for actual processing.
|
|
98
|
+
*
|
|
99
|
+
* @param {...unknown} args - Log level (optional) followed by message arguments
|
|
100
|
+
* @returns {void}
|
|
101
|
+
* @example
|
|
102
|
+
* Glog.execute(0, 'Error:', error.message)
|
|
103
|
+
* Glog.execute('Simple message') // Level 0 assumed
|
|
104
|
+
*/
|
|
105
|
+
static execute(...args) {
|
|
106
|
+
this.#log(...args)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Wrap the class in a proxy
|
|
111
|
+
export default new Proxy(Glog, {
|
|
112
|
+
apply(target, thisArg, argumentsList) {
|
|
113
|
+
// When called as function: MyClass(things, and, stuff)
|
|
114
|
+
return target.execute(...argumentsList)
|
|
115
|
+
},
|
|
116
|
+
construct(target, argumentsList) {
|
|
117
|
+
return new target(...argumentsList)
|
|
118
|
+
}
|
|
119
|
+
})
|
package/src/lib/Util.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import {createHash} from "node:crypto"
|
|
2
2
|
import {performance} from "node:perf_hooks"
|
|
3
|
+
import {EventEmitter} from "node:events"
|
|
4
|
+
import Sass from "./Sass.js"
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Utility class providing common helper functions for string manipulation,
|
|
@@ -131,4 +133,91 @@ export default class Util {
|
|
|
131
133
|
static async race(promises) {
|
|
132
134
|
return await Promise.race(promises)
|
|
133
135
|
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Private method that performs the actual async emission logic.
|
|
139
|
+
* Handles listener execution, error aggregation, and result processing.
|
|
140
|
+
*
|
|
141
|
+
* @param {object} emitter - The emitter object (already validated)
|
|
142
|
+
* @param {string} event - The event name to emit
|
|
143
|
+
* @param {...unknown} args - Arguments to pass to event listeners
|
|
144
|
+
* @returns {Promise<void>} Resolves when all listeners have completed
|
|
145
|
+
*/
|
|
146
|
+
static async #performAsyncEmit(emitter, event, ...args) {
|
|
147
|
+
const listeners = emitter.listeners(event)
|
|
148
|
+
|
|
149
|
+
if(listeners.length === 0)
|
|
150
|
+
return // No listeners, nothing to do
|
|
151
|
+
|
|
152
|
+
const settled =
|
|
153
|
+
await Promise.allSettled(listeners.map(listener => listener(...args)))
|
|
154
|
+
|
|
155
|
+
const rejected = settled.filter(result => result.status === "rejected")
|
|
156
|
+
|
|
157
|
+
if(rejected.length > 0) {
|
|
158
|
+
if(rejected[0].reason instanceof Error)
|
|
159
|
+
throw rejected[0].reason
|
|
160
|
+
else
|
|
161
|
+
throw Sass.new(rejected[0].reason)
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Emits an event asynchronously and waits for all listeners to complete.
|
|
167
|
+
* Unlike the standard EventEmitter.emit() which is synchronous, this method
|
|
168
|
+
* properly handles async event listeners by waiting for all of them to
|
|
169
|
+
* resolve or reject using Promise.allSettled().
|
|
170
|
+
*
|
|
171
|
+
* Uses strict instanceof checking to ensure the emitter is a genuine EventEmitter.
|
|
172
|
+
*
|
|
173
|
+
* @param {EventEmitter} emitter - The EventEmitter instance to emit on
|
|
174
|
+
* @param {string} event - The event name to emit
|
|
175
|
+
* @param {...unknown} args - Arguments to pass to event listeners
|
|
176
|
+
* @returns {Promise<void>} Resolves when all listeners have completed
|
|
177
|
+
*/
|
|
178
|
+
static async asyncEmit(emitter, event, ...args) {
|
|
179
|
+
try {
|
|
180
|
+
if(!(emitter instanceof EventEmitter))
|
|
181
|
+
throw Sass.new("First argument must be an EventEmitter instance")
|
|
182
|
+
|
|
183
|
+
await this.#performAsyncEmit(emitter, event, ...args)
|
|
184
|
+
} catch(error) {
|
|
185
|
+
const argsDesc = args.length > 0 ? `with arguments: ${args.map(String).join(", ")}` : "with no arguments"
|
|
186
|
+
|
|
187
|
+
throw Sass.new(
|
|
188
|
+
`Processing '${event}' event ${argsDesc}.`,
|
|
189
|
+
error
|
|
190
|
+
)
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Emits an event asynchronously and waits for all listeners to complete.
|
|
196
|
+
* Like asyncEmit, but uses duck typing for more flexible emitter validation.
|
|
197
|
+
* Accepts any object that has the required EventEmitter-like methods.
|
|
198
|
+
*
|
|
199
|
+
* @param {object} emitter - Any object with EventEmitter-like interface
|
|
200
|
+
* @param {string} event - The event name to emit
|
|
201
|
+
* @param {...unknown} args - Arguments to pass to event listeners
|
|
202
|
+
* @returns {Promise<void>} Resolves when all listeners have completed
|
|
203
|
+
*/
|
|
204
|
+
static async asyncEmitAnon(emitter, event, ...args) {
|
|
205
|
+
try {
|
|
206
|
+
if(!emitter ||
|
|
207
|
+
typeof emitter.listeners !== "function" ||
|
|
208
|
+
typeof emitter.on !== "function" ||
|
|
209
|
+
typeof emitter.emit !== "function") {
|
|
210
|
+
throw Sass.new("First argument must be an EventEmitter-like object")
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
await this.#performAsyncEmit(emitter, event, ...args)
|
|
214
|
+
} catch(error) {
|
|
215
|
+
const argsDesc = args.length > 0 ? `with arguments: ${args.map(String).join(", ")}` : "with no arguments"
|
|
216
|
+
|
|
217
|
+
throw Sass.new(
|
|
218
|
+
`Processing '${event}' event ${argsDesc}.`,
|
|
219
|
+
error
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
}
|
|
134
223
|
}
|
package/src/types/Data.d.ts
CHANGED
|
@@ -94,4 +94,10 @@ export default class Data {
|
|
|
94
94
|
|
|
95
95
|
/** Filter an array asynchronously */
|
|
96
96
|
static asyncFilter<T>(arr: Array<T>, predicate: (item: T) => Promise<boolean>): Promise<Array<T>>
|
|
97
|
-
|
|
97
|
+
|
|
98
|
+
/** Ensures a value is within a specified range */
|
|
99
|
+
static clamp(val: number, min: number, max: number): number
|
|
100
|
+
|
|
101
|
+
/** Checks if a value is within a specified range (inclusive) */
|
|
102
|
+
static clamped(val: number, min: number, max: number): boolean
|
|
103
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Implementation: ../lib/Glog.js
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Global logging utility with configurable log levels and prefixes.
|
|
5
|
+
* Provides a flexible logging system that can be used as both a class and
|
|
6
|
+
* a callable function, with support for log level filtering and custom
|
|
7
|
+
* prefixes for better log organization.
|
|
8
|
+
*
|
|
9
|
+
* The Glog class uses a proxy to enable both class-style and function-style
|
|
10
|
+
* usage patterns, making it convenient for different coding preferences.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* // Set up logging configuration
|
|
15
|
+
* Glog.setLogLevel(3).setLogPrefix('[MyApp]')
|
|
16
|
+
*
|
|
17
|
+
* // Log messages with different levels
|
|
18
|
+
* Glog(0, 'Critical error') // Always shown
|
|
19
|
+
* Glog(2, 'Debug info') // Shown if logLevel >= 2
|
|
20
|
+
* Glog('Simple message') // Level 0 by default
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
interface GlogInterface {
|
|
24
|
+
/**
|
|
25
|
+
* Sets the log prefix for all subsequent log messages.
|
|
26
|
+
* The prefix helps identify the source of log messages in complex
|
|
27
|
+
* applications with multiple components.
|
|
28
|
+
*
|
|
29
|
+
* @param prefix - The prefix string to prepend to log messages
|
|
30
|
+
* @returns Returns the Glog class for method chaining
|
|
31
|
+
*/
|
|
32
|
+
setLogPrefix(prefix: string): typeof Glog
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Sets the minimum log level for messages to be displayed.
|
|
36
|
+
* Messages with a level higher than this threshold will be filtered out.
|
|
37
|
+
* Log levels range from 0 (critical) to 5 (verbose debug).
|
|
38
|
+
*
|
|
39
|
+
* @param level - The minimum log level (0-5, clamped to range)
|
|
40
|
+
* @returns Returns the Glog class for method chaining
|
|
41
|
+
*/
|
|
42
|
+
setLogLevel(level: number): typeof Glog
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Executes a log operation with the provided arguments.
|
|
46
|
+
* This method serves as the entry point for all logging operations.
|
|
47
|
+
*
|
|
48
|
+
* @param args - Log level (optional) followed by message arguments
|
|
49
|
+
*/
|
|
50
|
+
execute(...args: any[]): void
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Callable interface for the proxied Glog class.
|
|
55
|
+
* Allows the class to be used as a function.
|
|
56
|
+
*/
|
|
57
|
+
interface GlogCallable {
|
|
58
|
+
/**
|
|
59
|
+
* Log a message with optional level specification.
|
|
60
|
+
*
|
|
61
|
+
* @param args - Either (level: number, ...messages) or (...messages)
|
|
62
|
+
*/
|
|
63
|
+
(...args: any[]): void
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* The Glog class with proxy functionality for callable behavior.
|
|
68
|
+
* Can be used both as a static class and as a callable function.
|
|
69
|
+
*/
|
|
70
|
+
declare const Glog: GlogInterface & GlogCallable
|
|
71
|
+
|
|
72
|
+
export default Glog
|
package/src/types/Util.d.ts
CHANGED
|
@@ -81,6 +81,33 @@ declare class Util {
|
|
|
81
81
|
* @returns Result of the first settled promise
|
|
82
82
|
*/
|
|
83
83
|
static race<T>(promises: Array<Promise<T>>): Promise<T>
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Emits an event asynchronously and waits for all listeners to complete.
|
|
87
|
+
* Unlike the standard EventEmitter.emit() which is synchronous, this method
|
|
88
|
+
* properly handles async event listeners by waiting for all of them to
|
|
89
|
+
* resolve or reject using Promise.allSettled().
|
|
90
|
+
*
|
|
91
|
+
* Uses strict instanceof checking to ensure the emitter is a genuine EventEmitter.
|
|
92
|
+
*
|
|
93
|
+
* @param emitter - The EventEmitter instance to emit on
|
|
94
|
+
* @param event - The event name to emit
|
|
95
|
+
* @param args - Arguments to pass to event listeners
|
|
96
|
+
* @returns Resolves when all listeners have completed
|
|
97
|
+
*/
|
|
98
|
+
static asyncEmit(emitter: import('events').EventEmitter, event: string, ...args: unknown[]): Promise<void>
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Emits an event asynchronously and waits for all listeners to complete.
|
|
102
|
+
* Like asyncEmit, but uses duck typing for more flexible emitter validation.
|
|
103
|
+
* Accepts any object that has the required EventEmitter-like methods.
|
|
104
|
+
*
|
|
105
|
+
* @param emitter - Any object with EventEmitter-like interface
|
|
106
|
+
* @param event - The event name to emit
|
|
107
|
+
* @param args - Arguments to pass to event listeners
|
|
108
|
+
* @returns Resolves when all listeners have completed
|
|
109
|
+
*/
|
|
110
|
+
static asyncEmitAnon(emitter: { listeners(event: string): Function[], on(event: string, listener: Function): any, emit(event: string, ...args: unknown[]): any }, event: string, ...args: unknown[]): Promise<void>
|
|
84
111
|
}
|
|
85
112
|
|
|
86
113
|
export default Util
|
package/src/types/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { default as File } from './File.js'
|
|
|
7
7
|
// Utility classes
|
|
8
8
|
export { default as Cache } from './Cache.js'
|
|
9
9
|
export { default as Data } from './Data.js'
|
|
10
|
+
export { default as Glog } from './Glog.js'
|
|
10
11
|
export { default as Sass } from './Sass.js'
|
|
11
12
|
export { default as Term } from './Term.js'
|
|
12
13
|
export { default as Type } from './Type.js'
|