ts-data-forge 1.5.2 → 2.0.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.
Files changed (41) hide show
  1. package/README.md +56 -44
  2. package/dist/array/array-utils.d.mts +661 -166
  3. package/dist/array/array-utils.d.mts.map +1 -1
  4. package/dist/array/array-utils.mjs +719 -79
  5. package/dist/array/array-utils.mjs.map +1 -1
  6. package/dist/array/index.d.mts +0 -1
  7. package/dist/array/index.d.mts.map +1 -1
  8. package/dist/array/index.mjs +0 -1
  9. package/dist/array/index.mjs.map +1 -1
  10. package/dist/collections/queue.mjs +0 -1
  11. package/dist/collections/queue.mjs.map +1 -1
  12. package/dist/collections/stack.mjs +4 -5
  13. package/dist/collections/stack.mjs.map +1 -1
  14. package/dist/functional/pipe.d.mts +56 -61
  15. package/dist/functional/pipe.d.mts.map +1 -1
  16. package/dist/functional/pipe.mjs.map +1 -1
  17. package/dist/globals.d.mts +10 -9
  18. package/dist/index.mjs +0 -1
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/json/json.mjs +0 -1
  21. package/dist/json/json.mjs.map +1 -1
  22. package/dist/number/num.d.mts +1 -1
  23. package/package.json +2 -2
  24. package/src/array/array-utils-modification.test.mts +93 -67
  25. package/src/array/array-utils-overload-type-error.test.mts +2 -2
  26. package/src/array/array-utils-reducing-value.test.mts +31 -37
  27. package/src/array/array-utils-slice-clamped.test.mts +94 -70
  28. package/src/array/array-utils-transformation.test.mts +557 -10
  29. package/src/array/array-utils.mts +1457 -516
  30. package/src/array/index.mts +0 -1
  31. package/src/collections/queue.mts +2 -2
  32. package/src/collections/stack.mts +8 -8
  33. package/src/functional/pipe.mts +65 -75
  34. package/src/globals.d.mts +10 -9
  35. package/src/number/num.mts +1 -1
  36. package/dist/array/tuple-utils.d.mts +0 -407
  37. package/dist/array/tuple-utils.d.mts.map +0 -1
  38. package/dist/array/tuple-utils.mjs +0 -345
  39. package/dist/array/tuple-utils.mjs.map +0 -1
  40. package/src/array/tuple-utils.mts +0 -498
  41. package/src/array/tuple-utils.test.mts +0 -518
package/README.md CHANGED
@@ -7,6 +7,17 @@
7
7
 
8
8
  **ts-data-forge** is a TypeScript utility library that provides type-safe functional programming utilities with zero runtime dependencies. It aims to enhance development robustness, maintainability, and correctness by leveraging TypeScript's powerful type system.
9
9
 
10
+ ## Perfect Companion to ts-type-forge
11
+
12
+ **ts-data-forge** is designed as the ideal runtime companion to [**ts-type-forge**](https://github.com/noshiro-pf/ts-type-forge), a powerful type utility library. While ts-type-forge provides compile-time type utilities for advanced TypeScript type manipulation, ts-data-forge complements it with runtime utilities that maintain the same level of type safety.
13
+
14
+ Together, they form a complete TypeScript development toolkit:
15
+
16
+ - **ts-type-forge**: Compile-time type utilities (type manipulation, type inference, advanced type patterns)
17
+ - **ts-data-forge**: Runtime utilities with strong type safety (type guards, branded types, functional programming utilities)
18
+
19
+ This synergy enables you to build fully type-safe applications from compile-time to runtime, ensuring type correctness throughout your entire codebase.
20
+
10
21
  ## Features
11
22
 
12
23
  This library offers a range of utilities, including:
@@ -155,7 +166,7 @@ const maybeValue = Optional.some(42);
155
166
 
156
167
  const doubled = Optional.map(maybeValue, (x) => x * 2);
157
168
 
158
- assert.strictEqual(Optional.unwrapOr(doubled, 0), 84);
169
+ assert(Optional.unwrapOr(doubled, 0) === 84);
159
170
 
160
171
  // Result for error handling
161
172
  const success = Result.ok(42);
@@ -185,16 +196,16 @@ const handleStatus = (status: Status, data?: string): string =>
185
196
  error: 'An error occurred',
186
197
  });
187
198
 
188
- assert.strictEqual(handleStatus('loading'), 'Please wait...');
189
- assert.strictEqual(handleStatus('success', 'Hello'), 'Data: Hello');
190
- assert.strictEqual(handleStatus('error'), 'An error occurred');
199
+ assert(handleStatus('loading') === 'Please wait...');
200
+ assert(handleStatus('success', 'Hello') === 'Data: Hello');
201
+ assert(handleStatus('error') === 'An error occurred');
191
202
 
192
203
  // Pattern matching with Result
193
204
  const processResult = (result: Result<number, string>): string =>
194
205
  Result.isOk(result) ? `Success: ${result.value}` : `Error: ${result.value}`;
195
206
 
196
- assert.strictEqual(processResult(Result.ok(42)), 'Success: 42');
197
- assert.strictEqual(processResult(Result.err('Failed')), 'Error: Failed');
207
+ assert(processResult(Result.ok(42)) === 'Success: 42');
208
+ assert(processResult(Result.err('Failed')) === 'Error: Failed');
198
209
  ```
199
210
 
200
211
  ### 3. Number Utilities with `Num` and Branded Number Types
@@ -205,35 +216,35 @@ The `Num` object provides safe and convenient functions for numerical operations
205
216
  import { Num } from 'ts-data-forge';
206
217
 
207
218
  // Basic conversions
208
- assert.strictEqual(Num.from('123'), 123);
209
- assert.strictEqual(Number.isNaN(Num.from('abc')), true);
219
+ assert(Num.from('123') === 123);
220
+ assert(Number.isNaN(Num.from('abc')));
210
221
 
211
222
  // Range checking
212
223
  const inRange = Num.isInRange(0, 10);
213
224
 
214
- assert.strictEqual(inRange(5), true);
215
- assert.strictEqual(inRange(0), true); // (inclusive lower bound)
216
- assert.strictEqual(inRange(10), false); // (exclusive upper bound)
225
+ assert(inRange(5));
226
+ assert(inRange(0)); // (inclusive lower bound)
227
+ assert(!inRange(10)); // (exclusive upper bound)
217
228
 
218
229
  // Clamping values
219
230
  const clamp = Num.clamp(0, 100);
220
231
 
221
- assert.strictEqual(clamp(150), 100);
222
- assert.strictEqual(clamp(-10), 0);
232
+ assert(clamp(150) === 100);
233
+ assert(clamp(-10) === 0);
223
234
 
224
235
  // Rounding utilities
225
236
  const round2 = Num.round(2);
226
237
 
227
- assert.strictEqual(round2(3.14159), 3.14);
228
- assert.strictEqual(Num.roundAt(3.14159, 3), 3.142);
229
- assert.strictEqual(Num.roundToInt(3.7), 4);
238
+ assert(round2(3.14159) === 3.14);
239
+ assert(Num.roundAt(3.14159, 3) === 3.142);
240
+ assert(Num.roundToInt(3.7) === 4);
230
241
 
231
242
  // Type guards
232
243
  const value = 5; // example value
233
244
  if (Num.isNonZero(value)) {
234
245
  // value is guaranteed to be non-zero
235
246
  const result = Num.div(10, value); // Safe division
236
- assert.strictEqual(result, 2);
247
+ assert(result === 2);
237
248
  }
238
249
  ```
239
250
 
@@ -261,10 +272,10 @@ const unsigned = asUint(42); // Uint - non-negative integer
261
272
  const finite = asFiniteNumber(3.14); // FiniteNumber - finite floating-point
262
273
  const safeInt = asSafeInt(42); // SafeInt - integer in safe range
263
274
 
264
- assert.strictEqual(integer, 42);
265
- assert.strictEqual(unsigned, 42);
266
- assert.strictEqual(finite, 3.14);
267
- assert.strictEqual(safeInt, 42);
275
+ assert(integer === 42);
276
+ assert(unsigned === 42);
277
+ assert(finite === 3.14);
278
+ assert(safeInt === 42);
268
279
 
269
280
  // This line would cause a runtime error:
270
281
  assert.throw(() => {
@@ -274,29 +285,29 @@ assert.throw(() => {
274
285
  // Range-constrained types (16-bit, 32-bit)
275
286
  const int16 = asInt16(1000); // Int16: [-32768, 32767]
276
287
  const uint32 = asUint32(3000000000); // Uint32: [0, 4294967295]
277
- assert.strictEqual(int16, 1000);
278
- assert.strictEqual(uint32, 3000000000);
288
+ assert(int16 === 1000);
289
+ assert(uint32 === 3000000000);
279
290
 
280
291
  // Non-zero and positive variants
281
292
  const nonZeroInt = asNonZeroInt(5); // NonZeroInt - excludes zero
282
293
  const positiveInt = asPositiveInt(10); // PositiveInt - excludes zero and negatives
283
- assert.strictEqual(nonZeroInt, 5);
284
- assert.strictEqual(positiveInt, 10);
294
+ assert(nonZeroInt === 5);
295
+ assert(positiveInt === 10);
285
296
 
286
297
  // Type-safe arithmetic with automatic clamping
287
298
  const sum = Int16.add(int16, asInt16(2000)); // Int16 (3000)
288
299
  const clamped = Int16.clamp(100000); // Int16 (32767 - clamped to MAX_VALUE)
289
- assert.strictEqual(sum, 3000);
290
- assert.strictEqual(clamped, 32767);
300
+ assert(sum === 3000);
301
+ assert(clamped === 32767);
291
302
 
292
303
  // Safe division with non-zero types
293
304
  const ratio = NonZeroInt.div(asNonZeroInt(10), nonZeroInt); // No division by zero risk
294
- assert.strictEqual(ratio, 2);
305
+ assert(ratio === 2);
295
306
 
296
307
  // Random generation within type constraints
297
308
  const randomInt16 = Int16.random(); // Int16 (random value in valid range)
298
- assert.strictEqual(-32768 <= randomInt16, true);
299
- assert.strictEqual(randomInt16 <= 32767, true);
309
+ assert(-32768 <= randomInt16);
310
+ assert(randomInt16 <= 32767);
300
311
  ```
301
312
 
302
313
  ### 4. Array Utilities with `Arr`
@@ -311,13 +322,13 @@ const numbers: readonly number[] = [1, 2, 3, 4, 5, 2, 3];
311
322
  // Reduction
312
323
  const sum = Arr.sum(numbers);
313
324
 
314
- assert.strictEqual(sum, 20);
325
+ assert(sum === 20);
315
326
 
316
327
  // Type-safe length checking
317
328
  if (Arr.isArrayAtLeastLength(numbers, 2)) {
318
329
  // numbers is now guaranteed to have at least 2 elements
319
330
  expectType<typeof numbers, readonly [number, number, ...number[]]>('=');
320
- assert.strictEqual(numbers[1], 2); // Safe access to index 1
331
+ assert(numbers[1] === 2); // Safe access to index 1
321
332
  }
322
333
 
323
334
  // Take first n elements
@@ -350,7 +361,7 @@ assert.deepStrictEqual(
350
361
  Optional.some({ name: 'Charlie', age: 35 } as const),
351
362
  );
352
363
  if (Optional.isSome(oldestPerson)) {
353
- assert.strictEqual(oldestPerson.value.name, 'Charlie');
364
+ assert(oldestPerson.value.name === 'Charlie');
354
365
  }
355
366
  ```
356
367
 
@@ -367,10 +378,10 @@ const mapWithOne = originalMap.set('one', 1);
367
378
  const mapWithTwo = mapWithOne.set('two', 2);
368
379
 
369
380
  // Original map is unchanged
370
- assert.strictEqual(originalMap.size, 0);
381
+ assert(originalMap.size === 0);
371
382
  assert.deepStrictEqual(mapWithTwo.get('one'), Optional.some(1));
372
383
 
373
- assert.strictEqual(mapWithTwo.has('three'), false);
384
+ assert(!mapWithTwo.has('three'));
374
385
 
375
386
  // Using pipe for fluent updates
376
387
  const sequence = Arr.seq(10); // [0, 1, 2, ..., 9]
@@ -380,7 +391,7 @@ const pairs = sequence.map(
380
391
  const skipped = Arr.skip(pairs, 1); // [[1, "1"], ..., [9, "9"]]
381
392
  const idMap = IMap.create<number, string>(skipped);
382
393
 
383
- assert.strictEqual(idMap.size, 9);
394
+ assert(idMap.size === 9);
384
395
 
385
396
  // Efficient batch updates with withMutations
386
397
  const idMapUpdated = idMap.withMutations([
@@ -389,15 +400,15 @@ const idMapUpdated = idMap.withMutations([
389
400
  { type: 'delete', key: 4 },
390
401
  ]);
391
402
 
392
- assert.strictEqual(idMapUpdated.size, 9);
403
+ assert(idMapUpdated.size === 9);
393
404
 
394
405
  // ISet usage
395
406
  const originalSet = ISet.create<number>([]);
396
407
  const setWithItems = originalSet.add(1).add(2).add(1); // Duplicate ignored
397
408
 
398
- assert.strictEqual(originalSet.size, 0); // (unchanged)
399
- assert.strictEqual(setWithItems.has(1), true);
400
- assert.strictEqual(setWithItems.size, 2);
409
+ assert(originalSet.size === 0); // (unchanged)
410
+ assert(setWithItems.has(1));
411
+ assert(setWithItems.size === 2);
401
412
  ```
402
413
 
403
414
  ### 6. Type Guards
@@ -430,9 +441,9 @@ if (isNonNullObject(value)) {
430
441
  }
431
442
 
432
443
  // Example usage
433
- assert.strictEqual(processData({ name: 'Alice' }), 'Hello, Alice!');
434
- assert.strictEqual(processData({ age: 30 }), undefined);
435
- assert.strictEqual(processData('not an object'), undefined);
444
+ assert(processData({ name: 'Alice' }) === 'Hello, Alice!');
445
+ assert(processData({ age: 30 }) === undefined);
446
+ assert(processData('not an object') === undefined);
436
447
  ```
437
448
 
438
449
  ### 7. Iteration with `range`
@@ -532,7 +543,8 @@ assert.deepStrictEqual(updatedState.items, ['newItem1', 'newItem2']);
532
543
 
533
544
  **Important Notes:**
534
545
 
535
- - This library **only supports ESM (ES Modules)**. CommonJS is not supported.
546
+ - This library **only supports ESM (ES Modules)** and is designed for native ESM environments. CommonJS is not supported.
547
+ - The library uses `.mts` file extensions and proper ESM exports, making it compatible with modern Node.js ESM resolution and bundlers that support native ESM.
536
548
  - This library uses advanced TypeScript features, including branded types for enhanced type safety. Some functions require specific branded types as parameters (such as `Uint32` in `newArray`). The examples above use the small literal numeric values specifically allowed in each function for brevity, but in actual use you should use the provided type conversion functions (such as `asUint32`) or cast to the appropriate branded type, for example `as Uint32`.
537
549
 
538
550
  ## Removing `expectType` in Production