@gesslar/toolkit 4.0.0 → 4.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.
Files changed (38) hide show
  1. package/README.md +1 -0
  2. package/package.json +1 -1
  3. package/src/browser/lib/Data.js +4 -4
  4. package/src/browser/lib/TypeSpec.js +115 -39
  5. package/src/node/index.js +2 -1
  6. package/src/node/lib/Cache.js +105 -35
  7. package/src/node/lib/Data.js +49 -0
  8. package/src/node/lib/DirectoryObject.js +4 -7
  9. package/src/node/lib/FileObject.js +89 -53
  10. package/src/node/lib/FileSystem.js +47 -2
  11. package/src/node/lib/Font.js +1 -1
  12. package/src/node/lib/Notify.js +6 -6
  13. package/src/node/lib/Term.js +1 -1
  14. package/src/node/lib/Util.js +3 -3
  15. package/src/node/lib/Watcher.js +118 -0
  16. package/types/browser/lib/Data.d.ts +2 -8
  17. package/types/browser/lib/Data.d.ts.map +1 -1
  18. package/types/browser/lib/TypeSpec.d.ts +21 -36
  19. package/types/browser/lib/TypeSpec.d.ts.map +1 -1
  20. package/types/node/index.d.ts +2 -1
  21. package/types/node/lib/Cache.d.ts +36 -5
  22. package/types/node/lib/Cache.d.ts.map +1 -1
  23. package/types/node/lib/Data.d.ts +19 -0
  24. package/types/node/lib/Data.d.ts.map +1 -0
  25. package/types/node/lib/DirectoryObject.d.ts +6 -5
  26. package/types/node/lib/DirectoryObject.d.ts.map +1 -1
  27. package/types/node/lib/FileObject.d.ts +54 -26
  28. package/types/node/lib/FileObject.d.ts.map +1 -1
  29. package/types/node/lib/FileSystem.d.ts +19 -0
  30. package/types/node/lib/FileSystem.d.ts.map +1 -1
  31. package/types/node/lib/Notify.d.ts +10 -10
  32. package/types/node/lib/Notify.d.ts.map +1 -1
  33. package/types/node/lib/Term.d.ts +2 -2
  34. package/types/node/lib/Term.d.ts.map +1 -1
  35. package/types/node/lib/Util.d.ts +6 -6
  36. package/types/node/lib/Util.d.ts.map +1 -1
  37. package/types/node/lib/Watcher.d.ts +38 -0
  38. package/types/node/lib/Watcher.d.ts.map +1 -0
@@ -4,14 +4,13 @@
4
4
  * resolution and existence checks.
5
5
  */
6
6
 
7
- import JSON5 from "json5"
7
+ import {Buffer} from "node:buffer"
8
8
  import fs from "node:fs/promises"
9
- import YAML from "yaml"
10
9
  import {URL} from "node:url"
11
- import {Buffer} from "node:buffer"
12
10
  import {inspect} from "node:util"
13
11
 
14
- import Data from "../../browser/lib/Data.js"
12
+ import Cache from "./Cache.js"
13
+ import Data from "./Data.js"
15
14
  import DirectoryObject from "./DirectoryObject.js"
16
15
  import FS from "./FileSystem.js"
17
16
  import Sass from "./Sass.js"
@@ -33,19 +32,6 @@ import Valid from "./Valid.js"
33
32
  */
34
33
 
35
34
  export default class FileObject extends FS {
36
- /**
37
- * Configuration mapping data types to their respective parser modules for loadData method.
38
- * Each parser module must have a .parse() method that accepts a string and returns parsed data.
39
- *
40
- * @type {{[key: string]: Array<typeof JSON5 | typeof YAML>}}
41
- */
42
- static dataLoaderConfig = Object.freeze({
43
- json5: [JSON5],
44
- json: [JSON5],
45
- yaml: [YAML],
46
- any: [JSON5, YAML]
47
- })
48
-
49
35
  /**
50
36
  * @type {object}
51
37
  * @property {string|null} supplied - User-supplied path
@@ -70,6 +56,8 @@ export default class FileObject extends FS {
70
56
  real: null,
71
57
  })
72
58
 
59
+ #cache = null
60
+
73
61
  /**
74
62
  * Constructs a FileObject instance.
75
63
  *
@@ -162,6 +150,7 @@ export default class FileObject extends FS {
162
150
  extension: this.extension,
163
151
  isFile: this.isFile,
164
152
  parentPath: this.parentPath,
153
+ cached: this.cached
165
154
  }
166
155
  }
167
156
 
@@ -377,17 +366,74 @@ export default class FileObject extends FS {
377
366
  }
378
367
  }
379
368
 
369
+ /**
370
+ * Whether this FileObject has an active cache attached.
371
+ *
372
+ * @returns {boolean} True if a Cache instance is attached
373
+ */
374
+ get cached() {
375
+ return Data.isType(this.#cache, "Cache")
376
+ }
377
+
378
+ /**
379
+ * Attaches a Cache instance to this FileObject for caching read and
380
+ * loadData results. If no cache is provided, a new Cache is created.
381
+ *
382
+ * @param {Cache} [cache] - The Cache instance to attach
383
+ * @returns {FileObject} This FileObject for chaining
384
+ * @throws {Sass} If a cache is already attached
385
+ */
386
+ withCache(cache) {
387
+ Valid.type(cache, "Undefined|Cache")
388
+ Valid.assert(!this.#cache, "Cache already set. Remove the cache before re-assigning.")
389
+
390
+ cache ??= new Cache()
391
+
392
+ this.#cache = cache
393
+
394
+ return this
395
+ }
396
+
397
+ /**
398
+ * Removes the attached cache, clearing any cached data for this file first.
399
+ *
400
+ * @returns {FileObject} This FileObject for chaining
401
+ */
402
+ removeCache() {
403
+ this.resetCache()
404
+ this.#cache = null
405
+
406
+ return this
407
+ }
408
+
409
+ /**
410
+ * Clears cached data for this file without removing the cache itself.
411
+ *
412
+ * @returns {FileObject} This FileObject for chaining
413
+ */
414
+ resetCache() {
415
+ this.#cache?.resetCache(this)
416
+
417
+ return this
418
+ }
419
+
380
420
  /**
381
421
  * Reads the content of a file asynchronously.
382
422
  *
383
- * @param {string} [encoding] - The encoding to read the file as.
423
+ * @param {object} [options] - Read options
424
+ * @param {string} [options.encoding="utf8"] - The encoding to read the file as
425
+ * @param {boolean} [options.skipCache=false] - If true, bypass the cache
384
426
  * @returns {Promise<string>} The file contents
385
427
  */
386
- async read(encoding="utf8") {
428
+ async read({encoding="utf8", skipCache=false} = {}) {
387
429
  const filePath = this.path
388
430
 
431
+ if(this.#cache && skipCache === false)
432
+ return await this.#cache.loadFromCache(
433
+ this, {encoding})
434
+
389
435
  if(!(await this.exists))
390
- throw Sass.new(`No such file '${filePath}'`)
436
+ throw Sass.new(`No such file '${this}'`)
391
437
 
392
438
  return await fs.readFile(filePath, encoding)
393
439
  }
@@ -419,7 +465,7 @@ export default class FileObject extends FS {
419
465
  *
420
466
  * @param {string} content - The content to write
421
467
  * @param {string} [encoding] - The encoding in which to write (default: "utf8")
422
- * @returns {Promise<void>}
468
+ * @returns {Promise<undefined>}
423
469
  * @throws {Sass} If the file URL is invalid or the parent directory doesn't exist
424
470
  * @example
425
471
  * const file = new FileObject('./output/data.json')
@@ -444,7 +490,7 @@ export default class FileObject extends FS {
444
490
  * Supports ArrayBuffer, TypedArrays (Uint8Array, etc.), Blob, and Node Buffer types.
445
491
  *
446
492
  * @param {ArrayBuffer|Blob|Buffer} data - The binary data to write
447
- * @returns {Promise<void>}
493
+ * @returns {Promise<undefined>}
448
494
  * @throws {Sass} If the file URL is invalid
449
495
  * @throws {Sass} If the parent directory doesn't exist
450
496
  * @throws {Sass} If the data is not a valid binary type
@@ -471,44 +517,34 @@ export default class FileObject extends FS {
471
517
  }
472
518
 
473
519
  /**
474
- * Loads an object from JSON or YAML file.
475
- * Attempts to parse content as JSON5 first, then falls back to YAML if specified.
520
+ * Loads an object from JSON or YAML file. Attempts to parse content as JSON5
521
+ * first, then falls back to YAML if specified.
476
522
  *
477
- * @param {string} [type] - The expected type of data to parse ("json", "json5", "yaml", or "any")
478
- * @param {string} [encoding] - The encoding to read the file as (default: "utf8")
523
+ * @param {object} [options] - Load options
524
+ * @param {string} [options.type="any"] - The expected type of data to parse ("json", "json5", "yaml", or "any")
525
+ * @param {string} [options.encoding="utf8"] - The encoding to read the file as
526
+ * @param {boolean} [options.skipCache=false] - If true, bypass the cache
479
527
  * @returns {Promise<unknown>} The parsed data object
480
528
  * @throws {Sass} If the content cannot be parsed or type is unsupported
481
529
  * @example
482
530
  * const configFile = new FileObject('./config.json5')
483
- * const config = await configFile.loadData('json5')
531
+ * const config = await configFile.loadData({type: 'json5'})
484
532
  *
485
533
  * // Auto-detect format
486
- * const data = await configFile.loadData('any')
487
- */
488
- async loadData(type="any", encoding="utf8") {
489
- const content = await this.read(encoding)
490
- const normalizedType = type.toLowerCase()
491
- const toTry = {
492
- json5: [JSON5],
493
- json: [JSON5],
494
- yaml: [YAML],
495
- any: [JSON5,YAML]
496
- }[normalizedType]
497
-
498
- if(!toTry)
499
- throw Sass.new(`Unsupported data type '${type}'. Supported types: json, json5, yaml.`)
500
-
501
- for(const format of toTry) {
502
- try {
503
- const result = format.parse(content)
504
-
505
- return result
506
- } catch {
507
- // nothing to see here
508
- }
509
- }
534
+ * const data = await configFile.loadData()
535
+ */
536
+ async loadData({type="any", encoding="utf8", skipCache=false} = {}) {
537
+ if(this.#cache && skipCache === false)
538
+ return await this.#cache.loadDataFromCache(
539
+ this, {encoding, type})
540
+
541
+ if(!(await this.exists))
542
+ throw Sass.new(`No such file '${this}'`)
543
+
544
+ const content = await this.read({encoding, skipCache})
545
+ const result = Data.textAsData(content, type)
510
546
 
511
- throw Sass.new(`Content is neither valid JSON5 nor valid YAML:\n'${this.path}'`)
547
+ return result
512
548
  }
513
549
 
514
550
  /**
@@ -610,7 +646,7 @@ export default class FileObject extends FS {
610
646
  /**
611
647
  * Deletes the file from the filesystem.
612
648
  *
613
- * @returns {Promise<void>} Resolves when file is deleted
649
+ * @returns {Promise<undefined>} Resolves when file is deleted
614
650
  * @throws {Sass} If the file URL is invalid
615
651
  * @throws {Sass} If the file does not exist
616
652
  * @example
@@ -11,12 +11,14 @@
11
11
  import path from "node:path"
12
12
  import url from "node:url"
13
13
 
14
+ import Collection from "../../browser/lib/Collection.js"
14
15
  import Data from "../../browser/lib/Data.js"
16
+ import Glog from "./Glog.js"
15
17
  import Valid from "./Valid.js"
16
- import Collection from "../../browser/lib/Collection.js"
18
+ import Watcher from "./Watcher.js"
17
19
 
18
20
  /**
19
- * @import {Sass} from "./Sass.js"
21
+ * @import Sass from "./Sass.js"
20
22
  */
21
23
 
22
24
  const fdTypes = Object.freeze(["file", "directory"])
@@ -33,6 +35,8 @@ export default class FileSystem {
33
35
  static upperFdTypes = upperFdTypes
34
36
  static fdType = fdType
35
37
 
38
+ #watcher = null
39
+
36
40
  /**
37
41
  * Compute the relative path from another file or directory to this instance.
38
42
  *
@@ -53,6 +57,47 @@ export default class FileSystem {
53
57
  return FileSystem.relativeOrAbsolute(fileOrDirectoryObject, this)
54
58
  }
55
59
 
60
+ /**
61
+ * Watch this file or directory for changes.
62
+ *
63
+ * @param {object} [options] - Watch options
64
+ * @param {Function} [options.onChange] - Callback invoked on change
65
+ * @param {number} [options.debounceMs] - Debounce interval in milliseconds
66
+ * @param {boolean} [options.persistent] - Keep the process alive while watching
67
+ * @returns {Promise<undefined>}
68
+ */
69
+ async watch(options={}) {
70
+ Valid.type(options, "Object")
71
+
72
+ const localOptions = Collection.cloneObject(options)
73
+
74
+ const {onChange} = localOptions ?? {}
75
+ Valid.type(onChange, "Undefined|Function")
76
+
77
+ delete localOptions.onChange
78
+
79
+ this.stopWatching()
80
+
81
+ this.#watcher = new Watcher()
82
+
83
+ await this.#watcher.watch(this, Object.assign({},
84
+ localOptions,
85
+ {
86
+ onChange: onChange ?? (() => {
87
+ Glog(`${this} changed somehow.`)
88
+ })
89
+ }
90
+ ))
91
+ }
92
+
93
+ /**
94
+ * Stop watching this file or directory for changes.
95
+ */
96
+ stopWatching() {
97
+ this.#watcher?.stopWatching()
98
+ this.#watcher = null
99
+ }
100
+
56
101
  /**
57
102
  * Fix slashes in a path
58
103
  *
@@ -11,7 +11,7 @@ import DirectoryObject from "./DirectoryObject.js"
11
11
  import FS from "./FileSystem.js"
12
12
 
13
13
  /**
14
- * @import {FileObject} from "./FileObject.js"
14
+ * @import FileObject from "./FileObject.js"
15
15
  */
16
16
 
17
17
  const execFile = promisify(child_process.execFile)
@@ -31,7 +31,7 @@ export class Notify {
31
31
  *
32
32
  * @param {string} type - Event name to dispatch.
33
33
  * @param {unknown} [payload] - Data to send with the event.
34
- * @returns {void}
34
+ * @returns {undefined}
35
35
  */
36
36
  emit(type, payload=undefined) {
37
37
  Valid.type(type, "String", {allowEmpty: false})
@@ -46,7 +46,7 @@ export class Notify {
46
46
  *
47
47
  * @param {string} type - Event name to dispatch.
48
48
  * @param {unknown} [payload] - Data to send with the event.
49
- * @returns {Promise<void>} Resolves when all listeners have completed.
49
+ * @returns {Promise<undefined>} Resolves when all listeners have completed.
50
50
  */
51
51
  async asyncEmit(type, payload) {
52
52
  Valid.type(type, "String", {allowEmpty: false})
@@ -74,10 +74,10 @@ export class Notify {
74
74
  * Registers a listener for the given event type.
75
75
  *
76
76
  * @param {string} type - Event name to listen for.
77
- * @param {(payload: unknown) => void} handler - Listener callback.
77
+ * @param {(payload: unknown) => undefined} handler - Listener callback.
78
78
  * @param {EventEmitter} [emitter] - The EventEmitter to attach to. Default is internal emitter.
79
79
  * @param {NotifyEventOptions} [options] - Options for the listener.
80
- * @returns {() => void} Dispose function to unregister the handler.
80
+ * @returns {() => undefined} Dispose function to unregister the handler.
81
81
  */
82
82
  on(type, handler, emitter=this.#emitter, options=undefined) {
83
83
  Valid.type(type, "String", {allowEmpty: false})
@@ -96,9 +96,9 @@ export class Notify {
96
96
  * Removes a previously registered listener for the given event type.
97
97
  *
98
98
  * @param {string} type - Event name to remove.
99
- * @param {(payload: unknown) => void} handler - Listener callback to detach.
99
+ * @param {(payload: unknown) => undefined} handler - Listener callback to detach.
100
100
  * @param {EventEmitter} [emitter] - The EventEmitter from which to remove. Default is internal emitter.
101
- * @returns {void}
101
+ * @returns {undefined}
102
102
  */
103
103
  off(type, handler, emitter=this.#emitter) {
104
104
  Valid.type(type, "String", {allowEmpty: false})
@@ -230,7 +230,7 @@ export default class Term {
230
230
  * @param {string | Array<string | [string, string]>} args - Message or segments.
231
231
  * @param {object} [options] - Behaviour flags.
232
232
  * @param {boolean} options.silent - When true, suppress output.
233
- * @returns {void}
233
+ * @returns {undefined}
234
234
  */
235
235
  static status(args, {silent=false} = {}) {
236
236
  if(silent)
@@ -65,7 +65,7 @@ export default class Util extends BrowserUtil {
65
65
  * @param {object} emitter - The emitter object (already validated)
66
66
  * @param {string} event - The event name to emit
67
67
  * @param {...unknown} args - Arguments to pass to event listeners
68
- * @returns {Promise<void>} Resolves when all listeners have completed
68
+ * @returns {Promise<undefined>} Resolves when all listeners have completed
69
69
  */
70
70
  static async #performAsyncEmit(emitter, event, ...args) {
71
71
  const listeners = emitter.listeners(event)
@@ -97,7 +97,7 @@ export default class Util extends BrowserUtil {
97
97
  * @param {EventEmitter} emitter - The EventEmitter instance to emit on
98
98
  * @param {string} event - The event name to emit
99
99
  * @param {...unknown} args - Arguments to pass to event listeners
100
- * @returns {Promise<void>} Resolves when all listeners have completed
100
+ * @returns {Promise<undefined>} Resolves when all listeners have completed
101
101
  */
102
102
  static async asyncEmit(emitter, event, ...args) {
103
103
  try {
@@ -124,7 +124,7 @@ export default class Util extends BrowserUtil {
124
124
  * @param {object} emitter - Any object with EventEmitter-like interface
125
125
  * @param {string} event - The event name to emit
126
126
  * @param {...unknown} args - Arguments to pass to event listeners
127
- * @returns {Promise<void>} Resolves when all listeners have completed, but no grapes.
127
+ * @returns {Promise<undefined>} Resolves when all listeners have completed, but no grapes.
128
128
  */
129
129
  static async asyncEmitQuack(emitter, event, ...args) {
130
130
  try {
@@ -0,0 +1,118 @@
1
+ import {watch} from "node:fs/promises"
2
+ import Valid from "./Valid.js"
3
+ import Data from "./Data.js"
4
+ import Time from "../../browser/lib/Time.js"
5
+
6
+ /**
7
+ * @import FileObject from "./FileObject.js"
8
+ * @import DirectoryObject from "./DirectoryObject.js"
9
+ */
10
+
11
+ export const OverFlowBehaviour = Object.freeze({
12
+ IGNORE: "ignore",
13
+ THROW: "throw",
14
+ })
15
+
16
+ export default class Watcher {
17
+ #abortController
18
+ #state = new Map()
19
+
20
+ /**
21
+ * Watch one or more file/directory targets for changes, invoking a callback
22
+ * with debounce protection.
23
+ *
24
+ * @param {FileObject|DirectoryObject|Array.<(FileObject|DirectoryObject)>} targets - The target(s) to watch
25
+ * @param {object} options - Watch options
26
+ * @param {(target: FileObject|DirectoryObject) => void} options.onChange - Callback invoked on change
27
+ * @param {number} [options.debounceMs=50] - Debounce interval in milliseconds
28
+ * @param {boolean} [options.persistent=true] - Keep the process alive while watching
29
+ * @param {boolean} [options.recursive=false] - Watch subdirectories (directories only)
30
+ * @param {string} [options.overflow="ignore"] - Overflow behaviour ("ignore" or "throw")
31
+ * @returns {Promise<undefined>}
32
+ */
33
+ async watch(targets, {
34
+ onChange,
35
+ debounceMs=50,
36
+ persistent=true,
37
+ recursive=false,
38
+ overflow=OverFlowBehaviour.IGNORE
39
+ } = {}) {
40
+ Valid.type(targets, "FileObject|DirectoryObject|(FileObject|DirectoryObject)[]")
41
+ Valid.type(onChange, "Function")
42
+ Valid.type(debounceMs, "Number")
43
+ Valid.type(persistent, "Boolean")
44
+ Valid.type(recursive, "Undefined|Boolean")
45
+ Valid.type(overflow, "String")
46
+ Valid.assert(Object.values(OverFlowBehaviour).includes(overflow), `Overflow must be one of "ignore" or "throw".`)
47
+
48
+ if(!Data.isType(targets, "Array")) {
49
+ targets = [targets]
50
+ }
51
+
52
+ this.#abortController = new AbortController()
53
+
54
+ for(const target of targets) {
55
+ const watcher = watch(target.url, {
56
+ recursive: target.isDirectory ? recursive : false,
57
+ persistent,
58
+ signal: this.#abortController.signal,
59
+ overflow
60
+ })
61
+
62
+ this.#state.set(target, {busy: false, pending: false})
63
+
64
+ ;(async() => {
65
+ try {
66
+ for await(const _ of watcher) {
67
+ const state = this.#state.get(target)
68
+
69
+ if(!state) {
70
+ return
71
+ }
72
+
73
+ if(state.busy) {
74
+ state.pending = true
75
+ continue
76
+ }
77
+
78
+ state.pending = false
79
+ state.busy = true
80
+
81
+ while(true) {
82
+ await Time.after(debounceMs)
83
+
84
+ if(state.pending) {
85
+ state.pending = false
86
+ continue
87
+ }
88
+
89
+ break
90
+ }
91
+
92
+ try {
93
+ await onChange(target)
94
+ } catch(callbackErr) {
95
+ console.error("Watcher onChange callback error:", callbackErr)
96
+ }
97
+ state.busy = false
98
+ }
99
+ } catch(err) {
100
+ if(err.name === "AbortError") {
101
+ return
102
+ }
103
+
104
+ console.error("Watcher error:", err)
105
+ }
106
+ })()
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Stop watching all targets.
112
+ */
113
+ stopWatching() {
114
+ this.#state.clear()
115
+ this.#abortController?.abort()
116
+ this.#abortController = null
117
+ }
118
+ }
@@ -106,15 +106,9 @@ export default class Data {
106
106
  * defining the type of a value and whether an array is expected.
107
107
  *
108
108
  * @param {string} string - The string to parse into a type spec.
109
- * @param {TypeSpecOptions} [options] - Additional options for parsing.
110
- * @returns {Array<object>} An array of type specs.
109
+ * @returns {TypeSpec} A new TypeSpec instance.
111
110
  */
112
- static newTypeSpec(string: string, options?: {
113
- /**
114
- * - The delimiter for union types
115
- */
116
- delimiter?: string;
117
- }): Array<object>;
111
+ static newTypeSpec(string: string): TypeSpec;
118
112
  /**
119
113
  * Checks if a value is of a specified type
120
114
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Data.d.ts","sourceRoot":"","sources":["../../../src/browser/lib/Data.js"],"names":[],"mappings":"AAUA;IACA;;;;;OAKG;IACD,mBAFQ,KAAK,CAAC,MAAM,CAAC,CAgBnB;IAEF;;;;;OAKG;IACH,qBAFU,KAAK,CAAC,MAAM,CAAC,CAmBrB;IAEF;;;;;;;OAOG;IACH,kBAFU,KAAK,CAAC,MAAM,CAAC,CAKrB;IAEF;;;;;OAKG;IACH,uBAFU,KAAK,CAAC,MAAM,CAAC,CAE2D;IAElF;;;;;;OAMG;IACH,sBAJW,MAAM,UACN,MAAM,GACJ,MAAM,CAMlB;IAED;;;;;;OAMG;IACH,uBAJW,MAAM,WACN,MAAM,GACJ,MAAM,CAMlB;IAED;;;;;;;;;;;OAWG;IACH,yBATW,MAAM,UACN,MAAM,oBACN,OAAO,GACL,MAAM,CAWlB;IAED;;;;;;;;;;;OAWG;IACH,wBATW,MAAM,UACN,MAAM,oBACN,OAAO,GACL,MAAM,CAWlB;IAED;;;;;;;OAOG;IACH,yBALW,MAAM,UACN,MAAM,oBACN,OAAO,GACL,MAAM,CAWlB;IAED;;;;;;;OAOG;IACH,0BALW,MAAM,UACN,MAAM,oBACN,OAAO,GACL,MAAM,CAYlB;IAED;;;;;OAKG;IAEH;;;;;OAKG;IAEH;;;;;;;OAOG;IACH,2BAJW,MAAM;;;;oBAdH,MAAM;QAgBP,KAAK,CAAC,MAAM,CAAC,CAIzB;IAED;;;;;;;OAOG;IACH,qBALW,OAAO,QACP,MAAM,GAAC,QAAQ;;;;qBAnBZ,OAAO;QAqBR,OAAO,CAQnB;IAED;;;;;OAKG;IACH,yBAHW,MAAM,GACJ,OAAO,CASnB;IAED;;;;;;;;OAQG;IACH,yBAJW,OAAO,QACP,MAAM,GACJ,OAAO,CAenB;IAED;;;;;;OAMG;IACH,qBAHW,OAAO,GACL,MAAM,CAoBlB;IAED;;;;;OAKG;IACH,wBAHW,OAAO,GACL,OAAO,CAInB;IAED;;;;;;;;OAQG;IACH,sBALW,OAAO,oBACP,OAAO,GAEL,OAAO,CA8BnB;IAED;;;;;OAKG;IACH,6BAHW,MAAM,GACJ,MAAM,CAmBlB;IAED;;;;;;;OAOG;IACH,6BAJW,MAAM,QACN,KAAK,CAAC,MAAM,CAAC,GACX,MAAM,CAiBlB;IAED;;;;;;;OAOG;IACH,2BAJW,MAAM,QACN,KAAK,CAAC,MAAM,CAAC,SACb,OAAO,QAMjB;IAED;;;;;OAKG;IACH,+BAHc,MAAM,EAAA,GACP,MAAM,CAqBlB;IAED;;;;;;;OAOG;IACH,wBAJW,KAAK,CAAC,OAAO,CAAC,aACd,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,GAClC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAMnC;IAED;;;;;;;OAOG;IACH,kBALW,MAAM,OACN,MAAM,OACN,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;;OAOG;IACH,oBALW,MAAM,OACN,MAAM,OACN,MAAM,GACJ,OAAO,CAInB;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,4BAbW,OAAO,GACL,OAAO,CA+BnB;IAED;;;;;;;;;;;;;;;OAeG;IACH,uBAXW,OAAO,GACL,OAAO,CAgBnB;CACF;qBA5gBoB,eAAe"}
1
+ {"version":3,"file":"Data.d.ts","sourceRoot":"","sources":["../../../src/browser/lib/Data.js"],"names":[],"mappings":"AAUA;IACA;;;;;OAKG;IACD,mBAFQ,KAAK,CAAC,MAAM,CAAC,CAgBnB;IAEF;;;;;OAKG;IACH,qBAFU,KAAK,CAAC,MAAM,CAAC,CAmBrB;IAEF;;;;;;;OAOG;IACH,kBAFU,KAAK,CAAC,MAAM,CAAC,CAKrB;IAEF;;;;;OAKG;IACH,uBAFU,KAAK,CAAC,MAAM,CAAC,CAE2D;IAElF;;;;;;OAMG;IACH,sBAJW,MAAM,UACN,MAAM,GACJ,MAAM,CAMlB;IAED;;;;;;OAMG;IACH,uBAJW,MAAM,WACN,MAAM,GACJ,MAAM,CAMlB;IAED;;;;;;;;;;;OAWG;IACH,yBATW,MAAM,UACN,MAAM,oBACN,OAAO,GACL,MAAM,CAWlB;IAED;;;;;;;;;;;OAWG;IACH,wBATW,MAAM,UACN,MAAM,oBACN,OAAO,GACL,MAAM,CAWlB;IAED;;;;;;;OAOG;IACH,yBALW,MAAM,UACN,MAAM,oBACN,OAAO,GACL,MAAM,CAWlB;IAED;;;;;;;OAOG;IACH,0BALW,MAAM,UACN,MAAM,oBACN,OAAO,GACL,MAAM,CAYlB;IAED;;;;;OAKG;IAEH;;;;;OAKG;IAEH;;;;;;OAMG;IACH,2BAHW,MAAM,GACJ,QAAQ,CAIpB;IAED;;;;;;;OAOG;IACH,qBALW,OAAO,QACP,MAAM,GAAC,QAAQ;;;;qBAlBZ,OAAO;QAoBR,OAAO,CAQnB;IAED;;;;;OAKG;IACH,yBAHW,MAAM,GACJ,OAAO,CASnB;IAED;;;;;;;;OAQG;IACH,yBAJW,OAAO,QACP,MAAM,GACJ,OAAO,CAenB;IAED;;;;;;OAMG;IACH,qBAHW,OAAO,GACL,MAAM,CAoBlB;IAED;;;;;OAKG;IACH,wBAHW,OAAO,GACL,OAAO,CAInB;IAED;;;;;;;;OAQG;IACH,sBALW,OAAO,oBACP,OAAO,GAEL,OAAO,CA8BnB;IAED;;;;;OAKG;IACH,6BAHW,MAAM,GACJ,MAAM,CAmBlB;IAED;;;;;;;OAOG;IACH,6BAJW,MAAM,QACN,KAAK,CAAC,MAAM,CAAC,GACX,MAAM,CAiBlB;IAED;;;;;;;OAOG;IACH,2BAJW,MAAM,QACN,KAAK,CAAC,MAAM,CAAC,SACb,OAAO,QAMjB;IAED;;;;;OAKG;IACH,+BAHc,MAAM,EAAA,GACP,MAAM,CAqBlB;IAED;;;;;;;OAOG;IACH,wBAJW,KAAK,CAAC,OAAO,CAAC,aACd,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,GAClC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAMnC;IAED;;;;;;;OAOG;IACH,kBALW,MAAM,OACN,MAAM,OACN,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;;OAOG;IACH,oBALW,MAAM,OACN,MAAM,OACN,MAAM,GACJ,OAAO,CAInB;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,4BAbW,OAAO,GACL,OAAO,CA+BnB;IAED;;;;;;;;;;;;;;;OAeG;IACH,uBAXW,OAAO,GACL,OAAO,CAgBnB;CAEF;qBA5gBoB,eAAe"}
@@ -1,15 +1,3 @@
1
- /**
2
- * Options for creating a new TypeSpec.
3
- *
4
- * @typedef {object} TypeSpecOptions
5
- * @property {string} [delimiter="|"] - The delimiter for union types
6
- */
7
- /**
8
- * Options for type validation methods.
9
- *
10
- * @typedef {object} TypeValidationOptions
11
- * @property {boolean} [allowEmpty=true] - Whether empty values are allowed
12
- */
13
1
  /**
14
2
  * Type specification class for parsing and validating complex type definitions.
15
3
  * Supports union types, array types, and validation options.
@@ -19,9 +7,8 @@ export default class TypeSpec {
19
7
  * Creates a new TypeSpec instance.
20
8
  *
21
9
  * @param {string} string - The type specification string (e.g., "string|number", "object[]")
22
- * @param {TypeSpecOptions} [options] - Additional parsing options
23
10
  */
24
- constructor(string: string, options?: TypeSpecOptions);
11
+ constructor(string: string);
25
12
  specs: any[];
26
13
  length: number;
27
14
  stringRepresentation: string;
@@ -91,36 +78,34 @@ export default class TypeSpec {
91
78
  * Handles array types, union types, and empty value validation.
92
79
  *
93
80
  * @param {unknown} value - The value to test against the type specifications
94
- * @param {TypeValidationOptions} [options] - Validation options
81
+ * @param {TypeMatchOptions} [options] - Validation options
95
82
  * @returns {boolean} True if the value matches any type specification
96
83
  */
97
- matches(value: unknown, options?: TypeValidationOptions): boolean;
84
+ matches(value: unknown, options?: {
85
+ /**
86
+ * - Permit a spec of {@link Data.emptyableTypes} to be empty
87
+ */
88
+ allowEmpty?: boolean;
89
+ }): boolean;
90
+ /**
91
+ * Options that can be passed to {@link TypeSpec.match}
92
+ *
93
+ * @typedef {object} TypeMatchOptions
94
+ * @property {boolean} [allowEmpty=true] - Permit a spec of {@link Data.emptyableTypes} to be empty
95
+ */
98
96
  /**
99
97
  * Returns matching type specifications for a value.
100
98
  *
101
99
  * @param {unknown} value - The value to test against the type specifications
102
- * @param {TypeValidationOptions} [options] - Validation options
100
+ * @param {TypeMatchOptions} [options] - Validation options
103
101
  * @returns {Array<object>} Array of matching type specifications
104
102
  */
105
- match(value: unknown, options?: TypeValidationOptions): Array<object>;
103
+ match(value: unknown, { allowEmpty, }?: {
104
+ /**
105
+ * - Permit a spec of {@link Data.emptyableTypes} to be empty
106
+ */
107
+ allowEmpty?: boolean;
108
+ }): Array<object>;
106
109
  #private;
107
110
  }
108
- /**
109
- * Options for creating a new TypeSpec.
110
- */
111
- export type TypeSpecOptions = {
112
- /**
113
- * - The delimiter for union types
114
- */
115
- delimiter?: string;
116
- };
117
- /**
118
- * Options for type validation methods.
119
- */
120
- export type TypeValidationOptions = {
121
- /**
122
- * - Whether empty values are allowed
123
- */
124
- allowEmpty?: boolean;
125
- };
126
111
  //# sourceMappingURL=TypeSpec.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TypeSpec.d.ts","sourceRoot":"","sources":["../../../src/browser/lib/TypeSpec.js"],"names":[],"mappings":"AAWA;;;;;GAKG;AAEH;;;;;GAKG;AAEH;;;GAGG;AACH;IAGE;;;;;OAKG;IACH,oBAHW,MAAM,YACN,eAAe,EAUzB;IAJC,aAAwB;IACxB,eAAgC;IAChC,6BAA2C;IAI7C;;;;OAIG;IACH,YAFa,MAAM,CAQlB;IAED;;;;OAIG;IACH,UAFa,OAAO,CASnB;IAED;;;;OAIG;IACH,kBAFW,CAAS,IAAO,EAAP,OAAO,KAAG,IAAI,QAIjC;IAED;;;;;OAKG;IACH,gBAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,OAAO,CAInB;IAED;;;;;OAKG;IACH,eAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,OAAO,CAInB;IAED;;;;;OAKG;IACH,iBAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,KAAK,CAAC,OAAO,CAAC,CAI1B;IAED;;;;;OAKG;IACH,cAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,KAAK,CAAC,OAAO,CAAC,CAI1B;IAED;;;;;;OAMG;IACH,iBAJW,CAAS,IAAO,EAAP,OAAO,EAAE,IAAO,EAAP,OAAO,KAAG,OAAO,gBACnC,OAAO,GACL,OAAO,CAInB;IAED;;;;;OAKG;IACH,eAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,MAAM,GAAC,SAAS,CAI5B;IAED;;;;;;;OAOG;IACH,eAJW,OAAO,YACP,qBAAqB,GACnB,OAAO,CAInB;IAED;;;;;;OAMG;IACH,aAJW,OAAO,YACP,qBAAqB,GACnB,KAAK,CAAC,MAAM,CAAC,CA+DzB;;CAkDF;;;;;;;;gBApQa,MAAM;;;;;;;;;iBAON,OAAO"}
1
+ {"version":3,"file":"TypeSpec.d.ts","sourceRoot":"","sources":["../../../src/browser/lib/TypeSpec.js"],"names":[],"mappings":"AAWA;;;GAGG;AACH;IAGE;;;;OAIG;IACH,oBAFW,MAAM,EAUhB;IAJC,aAAwB;IACxB,eAAgC;IAChC,6BAA2C;IAI7C;;;;OAIG;IACH,YAFa,MAAM,CAkBlB;IAED;;;;OAIG;IACH,UAFa,OAAO,CASnB;IAED;;;;OAIG;IACH,kBAFW,CAAS,IAAO,EAAP,OAAO,KAAG,IAAI,QAIjC;IAED;;;;;OAKG;IACH,gBAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,OAAO,CAInB;IAED;;;;;OAKG;IACH,eAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,OAAO,CAInB;IAED;;;;;OAKG;IACH,iBAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,KAAK,CAAC,OAAO,CAAC,CAI1B;IAED;;;;;OAKG;IACH,cAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,KAAK,CAAC,OAAO,CAAC,CAI1B;IAED;;;;;;OAMG;IACH,iBAJW,CAAS,IAAO,EAAP,OAAO,EAAE,IAAO,EAAP,OAAO,KAAG,OAAO,gBACnC,OAAO,GACL,OAAO,CAInB;IAED;;;;;OAKG;IACH,eAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,MAAM,GAAC,SAAS,CAI5B;IAED;;;;;;;OAOG;IACH,eAJW,OAAO;;;;qBAYJ,OAAO;QAVR,OAAO,CAInB;IAED;;;;;OAKG;IAEH;;;;;;OAMG;IACH,aAJW,OAAO;;;;qBANJ,OAAO;QAQR,KAAK,CAAC,MAAM,CAAC,CAsGzB;;CAqFF"}
@@ -1,5 +1,5 @@
1
1
  export { default as Collection } from "../browser/lib/Collection.js";
2
- export { default as Data } from "../browser/lib/Data.js";
2
+ export { default as Data } from "./lib/Data.js";
3
3
  export { default as Promised } from "../browser/lib/Promised.js";
4
4
  export { default as Time } from "../browser/lib/Time.js";
5
5
  export { default as Type } from "../browser/lib/TypeSpec.js";
@@ -16,4 +16,5 @@ export { default as Glog } from "./lib/Glog.js";
16
16
  export { default as Term } from "./lib/Term.js";
17
17
  export { default as Disposer, Disposer as DisposerClass } from "../browser/lib/Disposer.js";
18
18
  export { default as Notify, Notify as NotifyClass } from "./lib/Notify.js";
19
+ export { default as Watcher, OverFlowBehaviour } from "./lib/Watcher.js";
19
20
  //# sourceMappingURL=index.d.ts.map