@nlozgachev/pipelined 0.25.0 → 0.27.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.
@@ -249,6 +249,32 @@ declare namespace Result {
249
249
  * ```
250
250
  */
251
251
  const tap: <E, A>(f: (a: A) => void) => (data: Result<E, A>) => Result<E, A>;
252
+ /**
253
+ * Executes a side effect on the error value without changing the Result.
254
+ * Useful for logging or reporting errors.
255
+ *
256
+ * @example
257
+ * ```ts
258
+ * pipe(
259
+ * Result.err("not found"),
260
+ * Result.tapError(e => console.error("validation failed:", e)),
261
+ * Result.chain(save),
262
+ * )
263
+ * ```
264
+ */
265
+ const tapError: <E, A>(f: (e: E) => void) => (data: Result<E, A>) => Result<E, A>;
266
+ /**
267
+ * Creates a Result from a predicate applied to a value.
268
+ * Returns Ok if the predicate passes, Err from onFalse otherwise.
269
+ *
270
+ * @example
271
+ * ```ts
272
+ * pipe(5, Result.fromPredicate(n => n > 0, n => `${n} is not positive`)); // Ok(5)
273
+ * pipe(-1, Result.fromPredicate(n => n > 0, n => `${n} is not positive`)); // Err("-1 is not positive")
274
+ * pipe("", Result.fromPredicate(s => s.length > 0, () => "empty string")); // Err("empty string")
275
+ * ```
276
+ */
277
+ const fromPredicate: <E, A>(pred: (a: A) => boolean, onFalse: (a: A) => E) => (a: A) => Result<E, A>;
252
278
  /**
253
279
  * Recovers from an error by providing a fallback Result.
254
280
  * The fallback can produce a different success type, widening the result to `Result<E, A | B>`.
@@ -346,6 +372,20 @@ declare namespace Maybe {
346
372
  * Returns None if undefined, Some otherwise.
347
373
  */
348
374
  const fromUndefined: <A>(value: A | undefined) => Maybe<A>;
375
+ /**
376
+ * Creates a Maybe from a predicate applied to a value.
377
+ * Returns Some if the predicate passes, None otherwise.
378
+ *
379
+ * @example
380
+ * ```ts
381
+ * Maybe.fromPredicate((n: number) => n >= 18)(21); // Some(21)
382
+ * Maybe.fromPredicate((n: number) => n >= 18)(15); // None
383
+ *
384
+ * pipe("hello", Maybe.fromPredicate((s: string) => s.length > 0)); // Some("hello")
385
+ * pipe("", Maybe.fromPredicate((s: string) => s.length > 0)); // None
386
+ * ```
387
+ */
388
+ const fromPredicate: <A>(pred: (a: A) => boolean) => (a: A) => Maybe<A>;
349
389
  /**
350
390
  * Converts an Maybe to a Result.
351
391
  * Some becomes Ok, None becomes Err with the provided error.
@@ -557,6 +597,17 @@ declare namespace Task {
557
597
  * ```
558
598
  */
559
599
  const from: <A>(f: (signal?: AbortSignal) => Promise<A>) => Task<A>;
600
+ /**
601
+ * Creates a Task from a lazy synchronous thunk.
602
+ * Unlike `Task.resolve(f())`, `fromSync` does not evaluate `f` until the Task is called.
603
+ *
604
+ * @example
605
+ * ```ts
606
+ * const t = Task.fromSync(() => Date.now()); // Date.now() not called yet
607
+ * const ts = await t(); // called here, every time
608
+ * ```
609
+ */
610
+ const fromSync: <A>(f: () => A) => Task<A>;
560
611
  /**
561
612
  * Transforms the value inside a Task.
562
613
  *
@@ -249,6 +249,32 @@ declare namespace Result {
249
249
  * ```
250
250
  */
251
251
  const tap: <E, A>(f: (a: A) => void) => (data: Result<E, A>) => Result<E, A>;
252
+ /**
253
+ * Executes a side effect on the error value without changing the Result.
254
+ * Useful for logging or reporting errors.
255
+ *
256
+ * @example
257
+ * ```ts
258
+ * pipe(
259
+ * Result.err("not found"),
260
+ * Result.tapError(e => console.error("validation failed:", e)),
261
+ * Result.chain(save),
262
+ * )
263
+ * ```
264
+ */
265
+ const tapError: <E, A>(f: (e: E) => void) => (data: Result<E, A>) => Result<E, A>;
266
+ /**
267
+ * Creates a Result from a predicate applied to a value.
268
+ * Returns Ok if the predicate passes, Err from onFalse otherwise.
269
+ *
270
+ * @example
271
+ * ```ts
272
+ * pipe(5, Result.fromPredicate(n => n > 0, n => `${n} is not positive`)); // Ok(5)
273
+ * pipe(-1, Result.fromPredicate(n => n > 0, n => `${n} is not positive`)); // Err("-1 is not positive")
274
+ * pipe("", Result.fromPredicate(s => s.length > 0, () => "empty string")); // Err("empty string")
275
+ * ```
276
+ */
277
+ const fromPredicate: <E, A>(pred: (a: A) => boolean, onFalse: (a: A) => E) => (a: A) => Result<E, A>;
252
278
  /**
253
279
  * Recovers from an error by providing a fallback Result.
254
280
  * The fallback can produce a different success type, widening the result to `Result<E, A | B>`.
@@ -346,6 +372,20 @@ declare namespace Maybe {
346
372
  * Returns None if undefined, Some otherwise.
347
373
  */
348
374
  const fromUndefined: <A>(value: A | undefined) => Maybe<A>;
375
+ /**
376
+ * Creates a Maybe from a predicate applied to a value.
377
+ * Returns Some if the predicate passes, None otherwise.
378
+ *
379
+ * @example
380
+ * ```ts
381
+ * Maybe.fromPredicate((n: number) => n >= 18)(21); // Some(21)
382
+ * Maybe.fromPredicate((n: number) => n >= 18)(15); // None
383
+ *
384
+ * pipe("hello", Maybe.fromPredicate((s: string) => s.length > 0)); // Some("hello")
385
+ * pipe("", Maybe.fromPredicate((s: string) => s.length > 0)); // None
386
+ * ```
387
+ */
388
+ const fromPredicate: <A>(pred: (a: A) => boolean) => (a: A) => Maybe<A>;
349
389
  /**
350
390
  * Converts an Maybe to a Result.
351
391
  * Some becomes Ok, None becomes Err with the provided error.
@@ -557,6 +597,17 @@ declare namespace Task {
557
597
  * ```
558
598
  */
559
599
  const from: <A>(f: (signal?: AbortSignal) => Promise<A>) => Task<A>;
600
+ /**
601
+ * Creates a Task from a lazy synchronous thunk.
602
+ * Unlike `Task.resolve(f())`, `fromSync` does not evaluate `f` until the Task is called.
603
+ *
604
+ * @example
605
+ * ```ts
606
+ * const t = Task.fromSync(() => Date.now()); // Date.now() not called yet
607
+ * const ts = await t(); // called here, every time
608
+ * ```
609
+ */
610
+ const fromSync: <A>(f: () => A) => Task<A>;
560
611
  /**
561
612
  * Transforms the value inside a Task.
562
613
  *
@@ -20,6 +20,7 @@ var Maybe;
20
20
  Maybe2.toNullable = (data) => (0, Maybe2.isSome)(data) ? data.value : null;
21
21
  Maybe2.toUndefined = (data) => (0, Maybe2.isSome)(data) ? data.value : void 0;
22
22
  Maybe2.fromUndefined = (value) => value === void 0 ? (0, Maybe2.none)() : (0, Maybe2.some)(value);
23
+ Maybe2.fromPredicate = (pred) => (a) => pred(a) ? (0, Maybe2.some)(a) : (0, Maybe2.none)();
23
24
  Maybe2.toResult = (onNone) => (data) => (0, Maybe2.isSome)(data) ? Result.ok(data.value) : Result.err(onNone());
24
25
  Maybe2.fromResult = (data) => Result.isOk(data) ? (0, Maybe2.some)(data.value) : (0, Maybe2.none)();
25
26
  Maybe2.map = (f) => (data) => (0, Maybe2.isSome)(data) ? (0, Maybe2.some)(f(data.value)) : data;
@@ -60,6 +61,11 @@ var Result;
60
61
  if ((0, Result2.isOk)(data)) f(data.value);
61
62
  return data;
62
63
  };
64
+ Result2.tapError = (f) => (data) => {
65
+ if ((0, Result2.isErr)(data)) f(data.error);
66
+ return data;
67
+ };
68
+ Result2.fromPredicate = (pred, onFalse) => (a) => pred(a) ? (0, Result2.ok)(a) : (0, Result2.err)(onFalse(a));
63
69
  Result2.recover = (fallback) => (data) => (0, Result2.isOk)(data) ? data : fallback(data.error);
64
70
  Result2.recoverUnless = (blockedErr, fallback) => (data) => (0, Result2.isErr)(data) && data.error !== blockedErr ? fallback() : data;
65
71
  Result2.toMaybe = (data) => (0, Result2.isOk)(data) ? Maybe.some(data.value) : Maybe.none();
@@ -72,6 +78,7 @@ var Task;
72
78
  ((Task2) => {
73
79
  Task2.resolve = (value) => () => Deferred.fromPromise(Promise.resolve(value));
74
80
  Task2.from = (f) => (signal) => Deferred.fromPromise(f(signal));
81
+ Task2.fromSync = (f) => () => Deferred.fromPromise(Promise.resolve(f()));
75
82
  Task2.map = (f) => (data) => (0, Task2.from)((signal) => toPromise(data, signal).then(f));
76
83
  Task2.chain = (f) => (data) => (0, Task2.from)((signal) => toPromise(data, signal).then((a) => toPromise(f(a), signal)));
77
84
  Task2.ap = (arg) => (data) => (0, Task2.from)(
@@ -3,7 +3,7 @@ import {
3
3
  Maybe,
4
4
  Result,
5
5
  Task
6
- } from "./chunk-2DPG2RDB.mjs";
6
+ } from "./chunk-HHCRWQYN.mjs";
7
7
  import {
8
8
  isNonEmptyList
9
9
  } from "./chunk-DBIC62UV.mjs";
@@ -35,6 +35,12 @@ var Arr;
35
35
  for (let i = 0; i < n; i++) result[i] = f(data[i]);
36
36
  return result;
37
37
  };
38
+ Arr2.mapWithIndex = (f) => (data) => {
39
+ const n = data.length;
40
+ const result = new Array(n);
41
+ for (let i = 0; i < n; i++) result[i] = f(i, data[i]);
42
+ return result;
43
+ };
38
44
  Arr2.filter = (predicate) => (data) => {
39
45
  const n = data.length;
40
46
  const result = [];
@@ -43,6 +49,14 @@ var Arr;
43
49
  }
44
50
  return result;
45
51
  };
52
+ Arr2.filterMap = (f) => (data) => {
53
+ const result = [];
54
+ for (let i = 0; i < data.length; i++) {
55
+ const mapped = f(data[i]);
56
+ if (mapped.kind === "Some") result.push(mapped.value);
57
+ }
58
+ return result;
59
+ };
46
60
  Arr2.partition = (predicate) => (data) => {
47
61
  const pass = [];
48
62
  const fail = [];
@@ -354,6 +368,12 @@ var Num;
354
368
  Num2.subtract = (b) => (a) => a - b;
355
369
  Num2.multiply = (b) => (a) => a * b;
356
370
  Num2.divide = (b) => (a) => a / b;
371
+ Num2.abs = (n) => Math.abs(n);
372
+ Num2.negate = (n) => -n;
373
+ Num2.round = (n) => Math.round(n);
374
+ Num2.floor = (n) => Math.floor(n);
375
+ Num2.ceil = (n) => Math.ceil(n);
376
+ Num2.remainder = (divisor) => (n) => n % divisor;
357
377
  })(Num || (Num = {}));
358
378
 
359
379
  // src/Utils/Rec.ts
@@ -471,12 +491,20 @@ var Str;
471
491
  Str2.split = (separator) => (s) => s.split(separator);
472
492
  Str2.trim = (s) => s.trim();
473
493
  Str2.includes = (substring) => (s) => s.includes(substring);
494
+ Str2.replace = (pattern, replacement) => (s) => s.replace(pattern, replacement);
495
+ Str2.replaceAll = (pattern, replacement) => (s) => s.replaceAll(pattern, replacement);
474
496
  Str2.startsWith = (prefix) => (s) => s.startsWith(prefix);
475
497
  Str2.endsWith = (suffix) => (s) => s.endsWith(suffix);
476
498
  Str2.toUpperCase = (s) => s.toUpperCase();
477
499
  Str2.toLowerCase = (s) => s.toLowerCase();
478
500
  Str2.lines = (s) => s.split(/\r?\n|\r/);
479
501
  Str2.words = (s) => s.trim().split(/\s+/).filter(Boolean);
502
+ Str2.isEmpty = (s) => s.length === 0;
503
+ Str2.isBlank = (s) => s.trim().length === 0;
504
+ Str2.length = (s) => s.length;
505
+ Str2.slice = (start, end) => (s) => s.slice(start, end);
506
+ Str2.padStart = (maxLength, fillString) => (s) => s.padStart(maxLength, fillString);
507
+ Str2.padEnd = (maxLength, fillString) => (s) => s.padEnd(maxLength, fillString);
480
508
  Str2.parse = {
481
509
  /**
482
510
  * Parses a string as an integer (base 10). Returns `None` if the result is `NaN`.
@@ -3,7 +3,7 @@ import {
3
3
  Maybe,
4
4
  Result,
5
5
  Task
6
- } from "./chunk-2DPG2RDB.mjs";
6
+ } from "./chunk-HHCRWQYN.mjs";
7
7
 
8
8
  // src/Core/Lens.ts
9
9
  var Lens;
@@ -1092,6 +1092,8 @@ var RemoteData;
1092
1092
  RemoteData2.recover = (fallback) => (data) => (0, RemoteData2.isFailure)(data) ? fallback(data.error) : data;
1093
1093
  RemoteData2.toMaybe = (data) => (0, RemoteData2.isSuccess)(data) ? Maybe.some(data.value) : Maybe.none();
1094
1094
  RemoteData2.toResult = (onNotReady) => (data) => (0, RemoteData2.isSuccess)(data) ? Result.ok(data.value) : Result.err((0, RemoteData2.isFailure)(data) ? data.error : onNotReady());
1095
+ RemoteData2.fromResult = (data) => Result.isOk(data) ? (0, RemoteData2.success)(data.value) : (0, RemoteData2.failure)(data.error);
1096
+ RemoteData2.fromMaybe = (onNone) => (data) => Maybe.isSome(data) ? (0, RemoteData2.success)(data.value) : (0, RemoteData2.failure)(onNone());
1095
1097
  })(RemoteData || (RemoteData = {}));
1096
1098
 
1097
1099
  // src/Core/Resource.ts
@@ -1205,6 +1207,7 @@ var TaskResult;
1205
1207
  )(data);
1206
1208
  TaskResult2.getOrElse = (defaultValue) => (data) => Task.map(Result.getOrElse(defaultValue))(data);
1207
1209
  TaskResult2.tap = (f) => (data) => Task.map(Result.tap(f))(data);
1210
+ TaskResult2.tapError = (f) => (data) => Task.map(Result.tapError(f))(data);
1208
1211
  })(TaskResult || (TaskResult = {}));
1209
1212
 
1210
1213
  // src/Core/Validation.ts
package/dist/core.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { M as Maybe, W as WithValue, a as WithLog, D as Deferred, R as Result, b as WithKind, c as WithError, d as RetryOptions, e as TimeoutOptions, f as WithTimeout, g as WithMinInterval, h as WithCooldown, i as WithConcurrency, j as WithSize, k as WithMs, l as WithN, T as Task, m as WithErrors, n as WithFirst, o as WithSecond } from './Task-C7M6gLYu.mjs';
2
- export { E as Err, N as None, O as Ok, S as Some } from './Task-C7M6gLYu.mjs';
1
+ import { M as Maybe, W as WithValue, a as WithLog, D as Deferred, R as Result, b as WithKind, c as WithError, d as RetryOptions, e as TimeoutOptions, f as WithTimeout, g as WithMinInterval, h as WithCooldown, i as WithConcurrency, j as WithSize, k as WithMs, l as WithN, T as Task, m as WithErrors, n as WithFirst, o as WithSecond } from './Task-vQb3-puQ.mjs';
2
+ export { E as Err, N as None, O as Ok, S as Some } from './Task-vQb3-puQ.mjs';
3
3
  import { N as NonEmptyList } from './NonEmptyList-BlGFjor5.mjs';
4
4
 
5
5
  /** Keys of T for which undefined is assignable (i.e. optional fields). */
@@ -1644,6 +1644,28 @@ declare namespace RemoteData {
1644
1644
  * ```
1645
1645
  */
1646
1646
  const toResult: <E>(onNotReady: () => E) => <A>(data: RemoteData<E, A>) => Result<E, A>;
1647
+ /**
1648
+ * Converts a Result to a RemoteData.
1649
+ * Ok becomes Success, Err becomes Failure.
1650
+ *
1651
+ * @example
1652
+ * ```ts
1653
+ * const result = await TaskResult.tryCatch(fetchUser, String)();
1654
+ * setState(RemoteData.fromResult(result)); // Success(user) or Failure(msg)
1655
+ * ```
1656
+ */
1657
+ const fromResult: <E, A>(data: Result<E, A>) => RemoteData<E, A>;
1658
+ /**
1659
+ * Converts a Maybe to a RemoteData.
1660
+ * Some becomes Success, None becomes Failure using the onNone error producer.
1661
+ *
1662
+ * @example
1663
+ * ```ts
1664
+ * pipe(Maybe.some(user), RemoteData.fromMaybe(() => "not found")); // Success(user)
1665
+ * pipe(Maybe.none(), RemoteData.fromMaybe(() => "not found")); // Failure("not found")
1666
+ * ```
1667
+ */
1668
+ const fromMaybe: <E>(onNone: () => E) => <A>(data: Maybe<A>) => RemoteData<E, A>;
1647
1669
  }
1648
1670
 
1649
1671
  /**
@@ -1723,6 +1745,20 @@ declare namespace TaskResult {
1723
1745
  * Useful for logging or debugging.
1724
1746
  */
1725
1747
  const tap: <E, A>(f: (a: A) => void) => (data: TaskResult<E, A>) => TaskResult<E, A>;
1748
+ /**
1749
+ * Executes a side effect on the error value without changing the TaskResult.
1750
+ * Useful for logging or reporting async errors.
1751
+ *
1752
+ * @example
1753
+ * ```ts
1754
+ * pipe(
1755
+ * fetchUser(id),
1756
+ * TaskResult.tapError(e => console.error("fetch failed:", e)),
1757
+ * TaskResult.chain(saveToCache),
1758
+ * )
1759
+ * ```
1760
+ */
1761
+ const tapError: <E, A>(f: (e: E) => void) => (data: TaskResult<E, A>) => TaskResult<E, A>;
1726
1762
  }
1727
1763
 
1728
1764
  /**
package/dist/core.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { M as Maybe, W as WithValue, a as WithLog, D as Deferred, R as Result, b as WithKind, c as WithError, d as RetryOptions, e as TimeoutOptions, f as WithTimeout, g as WithMinInterval, h as WithCooldown, i as WithConcurrency, j as WithSize, k as WithMs, l as WithN, T as Task, m as WithErrors, n as WithFirst, o as WithSecond } from './Task-BbTMuIby.js';
2
- export { E as Err, N as None, O as Ok, S as Some } from './Task-BbTMuIby.js';
1
+ import { M as Maybe, W as WithValue, a as WithLog, D as Deferred, R as Result, b as WithKind, c as WithError, d as RetryOptions, e as TimeoutOptions, f as WithTimeout, g as WithMinInterval, h as WithCooldown, i as WithConcurrency, j as WithSize, k as WithMs, l as WithN, T as Task, m as WithErrors, n as WithFirst, o as WithSecond } from './Task-C8Pgm7EX.js';
2
+ export { E as Err, N as None, O as Ok, S as Some } from './Task-C8Pgm7EX.js';
3
3
  import { N as NonEmptyList } from './NonEmptyList-BlGFjor5.js';
4
4
 
5
5
  /** Keys of T for which undefined is assignable (i.e. optional fields). */
@@ -1644,6 +1644,28 @@ declare namespace RemoteData {
1644
1644
  * ```
1645
1645
  */
1646
1646
  const toResult: <E>(onNotReady: () => E) => <A>(data: RemoteData<E, A>) => Result<E, A>;
1647
+ /**
1648
+ * Converts a Result to a RemoteData.
1649
+ * Ok becomes Success, Err becomes Failure.
1650
+ *
1651
+ * @example
1652
+ * ```ts
1653
+ * const result = await TaskResult.tryCatch(fetchUser, String)();
1654
+ * setState(RemoteData.fromResult(result)); // Success(user) or Failure(msg)
1655
+ * ```
1656
+ */
1657
+ const fromResult: <E, A>(data: Result<E, A>) => RemoteData<E, A>;
1658
+ /**
1659
+ * Converts a Maybe to a RemoteData.
1660
+ * Some becomes Success, None becomes Failure using the onNone error producer.
1661
+ *
1662
+ * @example
1663
+ * ```ts
1664
+ * pipe(Maybe.some(user), RemoteData.fromMaybe(() => "not found")); // Success(user)
1665
+ * pipe(Maybe.none(), RemoteData.fromMaybe(() => "not found")); // Failure("not found")
1666
+ * ```
1667
+ */
1668
+ const fromMaybe: <E>(onNone: () => E) => <A>(data: Maybe<A>) => RemoteData<E, A>;
1647
1669
  }
1648
1670
 
1649
1671
  /**
@@ -1723,6 +1745,20 @@ declare namespace TaskResult {
1723
1745
  * Useful for logging or debugging.
1724
1746
  */
1725
1747
  const tap: <E, A>(f: (a: A) => void) => (data: TaskResult<E, A>) => TaskResult<E, A>;
1748
+ /**
1749
+ * Executes a side effect on the error value without changing the TaskResult.
1750
+ * Useful for logging or reporting async errors.
1751
+ *
1752
+ * @example
1753
+ * ```ts
1754
+ * pipe(
1755
+ * fetchUser(id),
1756
+ * TaskResult.tapError(e => console.error("fetch failed:", e)),
1757
+ * TaskResult.chain(saveToCache),
1758
+ * )
1759
+ * ```
1760
+ */
1761
+ const tapError: <E, A>(f: (e: E) => void) => (data: TaskResult<E, A>) => TaskResult<E, A>;
1726
1762
  }
1727
1763
 
1728
1764
  /**
package/dist/core.js CHANGED
@@ -126,6 +126,11 @@ var Result;
126
126
  if ((0, Result2.isOk)(data)) f(data.value);
127
127
  return data;
128
128
  };
129
+ Result2.tapError = (f) => (data) => {
130
+ if ((0, Result2.isErr)(data)) f(data.error);
131
+ return data;
132
+ };
133
+ Result2.fromPredicate = (pred, onFalse) => (a) => pred(a) ? (0, Result2.ok)(a) : (0, Result2.err)(onFalse(a));
129
134
  Result2.recover = (fallback) => (data) => (0, Result2.isOk)(data) ? data : fallback(data.error);
130
135
  Result2.recoverUnless = (blockedErr, fallback) => (data) => (0, Result2.isErr)(data) && data.error !== blockedErr ? fallback() : data;
131
136
  Result2.toMaybe = (data) => (0, Result2.isOk)(data) ? Maybe.some(data.value) : Maybe.none();
@@ -144,6 +149,7 @@ var Maybe;
144
149
  Maybe2.toNullable = (data) => (0, Maybe2.isSome)(data) ? data.value : null;
145
150
  Maybe2.toUndefined = (data) => (0, Maybe2.isSome)(data) ? data.value : void 0;
146
151
  Maybe2.fromUndefined = (value) => value === void 0 ? (0, Maybe2.none)() : (0, Maybe2.some)(value);
152
+ Maybe2.fromPredicate = (pred) => (a) => pred(a) ? (0, Maybe2.some)(a) : (0, Maybe2.none)();
147
153
  Maybe2.toResult = (onNone) => (data) => (0, Maybe2.isSome)(data) ? Result.ok(data.value) : Result.err(onNone());
148
154
  Maybe2.fromResult = (data) => Result.isOk(data) ? (0, Maybe2.some)(data.value) : (0, Maybe2.none)();
149
155
  Maybe2.map = (f) => (data) => (0, Maybe2.isSome)(data) ? (0, Maybe2.some)(f(data.value)) : data;
@@ -1198,6 +1204,8 @@ var RemoteData;
1198
1204
  RemoteData2.recover = (fallback) => (data) => (0, RemoteData2.isFailure)(data) ? fallback(data.error) : data;
1199
1205
  RemoteData2.toMaybe = (data) => (0, RemoteData2.isSuccess)(data) ? Maybe.some(data.value) : Maybe.none();
1200
1206
  RemoteData2.toResult = (onNotReady) => (data) => (0, RemoteData2.isSuccess)(data) ? Result.ok(data.value) : Result.err((0, RemoteData2.isFailure)(data) ? data.error : onNotReady());
1207
+ RemoteData2.fromResult = (data) => Result.isOk(data) ? (0, RemoteData2.success)(data.value) : (0, RemoteData2.failure)(data.error);
1208
+ RemoteData2.fromMaybe = (onNone) => (data) => Maybe.isSome(data) ? (0, RemoteData2.success)(data.value) : (0, RemoteData2.failure)(onNone());
1201
1209
  })(RemoteData || (RemoteData = {}));
1202
1210
 
1203
1211
  // src/Core/Task.ts
@@ -1206,6 +1214,7 @@ var Task;
1206
1214
  ((Task2) => {
1207
1215
  Task2.resolve = (value) => () => Deferred.fromPromise(Promise.resolve(value));
1208
1216
  Task2.from = (f) => (signal) => Deferred.fromPromise(f(signal));
1217
+ Task2.fromSync = (f) => () => Deferred.fromPromise(Promise.resolve(f()));
1209
1218
  Task2.map = (f) => (data) => (0, Task2.from)((signal) => toPromise(data, signal).then(f));
1210
1219
  Task2.chain = (f) => (data) => (0, Task2.from)((signal) => toPromise(data, signal).then((a) => toPromise(f(a), signal)));
1211
1220
  Task2.ap = (arg) => (data) => (0, Task2.from)(
@@ -1407,6 +1416,7 @@ var TaskResult;
1407
1416
  )(data);
1408
1417
  TaskResult2.getOrElse = (defaultValue) => (data) => Task.map(Result.getOrElse(defaultValue))(data);
1409
1418
  TaskResult2.tap = (f) => (data) => Task.map(Result.tap(f))(data);
1419
+ TaskResult2.tapError = (f) => (data) => Task.map(Result.tapError(f))(data);
1410
1420
  })(TaskResult || (TaskResult = {}));
1411
1421
 
1412
1422
  // src/Core/Validation.ts
package/dist/core.mjs CHANGED
@@ -15,13 +15,13 @@ import {
15
15
  These,
16
16
  Tuple,
17
17
  Validation
18
- } from "./chunk-UFQE2J63.mjs";
18
+ } from "./chunk-YYVONF5X.mjs";
19
19
  import {
20
20
  Deferred,
21
21
  Maybe,
22
22
  Result,
23
23
  Task
24
- } from "./chunk-2DPG2RDB.mjs";
24
+ } from "./chunk-HHCRWQYN.mjs";
25
25
  export {
26
26
  Deferred,
27
27
  Lens,
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { and, compose, constFalse, constNull, constTrue, constUndefined, constVoid, constant, converge, curry, curry3, curry4, flip, flow, identity, juxt, memoize, memoizeWeak, not, on, once, or, pipe, tap, uncurry, uncurry3, uncurry4 } from './composition.mjs';
2
- export { D as Deferred, E as Err, M as Maybe, N as None, O as Ok, R as Result, S as Some, T as Task } from './Task-C7M6gLYu.mjs';
2
+ export { D as Deferred, E as Err, M as Maybe, N as None, O as Ok, R as Result, S as Some, T as Task } from './Task-vQb3-puQ.mjs';
3
3
  export { Failure, Invalid, Lens, Loading, Logged, NotAsked, Op, Optional, Predicate, Reader, Refinement, RemoteData, Resource, State, Success, TaskMaybe, TaskResult, TaskValidation, These, TheseBoth, TheseFirst, TheseSecond, Tuple, Valid, Validation } from './core.mjs';
4
4
  export { Brand } from './types.mjs';
5
5
  export { N as NonEmptyList, i as isNonEmptyList } from './NonEmptyList-BlGFjor5.mjs';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { and, compose, constFalse, constNull, constTrue, constUndefined, constVoid, constant, converge, curry, curry3, curry4, flip, flow, identity, juxt, memoize, memoizeWeak, not, on, once, or, pipe, tap, uncurry, uncurry3, uncurry4 } from './composition.js';
2
- export { D as Deferred, E as Err, M as Maybe, N as None, O as Ok, R as Result, S as Some, T as Task } from './Task-BbTMuIby.js';
2
+ export { D as Deferred, E as Err, M as Maybe, N as None, O as Ok, R as Result, S as Some, T as Task } from './Task-C8Pgm7EX.js';
3
3
  export { Failure, Invalid, Lens, Loading, Logged, NotAsked, Op, Optional, Predicate, Reader, Refinement, RemoteData, Resource, State, Success, TaskMaybe, TaskResult, TaskValidation, These, TheseBoth, TheseFirst, TheseSecond, Tuple, Valid, Validation } from './core.js';
4
4
  export { Brand } from './types.js';
5
5
  export { N as NonEmptyList, i as isNonEmptyList } from './NonEmptyList-BlGFjor5.js';
package/dist/index.js CHANGED
@@ -371,6 +371,11 @@ var Result;
371
371
  if ((0, Result2.isOk)(data)) f(data.value);
372
372
  return data;
373
373
  };
374
+ Result2.tapError = (f) => (data) => {
375
+ if ((0, Result2.isErr)(data)) f(data.error);
376
+ return data;
377
+ };
378
+ Result2.fromPredicate = (pred, onFalse) => (a) => pred(a) ? (0, Result2.ok)(a) : (0, Result2.err)(onFalse(a));
374
379
  Result2.recover = (fallback) => (data) => (0, Result2.isOk)(data) ? data : fallback(data.error);
375
380
  Result2.recoverUnless = (blockedErr, fallback) => (data) => (0, Result2.isErr)(data) && data.error !== blockedErr ? fallback() : data;
376
381
  Result2.toMaybe = (data) => (0, Result2.isOk)(data) ? Maybe.some(data.value) : Maybe.none();
@@ -389,6 +394,7 @@ var Maybe;
389
394
  Maybe2.toNullable = (data) => (0, Maybe2.isSome)(data) ? data.value : null;
390
395
  Maybe2.toUndefined = (data) => (0, Maybe2.isSome)(data) ? data.value : void 0;
391
396
  Maybe2.fromUndefined = (value) => value === void 0 ? (0, Maybe2.none)() : (0, Maybe2.some)(value);
397
+ Maybe2.fromPredicate = (pred) => (a) => pred(a) ? (0, Maybe2.some)(a) : (0, Maybe2.none)();
392
398
  Maybe2.toResult = (onNone) => (data) => (0, Maybe2.isSome)(data) ? Result.ok(data.value) : Result.err(onNone());
393
399
  Maybe2.fromResult = (data) => Result.isOk(data) ? (0, Maybe2.some)(data.value) : (0, Maybe2.none)();
394
400
  Maybe2.map = (f) => (data) => (0, Maybe2.isSome)(data) ? (0, Maybe2.some)(f(data.value)) : data;
@@ -1443,6 +1449,8 @@ var RemoteData;
1443
1449
  RemoteData2.recover = (fallback) => (data) => (0, RemoteData2.isFailure)(data) ? fallback(data.error) : data;
1444
1450
  RemoteData2.toMaybe = (data) => (0, RemoteData2.isSuccess)(data) ? Maybe.some(data.value) : Maybe.none();
1445
1451
  RemoteData2.toResult = (onNotReady) => (data) => (0, RemoteData2.isSuccess)(data) ? Result.ok(data.value) : Result.err((0, RemoteData2.isFailure)(data) ? data.error : onNotReady());
1452
+ RemoteData2.fromResult = (data) => Result.isOk(data) ? (0, RemoteData2.success)(data.value) : (0, RemoteData2.failure)(data.error);
1453
+ RemoteData2.fromMaybe = (onNone) => (data) => Maybe.isSome(data) ? (0, RemoteData2.success)(data.value) : (0, RemoteData2.failure)(onNone());
1446
1454
  })(RemoteData || (RemoteData = {}));
1447
1455
 
1448
1456
  // src/Core/Task.ts
@@ -1451,6 +1459,7 @@ var Task;
1451
1459
  ((Task2) => {
1452
1460
  Task2.resolve = (value) => () => Deferred.fromPromise(Promise.resolve(value));
1453
1461
  Task2.from = (f) => (signal) => Deferred.fromPromise(f(signal));
1462
+ Task2.fromSync = (f) => () => Deferred.fromPromise(Promise.resolve(f()));
1454
1463
  Task2.map = (f) => (data) => (0, Task2.from)((signal) => toPromise(data, signal).then(f));
1455
1464
  Task2.chain = (f) => (data) => (0, Task2.from)((signal) => toPromise(data, signal).then((a) => toPromise(f(a), signal)));
1456
1465
  Task2.ap = (arg) => (data) => (0, Task2.from)(
@@ -1652,6 +1661,7 @@ var TaskResult;
1652
1661
  )(data);
1653
1662
  TaskResult2.getOrElse = (defaultValue) => (data) => Task.map(Result.getOrElse(defaultValue))(data);
1654
1663
  TaskResult2.tap = (f) => (data) => Task.map(Result.tap(f))(data);
1664
+ TaskResult2.tapError = (f) => (data) => Task.map(Result.tapError(f))(data);
1655
1665
  })(TaskResult || (TaskResult = {}));
1656
1666
 
1657
1667
  // src/Core/Validation.ts
@@ -1862,6 +1872,12 @@ var Arr;
1862
1872
  for (let i = 0; i < n; i++) result[i] = f(data[i]);
1863
1873
  return result;
1864
1874
  };
1875
+ Arr2.mapWithIndex = (f) => (data) => {
1876
+ const n = data.length;
1877
+ const result = new Array(n);
1878
+ for (let i = 0; i < n; i++) result[i] = f(i, data[i]);
1879
+ return result;
1880
+ };
1865
1881
  Arr2.filter = (predicate) => (data) => {
1866
1882
  const n = data.length;
1867
1883
  const result = [];
@@ -1870,6 +1886,14 @@ var Arr;
1870
1886
  }
1871
1887
  return result;
1872
1888
  };
1889
+ Arr2.filterMap = (f) => (data) => {
1890
+ const result = [];
1891
+ for (let i = 0; i < data.length; i++) {
1892
+ const mapped = f(data[i]);
1893
+ if (mapped.kind === "Some") result.push(mapped.value);
1894
+ }
1895
+ return result;
1896
+ };
1873
1897
  Arr2.partition = (predicate) => (data) => {
1874
1898
  const pass = [];
1875
1899
  const fail = [];
@@ -2181,6 +2205,12 @@ var Num;
2181
2205
  Num2.subtract = (b) => (a) => a - b;
2182
2206
  Num2.multiply = (b) => (a) => a * b;
2183
2207
  Num2.divide = (b) => (a) => a / b;
2208
+ Num2.abs = (n) => Math.abs(n);
2209
+ Num2.negate = (n) => -n;
2210
+ Num2.round = (n) => Math.round(n);
2211
+ Num2.floor = (n) => Math.floor(n);
2212
+ Num2.ceil = (n) => Math.ceil(n);
2213
+ Num2.remainder = (divisor) => (n) => n % divisor;
2184
2214
  })(Num || (Num = {}));
2185
2215
 
2186
2216
  // src/Utils/Rec.ts
@@ -2298,12 +2328,20 @@ var Str;
2298
2328
  Str2.split = (separator) => (s) => s.split(separator);
2299
2329
  Str2.trim = (s) => s.trim();
2300
2330
  Str2.includes = (substring) => (s) => s.includes(substring);
2331
+ Str2.replace = (pattern, replacement) => (s) => s.replace(pattern, replacement);
2332
+ Str2.replaceAll = (pattern, replacement) => (s) => s.replaceAll(pattern, replacement);
2301
2333
  Str2.startsWith = (prefix) => (s) => s.startsWith(prefix);
2302
2334
  Str2.endsWith = (suffix) => (s) => s.endsWith(suffix);
2303
2335
  Str2.toUpperCase = (s) => s.toUpperCase();
2304
2336
  Str2.toLowerCase = (s) => s.toLowerCase();
2305
2337
  Str2.lines = (s) => s.split(/\r?\n|\r/);
2306
2338
  Str2.words = (s) => s.trim().split(/\s+/).filter(Boolean);
2339
+ Str2.isEmpty = (s) => s.length === 0;
2340
+ Str2.isBlank = (s) => s.trim().length === 0;
2341
+ Str2.length = (s) => s.length;
2342
+ Str2.slice = (start, end) => (s) => s.slice(start, end);
2343
+ Str2.padStart = (maxLength, fillString) => (s) => s.padStart(maxLength, fillString);
2344
+ Str2.padEnd = (maxLength, fillString) => (s) => s.padEnd(maxLength, fillString);
2307
2345
  Str2.parse = {
2308
2346
  /**
2309
2347
  * Parses a string as an integer (base 10). Returns `None` if the result is `NaN`.
package/dist/index.mjs CHANGED
@@ -44,7 +44,7 @@ import {
44
44
  These,
45
45
  Tuple,
46
46
  Validation
47
- } from "./chunk-UFQE2J63.mjs";
47
+ } from "./chunk-YYVONF5X.mjs";
48
48
  import {
49
49
  Arr,
50
50
  Dict,
@@ -52,13 +52,13 @@ import {
52
52
  Rec,
53
53
  Str,
54
54
  Uniq
55
- } from "./chunk-C3Z56PCR.mjs";
55
+ } from "./chunk-SBTMTAZF.mjs";
56
56
  import {
57
57
  Deferred,
58
58
  Maybe,
59
59
  Result,
60
60
  Task
61
- } from "./chunk-2DPG2RDB.mjs";
61
+ } from "./chunk-HHCRWQYN.mjs";
62
62
  import {
63
63
  Brand
64
64
  } from "./chunk-BYWKZLHM.mjs";
package/dist/utils.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { M as Maybe, R as Result, T as Task } from './Task-C7M6gLYu.mjs';
1
+ import { M as Maybe, R as Result, T as Task } from './Task-vQb3-puQ.mjs';
2
2
  import { N as NonEmptyList } from './NonEmptyList-BlGFjor5.mjs';
3
3
 
4
4
  /**
@@ -93,6 +93,18 @@ declare namespace Arr {
93
93
  * ```
94
94
  */
95
95
  const map: <A, B>(f: (a: A) => B) => (data: readonly A[]) => readonly B[];
96
+ /**
97
+ * Transforms each element using both its value and its zero-based index.
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * pipe(
102
+ * ["a", "b", "c"],
103
+ * Arr.mapWithIndex((i, s) => ({ position: i + 1, value: s }))
104
+ * ); // [{ position: 1, value: "a" }, { position: 2, value: "b" }, { position: 3, value: "c" }]
105
+ * ```
106
+ */
107
+ const mapWithIndex: <A, B>(f: (i: number, a: A) => B) => (data: readonly A[]) => readonly B[];
96
108
  /**
97
109
  * Filters elements that satisfy the predicate.
98
110
  *
@@ -102,6 +114,21 @@ declare namespace Arr {
102
114
  * ```
103
115
  */
104
116
  const filter: <A>(predicate: (a: A) => boolean) => (data: readonly A[]) => readonly A[];
117
+ /**
118
+ * Maps each element to a Maybe and collects only the Some values.
119
+ * Combines map and filter in a single pass.
120
+ *
121
+ * @example
122
+ * ```ts
123
+ * const parseNum = (s: string): Maybe<number> => {
124
+ * const n = Number(s);
125
+ * return isNaN(n) ? Maybe.none() : Maybe.some(n);
126
+ * };
127
+ *
128
+ * pipe(["1", "abc", "3"], Arr.filterMap(parseNum)); // [1, 3]
129
+ * ```
130
+ */
131
+ const filterMap: <A, B>(f: (a: A) => Maybe<B>) => (data: readonly A[]) => readonly B[];
105
132
  /**
106
133
  * Splits an array into two groups based on a predicate.
107
134
  * First group contains elements that satisfy the predicate,
@@ -840,6 +867,66 @@ declare namespace Num {
840
867
  * ```
841
868
  */
842
869
  const divide: (b: number) => (a: number) => number;
870
+ /**
871
+ * Returns the absolute value of a number.
872
+ *
873
+ * @example
874
+ * ```ts
875
+ * pipe(-5, Num.abs); // 5
876
+ * pipe(5, Num.abs); // 5
877
+ * ```
878
+ */
879
+ const abs: (n: number) => number;
880
+ /**
881
+ * Negates a number (arithmetic negation).
882
+ *
883
+ * @example
884
+ * ```ts
885
+ * pipe(5, Num.negate); // -5
886
+ * pipe(-5, Num.negate); // 5
887
+ * ```
888
+ */
889
+ const negate: (n: number) => number;
890
+ /**
891
+ * Rounds a number to the nearest integer.
892
+ *
893
+ * @example
894
+ * ```ts
895
+ * pipe(3.5, Num.round); // 4
896
+ * pipe(3.4, Num.round); // 3
897
+ * ```
898
+ */
899
+ const round: (n: number) => number;
900
+ /**
901
+ * Rounds a number down to the nearest integer.
902
+ *
903
+ * @example
904
+ * ```ts
905
+ * pipe(3.9, Num.floor); // 3
906
+ * pipe(-3.2, Num.floor); // -4
907
+ * ```
908
+ */
909
+ const floor: (n: number) => number;
910
+ /**
911
+ * Rounds a number up to the nearest integer.
912
+ *
913
+ * @example
914
+ * ```ts
915
+ * pipe(3.1, Num.ceil); // 4
916
+ * pipe(-3.9, Num.ceil); // -3
917
+ * ```
918
+ */
919
+ const ceil: (n: number) => number;
920
+ /**
921
+ * Returns the remainder of dividing a number by `divisor`. Data-last: `remainder(divisor)(a)` = `a % divisor`.
922
+ *
923
+ * @example
924
+ * ```ts
925
+ * pipe(10, Num.remainder(3)); // 1
926
+ * pipe([10, 11, 12], Arr.map(Num.remainder(3))); // [1, 2, 0]
927
+ * ```
928
+ */
929
+ const remainder: (divisor: number) => (n: number) => number;
843
930
  }
844
931
 
845
932
  /**
@@ -1041,6 +1128,26 @@ declare namespace Str {
1041
1128
  * ```
1042
1129
  */
1043
1130
  const includes: (substring: string) => (s: string) => boolean;
1131
+ /**
1132
+ * Replaces the first occurrence of a pattern in a string. Data-last: use in `pipe`.
1133
+ *
1134
+ * @example
1135
+ * ```ts
1136
+ * pipe("foo foo foo", Str.replace("foo", "bar")); // "bar foo foo"
1137
+ * pipe("Hello World", Str.replace(/world/i, "Earth")); // "Hello Earth"
1138
+ * ```
1139
+ */
1140
+ const replace: (pattern: string | RegExp, replacement: string) => (s: string) => string;
1141
+ /**
1142
+ * Replaces all occurrences of a pattern in a string. Data-last: use in `pipe`.
1143
+ *
1144
+ * @example
1145
+ * ```ts
1146
+ * pipe("foo foo foo", Str.replaceAll("foo", "bar")); // "bar bar bar"
1147
+ * pipe("aAbBaA", Str.replaceAll(/a/gi, "x")); // "xxBBxx"
1148
+ * ```
1149
+ */
1150
+ const replaceAll: (pattern: string | RegExp, replacement: string) => (s: string) => string;
1044
1151
  /**
1045
1152
  * Returns `true` when the string starts with the given prefix.
1046
1153
  *
@@ -1098,6 +1205,66 @@ declare namespace Str {
1098
1205
  * ```
1099
1206
  */
1100
1207
  const words: (s: string) => readonly string[];
1208
+ /**
1209
+ * Returns `true` when the string is empty.
1210
+ *
1211
+ * @example
1212
+ * ```ts
1213
+ * pipe("", Str.isEmpty); // true
1214
+ * pipe("hi", Str.isEmpty); // false
1215
+ * ```
1216
+ */
1217
+ const isEmpty: (s: string) => boolean;
1218
+ /**
1219
+ * Returns `true` when the string is empty or contains only whitespace.
1220
+ *
1221
+ * @example
1222
+ * ```ts
1223
+ * pipe(" ", Str.isBlank); // true
1224
+ * pipe("hi", Str.isBlank); // false
1225
+ * ```
1226
+ */
1227
+ const isBlank: (s: string) => boolean;
1228
+ /**
1229
+ * Returns the length of the string.
1230
+ *
1231
+ * @example
1232
+ * ```ts
1233
+ * pipe("hello", Str.length); // 5
1234
+ * pipe("", Str.length); // 0
1235
+ * ```
1236
+ */
1237
+ const length: (s: string) => number;
1238
+ /**
1239
+ * Extracts a substring between two indices. Data-last: use in `pipe`.
1240
+ *
1241
+ * @example
1242
+ * ```ts
1243
+ * pipe("hello", Str.slice(1, 3)); // "el"
1244
+ * pipe("hello", Str.slice(2)); // "llo"
1245
+ * ```
1246
+ */
1247
+ const slice: (start: number, end?: number) => (s: string) => string;
1248
+ /**
1249
+ * Pads the start of a string to a specified length. Data-last: use in `pipe`.
1250
+ *
1251
+ * @example
1252
+ * ```ts
1253
+ * pipe("5", Str.padStart(3, "0")); // "005"
1254
+ * pipe("hi", Str.padStart(5)); // " hi"
1255
+ * ```
1256
+ */
1257
+ const padStart: (maxLength: number, fillString?: string) => (s: string) => string;
1258
+ /**
1259
+ * Pads the end of a string to a specified length. Data-last: use in `pipe`.
1260
+ *
1261
+ * @example
1262
+ * ```ts
1263
+ * pipe("hi", Str.padEnd(5, ".")); // "hi..."
1264
+ * pipe("hi", Str.padEnd(5)); // "hi "
1265
+ * ```
1266
+ */
1267
+ const padEnd: (maxLength: number, fillString?: string) => (s: string) => string;
1101
1268
  /**
1102
1269
  * Safe number parsers that return `Maybe` instead of `NaN`.
1103
1270
  */
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { M as Maybe, R as Result, T as Task } from './Task-BbTMuIby.js';
1
+ import { M as Maybe, R as Result, T as Task } from './Task-C8Pgm7EX.js';
2
2
  import { N as NonEmptyList } from './NonEmptyList-BlGFjor5.js';
3
3
 
4
4
  /**
@@ -93,6 +93,18 @@ declare namespace Arr {
93
93
  * ```
94
94
  */
95
95
  const map: <A, B>(f: (a: A) => B) => (data: readonly A[]) => readonly B[];
96
+ /**
97
+ * Transforms each element using both its value and its zero-based index.
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * pipe(
102
+ * ["a", "b", "c"],
103
+ * Arr.mapWithIndex((i, s) => ({ position: i + 1, value: s }))
104
+ * ); // [{ position: 1, value: "a" }, { position: 2, value: "b" }, { position: 3, value: "c" }]
105
+ * ```
106
+ */
107
+ const mapWithIndex: <A, B>(f: (i: number, a: A) => B) => (data: readonly A[]) => readonly B[];
96
108
  /**
97
109
  * Filters elements that satisfy the predicate.
98
110
  *
@@ -102,6 +114,21 @@ declare namespace Arr {
102
114
  * ```
103
115
  */
104
116
  const filter: <A>(predicate: (a: A) => boolean) => (data: readonly A[]) => readonly A[];
117
+ /**
118
+ * Maps each element to a Maybe and collects only the Some values.
119
+ * Combines map and filter in a single pass.
120
+ *
121
+ * @example
122
+ * ```ts
123
+ * const parseNum = (s: string): Maybe<number> => {
124
+ * const n = Number(s);
125
+ * return isNaN(n) ? Maybe.none() : Maybe.some(n);
126
+ * };
127
+ *
128
+ * pipe(["1", "abc", "3"], Arr.filterMap(parseNum)); // [1, 3]
129
+ * ```
130
+ */
131
+ const filterMap: <A, B>(f: (a: A) => Maybe<B>) => (data: readonly A[]) => readonly B[];
105
132
  /**
106
133
  * Splits an array into two groups based on a predicate.
107
134
  * First group contains elements that satisfy the predicate,
@@ -840,6 +867,66 @@ declare namespace Num {
840
867
  * ```
841
868
  */
842
869
  const divide: (b: number) => (a: number) => number;
870
+ /**
871
+ * Returns the absolute value of a number.
872
+ *
873
+ * @example
874
+ * ```ts
875
+ * pipe(-5, Num.abs); // 5
876
+ * pipe(5, Num.abs); // 5
877
+ * ```
878
+ */
879
+ const abs: (n: number) => number;
880
+ /**
881
+ * Negates a number (arithmetic negation).
882
+ *
883
+ * @example
884
+ * ```ts
885
+ * pipe(5, Num.negate); // -5
886
+ * pipe(-5, Num.negate); // 5
887
+ * ```
888
+ */
889
+ const negate: (n: number) => number;
890
+ /**
891
+ * Rounds a number to the nearest integer.
892
+ *
893
+ * @example
894
+ * ```ts
895
+ * pipe(3.5, Num.round); // 4
896
+ * pipe(3.4, Num.round); // 3
897
+ * ```
898
+ */
899
+ const round: (n: number) => number;
900
+ /**
901
+ * Rounds a number down to the nearest integer.
902
+ *
903
+ * @example
904
+ * ```ts
905
+ * pipe(3.9, Num.floor); // 3
906
+ * pipe(-3.2, Num.floor); // -4
907
+ * ```
908
+ */
909
+ const floor: (n: number) => number;
910
+ /**
911
+ * Rounds a number up to the nearest integer.
912
+ *
913
+ * @example
914
+ * ```ts
915
+ * pipe(3.1, Num.ceil); // 4
916
+ * pipe(-3.9, Num.ceil); // -3
917
+ * ```
918
+ */
919
+ const ceil: (n: number) => number;
920
+ /**
921
+ * Returns the remainder of dividing a number by `divisor`. Data-last: `remainder(divisor)(a)` = `a % divisor`.
922
+ *
923
+ * @example
924
+ * ```ts
925
+ * pipe(10, Num.remainder(3)); // 1
926
+ * pipe([10, 11, 12], Arr.map(Num.remainder(3))); // [1, 2, 0]
927
+ * ```
928
+ */
929
+ const remainder: (divisor: number) => (n: number) => number;
843
930
  }
844
931
 
845
932
  /**
@@ -1041,6 +1128,26 @@ declare namespace Str {
1041
1128
  * ```
1042
1129
  */
1043
1130
  const includes: (substring: string) => (s: string) => boolean;
1131
+ /**
1132
+ * Replaces the first occurrence of a pattern in a string. Data-last: use in `pipe`.
1133
+ *
1134
+ * @example
1135
+ * ```ts
1136
+ * pipe("foo foo foo", Str.replace("foo", "bar")); // "bar foo foo"
1137
+ * pipe("Hello World", Str.replace(/world/i, "Earth")); // "Hello Earth"
1138
+ * ```
1139
+ */
1140
+ const replace: (pattern: string | RegExp, replacement: string) => (s: string) => string;
1141
+ /**
1142
+ * Replaces all occurrences of a pattern in a string. Data-last: use in `pipe`.
1143
+ *
1144
+ * @example
1145
+ * ```ts
1146
+ * pipe("foo foo foo", Str.replaceAll("foo", "bar")); // "bar bar bar"
1147
+ * pipe("aAbBaA", Str.replaceAll(/a/gi, "x")); // "xxBBxx"
1148
+ * ```
1149
+ */
1150
+ const replaceAll: (pattern: string | RegExp, replacement: string) => (s: string) => string;
1044
1151
  /**
1045
1152
  * Returns `true` when the string starts with the given prefix.
1046
1153
  *
@@ -1098,6 +1205,66 @@ declare namespace Str {
1098
1205
  * ```
1099
1206
  */
1100
1207
  const words: (s: string) => readonly string[];
1208
+ /**
1209
+ * Returns `true` when the string is empty.
1210
+ *
1211
+ * @example
1212
+ * ```ts
1213
+ * pipe("", Str.isEmpty); // true
1214
+ * pipe("hi", Str.isEmpty); // false
1215
+ * ```
1216
+ */
1217
+ const isEmpty: (s: string) => boolean;
1218
+ /**
1219
+ * Returns `true` when the string is empty or contains only whitespace.
1220
+ *
1221
+ * @example
1222
+ * ```ts
1223
+ * pipe(" ", Str.isBlank); // true
1224
+ * pipe("hi", Str.isBlank); // false
1225
+ * ```
1226
+ */
1227
+ const isBlank: (s: string) => boolean;
1228
+ /**
1229
+ * Returns the length of the string.
1230
+ *
1231
+ * @example
1232
+ * ```ts
1233
+ * pipe("hello", Str.length); // 5
1234
+ * pipe("", Str.length); // 0
1235
+ * ```
1236
+ */
1237
+ const length: (s: string) => number;
1238
+ /**
1239
+ * Extracts a substring between two indices. Data-last: use in `pipe`.
1240
+ *
1241
+ * @example
1242
+ * ```ts
1243
+ * pipe("hello", Str.slice(1, 3)); // "el"
1244
+ * pipe("hello", Str.slice(2)); // "llo"
1245
+ * ```
1246
+ */
1247
+ const slice: (start: number, end?: number) => (s: string) => string;
1248
+ /**
1249
+ * Pads the start of a string to a specified length. Data-last: use in `pipe`.
1250
+ *
1251
+ * @example
1252
+ * ```ts
1253
+ * pipe("5", Str.padStart(3, "0")); // "005"
1254
+ * pipe("hi", Str.padStart(5)); // " hi"
1255
+ * ```
1256
+ */
1257
+ const padStart: (maxLength: number, fillString?: string) => (s: string) => string;
1258
+ /**
1259
+ * Pads the end of a string to a specified length. Data-last: use in `pipe`.
1260
+ *
1261
+ * @example
1262
+ * ```ts
1263
+ * pipe("hi", Str.padEnd(5, ".")); // "hi..."
1264
+ * pipe("hi", Str.padEnd(5)); // "hi "
1265
+ * ```
1266
+ */
1267
+ const padEnd: (maxLength: number, fillString?: string) => (s: string) => string;
1101
1268
  /**
1102
1269
  * Safe number parsers that return `Maybe` instead of `NaN`.
1103
1270
  */
package/dist/utils.js CHANGED
@@ -63,6 +63,11 @@ var Result;
63
63
  if ((0, Result2.isOk)(data)) f(data.value);
64
64
  return data;
65
65
  };
66
+ Result2.tapError = (f) => (data) => {
67
+ if ((0, Result2.isErr)(data)) f(data.error);
68
+ return data;
69
+ };
70
+ Result2.fromPredicate = (pred, onFalse) => (a) => pred(a) ? (0, Result2.ok)(a) : (0, Result2.err)(onFalse(a));
66
71
  Result2.recover = (fallback) => (data) => (0, Result2.isOk)(data) ? data : fallback(data.error);
67
72
  Result2.recoverUnless = (blockedErr, fallback) => (data) => (0, Result2.isErr)(data) && data.error !== blockedErr ? fallback() : data;
68
73
  Result2.toMaybe = (data) => (0, Result2.isOk)(data) ? Maybe.some(data.value) : Maybe.none();
@@ -81,6 +86,7 @@ var Maybe;
81
86
  Maybe2.toNullable = (data) => (0, Maybe2.isSome)(data) ? data.value : null;
82
87
  Maybe2.toUndefined = (data) => (0, Maybe2.isSome)(data) ? data.value : void 0;
83
88
  Maybe2.fromUndefined = (value) => value === void 0 ? (0, Maybe2.none)() : (0, Maybe2.some)(value);
89
+ Maybe2.fromPredicate = (pred) => (a) => pred(a) ? (0, Maybe2.some)(a) : (0, Maybe2.none)();
84
90
  Maybe2.toResult = (onNone) => (data) => (0, Maybe2.isSome)(data) ? Result.ok(data.value) : Result.err(onNone());
85
91
  Maybe2.fromResult = (data) => Result.isOk(data) ? (0, Maybe2.some)(data.value) : (0, Maybe2.none)();
86
92
  Maybe2.map = (f) => (data) => (0, Maybe2.isSome)(data) ? (0, Maybe2.some)(f(data.value)) : data;
@@ -103,6 +109,7 @@ var Task;
103
109
  ((Task2) => {
104
110
  Task2.resolve = (value) => () => Deferred.fromPromise(Promise.resolve(value));
105
111
  Task2.from = (f) => (signal) => Deferred.fromPromise(f(signal));
112
+ Task2.fromSync = (f) => () => Deferred.fromPromise(Promise.resolve(f()));
106
113
  Task2.map = (f) => (data) => (0, Task2.from)((signal) => toPromise(data, signal).then(f));
107
114
  Task2.chain = (f) => (data) => (0, Task2.from)((signal) => toPromise(data, signal).then((a) => toPromise(f(a), signal)));
108
115
  Task2.ap = (arg) => (data) => (0, Task2.from)(
@@ -223,6 +230,12 @@ var Arr;
223
230
  for (let i = 0; i < n; i++) result[i] = f(data[i]);
224
231
  return result;
225
232
  };
233
+ Arr2.mapWithIndex = (f) => (data) => {
234
+ const n = data.length;
235
+ const result = new Array(n);
236
+ for (let i = 0; i < n; i++) result[i] = f(i, data[i]);
237
+ return result;
238
+ };
226
239
  Arr2.filter = (predicate) => (data) => {
227
240
  const n = data.length;
228
241
  const result = [];
@@ -231,6 +244,14 @@ var Arr;
231
244
  }
232
245
  return result;
233
246
  };
247
+ Arr2.filterMap = (f) => (data) => {
248
+ const result = [];
249
+ for (let i = 0; i < data.length; i++) {
250
+ const mapped = f(data[i]);
251
+ if (mapped.kind === "Some") result.push(mapped.value);
252
+ }
253
+ return result;
254
+ };
234
255
  Arr2.partition = (predicate) => (data) => {
235
256
  const pass = [];
236
257
  const fail = [];
@@ -542,6 +563,12 @@ var Num;
542
563
  Num2.subtract = (b) => (a) => a - b;
543
564
  Num2.multiply = (b) => (a) => a * b;
544
565
  Num2.divide = (b) => (a) => a / b;
566
+ Num2.abs = (n) => Math.abs(n);
567
+ Num2.negate = (n) => -n;
568
+ Num2.round = (n) => Math.round(n);
569
+ Num2.floor = (n) => Math.floor(n);
570
+ Num2.ceil = (n) => Math.ceil(n);
571
+ Num2.remainder = (divisor) => (n) => n % divisor;
545
572
  })(Num || (Num = {}));
546
573
 
547
574
  // src/Utils/Rec.ts
@@ -659,12 +686,20 @@ var Str;
659
686
  Str2.split = (separator) => (s) => s.split(separator);
660
687
  Str2.trim = (s) => s.trim();
661
688
  Str2.includes = (substring) => (s) => s.includes(substring);
689
+ Str2.replace = (pattern, replacement) => (s) => s.replace(pattern, replacement);
690
+ Str2.replaceAll = (pattern, replacement) => (s) => s.replaceAll(pattern, replacement);
662
691
  Str2.startsWith = (prefix) => (s) => s.startsWith(prefix);
663
692
  Str2.endsWith = (suffix) => (s) => s.endsWith(suffix);
664
693
  Str2.toUpperCase = (s) => s.toUpperCase();
665
694
  Str2.toLowerCase = (s) => s.toLowerCase();
666
695
  Str2.lines = (s) => s.split(/\r?\n|\r/);
667
696
  Str2.words = (s) => s.trim().split(/\s+/).filter(Boolean);
697
+ Str2.isEmpty = (s) => s.length === 0;
698
+ Str2.isBlank = (s) => s.trim().length === 0;
699
+ Str2.length = (s) => s.length;
700
+ Str2.slice = (start, end) => (s) => s.slice(start, end);
701
+ Str2.padStart = (maxLength, fillString) => (s) => s.padStart(maxLength, fillString);
702
+ Str2.padEnd = (maxLength, fillString) => (s) => s.padEnd(maxLength, fillString);
668
703
  Str2.parse = {
669
704
  /**
670
705
  * Parses a string as an integer (base 10). Returns `None` if the result is `NaN`.
package/dist/utils.mjs CHANGED
@@ -5,8 +5,8 @@ import {
5
5
  Rec,
6
6
  Str,
7
7
  Uniq
8
- } from "./chunk-C3Z56PCR.mjs";
9
- import "./chunk-2DPG2RDB.mjs";
8
+ } from "./chunk-SBTMTAZF.mjs";
9
+ import "./chunk-HHCRWQYN.mjs";
10
10
  import "./chunk-DBIC62UV.mjs";
11
11
  export {
12
12
  Arr,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nlozgachev/pipelined",
3
- "version": "0.25.0",
3
+ "version": "0.27.0",
4
4
  "description": "Opinionated functional abstractions for TypeScript",
5
5
  "license": "BSD-3-Clause",
6
6
  "homepage": "https://pipelined.lozgachev.dev",