URLStoreclass
Store a URL, e.g. https://top.com/a/b/c
new URLStore(url: PossibleURL, base?: PossibleURL)
Observable value containers for reactive state. A Store<T> holds a single current value, broadcasts changes to all active consumers, and integrates with React Suspense out of the box. Stores suppress duplicate emissions using deep equality, so consumers only see genuine changes.
Loading state — a store starts in a loading state represented internally by the NONE sentinel. Reading Store.value while loading throws a Promise (the store's internal DeferredSequence), which React Suspense catches and waits on. Reading Store.loading is safe and never throws.
Error state — setting Store.reason puts the store in an error state. Subsequent reads of .value throw that reason, which React error boundaries can catch.
Async iteration — Store<T> implements AsyncIterable<T>. Iterating with for await...of first emits the current value (if one exists), then emits each subsequent value as it changes. The iterator blocks between values using the store's internal DeferredSequence.
Duplicate suppression — deep equality is checked before emitting. Setting the same value twice only triggers one emission.
Starters — store.starter accepts a function that runs when the store has at least one active iterator and stops when none remain. Use this to wire up external subscriptions (e.g. a database realtime feed) that should only be active while something is listening.
Subclasses
ItemStore and QueryStore in the shelving/db module extend FetchStore directly, adding database-aware fetch and subscription logic.
Every store shares the same core: set .value, read it back (or for await it), and consumers see the change. The base Store page covers the full lifecycle; each subclass page covers its own helpers.
As an integration example, Store.through() bridges any AsyncIterable source into a store — it sets the store's value for each item yielded and re-yields it:
import { Store, NONE } from "shelving/store";
const store = new Store<number>(NONE);
async function connect(stream: AsyncIterable<number>) {
for await (const _ of store.through(stream)) {
// store.value is updated on each iteration; any consumers re-render
}
}Store a URL, e.g. https://top.com/a/b/c
new URLStore(url: PossibleURL, base?: PossibleURL)
Store that retains its most recent value and is async-iterable to allow values to be observed.
new Store<T, TT>(value: StoreInternal<T>)
Store a boolean value.
new BooleanStore(value: boolean = false)
Store an immutable array of items, with helpers to read and mutate its contents.
new ArrayStore<T>(value: PossibleArray<T> = [])
Store an absolute path, e.g. /a/b/c
new PathStore(path: AbsolutePath | RelativePath = ".", base: AbsolutePath = "/")
Store that fetches its values from a remote source on demand.
new FetchStore<T, TT>(value: T | typeof NONE, callback?: FetchCallback<TT>)
Store a data object, with helpers to read and update individual props.
new DataStore<T>()
Store a data object that may be undefined (e.g. a document that may not exist).
new OptionalDataStore<T>()
Store a dictionary object (string-keyed map of values), with helpers to read and mutate its entries.
new DictionaryStore<T>(value: PossibleDictionary<T> = EMPTY_DICTIONARY)
Store that fetches its values from a remote source by sending it a payload.
new PayloadFetchStore<P, R>(payload: P | typeof NONE, value: R | typeof NONE, callback?: PayloadFetchCallback<P, R>, debounce = 0)
Store that tracks its busy status via a separate this.busy store.
new BusyStore<T, TT>()
Any Store instance.
Store<any, any>
Synchronous values that a store natively knows how to process as inputs.
I | typeof SKIP | typeof NONE
Synchronous or asynchronous values that a store natively knows how to process as inputs.
StoreInput<I> | PromiseLike<StoreInput<I>>
Internal storage value for a store.
O | typeof NONE
Callback that sets a store's value (possibly asynchronously).
(...args: A) => AsyncStoreInput<I>
Reducer that receives a store's current value and returns the store's next value (possibly asynchronously).
(value: O, ...args: A) => AsyncStoreInput<I>
Callback that fetches the next value for a FetchStore.
(signal: AbortSignal) => StoreInput<T> | PromiseLike<StoreInput<T>>
Callback that fetches the next value for a PayloadFetchStore from a payload.
(payload: P, signal: AbortSignal) => AsyncStoreInput<R>
maxAge of zero passed to refresh() means "always refresh this value" (this is the default).
maxAge of Infinity passed to refresh() means "only refresh if this value is not loaded or invalid".