@gesslar/toolkit 0.2.0 → 0.2.1

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": "@gesslar/toolkit",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Get in, bitches, we're going toolkitting.",
5
5
  "main": "./src/index.js",
6
6
  "type": "module",
package/src/index.js CHANGED
@@ -5,6 +5,7 @@ export {default as FS} from "./lib/FS.js"
5
5
 
6
6
  // Utility classes
7
7
  export {default as Cache} from "./lib/Cache.js"
8
+ export {default as Collection} from "./lib/Collection.js"
8
9
  export {default as Data} from "./lib/Data.js"
9
10
  export {default as Glog} from "./lib/Glog.js"
10
11
  export {default as Sass} from "./lib/Sass.js"
@@ -0,0 +1,108 @@
1
+ import Data from "./Data.js"
2
+ import Valid from "./Valid.js"
3
+
4
+ export default class Collection {
5
+ static evalArray(collection, predicate, forward=true) {
6
+ const req = "Array"
7
+ const type = Data.typeOf(collection)
8
+
9
+ Valid.type(collection, req, `Invalid collection. Expected '${req}, got ${type}`)
10
+ Valid.type(predicate, "Function",
11
+ `Invalid predicate, expected 'Function', got ${Data.typeOf(predicate)}`)
12
+
13
+ const work = forward
14
+ ? Array.from(collection)
15
+ : Array.from(collection).toReversed()
16
+
17
+ for(let i = 0; i < work.length; i++) {
18
+ const result = predicate(work[i], i, collection) ?? null
19
+
20
+ if(result)
21
+ return result
22
+ }
23
+ }
24
+
25
+ static evalObject(collection, predicate) {
26
+ const req = "Object"
27
+ const type = Data.typeOf(collection)
28
+
29
+ Valid.type(collection, req, `Invalid collection. Expected '${req}, got ${type}`)
30
+ Valid.type(predicate, "Function",
31
+ `Invalid predicate, expected 'Function', got ${Data.typeOf(predicate)}`)
32
+
33
+ const work = Object.entries(collection)
34
+
35
+ for(let i = 0; i < work.length; i++) {
36
+ const result = predicate(work[i][1], work[i][0], collection)
37
+
38
+ if(result)
39
+ return result
40
+ }
41
+ }
42
+
43
+ static evalSet(collection, predicate) {
44
+ const req = "Set"
45
+ const type = Data.typeOf(collection)
46
+
47
+ Valid.type(collection, req, `Invalid collection. Expected '${req}, got ${type}`)
48
+ Valid.type(predicate, "Function",
49
+ `Invalid predicate, expected 'Function', got ${Data.typeOf(predicate)}`)
50
+
51
+ const work = Array.from(collection)
52
+
53
+ for(let i = 0; i < work.length; i++) {
54
+ const result = predicate(work[i], collection)
55
+
56
+ if(result)
57
+ return result
58
+ }
59
+ }
60
+
61
+ static evalMap(collection, predicate, forward=true) {
62
+ const req = "Map"
63
+ const type = Data.typeOf(collection)
64
+
65
+ Valid.type(collection, req, `Invalid collection. Expected '${req}, got ${type}`)
66
+ Valid.type(predicate, "Function",
67
+ `Invalid predicate, expected 'Function', got ${Data.typeOf(predicate)}`)
68
+
69
+ const work = forward
70
+ ? Array.from(collection)
71
+ : Array.from(collection).toReversed()
72
+
73
+ for(let i = 0; i < work.length; i++) {
74
+ const result = predicate(work[i][1], work[i][0], collection) ?? null
75
+
76
+ if(result)
77
+ return result
78
+ }
79
+ }
80
+
81
+ static zip(array1, array2) {
82
+ const minLength = Math.min(array1.length, array2.length)
83
+
84
+ return Array.from({length: minLength}, (_, i) => [array1[i], array2[i]])
85
+ }
86
+
87
+ static unzip(array) {
88
+ if(!Array.isArray(array) || array.length === 0) {
89
+ return [] // Handle empty or invalid input
90
+ }
91
+
92
+ // Determine the number of "unzipped" arrays needed
93
+ // This assumes all inner arrays have the same length, or we take the max length
94
+ const numUnzippedArrays = Math.max(...array.map(arr => arr.length))
95
+
96
+ // Initialize an array of empty arrays to hold the unzipped results
97
+ const unzipped = Array.from({length: numUnzippedArrays}, () => [])
98
+
99
+ // Iterate through the zipped array and populate the unzipped arrays
100
+ for(let i = 0; i < array.length; i++) {
101
+ for(let j = 0; j < numUnzippedArrays; j++) {
102
+ unzipped[j].push(array[i][j])
103
+ }
104
+ }
105
+
106
+ return unzipped
107
+ }
108
+ }
@@ -0,0 +1,138 @@
1
+ // Implementation: ../lib/Collection.js
2
+ // Type definitions for Collection utilities
3
+
4
+ /**
5
+ * Collection utility functions for evaluating and manipulating arrays, objects, sets, and maps.
6
+ * Provides functional programming patterns for collection processing with consistent error handling.
7
+ */
8
+ export default class Collection {
9
+ /**
10
+ * Evaluates an array with a predicate function, returning the first truthy result.
11
+ *
12
+ * @param collection - The array to evaluate
13
+ * @param predicate - Function called for each element: (element, index, array) => result
14
+ * @param forward - Whether to iterate forward (true) or backward (false). Default: true
15
+ * @returns The first truthy result from the predicate, or undefined if none found
16
+ *
17
+ * @throws {Sass} If collection is not an Array or predicate is not a Function
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * import { Collection } from '@gesslar/toolkit'
22
+ *
23
+ * const numbers = [1, 2, 3, 4, 5]
24
+ * const result = Collection.evalArray(numbers, (n, i) => n > 3 ? n * 2 : null)
25
+ * console.log(result) // 8 (first element > 3, doubled)
26
+ * ```
27
+ */
28
+ static evalArray<T, R>(
29
+ collection: T[],
30
+ predicate: (element: T, index: number, array: T[]) => R | null | undefined,
31
+ forward?: boolean
32
+ ): R | undefined
33
+
34
+ /**
35
+ * Evaluates an object with a predicate function, returning the first truthy result.
36
+ *
37
+ * @param collection - The object to evaluate
38
+ * @param predicate - Function called for each property: (value, key, object) => result
39
+ * @returns The first truthy result from the predicate, or undefined if none found
40
+ *
41
+ * @throws {Sass} If collection is not an Object or predicate is not a Function
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * import { Collection } from '@gesslar/toolkit'
46
+ *
47
+ * const obj = {a: 1, b: 2, c: 3}
48
+ * const result = Collection.evalObject(obj, (value, key) => value > 2 ? `${key}:${value}` : null)
49
+ * console.log(result) // "c:3"
50
+ * ```
51
+ */
52
+ static evalObject<T, R>(
53
+ collection: Record<string, T>,
54
+ predicate: (value: T, key: string, object: Record<string, T>) => R | null | undefined
55
+ ): R | undefined
56
+
57
+ /**
58
+ * Evaluates a Set with a predicate function, returning the first truthy result.
59
+ *
60
+ * @param collection - The Set to evaluate
61
+ * @param predicate - Function called for each element: (element, set) => result
62
+ * @returns The first truthy result from the predicate, or undefined if none found
63
+ *
64
+ * @throws {Sass} If collection is not a Set or predicate is not a Function
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * import { Collection } from '@gesslar/toolkit'
69
+ *
70
+ * const set = new Set([1, 2, 3, 4, 5])
71
+ * const result = Collection.evalSet(set, (n, s) => n > 3 ? n * 2 : null)
72
+ * console.log(result) // 8
73
+ * ```
74
+ */
75
+ static evalSet<T, R>(
76
+ collection: Set<T>,
77
+ predicate: (element: T, set: Set<T>) => R | null | undefined
78
+ ): R | undefined
79
+
80
+ /**
81
+ * Evaluates a Map with a predicate function, returning the first truthy result.
82
+ *
83
+ * @param collection - The Map to evaluate
84
+ * @param predicate - Function called for each entry: (value, key, map) => result
85
+ * @param forward - Whether to iterate forward (true) or backward (false). Default: true
86
+ * @returns The first truthy result from the predicate, or undefined if none found
87
+ *
88
+ * @throws {Sass} If collection is not a Map or predicate is not a Function
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * import { Collection } from '@gesslar/toolkit'
93
+ *
94
+ * const map = new Map([['a', 1], ['b', 2], ['c', 3]])
95
+ * const result = Collection.evalMap(map, (value, key) => value > 2 ? `${key}:${value}` : null)
96
+ * console.log(result) // "c:3"
97
+ * ```
98
+ */
99
+ static evalMap<K, V, R>(
100
+ collection: Map<K, V>,
101
+ predicate: (value: V, key: K, map: Map<K, V>) => R | null | undefined,
102
+ forward?: boolean
103
+ ): R | undefined
104
+
105
+ /**
106
+ * Zips two arrays together into an array of pairs.
107
+ *
108
+ * @param array1 - The first array
109
+ * @param array2 - The second array
110
+ * @returns Array of [element1, element2] pairs, length of shorter input array
111
+ *
112
+ * @example
113
+ * ```typescript
114
+ * import { Collection } from '@gesslar/toolkit'
115
+ *
116
+ * const result = Collection.zip([1, 2, 3], ['a', 'b', 'c'])
117
+ * console.log(result) // [[1, 'a'], [2, 'b'], [3, 'c']]
118
+ * ```
119
+ */
120
+ static zip<T, U>(array1: T[], array2: U[]): [T, U][]
121
+
122
+ /**
123
+ * Unzips an array of arrays into separate arrays.
124
+ *
125
+ * @param array - Array of arrays to unzip
126
+ * @returns Array of separate arrays, one for each position
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * import { Collection } from '@gesslar/toolkit'
131
+ *
132
+ * const zipped = [[1, 'a'], [2, 'b'], [3, 'c']]
133
+ * const result = Collection.unzip(zipped)
134
+ * console.log(result) // [[1, 2, 3], ['a', 'b', 'c']]
135
+ * ```
136
+ */
137
+ static unzip<T>(array: T[][]): T[][]
138
+ }
@@ -6,6 +6,7 @@ export { default as FS } from './FS.js'
6
6
 
7
7
  // Utility classes
8
8
  export { default as Cache } from './Cache.js'
9
+ export { default as Collection } from './Collection.js'
9
10
  export { default as Data } from './Data.js'
10
11
  export { default as Glog } from './Glog.js'
11
12
  export { default as Sass } from './Sass.js'