@reactra/resource 0.1.0-alpha.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Akhil Shastri and the Reactra contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # @reactra/resource
2
+
3
+ > Reactra resource runtime — declarative async data (Suspense, swr/cache/retry) for Reactra apps.
4
+
5
+ **Alpha** — published under the npm dist-tag `alpha`. APIs may change before 1.0.
6
+
7
+ ```bash
8
+ npm install @reactra/resource@alpha
9
+ ```
10
+
11
+ Part of [Reactra](https://github.com/akhilshastri/reactra) — a compiler-first,
12
+ React-19-compatible framework. See the [documentation](https://reactra-docs.vercel.app) to get
13
+ started.
14
+
15
+ ## License
16
+
17
+ MIT
@@ -0,0 +1,58 @@
1
+ /**
2
+ * A settled cache entry. A1 only stores resolved values; `error` is reserved
3
+ * for B/D stages that may cache rejections under explicit retry/SWR semantics.
4
+ * `controller` lets the cache abort an in-flight fetch on supersede / clear;
5
+ * A1 entries are always settled-resolved at write time, so the controller is
6
+ * effectively post-hoc (kept on the entry so future stages can compose).
7
+ */
8
+ export interface ResourceCacheEntry<T = unknown> {
9
+ readonly value: T | undefined;
10
+ readonly error: unknown;
11
+ readonly promise: Promise<T | undefined>;
12
+ readonly controller: AbortController;
13
+ readonly writtenAt: number;
14
+ }
15
+ /**
16
+ * The cache API every implementation must satisfy. Pluggable via
17
+ * `configureResources({ cache })` — a custom backend (sessionStorage, IndexedDB,
18
+ * remote KV) can drop in by implementing this shape.
19
+ */
20
+ export interface ResourceCache {
21
+ get<T = unknown>(resourceName: string, depsKey: string): ResourceCacheEntry<T> | undefined;
22
+ set<T = unknown>(resourceName: string, depsKey: string, entry: ResourceCacheEntry<T>): void;
23
+ /**
24
+ * Drop every entry whose `resourceName` matches. A1: eviction only — mounted
25
+ * consumers re-fetch on their next natural render (subscriber notify fan-out
26
+ * lands with A2/D when useMutation needs immediate refetch).
27
+ */
28
+ invalidate(resourceName: string | readonly string[]): void;
29
+ /**
30
+ * Remove a single entry by `(resourceName, depsKey)`. Aborts its controller
31
+ * and notifies subscribers. A silent no-op if the entry is not present. Added
32
+ * in Stage A2 so `useResource` can withdraw an in-flight tombstone when `fn`
33
+ * rejects — matching the A1 "do not cache rejections" rule for settled writes.
34
+ */
35
+ delete(resourceName: string, depsKey: string): void;
36
+ /**
37
+ * Stage D — returns true iff `resourceName` has ever been the target of a
38
+ * successful `set()` on this cache. Used by `useMutation`'s post-success
39
+ * invalidate path to fire **RES014** when `opts.invalidate` lists a name
40
+ * that no consumer has fetched (typo-likely). Names are added on `set` and
41
+ * NEVER removed — `clear` / `invalidate` only evict entries, not name
42
+ * registrations (the heuristic is "ever known", not "currently present").
43
+ */
44
+ hasName(resourceName: string): boolean;
45
+ subscribe(resourceName: string, depsKey: string, notify: () => void): () => void;
46
+ /** Drop every entry (or every entry for one resourceName). Aborts each controller. */
47
+ clear(resourceName?: string): void;
48
+ }
49
+ /**
50
+ * The default LRU implementation. `Map` preserves insertion order, so a
51
+ * `delete + set` on read bumps the entry to most-recent; oldest entries (front
52
+ * of the iterator) evict past `maxEntries`. Each entry's `AbortController` is
53
+ * aborted on supersede / eviction / clear / invalidate. Subscribers are keyed
54
+ * identically; `notify(key)` fans out to all of them on every mutation that
55
+ * touches that key.
56
+ */
57
+ export declare const createLRUCache: (maxEntries?: number) => ResourceCache;
58
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAkBA;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,GAAG,OAAO;IAC7C,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,SAAS,CAAA;IAC7B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA;IACxC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAA;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,kBAAkB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAA;IAC1F,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;IAC3F;;;;OAIG;IACH,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;IAC1D;;;;;OAKG;IACH,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACnD;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IACtC,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;IAChF,sFAAsF;IACtF,KAAK,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACnC;AAQD;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GAAI,mBAAe,KAAG,aAgIhD,CAAA"}
package/dist/cache.js ADDED
@@ -0,0 +1,167 @@
1
+ // @reactra/resource — ResourceCache (Resource v1.0 §6)
2
+ //
3
+ // Stage A1 surface: process-wide LRU singleton + a typed `ResourceCache`
4
+ // interface that custom implementations conform to. `createLRUCache(maxEntries)`
5
+ // builds the default; `configureResources({ cache })` (in `index.ts`) swaps the
6
+ // active instance at app boot. Entries are stored only on SUCCESSFUL `fn`
7
+ // resolution — A1 doesn't cache rejections (a failed fn naturally retries on
8
+ // next mount, matching v0 behaviour). Subscriber notification fan-out is wired
9
+ // (`subscribe` / notify on `set`/`invalidate`/`clear`) but Stage A1's
10
+ // `useResource` doesn't subscribe yet — mounted consumers detect cache changes
11
+ // on next natural render. A2 (in-flight dedup) and D (`useMutation.invalidate`)
12
+ // will start subscribing.
13
+ //
14
+ // Key shape: `<resourceName>|<depsKey>` (single joined string; the `|`
15
+ // separator is opaque to consumers — only `get(name, depsKey)` / `set(...)` are
16
+ // public). `depsKey` is the v0 `depsToKey` serialization (still computed in the
17
+ // hook); the cache treats it as an opaque opaque string.
18
+ const joinKey = (name, depsKey) => `${name}|${depsKey}`;
19
+ const splitName = (joined) => {
20
+ const sep = joined.indexOf("|");
21
+ return sep < 0 ? joined : joined.slice(0, sep);
22
+ };
23
+ /**
24
+ * The default LRU implementation. `Map` preserves insertion order, so a
25
+ * `delete + set` on read bumps the entry to most-recent; oldest entries (front
26
+ * of the iterator) evict past `maxEntries`. Each entry's `AbortController` is
27
+ * aborted on supersede / eviction / clear / invalidate. Subscribers are keyed
28
+ * identically; `notify(key)` fans out to all of them on every mutation that
29
+ * touches that key.
30
+ */
31
+ export const createLRUCache = (maxEntries = 50) => {
32
+ const entries = new Map();
33
+ const subscribers = new Map();
34
+ // Stage D — names that have ever been the target of a successful `set`.
35
+ // Grows on every set; never shrinks. The "ever known" semantics catches
36
+ // typos in `useMutation.invalidate(["..."])` without false-positiving on
37
+ // legitimate empty-cache invalidates (a mounted consumer has always set
38
+ // its key at least once before the first invalidate is meaningful).
39
+ const knownNames = new Set();
40
+ const notify = (key) => {
41
+ const set = subscribers.get(key);
42
+ if (set === undefined)
43
+ return;
44
+ // Iterate a snapshot — a notify() reentrantly unsubscribing must not
45
+ // disturb this fan-out.
46
+ for (const fn of [...set])
47
+ fn();
48
+ };
49
+ const evictIfOver = () => {
50
+ while (entries.size > maxEntries) {
51
+ const oldestKey = entries.keys().next().value;
52
+ if (oldestKey === undefined)
53
+ break;
54
+ const oldest = entries.get(oldestKey);
55
+ if (oldest !== undefined)
56
+ oldest.controller.abort();
57
+ entries.delete(oldestKey);
58
+ notify(oldestKey);
59
+ }
60
+ };
61
+ return {
62
+ get(name, depsKey) {
63
+ const key = joinKey(name, depsKey);
64
+ const e = entries.get(key);
65
+ if (e === undefined)
66
+ return undefined;
67
+ // LRU bump.
68
+ entries.delete(key);
69
+ entries.set(key, e);
70
+ return e;
71
+ },
72
+ set(name, depsKey, entry) {
73
+ knownNames.add(name);
74
+ const key = joinKey(name, depsKey);
75
+ const prior = entries.get(key);
76
+ // Supersede a different in-flight controller (the supersede case in §3 +
77
+ // architect Q9). If `prior.controller === entry.controller`, it's the same
78
+ // fetch landing — don't abort itself.
79
+ if (prior !== undefined && prior.controller !== entry.controller) {
80
+ prior.controller.abort();
81
+ }
82
+ entries.delete(key);
83
+ entries.set(key, entry);
84
+ evictIfOver();
85
+ notify(key);
86
+ },
87
+ delete(name, depsKey) {
88
+ const key = joinKey(name, depsKey);
89
+ const e = entries.get(key);
90
+ if (e === undefined)
91
+ return;
92
+ // Caller chose to delete — abort the controller unconditionally. (The
93
+ // useResource caller is doing this on fn-rejection; the in-flight is
94
+ // already settled-error so the abort is informational.)
95
+ e.controller.abort();
96
+ entries.delete(key);
97
+ notify(key);
98
+ },
99
+ invalidate(resourceName) {
100
+ const names = typeof resourceName === "string" ? [resourceName] : resourceName;
101
+ // RES014 — a name that never wrote to the cache has no entry to evict, so
102
+ // invalidating it is a silent no-op (it will NOT refetch). This catches the
103
+ // common footgun: `command f() => … invalidate [r]` where `r` lacks a
104
+ // `cache`/`swr` modifier, plus useMutation typos. Fires for BOTH paths now
105
+ // that both route through here. knownNames persists across eviction, so a
106
+ // genuinely-cached resource never trips this.
107
+ for (const name of names) {
108
+ if (!knownNames.has(name)) {
109
+ console.warn(`[reactra:resource] RES014: invalidate("${name}") names a resource with no cache entry — ` +
110
+ `it will not refetch. Add a \`cache\` or \`swr\` modifier to \`${name}\`, or check the spelling.`);
111
+ }
112
+ }
113
+ const nameSet = new Set(names);
114
+ // Snapshot keys — `entries.delete` inside the loop would disturb iteration.
115
+ for (const key of [...entries.keys()]) {
116
+ if (nameSet.has(splitName(key))) {
117
+ const e = entries.get(key);
118
+ if (e !== undefined)
119
+ e.controller.abort();
120
+ entries.delete(key);
121
+ notify(key);
122
+ }
123
+ }
124
+ },
125
+ subscribe(name, depsKey, notifyFn) {
126
+ const key = joinKey(name, depsKey);
127
+ let set = subscribers.get(key);
128
+ if (set === undefined) {
129
+ set = new Set();
130
+ subscribers.set(key, set);
131
+ }
132
+ set.add(notifyFn);
133
+ return () => {
134
+ const s = subscribers.get(key);
135
+ if (s === undefined)
136
+ return;
137
+ s.delete(notifyFn);
138
+ if (s.size === 0)
139
+ subscribers.delete(key);
140
+ };
141
+ },
142
+ hasName(name) {
143
+ return knownNames.has(name);
144
+ },
145
+ clear(resourceName) {
146
+ if (resourceName === undefined) {
147
+ for (const e of entries.values())
148
+ e.controller.abort();
149
+ const keys = [...entries.keys()];
150
+ entries.clear();
151
+ for (const key of keys)
152
+ notify(key);
153
+ return;
154
+ }
155
+ for (const key of [...entries.keys()]) {
156
+ if (splitName(key) === resourceName) {
157
+ const e = entries.get(key);
158
+ if (e !== undefined)
159
+ e.controller.abort();
160
+ entries.delete(key);
161
+ notify(key);
162
+ }
163
+ }
164
+ },
165
+ };
166
+ };
167
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,350 @@
1
+ import React from "react";
2
+ import { type ResourceCache, type ResourceCacheEntry } from "./cache.ts";
3
+ export { createLRUCache, type ResourceCache, type ResourceCacheEntry } from "./cache.ts";
4
+ /**
5
+ * Hook options. v1 added `resourceName` (compiler-injected from the binding
6
+ * identifier on every DSL `resource` call site) + `cache` + `retry` + `dedup`.
7
+ * v0 signature preserved exactly — every field is optional; omitting them all
8
+ * yields the v0 "every mount fetches" behaviour. See Resource v1 §2.
9
+ */
10
+ export interface ResourceOptions<T = unknown, S = T> {
11
+ /**
12
+ * Cache key prefix. Compiler-injected on every DSL `resource` declaration
13
+ * (derived from the binding identifier). Raw callers may omit it — doing so
14
+ * disables the cache for that call (and falls back to function-identity
15
+ * in-flight dedup once A2 lands). Required for `useMutation` invalidation
16
+ * to target this resource (§7, Stage D).
17
+ */
18
+ readonly resourceName?: string;
19
+ /**
20
+ * Cache policy. `false` (default) — every mount triggers a fresh fetch (v0
21
+ * behaviour). `true` — cache the result indefinitely, keyed by
22
+ * `(resourceName, depsKey)`. Object form lets per-resource override defaults.
23
+ * Stage A1 honours `true`/`{}`; `ttlMs`/`staleWhileRevalidate`/`maxEntries`
24
+ * fields are reserved (TTL + SWR ship with Stage B).
25
+ */
26
+ readonly cache?: boolean | {
27
+ readonly ttlMs?: number;
28
+ readonly staleWhileRevalidate?: boolean;
29
+ readonly maxEntries?: number;
30
+ };
31
+ /**
32
+ * Retry policy on rejection. Default: no retry (v0 behaviour). Stage C ships
33
+ * the implementation; the field is reserved here so v1 callers compile.
34
+ */
35
+ readonly retry?: number | {
36
+ readonly count: number;
37
+ readonly baseMs?: number;
38
+ readonly jitter?: boolean;
39
+ };
40
+ /**
41
+ * In-flight dedup — two concurrent calls with the same `(resourceName,
42
+ * depsKey)` share one fetch. Default `true` when `resourceName` is present.
43
+ * Stage A2 ships the implementation; reserved here so v1 callers compile.
44
+ */
45
+ readonly dedup?: boolean;
46
+ /**
47
+ * Slice/transform the fetched data with a **re-render bail-out**: the handle's
48
+ * `.data` is `select(rawData)`, and the consumer re-renders ONLY when the
49
+ * selected value changes (`Object.is`) — not when an unselected field of the
50
+ * raw data changes. The DSL `select(u => u.name)` modifier compiles to this.
51
+ * The cache stores the RAW value; each consumer applies its own `select`.
52
+ * v1: return a primitive or a stable reference — an object allocated fresh
53
+ * each call never bails (no comparator yet).
54
+ */
55
+ readonly select?: (data: T) => S;
56
+ }
57
+ /** Internal accessor — the active singleton. Not part of the public API. */
58
+ export declare const __getResourceCache: () => ResourceCache;
59
+ /** Test-only: reset the singleton + first-mount guard between test cases. */
60
+ export declare const __resetResourceConfigForTest: () => void;
61
+ /**
62
+ * Configure the resource layer at app boot (Resource v1 §9). Pass a custom
63
+ * `cache` implementation (must satisfy `ResourceCache`) or just override the
64
+ * built-in LRU's max-entries with `cacheMaxEntries`. **Must run before the
65
+ * first `useResource` mount** — calling it after throws RES010 (the cache
66
+ * implementation is already in use; the swap is rejected).
67
+ *
68
+ * Calling it more than once before the first mount overwrites silently (last
69
+ * call wins — typically only configures once at app boot). Calling it never
70
+ * is fine — the built-in LRU runs with `maxEntries: 50` and no TTL.
71
+ */
72
+ export declare const configureResources: (opts?: {
73
+ cache?: ResourceCache;
74
+ cacheMaxEntries?: number;
75
+ }) => void;
76
+ /**
77
+ * Stage B — TTL-based staleness check. Returns `true` iff `cache.ttlMs` is
78
+ * set AND `Date.now() - entry.writtenAt` exceeds it. No TTL = never stale
79
+ * (entries live until eviction). Exported under `__` so the test suite can
80
+ * exercise the predicate without standing up a render.
81
+ */
82
+ export declare const __isCacheEntryStale: (entry: ResourceCacheEntry, opts: ResourceOptions<any, any>, now?: number) => boolean;
83
+ /**
84
+ * Stage B — staleWhileRevalidate opt-in check. Returns `true` iff
85
+ * `opts.cache` is an object form AND `staleWhileRevalidate: true`. Bare
86
+ * `cache: true` is treated as "cache but no SWR" — explicit opt-in required.
87
+ */
88
+ export declare const __shouldRevalidate: (opts: ResourceOptions<any, any>) => boolean;
89
+ /** Normalized retry config; null means "no retry wrapper, call fn once". */
90
+ export interface __RetryConfig {
91
+ readonly count: number;
92
+ readonly baseMs: number;
93
+ readonly jitter: boolean;
94
+ }
95
+ /**
96
+ * Stage C — normalize `opts.retry` to a `__RetryConfig` or `null`. `retry: N`
97
+ * (number) becomes `{ count: N, baseMs: 250, jitter: true }`. `retry: { count }`
98
+ * fills in the same defaults for unset fields. `retry: 0` or absent returns
99
+ * null (consumer fires `fn` once with zero retry overhead).
100
+ */
101
+ export declare const __normalizeRetry: (opts: ResourceOptions<any, any>) => __RetryConfig | null;
102
+ /**
103
+ * Stage C — exponential backoff with optional ±20% jitter. Delay for attempt
104
+ * `n` (0-indexed) is `baseMs * 2^n`, optionally multiplied by a uniform
105
+ * `[0.8, 1.2)` jitter factor. `random` is injectable so tests can pin both
106
+ * extremes (`() => 0` → 0.8x; `() => 1` → 1.2x).
107
+ */
108
+ export declare const __computeRetryDelay: (attempt: number, config: {
109
+ readonly baseMs: number;
110
+ readonly jitter: boolean;
111
+ }, random?: () => number) => number;
112
+ /**
113
+ * Stage C — abortable `setTimeout` as a Promise. Resolves after `ms`; rejects
114
+ * with a DOMException("Aborted", "AbortError") if `signal` aborts before the
115
+ * timer fires (the timer is cleared). If the signal is already aborted at
116
+ * call time, rejects synchronously on the next microtask.
117
+ */
118
+ export declare const __delay: (ms: number, signal: AbortSignal) => Promise<void>;
119
+ /**
120
+ * Stage C — fire `fn(deps, { signal })` up to `config.count + 1` times (one
121
+ * initial + `count` retries), with exponential backoff + jitter between
122
+ * attempts. On `AbortError` from `fn` OR signal abort during the backoff
123
+ * delay, the loop short-circuits and the abort propagates. On exhaustion,
124
+ * logs RES012 (dev-gated — prod stays silent since the error already surfaces
125
+ * via `r.error` + ErrorBoundary + the rejected promise) and re-throws the last
126
+ * error UNCONDITIONALLY. The hook's existing `.then` chain handles
127
+ * `setState({ error })` + cache.delete tombstone removal unchanged.
128
+ */
129
+ export declare const __fireWithRetry: <Deps, T>(deps: NonNullable<Deps>, signal: AbortSignal, config: __RetryConfig, fn: (deps: NonNullable<Deps>, ctx: {
130
+ signal: AbortSignal;
131
+ }) => Promise<T>, random?: () => number) => Promise<T>;
132
+ /**
133
+ * Handle returned by `useResource`. Drives both the `await(r)` Suspense
134
+ * boundary (via `promise`) and the success branch body (via `data`).
135
+ *
136
+ * `S` is the SELECTED type (`= T` when no `select`): `.data` is what the consumer
137
+ * sees (the slice). `.promise` stays `Promise<T | undefined>` (the RAW fetch) — the
138
+ * `await(r){}` lowering discards its resolved value (it only drives Suspense; the
139
+ * body reads `.data`), so there's no need to project it through `select`.
140
+ */
141
+ export interface ResourceHandle<T, S = T> {
142
+ data: S | undefined;
143
+ error: unknown;
144
+ isPending: boolean;
145
+ refetch: () => void;
146
+ promise: Promise<T | undefined>;
147
+ }
148
+ /**
149
+ * Stable string key for a `deps` value. Arrays are unwrapped element-wise so
150
+ * `[1, 2]` keys identically to another `[1, 2]`; scalar refs are compared by
151
+ * `Object.is`-equivalent identity. Exported for tests.
152
+ */
153
+ export declare const depsToKey: (deps: unknown) => string;
154
+ /**
155
+ * The Reactra resource hook. Compiler-emitted from `resource r(deps) => fn(deps)`.
156
+ *
157
+ * Behaviour per Resource v0 §2 + §3:
158
+ * - `deps === null` → skip the call. `data/error: undefined`, `isPending: false`,
159
+ * `promise: Promise.resolve(undefined)`.
160
+ * - `deps === undefined` → same as `null` but emits a RES004 warning. The
161
+ * explicit skip sentinel is `null`.
162
+ * - Otherwise `fn(deps, { signal })` runs immediately. `data` updates on
163
+ * resolution; `error` updates on rejection (preserving last good `data`).
164
+ * - Deps change (shallow `Object.is`) aborts the in-flight call and re-fires.
165
+ * - `refetch()` aborts the current call and re-fires with the same deps.
166
+ * - Late resolutions are dropped via a generation counter.
167
+ *
168
+ * The returned `promise` is always non-null and is fed to `React.use()` inside
169
+ * compiled `await(r) { }` blocks so React 19's Suspense can drive the boundary.
170
+ *
171
+ * ## StrictMode-safety (the reason this hook is ref-cached, not useMemo'd)
172
+ *
173
+ * Earlier drafts used `useMemo` for the promise and a `useEffect(() => () =>
174
+ * abort())` cleanup. That breaks under React.StrictMode in dev. StrictMode
175
+ * double-invokes render → mount → cleanup → mount on first mount to surface
176
+ * impurity. The first mount's `useEffect` cleanup aborts the controller while
177
+ * the SAME promise object is still referenced by the rendered tree; on the
178
+ * fake-remount, `React.use(promise)` sees a rejected (AbortError) promise and
179
+ * the surrounding ErrorBoundary fires for what should be a normal load.
180
+ * Removing the cleanup-side abort alone doesn't fix it — the top-of-useMemo
181
+ * abort + StrictMode's deliberate memo-discard still leave a rejected promise
182
+ * visible to React.use either way (useMemo is a cache *hint*, not a guarantee).
183
+ *
184
+ * The fix: cache the entry in a `useRef`. Refs are mutable cells that survive
185
+ * StrictMode's fake-unmount unchanged because they live outside React's
186
+ * render-output reconciliation. On the fake-remount, the same `depsKey` finds
187
+ * the existing entry and reuses its unaborted promise. Abort happens ONLY at
188
+ * the top of the cache-miss branch (genuine deps change or first call), never
189
+ * from an effect cleanup. Late resolutions are still dropped by the
190
+ * `genRef === myGen` guard inside the .then handlers, which covers the cases
191
+ * the cleanup-abort used to: deps-change, refetch, and the rarer "still
192
+ * in-flight at real unmount" case (setState on an unmounted component is a
193
+ * silent no-op in React 18+; no error, no warning, just a dropped state
194
+ * update). The minor cost is that a fetch in flight at real unmount keeps
195
+ * running until the network call completes — but its resolution is dropped,
196
+ * so no setState-on-unmounted and no observable bug. Worth it for StrictMode.
197
+ *
198
+ * Mutating refs during render is the standard React 19 pattern for cache-like
199
+ * state; React docs explicitly bless it when (a) the operation is idempotent
200
+ * for a given input (same depsKey → same entry) and (b) the mutation doesn't
201
+ * affect the rendered output during *this* render. Both hold here.
202
+ */
203
+ export declare const useResource: <Deps, T, S = T>(deps: Deps, fn: (deps: NonNullable<Deps>, ctx: {
204
+ signal: AbortSignal;
205
+ }) => Promise<T>, opts?: ResourceOptions<T, S>) => ResourceHandle<T, S>;
206
+ /**
207
+ * Props for the ErrorBoundary emitted by `await(r) error(e) { … }` blocks.
208
+ * `fallback` is a render-fn (not an element) so the boundary can pass the
209
+ * caught error to the user's `error(e) { JSX }` body verbatim.
210
+ */
211
+ /**
212
+ * Resource v1 §8.1 — the runtime helper a compiler-emitted `warm(inputs,
213
+ * signal)` companion calls per-resource. Best-effort cache pre-fill; never
214
+ * throws. The returned promise resolves when the entry settles (success or
215
+ * any failure, including AbortError).
216
+ *
217
+ * Behaviour:
218
+ * - If `(name, depsToKey(deps))` already has a cache entry (settled OR
219
+ * in-flight), resolve immediately. Stage E treats any present entry as
220
+ * "fresh enough" — consumers with SWR drive their own refresh from the
221
+ * render path; warm doesn't aggressively refresh.
222
+ * - Otherwise: write an in-flight tombstone (Stage A2 shape) keyed under
223
+ * a fresh `AbortController` so concurrent warm + consumer mounts dedup.
224
+ * Forward `callerSignal.abort` to the cache controller, propagating
225
+ * cancel-on-real-navigation through to `fn(deps, { signal })`.
226
+ * - On `fn` success: supersede the tombstone with the resolved entry
227
+ * (same controller → idempotent supersede per §6).
228
+ * - On `fn` failure (including AbortError): `cache.delete(name, depsKey)`
229
+ * withdraws the tombstone. Any consumer mid-adopt sees the
230
+ * `cacheBust = cacheCoupled && cached === undefined` check (Stage D)
231
+ * and re-fires fresh on its next render. Failures are silently
232
+ * resolved by the returned promise — RES015 was deliberately not
233
+ * minted (§5; failed warms are debug-only).
234
+ */
235
+ export declare const warmResource: <Deps, T>(name: string, deps: Deps, fn: (deps: Deps, ctx: {
236
+ signal: AbortSignal;
237
+ }) => Promise<T>, callerSignal: AbortSignal) => Promise<void>;
238
+ /**
239
+ * The name of a resource known to the project, used to type
240
+ * {@link MutationOptions.invalidate}. See Resource v1 §7.
241
+ *
242
+ * **This alias is `string` by default.** When `@reactra/vite-plugin` runs over
243
+ * a project it writes `.reactra/resource-names.d.ts`, which uses TS declaration
244
+ * merging to narrow this alias to the union of every `resource X(...)` name
245
+ * declared across the project (e.g. `"customer" | "orderSummary"`). With that
246
+ * file on the TS `include` path, `invalidate: ["custmer"]` becomes a compile
247
+ * error while `invalidate: ["customer"]` typechecks.
248
+ *
249
+ * The default-to-`string` guarantee is load-bearing: with NO generated file
250
+ * present (a fresh clone, a library consumer, a project that hasn't built yet),
251
+ * `invalidate: string[]` and `invalidate: ["anything"]` keep compiling — the
252
+ * typed union is an additive narrowing, never a hard requirement. RES014 stays
253
+ * the runtime backstop for dynamic / un-generated names.
254
+ *
255
+ * It must be a PROJECT-WIDE union (one merged declaration), not per-file:
256
+ * invalidation is cross-file (a mutation in `save.tsx` invalidates a resource
257
+ * declared in `[id].tsx`), so a per-file union would make correct cross-file
258
+ * invalidation a type error.
259
+ */
260
+ export type ResourceName = string;
261
+ /** Options for `useMutation`. See Resource v1 §7. */
262
+ export interface MutationOptions {
263
+ /**
264
+ * After a successful mutation, invalidate every resource whose `resourceName`
265
+ * appears in this list. v1 keys invalidation purely by `resourceName`
266
+ * (architect Q6 Path C — the `tags` field is deferred to v1.1 with the DSL
267
+ * grammar extension). Typed as {@link ResourceName}[] so a typo fails at
268
+ * compile time once `.reactra/resource-names.d.ts` is generated; RES014 stays
269
+ * the runtime backstop (warns when a listed name has never been written to
270
+ * the cache, e.g. a dynamic name). The mutation still completes either way.
271
+ */
272
+ readonly invalidate?: readonly ResourceName[];
273
+ /**
274
+ * If false (default), calling `mutate()` while a previous call is in-flight
275
+ * throws **RES013**. Set true to allow overlapping calls — the most recent
276
+ * resolution wins for the handle's `data`/`error`/`isPending`; older calls
277
+ * still resolve their own returned promise (they're just no-ops for the
278
+ * handle's state).
279
+ */
280
+ readonly concurrent?: boolean;
281
+ /** Per-mutation retry policy. Same shape as `ResourceOptions.retry`. */
282
+ readonly retry?: ResourceOptions["retry"];
283
+ }
284
+ /** Handle returned by `useMutation`. See Resource v1 §7. */
285
+ export interface MutationHandle<Args, T> {
286
+ /**
287
+ * Fire the mutation. Returns a promise resolving to `T` on success. Throws
288
+ * RES013 if called while `isPending` is true and `concurrent !== true`.
289
+ */
290
+ mutate: (args: Args) => Promise<T>;
291
+ /** True while the latest `mutate()` call's promise is unresolved. */
292
+ isPending: boolean;
293
+ /** Last successful return value; cleared by `reset()` or overwritten by the next success. */
294
+ data: T | undefined;
295
+ /** Last error; cleared by `reset()` or by the next successful resolution. */
296
+ error: unknown;
297
+ /** Clear `data` + `error` + abort any in-flight call. **Stable reference.** */
298
+ reset: () => void;
299
+ }
300
+ /**
301
+ * Resource v1 §7 — `useMutation(fn, opts?)`. A user-called hook for
302
+ * non-idempotent side effects (POST, PATCH, DELETE, …) that may need to
303
+ * invalidate cached resources on success. Lives in `@reactra/resource`; NOT
304
+ * emitted by the compiler from any DSL keyword (architect Q6 — `mutation` is
305
+ * deliberately not added to the 25-keyword surface in v1).
306
+ *
307
+ * Behaviour:
308
+ * - `mutate(args)` immediately calls `fn(args, { signal })` and returns the
309
+ * promise. `isPending` toggles `true → false` on settle (success OR error).
310
+ * - On success: writes `data`, clears `error`, then runs
311
+ * `__currentCache.invalidate(opts.invalidate)` if `invalidate` is set. The
312
+ * returned promise resolves AFTER invalidation is initiated.
313
+ * - On rejection: writes `error`, retains the previous `data`. Retries (if
314
+ * `opts.retry`) drain before the rejection lands. A final failure does NOT
315
+ * invalidate.
316
+ * - `reset()` aborts the in-flight call, clears `data` + `error`, toggles
317
+ * `isPending` false. Reference is stable across renders.
318
+ * - **RES013** throws if `mutate()` is called while `isPending` is true and
319
+ * `concurrent !== true`. Set `concurrent: true` to opt in to overlap.
320
+ * - **RES014** warns if `opts.invalidate` lists a name not yet known to the
321
+ * cache (likely a typo). The mutation still completes.
322
+ *
323
+ * StrictMode: no `useEffect`. The in-flight controller lives in a `useRef`
324
+ * and is aborted by `reset()` or replaced on the next `mutate()` call.
325
+ */
326
+ export declare const useMutation: <Args, T>(fn: (args: Args, ctx: {
327
+ signal: AbortSignal;
328
+ }) => Promise<T>, opts?: MutationOptions) => MutationHandle<Args, T>;
329
+ export interface ErrorBoundaryProps {
330
+ children: React.ReactNode;
331
+ fallback: (error: unknown) => React.ReactNode;
332
+ }
333
+ interface ErrorBoundaryState {
334
+ error: unknown;
335
+ }
336
+ /**
337
+ * React class component used by compiled `await(r) error(e) { … }` blocks.
338
+ * Phase-1 surface: catches render-time errors below the boundary, then
339
+ * renders `fallback(error)`. No reset API yet — a fresh boundary is created
340
+ * on every parent re-render that re-emits a new JSX subtree.
341
+ *
342
+ * Resource v0 §4: errors thrown inside `fn` reject the promise; React.use()
343
+ * re-throws on subsequent render; this boundary catches the re-throw.
344
+ */
345
+ export declare class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
346
+ state: ErrorBoundaryState;
347
+ static getDerivedStateFromError: (error: unknown) => ErrorBoundaryState;
348
+ render(): React.ReactNode;
349
+ }
350
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}