@nlozgachev/pipelined 0.40.0 → 0.42.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,3 +1,5 @@
1
+ import { D as Duration } from './Duration-BTeT9D-q.js';
2
+
1
3
  /**
2
4
  * Composes functions from right to left, returning a new function.
3
5
  * This is the traditional mathematical function composition: (f . g)(x) = f(g(x))
@@ -617,7 +619,132 @@ interface pipe {
617
619
  *
618
620
  * @see {@link Maybe.tap} for Maybe-specific tap that only runs on Some
619
621
  */
620
- declare const tap: <A>(f: (a: A) => void) => (a: A) => A;
622
+ declare function tap<A>(f: (a: A) => void): (a: A) => A;
623
+ declare namespace tap {
624
+ /**
625
+ * Configuration options for {@link tap.log}.
626
+ */
627
+ type LogOptions<A> = {
628
+ /**
629
+ * An optional label prefix for the log output (e.g., `[label]: value`).
630
+ */
631
+ readonly label?: string;
632
+ /**
633
+ * The logging destination function. Defaults to `console.log`.
634
+ */
635
+ readonly logger?: (message: string) => void;
636
+ /**
637
+ * A custom formatter function to convert the piped value to a string.
638
+ * Defaults to `JSON.stringify` for objects and `String(value)` for primitives.
639
+ */
640
+ readonly formatter?: (value: A) => string;
641
+ };
642
+ /**
643
+ * Configuration options for {@link tap.inspect}.
644
+ */
645
+ type InspectOptions = {
646
+ /**
647
+ * An optional label prefix for the inspect output (e.g., `[label]: value`).
648
+ */
649
+ readonly label?: string;
650
+ /**
651
+ * The maximum depth to recurse when formatting the object.
652
+ * Defaults to `null` (infinite depth).
653
+ */
654
+ readonly depth?: number;
655
+ /**
656
+ * Whether to colorize the output using ANSI color codes.
657
+ * Defaults to `true`.
658
+ */
659
+ readonly colors?: boolean;
660
+ };
661
+ /**
662
+ * Configuration options for {@link tap.async}.
663
+ */
664
+ type AsyncOptions = {
665
+ /**
666
+ * A callback to handle exceptions thrown by the async side-effect.
667
+ * Defaults to logging via `console.error`.
668
+ */
669
+ readonly onError?: (error: unknown) => void;
670
+ };
671
+ /**
672
+ * Configuration options for {@link tap.time}, enforcing mutual exclusivity
673
+ * between console logging and custom handlers.
674
+ */
675
+ type TimeConfig = {
676
+ label: string;
677
+ onFinish?: never;
678
+ } | {
679
+ onFinish: (duration: Duration) => void;
680
+ label?: never;
681
+ };
682
+ /**
683
+ * Logs the piped value to the console or a custom logger, returning the value unchanged.
684
+ *
685
+ * @example
686
+ * ```ts
687
+ * pipe(
688
+ * 42,
689
+ * tap.log(), // logs: 42
690
+ * tap.log({ label: "Count" }) // logs: [Count]: 42
691
+ * );
692
+ * ```
693
+ */
694
+ const log: <A>(options?: LogOptions<A>) => (a: A) => A;
695
+ /**
696
+ * Performs a deep structured inspect formatting on the piped value, returning it unchanged.
697
+ * In Node.js environments, this utilizes Node's `node:util` `inspect` utility.
698
+ *
699
+ * @example
700
+ * ```ts
701
+ * pipe(
702
+ * { user: { name: "Alice", details: { age: 30 } } },
703
+ * tap.inspect({ label: "User Object", depth: 2 })
704
+ * );
705
+ * ```
706
+ */
707
+ const inspect: <A>(options?: InspectOptions) => (a: A) => A;
708
+ /**
709
+ * Triggers a fire-and-forget asynchronous side effect in the background,
710
+ * returning the piped value immediately and synchronously.
711
+ * Any errors thrown by the async function are caught and forwarded to `onError`.
712
+ *
713
+ * @example
714
+ * ```ts
715
+ * pipe(
716
+ * user,
717
+ * tap.async(async (u) => {
718
+ * await saveToDatabase(u);
719
+ * }, { onError: (err) => logError(err) })
720
+ * );
721
+ * ```
722
+ */
723
+ const async: <A>(fn: (a: A) => Promise<unknown>, options?: AsyncOptions) => (a: A) => A;
724
+ /**
725
+ * Runs a function and measures its execution duration, returning the value unchanged.
726
+ * Supports both synchronous and asynchronous functions. If the timed function returns
727
+ * a Promise, duration measurement resolves asynchronously upon resolution/rejection.
728
+ *
729
+ * @example
730
+ * ```ts
731
+ * // Time a synchronous computation
732
+ * pipe(
733
+ * data,
734
+ * tap.time(processData, { label: "sync-process" })
735
+ * );
736
+ *
737
+ * // Time an asynchronous fetch with custom metrics callback
738
+ * pipe(
739
+ * data,
740
+ * tap.time(fetchData, {
741
+ * onFinish: (dur) => metrics.histogram("api.time", Duration.toMilliseconds(dur))
742
+ * })
743
+ * );
744
+ * ```
745
+ */
746
+ const time: <A>(fn: (a: A) => unknown, config: TimeConfig) => (a: A) => A;
747
+ }
621
748
 
622
749
  /**
623
750
  * Converts a curried function into a multi-argument function.
@@ -369,10 +369,117 @@ pipe.try = (f, onError) => (a) => {
369
369
  };
370
370
 
371
371
  // src/Composition/tap.ts
372
- var tap = (f) => (a) => {
373
- f(a);
374
- return a;
375
- };
372
+ var import_node_util = require("util");
373
+
374
+ // src/Types/Brand.ts
375
+ var Brand;
376
+ ((Brand2) => {
377
+ Brand2.wrap = () => (value) => value;
378
+ Brand2.unwrap = (branded) => branded;
379
+ })(Brand || (Brand = {}));
380
+
381
+ // src/Types/Duration.ts
382
+ var Duration;
383
+ ((Duration2) => {
384
+ const wrap = Brand.wrap();
385
+ Duration2.milliseconds = (ms) => wrap(ms);
386
+ Duration2.seconds = (s) => wrap(s * 1e3);
387
+ Duration2.minutes = (m) => wrap(m * 60 * 1e3);
388
+ Duration2.hours = (h) => wrap(h * 60 * 60 * 1e3);
389
+ Duration2.days = (d) => wrap(d * 24 * 60 * 60 * 1e3);
390
+ Duration2.toMilliseconds = (d) => Brand.unwrap(d);
391
+ Duration2.toSeconds = (d) => Brand.unwrap(d) / 1e3;
392
+ Duration2.toMinutes = (d) => Brand.unwrap(d) / (60 * 1e3);
393
+ Duration2.toHours = (d) => Brand.unwrap(d) / (60 * 60 * 1e3);
394
+ Duration2.toDays = (d) => Brand.unwrap(d) / (24 * 60 * 60 * 1e3);
395
+ Duration2.add = (other) => (self) => wrap(Brand.unwrap(self) + Brand.unwrap(other));
396
+ Duration2.subtract = (other) => (self) => wrap(Brand.unwrap(self) - Brand.unwrap(other));
397
+ })(Duration || (Duration = {}));
398
+
399
+ // src/Composition/tap.ts
400
+ function tap(f) {
401
+ return (a) => {
402
+ f(a);
403
+ return a;
404
+ };
405
+ }
406
+ ((tap2) => {
407
+ tap2.log = (options) => (a) => {
408
+ const logger = options?.logger ?? console.log;
409
+ const formatter = options?.formatter ?? ((val) => {
410
+ try {
411
+ return typeof val === "object" && val !== null ? JSON.stringify(val) : String(val);
412
+ } catch {
413
+ return String(val);
414
+ }
415
+ });
416
+ const formatted = formatter(a);
417
+ if (options?.label !== void 0) {
418
+ logger(`[${options.label}]: ${formatted}`);
419
+ } else {
420
+ logger(formatted);
421
+ }
422
+ return a;
423
+ };
424
+ tap2.inspect = (options) => (a) => {
425
+ const label = options?.label;
426
+ const depth = options?.depth ?? null;
427
+ const colors = options?.colors ?? true;
428
+ let formatted;
429
+ if (typeof import_node_util.inspect === "function") {
430
+ formatted = (0, import_node_util.inspect)(a, { depth, colors });
431
+ } else {
432
+ try {
433
+ formatted = JSON.stringify(a, null, 2);
434
+ } catch {
435
+ formatted = String(a);
436
+ }
437
+ }
438
+ if (label !== void 0) {
439
+ console.log(`[${label}]: ${formatted}`);
440
+ } else {
441
+ console.log(formatted);
442
+ }
443
+ return a;
444
+ };
445
+ tap2.async = (fn, options) => (a) => {
446
+ const onError = options?.onError ?? console.error;
447
+ fn(a).catch((err) => {
448
+ onError(err);
449
+ });
450
+ return a;
451
+ };
452
+ tap2.time = (fn, config) => (a) => {
453
+ const start = performance.now();
454
+ const triggerFinish = (duration) => {
455
+ if (config.label !== void 0) {
456
+ console.log(`[${config.label}]: ${Duration.toMilliseconds(duration)}ms`);
457
+ } else {
458
+ config.onFinish(duration);
459
+ }
460
+ };
461
+ try {
462
+ const res = fn(a);
463
+ if (res instanceof Promise) {
464
+ res.then(() => {
465
+ const duration = Duration.milliseconds(performance.now() - start);
466
+ triggerFinish(duration);
467
+ }, () => {
468
+ const duration = Duration.milliseconds(performance.now() - start);
469
+ triggerFinish(duration);
470
+ });
471
+ } else {
472
+ const duration = Duration.milliseconds(performance.now() - start);
473
+ triggerFinish(duration);
474
+ }
475
+ } catch (err) {
476
+ const duration = Duration.milliseconds(performance.now() - start);
477
+ triggerFinish(duration);
478
+ throw err;
479
+ }
480
+ return a;
481
+ };
482
+ })(tap || (tap = {}));
376
483
 
377
484
  // src/Composition/uncurry.ts
378
485
  function uncurry(f) {
@@ -27,7 +27,8 @@ import {
27
27
  uncurry,
28
28
  uncurry3,
29
29
  uncurry4
30
- } from "./chunk-3Q5UBRYB.mjs";
30
+ } from "./chunk-F6SBU7GB.mjs";
31
+ import "./chunk-GBB6LVLI.mjs";
31
32
  export {
32
33
  and,
33
34
  compose,
package/dist/core.d.mts CHANGED
@@ -1,6 +1,7 @@
1
- import { M as Maybe, q as WithValue, k as WithLog, D as Deferred, R as Result, j as WithKind, g as WithError, c as RetryOptions, d as TimeoutOptions, p as WithTimeout, l as WithMinInterval, e as WithCooldown, W as WithConcurrency, o as WithSize, f as WithDuration, m as WithN, T as Task, i as WithFirst, n as WithSecond, h as WithErrors } from './Task-DcXhCZYg.mjs';
2
- export { E as Equality, a as Err, N as None, O as Ok, b as Ordering, S as Some } from './Task-DcXhCZYg.mjs';
3
- import { Duration, NonEmptyList } from './types.mjs';
1
+ import { M as Maybe, q as WithValue, k as WithLog, D as Deferred, R as Result, j as WithKind, g as WithError, c as RetryOptions, d as TimeoutOptions, p as WithTimeout, l as WithMinInterval, e as WithCooldown, W as WithConcurrency, o as WithSize, f as WithDuration, m as WithN, T as Task, i as WithFirst, n as WithSecond, h as WithErrors } from './Task-BprUabHP.mjs';
2
+ export { E as Equality, a as Err, N as None, O as Ok, b as Ordering, S as Some } from './Task-BprUabHP.mjs';
3
+ import { D as Duration } from './Duration-BTeT9D-q.mjs';
4
+ import { NonEmptyList } from './types.mjs';
4
5
 
5
6
  /**
6
7
  * A type that can combine two values of type `A` into one, with a neutral starting value.
@@ -2591,7 +2592,7 @@ declare namespace TaskResult {
2591
2592
  * if (Result.isOk(result)) render(result.value);
2592
2593
  * ```
2593
2594
  */
2594
- const run: (signal?: AbortSignal) => <E, A>(task: TaskResult<E, A>) => Promise<Result<E, A>>;
2595
+ const run: (signal?: AbortSignal) => <E, A>(task: TaskResult<E, A>) => Deferred<Result<E, A>>;
2595
2596
  /**
2596
2597
  * Converts a TaskResult value into an object containing a single property.
2597
2598
  * Initiates the pipeline accumulator record.
package/dist/core.d.ts CHANGED
@@ -1,6 +1,7 @@
1
- import { M as Maybe, q as WithValue, k as WithLog, D as Deferred, R as Result, j as WithKind, g as WithError, c as RetryOptions, d as TimeoutOptions, p as WithTimeout, l as WithMinInterval, e as WithCooldown, W as WithConcurrency, o as WithSize, f as WithDuration, m as WithN, T as Task, i as WithFirst, n as WithSecond, h as WithErrors } from './Task-uupX7xd9.js';
2
- export { E as Equality, a as Err, N as None, O as Ok, b as Ordering, S as Some } from './Task-uupX7xd9.js';
3
- import { Duration, NonEmptyList } from './types.js';
1
+ import { M as Maybe, q as WithValue, k as WithLog, D as Deferred, R as Result, j as WithKind, g as WithError, c as RetryOptions, d as TimeoutOptions, p as WithTimeout, l as WithMinInterval, e as WithCooldown, W as WithConcurrency, o as WithSize, f as WithDuration, m as WithN, T as Task, i as WithFirst, n as WithSecond, h as WithErrors } from './Task-Dt3ZMen6.js';
2
+ export { E as Equality, a as Err, N as None, O as Ok, b as Ordering, S as Some } from './Task-Dt3ZMen6.js';
3
+ import { D as Duration } from './Duration-BTeT9D-q.js';
4
+ import { NonEmptyList } from './types.js';
4
5
 
5
6
  /**
6
7
  * A type that can combine two values of type `A` into one, with a neutral starting value.
@@ -2591,7 +2592,7 @@ declare namespace TaskResult {
2591
2592
  * if (Result.isOk(result)) render(result.value);
2592
2593
  * ```
2593
2594
  */
2594
- const run: (signal?: AbortSignal) => <E, A>(task: TaskResult<E, A>) => Promise<Result<E, A>>;
2595
+ const run: (signal?: AbortSignal) => <E, A>(task: TaskResult<E, A>) => Deferred<Result<E, A>>;
2595
2596
  /**
2596
2597
  * Converts a TaskResult value into an object containing a single property.
2597
2598
  * Initiates the pipeline accumulator record.
package/dist/core.js CHANGED
@@ -1673,9 +1673,7 @@ var Task;
1673
1673
  (signal) => new Promise((res) => {
1674
1674
  let timerId;
1675
1675
  const onAbort = () => {
1676
- if (timerId !== void 0) {
1677
- clearTimeout(timerId);
1678
- }
1676
+ clearTimeout(timerId);
1679
1677
  res(toPromise(data, signal));
1680
1678
  };
1681
1679
  if (signal) {
@@ -1696,27 +1694,20 @@ var Task;
1696
1694
  return Promise.resolve([]);
1697
1695
  }
1698
1696
  const results = [];
1699
- const wait = () => {
1700
- if (signal?.aborted) {
1701
- return Promise.resolve();
1697
+ const wait = () => new Promise((r) => {
1698
+ let timerId;
1699
+ const onAbort = () => {
1700
+ clearTimeout(timerId);
1701
+ r();
1702
+ };
1703
+ if (signal) {
1704
+ signal.addEventListener("abort", onAbort, { once: true });
1702
1705
  }
1703
- return new Promise((r) => {
1704
- let timerId;
1705
- const onAbort = () => {
1706
- if (timerId !== void 0) {
1707
- clearTimeout(timerId);
1708
- }
1709
- r();
1710
- };
1711
- if (signal) {
1712
- signal.addEventListener("abort", onAbort, { once: true });
1713
- }
1714
- timerId = setTimeout(() => {
1715
- signal?.removeEventListener("abort", onAbort);
1716
- r();
1717
- }, delayDuration ? getMs2(delayDuration) : 0);
1718
- });
1719
- };
1706
+ timerId = setTimeout(() => {
1707
+ signal?.removeEventListener("abort", onAbort);
1708
+ r();
1709
+ }, delayDuration ? getMs2(delayDuration) : 0);
1710
+ });
1720
1711
  const run2 = (left) => {
1721
1712
  if (signal?.aborted) {
1722
1713
  return Promise.resolve(results);
@@ -1733,27 +1724,20 @@ var Task;
1733
1724
  });
1734
1725
  Task2.repeatUntil = (options) => (task) => (0, Task2.from)((signal) => {
1735
1726
  const { when: predicate, delay: delayDuration, maxAttempts } = options;
1736
- const wait = () => {
1737
- if (signal?.aborted) {
1738
- return Promise.resolve();
1727
+ const wait = () => new Promise((r) => {
1728
+ let timerId;
1729
+ const onAbort = () => {
1730
+ clearTimeout(timerId);
1731
+ r();
1732
+ };
1733
+ if (signal) {
1734
+ signal.addEventListener("abort", onAbort, { once: true });
1739
1735
  }
1740
- return new Promise((r) => {
1741
- let timerId;
1742
- const onAbort = () => {
1743
- if (timerId !== void 0) {
1744
- clearTimeout(timerId);
1745
- }
1746
- r();
1747
- };
1748
- if (signal) {
1749
- signal.addEventListener("abort", onAbort, { once: true });
1750
- }
1751
- timerId = setTimeout(() => {
1752
- signal?.removeEventListener("abort", onAbort);
1753
- r();
1754
- }, delayDuration ? getMs2(delayDuration) : 0);
1755
- });
1756
- };
1736
+ timerId = setTimeout(() => {
1737
+ signal?.removeEventListener("abort", onAbort);
1738
+ r();
1739
+ }, delayDuration ? getMs2(delayDuration) : 0);
1740
+ });
1757
1741
  const run2 = (attempt, lastValue) => {
1758
1742
  if (signal?.aborted && lastValue !== void 0) {
1759
1743
  return Promise.resolve(lastValue);
@@ -1822,9 +1806,7 @@ var Task;
1822
1806
  const controller = new AbortController();
1823
1807
  let timerId;
1824
1808
  function cleanUp() {
1825
- if (timerId !== void 0) {
1826
- clearTimeout(timerId);
1827
- }
1809
+ clearTimeout(timerId);
1828
1810
  outerSignal?.removeEventListener("abort", onOuterAbort);
1829
1811
  }
1830
1812
  function onOuterAbort() {
@@ -1870,7 +1852,7 @@ var Task;
1870
1852
  };
1871
1853
  return { task, abort };
1872
1854
  };
1873
- Task2.run = (signal) => (task) => Deferred.toPromise(task(signal));
1855
+ Task2.run = (signal) => (task) => task(signal);
1874
1856
  Task2.bindTo = (key) => (data) => (0, Task2.map)((a) => ({ [key]: a }))(data);
1875
1857
  Task2.bind = (key, f) => (data) => (0, Task2.chain)(
1876
1858
  (a) => (0, Task2.map)((b) => ({ ...a, [key]: b }))(f(a))
@@ -1934,7 +1916,7 @@ var TaskResult3;
1934
1916
  ([of_, oa]) => Result.ap(oa)(of_)
1935
1917
  )
1936
1918
  );
1937
- TaskResult4.run = (signal) => (task) => Deferred.toPromise(task(signal));
1919
+ TaskResult4.run = (signal) => (task) => task(signal);
1938
1920
  TaskResult4.bindTo = (key) => (data) => (0, TaskResult4.map)((a) => ({ [key]: a }))(data);
1939
1921
  TaskResult4.bind = (key, f) => (data) => (0, TaskResult4.chain)(
1940
1922
  (a) => (0, TaskResult4.map)((b) => ({ ...a, [key]: b }))(f(a))
package/dist/core.mjs CHANGED
@@ -23,8 +23,8 @@ import {
23
23
  These,
24
24
  Tuple,
25
25
  Validation
26
- } from "./chunk-4R4XUP4M.mjs";
27
- import "./chunk-5AFEEFE4.mjs";
26
+ } from "./chunk-OAP765G3.mjs";
27
+ import "./chunk-GBB6LVLI.mjs";
28
28
  export {
29
29
  Combinable,
30
30
  Deferred,
package/dist/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { and, compose, constFalse, constNull, constTrue, constUndefined, constVoid, constant, converge, curry, curry3, curry4, defaultTo, flip, flow, identity, juxt, memoize, memoizeWeak, not, on, once, or, pipe, tap, uncurry, uncurry3, uncurry4 } from './composition.mjs';
2
2
  export { Combinable, Failed, Failure, Lazy, Lens, Loading, Logged, NotAsked, Op, Optional, Passed, Predicate, Reader, Refinement, RemoteData, Resource, State, Success, TaskMaybe, TaskResult, TaskValidation, These, TheseBoth, TheseFirst, TheseSecond, Tuple, Validation } from './core.mjs';
3
- export { D as Deferred, E as Equality, a as Err, M as Maybe, N as None, O as Ok, b as Ordering, R as Result, S as Some, T as Task } from './Task-DcXhCZYg.mjs';
3
+ export { D as Deferred, E as Equality, a as Err, M as Maybe, N as None, O as Ok, b as Ordering, R as Result, S as Some, T as Task } from './Task-BprUabHP.mjs';
4
4
  export { Arr, Dict, Num, Rec, Str, Uniq } from './utils.mjs';
5
- export { Brand, Duration, NonEmptyList, isNonEmptyList } from './types.mjs';
5
+ export { B as Brand, D as Duration } from './Duration-BTeT9D-q.mjs';
6
+ export { NonEmptyList, isNonEmptyList } from './types.mjs';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { and, compose, constFalse, constNull, constTrue, constUndefined, constVoid, constant, converge, curry, curry3, curry4, defaultTo, flip, flow, identity, juxt, memoize, memoizeWeak, not, on, once, or, pipe, tap, uncurry, uncurry3, uncurry4 } from './composition.js';
2
2
  export { Combinable, Failed, Failure, Lazy, Lens, Loading, Logged, NotAsked, Op, Optional, Passed, Predicate, Reader, Refinement, RemoteData, Resource, State, Success, TaskMaybe, TaskResult, TaskValidation, These, TheseBoth, TheseFirst, TheseSecond, Tuple, Validation } from './core.js';
3
- export { D as Deferred, E as Equality, a as Err, M as Maybe, N as None, O as Ok, b as Ordering, R as Result, S as Some, T as Task } from './Task-uupX7xd9.js';
3
+ export { D as Deferred, E as Equality, a as Err, M as Maybe, N as None, O as Ok, b as Ordering, R as Result, S as Some, T as Task } from './Task-Dt3ZMen6.js';
4
4
  export { Arr, Dict, Num, Rec, Str, Uniq } from './utils.js';
5
- export { Brand, Duration, NonEmptyList, isNonEmptyList } from './types.js';
5
+ export { B as Brand, D as Duration } from './Duration-BTeT9D-q.js';
6
+ export { NonEmptyList, isNonEmptyList } from './types.js';