-
Notifications
You must be signed in to change notification settings - Fork 0
Closed
Labels
[STAGE-2] incomplete implementationRemove this label when implementation is completeRemove this label when implementation is complete[STAGE-2] not fully covered by tests yetRemove this label when tests are verified to cover the implementationRemove this label when tests are verified to cover the implementation[STAGE-2] unresolved discussions leftRemove this label when all critical discussions are resolved on the issueRemove this label when all critical discussions are resolved on the issue[STAGE-3] docs changes not added yetRemove this label when the necessary documentation for the feature / change is addedRemove this label when the necessary documentation for the feature / change is added[STAGE-3] missing 2 reviews for RFC PRsRemove this label when at least 2 core team members reviewed and approved the RFC implementationRemove this label when at least 2 core team members reviewed and approved the RFC implementation
Description
Champion
What's the motivation for this proposal?
Summary
Replace useAsyncComputed$ with a new useAsync$ that unifies async computation, observable values, polling, and eager cleanup, while aligning closer to useSignal semantics.
Motivation
Current useAsyncComputed$ overlaps with useResource$ but neither are great.
A more powerful, writable async primitive would better support data fetching, streaming, auto-updating values, and background calculations.
Proposal
Rename useAsyncComputed$ to useAsync$:
useAsync$<T>(
callback: (ctx: { track: TrackFn, cleanup: CleanupFn, poll: PollFn }) => Promise<T> | T,
options?: {
initial?: T | (() => T); // like useSignal; prevents throw on read when uninitialized
eagerCleanup?: boolean; // run cleanup next tick when subscribers drop to 0
awaitPrevious?: boolean; // wait for previous invocation to complete before running again
pollMs?: number; // re-run after N ms if subscribers exist
timeout?: number; // abort after timeout
}
): AsyncSignal<unknown>;Key changes:
- Writable result –
result.value = …updates subscribers directly; clears loading/error state. - Error handling –
result.error = …propagates error on read. - Initial value – optional
initialavoids throw when reading before first resolution. - Eager cleanup – cleanup runs immediately (next tick) when no subscribers remain.
- Polling – via
pollMs: numberoption orpoll(ms)callback for periodic re-execution; use.invalidate()as before to do it manually.
Example
const data = useAsync$(({ cleanup }) => {
const channel = await makeChannel();
channel.on('data', d => data.value = d); // push updates
channel.on('error', e => data.error = e); // propagate errors
cleanup(() => channel.close());
return 'PENDING';
}, { eagerCleanup: true });Benefits
- Single primitive for async data, observables, polling, and background tasks.
- Consistent with
useSignalmental model. - Reduces need for separate
useResource$or custom observables. - Enables streaming/server-sent events, WebSocket handling, and auto-refetching patterns out of the box.
Discussion points
- Should
pollbe an option, callback, both, or neither?
Addition: generators
The callback should also be able to be a generator function, it should be wrapped so that every invocation updates the value.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
[STAGE-2] incomplete implementationRemove this label when implementation is completeRemove this label when implementation is complete[STAGE-2] not fully covered by tests yetRemove this label when tests are verified to cover the implementationRemove this label when tests are verified to cover the implementation[STAGE-2] unresolved discussions leftRemove this label when all critical discussions are resolved on the issueRemove this label when all critical discussions are resolved on the issue[STAGE-3] docs changes not added yetRemove this label when the necessary documentation for the feature / change is addedRemove this label when the necessary documentation for the feature / change is added[STAGE-3] missing 2 reviews for RFC PRsRemove this label when at least 2 core team members reviewed and approved the RFC implementationRemove this label when at least 2 core team members reviewed and approved the RFC implementation
Type
Projects
Status
Released as Stable (STAGE 5)