@nlozgachev/pipelined 0.6.4

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 (144) hide show
  1. package/README.md +85 -0
  2. package/esm/mod.js +3 -0
  3. package/esm/package.json +3 -0
  4. package/esm/src/Composition/compose.js +3 -0
  5. package/esm/src/Composition/converge.js +3 -0
  6. package/esm/src/Composition/curry.js +42 -0
  7. package/esm/src/Composition/flip.js +20 -0
  8. package/esm/src/Composition/flow.js +8 -0
  9. package/esm/src/Composition/fn.js +85 -0
  10. package/esm/src/Composition/index.js +13 -0
  11. package/esm/src/Composition/juxt.js +3 -0
  12. package/esm/src/Composition/memoize.js +66 -0
  13. package/esm/src/Composition/not.js +25 -0
  14. package/esm/src/Composition/on.js +12 -0
  15. package/esm/src/Composition/pipe.js +3 -0
  16. package/esm/src/Composition/tap.js +33 -0
  17. package/esm/src/Composition/uncurry.js +32 -0
  18. package/esm/src/Core/Arr.js +463 -0
  19. package/esm/src/Core/Deferred.js +26 -0
  20. package/esm/src/Core/InternalTypes.js +1 -0
  21. package/esm/src/Core/Lens.js +98 -0
  22. package/esm/src/Core/Option.js +186 -0
  23. package/esm/src/Core/Optional.js +160 -0
  24. package/esm/src/Core/Reader.js +134 -0
  25. package/esm/src/Core/Rec.js +167 -0
  26. package/esm/src/Core/RemoteData.js +206 -0
  27. package/esm/src/Core/Result.js +164 -0
  28. package/esm/src/Core/Task.js +187 -0
  29. package/esm/src/Core/TaskOption.js +105 -0
  30. package/esm/src/Core/TaskResult.js +125 -0
  31. package/esm/src/Core/TaskValidation.js +101 -0
  32. package/esm/src/Core/These.js +241 -0
  33. package/esm/src/Core/Validation.js +214 -0
  34. package/esm/src/Core/index.js +15 -0
  35. package/esm/src/Types/Brand.js +28 -0
  36. package/esm/src/Types/NonEmptyList.js +14 -0
  37. package/esm/src/Types/index.js +2 -0
  38. package/package.json +61 -0
  39. package/script/mod.js +19 -0
  40. package/script/package.json +3 -0
  41. package/script/src/Composition/compose.js +6 -0
  42. package/script/src/Composition/converge.js +6 -0
  43. package/script/src/Composition/curry.js +48 -0
  44. package/script/src/Composition/flip.js +24 -0
  45. package/script/src/Composition/flow.js +11 -0
  46. package/script/src/Composition/fn.js +98 -0
  47. package/script/src/Composition/index.js +29 -0
  48. package/script/src/Composition/juxt.js +6 -0
  49. package/script/src/Composition/memoize.js +71 -0
  50. package/script/src/Composition/not.js +29 -0
  51. package/script/src/Composition/on.js +16 -0
  52. package/script/src/Composition/pipe.js +6 -0
  53. package/script/src/Composition/tap.js +37 -0
  54. package/script/src/Composition/uncurry.js +38 -0
  55. package/script/src/Core/Arr.js +466 -0
  56. package/script/src/Core/Deferred.js +29 -0
  57. package/script/src/Core/InternalTypes.js +2 -0
  58. package/script/src/Core/Lens.js +101 -0
  59. package/script/src/Core/Option.js +189 -0
  60. package/script/src/Core/Optional.js +163 -0
  61. package/script/src/Core/Reader.js +137 -0
  62. package/script/src/Core/Rec.js +170 -0
  63. package/script/src/Core/RemoteData.js +209 -0
  64. package/script/src/Core/Result.js +167 -0
  65. package/script/src/Core/Task.js +190 -0
  66. package/script/src/Core/TaskOption.js +108 -0
  67. package/script/src/Core/TaskResult.js +128 -0
  68. package/script/src/Core/TaskValidation.js +104 -0
  69. package/script/src/Core/These.js +244 -0
  70. package/script/src/Core/Validation.js +217 -0
  71. package/script/src/Core/index.js +31 -0
  72. package/script/src/Types/Brand.js +31 -0
  73. package/script/src/Types/NonEmptyList.js +18 -0
  74. package/script/src/Types/index.js +18 -0
  75. package/types/mod.d.ts +4 -0
  76. package/types/mod.d.ts.map +1 -0
  77. package/types/src/Composition/compose.d.ts +33 -0
  78. package/types/src/Composition/compose.d.ts.map +1 -0
  79. package/types/src/Composition/converge.d.ts +21 -0
  80. package/types/src/Composition/converge.d.ts.map +1 -0
  81. package/types/src/Composition/curry.d.ts +43 -0
  82. package/types/src/Composition/curry.d.ts.map +1 -0
  83. package/types/src/Composition/flip.d.ts +21 -0
  84. package/types/src/Composition/flip.d.ts.map +1 -0
  85. package/types/src/Composition/flow.d.ts +56 -0
  86. package/types/src/Composition/flow.d.ts.map +1 -0
  87. package/types/src/Composition/fn.d.ts +76 -0
  88. package/types/src/Composition/fn.d.ts.map +1 -0
  89. package/types/src/Composition/index.d.ts +14 -0
  90. package/types/src/Composition/index.d.ts.map +1 -0
  91. package/types/src/Composition/juxt.d.ts +18 -0
  92. package/types/src/Composition/juxt.d.ts.map +1 -0
  93. package/types/src/Composition/memoize.d.ts +46 -0
  94. package/types/src/Composition/memoize.d.ts.map +1 -0
  95. package/types/src/Composition/not.d.ts +26 -0
  96. package/types/src/Composition/not.d.ts.map +1 -0
  97. package/types/src/Composition/on.d.ts +13 -0
  98. package/types/src/Composition/on.d.ts.map +1 -0
  99. package/types/src/Composition/pipe.d.ts +56 -0
  100. package/types/src/Composition/pipe.d.ts.map +1 -0
  101. package/types/src/Composition/tap.d.ts +31 -0
  102. package/types/src/Composition/tap.d.ts.map +1 -0
  103. package/types/src/Composition/uncurry.d.ts +54 -0
  104. package/types/src/Composition/uncurry.d.ts.map +1 -0
  105. package/types/src/Core/Arr.d.ts +355 -0
  106. package/types/src/Core/Arr.d.ts.map +1 -0
  107. package/types/src/Core/Deferred.d.ts +49 -0
  108. package/types/src/Core/Deferred.d.ts.map +1 -0
  109. package/types/src/Core/InternalTypes.d.ts +20 -0
  110. package/types/src/Core/InternalTypes.d.ts.map +1 -0
  111. package/types/src/Core/Lens.d.ts +118 -0
  112. package/types/src/Core/Lens.d.ts.map +1 -0
  113. package/types/src/Core/Option.d.ts +205 -0
  114. package/types/src/Core/Option.d.ts.map +1 -0
  115. package/types/src/Core/Optional.d.ts +158 -0
  116. package/types/src/Core/Optional.d.ts.map +1 -0
  117. package/types/src/Core/Reader.d.ts +156 -0
  118. package/types/src/Core/Reader.d.ts.map +1 -0
  119. package/types/src/Core/Rec.d.ts +121 -0
  120. package/types/src/Core/Rec.d.ts.map +1 -0
  121. package/types/src/Core/RemoteData.d.ts +192 -0
  122. package/types/src/Core/RemoteData.d.ts.map +1 -0
  123. package/types/src/Core/Result.d.ts +176 -0
  124. package/types/src/Core/Result.d.ts.map +1 -0
  125. package/types/src/Core/Task.d.ts +189 -0
  126. package/types/src/Core/Task.d.ts.map +1 -0
  127. package/types/src/Core/TaskOption.d.ts +120 -0
  128. package/types/src/Core/TaskOption.d.ts.map +1 -0
  129. package/types/src/Core/TaskResult.d.ts +117 -0
  130. package/types/src/Core/TaskResult.d.ts.map +1 -0
  131. package/types/src/Core/TaskValidation.d.ts +119 -0
  132. package/types/src/Core/TaskValidation.d.ts.map +1 -0
  133. package/types/src/Core/These.d.ts +221 -0
  134. package/types/src/Core/These.d.ts.map +1 -0
  135. package/types/src/Core/Validation.d.ts +213 -0
  136. package/types/src/Core/Validation.d.ts.map +1 -0
  137. package/types/src/Core/index.d.ts +16 -0
  138. package/types/src/Core/index.d.ts.map +1 -0
  139. package/types/src/Types/Brand.d.ts +52 -0
  140. package/types/src/Types/Brand.d.ts.map +1 -0
  141. package/types/src/Types/NonEmptyList.d.ts +29 -0
  142. package/types/src/Types/NonEmptyList.d.ts.map +1 -0
  143. package/types/src/Types/index.d.ts +3 -0
  144. package/types/src/Types/index.d.ts.map +1 -0
@@ -0,0 +1,28 @@
1
+ export var Brand;
2
+ (function (Brand) {
3
+ /**
4
+ * Returns a constructor that wraps a value of type T in brand K.
5
+ * The resulting function performs an unchecked cast — only use when the raw
6
+ * value is known to satisfy the brand's invariants.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * type PositiveNumber = Brand<"PositiveNumber", number>;
11
+ * const toPositiveNumber = Brand.wrap<"PositiveNumber", number>();
12
+ *
13
+ * const n: PositiveNumber = toPositiveNumber(42);
14
+ * ```
15
+ */
16
+ Brand.wrap = () => (value) => value;
17
+ /**
18
+ * Strips the brand and returns the underlying value.
19
+ * Since Brand<K, T> extends T this is rarely needed, but can improve readability.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const userId: UserId = toUserId("user-123");
24
+ * const raw: string = Brand.unwrap(userId); // "user-123"
25
+ * ```
26
+ */
27
+ Brand.unwrap = (branded) => branded;
28
+ })(Brand || (Brand = {}));
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Type guard that checks if an array is non-empty.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * const items: string[] = getItems();
7
+ *
8
+ * if (isNonEmptyList(items)) {
9
+ * // TypeScript knows items has at least one element
10
+ * const first = items[0]; // string, not string | undefined
11
+ * }
12
+ * ```
13
+ */
14
+ export const isNonEmptyList = (list) => list.length > 0;
@@ -0,0 +1,2 @@
1
+ export * from "./Brand.js";
2
+ export * from "./NonEmptyList.js";
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@nlozgachev/pipelined",
3
+ "version": "0.6.4",
4
+ "description": "Simple functional programming toolkit for TypeScript",
5
+ "keywords": [
6
+ "functional",
7
+ "fp",
8
+ "typescript",
9
+ "composition",
10
+ "pipe"
11
+ ],
12
+ "homepage": "https://pipelined.lozgachev.dev",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/nlozgachev/pipelined"
16
+ },
17
+ "license": "BSD-3-Clause",
18
+ "types": "./types/mod.d.ts",
19
+ "exports": {
20
+ "./composition": {
21
+ "import": {
22
+ "types": "./types/src/Composition/index.d.ts",
23
+ "default": "./esm/src/Composition/index.js"
24
+ },
25
+ "require": {
26
+ "types": "./types/src/Composition/index.d.ts",
27
+ "default": "./script/src/Composition/index.js"
28
+ }
29
+ },
30
+ "./core": {
31
+ "import": {
32
+ "types": "./types/src/Core/index.d.ts",
33
+ "default": "./esm/src/Core/index.js"
34
+ },
35
+ "require": {
36
+ "types": "./types/src/Core/index.d.ts",
37
+ "default": "./script/src/Core/index.js"
38
+ }
39
+ },
40
+ "./types": {
41
+ "import": {
42
+ "types": "./types/src/Types/index.d.ts",
43
+ "default": "./esm/src/Types/index.js"
44
+ },
45
+ "require": {
46
+ "types": "./types/src/Types/index.d.ts",
47
+ "default": "./script/src/Types/index.js"
48
+ }
49
+ }
50
+ },
51
+ "scripts": {},
52
+ "sideEffects": false,
53
+ "engines": {
54
+ "node": ">=22"
55
+ },
56
+ "files": [
57
+ "esm",
58
+ "script",
59
+ "types"
60
+ ]
61
+ }
package/script/mod.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./src/Composition/index.js"), exports);
18
+ __exportStar(require("./src/Core/index.js"), exports);
19
+ __exportStar(require("./src/Composition/index.js"), exports);
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compose = compose;
4
+ function compose(...fns) {
5
+ return (arg) => fns.reduceRight((acc, fn) => fn(acc), arg);
6
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.converge = converge;
4
+ function converge(f, transformers) {
5
+ return (a) => f(...transformers.map((t) => t(a)));
6
+ }
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.curry4 = exports.curry3 = exports.curry = void 0;
4
+ /**
5
+ * Converts a multi-argument function into a curried function.
6
+ * The inverse of `uncurry`.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * const add = (a: number, b: number) => a + b;
11
+ * const curriedAdd = curry(add);
12
+ * curriedAdd(1)(2); // 3
13
+ *
14
+ * // Partial application
15
+ * const addTen = curriedAdd(10);
16
+ * addTen(5); // 15
17
+ * ```
18
+ *
19
+ * @see {@link uncurry} for the inverse operation
20
+ * @see {@link curry3} for 3-argument functions
21
+ * @see {@link curry4} for 4-argument functions
22
+ */
23
+ const curry = (f) => (a) => (b) => f(a, b);
24
+ exports.curry = curry;
25
+ /**
26
+ * Converts a 3-argument function into a curried function.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * const add3 = (a: number, b: number, c: number) => a + b + c;
31
+ * const curriedAdd3 = curry3(add3);
32
+ * curriedAdd3(1)(2)(3); // 6
33
+ * ```
34
+ */
35
+ const curry3 = (f) => (a) => (b) => (c) => f(a, b, c);
36
+ exports.curry3 = curry3;
37
+ /**
38
+ * Converts a 4-argument function into a curried function.
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * const add4 = (a: number, b: number, c: number, d: number) => a + b + c + d;
43
+ * const curriedAdd4 = curry4(add4);
44
+ * curriedAdd4(1)(2)(3)(4); // 10
45
+ * ```
46
+ */
47
+ const curry4 = (f) => (a) => (b) => (c) => (d) => f(a, b, c, d);
48
+ exports.curry4 = curry4;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.flip = void 0;
4
+ /**
5
+ * Flips the order of arguments for a curried binary function.
6
+ * Converts a data-last function to data-first.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * // Original data-last (for pipe)
11
+ * pipe(
12
+ * Option.some(5),
13
+ * Option.map(n => n * 2)
14
+ * ); // Some(10)
15
+ *
16
+ * // Flipped to data-first
17
+ * const mapFirst = flip(Option.map);
18
+ * mapFirst(Option.some(5))(n => n * 2); // Some(10)
19
+ * ```
20
+ *
21
+ * @see {@link uncurry} for converting curried functions to multi-argument functions
22
+ */
23
+ const flip = (f) => (b) => (a) => f(a)(b);
24
+ exports.flip = flip;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.flow = flow;
4
+ function flow(...fns) {
5
+ return (...args) => {
6
+ if (fns.length === 0)
7
+ return args[0];
8
+ const [first, ...rest] = fns;
9
+ return rest.reduce((acc, fn) => fn(acc), first(...args));
10
+ };
11
+ }
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.once = exports.or = exports.and = exports.constVoid = exports.constUndefined = exports.constNull = exports.constFalse = exports.constTrue = exports.constant = exports.identity = void 0;
4
+ /**
5
+ * Returns the value unchanged. The identity function.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * identity(42); // 42
10
+ * pipe(Option.some(5), Option.fold(() => 0, identity)); // 5
11
+ * ```
12
+ */
13
+ const identity = (a) => a;
14
+ exports.identity = identity;
15
+ /**
16
+ * Creates a function that always returns the given value, ignoring its argument.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * const always42 = constant(42);
21
+ * always42(); // 42
22
+ * [1, 2, 3].map(constant("x")); // ["x", "x", "x"]
23
+ * ```
24
+ */
25
+ const constant = (a) => () => a;
26
+ exports.constant = constant;
27
+ /** Always returns `true`. */
28
+ const constTrue = () => true;
29
+ exports.constTrue = constTrue;
30
+ /** Always returns `false`. */
31
+ const constFalse = () => false;
32
+ exports.constFalse = constFalse;
33
+ /** Always returns `null`. */
34
+ const constNull = () => null;
35
+ exports.constNull = constNull;
36
+ /** Always returns `undefined`. */
37
+ const constUndefined = () => undefined;
38
+ exports.constUndefined = constUndefined;
39
+ /** Always returns `void`. */
40
+ const constVoid = () => { };
41
+ exports.constVoid = constVoid;
42
+ /**
43
+ * Combines two predicates with logical AND.
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * const isPositive = (n: number) => n > 0;
48
+ * const isEven = (n: number) => n % 2 === 0;
49
+ * const isPositiveEven = and(isPositive, isEven);
50
+ *
51
+ * isPositiveEven(4); // true
52
+ * isPositiveEven(-2); // false
53
+ * isPositiveEven(3); // false
54
+ * ```
55
+ */
56
+ const and = (p1, p2) => (...args) => p1(...args) && p2(...args);
57
+ exports.and = and;
58
+ /**
59
+ * Combines two predicates with logical OR.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * const isNegative = (n: number) => n < 0;
64
+ * const isZero = (n: number) => n === 0;
65
+ * const isNonPositive = or(isNegative, isZero);
66
+ *
67
+ * isNonPositive(-1); // true
68
+ * isNonPositive(0); // true
69
+ * isNonPositive(1); // false
70
+ * ```
71
+ */
72
+ const or = (p1, p2) => (...args) => p1(...args) || p2(...args);
73
+ exports.or = or;
74
+ /**
75
+ * Creates a function that executes at most once.
76
+ * Subsequent calls return the cached result from the first execution.
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * let count = 0;
81
+ * const initOnce = once(() => { count++; return "initialized"; });
82
+ *
83
+ * initOnce(); // "initialized", count === 1
84
+ * initOnce(); // "initialized", count === 1 (not called again)
85
+ * ```
86
+ */
87
+ const once = (f) => {
88
+ let called = false;
89
+ let result;
90
+ return () => {
91
+ if (!called) {
92
+ result = f();
93
+ called = true;
94
+ }
95
+ return result;
96
+ };
97
+ };
98
+ exports.once = once;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./compose.js"), exports);
18
+ __exportStar(require("./converge.js"), exports);
19
+ __exportStar(require("./curry.js"), exports);
20
+ __exportStar(require("./flip.js"), exports);
21
+ __exportStar(require("./fn.js"), exports);
22
+ __exportStar(require("./flow.js"), exports);
23
+ __exportStar(require("./juxt.js"), exports);
24
+ __exportStar(require("./memoize.js"), exports);
25
+ __exportStar(require("./not.js"), exports);
26
+ __exportStar(require("./on.js"), exports);
27
+ __exportStar(require("./pipe.js"), exports);
28
+ __exportStar(require("./tap.js"), exports);
29
+ __exportStar(require("./uncurry.js"), exports);
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.juxt = juxt;
4
+ function juxt(fns) {
5
+ return (a) => fns.map((f) => f(a));
6
+ }
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.memoizeWeak = exports.memoize = void 0;
4
+ /**
5
+ * Creates a memoized version of a function that caches results.
6
+ * Subsequent calls with the same argument return the cached result.
7
+ *
8
+ * By default, uses the argument directly as the cache key.
9
+ * For complex arguments, provide a custom `keyFn` to generate cache keys.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * // Basic usage
14
+ * const expensive = memoize((n: number) => {
15
+ * console.log("Computing...");
16
+ * return n * 2;
17
+ * });
18
+ *
19
+ * expensive(5); // logs "Computing...", returns 10
20
+ * expensive(5); // returns 10 (cached, no log)
21
+ * expensive(3); // logs "Computing...", returns 6
22
+ *
23
+ * // With custom key function for objects
24
+ * const fetchUser = memoize(
25
+ * (opts: { id: string }) => fetch(`/users/${opts.id}`),
26
+ * opts => opts.id
27
+ * );
28
+ * ```
29
+ */
30
+ const memoize = (f, keyFn = (a) => a) => {
31
+ const cache = new Map();
32
+ return (a) => {
33
+ const key = keyFn(a);
34
+ if (cache.has(key)) {
35
+ return cache.get(key);
36
+ }
37
+ const result = f(a);
38
+ cache.set(key, result);
39
+ return result;
40
+ };
41
+ };
42
+ exports.memoize = memoize;
43
+ /**
44
+ * Creates a memoized version of a function using WeakMap.
45
+ * Only works with object arguments, but allows garbage collection
46
+ * of cached values when keys are no longer referenced.
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * const processUser = memoizeWeak((user: User) => {
51
+ * return expensiveOperation(user);
52
+ * });
53
+ *
54
+ * const user = { id: 1, name: "Alice" };
55
+ * processUser(user); // computed
56
+ * processUser(user); // cached
57
+ * // When `user` is garbage collected, cached result is too
58
+ * ```
59
+ */
60
+ const memoizeWeak = (f) => {
61
+ const cache = new WeakMap();
62
+ return (a) => {
63
+ if (cache.has(a)) {
64
+ return cache.get(a);
65
+ }
66
+ const result = f(a);
67
+ cache.set(a, result);
68
+ return result;
69
+ };
70
+ };
71
+ exports.memoizeWeak = memoizeWeak;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.not = void 0;
4
+ /**
5
+ * Negates a predicate function.
6
+ * Returns a new predicate that returns true when the original returns false, and vice versa.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * const isEven = (n: number) => n % 2 === 0;
11
+ * const isOdd = not(isEven);
12
+ *
13
+ * isOdd(3); // true
14
+ * isOdd(4); // false
15
+ *
16
+ * // With array methods
17
+ * const numbers = [1, 2, 3, 4, 5];
18
+ * numbers.filter(not(isEven)); // [1, 3, 5]
19
+ *
20
+ * // In pipelines
21
+ * pipe(
22
+ * users,
23
+ * Array.filter(not(isAdmin)),
24
+ * Array.map(u => u.name)
25
+ * );
26
+ * ```
27
+ */
28
+ const not = (predicate) => (...args) => !predicate(...args);
29
+ exports.not = not;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.on = void 0;
4
+ /**
5
+ * Applies a projection to both arguments of a binary function before calling it.
6
+ * Most useful for building comparators and equality checks over projected values.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * const byLength = on((a: number, b: number) => a - b, (s: string) => s.length);
11
+ *
12
+ * ["banana", "fig", "apple"].sort(byLength); // ["fig", "apple", "banana"]
13
+ * ```
14
+ */
15
+ const on = (f, g) => (a, b) => f(g(a), g(b));
16
+ exports.on = on;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pipe = pipe;
4
+ function pipe(a, ...fns) {
5
+ return fns.reduce((acc, fn) => fn(acc), a);
6
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tap = void 0;
4
+ /**
5
+ * Executes a side effect function and returns the original value unchanged.
6
+ * Useful for logging, debugging, or other side effects within a pipeline.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * // Debugging a pipeline
11
+ * pipe(
12
+ * Option.some(5),
13
+ * tap(x => console.log("Before map:", x)),
14
+ * Option.map(n => n * 2),
15
+ * tap(x => console.log("After map:", x)),
16
+ * Option.getOrElse(0)
17
+ * );
18
+ * // logs: "Before map: { kind: 'Some', value: 5 }"
19
+ * // logs: "After map: { kind: 'Some', value: 10 }"
20
+ * // returns: 10
21
+ *
22
+ * // Collecting intermediate values
23
+ * const values: number[] = [];
24
+ * pipe(
25
+ * [1, 2, 3],
26
+ * arr => arr.map(n => n * 2),
27
+ * tap(arr => values.push(...arr))
28
+ * );
29
+ * ```
30
+ *
31
+ * @see {@link Option.tap} for Option-specific tap that only runs on Some
32
+ */
33
+ const tap = (f) => (a) => {
34
+ f(a);
35
+ return a;
36
+ };
37
+ exports.tap = tap;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.uncurry4 = exports.uncurry3 = void 0;
4
+ exports.uncurry = uncurry;
5
+ // deno-lint-ignore no-explicit-any
6
+ function uncurry(f) {
7
+ // f.length determines the outer arity; inner.length determines the inner arity.
8
+ // The typed overloads guarantee these are 0, 1, or 2 total args.
9
+ // deno-lint-ignore no-explicit-any
10
+ return (...args) => {
11
+ const inner = f(...args.slice(0, f.length));
12
+ return inner.length === 0 ? inner() : inner(...args.slice(f.length));
13
+ };
14
+ }
15
+ /**
16
+ * Converts a curried 3-argument function into a multi-argument function.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * const curriedAdd3 = (a: number) => (b: number) => (c: number) => a + b + c;
21
+ * const add3 = uncurry3(curriedAdd3);
22
+ * add3(1, 2, 3); // 6
23
+ * ```
24
+ */
25
+ const uncurry3 = (f) => (a, b, c) => f(a)(b)(c);
26
+ exports.uncurry3 = uncurry3;
27
+ /**
28
+ * Converts a curried 4-argument function into a multi-argument function.
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * const curriedAdd4 = (a: number) => (b: number) => (c: number) => (d: number) => a + b + c + d;
33
+ * const add4 = uncurry4(curriedAdd4);
34
+ * add4(1, 2, 3, 4); // 10
35
+ * ```
36
+ */
37
+ const uncurry4 = (f) => (a, b, c, d) => f(a)(b)(c)(d);
38
+ exports.uncurry4 = uncurry4;