@nlozgachev/pipelined 0.47.0 → 0.48.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.
@@ -1,5 +1,5 @@
1
- import { A as Awaitable, T as Thenable } from './InternalTypes-Mssktd7z.js';
2
- import { Duration } from './types.js';
1
+ import { A as Awaitable, T as Thenable } from './InternalTypes-LdhLQx3N.js';
2
+ import { D as Duration } from './Duration-B8joKzro.js';
3
3
 
4
4
  /**
5
5
  * Composes functions from right to left, returning a new function.
@@ -156,6 +156,8 @@ declare function async$1<A, B, C, D, E, F, G, H, I, J, K>(ab: (a: A) => Awaitabl
156
156
  *
157
157
  * @example
158
158
  * ```ts
159
+ * type User = { name: string };
160
+ *
159
161
  * // Create a reusable transformation
160
162
  * const processUser = flow(
161
163
  * (user: User) => user.name,
@@ -228,22 +230,73 @@ declare namespace flow {
228
230
  interface flow {
229
231
  /**
230
232
  * Executes a function on the piped value if a predicate is met, otherwise returns the value unchanged.
233
+ *
234
+ * @example
235
+ * ```ts
236
+ * const doubleIfEven = flow.when(
237
+ * (n: number) => n % 2 === 0,
238
+ * n => n * 2
239
+ * );
240
+ * doubleIfEven(4); // 8
241
+ * doubleIfEven(5); // 5
242
+ * ```
231
243
  */
232
244
  readonly when: <A>(predicate: (a: A) => boolean, onTrue: (a: A) => A) => (a: A) => A;
233
245
  /**
234
246
  * Executes a function on the piped value if a predicate is NOT met, otherwise returns the value unchanged.
247
+ *
248
+ * @example
249
+ * ```ts
250
+ * const doubleIfOdd = flow.unless(
251
+ * (n: number) => n % 2 === 0,
252
+ * n => n * 2
253
+ * );
254
+ * doubleIfOdd(5); // 10
255
+ * doubleIfOdd(4); // 4
256
+ * ```
235
257
  */
236
258
  readonly unless: <A>(predicate: (a: A) => boolean, onFalse: (a: A) => A) => (a: A) => A;
237
259
  /**
238
260
  * Executes one of two functions based on a predicate, acting as a functional if-else/ternary helper.
261
+ *
262
+ * @example
263
+ * ```ts
264
+ * const formatNumber = flow.either(
265
+ * (n: number) => n >= 0,
266
+ * n => `+${n}`,
267
+ * n => `${n}`
268
+ * );
269
+ * formatNumber(5); // "+5"
270
+ * formatNumber(-3); // "-3"
271
+ * ```
239
272
  */
240
273
  readonly either: <A, B>(predicate: (a: A) => boolean, onTrue: (a: A) => B, onFalse: (a: A) => B) => (a: A) => B;
241
274
  /**
242
275
  * Creates a pipeline step that wraps a throwing function in a try/catch, returning a fallback value if an error occurs.
276
+ *
277
+ * @example
278
+ * ```ts
279
+ * const safeParse = flow.try(
280
+ * (s: string) => JSON.parse(s),
281
+ * (_err, _s) => null
282
+ * );
283
+ * safeParse('{"a":1}'); // { a: 1 }
284
+ * safeParse('invalid'); // null
285
+ * ```
243
286
  */
244
287
  readonly try: <A, B, C>(f: (a: A) => B, onError: (error: unknown, value: A) => C) => (a: A) => B | C;
245
288
  /**
246
289
  * Builds an object by applying a record of field-level transformer functions to the piped input.
290
+ *
291
+ * @example
292
+ * ```ts
293
+ * type User = { name: string; age: number };
294
+ * const summarizeUser = flow.struct<User, { name: string; isAdult: boolean }>({
295
+ * name: u => u.name,
296
+ * isAdult: u => u.age >= 18,
297
+ * });
298
+ * summarizeUser({ name: "Alice", age: 25 }); // { name: "Alice", isAdult: true }
299
+ * ```
247
300
  */
248
301
  readonly struct: <A, R extends Record<string, unknown>>(fields: {
249
302
  [K in keyof R]: (a: A) => R[K];
@@ -251,10 +304,30 @@ interface flow {
251
304
  /**
252
305
  * Pipes a value through a sequence of operations, short-circuiting and propagating
253
306
  * null or undefined immediately if any intermediate step evaluates to nil.
307
+ *
308
+ * @example
309
+ * ```ts
310
+ * const getCityLength = flow.safe(
311
+ * (user: { address?: { city?: string } }) => user.address,
312
+ * address => address.city,
313
+ * city => city.length
314
+ * );
315
+ * getCityLength({ address: { city: "Paris" } }); // 5
316
+ * getCityLength({}); // undefined
317
+ * ```
254
318
  */
255
319
  readonly safe: typeof safe$1;
256
320
  /**
257
321
  * Pipes a value through a sequence of operations, supporting asynchronous transitions at any step.
322
+ *
323
+ * @example
324
+ * ```ts
325
+ * const processId = flow.async(
326
+ * (id: number) => Promise.resolve(`user-${id}`),
327
+ * name => name.toUpperCase()
328
+ * );
329
+ * await processId(42); // "USER-42"
330
+ * ```
258
331
  */
259
332
  readonly async: typeof async$1;
260
333
  }
@@ -280,15 +353,50 @@ declare const identity: <A>(a: A) => A;
280
353
  * ```
281
354
  */
282
355
  declare const constant: <A>(a: A) => () => A;
283
- /** Always returns `true`. */
356
+ /**
357
+ * Always returns `true`.
358
+ *
359
+ * @example
360
+ * ```ts
361
+ * constTrue(); // true
362
+ * ```
363
+ */
284
364
  declare const constTrue: () => true;
285
- /** Always returns `false`. */
365
+ /**
366
+ * Always returns `false`.
367
+ *
368
+ * @example
369
+ * ```ts
370
+ * constFalse(); // false
371
+ * ```
372
+ */
286
373
  declare const constFalse: () => false;
287
- /** Always returns `null`. */
374
+ /**
375
+ * Always returns `null`.
376
+ *
377
+ * @example
378
+ * ```ts
379
+ * constNull(); // null
380
+ * ```
381
+ */
288
382
  declare const constNull: () => null;
289
- /** Always returns `undefined`. */
383
+ /**
384
+ * Always returns `undefined`.
385
+ *
386
+ * @example
387
+ * ```ts
388
+ * constUndefined(); // undefined
389
+ * ```
390
+ */
290
391
  declare const constUndefined: () => undefined;
291
- /** Always returns `void`. */
392
+ /**
393
+ * Always returns `void`.
394
+ *
395
+ * @example
396
+ * ```ts
397
+ * constVoid(); // undefined
398
+ * ```
399
+ */
292
400
  declare const constVoid: () => void;
293
401
  /**
294
402
  * Combines two predicates with logical AND.
@@ -343,11 +451,33 @@ declare const once: <A>(f: () => A) => () => A;
343
451
  * const getName = flow(
344
452
  * (u: { name?: string | null }) => u.name,
345
453
  * defaultTo("Guest"),
346
- * name => name.toUpperCase()
454
+ * (name: string) => name.toUpperCase()
347
455
  * ); // returns string
348
456
  * ```
349
457
  */
350
458
  declare const defaultTo: <B>(fallback: B) => <A>(a: A) => NonNullable<A> | B;
459
+ /**
460
+ * Converts a function taking multiple arguments into a function taking a single tuple argument.
461
+ *
462
+ * @example
463
+ * ```ts
464
+ * const add = (a: number, b: number) => a + b;
465
+ * const addTuple = tuple(add);
466
+ * addTuple([2, 3]); // 5
467
+ * ```
468
+ */
469
+ declare const tuple: <Args extends readonly unknown[], R>(f: (...args: Args) => R) => (args: Args) => R;
470
+ /**
471
+ * Converts a function taking a single tuple argument into a function taking multiple arguments.
472
+ *
473
+ * @example
474
+ * ```ts
475
+ * const addTuple = ([a, b]: readonly [number, number]) => a + b;
476
+ * const add = untuple(addTuple);
477
+ * add(2, 3); // 5
478
+ * ```
479
+ */
480
+ declare const untuple: <Args extends readonly unknown[], R>(f: (args: Args) => R) => (...args: Args) => R;
351
481
 
352
482
  /**
353
483
  * Applies an input to an array of functions and collects the results into a tuple.
@@ -389,11 +519,13 @@ declare function juxt<A, B>(fns: ReadonlyArray<(a: A) => B>): (a: A) => B[];
389
519
  * // With custom key function for objects
390
520
  * const fetchUser = memoize(
391
521
  * (opts: { id: string }) => fetch(`/users/${opts.id}`),
392
- * opts => opts.id
522
+ * { key: (opts) => opts.id }
393
523
  * );
394
524
  * ```
395
525
  */
396
- declare const memoize: <A, B>(f: (a: A) => B, keyFn?: (a: A) => unknown) => (a: A) => B;
526
+ declare const memoize: <A, B>(f: (a: A) => B, options?: {
527
+ readonly key?: (a: A) => unknown;
528
+ }) => (a: A) => B;
397
529
  /**
398
530
  * Creates a memoized version of a function using WeakMap.
399
531
  * Only works with object arguments, but allows garbage collection
@@ -401,6 +533,9 @@ declare const memoize: <A, B>(f: (a: A) => B, keyFn?: (a: A) => unknown) => (a:
401
533
  *
402
534
  * @example
403
535
  * ```ts
536
+ * type User = { id: number; name: string };
537
+ * const expensiveOperation = (u: User) => u.name.toUpperCase();
538
+ *
404
539
  * const processUser = memoizeWeak((user: User) => {
405
540
  * return expensiveOperation(user);
406
541
  * });
@@ -430,10 +565,12 @@ declare const memoizeWeak: <A extends object, B>(f: (a: A) => B) => (a: A) => B;
430
565
  * numbers.filter(not(isEven)); // [1, 3, 5]
431
566
  *
432
567
  * // In pipelines
568
+ * const users = [{ name: "Alice", isAdmin: false }, { name: "Bob", isAdmin: true }];
569
+ * const isAdmin = (u: { name: string; isAdmin: boolean }) => u.isAdmin;
433
570
  * pipe(
434
571
  * users,
435
- * Array.filter(not(isAdmin)),
436
- * Array.map(u => u.name)
572
+ * Arr.filter(not(isAdmin)),
573
+ * Arr.map((u: { name: string; isAdmin: boolean }) => u.name)
437
574
  * );
438
575
  * ```
439
576
  */
@@ -504,7 +641,7 @@ declare function async<A, B, C, D, E, F, G, H, I, J, K>(a: Awaitable<A>, ab: (a:
504
641
  *
505
642
  * // Error handling with Result
506
643
  * const parsed = pipe(
507
- * Result.tryCatch(() => JSON.parse('{"value": 42}'), () => "Invalid JSON"),
644
+ * Result.tryCatch(() => JSON.parse('{"value": 42}'), { onError: () => "Invalid JSON" }),
508
645
  * Result.map((data: { value: number }) => data.value),
509
646
  * Result.getOrElse(() => null)
510
647
  * ); // 42
@@ -560,22 +697,65 @@ declare namespace pipe {
560
697
  interface pipe {
561
698
  /**
562
699
  * Executes a function on the piped value if a predicate is met, otherwise returns the value unchanged.
700
+ *
701
+ * @example
702
+ * ```ts
703
+ * pipe(
704
+ * 4,
705
+ * pipe.when(n => n % 2 === 0, n => n * 2)
706
+ * ); // 8
707
+ * ```
563
708
  */
564
709
  readonly when: <A>(predicate: (a: A) => boolean, onTrue: (a: A) => A) => (a: A) => A;
565
710
  /**
566
711
  * Executes a function on the piped value if a predicate is NOT met, otherwise returns the value unchanged.
712
+ *
713
+ * @example
714
+ * ```ts
715
+ * pipe(
716
+ * 5,
717
+ * pipe.unless(n => n % 2 === 0, n => n * 2)
718
+ * ); // 10
719
+ * ```
567
720
  */
568
721
  readonly unless: <A>(predicate: (a: A) => boolean, onFalse: (a: A) => A) => (a: A) => A;
569
722
  /**
570
723
  * Executes one of two functions based on a predicate, acting as a functional if-else/ternary helper.
724
+ *
725
+ * @example
726
+ * ```ts
727
+ * pipe(
728
+ * 5,
729
+ * pipe.either(n => n >= 0, n => `+${n}`, n => `${n}`)
730
+ * ); // "+5"
731
+ * ```
571
732
  */
572
733
  readonly either: <A, B>(predicate: (a: A) => boolean, onTrue: (a: A) => B, onFalse: (a: A) => B) => (a: A) => B;
573
734
  /**
574
735
  * Creates a pipeline step that wraps a throwing function in a try/catch, returning a fallback value if an error occurs.
736
+ *
737
+ * @example
738
+ * ```ts
739
+ * pipe(
740
+ * '{"a":1}',
741
+ * pipe.try(s => JSON.parse(s), () => null)
742
+ * ); // { a: 1 }
743
+ * ```
575
744
  */
576
745
  readonly try: <A, B, C>(f: (a: A) => B, onError: (error: unknown, value: A) => C) => (a: A) => B | C;
577
746
  /**
578
747
  * Builds an object by applying a record of field-level transformer functions to the piped input.
748
+ *
749
+ * @example
750
+ * ```ts
751
+ * pipe(
752
+ * { name: "Alice", age: 25 },
753
+ * pipe.struct({
754
+ * name: u => u.name,
755
+ * isAdult: u => u.age >= 18
756
+ * })
757
+ * ); // { name: "Alice", isAdult: true }
758
+ * ```
579
759
  */
580
760
  readonly struct: <A, R extends Record<string, unknown>>(fields: {
581
761
  [K in keyof R]: (a: A) => R[K];
@@ -583,10 +763,29 @@ interface pipe {
583
763
  /**
584
764
  * Pipes a value through a sequence of operations, short-circuiting and propagating
585
765
  * null or undefined immediately if any intermediate step evaluates to nil.
766
+ *
767
+ * @example
768
+ * ```ts
769
+ * pipe.safe(
770
+ * { address: { city: "Paris" } },
771
+ * user => user.address,
772
+ * address => address.city,
773
+ * city => city.length
774
+ * ); // 5
775
+ * ```
586
776
  */
587
777
  readonly safe: typeof safe;
588
778
  /**
589
779
  * Pipes a value through a sequence of operations, supporting asynchronous transitions at any step.
780
+ *
781
+ * @example
782
+ * ```ts
783
+ * await pipe.async(
784
+ * 42,
785
+ * n => Promise.resolve(`user-${n}`),
786
+ * name => name.toUpperCase()
787
+ * ); // "USER-42"
788
+ * ```
590
789
  */
591
790
  readonly async: typeof async;
592
791
  }
@@ -603,7 +802,7 @@ interface pipe {
603
802
  * tap(x => console.log("Before map:", x)),
604
803
  * Maybe.map(n => n * 2),
605
804
  * tap(x => console.log("After map:", x)),
606
- * Maybe.getOrElse(0)
805
+ * Maybe.getOrElse(() => 0)
607
806
  * );
608
807
  * // logs: "Before map: { kind: 'Some', value: 5 }"
609
808
  * // logs: "After map: { kind: 'Some', value: 10 }"
@@ -713,6 +912,10 @@ declare namespace tap {
713
912
  *
714
913
  * @example
715
914
  * ```ts
915
+ * const user = { id: 1 };
916
+ * const saveToDatabase = async (u: typeof user) => {};
917
+ * const logError = (err: unknown) => console.error(err);
918
+ *
716
919
  * pipe(
717
920
  * user,
718
921
  * tap.async(async (u) => {
@@ -729,6 +932,11 @@ declare namespace tap {
729
932
  *
730
933
  * @example
731
934
  * ```ts
935
+ * const data = [1, 2, 3];
936
+ * const processData = (d: typeof data) => d.map(n => n * 2);
937
+ * const fetchData = async (d: typeof data) => d.length;
938
+ * const metrics = { histogram: (name: string, ms: number) => {} };
939
+ *
732
940
  * // Time a synchronous computation
733
941
  * pipe(
734
942
  * data,
@@ -760,15 +968,15 @@ declare namespace tap {
760
968
  * uncurry(nested)(); // 42
761
969
  *
762
970
  * // Original curried function
763
- * Maybe.map(n => n * 2)(Maybe.make.some(5)); // Some(10)
971
+ * Maybe.map((n: number) => n * 2)(Maybe.make.some(5)); // Some(10)
764
972
  *
765
973
  * // Uncurried - all arguments at once
766
974
  * const mapUncurried = uncurry(Maybe.map);
767
- * mapUncurried(n => n * 2, Maybe.make.some(5)); // Some(10)
975
+ * mapUncurried((n: number) => n * 2, Maybe.make.some(5)); // Some(10)
768
976
  *
769
977
  * // Combined with flip for data-first uncurried
770
978
  * const mapDataFirst = uncurry(flip(Maybe.map));
771
- * mapDataFirst(Maybe.make.some(5), n => n * 2); // Some(10)
979
+ * mapDataFirst(Maybe.make.some(5), (n: number) => n * 2); // Some(10)
772
980
  * ```
773
981
  *
774
982
  * @see {@link flip} for reversing curried argument order
@@ -801,4 +1009,4 @@ declare const uncurry3: <A, B, C, D>(f: (a: A) => (b: B) => (c: C) => D) => (a:
801
1009
  */
802
1010
  declare const uncurry4: <A, B, C, D, E>(f: (a: A) => (b: B) => (c: C) => (d: D) => E) => (a: A, b: B, c: C, d: D) => E;
803
1011
 
804
- export { and, compose, constFalse, constNull, constTrue, constUndefined, constVoid, constant, converge, curry, curry3, curry4, defaultTo, flip, flow, identity, juxt, memoize, memoizeWeak, not, on, once, or, pipe, tap, uncurry, uncurry3, uncurry4 };
1012
+ export { and, compose, constFalse, constNull, constTrue, constUndefined, constVoid, constant, converge, curry, curry3, curry4, defaultTo, flip, flow, identity, juxt, memoize, memoizeWeak, not, on, once, or, pipe, tap, tuple, uncurry, uncurry3, uncurry4, untuple };
@@ -45,9 +45,11 @@ __export(Composition_exports, {
45
45
  or: () => or,
46
46
  pipe: () => pipe,
47
47
  tap: () => tap,
48
+ tuple: () => tuple,
48
49
  uncurry: () => uncurry,
49
50
  uncurry3: () => uncurry3,
50
- uncurry4: () => uncurry4
51
+ uncurry4: () => uncurry4,
52
+ untuple: () => untuple
51
53
  });
52
54
  module.exports = __toCommonJS(Composition_exports);
53
55
 
@@ -249,6 +251,8 @@ var once = (f) => {
249
251
  };
250
252
  };
251
253
  var defaultTo = (fallback) => (a) => a === null || a === void 0 ? fallback : a;
254
+ var tuple = (f) => (args) => f(...args);
255
+ var untuple = (f) => (...args) => f(args);
252
256
 
253
257
  // src/Composition/juxt.ts
254
258
  function juxt(fns) {
@@ -256,8 +260,9 @@ function juxt(fns) {
256
260
  }
257
261
 
258
262
  // src/Composition/memoize.ts
259
- var memoize = (f, keyFn = (a) => a) => {
263
+ var memoize = (f, options) => {
260
264
  const cache = /* @__PURE__ */ new Map();
265
+ const keyFn = options?.key ?? ((a) => a);
261
266
  return (a) => {
262
267
  const key = keyFn(a);
263
268
  if (cache.has(key)) {
@@ -520,7 +525,9 @@ var uncurry4 = (f) => (a, b, c, d) => f(a)(b)(c)(d);
520
525
  or,
521
526
  pipe,
522
527
  tap,
528
+ tuple,
523
529
  uncurry,
524
530
  uncurry3,
525
- uncurry4
531
+ uncurry4,
532
+ untuple
526
533
  });
@@ -24,11 +24,13 @@ import {
24
24
  or,
25
25
  pipe,
26
26
  tap,
27
+ tuple,
27
28
  uncurry,
28
29
  uncurry3,
29
- uncurry4
30
- } from "./chunk-KOYYDQH4.mjs";
31
- import "./chunk-XTVF5R6R.mjs";
30
+ uncurry4,
31
+ untuple
32
+ } from "./chunk-5OFVS5UZ.mjs";
33
+ import "./chunk-DENXUTKL.mjs";
32
34
  export {
33
35
  and,
34
36
  compose,
@@ -55,7 +57,9 @@ export {
55
57
  or,
56
58
  pipe,
57
59
  tap,
60
+ tuple,
58
61
  uncurry,
59
62
  uncurry3,
60
- uncurry4
63
+ uncurry4,
64
+ untuple
61
65
  };