@nlozgachev/pipelined 0.32.0 → 0.33.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,4 +1,4 @@
1
- import { N as NonEmptyList } from './NonEmptyList-BlGFjor5.js';
1
+ import { NonEmptyList, Duration } from './types.mjs';
2
2
 
3
3
  type WithKind<K extends string> = {
4
4
  readonly kind: K;
@@ -223,6 +223,44 @@ declare namespace Result {
223
223
  * ```
224
224
  */
225
225
  const fromPredicate: <E, A>(pred: (a: A) => boolean, onFalse: (a: A) => E) => (a: A) => Result<E, A>;
226
+ /**
227
+ * Creates a Result from a nullable value.
228
+ * Returns Ok if the value is not null or undefined, error from onNull otherwise.
229
+ *
230
+ * @example
231
+ * ```ts
232
+ * pipe(null, Result.fromNullable(() => "is null")); // Error("is null")
233
+ * pipe(42, Result.fromNullable(() => "is null")); // Ok(42)
234
+ * ```
235
+ */
236
+ const fromNullable: <E>(onNull: () => E) => <A>(value: A | null | undefined) => Result<E, A>;
237
+ /**
238
+ * Creates a Result from a Maybe.
239
+ * Some becomes Ok, None becomes error from onNone.
240
+ *
241
+ * @example
242
+ * ```ts
243
+ * pipe(Maybe.none(), Result.fromMaybe(() => "is none")); // Error("is none")
244
+ * pipe(Maybe.some(42), Result.fromMaybe(() => "is none")); // Ok(42)
245
+ * ```
246
+ */
247
+ const fromMaybe: <E>(onNone: () => E) => <A>(maybe: Maybe<A>) => Result<E, A>;
248
+ /**
249
+ * Wraps a throwing function of any arguments, returning a new function
250
+ * that catches errors and returns a Result.
251
+ *
252
+ * @example
253
+ * ```ts
254
+ * const safeParse = Result.fromThrowable(
255
+ * (s: string) => JSON.parse(s),
256
+ * (e) => new Error(`Parse error: ${e}`)
257
+ * );
258
+ *
259
+ * safeParse('{"a":1}'); // Ok({ a: 1 })
260
+ * safeParse('invalid'); // Error(Error)
261
+ * ```
262
+ */
263
+ const fromThrowable: <Args extends readonly unknown[], A, E>(f: (...args: Args) => A, onError: (e: unknown) => E) => (...args: Args) => Result<E, A>;
226
264
  /**
227
265
  * Recovers from an error by providing a fallback Result.
228
266
  * The fallback can produce a different success type, widening the result to `Result<E, A | B>`.
@@ -844,37 +882,37 @@ declare namespace Task {
844
882
  */
845
883
  const all: <T extends readonly Task<unknown>[]>(tasks: T) => Task<{ [K in keyof T]: T[K] extends Task<infer A> ? A : never; }>;
846
884
  /**
847
- * Delays the execution of a Task by the specified milliseconds.
885
+ * Delays the execution of a Task by the specified milliseconds or duration.
848
886
  * Useful for debouncing or rate limiting.
849
887
  *
850
888
  * @example
851
889
  * ```ts
852
890
  * pipe(
853
891
  * Task.resolve(42),
854
- * Task.delay(1000)
892
+ * Task.delay(Duration.seconds(1))
855
893
  * )(); // Resolves after 1 second
856
894
  * ```
857
895
  */
858
- const delay: (ms: number) => <A>(data: Task<A>) => Task<A>;
896
+ const delay: (ms: number | Duration) => <A>(data: Task<A>) => Task<A>;
859
897
  /**
860
898
  * Runs a Task a fixed number of times sequentially, collecting all results into an array.
861
- * An optional delay (ms) can be inserted between runs.
899
+ * An optional delay (ms or Duration) can be inserted between runs.
862
900
  *
863
901
  * @example
864
902
  * ```ts
865
903
  * pipe(
866
904
  * pollSensor,
867
- * Task.repeat({ times: 5, delay: 1000 })
905
+ * Task.repeat({ times: 5, delay: Duration.seconds(1) })
868
906
  * )(); // Task<Reading[]> — 5 readings, one per second
869
907
  * ```
870
908
  */
871
909
  const repeat: (options: {
872
910
  times: number;
873
- delay?: number;
911
+ delay?: number | Duration;
874
912
  }) => <A>(task: Task<A>) => Task<readonly A[]>;
875
913
  /**
876
914
  * Runs a Task repeatedly until the result satisfies a predicate, returning that result.
877
- * An optional delay (ms) can be inserted between runs.
915
+ * An optional delay (ms or Duration) can be inserted between runs.
878
916
  * An optional `maxAttempts` cap stops the loop after N calls — the last value is returned
879
917
  * regardless of whether the predicate was satisfied.
880
918
  *
@@ -882,18 +920,19 @@ declare namespace Task {
882
920
  * ```ts
883
921
  * pipe(
884
922
  * checkStatus,
885
- * Task.repeatUntil({ when: (s) => s === "ready", delay: 500 })
923
+ * Task.repeatUntil({ when: (s) => s === "ready", delay: Duration.milliseconds(500) })
886
924
  * )(); // polls every 500ms until status is "ready"
887
925
  * ```
888
926
  */
889
927
  const repeatUntil: <A>(options: {
890
928
  when: (a: A) => boolean;
891
- delay?: number;
929
+ delay?: number | Duration;
892
930
  maxAttempts?: number;
893
931
  }) => (task: Task<A>) => Task<A>;
894
932
  /**
895
933
  * Resolves with the value of the first Task to complete. All Tasks start
896
- * immediately; the rest are abandoned once one resolves.
934
+ * immediately. When one resolves, the other tasks are cancelled (aborted)
935
+ * downstream.
897
936
  *
898
937
  * @example
899
938
  * ```ts
@@ -904,6 +943,17 @@ declare namespace Task {
904
943
  * ```
905
944
  */
906
945
  const race: <A>(tasks: ReadonlyArray<Task<A>>) => Task<A>;
946
+ /**
947
+ * Runs an array of Tasks concurrently and collects their results in an array.
948
+ * Forward-propagates the call site's AbortSignal to all subtasks concurrently.
949
+ *
950
+ * @example
951
+ * ```ts
952
+ * Task.sequence([loadConfig, detectLocale, loadTheme])();
953
+ * // Deferred<[Config, string, Theme]>
954
+ * ```
955
+ */
956
+ const sequence: <A>(tasks: ReadonlyArray<Task<A>>) => Task<ReadonlyArray<A>>;
907
957
  /**
908
958
  * Runs an array of Tasks one at a time in order, collecting all results.
909
959
  * Each Task starts only after the previous one resolves.
@@ -931,12 +981,12 @@ declare namespace Task {
931
981
  * ```ts
932
982
  * pipe(
933
983
  * heavyComputation,
934
- * Task.timeout(5000, () => "timed out"),
984
+ * Task.timeout(Duration.seconds(5), () => "timed out"),
935
985
  * TaskResult.chain(processResult)
936
986
  * );
937
987
  * ```
938
988
  */
939
- const timeout: <E>(ms: number, onTimeout: () => E) => <A>(task: Task<A>) => Task<Result<E, A>>;
989
+ const timeout: <E>(ms: number | Duration, onTimeout: () => E) => <A>(task: Task<A>) => Task<Result<E, A>>;
940
990
  /**
941
991
  * Creates a Task paired with an `abort` handle. Calling `abort()` cancels the
942
992
  * current in-flight call immediately. Unlike a one-shot abort, calling `task()`
@@ -1,4 +1,4 @@
1
- import { N as NonEmptyList } from './NonEmptyList-BlGFjor5.mjs';
1
+ import { NonEmptyList, Duration } from './types.js';
2
2
 
3
3
  type WithKind<K extends string> = {
4
4
  readonly kind: K;
@@ -223,6 +223,44 @@ declare namespace Result {
223
223
  * ```
224
224
  */
225
225
  const fromPredicate: <E, A>(pred: (a: A) => boolean, onFalse: (a: A) => E) => (a: A) => Result<E, A>;
226
+ /**
227
+ * Creates a Result from a nullable value.
228
+ * Returns Ok if the value is not null or undefined, error from onNull otherwise.
229
+ *
230
+ * @example
231
+ * ```ts
232
+ * pipe(null, Result.fromNullable(() => "is null")); // Error("is null")
233
+ * pipe(42, Result.fromNullable(() => "is null")); // Ok(42)
234
+ * ```
235
+ */
236
+ const fromNullable: <E>(onNull: () => E) => <A>(value: A | null | undefined) => Result<E, A>;
237
+ /**
238
+ * Creates a Result from a Maybe.
239
+ * Some becomes Ok, None becomes error from onNone.
240
+ *
241
+ * @example
242
+ * ```ts
243
+ * pipe(Maybe.none(), Result.fromMaybe(() => "is none")); // Error("is none")
244
+ * pipe(Maybe.some(42), Result.fromMaybe(() => "is none")); // Ok(42)
245
+ * ```
246
+ */
247
+ const fromMaybe: <E>(onNone: () => E) => <A>(maybe: Maybe<A>) => Result<E, A>;
248
+ /**
249
+ * Wraps a throwing function of any arguments, returning a new function
250
+ * that catches errors and returns a Result.
251
+ *
252
+ * @example
253
+ * ```ts
254
+ * const safeParse = Result.fromThrowable(
255
+ * (s: string) => JSON.parse(s),
256
+ * (e) => new Error(`Parse error: ${e}`)
257
+ * );
258
+ *
259
+ * safeParse('{"a":1}'); // Ok({ a: 1 })
260
+ * safeParse('invalid'); // Error(Error)
261
+ * ```
262
+ */
263
+ const fromThrowable: <Args extends readonly unknown[], A, E>(f: (...args: Args) => A, onError: (e: unknown) => E) => (...args: Args) => Result<E, A>;
226
264
  /**
227
265
  * Recovers from an error by providing a fallback Result.
228
266
  * The fallback can produce a different success type, widening the result to `Result<E, A | B>`.
@@ -844,37 +882,37 @@ declare namespace Task {
844
882
  */
845
883
  const all: <T extends readonly Task<unknown>[]>(tasks: T) => Task<{ [K in keyof T]: T[K] extends Task<infer A> ? A : never; }>;
846
884
  /**
847
- * Delays the execution of a Task by the specified milliseconds.
885
+ * Delays the execution of a Task by the specified milliseconds or duration.
848
886
  * Useful for debouncing or rate limiting.
849
887
  *
850
888
  * @example
851
889
  * ```ts
852
890
  * pipe(
853
891
  * Task.resolve(42),
854
- * Task.delay(1000)
892
+ * Task.delay(Duration.seconds(1))
855
893
  * )(); // Resolves after 1 second
856
894
  * ```
857
895
  */
858
- const delay: (ms: number) => <A>(data: Task<A>) => Task<A>;
896
+ const delay: (ms: number | Duration) => <A>(data: Task<A>) => Task<A>;
859
897
  /**
860
898
  * Runs a Task a fixed number of times sequentially, collecting all results into an array.
861
- * An optional delay (ms) can be inserted between runs.
899
+ * An optional delay (ms or Duration) can be inserted between runs.
862
900
  *
863
901
  * @example
864
902
  * ```ts
865
903
  * pipe(
866
904
  * pollSensor,
867
- * Task.repeat({ times: 5, delay: 1000 })
905
+ * Task.repeat({ times: 5, delay: Duration.seconds(1) })
868
906
  * )(); // Task<Reading[]> — 5 readings, one per second
869
907
  * ```
870
908
  */
871
909
  const repeat: (options: {
872
910
  times: number;
873
- delay?: number;
911
+ delay?: number | Duration;
874
912
  }) => <A>(task: Task<A>) => Task<readonly A[]>;
875
913
  /**
876
914
  * Runs a Task repeatedly until the result satisfies a predicate, returning that result.
877
- * An optional delay (ms) can be inserted between runs.
915
+ * An optional delay (ms or Duration) can be inserted between runs.
878
916
  * An optional `maxAttempts` cap stops the loop after N calls — the last value is returned
879
917
  * regardless of whether the predicate was satisfied.
880
918
  *
@@ -882,18 +920,19 @@ declare namespace Task {
882
920
  * ```ts
883
921
  * pipe(
884
922
  * checkStatus,
885
- * Task.repeatUntil({ when: (s) => s === "ready", delay: 500 })
923
+ * Task.repeatUntil({ when: (s) => s === "ready", delay: Duration.milliseconds(500) })
886
924
  * )(); // polls every 500ms until status is "ready"
887
925
  * ```
888
926
  */
889
927
  const repeatUntil: <A>(options: {
890
928
  when: (a: A) => boolean;
891
- delay?: number;
929
+ delay?: number | Duration;
892
930
  maxAttempts?: number;
893
931
  }) => (task: Task<A>) => Task<A>;
894
932
  /**
895
933
  * Resolves with the value of the first Task to complete. All Tasks start
896
- * immediately; the rest are abandoned once one resolves.
934
+ * immediately. When one resolves, the other tasks are cancelled (aborted)
935
+ * downstream.
897
936
  *
898
937
  * @example
899
938
  * ```ts
@@ -904,6 +943,17 @@ declare namespace Task {
904
943
  * ```
905
944
  */
906
945
  const race: <A>(tasks: ReadonlyArray<Task<A>>) => Task<A>;
946
+ /**
947
+ * Runs an array of Tasks concurrently and collects their results in an array.
948
+ * Forward-propagates the call site's AbortSignal to all subtasks concurrently.
949
+ *
950
+ * @example
951
+ * ```ts
952
+ * Task.sequence([loadConfig, detectLocale, loadTheme])();
953
+ * // Deferred<[Config, string, Theme]>
954
+ * ```
955
+ */
956
+ const sequence: <A>(tasks: ReadonlyArray<Task<A>>) => Task<ReadonlyArray<A>>;
907
957
  /**
908
958
  * Runs an array of Tasks one at a time in order, collecting all results.
909
959
  * Each Task starts only after the previous one resolves.
@@ -931,12 +981,12 @@ declare namespace Task {
931
981
  * ```ts
932
982
  * pipe(
933
983
  * heavyComputation,
934
- * Task.timeout(5000, () => "timed out"),
984
+ * Task.timeout(Duration.seconds(5), () => "timed out"),
935
985
  * TaskResult.chain(processResult)
936
986
  * );
937
987
  * ```
938
988
  */
939
- const timeout: <E>(ms: number, onTimeout: () => E) => <A>(task: Task<A>) => Task<Result<E, A>>;
989
+ const timeout: <E>(ms: number | Duration, onTimeout: () => E) => <A>(task: Task<A>) => Task<Result<E, A>>;
940
990
  /**
941
991
  * Creates a Task paired with an `abort` handle. Calling `abort()` cancels the
942
992
  * current in-flight call immediately. Unlike a one-shot abort, calling `task()`
@@ -3,7 +3,7 @@ import {
3
3
  Maybe,
4
4
  Result,
5
5
  Task
6
- } from "./chunk-TK5ZCGP2.mjs";
6
+ } from "./chunk-GSTKY7MF.mjs";
7
7
 
8
8
  // src/Core/Combinable.ts
9
9
  var Combinable;
@@ -1331,6 +1331,8 @@ var TaskMaybe;
1331
1331
  TaskMaybe2.some = (value) => Task.resolve(Maybe.some(value));
1332
1332
  TaskMaybe2.none = () => Task.resolve(Maybe.none());
1333
1333
  TaskMaybe2.fromMaybe = (option) => Task.resolve(option);
1334
+ TaskMaybe2.fromNullable = (value) => Task.resolve(Maybe.fromNullable(value));
1335
+ TaskMaybe2.fromResult = (result) => Task.resolve(Result.toMaybe(result));
1334
1336
  TaskMaybe2.fromTask = (task) => Task.map(Maybe.some)(task);
1335
1337
  TaskMaybe2.tryCatch = (f) => Task.from(
1336
1338
  (signal) => f(signal).then(Maybe.some).catch(() => Maybe.none())
@@ -1356,6 +1358,12 @@ var TaskResult;
1356
1358
  ((TaskResult2) => {
1357
1359
  TaskResult2.ok = (value) => Task.resolve(Result.ok(value));
1358
1360
  TaskResult2.err = (error) => Task.resolve(Result.error(error));
1361
+ TaskResult2.fromNullable = (onNull) => (value) => Task.resolve(value === null || value === void 0 ? Result.error(onNull()) : Result.ok(value));
1362
+ TaskResult2.fromMaybe = (onNone) => (maybe) => Task.resolve(Maybe.isNone(maybe) ? Result.error(onNone()) : Result.ok(maybe.value));
1363
+ TaskResult2.fromResult = (result) => Task.resolve(result);
1364
+ TaskResult2.fromThrowable = (f, onError) => (...args) => Task.from(
1365
+ () => f(...args).then(Result.ok).catch((e) => Result.error(onError(e)))
1366
+ );
1359
1367
  TaskResult2.tryCatch = (f, onError) => Task.from(
1360
1368
  (signal) => f(signal).then(Result.ok).catch((e) => Result.error(onError(e)))
1361
1369
  );
@@ -1401,6 +1409,8 @@ var Validation;
1401
1409
  Validation2.isValid = (data) => data.kind === "Valid";
1402
1410
  Validation2.isInvalid = (data) => data.kind === "Invalid";
1403
1411
  Validation2.fromPredicate = (pred, onFalse) => (a) => pred(a) ? (0, Validation2.valid)(a) : (0, Validation2.invalid)(onFalse(a));
1412
+ Validation2.fromNullable = (onNull) => (value) => value === null || value === void 0 ? (0, Validation2.invalid)(onNull()) : (0, Validation2.valid)(value);
1413
+ Validation2.fromMaybe = (onNone) => (maybe) => Maybe.isNone(maybe) ? (0, Validation2.invalid)(onNone()) : (0, Validation2.valid)(maybe.value);
1404
1414
  Validation2.map = (f) => (data) => (0, Validation2.isValid)(data) ? (0, Validation2.valid)(f(data.value)) : data;
1405
1415
  Validation2.ap = (arg) => (data) => {
1406
1416
  if ((0, Validation2.isValid)(data) && (0, Validation2.isValid)(arg)) return (0, Validation2.valid)(data.value(arg.value));
@@ -1452,6 +1462,9 @@ var TaskValidation;
1452
1462
  TaskValidation2.invalid = (error) => Task.resolve(Validation.invalid(error));
1453
1463
  TaskValidation2.invalidAll = (errors) => Task.resolve(Validation.invalidAll(errors));
1454
1464
  TaskValidation2.fromValidation = (validation) => Task.resolve(validation);
1465
+ TaskValidation2.fromNullable = (onNull) => (value) => Task.resolve(value === null || value === void 0 ? Validation.invalid(onNull()) : Validation.valid(value));
1466
+ TaskValidation2.fromMaybe = (onNone) => (maybe) => Task.resolve(Maybe.isNone(maybe) ? Validation.invalid(onNone()) : Validation.valid(maybe.value));
1467
+ TaskValidation2.fromResult = (result) => Task.resolve(Validation.fromResult(result));
1455
1468
  TaskValidation2.tryCatch = (f, onError) => Task.from(
1456
1469
  (signal) => f(signal).then(Validation.valid).catch((e) => Validation.invalid(onError(e)))
1457
1470
  );
@@ -1,3 +1,7 @@
1
+ import {
2
+ Duration
3
+ } from "./chunk-VWVPHDZO.mjs";
4
+
1
5
  // src/Core/Maybe.ts
2
6
  var _none = { kind: "None" };
3
7
  var Maybe;
@@ -55,6 +59,15 @@ var Result;
55
59
  return data;
56
60
  };
57
61
  Result2.fromPredicate = (pred, onFalse) => (a) => pred(a) ? (0, Result2.ok)(a) : (0, Result2.error)(onFalse(a));
62
+ Result2.fromNullable = (onNull) => (value) => value === null || value === void 0 ? (0, Result2.error)(onNull()) : (0, Result2.ok)(value);
63
+ Result2.fromMaybe = (onNone) => (maybe) => Maybe.isNone(maybe) ? (0, Result2.error)(onNone()) : (0, Result2.ok)(maybe.value);
64
+ Result2.fromThrowable = (f, onError) => (...args) => {
65
+ try {
66
+ return (0, Result2.ok)(f(...args));
67
+ } catch (e) {
68
+ return (0, Result2.error)(onError(e));
69
+ }
70
+ };
58
71
  Result2.recover = (fallback) => (data) => (0, Result2.isOk)(data) ? data : fallback(data.error);
59
72
  Result2.recoverUnless = (isBlocked, fallback) => (data) => (0, Result2.isError)(data) && !isBlocked(data.error) ? fallback() : data;
60
73
  Result2.toMaybe = (data) => (0, Result2.isOk)(data) ? Maybe.some(data.value) : Maybe.none();
@@ -73,6 +86,7 @@ var Deferred;
73
86
 
74
87
  // src/Core/Task.ts
75
88
  var toPromise = (task, signal) => Deferred.toPromise(task(signal));
89
+ var getMs = (ms) => typeof ms === "number" ? ms : Duration.toMilliseconds(ms);
76
90
  var Task;
77
91
  ((Task2) => {
78
92
  Task2.resolve = (value) => () => Deferred.fromPromise(Promise.resolve(value));
@@ -113,7 +127,7 @@ var Task;
113
127
  timerId = setTimeout(() => {
114
128
  signal?.removeEventListener("abort", onAbort);
115
129
  resolve2(toPromise(data, signal));
116
- }, ms);
130
+ }, getMs(ms));
117
131
  })
118
132
  );
119
133
  Task2.repeat = (options) => (task) => (0, Task2.from)((signal) => {
@@ -136,7 +150,7 @@ var Task;
136
150
  timerId = setTimeout(() => {
137
151
  signal?.removeEventListener("abort", onAbort);
138
152
  r();
139
- }, ms || 0);
153
+ }, getMs(ms || 0));
140
154
  });
141
155
  };
142
156
  const run2 = (left) => {
@@ -169,7 +183,7 @@ var Task;
169
183
  timerId = setTimeout(() => {
170
184
  signal?.removeEventListener("abort", onAbort);
171
185
  r();
172
- }, ms || 0);
186
+ }, getMs(ms || 0));
173
187
  });
174
188
  };
175
189
  const run2 = (attempt, lastValue) => {
@@ -185,7 +199,39 @@ var Task;
185
199
  };
186
200
  return run2(1);
187
201
  });
188
- Task2.race = (tasks) => (0, Task2.from)((signal) => Promise.race(tasks.map((t) => toPromise(t, signal))));
202
+ Task2.race = (tasks) => {
203
+ if (tasks.length === 0) {
204
+ return () => Deferred.fromPromise(new Promise(() => {
205
+ }));
206
+ }
207
+ return (0, Task2.from)((outerSignal) => {
208
+ const controllers = tasks.map(() => new AbortController());
209
+ const onOuterAbort = () => {
210
+ for (const ctrl of controllers) ctrl.abort();
211
+ };
212
+ if (outerSignal) {
213
+ if (outerSignal.aborted) {
214
+ onOuterAbort();
215
+ } else {
216
+ outerSignal.addEventListener("abort", onOuterAbort, { once: true });
217
+ }
218
+ }
219
+ const promises = tasks.map((task, idx) => {
220
+ const ctrl = controllers[idx];
221
+ return toPromise(task, ctrl.signal).then((result) => {
222
+ for (let i = 0; i < controllers.length; i++) {
223
+ if (i !== idx) {
224
+ controllers[i].abort();
225
+ }
226
+ }
227
+ outerSignal?.removeEventListener("abort", onOuterAbort);
228
+ return result;
229
+ });
230
+ });
231
+ return Promise.race(promises);
232
+ });
233
+ };
234
+ Task2.sequence = (tasks) => (0, Task2.from)((signal) => Promise.all(tasks.map((t) => toPromise(t, signal))));
189
235
  Task2.sequential = (tasks) => (0, Task2.from)(async (signal) => {
190
236
  const results = [];
191
237
  for (const task of tasks) {
@@ -226,7 +272,7 @@ var Task;
226
272
  controller.abort();
227
273
  cleanUp();
228
274
  resolve2(Result.error(onTimeout()));
229
- }, ms);
275
+ }, getMs(ms));
230
276
  })
231
277
  ]);
232
278
  });
File without changes
@@ -0,0 +1,29 @@
1
+ // src/Types/Brand.ts
2
+ var Brand;
3
+ ((Brand2) => {
4
+ Brand2.wrap = () => (value) => value;
5
+ Brand2.unwrap = (branded) => branded;
6
+ })(Brand || (Brand = {}));
7
+
8
+ // src/Types/Duration.ts
9
+ var Duration;
10
+ ((Duration2) => {
11
+ const wrap = Brand.wrap();
12
+ Duration2.milliseconds = (ms) => wrap(ms);
13
+ Duration2.seconds = (s) => wrap(s * 1e3);
14
+ Duration2.minutes = (m) => wrap(m * 60 * 1e3);
15
+ Duration2.hours = (h) => wrap(h * 60 * 60 * 1e3);
16
+ Duration2.days = (d) => wrap(d * 24 * 60 * 60 * 1e3);
17
+ Duration2.toMilliseconds = (d) => Brand.unwrap(d);
18
+ Duration2.toSeconds = (d) => Brand.unwrap(d) / 1e3;
19
+ Duration2.toMinutes = (d) => Brand.unwrap(d) / (60 * 1e3);
20
+ Duration2.toHours = (d) => Brand.unwrap(d) / (60 * 60 * 1e3);
21
+ Duration2.toDays = (d) => Brand.unwrap(d) / (24 * 60 * 60 * 1e3);
22
+ Duration2.add = (other) => (self) => wrap(Brand.unwrap(self) + Brand.unwrap(other));
23
+ Duration2.subtract = (other) => (self) => wrap(Brand.unwrap(self) - Brand.unwrap(other));
24
+ })(Duration || (Duration = {}));
25
+
26
+ export {
27
+ Brand,
28
+ Duration
29
+ };
@@ -3,7 +3,7 @@ import {
3
3
  Maybe,
4
4
  Result,
5
5
  Task
6
- } from "./chunk-TK5ZCGP2.mjs";
6
+ } from "./chunk-GSTKY7MF.mjs";
7
7
  import {
8
8
  isNonEmptyList
9
9
  } from "./chunk-DBIC62UV.mjs";
@@ -65,6 +65,40 @@ var Arr;
65
65
  }
66
66
  return [pass, fail];
67
67
  };
68
+ Arr2.compact = (data) => {
69
+ const result = [];
70
+ for (const item of data) {
71
+ if (item.kind === "Some") {
72
+ result.push(item.value);
73
+ }
74
+ }
75
+ return result;
76
+ };
77
+ Arr2.separate = (data) => {
78
+ const errors = [];
79
+ const successes = [];
80
+ for (const item of data) {
81
+ if (item.kind === "Ok") {
82
+ successes.push(item.value);
83
+ } else {
84
+ errors.push(item.error);
85
+ }
86
+ }
87
+ return [errors, successes];
88
+ };
89
+ Arr2.partitionMap = (f) => (data) => {
90
+ const errors = [];
91
+ const successes = [];
92
+ for (const item of data) {
93
+ const mapped = f(item);
94
+ if (mapped.kind === "Ok") {
95
+ successes.push(mapped.value);
96
+ } else {
97
+ errors.push(mapped.error);
98
+ }
99
+ }
100
+ return [errors, successes];
101
+ };
68
102
  Arr2.groupBy = (f) => (data) => {
69
103
  const result = {};
70
104
  for (const a of data) {
@@ -596,6 +630,13 @@ var Str;
596
630
  return isNaN(n) ? Maybe.none() : Maybe.some(n);
597
631
  }
598
632
  };
633
+ Str2.parseJson = (s) => {
634
+ try {
635
+ return Result.ok(JSON.parse(s));
636
+ } catch (e) {
637
+ return Result.error(e);
638
+ }
639
+ };
599
640
  })(Str || (Str = {}));
600
641
 
601
642
  // src/Utils/Uniq.ts
package/dist/core.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- import { M as Maybe, W as WithValue, c as WithLog, D as Deferred, R as Result, d as WithKind, e as WithError, f as RetryOptions, g as TimeoutOptions, h as WithTimeout, i as WithMinInterval, j as WithCooldown, k as WithConcurrency, l as WithSize, m as WithMs, n as WithN, T as Task, o as WithErrors, p as WithFirst, q as WithSecond } from './Task-CJZfcOkO.mjs';
2
- export { E as Equality, a as Error, N as None, O as Ok, b as Ordering, S as Some } from './Task-CJZfcOkO.mjs';
3
- import { N as NonEmptyList } from './NonEmptyList-BlGFjor5.mjs';
1
+ import { M as Maybe, W as WithValue, c as WithLog, D as Deferred, R as Result, d as WithKind, e as WithError, f as RetryOptions, g as TimeoutOptions, h as WithTimeout, i as WithMinInterval, j as WithCooldown, k as WithConcurrency, l as WithSize, m as WithMs, n as WithN, T as Task, o as WithErrors, p as WithFirst, q as WithSecond } from './Task-5na0QzS4.mjs';
2
+ export { E as Equality, a as Error, N as None, O as Ok, b as Ordering, S as Some } from './Task-5na0QzS4.mjs';
3
+ import { NonEmptyList } from './types.mjs';
4
4
 
5
5
  /**
6
6
  * A type that can combine two values of type `A` into one, with a neutral starting value.
@@ -1984,6 +1984,25 @@ declare namespace TaskResult {
1984
1984
  * Creates a failed TaskResult with the given error.
1985
1985
  */
1986
1986
  const err: <E, A>(error: E) => TaskResult<E, A>;
1987
+ /**
1988
+ * Creates a TaskResult from a nullable value.
1989
+ * Returns Ok if the value is not null or undefined, error from onNull otherwise.
1990
+ */
1991
+ const fromNullable: <E>(onNull: () => E) => <A>(value: A | null | undefined) => TaskResult<E, A>;
1992
+ /**
1993
+ * Creates a TaskResult from a Maybe.
1994
+ * Some becomes Ok, None becomes error from onNone.
1995
+ */
1996
+ const fromMaybe: <E>(onNone: () => E) => <A>(maybe: Maybe<A>) => TaskResult<E, A>;
1997
+ /**
1998
+ * Lifts a Result into a TaskResult.
1999
+ */
2000
+ const fromResult: <E, A>(result: Result<E, A>) => TaskResult<E, A>;
2001
+ /**
2002
+ * Wraps a Promise-returning function of any arguments, returning a new function
2003
+ * that catches rejections and returns a TaskResult.
2004
+ */
2005
+ const fromThrowable: <Args extends readonly unknown[], A, E>(f: (...args: Args) => Promise<A>, onError: (e: unknown) => E) => (...args: Args) => TaskResult<E, A>;
1987
2006
  /**
1988
2007
  * Creates a TaskResult from a function that may throw.
1989
2008
  * Catches any errors and transforms them using the onError function.
@@ -2392,6 +2411,16 @@ declare namespace TaskMaybe {
2392
2411
  * Lifts an Option into a TaskMaybe.
2393
2412
  */
2394
2413
  const fromMaybe: <A>(option: Maybe<A>) => TaskMaybe<A>;
2414
+ /**
2415
+ * Creates a TaskMaybe from a nullable value.
2416
+ * Returns Some if the value is not null or undefined, None otherwise.
2417
+ */
2418
+ const fromNullable: <A>(value: A | null | undefined) => TaskMaybe<A>;
2419
+ /**
2420
+ * Creates a TaskMaybe from a Result.
2421
+ * Ok becomes Some, Error becomes None (the error value is discarded).
2422
+ */
2423
+ const fromResult: <E, A>(result: Result<E, A>) => TaskMaybe<A>;
2395
2424
  /**
2396
2425
  * Lifts a Task into a TaskMaybe by wrapping its result in Some.
2397
2426
  */
@@ -2561,6 +2590,30 @@ declare namespace Validation {
2561
2590
  * ```
2562
2591
  */
2563
2592
  const fromPredicate: <E, A>(pred: (a: A) => boolean, onFalse: (a: A) => E) => (a: A) => Validation<E, A>;
2593
+ /**
2594
+ * Creates a Validation from a nullable value.
2595
+ * If the value is null or undefined, returns Invalid with the error from onNull.
2596
+ * Otherwise, returns Valid.
2597
+ *
2598
+ * @example
2599
+ * ```ts
2600
+ * pipe(null, Validation.fromNullable(() => "is null")); // Invalid(["is null"])
2601
+ * pipe(42, Validation.fromNullable(() => "is null")); // Valid(42)
2602
+ * ```
2603
+ */
2604
+ const fromNullable: <E>(onNull: () => E) => <A>(value: A | null | undefined) => Validation<E, A>;
2605
+ /**
2606
+ * Creates a Validation from a Maybe.
2607
+ * If the Maybe is None, returns Invalid with the error from onNone.
2608
+ * Otherwise, returns Valid.
2609
+ *
2610
+ * @example
2611
+ * ```ts
2612
+ * pipe(Maybe.none(), Validation.fromMaybe(() => "is none")); // Invalid(["is none"])
2613
+ * pipe(Maybe.some(42), Validation.fromMaybe(() => "is none")); // Valid(42)
2614
+ * ```
2615
+ */
2616
+ const fromMaybe: <E>(onNone: () => E) => <A>(maybe: Maybe<A>) => Validation<E, A>;
2564
2617
  /**
2565
2618
  * Transforms the success value inside a Validation.
2566
2619
  *
@@ -2794,6 +2847,22 @@ declare namespace TaskValidation {
2794
2847
  * Lifts a Validation into a TaskValidation.
2795
2848
  */
2796
2849
  const fromValidation: <E, A>(validation: Validation<E, A>) => TaskValidation<E, A>;
2850
+ /**
2851
+ * Creates a TaskValidation from a nullable value.
2852
+ * If the value is null or undefined, returns Invalid with the error from onNull.
2853
+ * Otherwise, returns Valid.
2854
+ */
2855
+ const fromNullable: <E>(onNull: () => E) => <A>(value: A | null | undefined) => TaskValidation<E, A>;
2856
+ /**
2857
+ * Creates a TaskValidation from a Maybe.
2858
+ * Some becomes Valid, None becomes Invalid with the error from onNone.
2859
+ */
2860
+ const fromMaybe: <E>(onNone: () => E) => <A>(maybe: Maybe<A>) => TaskValidation<E, A>;
2861
+ /**
2862
+ * Creates a TaskValidation from a Result.
2863
+ * Ok becomes Valid, Error(e) becomes Invalid([e]).
2864
+ */
2865
+ const fromResult: <E, A>(result: Result<E, A>) => TaskValidation<E, A>;
2797
2866
  /**
2798
2867
  * Creates a TaskValidation from a Promise-returning function.
2799
2868
  * Catches any errors and transforms them using the onError function.