Radiant0.3.0-rc.2

Resources

createResource ties an async data flow to a host element's lifecycle. It starts observing when the element connects, aborts in-flight work on disconnect, and resumes from the current source on reconnect.

import { createResource } from '@ecopages/radiant';

Basic Usage

Fetch once on connect — no reactive source needed:

private data = createResource(this, {
	fetcher: (ctx) => fetch('/api/data', { signal: ctx.signal }).then((r) => r.json()),
});

Sourced Usage

Drive fetches from a reactive source. Source changes abort the previous request and start a new one.

source only re-runs when it reads a signal (or a host member backed by one). Prefer @state / @prop so plain property access tracks automatically:

@state activeCityId = 'venice';
 
private weatherQuery = createResource(this, {
	source: (ctx) => ctx.host.activeCityId,
	fetcher: (cityId, ctx) => fetchWeatherReport(cityId, ctx.signal),
	onSuccess: (report) => console.log(report),
});
 
override render() {
	const status = this.weatherQuery.status.get();
	const data = this.weatherQuery.data.get();
	// ...
}

You can also pass a raw signal and call .get() inside source. A plain field is not reactive — changing it will not refetch.

Returning a falsy value (false, null, undefined) from source disables fetching without clearing the current state.

Config Options

OptionTypeDescription
fetcher(source, ctx) => Promise<Value>The async function to call. Without source, receives only ctx. With source, the resolved source value is passed as the first argument. ctx provides host and signal.
source(ctx) => Source | false | null | undefinedA reactive selector that drives re-fetches. Falsy returns pause fetching.
initialValueValueSeed value exposed from data before the first successful resolution.
staleTimenumberMilliseconds a successful response stays fresh in the per-instance cache.
pendingDelaynumberMilliseconds to wait before transitioning status to 'pending'.
onSuccess(data, ctx) => voidCalled after each successful resolution, including cache hits.
onError(error, ctx) => voidCalled after each failed resolution. Not called for aborted requests.
onSettled(data, error, ctx) => voidCalled after each resolution, whether successful or failed.

Return Value

createResource returns a HostResource that implements AsyncStateResult<Value>:

Property / MethodTypeDescription
dataReadonlySignal<Value | undefined>The latest resolved value.
statusReadonlySignal<'idle' | 'pending' | 'success' | 'error'>Current fetch state.
errorReadonlySignal<unknown>The latest rejection reason, if any.
refetch()() => voidRe-runs the fetcher from the current source value.
abort()() => voidAborts the in-flight request.

Lifecycle

  1. Connect — the resource starts observing the source (or fetches immediately if no source is set).
  2. Source change — the previous request is aborted and a new one starts.
  3. Disconnect — the in-flight request is aborted. The current state is preserved.
  4. Reconnect — the resource resumes from the latest source value.

createResource registers these hooks automatically via registerConnectedCallback and registerCleanupCallback.

Related

  • See Weather App for a full sourced resource example with context.
  • createResource builds on the package-level asyncState primitive and adds host lifecycle ownership on top.