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.
- package/CHANGELOG.md +13 -0
- package/dist/core/index.d.mts +22 -2
- package/dist/core/index.d.ts +22 -2
- package/dist/core/index.js +42 -13
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +42 -13
- package/dist/core/index.mjs.map +1 -1
- package/dist/vue/index.d.mts +137 -52
- package/dist/vue/index.d.ts +137 -52
- package/dist/vue/index.js +30 -50
- package/dist/vue/index.js.map +1 -1
- package/dist/vue/index.mjs +30 -50
- package/dist/vue/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/vue/index.d.mts
CHANGED
|
@@ -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
|
-
}
|
|
135
|
-
readonly
|
|
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
|
-
}
|
|
239
|
-
readonly
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
347
|
-
*
|
|
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
|
|
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
|
-
}
|
|
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<{}>, {},
|
|
442
|
+
}>> & Readonly<{}>, {}, SlotsType<CustomSlots<E> & {
|
|
443
|
+
default: {
|
|
444
|
+
value: T;
|
|
445
|
+
};
|
|
446
|
+
}>, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
362
447
|
|
|
363
|
-
export {
|
|
448
|
+
export { type LazyActionRef, makeAsyncResultLoader, useAction, useAsyncResultList, useAsyncResultRef, useAsyncResultRefFromPromise, useGenerator, useLazyAction, useLazyGenerator, useReactiveChain, useReactiveGenerator };
|
package/dist/vue/index.d.ts
CHANGED
|
@@ -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
|
-
}
|
|
135
|
-
readonly
|
|
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
|
-
}
|
|
239
|
-
readonly
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
347
|
-
*
|
|
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
|
|
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
|
-
}
|
|
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<{}>, {},
|
|
442
|
+
}>> & Readonly<{}>, {}, SlotsType<CustomSlots<E> & {
|
|
443
|
+
default: {
|
|
444
|
+
value: T;
|
|
445
|
+
};
|
|
446
|
+
}>, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
362
447
|
|
|
363
|
-
export {
|
|
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
|
-
|
|
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
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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
|