Comparing version 0.0.1-alpha-10 to 0.0.1-alpha-11
@@ -47,6 +47,2 @@ type Resolver<T> = (payload: T) => any; | ||
interface Disposable { | ||
dispose: () => void; | ||
} | ||
interface ReadableState<T> { | ||
@@ -123,9 +119,9 @@ events: { | ||
type SyncSelector<T> = ReadableState<T> & Disposable; | ||
type AsyncSelector<T> = ReadableAsyncState<T> & Disposable; | ||
type SyncSelector<T> = ReadableState<T>; | ||
type AsyncSelector<T> = ReadableAsyncState<T>; | ||
type ContainsAsync<T extends any[]> = T extends [infer First, ...infer Rest] ? First extends ReadableAsyncState<any> ? true : ContainsAsync<Rest> : false; | ||
type Return<T extends any[], U> = ContainsAsync<T> extends true ? AsyncSelector<U> : SyncSelector<U>; | ||
type Return<T extends any[], U> = U extends PromiseLike<infer P> ? AsyncSelector<P> : ContainsAsync<T> extends true ? AsyncSelector<U> : SyncSelector<U>; | ||
declare const selector: <T extends any[], U>(states: [...T], predicate: (...values: { [K in keyof T]: InferReadableType<T[K]>; }) => U) => Return<T, U>; | ||
export { AsyncSetter, AsyncState, AsyncStatus, AsyncValue, AwaitableEvent, FamilyState, InferReadableType, ReadableAsyncState, ReadableState, Setter, State, WritableAsyncState, WritableState, action, asyncState, delay, familyState, fork, isReadableAsyncState, rejectAfter, scenario, scenarioOnEvery, scenarioOnce, selector, state }; |
@@ -248,3 +248,6 @@ 'use strict'; | ||
const asyncSelector = (states, predicate) => { | ||
let mounted = true; | ||
let error; | ||
let value; | ||
let isLoading = true; | ||
let nextVersion = -1; | ||
const events = { | ||
@@ -256,11 +259,42 @@ failed: new AwaitableEvent(), | ||
const getStatus = () => getCommonStatus(states); | ||
const get = () => { | ||
scenario(async () => { | ||
nextVersion++; | ||
const status = getStatus(); | ||
if (status !== AsyncStatus.LOADED) { | ||
return void 0; | ||
const asyncStates = states.filter(isReadableAsyncState); | ||
const errors = asyncStates.map((state) => state.getAsync().error).filter(Boolean); | ||
if (errors.length > 0) { | ||
error = new AggregateError(errors); | ||
value = void 0; | ||
isLoading = status === AsyncStatus.LOADING; | ||
queueMicrotask(() => events.changed.emit(value)); | ||
return; | ||
} | ||
const values = states.map((state) => state.get()); | ||
return predicate(...values); | ||
}; | ||
const getAsync = () => ({}); | ||
if (status === AsyncStatus.LOADED) { | ||
const values = states.map((state) => state.get()); | ||
fork(async () => { | ||
isLoading = true; | ||
let version = nextVersion; | ||
try { | ||
const newValue = await predicate(...values); | ||
if (version === nextVersion && newValue !== value) { | ||
error = void 0; | ||
value = newValue; | ||
} | ||
} catch (error2) { | ||
if (version === nextVersion) { | ||
error2 = void 0; | ||
value = void 0; | ||
} | ||
} finally { | ||
if (version === nextVersion) { | ||
isLoading = false; | ||
queueMicrotask(() => events.changed.emit(value)); | ||
} | ||
} | ||
}); | ||
} | ||
await Promise.race(states.map((state) => state.events.changed)); | ||
}); | ||
const get = () => value; | ||
const getAsync = () => ({ error, isLoading, value }); | ||
const getPromise = async () => { | ||
@@ -270,3 +304,3 @@ const values = await Promise.all( | ||
); | ||
return predicate(...values); | ||
return await predicate(...values); | ||
}; | ||
@@ -277,20 +311,4 @@ const then = async (resolve) => { | ||
}; | ||
const dispose = () => { | ||
mounted = false; | ||
}; | ||
(async () => { | ||
while (mounted) { | ||
await Promise.race(states.map((state) => state.events.changed)); | ||
const status = getStatus(); | ||
if (status === AsyncStatus.LOADING) { | ||
return; | ||
} | ||
queueMicrotask(() => { | ||
events.changed.emit(get()); | ||
}); | ||
} | ||
})(); | ||
return { | ||
events, | ||
dispose, | ||
get, | ||
@@ -305,3 +323,2 @@ getAsync, | ||
const syncSelector = (states, predicate) => { | ||
let mounted = true; | ||
const events = { | ||
@@ -318,16 +335,12 @@ changed: new AwaitableEvent() | ||
}; | ||
const dispose = () => { | ||
mounted = false; | ||
}; | ||
(async () => { | ||
while (mounted) { | ||
await Promise.race(states.map((state) => state.events.changed)); | ||
events.changed.emit(get()); | ||
} | ||
})(); | ||
return { events, dispose, get, then }; | ||
scenario(async () => { | ||
await Promise.race(states.map((state) => state.events.changed)); | ||
events.changed.emit(get()); | ||
}); | ||
return { events, get, then }; | ||
}; | ||
const selector = (states, predicate) => { | ||
const state = states.some((state2) => isReadableAsyncState(state2)) ? asyncSelector(states, predicate) : syncSelector(states, predicate); | ||
const isAsyncPredicate = predicate.constructor.name === "AsyncFunction"; | ||
const state = isAsyncPredicate || states.some((state2) => isReadableAsyncState(state2)) ? asyncSelector(states, predicate) : syncSelector(states, predicate); | ||
return state; | ||
@@ -334,0 +347,0 @@ }; |
{ | ||
"name": "awai", | ||
"version": "0.0.1-alpha-10", | ||
"version": "0.0.1-alpha-11", | ||
"author": "Yuriy Yakym", | ||
@@ -5,0 +5,0 @@ "description": "State management library", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
82895
755