@nlozgachev/pipelined 0.10.0 → 0.12.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 (76) hide show
  1. package/README.md +9 -3
  2. package/esm/src/Core/Option.js +2 -1
  3. package/esm/src/Core/RemoteData.js +5 -5
  4. package/esm/src/Core/TaskValidation.js +1 -3
  5. package/esm/src/Core/Tuple.js +112 -0
  6. package/esm/src/Core/index.js +4 -5
  7. package/esm/src/{Core → Utils}/Arr.js +95 -23
  8. package/esm/src/Utils/Dict.js +421 -0
  9. package/esm/src/Utils/Num.js +124 -0
  10. package/esm/src/{Core → Utils}/Rec.js +85 -11
  11. package/esm/src/Utils/Str.js +134 -0
  12. package/esm/src/Utils/Uniq.js +265 -0
  13. package/esm/src/Utils/index.js +6 -0
  14. package/package.json +11 -1
  15. package/script/src/Core/Option.js +2 -1
  16. package/script/src/Core/RemoteData.js +5 -5
  17. package/script/src/Core/TaskValidation.js +1 -3
  18. package/script/src/Core/Tuple.js +115 -0
  19. package/script/src/Core/index.js +4 -5
  20. package/script/src/{Core → Utils}/Arr.js +95 -23
  21. package/script/src/Utils/Dict.js +424 -0
  22. package/script/src/Utils/Num.js +127 -0
  23. package/script/src/{Core → Utils}/Rec.js +85 -11
  24. package/script/src/Utils/Str.js +137 -0
  25. package/script/src/Utils/Uniq.js +268 -0
  26. package/script/src/Utils/index.js +22 -0
  27. package/types/src/Composition/compose.d.ts.map +1 -1
  28. package/types/src/Composition/converge.d.ts.map +1 -1
  29. package/types/src/Composition/curry.d.ts.map +1 -1
  30. package/types/src/Composition/flow.d.ts.map +1 -1
  31. package/types/src/Composition/fn.d.ts.map +1 -1
  32. package/types/src/Composition/juxt.d.ts.map +1 -1
  33. package/types/src/Composition/memoize.d.ts.map +1 -1
  34. package/types/src/Composition/not.d.ts.map +1 -1
  35. package/types/src/Composition/on.d.ts.map +1 -1
  36. package/types/src/Composition/pipe.d.ts.map +1 -1
  37. package/types/src/Composition/uncurry.d.ts.map +1 -1
  38. package/types/src/Core/Deferred.d.ts.map +1 -1
  39. package/types/src/Core/Lens.d.ts.map +1 -1
  40. package/types/src/Core/Logged.d.ts.map +1 -1
  41. package/types/src/Core/Option.d.ts.map +1 -1
  42. package/types/src/Core/Optional.d.ts.map +1 -1
  43. package/types/src/Core/Predicate.d.ts.map +1 -1
  44. package/types/src/Core/Reader.d.ts.map +1 -1
  45. package/types/src/Core/Refinement.d.ts.map +1 -1
  46. package/types/src/Core/RemoteData.d.ts.map +1 -1
  47. package/types/src/Core/Result.d.ts.map +1 -1
  48. package/types/src/Core/State.d.ts.map +1 -1
  49. package/types/src/Core/Task.d.ts.map +1 -1
  50. package/types/src/Core/TaskOption.d.ts.map +1 -1
  51. package/types/src/Core/TaskResult.d.ts.map +1 -1
  52. package/types/src/Core/TaskValidation.d.ts.map +1 -1
  53. package/types/src/Core/These.d.ts.map +1 -1
  54. package/types/src/Core/Tuple.d.ts +129 -0
  55. package/types/src/Core/Tuple.d.ts.map +1 -0
  56. package/types/src/Core/Validation.d.ts.map +1 -1
  57. package/types/src/Core/index.d.ts +4 -5
  58. package/types/src/Core/index.d.ts.map +1 -1
  59. package/types/src/Types/Brand.d.ts.map +1 -1
  60. package/types/src/Types/NonEmptyList.d.ts.map +1 -1
  61. package/types/src/{Core → Utils}/Arr.d.ts +25 -3
  62. package/types/src/Utils/Arr.d.ts.map +1 -0
  63. package/types/src/Utils/Dict.d.ts +310 -0
  64. package/types/src/Utils/Dict.d.ts.map +1 -0
  65. package/types/src/Utils/Num.d.ts +110 -0
  66. package/types/src/Utils/Num.d.ts.map +1 -0
  67. package/types/src/{Core → Utils}/Rec.d.ts +39 -1
  68. package/types/src/Utils/Rec.d.ts.map +1 -0
  69. package/types/src/Utils/Str.d.ts +128 -0
  70. package/types/src/Utils/Str.d.ts.map +1 -0
  71. package/types/src/Utils/Uniq.d.ts +179 -0
  72. package/types/src/Utils/Uniq.d.ts.map +1 -0
  73. package/types/src/Utils/index.d.ts +7 -0
  74. package/types/src/Utils/index.d.ts.map +1 -0
  75. package/types/src/Core/Arr.d.ts.map +0 -1
  76. package/types/src/Core/Rec.d.ts.map +0 -1
@@ -0,0 +1,134 @@
1
+ import { Option } from "../Core/Option.js";
2
+ /**
3
+ * String utilities. All transformation functions are data-last and curried so they
4
+ * compose naturally with `pipe`. Safe parsers return `Option` instead of `NaN`.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * import { Str } from "@nlozgachev/pipelined/utils";
9
+ * import { pipe } from "@nlozgachev/pipelined/composition";
10
+ *
11
+ * pipe(" Hello, World! ", Str.trim, Str.toLowerCase); // "hello, world!"
12
+ * ```
13
+ */
14
+ export var Str;
15
+ (function (Str) {
16
+ /**
17
+ * Splits a string by a separator. Data-last: use in `pipe`.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * pipe("a,b,c", Str.split(",")); // ["a", "b", "c"]
22
+ * ```
23
+ */
24
+ Str.split = (separator) => (s) => s.split(separator);
25
+ /**
26
+ * Removes leading and trailing whitespace from a string.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * pipe(" hello ", Str.trim); // "hello"
31
+ * ```
32
+ */
33
+ Str.trim = (s) => s.trim();
34
+ /**
35
+ * Returns `true` when the string contains the given substring.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * pipe("hello world", Str.includes("world")); // true
40
+ * pipe("hello world", Str.includes("xyz")); // false
41
+ * ```
42
+ */
43
+ Str.includes = (substring) => (s) => s.includes(substring);
44
+ /**
45
+ * Returns `true` when the string starts with the given prefix.
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * pipe("hello world", Str.startsWith("hello")); // true
50
+ * pipe("hello world", Str.startsWith("world")); // false
51
+ * ```
52
+ */
53
+ Str.startsWith = (prefix) => (s) => s.startsWith(prefix);
54
+ /**
55
+ * Returns `true` when the string ends with the given suffix.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * pipe("hello world", Str.endsWith("world")); // true
60
+ * pipe("hello world", Str.endsWith("hello")); // false
61
+ * ```
62
+ */
63
+ Str.endsWith = (suffix) => (s) => s.endsWith(suffix);
64
+ /**
65
+ * Converts a string to uppercase.
66
+ *
67
+ * @example
68
+ * ```ts
69
+ * pipe("hello", Str.toUpperCase); // "HELLO"
70
+ * ```
71
+ */
72
+ Str.toUpperCase = (s) => s.toUpperCase();
73
+ /**
74
+ * Converts a string to lowercase.
75
+ *
76
+ * @example
77
+ * ```ts
78
+ * pipe("HELLO", Str.toLowerCase); // "hello"
79
+ * ```
80
+ */
81
+ Str.toLowerCase = (s) => s.toLowerCase();
82
+ /**
83
+ * Splits a string into lines, normalising `\r\n` and `\r` line endings.
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * Str.lines("one\ntwo\nthree"); // ["one", "two", "three"]
88
+ * Str.lines("a\r\nb"); // ["a", "b"]
89
+ * ```
90
+ */
91
+ Str.lines = (s) => s.split(/\r?\n|\r/);
92
+ /**
93
+ * Splits a string into words on any whitespace boundary, filtering out empty strings.
94
+ *
95
+ * @example
96
+ * ```ts
97
+ * Str.words(" hello world "); // ["hello", "world"]
98
+ * ```
99
+ */
100
+ Str.words = (s) => s.trim().split(/\s+/).filter(Boolean);
101
+ /**
102
+ * Safe number parsers that return `Option` instead of `NaN`.
103
+ */
104
+ Str.parse = {
105
+ /**
106
+ * Parses a string as an integer (base 10). Returns `None` if the result is `NaN`.
107
+ *
108
+ * @example
109
+ * ```ts
110
+ * Str.parse.int("42"); // Some(42)
111
+ * Str.parse.int("3.7"); // Some(3)
112
+ * Str.parse.int("abc"); // None
113
+ * ```
114
+ */
115
+ int: (s) => {
116
+ const n = parseInt(s, 10);
117
+ return isNaN(n) ? Option.none() : Option.some(n);
118
+ },
119
+ /**
120
+ * Parses a string as a floating-point number. Returns `None` if the result is `NaN`.
121
+ *
122
+ * @example
123
+ * ```ts
124
+ * Str.parse.float("3.14"); // Some(3.14)
125
+ * Str.parse.float("42"); // Some(42)
126
+ * Str.parse.float("abc"); // None
127
+ * ```
128
+ */
129
+ float: (s) => {
130
+ const n = parseFloat(s);
131
+ return isNaN(n) ? Option.none() : Option.some(n);
132
+ },
133
+ };
134
+ })(Str || (Str = {}));
@@ -0,0 +1,265 @@
1
+ /**
2
+ * Functional utilities for unique-value collections (`ReadonlySet<A>`). All functions are pure
3
+ * and data-last — they compose naturally with `pipe`.
4
+ *
5
+ * Every "mutating" operation returns a new set; the original is never changed.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { Uniq } from "@nlozgachev/pipelined/utils";
10
+ * import { pipe } from "@nlozgachev/pipelined/composition";
11
+ *
12
+ * const active = pipe(
13
+ * Uniq.fromArray(["alice", "bob", "alice", "carol"]),
14
+ * Uniq.remove("bob"),
15
+ * Uniq.map(name => name.toUpperCase()),
16
+ * );
17
+ * // ReadonlySet { "ALICE", "CAROL" }
18
+ * ```
19
+ */
20
+ export var Uniq;
21
+ (function (Uniq) {
22
+ // ---------------------------------------------------------------------------
23
+ // Constructors
24
+ // ---------------------------------------------------------------------------
25
+ /**
26
+ * Creates an empty unique collection.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * Uniq.empty<number>(); // ReadonlySet {}
31
+ * ```
32
+ */
33
+ Uniq.empty = () => new globalThis.Set();
34
+ /**
35
+ * Creates a unique collection containing a single item.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * Uniq.singleton(42); // ReadonlySet { 42 }
40
+ * ```
41
+ */
42
+ Uniq.singleton = (item) => new globalThis.Set([item]);
43
+ /**
44
+ * Creates a unique collection from an array, automatically discarding duplicates.
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * Uniq.fromArray([1, 2, 2, 3, 3, 3]); // ReadonlySet { 1, 2, 3 }
49
+ * Uniq.fromArray([]); // ReadonlySet {}
50
+ * ```
51
+ */
52
+ Uniq.fromArray = (arr) => new globalThis.Set(arr);
53
+ // ---------------------------------------------------------------------------
54
+ // Query
55
+ // ---------------------------------------------------------------------------
56
+ /**
57
+ * Returns `true` if the collection contains the given item.
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * pipe(Uniq.fromArray([1, 2, 3]), Uniq.has(2)); // true
62
+ * pipe(Uniq.fromArray([1, 2, 3]), Uniq.has(4)); // false
63
+ * ```
64
+ */
65
+ Uniq.has = (item) => (s) => s.has(item);
66
+ /**
67
+ * Returns the number of items in the collection.
68
+ *
69
+ * @example
70
+ * ```ts
71
+ * Uniq.size(Uniq.fromArray([1, 2, 3])); // 3
72
+ * ```
73
+ */
74
+ Uniq.size = (s) => s.size;
75
+ /**
76
+ * Returns `true` if the collection has no items.
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * Uniq.isEmpty(Uniq.empty()); // true
81
+ * ```
82
+ */
83
+ Uniq.isEmpty = (s) => s.size === 0;
84
+ /**
85
+ * Returns `true` if every item in `set` also exists in `other`.
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * pipe(Uniq.fromArray([1, 2]), Uniq.isSubsetOf(Uniq.fromArray([1, 2, 3]))); // true
90
+ * pipe(Uniq.fromArray([1, 4]), Uniq.isSubsetOf(Uniq.fromArray([1, 2, 3]))); // false
91
+ * pipe(Uniq.empty<number>(), Uniq.isSubsetOf(Uniq.fromArray([1, 2, 3]))); // true
92
+ * ```
93
+ */
94
+ Uniq.isSubsetOf = (other) => (s) => {
95
+ const set = s;
96
+ if (typeof set.isSubsetOf === "function")
97
+ return set.isSubsetOf(other);
98
+ for (const item of s)
99
+ if (!other.has(item))
100
+ return false;
101
+ return true;
102
+ };
103
+ // ---------------------------------------------------------------------------
104
+ // Modification
105
+ // ---------------------------------------------------------------------------
106
+ /**
107
+ * Returns a new collection with the item added. If the item is already present, returns the
108
+ * original collection unchanged.
109
+ *
110
+ * @example
111
+ * ```ts
112
+ * pipe(Uniq.fromArray([1, 2]), Uniq.insert(3)); // ReadonlySet { 1, 2, 3 }
113
+ * pipe(Uniq.fromArray([1, 2]), Uniq.insert(2)); // ReadonlySet { 1, 2 } — unchanged
114
+ * ```
115
+ */
116
+ Uniq.insert = (item) => (s) => {
117
+ if (s.has(item))
118
+ return s;
119
+ const result = new globalThis.Set(s);
120
+ result.add(item);
121
+ return result;
122
+ };
123
+ /**
124
+ * Returns a new collection with the item removed. If the item is not present, returns the
125
+ * original collection unchanged.
126
+ *
127
+ * @example
128
+ * ```ts
129
+ * pipe(Uniq.fromArray([1, 2, 3]), Uniq.remove(2)); // ReadonlySet { 1, 3 }
130
+ * pipe(Uniq.fromArray([1, 2, 3]), Uniq.remove(4)); // ReadonlySet { 1, 2, 3 } — unchanged
131
+ * ```
132
+ */
133
+ Uniq.remove = (item) => (s) => {
134
+ if (!s.has(item))
135
+ return s;
136
+ const result = new globalThis.Set(s);
137
+ result.delete(item);
138
+ return result;
139
+ };
140
+ // ---------------------------------------------------------------------------
141
+ // Transform
142
+ // ---------------------------------------------------------------------------
143
+ /**
144
+ * Applies `f` to each item, returning a new collection of the results. Duplicate results are
145
+ * automatically merged.
146
+ *
147
+ * @example
148
+ * ```ts
149
+ * pipe(Uniq.fromArray([1, 2, 3, 4]), Uniq.map(n => n % 3)); // ReadonlySet { 1, 2, 0 }
150
+ * ```
151
+ */
152
+ Uniq.map = (f) => (s) => {
153
+ const result = new globalThis.Set();
154
+ for (const item of s) {
155
+ result.add(f(item));
156
+ }
157
+ return result;
158
+ };
159
+ /**
160
+ * Returns a new collection containing only the items for which the predicate returns `true`.
161
+ *
162
+ * @example
163
+ * ```ts
164
+ * pipe(Uniq.fromArray([1, 2, 3, 4, 5]), Uniq.filter(n => n % 2 === 0));
165
+ * // ReadonlySet { 2, 4 }
166
+ * ```
167
+ */
168
+ Uniq.filter = (predicate) => (s) => {
169
+ const result = new globalThis.Set();
170
+ for (const item of s) {
171
+ if (predicate(item))
172
+ result.add(item);
173
+ }
174
+ return result;
175
+ };
176
+ // ---------------------------------------------------------------------------
177
+ // Set operations
178
+ // ---------------------------------------------------------------------------
179
+ /**
180
+ * Returns a new collection containing all items from both collections.
181
+ *
182
+ * @example
183
+ * ```ts
184
+ * pipe(Uniq.fromArray([1, 2, 3]), Uniq.union(Uniq.fromArray([2, 3, 4])));
185
+ * // ReadonlySet { 1, 2, 3, 4 }
186
+ * ```
187
+ */
188
+ Uniq.union = (other) => (s) => {
189
+ const set = s;
190
+ if (typeof set.union === "function")
191
+ return set.union(other);
192
+ const result = new globalThis.Set(s);
193
+ for (const item of other)
194
+ result.add(item);
195
+ return result;
196
+ };
197
+ /**
198
+ * Returns a new collection containing only the items that appear in both collections.
199
+ *
200
+ * @example
201
+ * ```ts
202
+ * pipe(Uniq.fromArray([1, 2, 3]), Uniq.intersection(Uniq.fromArray([2, 3, 4])));
203
+ * // ReadonlySet { 2, 3 }
204
+ * ```
205
+ */
206
+ Uniq.intersection = (other) => (s) => {
207
+ const set = s;
208
+ if (typeof set.intersection === "function")
209
+ return set.intersection(other);
210
+ const result = new globalThis.Set();
211
+ for (const item of s)
212
+ if (other.has(item))
213
+ result.add(item);
214
+ return result;
215
+ };
216
+ /**
217
+ * Returns a new collection containing only the items from `set` that do not appear in `other`.
218
+ *
219
+ * @example
220
+ * ```ts
221
+ * pipe(Uniq.fromArray([1, 2, 3, 4]), Uniq.difference(Uniq.fromArray([2, 4])));
222
+ * // ReadonlySet { 1, 3 }
223
+ * ```
224
+ */
225
+ Uniq.difference = (other) => (s) => {
226
+ const set = s;
227
+ if (typeof set.difference === "function")
228
+ return set.difference(other);
229
+ const result = new globalThis.Set();
230
+ for (const item of s)
231
+ if (!other.has(item))
232
+ result.add(item);
233
+ return result;
234
+ };
235
+ // ---------------------------------------------------------------------------
236
+ // Fold
237
+ // ---------------------------------------------------------------------------
238
+ /**
239
+ * Folds the collection into a single value by applying `f` to each item in insertion order.
240
+ *
241
+ * @example
242
+ * ```ts
243
+ * Uniq.reduce(0, (acc, n) => acc + n)(Uniq.fromArray([1, 2, 3])); // 6
244
+ * ```
245
+ */
246
+ Uniq.reduce = (init, f) => (s) => {
247
+ let acc = init;
248
+ for (const item of s) {
249
+ acc = f(acc, item);
250
+ }
251
+ return acc;
252
+ };
253
+ // ---------------------------------------------------------------------------
254
+ // Convert
255
+ // ---------------------------------------------------------------------------
256
+ /**
257
+ * Converts the collection to a readonly array in insertion order.
258
+ *
259
+ * @example
260
+ * ```ts
261
+ * Uniq.toArray(Uniq.fromArray([3, 1, 2])); // [3, 1, 2]
262
+ * ```
263
+ */
264
+ Uniq.toArray = (s) => [...s];
265
+ })(Uniq || (Uniq = {}));
@@ -0,0 +1,6 @@
1
+ export * from "./Arr.js";
2
+ export * from "./Rec.js";
3
+ export * from "./Num.js";
4
+ export * from "./Str.js";
5
+ export * from "./Dict.js";
6
+ export * from "./Uniq.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nlozgachev/pipelined",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "Simple functional programming toolkit for TypeScript",
5
5
  "keywords": [
6
6
  "functional",
@@ -37,6 +37,16 @@
37
37
  "default": "./script/src/Core/index.js"
38
38
  }
39
39
  },
40
+ "./utils": {
41
+ "import": {
42
+ "types": "./types/src/Utils/index.d.ts",
43
+ "default": "./esm/src/Utils/index.js"
44
+ },
45
+ "require": {
46
+ "types": "./types/src/Utils/index.d.ts",
47
+ "default": "./script/src/Utils/index.js"
48
+ }
49
+ },
40
50
  "./types": {
41
51
  "import": {
42
52
  "types": "./types/src/Types/index.d.ts",
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Option = void 0;
4
4
  const Result_js_1 = require("./Result.js");
5
+ const _none = { kind: "None" };
5
6
  var Option;
6
7
  (function (Option) {
7
8
  /**
@@ -15,7 +16,7 @@ var Option;
15
16
  /**
16
17
  * Creates a None (empty Option).
17
18
  */
18
- Option.none = () => ({ kind: "None" });
19
+ Option.none = () => _none;
19
20
  /**
20
21
  * Type guard that checks if a Option is None.
21
22
  */
@@ -3,16 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RemoteData = void 0;
4
4
  const Option_js_1 = require("./Option.js");
5
5
  const Result_js_1 = require("./Result.js");
6
+ const _notAsked = { kind: "NotAsked" };
7
+ const _loading = { kind: "Loading" };
6
8
  var RemoteData;
7
9
  (function (RemoteData) {
8
10
  /**
9
11
  * Creates a NotAsked RemoteData.
10
12
  */
11
- RemoteData.notAsked = () => ({ kind: "NotAsked" });
13
+ RemoteData.notAsked = () => _notAsked;
12
14
  /**
13
15
  * Creates a Loading RemoteData.
14
16
  */
15
- RemoteData.loading = () => ({ kind: "Loading" });
17
+ RemoteData.loading = () => _loading;
16
18
  /**
17
19
  * Creates a Failure RemoteData with the given error.
18
20
  */
@@ -208,7 +210,5 @@ var RemoteData;
208
210
  * ); // Ok(42)
209
211
  * ```
210
212
  */
211
- RemoteData.toResult = (onNotReady) => (data) => RemoteData.isSuccess(data)
212
- ? Result_js_1.Result.ok(data.value)
213
- : Result_js_1.Result.err(RemoteData.isFailure(data) ? data.error : onNotReady());
213
+ RemoteData.toResult = (onNotReady) => (data) => RemoteData.isSuccess(data) ? Result_js_1.Result.ok(data.value) : Result_js_1.Result.err(RemoteData.isFailure(data) ? data.error : onNotReady());
214
214
  })(RemoteData || (exports.RemoteData = RemoteData = {}));
@@ -94,9 +94,7 @@ var TaskValidation;
94
94
  * The fallback receives the accumulated error list so callers can inspect which errors occurred.
95
95
  * The fallback can produce a different success type, widening the result to `TaskValidation<E, A | B>`.
96
96
  */
97
- TaskValidation.recover = (fallback) => (data) => Task_js_1.Task.chain((validation) => Validation_js_1.Validation.isValid(validation)
98
- ? Task_js_1.Task.resolve(validation)
99
- : fallback(validation.errors))(data);
97
+ TaskValidation.recover = (fallback) => (data) => Task_js_1.Task.chain((validation) => Validation_js_1.Validation.isValid(validation) ? Task_js_1.Task.resolve(validation) : fallback(validation.errors))(data);
100
98
  /**
101
99
  * Runs two TaskValidations concurrently and combines their results into a tuple.
102
100
  * If both are Valid, returns Valid with both values. If either fails, accumulates
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Tuple = void 0;
4
+ var Tuple;
5
+ (function (Tuple) {
6
+ /**
7
+ * Creates a pair from two values.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * Tuple.make("Paris", 2_161_000); // ["Paris", 2161000]
12
+ * ```
13
+ */
14
+ Tuple.make = (first, second) => [first, second];
15
+ /**
16
+ * Returns the first value from the pair.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * Tuple.first(Tuple.make("Paris", 2_161_000)); // "Paris"
21
+ * ```
22
+ */
23
+ Tuple.first = (tuple) => tuple[0];
24
+ /**
25
+ * Returns the second value from the pair.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * Tuple.second(Tuple.make("Paris", 2_161_000)); // 2161000
30
+ * ```
31
+ */
32
+ Tuple.second = (tuple) => tuple[1];
33
+ /**
34
+ * Transforms the first value, leaving the second unchanged.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * pipe(Tuple.make("alice", 42), Tuple.mapFirst((s) => s.toUpperCase())); // ["ALICE", 42]
39
+ * ```
40
+ */
41
+ Tuple.mapFirst = (f) => (tuple) => [f(tuple[0]), tuple[1]];
42
+ /**
43
+ * Transforms the second value, leaving the first unchanged.
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * pipe(Tuple.make("alice", 42), Tuple.mapSecond((n) => n * 2)); // ["alice", 84]
48
+ * ```
49
+ */
50
+ Tuple.mapSecond = (f) => (tuple) => [tuple[0], f(tuple[1])];
51
+ /**
52
+ * Transforms both values independently in a single step.
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * pipe(
57
+ * Tuple.make("alice", 42),
58
+ * Tuple.mapBoth(
59
+ * (name) => name.toUpperCase(),
60
+ * (score) => score * 2,
61
+ * ),
62
+ * ); // ["ALICE", 84]
63
+ * ```
64
+ */
65
+ Tuple.mapBoth = (onFirst, onSecond) => (tuple) => [
66
+ onFirst(tuple[0]),
67
+ onSecond(tuple[1]),
68
+ ];
69
+ /**
70
+ * Applies a binary function to both values, collapsing the pair into a single value.
71
+ * Useful as the final step when consuming a pair in a pipeline.
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * pipe(Tuple.make("Alice", 100), Tuple.fold((name, score) => `${name}: ${score}`));
76
+ * // "Alice: 100"
77
+ * ```
78
+ */
79
+ Tuple.fold = (f) => (tuple) => f(tuple[0], tuple[1]);
80
+ /**
81
+ * Swaps the two values: `[A, B]` becomes `[B, A]`.
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * Tuple.swap(Tuple.make("key", 1)); // [1, "key"]
86
+ * ```
87
+ */
88
+ Tuple.swap = (tuple) => [tuple[1], tuple[0]];
89
+ /**
90
+ * Converts the pair to a heterogeneous readonly array `readonly (A | B)[]`.
91
+ *
92
+ * @example
93
+ * ```ts
94
+ * Tuple.toArray(Tuple.make("hello", 42)); // ["hello", 42]
95
+ * ```
96
+ */
97
+ Tuple.toArray = (tuple) => [...tuple];
98
+ /**
99
+ * Runs a side effect with both values without changing the pair.
100
+ * Useful for logging or debugging in the middle of a pipeline.
101
+ *
102
+ * @example
103
+ * ```ts
104
+ * pipe(
105
+ * Tuple.make("Paris", 2_161_000),
106
+ * Tuple.tap((city, pop) => console.log(`${city}: ${pop}`)),
107
+ * Tuple.mapSecond((n) => n / 1_000_000),
108
+ * ); // logs "Paris: 2161000", returns ["Paris", 2.161]
109
+ * ```
110
+ */
111
+ Tuple.tap = (f) => (tuple) => {
112
+ f(tuple[0], tuple[1]);
113
+ return tuple;
114
+ };
115
+ })(Tuple || (exports.Tuple = Tuple = {}));
@@ -14,22 +14,21 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./Arr.js"), exports);
18
- __exportStar(require("./Logged.js"), exports);
19
17
  __exportStar(require("./Deferred.js"), exports);
20
18
  __exportStar(require("./Lens.js"), exports);
19
+ __exportStar(require("./Logged.js"), exports);
21
20
  __exportStar(require("./Option.js"), exports);
22
- __exportStar(require("./Reader.js"), exports);
23
21
  __exportStar(require("./Optional.js"), exports);
24
- __exportStar(require("./Rec.js"), exports);
25
22
  __exportStar(require("./Predicate.js"), exports);
23
+ __exportStar(require("./Reader.js"), exports);
26
24
  __exportStar(require("./Refinement.js"), exports);
27
25
  __exportStar(require("./RemoteData.js"), exports);
28
- __exportStar(require("./State.js"), exports);
29
26
  __exportStar(require("./Result.js"), exports);
27
+ __exportStar(require("./State.js"), exports);
30
28
  __exportStar(require("./Task.js"), exports);
31
29
  __exportStar(require("./TaskOption.js"), exports);
32
30
  __exportStar(require("./TaskResult.js"), exports);
33
31
  __exportStar(require("./TaskValidation.js"), exports);
34
32
  __exportStar(require("./These.js"), exports);
33
+ __exportStar(require("./Tuple.js"), exports);
35
34
  __exportStar(require("./Validation.js"), exports);