unwrapped 0.1.8 → 0.1.10

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,17 @@
1
1
  # unwrapped
2
2
 
3
+ ## 0.1.10
4
+
5
+ ### Patch Changes
6
+
7
+ - 43b4f87: Added utility functions in KeyedAsyncCache
8
+
9
+ ## 0.1.9
10
+
11
+ ### Patch Changes
12
+
13
+ - 07818f4: Added onSuccess and onError listeners
14
+
3
15
  ## 0.1.8
4
16
 
5
17
  ### 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
@@ -607,6 +667,13 @@ declare class AsyncResultList<T = any, E extends ErrorBase = ErrorBase> {
607
667
  type KeyedAsyncCacheRefetchOptions = {
608
668
  policy: 'refetch' | 'if-error' | 'no-refetch';
609
669
  };
670
+ type CacheItem<P, V, E extends ErrorBase = ErrorBase> = {
671
+ result: AsyncResult<V, E>;
672
+ fetcherParams: P;
673
+ valid: boolean;
674
+ lastFetched?: number;
675
+ ttl?: number;
676
+ };
610
677
  /**
611
678
  * A cache for asynchronous operations that maps parameter sets to their corresponding AsyncResult.
612
679
  * Supports automatic refetching based on specified policies.
@@ -668,8 +735,23 @@ declare class KeyedAsyncCache<P, V, E extends ErrorBase = ErrorBase> {
668
735
  * Invalidates all cache entries.
669
736
  */
670
737
  invalidateAll(): void;
738
+ /**
739
+ * Gets all cache items.
740
+ * @returns an array of all cache items
741
+ */
742
+ get items(): CacheItem<P, V, E>[];
743
+ /**
744
+ * Gets the number of cache items.
745
+ * @returns the number of cache items
746
+ */
747
+ get size(): number;
748
+ /**
749
+ * Gets all cache items with successful results.
750
+ * @returns an array of cache items with successful results
751
+ */
752
+ get successfulItems(): CacheItem<P, V, E>[];
671
753
  }
672
754
 
673
755
  declare function delay(ms: number): AsyncResult<true>;
674
756
 
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 };
757
+ 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
@@ -607,6 +667,13 @@ declare class AsyncResultList<T = any, E extends ErrorBase = ErrorBase> {
607
667
  type KeyedAsyncCacheRefetchOptions = {
608
668
  policy: 'refetch' | 'if-error' | 'no-refetch';
609
669
  };
670
+ type CacheItem<P, V, E extends ErrorBase = ErrorBase> = {
671
+ result: AsyncResult<V, E>;
672
+ fetcherParams: P;
673
+ valid: boolean;
674
+ lastFetched?: number;
675
+ ttl?: number;
676
+ };
610
677
  /**
611
678
  * A cache for asynchronous operations that maps parameter sets to their corresponding AsyncResult.
612
679
  * Supports automatic refetching based on specified policies.
@@ -668,8 +735,23 @@ declare class KeyedAsyncCache<P, V, E extends ErrorBase = ErrorBase> {
668
735
  * Invalidates all cache entries.
669
736
  */
670
737
  invalidateAll(): void;
738
+ /**
739
+ * Gets all cache items.
740
+ * @returns an array of all cache items
741
+ */
742
+ get items(): CacheItem<P, V, E>[];
743
+ /**
744
+ * Gets the number of cache items.
745
+ * @returns the number of cache items
746
+ */
747
+ get size(): number;
748
+ /**
749
+ * Gets all cache items with successful results.
750
+ * @returns an array of cache items with successful results
751
+ */
752
+ get successfulItems(): CacheItem<P, V, E>[];
671
753
  }
672
754
 
673
755
  declare function delay(ms: number): AsyncResult<true>;
674
756
 
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 };
757
+ 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.
@@ -1055,6 +1131,27 @@ var KeyedAsyncCache = class {
1055
1131
  cacheItem.valid = false;
1056
1132
  }
1057
1133
  }
1134
+ /**
1135
+ * Gets all cache items.
1136
+ * @returns an array of all cache items
1137
+ */
1138
+ get items() {
1139
+ return Array.from(this._cache.values());
1140
+ }
1141
+ /**
1142
+ * Gets the number of cache items.
1143
+ * @returns the number of cache items
1144
+ */
1145
+ get size() {
1146
+ return this._cache.size;
1147
+ }
1148
+ /**
1149
+ * Gets all cache items with successful results.
1150
+ * @returns an array of cache items with successful results
1151
+ */
1152
+ get successfulItems() {
1153
+ return Array.from(this._cache.values()).filter((item) => item.result.isSuccess());
1154
+ }
1058
1155
  };
1059
1156
 
1060
1157
  // src/core/utils.ts
@@ -1066,7 +1163,7 @@ function delay(ms) {
1066
1163
  // Annotate the CommonJS export names for ESM import in node:
1067
1164
  0 && (module.exports = {
1068
1165
  AsyncResult,
1069
- AsyncResultList,
1166
+ AsyncResultCollection,
1070
1167
  ErrorBase,
1071
1168
  KeyedAsyncCache,
1072
1169
  Result,