unwrapped 0.1.8 → 0.1.9

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # unwrapped
2
2
 
3
+ ## 0.1.9
4
+
5
+ ### Patch Changes
6
+
7
+ - 07818f4: Added onSuccess and onError listeners
8
+
3
9
  ## 0.1.8
4
10
 
5
11
  ### Patch Changes
@@ -376,6 +376,30 @@ declare class AsyncResult<T, E extends ErrorBase = ErrorBase> {
376
376
  * @returns a function to remove the listener
377
377
  */
378
378
  listenUntilSettled(listener: AsyncResultListener<T, E>, immediate?: boolean): () => void;
379
+ /**
380
+ * Adds a one-time listener that is called once the AsyncResult settles on a success.
381
+ * @param callback callback called once the AsyncResult settled on a success
382
+ * @returns A function to unsubscribe early
383
+ */
384
+ onSuccessOnce(callback: (value: T) => void): () => void;
385
+ /**
386
+ * Adds a perpetual listener that is called every time the AsyncResult settles on a success.
387
+ * @param callback callback called every time the AsyncResult settles on a success
388
+ * @returns A function to unsubscribe
389
+ */
390
+ onSuccessPerpetual(callback: (value: T) => void): () => void;
391
+ /**
392
+ * Adds a one-time listener that is called once the AsyncResult settles on an error.
393
+ * @param callback callback called once the AsyncResult settled on an error
394
+ * @returns A function to unsubscribe early
395
+ */
396
+ onErrorOnce(callback: (error: E) => void): () => void;
397
+ /**
398
+ * Adds a perpetual listener that is called every time the AsyncResult settles on an error.
399
+ * @param callback callback called every time the AsyncResult settles on an error
400
+ * @returns A function to unsubscribe
401
+ */
402
+ onErrorPerpetual(callback: (error: E) => void): () => void;
379
403
  /**
380
404
  * Mirrors the state of another AsyncResult into this one.
381
405
  * Whenever the other AsyncResult changes state, this AsyncResult is updated to match.
@@ -483,23 +507,47 @@ declare class AsyncResult<T, E extends ErrorBase = ErrorBase> {
483
507
  /**
484
508
  * The possible states of an AsyncResultList.
485
509
  */
486
- type AsyncResultListState = "any-loading" | "all-settled";
487
- interface AsyncResultListItem<T = any, E extends ErrorBase = ErrorBase> {
510
+ type AsyncResultCollectionState = "any-loading" | "all-settled";
511
+ interface AsyncResultCollectionItem<T = any, E extends ErrorBase = ErrorBase> {
488
512
  key: string;
489
513
  result: AsyncResult<T, E>;
490
514
  unsub: () => void;
491
515
  }
492
516
  /**
493
- * A list that manages multiple AsyncResult instances, tracking their states and providing utilities to monitor them.
517
+ * Manages a collection of AsyncResult tasks with state tracking and listener support.
518
+ *
519
+ * This class provides a way to group multiple async operations, track their overall state
520
+ * (whether any are loading or all have settled), and react to state changes through listeners.
521
+ *
522
+ * @template T - The success value type for all AsyncResult tasks in this collection
523
+ * @template E - The error type for all AsyncResult tasks, defaults to ErrorBase
524
+ *
525
+ * @example
526
+ * ```typescript
527
+ * const collection = new AsyncResultCollection<User>();
528
+ * const userTask = new AsyncResult<User>();
529
+ *
530
+ * collection.add('user-1', userTask);
531
+ *
532
+ * collection.listen((taskQueue) => {
533
+ * console.log('Collection state changed:', taskQueue.state);
534
+ * });
535
+ * ```
536
+ *
537
+ * @remarks
538
+ * - Tasks can be automatically removed when they settle or kept in the collection
539
+ * - The collection state is either "any-loading" (at least one task is loading) or "all-settled" (no tasks loading)
540
+ * - Listeners are notified whenever the collection state changes
541
+ * - Use filtering methods to query tasks by their state (success, error, loading)
494
542
  */
495
- declare class AsyncResultList<T = any, E extends ErrorBase = ErrorBase> {
543
+ declare class AsyncResultCollection<T = any, E extends ErrorBase = ErrorBase> {
496
544
  private _list;
497
545
  private _listeners;
498
546
  private _state;
499
547
  /**
500
548
  * Gets the current tasks in the AsyncResultList.
501
549
  */
502
- get tasks(): Map<string, AsyncResultListItem<T, E>>;
550
+ get tasks(): Map<string, AsyncResultCollectionItem<T, E>>;
503
551
  /**
504
552
  * Gets the number of tasks in the list.
505
553
  */
@@ -516,7 +564,7 @@ declare class AsyncResultList<T = any, E extends ErrorBase = ErrorBase> {
516
564
  /**
517
565
  * Gets the current state of the AsyncResultList.
518
566
  */
519
- get state(): AsyncResultListState;
567
+ get state(): AsyncResultCollectionState;
520
568
  private set state(value);
521
569
  private _onTaskFinished;
522
570
  /**
@@ -524,7 +572,19 @@ declare class AsyncResultList<T = any, E extends ErrorBase = ErrorBase> {
524
572
  * @param listener the function to call when the state changes
525
573
  * @returns a function to unsubscribe the listener
526
574
  */
527
- listen(listener: (taskQueue: AsyncResultList<T, E>) => void): () => void;
575
+ listen(listener: (taskQueue: AsyncResultCollection<T, E>) => void): () => void;
576
+ /**
577
+ * Adds a listener that gets called whenever any item in the AsyncResultList succeeds.
578
+ * @param listener the function to call when an item succeeds
579
+ * @returns a function to unsubscribe the listener
580
+ */
581
+ onItemSuccess(listener: (task: AsyncResult<T, E>, key: string) => void): () => void;
582
+ /**
583
+ * Adds a listener that gets called whenever any item in the AsyncResultList errors.
584
+ * @param listener the function to call when an item errors
585
+ * @returns a function to unsubscribe the listener
586
+ */
587
+ onItemError(listener: (task: AsyncResult<T, E>, key: string) => void): () => void;
528
588
  /**
529
589
  * Adds an AsyncResult task to the list.
530
590
  * @param key the unique key for the task
@@ -672,4 +732,4 @@ declare class KeyedAsyncCache<P, V, E extends ErrorBase = ErrorBase> {
672
732
 
673
733
  declare function delay(ms: number): AsyncResult<true>;
674
734
 
675
- export { type Action, AsyncResult, type AsyncResultGenerator, AsyncResultList, type AsyncResultListItem, type AsyncResultListState, type AsyncResultListener, type AsyncResultState, type ChainStep, ErrorBase, type FlatChainStep, KeyedAsyncCache, type LazyAction, Result, type ResultState, delay };
735
+ export { type Action, AsyncResult, AsyncResultCollection, type AsyncResultCollectionItem, type AsyncResultCollectionState, type AsyncResultGenerator, type AsyncResultListener, type AsyncResultState, type ChainStep, ErrorBase, type FlatChainStep, KeyedAsyncCache, type LazyAction, Result, type ResultState, delay };
@@ -376,6 +376,30 @@ declare class AsyncResult<T, E extends ErrorBase = ErrorBase> {
376
376
  * @returns a function to remove the listener
377
377
  */
378
378
  listenUntilSettled(listener: AsyncResultListener<T, E>, immediate?: boolean): () => void;
379
+ /**
380
+ * Adds a one-time listener that is called once the AsyncResult settles on a success.
381
+ * @param callback callback called once the AsyncResult settled on a success
382
+ * @returns A function to unsubscribe early
383
+ */
384
+ onSuccessOnce(callback: (value: T) => void): () => void;
385
+ /**
386
+ * Adds a perpetual listener that is called every time the AsyncResult settles on a success.
387
+ * @param callback callback called every time the AsyncResult settles on a success
388
+ * @returns A function to unsubscribe
389
+ */
390
+ onSuccessPerpetual(callback: (value: T) => void): () => void;
391
+ /**
392
+ * Adds a one-time listener that is called once the AsyncResult settles on an error.
393
+ * @param callback callback called once the AsyncResult settled on an error
394
+ * @returns A function to unsubscribe early
395
+ */
396
+ onErrorOnce(callback: (error: E) => void): () => void;
397
+ /**
398
+ * Adds a perpetual listener that is called every time the AsyncResult settles on an error.
399
+ * @param callback callback called every time the AsyncResult settles on an error
400
+ * @returns A function to unsubscribe
401
+ */
402
+ onErrorPerpetual(callback: (error: E) => void): () => void;
379
403
  /**
380
404
  * Mirrors the state of another AsyncResult into this one.
381
405
  * Whenever the other AsyncResult changes state, this AsyncResult is updated to match.
@@ -483,23 +507,47 @@ declare class AsyncResult<T, E extends ErrorBase = ErrorBase> {
483
507
  /**
484
508
  * The possible states of an AsyncResultList.
485
509
  */
486
- type AsyncResultListState = "any-loading" | "all-settled";
487
- interface AsyncResultListItem<T = any, E extends ErrorBase = ErrorBase> {
510
+ type AsyncResultCollectionState = "any-loading" | "all-settled";
511
+ interface AsyncResultCollectionItem<T = any, E extends ErrorBase = ErrorBase> {
488
512
  key: string;
489
513
  result: AsyncResult<T, E>;
490
514
  unsub: () => void;
491
515
  }
492
516
  /**
493
- * A list that manages multiple AsyncResult instances, tracking their states and providing utilities to monitor them.
517
+ * Manages a collection of AsyncResult tasks with state tracking and listener support.
518
+ *
519
+ * This class provides a way to group multiple async operations, track their overall state
520
+ * (whether any are loading or all have settled), and react to state changes through listeners.
521
+ *
522
+ * @template T - The success value type for all AsyncResult tasks in this collection
523
+ * @template E - The error type for all AsyncResult tasks, defaults to ErrorBase
524
+ *
525
+ * @example
526
+ * ```typescript
527
+ * const collection = new AsyncResultCollection<User>();
528
+ * const userTask = new AsyncResult<User>();
529
+ *
530
+ * collection.add('user-1', userTask);
531
+ *
532
+ * collection.listen((taskQueue) => {
533
+ * console.log('Collection state changed:', taskQueue.state);
534
+ * });
535
+ * ```
536
+ *
537
+ * @remarks
538
+ * - Tasks can be automatically removed when they settle or kept in the collection
539
+ * - The collection state is either "any-loading" (at least one task is loading) or "all-settled" (no tasks loading)
540
+ * - Listeners are notified whenever the collection state changes
541
+ * - Use filtering methods to query tasks by their state (success, error, loading)
494
542
  */
495
- declare class AsyncResultList<T = any, E extends ErrorBase = ErrorBase> {
543
+ declare class AsyncResultCollection<T = any, E extends ErrorBase = ErrorBase> {
496
544
  private _list;
497
545
  private _listeners;
498
546
  private _state;
499
547
  /**
500
548
  * Gets the current tasks in the AsyncResultList.
501
549
  */
502
- get tasks(): Map<string, AsyncResultListItem<T, E>>;
550
+ get tasks(): Map<string, AsyncResultCollectionItem<T, E>>;
503
551
  /**
504
552
  * Gets the number of tasks in the list.
505
553
  */
@@ -516,7 +564,7 @@ declare class AsyncResultList<T = any, E extends ErrorBase = ErrorBase> {
516
564
  /**
517
565
  * Gets the current state of the AsyncResultList.
518
566
  */
519
- get state(): AsyncResultListState;
567
+ get state(): AsyncResultCollectionState;
520
568
  private set state(value);
521
569
  private _onTaskFinished;
522
570
  /**
@@ -524,7 +572,19 @@ declare class AsyncResultList<T = any, E extends ErrorBase = ErrorBase> {
524
572
  * @param listener the function to call when the state changes
525
573
  * @returns a function to unsubscribe the listener
526
574
  */
527
- listen(listener: (taskQueue: AsyncResultList<T, E>) => void): () => void;
575
+ listen(listener: (taskQueue: AsyncResultCollection<T, E>) => void): () => void;
576
+ /**
577
+ * Adds a listener that gets called whenever any item in the AsyncResultList succeeds.
578
+ * @param listener the function to call when an item succeeds
579
+ * @returns a function to unsubscribe the listener
580
+ */
581
+ onItemSuccess(listener: (task: AsyncResult<T, E>, key: string) => void): () => void;
582
+ /**
583
+ * Adds a listener that gets called whenever any item in the AsyncResultList errors.
584
+ * @param listener the function to call when an item errors
585
+ * @returns a function to unsubscribe the listener
586
+ */
587
+ onItemError(listener: (task: AsyncResult<T, E>, key: string) => void): () => void;
528
588
  /**
529
589
  * Adds an AsyncResult task to the list.
530
590
  * @param key the unique key for the task
@@ -672,4 +732,4 @@ declare class KeyedAsyncCache<P, V, E extends ErrorBase = ErrorBase> {
672
732
 
673
733
  declare function delay(ms: number): AsyncResult<true>;
674
734
 
675
- export { type Action, AsyncResult, type AsyncResultGenerator, AsyncResultList, type AsyncResultListItem, type AsyncResultListState, type AsyncResultListener, type AsyncResultState, type ChainStep, ErrorBase, type FlatChainStep, KeyedAsyncCache, type LazyAction, Result, type ResultState, delay };
735
+ export { type Action, AsyncResult, AsyncResultCollection, type AsyncResultCollectionItem, type AsyncResultCollectionState, type AsyncResultGenerator, type AsyncResultListener, type AsyncResultState, type ChainStep, ErrorBase, type FlatChainStep, KeyedAsyncCache, type LazyAction, Result, type ResultState, delay };
@@ -21,7 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  AsyncResult: () => AsyncResult,
24
- AsyncResultList: () => AsyncResultList,
24
+ AsyncResultCollection: () => AsyncResultCollection,
25
25
  ErrorBase: () => ErrorBase,
26
26
  KeyedAsyncCache: () => KeyedAsyncCache,
27
27
  Result: () => Result,
@@ -519,6 +519,54 @@ var AsyncResult = class _AsyncResult {
519
519
  }, immediate);
520
520
  return unsub;
521
521
  }
522
+ /**
523
+ * Adds a one-time listener that is called once the AsyncResult settles on a success.
524
+ * @param callback callback called once the AsyncResult settled on a success
525
+ * @returns A function to unsubscribe early
526
+ */
527
+ onSuccessOnce(callback) {
528
+ return this.listenUntilSettled((result) => {
529
+ if (result.isSuccess()) {
530
+ callback(result.unwrapOrThrow());
531
+ }
532
+ });
533
+ }
534
+ /**
535
+ * Adds a perpetual listener that is called every time the AsyncResult settles on a success.
536
+ * @param callback callback called every time the AsyncResult settles on a success
537
+ * @returns A function to unsubscribe
538
+ */
539
+ onSuccessPerpetual(callback) {
540
+ return this.listen((result) => {
541
+ if (result.isSuccess()) {
542
+ callback(result.unwrapOrThrow());
543
+ }
544
+ });
545
+ }
546
+ /**
547
+ * Adds a one-time listener that is called once the AsyncResult settles on an error.
548
+ * @param callback callback called once the AsyncResult settled on an error
549
+ * @returns A function to unsubscribe early
550
+ */
551
+ onErrorOnce(callback) {
552
+ return this.listenUntilSettled((result) => {
553
+ if (result.isError()) {
554
+ callback(result.unwrapErrorOrNull());
555
+ }
556
+ });
557
+ }
558
+ /**
559
+ * Adds a perpetual listener that is called every time the AsyncResult settles on an error.
560
+ * @param callback callback called every time the AsyncResult settles on an error
561
+ * @returns A function to unsubscribe
562
+ */
563
+ onErrorPerpetual(callback) {
564
+ return this.listen((result) => {
565
+ if (result.isError()) {
566
+ callback(result.unwrapErrorOrNull());
567
+ }
568
+ });
569
+ }
522
570
  // === Mirroring ===
523
571
  /**
524
572
  * Mirrors the state of another AsyncResult into this one.
@@ -711,8 +759,8 @@ var AsyncResult = class _AsyncResult {
711
759
  }
712
760
  };
713
761
 
714
- // src/core/asyncResultList.ts
715
- var AsyncResultList = class {
762
+ // src/core/asyncResultCollection.ts
763
+ var AsyncResultCollection = class {
716
764
  _list = /* @__PURE__ */ new Map();
717
765
  _listeners = /* @__PURE__ */ new Set();
718
766
  _state = "all-settled";
@@ -767,6 +815,34 @@ var AsyncResultList = class {
767
815
  this._listeners.delete(listener);
768
816
  };
769
817
  }
818
+ /**
819
+ * Adds a listener that gets called whenever any item in the AsyncResultList succeeds.
820
+ * @param listener the function to call when an item succeeds
821
+ * @returns a function to unsubscribe the listener
822
+ */
823
+ onItemSuccess(listener) {
824
+ return this.listen((taskQueue) => {
825
+ for (const item of taskQueue._list.values()) {
826
+ if (item.result.isSuccess()) {
827
+ listener(item.result, item.key);
828
+ }
829
+ }
830
+ });
831
+ }
832
+ /**
833
+ * Adds a listener that gets called whenever any item in the AsyncResultList errors.
834
+ * @param listener the function to call when an item errors
835
+ * @returns a function to unsubscribe the listener
836
+ */
837
+ onItemError(listener) {
838
+ return this.listen((taskQueue) => {
839
+ for (const item of taskQueue._list.values()) {
840
+ if (item.result.isError()) {
841
+ listener(item.result, item.key);
842
+ }
843
+ }
844
+ });
845
+ }
770
846
  // === Managing tasks ===
771
847
  /**
772
848
  * Adds an AsyncResult task to the list.
@@ -1066,7 +1142,7 @@ function delay(ms) {
1066
1142
  // Annotate the CommonJS export names for ESM import in node:
1067
1143
  0 && (module.exports = {
1068
1144
  AsyncResult,
1069
- AsyncResultList,
1145
+ AsyncResultCollection,
1070
1146
  ErrorBase,
1071
1147
  KeyedAsyncCache,
1072
1148
  Result,