@gesslar/toolkit 3.22.2 → 3.23.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 (41) hide show
  1. package/README.md +2 -5
  2. package/package.json +10 -4
  3. package/src/browser/lib/Data.js +16 -2
  4. package/src/browser/lib/OObject.js +196 -0
  5. package/src/browser/lib/Promised.js +4 -2
  6. package/src/browser/lib/Time.js +4 -2
  7. package/src/browser/lib/TypeSpec.js +24 -5
  8. package/src/node/index.js +0 -3
  9. package/src/node/lib/DirectoryObject.js +100 -212
  10. package/src/node/lib/FileObject.js +26 -44
  11. package/src/node/lib/FileSystem.js +3 -42
  12. package/src/node/lib/Glog.js +2 -12
  13. package/src/node/lib/Valid.js +8 -1
  14. package/types/browser/lib/Data.d.ts +26 -4
  15. package/types/browser/lib/Data.d.ts.map +1 -1
  16. package/types/browser/lib/OObject.d.ts +127 -0
  17. package/types/browser/lib/OObject.d.ts.map +1 -0
  18. package/types/browser/lib/Promised.d.ts.map +1 -1
  19. package/types/browser/lib/Time.d.ts.map +1 -1
  20. package/types/browser/lib/TypeSpec.d.ts +42 -6
  21. package/types/browser/lib/TypeSpec.d.ts.map +1 -1
  22. package/types/node/index.d.ts +0 -3
  23. package/types/node/lib/DirectoryObject.d.ts +93 -51
  24. package/types/node/lib/DirectoryObject.d.ts.map +1 -1
  25. package/types/node/lib/FileObject.d.ts +2 -10
  26. package/types/node/lib/FileObject.d.ts.map +1 -1
  27. package/types/node/lib/FileSystem.d.ts +10 -19
  28. package/types/node/lib/FileSystem.d.ts.map +1 -1
  29. package/types/node/lib/Glog.d.ts +0 -7
  30. package/types/node/lib/Glog.d.ts.map +1 -1
  31. package/types/node/lib/Valid.d.ts +17 -2
  32. package/types/node/lib/Valid.d.ts.map +1 -1
  33. package/src/node/lib/TempDirectoryObject.js +0 -165
  34. package/src/node/lib/VDirectoryObject.js +0 -198
  35. package/src/node/lib/VFileObject.js +0 -110
  36. package/types/node/lib/TempDirectoryObject.d.ts +0 -42
  37. package/types/node/lib/TempDirectoryObject.d.ts.map +0 -1
  38. package/types/node/lib/VDirectoryObject.d.ts +0 -132
  39. package/types/node/lib/VDirectoryObject.d.ts.map +0 -1
  40. package/types/node/lib/VFileObject.d.ts +0 -33
  41. package/types/node/lib/VFileObject.d.ts.map +0 -1
package/README.md CHANGED
@@ -42,12 +42,10 @@ Includes all browser functionality plus Node.js-specific modules for file I/O, l
42
42
  | Notify | Event system wrapper for Node.js events |
43
43
  | Sass | Custom Error class with enhanced features |
44
44
  | Tantrum | AggregateError implementation |
45
- | TempDirectoryObject | Temporary directory management with automatic cleanup |
46
45
  | Term | Terminal formatting and output utilities |
47
46
  | Util | General utility functions (Node-enhanced version) |
48
47
  | Valid | Validation and assertion methods |
49
- | VDirectoryObject | Directory operations constrained to a specific tree |
50
- | VFileObject | Virtual file operations for in-memory file handling |
48
+
51
49
 
52
50
  ## Installation
53
51
 
@@ -100,8 +98,7 @@ import { Data, Collection, Util } from '@gesslar/toolkit/browser'
100
98
 
101
99
  The browser version includes: Collection, Data, Disposer, HTML, Notify, Sass,
102
100
  Tantrum, Type (TypeSpec), Util, and Valid. Node-only modules (Cache,
103
- DirectoryObject, FileObject, FileSystem, Glog, TempDirectoryObject, Term,
104
- VDirectoryObject, VFileObject) are not available in the browser version.
101
+ DirectoryObject, FileObject, FileSystem, Glog, Term) are not available in the browser version.
105
102
 
106
103
  ## Post Partum
107
104
 
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "name": "gesslar",
6
6
  "url": "https://gesslar.dev"
7
7
  },
8
- "version": "3.22.2",
8
+ "version": "3.23.0",
9
9
  "license": "Unlicense",
10
10
  "homepage": "https://github.com/gesslar/toolkit#readme",
11
11
  "repository": {
@@ -52,16 +52,22 @@
52
52
  "node": ">=22"
53
53
  },
54
54
  "dependencies": {
55
+ "@eslint/js": "^9.39.2",
55
56
  "@gesslar/colours": "^0.8.0",
57
+ "@stylistic/eslint-plugin": "^5.7.0",
56
58
  "ajv": "^8.17.1",
59
+ "globals": "^17.0.0",
57
60
  "json5": "^2.2.3",
61
+ "types": "^0.1.1",
58
62
  "yaml": "^2.8.2"
59
63
  },
60
64
  "devDependencies": {
61
- "@gesslar/uglier": "^1.0.0",
65
+ "@gesslar/uglier": "^1.1.0",
62
66
  "eslint": "^9.39.2",
63
- "happy-dom": "^20.1.0",
64
- "typescript": "^5.9.3"
67
+ "eslint-plugin-jsdoc": "^62.0.0",
68
+ "happy-dom": "^20.3.1",
69
+ "typescript": "^5.9.3",
70
+ "typescript-eslint": "^8.53.0"
65
71
  },
66
72
  "scripts": {
67
73
  "types": "node -e \"require('fs').rmSync('types',{recursive:true,force:true});\" && tsc -p tsconfig.types.json",
@@ -180,12 +180,26 @@ export default class Data {
180
180
  return string.slice(index + length)
181
181
  }
182
182
 
183
+ /**
184
+ * Options for creating a new TypeSpec.
185
+ *
186
+ * @typedef {object} TypeSpecOptions
187
+ * @property {string} [delimiter="|"] - The delimiter for union types
188
+ */
189
+
190
+ /**
191
+ * Options for type validation methods.
192
+ *
193
+ * @typedef {object} TypeValidationOptions
194
+ * @property {boolean} [allowEmpty=true] - Whether empty values are allowed
195
+ */
196
+
183
197
  /**
184
198
  * Creates a type spec from a string. A type spec is an array of objects
185
199
  * defining the type of a value and whether an array is expected.
186
200
  *
187
201
  * @param {string} string - The string to parse into a type spec.
188
- * @param {object} options - Additional options for parsing.
202
+ * @param {TypeSpecOptions} [options] - Additional options for parsing.
189
203
  * @returns {Array<object>} An array of type specs.
190
204
  */
191
205
  static newTypeSpec(string, options) {
@@ -197,7 +211,7 @@ export default class Data {
197
211
  *
198
212
  * @param {unknown} value The value to check
199
213
  * @param {string|TypeSpec} type The type to check for
200
- * @param {object} options Additional options for checking
214
+ * @param {TypeValidationOptions} [options] Additional options for checking
201
215
  * @returns {boolean} Whether the value is of the specified type
202
216
  */
203
217
  static isType(value, type, options = {}) {
@@ -0,0 +1,196 @@
1
+ import Data from "./Data.js"
2
+ import Valid from "./Valid.js"
3
+
4
+ /**
5
+ * @typedef {object} OObjectArrayInfo
6
+ * @property {Array<string>} path - The path array to the array element
7
+ * @property {string} flatPath - The dot-separated path to the array element
8
+ * @property {number} index - The index of the element in the array
9
+ */
10
+
11
+ /**
12
+ * @typedef {object} OObjectEntry
13
+ * @property {string} key - The property key
14
+ * @property {any} value - The property value
15
+ * @property {string} valueString - String representation of the value
16
+ * @property {Array<string>} path - The path array to this property
17
+ * @property {string} flatPath - The dot-separated path to this property
18
+ * @property {OObjectArrayInfo} [array] - Array information if this entry is from an array
19
+ */
20
+
21
+ /**
22
+ * @typedef {Record<string, any> | Array<any>} OObjectSource
23
+ */
24
+
25
+ export default class OObject {
26
+ /** @type {Array<OObjectEntry>} */
27
+ #data = []
28
+
29
+ /**
30
+ * Constructs an OObject with optional initial data.
31
+ *
32
+ * @param {Array<OObjectEntry>} oobject
33
+ */
34
+ constructor(oobject=[]) {
35
+ this.#data = oobject
36
+ }
37
+
38
+ /**
39
+ * Creates an OObject from a source object or array
40
+ *
41
+ * @param {OObjectSource} source - The source object or array to decompose
42
+ * @returns {OObject} A new OObject instance
43
+ */
44
+ static from(source) {
45
+ Valid.type(source, "Object|Array")
46
+
47
+ return new this(this.#decomposeObject(source))
48
+ }
49
+
50
+ /**
51
+ * Decomposes a nested object into flat entries with path information.
52
+ * Recursively processes objects and arrays to create a flat structure for
53
+ * evaluation.
54
+ *
55
+ * @param {Record<string, any>} work - The object to decompose
56
+ * @param {Array<string>} objectPath - Current path array for nested properties
57
+ * @returns {Array<OObjectEntry>} Array of decomposed object entries with path information
58
+ */
59
+ static #decomposeObject(work, objectPath=[]) {
60
+ Valid.type(work, "Object|Array")
61
+ Valid.type(objectPath, "Array")
62
+
63
+ const result = []
64
+
65
+ for(const key in work) {
66
+ const currPath = [...objectPath, key]
67
+ const item = work[key]
68
+
69
+ if(Data.isPlainObject(item)) {
70
+ result.push(...this.#decomposeObject(work[key], currPath))
71
+ } else if(Array.isArray(work[key])) {
72
+ work[key].forEach((item, index) => {
73
+ const path = [...currPath, String(index+1)]
74
+
75
+ if(Data.isPlainObject(item)) {
76
+ result.push(...this.#decomposeObject(item, path))
77
+ } else {
78
+ result.push({
79
+ key,
80
+ value: item,
81
+ valueString: String(item),
82
+ path,
83
+ flatPath: path.join("."),
84
+ array: {
85
+ path: path.slice(0, -1),
86
+ flatPath: path.slice(0, -1).join("."),
87
+ index
88
+ }
89
+ })
90
+ }
91
+ })
92
+ } else {
93
+ result.push({key, value: item, valueString: String(item), path: currPath, flatPath: currPath.join(".")})
94
+ }
95
+ }
96
+
97
+ return result
98
+ }
99
+
100
+ /**
101
+ * Gets the internal data array
102
+ *
103
+ * @returns {Array<object>} The decomposed object entries
104
+ */
105
+ get data() {
106
+ return this.#data
107
+ }
108
+
109
+ /**
110
+ * Finds the first entry matching a flat path or predicate
111
+ *
112
+ * @param {string|((entry: OObjectEntry, index: number, array: Array<OObjectEntry>) => boolean)} pathOrPredicate - Flat path string or predicate function
113
+ * @returns {OObjectEntry|undefined} The matching entry or undefined
114
+ */
115
+ find(pathOrPredicate) {
116
+ if(typeof pathOrPredicate === "string") {
117
+ return this.#data.find(entry => entry.flatPath === pathOrPredicate)
118
+ }
119
+
120
+ Valid.type(pathOrPredicate, "function")
121
+
122
+ return this.#data.find(pathOrPredicate)
123
+ }
124
+
125
+ /**
126
+ * Finds all entries matching a flat path or predicate
127
+ *
128
+ * @param {string|((entry: OObjectEntry, index: number, array: Array<OObjectEntry>) => boolean)} pathOrPredicate - Flat path string or predicate function
129
+ * @returns {Array<object>} Array of matching entries
130
+ */
131
+ findAll(pathOrPredicate) {
132
+ if(typeof pathOrPredicate === "string") {
133
+ return this.#data.filter(entry => entry.flatPath === pathOrPredicate)
134
+ }
135
+
136
+ Valid.type(pathOrPredicate, "function")
137
+
138
+ return this.#data.filter(pathOrPredicate)
139
+ }
140
+
141
+ /**
142
+ * Returns an iterator over all entries in order
143
+ *
144
+ * @returns {Iterator<object>} Iterator of decomposed entries
145
+ */
146
+ entries() {
147
+ return this.#data[Symbol.iterator]()
148
+ }
149
+
150
+ /**
151
+ * Executes a callback for each entry in order
152
+ *
153
+ * @param {(entry: OObjectEntry, index: number, array: Array<OObjectEntry>) => void} callback - Function to call for each entry
154
+ * @returns {void}
155
+ */
156
+ forEach(callback) {
157
+ Valid.type(callback, "function")
158
+
159
+ this.#data.forEach(callback)
160
+ }
161
+
162
+ /**
163
+ * Ensures a path exists in the data, optionally setting a value
164
+ *
165
+ * @param {string} flatPath - The dot-separated path to ensure
166
+ * @param {*} value - Optional value to set (defaults to undefined)
167
+ * @returns {object} The entry at the path
168
+ */
169
+ assurePath(flatPath, value=undefined) {
170
+ Valid.type(flatPath, "string")
171
+
172
+ let entry = this.find(flatPath)
173
+
174
+ if(!entry) {
175
+ const path = flatPath.split(".")
176
+ const key = path[path.length - 1]
177
+
178
+ /** @type {OObjectEntry} */
179
+ const newEntry = {
180
+ key,
181
+ value,
182
+ valueString: String(value),
183
+ path,
184
+ flatPath
185
+ }
186
+
187
+ this.#data.push(newEntry)
188
+ entry = newEntry
189
+ } else if(value !== undefined) {
190
+ entry.value = value
191
+ entry.valueString = String(value)
192
+ }
193
+
194
+ return entry
195
+ }
196
+ }
@@ -118,10 +118,12 @@ export default class Promised {
118
118
  * @param {Array<{status: 'fulfilled'|'rejected', value?: unknown, reason?: unknown}>} settled - Array of settled promise results
119
119
  * @throws {Tantrum} Throws a Tantrum error with rejection reasons
120
120
  */
121
- static throw(message="GIGO", settled) {
122
- Valid.type(message, "String", {allowEmpty: false})
121
+ static throw(message, settled) {
122
+ Valid.type(message, "Null|Undefined|String", {allowEmpty: false})
123
123
  Valid.type(settled, "Array")
124
124
 
125
+ message ??= "GIGO"
126
+
125
127
  const rejected = this.rejected(settled)
126
128
  const reasons = this.reasons(rejected)
127
129
 
@@ -1,5 +1,5 @@
1
+ import Sass from "./Sass.js"
1
2
  import Valid from "./Valid.js"
2
-
3
3
  /**
4
4
  * Utility class for timing operations and promise-based delays.
5
5
  * Provides methods for creating cancellable timeout promises.
@@ -30,7 +30,9 @@ export default class Time {
30
30
 
31
31
  let timerId
32
32
  const promise = new Promise(resolve => {
33
- timerId = setTimeout(() => resolve(value), delay)
33
+ // Cap at max 32-bit signed integer to avoid Node.js timeout overflow warning
34
+ const safeDelay = Math.min(delay, 2147483647)
35
+ timerId = setTimeout(() => resolve(value), safeDelay)
34
36
  })
35
37
  promise.timerId = timerId
36
38
 
@@ -9,6 +9,20 @@ import Data from "./Data.js"
9
9
  import Sass from "./Sass.js"
10
10
  import Util from "./Util.js"
11
11
 
12
+ /**
13
+ * Options for creating a new TypeSpec.
14
+ *
15
+ * @typedef {object} TypeSpecOptions
16
+ * @property {string} [delimiter="|"] - The delimiter for union types
17
+ */
18
+
19
+ /**
20
+ * Options for type validation methods.
21
+ *
22
+ * @typedef {object} TypeValidationOptions
23
+ * @property {boolean} [allowEmpty=true] - Whether empty values are allowed
24
+ */
25
+
12
26
  /**
13
27
  * Type specification class for parsing and validating complex type definitions.
14
28
  * Supports union types, array types, and validation options.
@@ -20,7 +34,7 @@ export default class TypeSpec {
20
34
  * Creates a new TypeSpec instance.
21
35
  *
22
36
  * @param {string} string - The type specification string (e.g., "string|number", "object[]")
23
- * @param {unknown} options - Additional parsing options
37
+ * @param {TypeSpecOptions} [options] - Additional parsing options
24
38
  */
25
39
  constructor(string, options) {
26
40
  this.#specs = []
@@ -134,14 +148,20 @@ export default class TypeSpec {
134
148
  * Handles array types, union types, and empty value validation.
135
149
  *
136
150
  * @param {unknown} value - The value to test against the type specifications
137
- * @param {unknown} options - Validation options
138
- * @param {boolean} options.allowEmpty - Whether empty values are allowed
151
+ * @param {TypeValidationOptions} [options] - Validation options
139
152
  * @returns {boolean} True if the value matches any type specification
140
153
  */
141
154
  matches(value, options) {
142
155
  return this.match(value, options).length > 0
143
156
  }
144
157
 
158
+ /**
159
+ * Returns matching type specifications for a value.
160
+ *
161
+ * @param {unknown} value - The value to test against the type specifications
162
+ * @param {TypeValidationOptions} [options] - Validation options
163
+ * @returns {Array<object>} Array of matching type specifications
164
+ */
145
165
  match(value, options) {
146
166
  const allowEmpty = options?.allowEmpty ?? true
147
167
 
@@ -211,8 +231,7 @@ export default class TypeSpec {
211
231
  *
212
232
  * @private
213
233
  * @param {string} string - The type specification string to parse
214
- * @param {unknown} options - Parsing options
215
- * @param {string} options.delimiter - The delimiter for union types
234
+ * @param {TypeSpecOptions} [options] - Parsing options
216
235
  * @throws {Sass} If the type specification is invalid
217
236
  */
218
237
  #parse(string, options={delimiter: "|"}) {
package/src/node/index.js CHANGED
@@ -20,7 +20,4 @@ export {default as FileObject} from "./lib/FileObject.js"
20
20
  export {default as FileSystem} from "./lib/FileSystem.js"
21
21
  export {default as Glog} from "./lib/Glog.js"
22
22
  export {default as Notify} from "./lib/Notify.js"
23
- export {default as TempDirectoryObject} from "./lib/TempDirectoryObject.js"
24
23
  export {default as Term} from "./lib/Term.js"
25
- export {default as VFileObject} from "./lib/VFileObject.js"
26
- export {default as VDirectoryObject} from "./lib/VDirectoryObject.js"