unwrapped 0.1.6 → 0.1.8

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,7 +1,7 @@
1
1
  import * as unwrapped_core from 'unwrapped/core';
2
2
  import { ErrorBase, AsyncResult, Result, FlatChainStep, Action, AsyncResultGenerator, AsyncResultList } from 'unwrapped/core';
3
3
  import * as vue from 'vue';
4
- import { Ref, WatchSource, VNode } from 'vue';
4
+ import { Ref, WatchSource, VNode, SlotsType } from 'vue';
5
5
 
6
6
  interface ReactiveProcessOptions {
7
7
  immediate: boolean;
@@ -89,6 +89,55 @@ declare function useReactiveGenerator<Inputs, T, E extends ErrorBase = ErrorBase
89
89
  */
90
90
  declare function useAsyncResultList<T = any, E extends ErrorBase = ErrorBase>(): Ref<{
91
91
  readonly tasks: Map<string, {
92
+ key: string;
93
+ result: {
94
+ state: {
95
+ status: "idle";
96
+ } | {
97
+ status: "loading";
98
+ promise: {
99
+ then: <TResult1 = Result<T, E>, TResult2 = never>(onfulfilled?: ((value: Result<T, E>) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) => Promise<TResult1 | TResult2>;
100
+ catch: <TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null | undefined) => Promise<Result<T, E> | TResult>;
101
+ finally: (onfinally?: (() => void) | null | undefined) => Promise<Result<T, E>>;
102
+ readonly [Symbol.toStringTag]: string;
103
+ };
104
+ } | {
105
+ status: "success";
106
+ value: vue.UnwrapRef<T>;
107
+ } | {
108
+ status: "error";
109
+ error: vue.UnwrapRef<E>;
110
+ };
111
+ isSuccess: () => boolean;
112
+ isError: () => boolean;
113
+ isIdle: () => boolean;
114
+ isLoading: () => boolean;
115
+ unwrapOrNull: () => T | null;
116
+ unwrapOrThrow: () => T;
117
+ unwrapErrorOrNull: () => E | null;
118
+ updateFromValue: (value: T) => AsyncResult<T, E>;
119
+ updateFromError: (error: E) => AsyncResult<T, E>;
120
+ updateFromValuePromise: (promise: Promise<T>) => AsyncResult<T, E>;
121
+ waitForSettled: () => Promise<AsyncResult<T, E>>;
122
+ toResultPromise: () => Promise<Result<T, E>>;
123
+ toValueOrThrowPromise: () => Promise<T>;
124
+ toValueOrNullPromise: () => Promise<T | null>;
125
+ updateFromResultPromise: (promise: Promise<Result<T, E>>) => AsyncResult<T, E>;
126
+ listen: (listener: unwrapped_core.AsyncResultListener<T, E>, immediate?: boolean) => () => void;
127
+ listenUntilSettled: (listener: unwrapped_core.AsyncResultListener<T, E>, immediate?: boolean) => () => void;
128
+ mirror: (other: AsyncResult<T, E>) => () => void;
129
+ mirrorUntilSettled: (other: AsyncResult<T, E>) => () => void;
130
+ chain: <O, E2 extends ErrorBase = ErrorBase>(fn: unwrapped_core.ChainStep<T, O, E | E2>) => AsyncResult<O, E | E2>;
131
+ flatChain: <O, E2 extends ErrorBase = ErrorBase>(fn: FlatChainStep<T, O, E | E2>) => AsyncResult<O, E | E2>;
132
+ runInPlace: (generatorFunc: () => AsyncResultGenerator<T>) => AsyncResult<T, E>;
133
+ log: (name?: string) => void;
134
+ debug: (name?: string) => () => void;
135
+ [Symbol.iterator]: () => Generator<AsyncResult<T, E>, T, any>;
136
+ };
137
+ unsub: () => void;
138
+ }> & Omit<Map<string, unwrapped_core.AsyncResultListItem<T, E>>, keyof Map<any, any>>;
139
+ readonly length: number;
140
+ readonly items: {
92
141
  state: {
93
142
  status: "idle";
94
143
  } | {
@@ -131,9 +180,8 @@ declare function useAsyncResultList<T = any, E extends ErrorBase = ErrorBase>():
131
180
  log: (name?: string) => void;
132
181
  debug: (name?: string) => () => void;
133
182
  [Symbol.iterator]: () => Generator<AsyncResult<T, E>, T, any>;
134
- }> & Omit<Map<string, AsyncResult<T, E>>, keyof Map<any, any>>;
135
- readonly length: number;
136
- readonly items: {
183
+ }[];
184
+ readonly entries: [string, {
137
185
  state: {
138
186
  status: "idle";
139
187
  } | {
@@ -176,10 +224,12 @@ declare function useAsyncResultList<T = any, E extends ErrorBase = ErrorBase>():
176
224
  log: (name?: string) => void;
177
225
  debug: (name?: string) => () => void;
178
226
  [Symbol.iterator]: () => Generator<AsyncResult<T, E>, T, any>;
179
- }[];
227
+ }][];
180
228
  state: unwrapped_core.AsyncResultListState;
181
229
  listen: (listener: (taskQueue: AsyncResultList<T, E>) => void) => () => void;
182
230
  add: (key: string, task: AsyncResult<T, E>, removeOnSettle?: boolean) => AsyncResult<T, E>;
231
+ remove: (key: string) => boolean;
232
+ clear: () => void;
183
233
  anyLoading: () => boolean;
184
234
  getAllFiltered: (predicate: (task: AsyncResult<T, E>) => boolean) => AsyncResult<T, E>[];
185
235
  getAllFilteredAndMap: <U>(filterPredicate: (task: AsyncResult<T, E>) => boolean, mapFunc: (task: AsyncResult<T, E>) => U) => U[];
@@ -193,6 +243,55 @@ declare function useAsyncResultList<T = any, E extends ErrorBase = ErrorBase>():
193
243
  debug: (name?: string) => () => void;
194
244
  }, AsyncResultList<T, E> | {
195
245
  readonly tasks: Map<string, {
246
+ key: string;
247
+ result: {
248
+ state: {
249
+ status: "idle";
250
+ } | {
251
+ status: "loading";
252
+ promise: {
253
+ then: <TResult1 = Result<T, E>, TResult2 = never>(onfulfilled?: ((value: Result<T, E>) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) => Promise<TResult1 | TResult2>;
254
+ catch: <TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null | undefined) => Promise<Result<T, E> | TResult>;
255
+ finally: (onfinally?: (() => void) | null | undefined) => Promise<Result<T, E>>;
256
+ readonly [Symbol.toStringTag]: string;
257
+ };
258
+ } | {
259
+ status: "success";
260
+ value: vue.UnwrapRef<T>;
261
+ } | {
262
+ status: "error";
263
+ error: vue.UnwrapRef<E>;
264
+ };
265
+ isSuccess: () => boolean;
266
+ isError: () => boolean;
267
+ isIdle: () => boolean;
268
+ isLoading: () => boolean;
269
+ unwrapOrNull: () => T | null;
270
+ unwrapOrThrow: () => T;
271
+ unwrapErrorOrNull: () => E | null;
272
+ updateFromValue: (value: T) => AsyncResult<T, E>;
273
+ updateFromError: (error: E) => AsyncResult<T, E>;
274
+ updateFromValuePromise: (promise: Promise<T>) => AsyncResult<T, E>;
275
+ waitForSettled: () => Promise<AsyncResult<T, E>>;
276
+ toResultPromise: () => Promise<Result<T, E>>;
277
+ toValueOrThrowPromise: () => Promise<T>;
278
+ toValueOrNullPromise: () => Promise<T | null>;
279
+ updateFromResultPromise: (promise: Promise<Result<T, E>>) => AsyncResult<T, E>;
280
+ listen: (listener: unwrapped_core.AsyncResultListener<T, E>, immediate?: boolean) => () => void;
281
+ listenUntilSettled: (listener: unwrapped_core.AsyncResultListener<T, E>, immediate?: boolean) => () => void;
282
+ mirror: (other: AsyncResult<T, E>) => () => void;
283
+ mirrorUntilSettled: (other: AsyncResult<T, E>) => () => void;
284
+ chain: <O, E2 extends ErrorBase = ErrorBase>(fn: unwrapped_core.ChainStep<T, O, E | E2>) => AsyncResult<O, E | E2>;
285
+ flatChain: <O, E2 extends ErrorBase = ErrorBase>(fn: FlatChainStep<T, O, E | E2>) => AsyncResult<O, E | E2>;
286
+ runInPlace: (generatorFunc: () => AsyncResultGenerator<T>) => AsyncResult<T, E>;
287
+ log: (name?: string) => void;
288
+ debug: (name?: string) => () => void;
289
+ [Symbol.iterator]: () => Generator<AsyncResult<T, E>, T, any>;
290
+ };
291
+ unsub: () => void;
292
+ }> & Omit<Map<string, unwrapped_core.AsyncResultListItem<T, E>>, keyof Map<any, any>>;
293
+ readonly length: number;
294
+ readonly items: {
196
295
  state: {
197
296
  status: "idle";
198
297
  } | {
@@ -235,9 +334,8 @@ declare function useAsyncResultList<T = any, E extends ErrorBase = ErrorBase>():
235
334
  log: (name?: string) => void;
236
335
  debug: (name?: string) => () => void;
237
336
  [Symbol.iterator]: () => Generator<AsyncResult<T, E>, T, any>;
238
- }> & Omit<Map<string, AsyncResult<T, E>>, keyof Map<any, any>>;
239
- readonly length: number;
240
- readonly items: {
337
+ }[];
338
+ readonly entries: [string, {
241
339
  state: {
242
340
  status: "idle";
243
341
  } | {
@@ -280,10 +378,12 @@ declare function useAsyncResultList<T = any, E extends ErrorBase = ErrorBase>():
280
378
  log: (name?: string) => void;
281
379
  debug: (name?: string) => () => void;
282
380
  [Symbol.iterator]: () => Generator<AsyncResult<T, E>, T, any>;
283
- }[];
381
+ }][];
284
382
  state: unwrapped_core.AsyncResultListState;
285
383
  listen: (listener: (taskQueue: AsyncResultList<T, E>) => void) => () => void;
286
384
  add: (key: string, task: AsyncResult<T, E>, removeOnSettle?: boolean) => AsyncResult<T, E>;
385
+ remove: (key: string) => boolean;
386
+ clear: () => void;
287
387
  anyLoading: () => boolean;
288
388
  getAllFiltered: (predicate: (task: AsyncResult<T, E>) => boolean) => AsyncResult<T, E>[];
289
389
  getAllFilteredAndMap: <U>(filterPredicate: (task: AsyncResult<T, E>) => boolean, mapFunc: (task: AsyncResult<T, E>) => U) => U[];
@@ -297,67 +397,52 @@ declare function useAsyncResultList<T = any, E extends ErrorBase = ErrorBase>():
297
397
  debug: (name?: string) => () => void;
298
398
  }>;
299
399
 
300
- /**
301
- * A Vue component that displays different content based on the state of an AsyncResult.
302
- * It supports slots for 'loading', 'error', 'success' (default), and 'idle' states.
303
- *
304
- * @example
305
- * <AsyncResultLoader :result="myAsyncResult">
306
- * <template #loading>
307
- * <div>Loading data...</div>
308
- * </template>
309
- * <template #error="{ error }">
310
- * <div>Error occurred: {{ error.message }}</div>
311
- * </template>
312
- * <template #default="{ value }">
313
- * <div>Data loaded: {{ value }}</div>
314
- * </template>
315
- * <template #idle>
316
- * <div>Waiting to start...</div>
317
- * </template>
318
- * </AsyncResultLoader>
319
- */
320
- declare const AsyncResultLoader: vue.DefineComponent<vue.ExtractPropTypes<{
321
- result: {
322
- type: () => AsyncResult<unknown>;
323
- required: true;
324
- };
325
- }>, () => VNode<vue.RendererNode, vue.RendererElement, {
326
- [key: string]: any;
327
- }> | VNode<vue.RendererNode, vue.RendererElement, {
328
- [key: string]: any;
329
- }>[] | null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
330
- result: {
331
- type: () => AsyncResult<unknown>;
332
- required: true;
333
- };
334
- }>> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
335
400
  interface CustomSlots<E extends ErrorBase = ErrorBase> {
336
401
  loading?: () => VNode;
337
402
  error?: (props: {
338
403
  error: E;
339
404
  }) => VNode;
405
+ idle?: () => VNode;
340
406
  }
341
407
  /**
342
- * Builds a custom AsyncResultLoader component with predefined slots for loading and error states.
408
+ * Factory function to create a component that displays different content based on an AsyncResult's state. Provides slots for loading, error, idle, and success states and passes the relevant data to each slot, and are typed appropriately.
409
+ * @param slots predefined slots for loading, error, and idle states. Useful for not having to repeat the same template for displaying a framework-specific spinner while in loading state, or a custom error message.
410
+ * @param name Optional internal name for the component
411
+ * @returns An instantiable component that accepts an AsyncResult prop and a default slot for the success state.
343
412
  *
344
- * Useful for creating reusable components with consistent loading and error handling UI (eg. framework-specific spinners, etc...).
413
+ * @example
414
+ * // loaders.ts - Create reusable loader with default loading/error UI
415
+ * const MyLoader = makeAsyncResultLoader({
416
+ * loading: () => h(Spinner),
417
+ * error: ({ error }) => h(ErrorDisplay, { error }),
418
+ * idle: () => h('div', 'Ready')
419
+ * });
345
420
  *
346
- * @param slots the custom slots for loading and error states
347
- * @returns a Vue component that uses the provided slots
421
+ * // MyPage.vue - Use the loader with custom success content
422
+ * <MyLoader :result="myAsyncResult">
423
+ * <template #default="{ value }">
424
+ * <UserProfile :user="value" />
425
+ * </template>
426
+ * </MyLoader>
348
427
  */
349
- declare function buildCustomAsyncResultLoader<T, E extends ErrorBase = ErrorBase>(slots: CustomSlots<E>): vue.DefineComponent<vue.ExtractPropTypes<{
428
+ declare function makeAsyncResultLoader<T, E extends ErrorBase = ErrorBase>(slots: CustomSlots<E>, name?: string): vue.DefineComponent<vue.ExtractPropTypes<{
350
429
  result: {
351
430
  type: () => AsyncResult<T, E>;
352
431
  required: true;
353
432
  };
354
433
  }>, () => VNode<vue.RendererNode, vue.RendererElement, {
355
434
  [key: string]: any;
356
- }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
435
+ }> | VNode<vue.RendererNode, vue.RendererElement, {
436
+ [key: string]: any;
437
+ }>[], {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
357
438
  result: {
358
439
  type: () => AsyncResult<T, E>;
359
440
  required: true;
360
441
  };
361
- }>> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
442
+ }>> & Readonly<{}>, {}, SlotsType<CustomSlots<E> & {
443
+ default: {
444
+ value: T;
445
+ };
446
+ }>, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
362
447
 
363
- export { AsyncResultLoader, type LazyActionRef, buildCustomAsyncResultLoader, useAction, useAsyncResultList, useAsyncResultRef, useAsyncResultRefFromPromise, useGenerator, useLazyAction, useLazyGenerator, useReactiveChain, useReactiveGenerator };
448
+ export { type LazyActionRef, makeAsyncResultLoader, useAction, useAsyncResultList, useAsyncResultRef, useAsyncResultRefFromPromise, useGenerator, useLazyAction, useLazyGenerator, useReactiveChain, useReactiveGenerator };
@@ -1,7 +1,7 @@
1
1
  import * as unwrapped_core from 'unwrapped/core';
2
2
  import { ErrorBase, AsyncResult, Result, FlatChainStep, Action, AsyncResultGenerator, AsyncResultList } from 'unwrapped/core';
3
3
  import * as vue from 'vue';
4
- import { Ref, WatchSource, VNode } from 'vue';
4
+ import { Ref, WatchSource, VNode, SlotsType } from 'vue';
5
5
 
6
6
  interface ReactiveProcessOptions {
7
7
  immediate: boolean;
@@ -89,6 +89,55 @@ declare function useReactiveGenerator<Inputs, T, E extends ErrorBase = ErrorBase
89
89
  */
90
90
  declare function useAsyncResultList<T = any, E extends ErrorBase = ErrorBase>(): Ref<{
91
91
  readonly tasks: Map<string, {
92
+ key: string;
93
+ result: {
94
+ state: {
95
+ status: "idle";
96
+ } | {
97
+ status: "loading";
98
+ promise: {
99
+ then: <TResult1 = Result<T, E>, TResult2 = never>(onfulfilled?: ((value: Result<T, E>) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) => Promise<TResult1 | TResult2>;
100
+ catch: <TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null | undefined) => Promise<Result<T, E> | TResult>;
101
+ finally: (onfinally?: (() => void) | null | undefined) => Promise<Result<T, E>>;
102
+ readonly [Symbol.toStringTag]: string;
103
+ };
104
+ } | {
105
+ status: "success";
106
+ value: vue.UnwrapRef<T>;
107
+ } | {
108
+ status: "error";
109
+ error: vue.UnwrapRef<E>;
110
+ };
111
+ isSuccess: () => boolean;
112
+ isError: () => boolean;
113
+ isIdle: () => boolean;
114
+ isLoading: () => boolean;
115
+ unwrapOrNull: () => T | null;
116
+ unwrapOrThrow: () => T;
117
+ unwrapErrorOrNull: () => E | null;
118
+ updateFromValue: (value: T) => AsyncResult<T, E>;
119
+ updateFromError: (error: E) => AsyncResult<T, E>;
120
+ updateFromValuePromise: (promise: Promise<T>) => AsyncResult<T, E>;
121
+ waitForSettled: () => Promise<AsyncResult<T, E>>;
122
+ toResultPromise: () => Promise<Result<T, E>>;
123
+ toValueOrThrowPromise: () => Promise<T>;
124
+ toValueOrNullPromise: () => Promise<T | null>;
125
+ updateFromResultPromise: (promise: Promise<Result<T, E>>) => AsyncResult<T, E>;
126
+ listen: (listener: unwrapped_core.AsyncResultListener<T, E>, immediate?: boolean) => () => void;
127
+ listenUntilSettled: (listener: unwrapped_core.AsyncResultListener<T, E>, immediate?: boolean) => () => void;
128
+ mirror: (other: AsyncResult<T, E>) => () => void;
129
+ mirrorUntilSettled: (other: AsyncResult<T, E>) => () => void;
130
+ chain: <O, E2 extends ErrorBase = ErrorBase>(fn: unwrapped_core.ChainStep<T, O, E | E2>) => AsyncResult<O, E | E2>;
131
+ flatChain: <O, E2 extends ErrorBase = ErrorBase>(fn: FlatChainStep<T, O, E | E2>) => AsyncResult<O, E | E2>;
132
+ runInPlace: (generatorFunc: () => AsyncResultGenerator<T>) => AsyncResult<T, E>;
133
+ log: (name?: string) => void;
134
+ debug: (name?: string) => () => void;
135
+ [Symbol.iterator]: () => Generator<AsyncResult<T, E>, T, any>;
136
+ };
137
+ unsub: () => void;
138
+ }> & Omit<Map<string, unwrapped_core.AsyncResultListItem<T, E>>, keyof Map<any, any>>;
139
+ readonly length: number;
140
+ readonly items: {
92
141
  state: {
93
142
  status: "idle";
94
143
  } | {
@@ -131,9 +180,8 @@ declare function useAsyncResultList<T = any, E extends ErrorBase = ErrorBase>():
131
180
  log: (name?: string) => void;
132
181
  debug: (name?: string) => () => void;
133
182
  [Symbol.iterator]: () => Generator<AsyncResult<T, E>, T, any>;
134
- }> & Omit<Map<string, AsyncResult<T, E>>, keyof Map<any, any>>;
135
- readonly length: number;
136
- readonly items: {
183
+ }[];
184
+ readonly entries: [string, {
137
185
  state: {
138
186
  status: "idle";
139
187
  } | {
@@ -176,10 +224,12 @@ declare function useAsyncResultList<T = any, E extends ErrorBase = ErrorBase>():
176
224
  log: (name?: string) => void;
177
225
  debug: (name?: string) => () => void;
178
226
  [Symbol.iterator]: () => Generator<AsyncResult<T, E>, T, any>;
179
- }[];
227
+ }][];
180
228
  state: unwrapped_core.AsyncResultListState;
181
229
  listen: (listener: (taskQueue: AsyncResultList<T, E>) => void) => () => void;
182
230
  add: (key: string, task: AsyncResult<T, E>, removeOnSettle?: boolean) => AsyncResult<T, E>;
231
+ remove: (key: string) => boolean;
232
+ clear: () => void;
183
233
  anyLoading: () => boolean;
184
234
  getAllFiltered: (predicate: (task: AsyncResult<T, E>) => boolean) => AsyncResult<T, E>[];
185
235
  getAllFilteredAndMap: <U>(filterPredicate: (task: AsyncResult<T, E>) => boolean, mapFunc: (task: AsyncResult<T, E>) => U) => U[];
@@ -193,6 +243,55 @@ declare function useAsyncResultList<T = any, E extends ErrorBase = ErrorBase>():
193
243
  debug: (name?: string) => () => void;
194
244
  }, AsyncResultList<T, E> | {
195
245
  readonly tasks: Map<string, {
246
+ key: string;
247
+ result: {
248
+ state: {
249
+ status: "idle";
250
+ } | {
251
+ status: "loading";
252
+ promise: {
253
+ then: <TResult1 = Result<T, E>, TResult2 = never>(onfulfilled?: ((value: Result<T, E>) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) => Promise<TResult1 | TResult2>;
254
+ catch: <TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null | undefined) => Promise<Result<T, E> | TResult>;
255
+ finally: (onfinally?: (() => void) | null | undefined) => Promise<Result<T, E>>;
256
+ readonly [Symbol.toStringTag]: string;
257
+ };
258
+ } | {
259
+ status: "success";
260
+ value: vue.UnwrapRef<T>;
261
+ } | {
262
+ status: "error";
263
+ error: vue.UnwrapRef<E>;
264
+ };
265
+ isSuccess: () => boolean;
266
+ isError: () => boolean;
267
+ isIdle: () => boolean;
268
+ isLoading: () => boolean;
269
+ unwrapOrNull: () => T | null;
270
+ unwrapOrThrow: () => T;
271
+ unwrapErrorOrNull: () => E | null;
272
+ updateFromValue: (value: T) => AsyncResult<T, E>;
273
+ updateFromError: (error: E) => AsyncResult<T, E>;
274
+ updateFromValuePromise: (promise: Promise<T>) => AsyncResult<T, E>;
275
+ waitForSettled: () => Promise<AsyncResult<T, E>>;
276
+ toResultPromise: () => Promise<Result<T, E>>;
277
+ toValueOrThrowPromise: () => Promise<T>;
278
+ toValueOrNullPromise: () => Promise<T | null>;
279
+ updateFromResultPromise: (promise: Promise<Result<T, E>>) => AsyncResult<T, E>;
280
+ listen: (listener: unwrapped_core.AsyncResultListener<T, E>, immediate?: boolean) => () => void;
281
+ listenUntilSettled: (listener: unwrapped_core.AsyncResultListener<T, E>, immediate?: boolean) => () => void;
282
+ mirror: (other: AsyncResult<T, E>) => () => void;
283
+ mirrorUntilSettled: (other: AsyncResult<T, E>) => () => void;
284
+ chain: <O, E2 extends ErrorBase = ErrorBase>(fn: unwrapped_core.ChainStep<T, O, E | E2>) => AsyncResult<O, E | E2>;
285
+ flatChain: <O, E2 extends ErrorBase = ErrorBase>(fn: FlatChainStep<T, O, E | E2>) => AsyncResult<O, E | E2>;
286
+ runInPlace: (generatorFunc: () => AsyncResultGenerator<T>) => AsyncResult<T, E>;
287
+ log: (name?: string) => void;
288
+ debug: (name?: string) => () => void;
289
+ [Symbol.iterator]: () => Generator<AsyncResult<T, E>, T, any>;
290
+ };
291
+ unsub: () => void;
292
+ }> & Omit<Map<string, unwrapped_core.AsyncResultListItem<T, E>>, keyof Map<any, any>>;
293
+ readonly length: number;
294
+ readonly items: {
196
295
  state: {
197
296
  status: "idle";
198
297
  } | {
@@ -235,9 +334,8 @@ declare function useAsyncResultList<T = any, E extends ErrorBase = ErrorBase>():
235
334
  log: (name?: string) => void;
236
335
  debug: (name?: string) => () => void;
237
336
  [Symbol.iterator]: () => Generator<AsyncResult<T, E>, T, any>;
238
- }> & Omit<Map<string, AsyncResult<T, E>>, keyof Map<any, any>>;
239
- readonly length: number;
240
- readonly items: {
337
+ }[];
338
+ readonly entries: [string, {
241
339
  state: {
242
340
  status: "idle";
243
341
  } | {
@@ -280,10 +378,12 @@ declare function useAsyncResultList<T = any, E extends ErrorBase = ErrorBase>():
280
378
  log: (name?: string) => void;
281
379
  debug: (name?: string) => () => void;
282
380
  [Symbol.iterator]: () => Generator<AsyncResult<T, E>, T, any>;
283
- }[];
381
+ }][];
284
382
  state: unwrapped_core.AsyncResultListState;
285
383
  listen: (listener: (taskQueue: AsyncResultList<T, E>) => void) => () => void;
286
384
  add: (key: string, task: AsyncResult<T, E>, removeOnSettle?: boolean) => AsyncResult<T, E>;
385
+ remove: (key: string) => boolean;
386
+ clear: () => void;
287
387
  anyLoading: () => boolean;
288
388
  getAllFiltered: (predicate: (task: AsyncResult<T, E>) => boolean) => AsyncResult<T, E>[];
289
389
  getAllFilteredAndMap: <U>(filterPredicate: (task: AsyncResult<T, E>) => boolean, mapFunc: (task: AsyncResult<T, E>) => U) => U[];
@@ -297,67 +397,52 @@ declare function useAsyncResultList<T = any, E extends ErrorBase = ErrorBase>():
297
397
  debug: (name?: string) => () => void;
298
398
  }>;
299
399
 
300
- /**
301
- * A Vue component that displays different content based on the state of an AsyncResult.
302
- * It supports slots for 'loading', 'error', 'success' (default), and 'idle' states.
303
- *
304
- * @example
305
- * <AsyncResultLoader :result="myAsyncResult">
306
- * <template #loading>
307
- * <div>Loading data...</div>
308
- * </template>
309
- * <template #error="{ error }">
310
- * <div>Error occurred: {{ error.message }}</div>
311
- * </template>
312
- * <template #default="{ value }">
313
- * <div>Data loaded: {{ value }}</div>
314
- * </template>
315
- * <template #idle>
316
- * <div>Waiting to start...</div>
317
- * </template>
318
- * </AsyncResultLoader>
319
- */
320
- declare const AsyncResultLoader: vue.DefineComponent<vue.ExtractPropTypes<{
321
- result: {
322
- type: () => AsyncResult<unknown>;
323
- required: true;
324
- };
325
- }>, () => VNode<vue.RendererNode, vue.RendererElement, {
326
- [key: string]: any;
327
- }> | VNode<vue.RendererNode, vue.RendererElement, {
328
- [key: string]: any;
329
- }>[] | null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
330
- result: {
331
- type: () => AsyncResult<unknown>;
332
- required: true;
333
- };
334
- }>> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
335
400
  interface CustomSlots<E extends ErrorBase = ErrorBase> {
336
401
  loading?: () => VNode;
337
402
  error?: (props: {
338
403
  error: E;
339
404
  }) => VNode;
405
+ idle?: () => VNode;
340
406
  }
341
407
  /**
342
- * Builds a custom AsyncResultLoader component with predefined slots for loading and error states.
408
+ * Factory function to create a component that displays different content based on an AsyncResult's state. Provides slots for loading, error, idle, and success states and passes the relevant data to each slot, and are typed appropriately.
409
+ * @param slots predefined slots for loading, error, and idle states. Useful for not having to repeat the same template for displaying a framework-specific spinner while in loading state, or a custom error message.
410
+ * @param name Optional internal name for the component
411
+ * @returns An instantiable component that accepts an AsyncResult prop and a default slot for the success state.
343
412
  *
344
- * Useful for creating reusable components with consistent loading and error handling UI (eg. framework-specific spinners, etc...).
413
+ * @example
414
+ * // loaders.ts - Create reusable loader with default loading/error UI
415
+ * const MyLoader = makeAsyncResultLoader({
416
+ * loading: () => h(Spinner),
417
+ * error: ({ error }) => h(ErrorDisplay, { error }),
418
+ * idle: () => h('div', 'Ready')
419
+ * });
345
420
  *
346
- * @param slots the custom slots for loading and error states
347
- * @returns a Vue component that uses the provided slots
421
+ * // MyPage.vue - Use the loader with custom success content
422
+ * <MyLoader :result="myAsyncResult">
423
+ * <template #default="{ value }">
424
+ * <UserProfile :user="value" />
425
+ * </template>
426
+ * </MyLoader>
348
427
  */
349
- declare function buildCustomAsyncResultLoader<T, E extends ErrorBase = ErrorBase>(slots: CustomSlots<E>): vue.DefineComponent<vue.ExtractPropTypes<{
428
+ declare function makeAsyncResultLoader<T, E extends ErrorBase = ErrorBase>(slots: CustomSlots<E>, name?: string): vue.DefineComponent<vue.ExtractPropTypes<{
350
429
  result: {
351
430
  type: () => AsyncResult<T, E>;
352
431
  required: true;
353
432
  };
354
433
  }>, () => VNode<vue.RendererNode, vue.RendererElement, {
355
434
  [key: string]: any;
356
- }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
435
+ }> | VNode<vue.RendererNode, vue.RendererElement, {
436
+ [key: string]: any;
437
+ }>[], {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
357
438
  result: {
358
439
  type: () => AsyncResult<T, E>;
359
440
  required: true;
360
441
  };
361
- }>> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
442
+ }>> & Readonly<{}>, {}, SlotsType<CustomSlots<E> & {
443
+ default: {
444
+ value: T;
445
+ };
446
+ }>, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
362
447
 
363
- export { AsyncResultLoader, type LazyActionRef, buildCustomAsyncResultLoader, useAction, useAsyncResultList, useAsyncResultRef, useAsyncResultRefFromPromise, useGenerator, useLazyAction, useLazyGenerator, useReactiveChain, useReactiveGenerator };
448
+ export { type LazyActionRef, makeAsyncResultLoader, useAction, useAsyncResultList, useAsyncResultRef, useAsyncResultRefFromPromise, useGenerator, useLazyAction, useLazyGenerator, useReactiveChain, useReactiveGenerator };
package/dist/vue/index.js CHANGED
@@ -20,8 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/vue/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- AsyncResultLoader: () => AsyncResultLoader,
24
- buildCustomAsyncResultLoader: () => buildCustomAsyncResultLoader,
23
+ makeAsyncResultLoader: () => makeAsyncResultLoader,
25
24
  useAction: () => useAction,
26
25
  useAsyncResultList: () => useAsyncResultList,
27
26
  useAsyncResultRef: () => useAsyncResultRef,
@@ -104,64 +103,45 @@ function useAsyncResultList() {
104
103
 
105
104
  // src/vue/components/asyncResultLoader.ts
106
105
  var import_vue2 = require("vue");
107
- var AsyncResultLoader = (0, import_vue2.defineComponent)({
108
- name: "AsyncResultLoader",
109
- props: {
110
- result: {
111
- type: Object,
112
- required: true
113
- }
114
- },
115
- setup(props, { slots }) {
116
- let resultRef = useAsyncResultRef(props.result);
117
- (0, import_vue2.watch)(
118
- () => props.result,
119
- (newResult, oldResult) => {
120
- if (newResult === oldResult) return;
121
- resultRef = useAsyncResultRef(newResult);
122
- },
123
- { immediate: true }
124
- );
125
- return () => {
126
- const s = resultRef.value.state;
127
- switch (s.status) {
128
- case "loading":
129
- return slots.loading ? slots.loading() : (0, import_vue2.h)("div", { class: "loading" }, "Loading\u2026");
130
- case "error":
131
- return slots.error ? slots.error({ error: s.error }) : (0, import_vue2.h)("div", { class: "error" }, `Error: ${s.error}`);
132
- case "success":
133
- return slots.default ? slots.default({ value: s.value }) : null;
134
- default:
135
- return slots.idle ? slots.idle() : (0, import_vue2.h)("div", { class: "idle" }, "Idle");
136
- }
137
- };
138
- }
139
- });
140
- function buildCustomAsyncResultLoader(slots) {
141
- const comp = (0, import_vue2.defineComponent)({
142
- name: "CustomAsyncResultLoader",
106
+ var import_core2 = require("unwrapped/core");
107
+ function makeAsyncResultLoader(slots, name = "AsyncResultLoader") {
108
+ return (0, import_vue2.defineComponent)({
109
+ name,
143
110
  props: {
144
111
  result: {
145
112
  type: Object,
146
113
  required: true
147
114
  }
148
115
  },
116
+ slots: Object,
149
117
  setup(props, context) {
118
+ let resultRef = useAsyncResultRef(props.result);
119
+ (0, import_vue2.watch)(
120
+ () => props.result,
121
+ (newResult, oldResult) => {
122
+ if (newResult === oldResult) return;
123
+ resultRef = useAsyncResultRef(newResult);
124
+ },
125
+ { immediate: true }
126
+ );
150
127
  return () => {
151
- const renderLoading = context.slots.loading ?? slots.loading ?? (() => void 0);
152
- const renderError = context.slots.error ?? slots.error ?? (() => void 0);
153
- return (0, import_vue2.h)(
154
- AsyncResultLoader,
155
- { result: props.result },
156
- {
157
- default: context.slots.default ? (propsDefault) => context.slots.default(propsDefault) : void 0,
158
- loading: () => renderLoading(),
159
- error: ((propsError) => renderError(propsError))
160
- }
161
- );
128
+ const s = resultRef.value.state;
129
+ const renderDefault = context.slots.default ?? (() => (0, import_vue2.h)("div", { class: "success" }, "Success"));
130
+ const renderError = context.slots.error ?? slots.error ?? (() => (0, import_vue2.h)("div", { class: "error" }, "Error"));
131
+ const renderLoading = context.slots.loading ?? slots.loading ?? (() => (0, import_vue2.h)("div", { class: "loading" }, "Loading\u2026"));
132
+ const renderIdle = context.slots.idle ?? slots.idle ?? (() => (0, import_vue2.h)("div", { class: "idle" }, "Idle"));
133
+ switch (s.status) {
134
+ case "loading":
135
+ return renderLoading();
136
+ case "error":
137
+ return renderError({ error: s.error });
138
+ case "success":
139
+ return renderDefault({ value: s.value });
140
+ default:
141
+ return renderIdle();
142
+ }
162
143
  };
163
144
  }
164
145
  });
165
- return comp;
166
146
  }
167
147
  //# sourceMappingURL=index.js.map