@haddowg/json-api-query 1.0.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 +21 -0
- package/README.md +183 -0
- package/dist/index.cjs +836 -0
- package/dist/index.d.cts +438 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +438 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +810 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +65 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
import { ApiDescriptor, AtomicHandle, AtomicRecorder, AtomicResult, AtomicResults, Collection, CreateInput, FieldsMap, IncludePath, LinkageRef, ReadResult, RelationName, RelationReadQuery, RelationshipAccessor, SingleReadQuery, TypeName, TypedReadQuery, UpdateInput, WriteOptions } from "@haddowg/json-api-client";
|
|
2
|
+
import { QueryClient } from "@tanstack/query-core";
|
|
3
|
+
|
|
4
|
+
//#region src/install.d.ts
|
|
5
|
+
/** Tear down an installed normalization subscription. Idempotent. */
|
|
6
|
+
type Teardown = () => void;
|
|
7
|
+
/**
|
|
8
|
+
* Subscribe the normalizer to a QueryClient's query + mutation caches: each time a query or
|
|
9
|
+
* mutation settles successfully, the freshly-resolved data is indexed by `type:id` and patched
|
|
10
|
+
* across every cached query in place (preserving edge-local `$pivot`/`$edge`).
|
|
11
|
+
*
|
|
12
|
+
* A QueryClient may host only ONE descriptor (see {@link installed}): installing a *second*,
|
|
13
|
+
* different descriptor on the same QueryClient throws, because the normalizer cannot safely tell
|
|
14
|
+
* which descriptor a given `type:id` belongs to once two descriptors overlap. Use one QueryClient
|
|
15
|
+
* per typed client/server. Re-installing the *same* descriptor is allowed (idempotent-friendly):
|
|
16
|
+
* it just adds another subscription pair with its own teardown.
|
|
17
|
+
*
|
|
18
|
+
* Re-entrancy is guarded: the patch pass itself sets data on other queries (firing further
|
|
19
|
+
* `success` events), so while a pass runs we ignore the events it generates — otherwise a
|
|
20
|
+
* single response would cascade into a loop. Returns a {@link Teardown} that removes both
|
|
21
|
+
* subscriptions (and clears the install record when this was the active install).
|
|
22
|
+
*/
|
|
23
|
+
declare function installNormalization(queryClient: QueryClient, descriptor: ApiDescriptor): Teardown;
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/keys.d.ts
|
|
26
|
+
/**
|
|
27
|
+
* The deterministic query-key factory (CONTEXT.md "Cache & normalization (TanStack layer)").
|
|
28
|
+
*
|
|
29
|
+
* A key is a stable, hierarchical readonly tuple `[type, operation, ...id?, ...rel?, params?]`.
|
|
30
|
+
* The hierarchy is the contract the normalization layer + targeted invalidation lean on: a
|
|
31
|
+
* prefix of a key matches every key beneath it (TanStack's `queryKey` matching is prefix-based),
|
|
32
|
+
* so `[type]` invalidates a whole type's subtree, `[type, operation]` an operation's subtree, and
|
|
33
|
+
* `[type, operation, id]` a single resource's reads. Params ride the LAST segment as a normalised
|
|
34
|
+
* object so two semantically-equal queries (keys reordered, equal values) share one key.
|
|
35
|
+
*/
|
|
36
|
+
/** The read operations a key can address (mirrors the client's per-operation path templates). */
|
|
37
|
+
type ReadOperation = 'fetchMany' | 'fetchOne' | 'fetchRelated' | 'fetchRelationship';
|
|
38
|
+
/**
|
|
39
|
+
* A normalised query-parameter value: JSON-ish, with object keys sorted recursively so equal
|
|
40
|
+
* params produce an identical (deeply-equal, stably-ordered) value regardless of authoring order.
|
|
41
|
+
*/
|
|
42
|
+
type NormalizedParams = string | number | boolean | null | readonly NormalizedParams[] | {
|
|
43
|
+
readonly [key: string]: NormalizedParams;
|
|
44
|
+
};
|
|
45
|
+
/** One segment of a query key: the type/operation/id/rel strings, or the trailing params object. */
|
|
46
|
+
type QueryKeyPart = string | {
|
|
47
|
+
readonly [key: string]: NormalizedParams;
|
|
48
|
+
};
|
|
49
|
+
/** A query key: the stable readonly tuple TanStack stores results under. */
|
|
50
|
+
type QueryKey = readonly QueryKeyPart[];
|
|
51
|
+
/**
|
|
52
|
+
* Recursively normalise a params value so semantically-equal params serialise identically:
|
|
53
|
+
* object keys are sorted; arrays keep order (order is meaningful in a list — `sort`, `include`);
|
|
54
|
+
* `undefined` members are dropped (an absent param == an unset one). Primitives pass through.
|
|
55
|
+
* Not JSON.stringify — the key stays a structured tuple so TanStack's structural matching and
|
|
56
|
+
* the devtools see real values, not an opaque string.
|
|
57
|
+
*/
|
|
58
|
+
declare function normalizeParams(value: unknown): NormalizedParams;
|
|
59
|
+
/** The addressing of a key, before params: type + operation, plus the id/rel an op needs. */
|
|
60
|
+
interface KeyTarget {
|
|
61
|
+
type: string;
|
|
62
|
+
operation: ReadOperation;
|
|
63
|
+
/** Present for resource-scoped ops (`fetchOne`/`fetchRelated`/`fetchRelationship`). */
|
|
64
|
+
id?: string;
|
|
65
|
+
/** Present for relation ops (`fetchRelated`/`fetchRelationship`). */
|
|
66
|
+
rel?: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Build a deterministic, hierarchical query key from `(type, operation, id?, rel?, params?)`.
|
|
70
|
+
* The fixed-position prefix (`type`, `operation`, then `id`, then `rel`) makes any ancestor a
|
|
71
|
+
* valid invalidation target; params (when present and non-empty) ride a single trailing
|
|
72
|
+
* normalised object so reorderings collapse to one key. An absent/empty params object adds no
|
|
73
|
+
* trailing segment, so a bare `list()` and `list({})` share a key.
|
|
74
|
+
*/
|
|
75
|
+
declare function keyFor(target: KeyTarget, params?: unknown): QueryKey;
|
|
76
|
+
/** The whole-type subtree prefix (`[type]`) — invalidates every operation/read of a type. */
|
|
77
|
+
declare function typeKey(type: string): readonly [string];
|
|
78
|
+
/** An operation subtree prefix (`[type, operation]`) — e.g. every `fetchMany` (list) of a type. */
|
|
79
|
+
declare function operationKey(type: string, operation: ReadOperation): readonly [string, string];
|
|
80
|
+
/**
|
|
81
|
+
* A single-resource subtree prefix (`[type, 'fetchOne', id]`) — matches that resource's reads.
|
|
82
|
+
* Pairs with {@link keyFor} (which places `id` at the same position), so it is a true prefix of
|
|
83
|
+
* every `fetchOne` key for the id regardless of its query params.
|
|
84
|
+
*/
|
|
85
|
+
declare function resourceKey(type: string, id: string): readonly [string, string, string];
|
|
86
|
+
/**
|
|
87
|
+
* A single-relation read prefix (`[type, operation, id, rel]`) for `fetchRelated` /
|
|
88
|
+
* `fetchRelationship` — matches one parent's reads of one relation, regardless of query params.
|
|
89
|
+
* Pairs with {@link keyFor} (which places `id` then `rel` at fixed positions), so it is a true
|
|
90
|
+
* prefix of every related/relationship key for that `(id, rel)`. Used for TARGETED invalidation of
|
|
91
|
+
* a parent's relation after a relationship mutation (never the type's collection lists — ADR 0003).
|
|
92
|
+
*/
|
|
93
|
+
declare function relationKey(type: string, operation: 'fetchRelated' | 'fetchRelationship', id: string, rel: string): readonly [string, string, string, string];
|
|
94
|
+
/**
|
|
95
|
+
* BOTH read prefixes for one parent's one relation — its related-collection reads
|
|
96
|
+
* (`[type, 'fetchRelated', id, rel]`) AND its relationship-linkage reads
|
|
97
|
+
* (`[type, 'fetchRelationship', id, rel]`). A relation is read over two surfaces, so a single
|
|
98
|
+
* prefix can't cover both; this returns the pair so an app targets every cached page of a
|
|
99
|
+
* `(parent, relation)` — for invalidation or an optimistic membership patch — WITHOUT
|
|
100
|
+
* reconstructing keys (or coupling to the page params a read used). PUBLIC: it is the key helper
|
|
101
|
+
* the relationship-mutation optimistic path and apps share (D35b).
|
|
102
|
+
*/
|
|
103
|
+
declare function relationReadKeys(type: string, id: string, rel: string): readonly [readonly [string, string, string, string], readonly [string, string, string, string]];
|
|
104
|
+
/**
|
|
105
|
+
* True when `key` is prefixed by `prefix` (segment-by-segment string equality over the prefix's
|
|
106
|
+
* length). The cache-walking optimistic/invalidation paths use it to find every page variant of a
|
|
107
|
+
* `(parent, relation)` read (whose params ride the key's trailing segment). Mirrors TanStack's own
|
|
108
|
+
* prefix-based `queryKey` matching so a targeted patch and TanStack's `invalidateQueries` agree.
|
|
109
|
+
*/
|
|
110
|
+
declare function keyHasPrefix(key: QueryKey, prefix: QueryKey): boolean;
|
|
111
|
+
//#endregion
|
|
112
|
+
//#region src/normalize.d.ts
|
|
113
|
+
/**
|
|
114
|
+
* Write-through patch (the heart of Strategy 2). Given a freshly-resolved materialised
|
|
115
|
+
* `result`, index its resources by `type:id` and patch every OTHER cached query that holds any
|
|
116
|
+
* of those `type:id`s in place, so a single response updates the same resource everywhere it
|
|
117
|
+
* is cached ("edit once, updates everywhere").
|
|
118
|
+
*
|
|
119
|
+
* Edge-local `$pivot`/`$edge` and a node's identity are preserved (only own-enumerable
|
|
120
|
+
* attribute props are overwritten). Pass `result` from an option factory's `onSuccess` (or use
|
|
121
|
+
* {@link installNormalization} to subscribe to every query/mutation success automatically).
|
|
122
|
+
*
|
|
123
|
+
* `result` is the materialised value the client produced for this response (a resource, a
|
|
124
|
+
* `Collection`, a related collection, or linkage). The same reference may also be the cached
|
|
125
|
+
* entry for the query that produced it — we mutate it too (idempotently), which is harmless and
|
|
126
|
+
* keeps every surface holding that resource consistent.
|
|
127
|
+
*
|
|
128
|
+
* CONTRACT: a single QueryClient must hold caches for ONE descriptor only. The patch matches a
|
|
129
|
+
* cached node purely by `type:id` and rewrites it with `descriptor`'s attribute split, so two
|
|
130
|
+
* descriptors that share a QueryClient and a `type:id` (e.g. a `default` + an `admin` server whose
|
|
131
|
+
* `users` differ) would cross-contaminate. `installNormalization` enforces this for the auto path;
|
|
132
|
+
* when calling `normalize` standalone, give each typed client/server its own QueryClient.
|
|
133
|
+
*/
|
|
134
|
+
declare function normalize(queryClient: QueryClient, result: unknown, descriptor: ApiDescriptor): void;
|
|
135
|
+
/**
|
|
136
|
+
* A captured snapshot of the prior state of every node an optimistic patch touched, with a
|
|
137
|
+
* `restore()` that puts each one back. The snapshot records, per affected cached node, the exact
|
|
138
|
+
* prior value of every attribute key the patch overwrote (and which keys were newly added), so a
|
|
139
|
+
* rollback is precise — it never disturbs keys the patch didn't touch, and it restores in place
|
|
140
|
+
* (preserving identity + the per-edge `$pivot`/`$edge`, exactly as the forward patch does).
|
|
141
|
+
*/
|
|
142
|
+
interface Snapshot {
|
|
143
|
+
/** Undo the optimistic patch — restore every touched node to its pre-patch attributes. */
|
|
144
|
+
restore(): void;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Apply an OPTIMISTIC attribute patch to a single `type:id` across every cached query and return a
|
|
148
|
+
* {@link Snapshot} to roll it back. Mirrors the success path ({@link normalize}) — same in-place
|
|
149
|
+
* attribute overwrite, same edge preservation — but for one known resource whose fresh attributes
|
|
150
|
+
* the caller predicts (an update patch's attribute keys), and it captures the prior state first so
|
|
151
|
+
* an error can restore it. Used by the update / relationship-set mutation factories' `onMutate`.
|
|
152
|
+
*/
|
|
153
|
+
declare function applyOptimisticPatch(queryClient: QueryClient, type: string, id: string, attributes: Record<string, unknown>, descriptor: ApiDescriptor): Snapshot;
|
|
154
|
+
/**
|
|
155
|
+
* A to-many array member for the optimistic patch: at minimum a linkage identifier (`type`+`id`,
|
|
156
|
+
* optional `$pivot`), but any extra own props are preserved — so a caller who passes a fully
|
|
157
|
+
* hydrated member (a resource view carrying attributes) gets a rich optimistic row, while a bare
|
|
158
|
+
* `{type,id}` identifier is equally valid. Membership identity is by `type:id` alone (`sameRef`).
|
|
159
|
+
*/
|
|
160
|
+
interface MembershipRef {
|
|
161
|
+
type: string;
|
|
162
|
+
id: string;
|
|
163
|
+
$pivot?: Record<string, unknown>;
|
|
164
|
+
[key: string]: unknown;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* A membership transform over the CURRENT members of a cached related/relationship read: given the
|
|
168
|
+
* present members (each an identifier `{type,id}` or a hydrated resource view — both expose
|
|
169
|
+
* `type`/`id`), return the optimistic next members. The relationship-mutation factories build one
|
|
170
|
+
* per verb (append the added refs, drop the removed ones, or swap in the replacement set).
|
|
171
|
+
*/
|
|
172
|
+
type MembershipTransform = (members: readonly MembershipRef[]) => readonly MembershipRef[];
|
|
173
|
+
/**
|
|
174
|
+
* Apply an OPTIMISTIC membership change to EVERY cached read of one parent's one relation — both its
|
|
175
|
+
* related-collection (`fetchRelated`) and its relationship-linkage (`fetchRelationship`) reads,
|
|
176
|
+
* matched BY KEY PREFIX so every page/param variant is covered at once (no coupling to the page
|
|
177
|
+
* params a read used — the pain point D35b removes). The to-many read caches an array of members, so
|
|
178
|
+
* the transform runs over that array; the snapshot restores each touched query's PRIOR data
|
|
179
|
+
* wholesale on error. On settle the factory invalidates the relation subtree, so the server
|
|
180
|
+
* reconciles regardless (a degraded optimistic member — an identifier without attributes — is
|
|
181
|
+
* replaced by the real one). A to-one `set` is handled separately (it caches a single value, not an
|
|
182
|
+
* array).
|
|
183
|
+
*/
|
|
184
|
+
declare function applyOptimisticMembership(queryClient: QueryClient, type: string, id: string, rel: string, transform: MembershipTransform): Snapshot;
|
|
185
|
+
/** True when two refs address the same resource (`type:id`). Ignores `$pivot`/attributes. */
|
|
186
|
+
declare function sameRef(a: MembershipRef, b: MembershipRef): boolean;
|
|
187
|
+
/**
|
|
188
|
+
* Apply an OPTIMISTIC to-one `set` to every cached relationship/related read of one parent's one
|
|
189
|
+
* relation (by key prefix): swap each cached value to `next` (a bare identifier ref, or `null` to
|
|
190
|
+
* clear), snapshotting the prior value for rollback. A to-one read caches a single value (not an
|
|
191
|
+
* array), so a plain replacement is correct; the settle refetch reconciles a bare identifier into
|
|
192
|
+
* the fully-hydrated resource. `undefined` next means the ref carried no cache identity (an
|
|
193
|
+
* lid-only atomic handle) — the cache is left untouched (the wire write still happens).
|
|
194
|
+
*/
|
|
195
|
+
declare function applyOptimisticToOne(queryClient: QueryClient, type: string, id: string, rel: string, next: MembershipRef | null | undefined): Snapshot;
|
|
196
|
+
//#endregion
|
|
197
|
+
//#region src/mutate.d.ts
|
|
198
|
+
/**
|
|
199
|
+
* A TanStack-compatible mutation-options object: the async `mutationFn` plus the lifecycle
|
|
200
|
+
* callbacks the binding wires for normalization / invalidation / optimism. Structurally
|
|
201
|
+
* assignable to `query-core`'s `MutationOptions`/`UseMutationOptions` (the user merges in
|
|
202
|
+
* `retry`, `onMutate` of their own, etc.), so the binding needn't import or re-export
|
|
203
|
+
* query-core's option type — it stays a peer.
|
|
204
|
+
*
|
|
205
|
+
* `TData` is the resolved result, `TVars` the input the caller passes to `mutate(vars)`, and
|
|
206
|
+
* `TContext` the value `onMutate` threads to `onError`/`onSettled` (here a {@link MutationContext}
|
|
207
|
+
* carrying the optimistic snapshot).
|
|
208
|
+
*/
|
|
209
|
+
interface MutationOptions<TData, TVars, TContext = unknown> {
|
|
210
|
+
mutationFn: (variables: TVars) => Promise<TData>;
|
|
211
|
+
onMutate?: (variables: TVars) => Promise<TContext> | TContext;
|
|
212
|
+
onError?: (error: unknown, variables: TVars, context: TContext | undefined) => void;
|
|
213
|
+
onSuccess?: (data: TData, variables: TVars, context: TContext | undefined) => void;
|
|
214
|
+
onSettled?: (data: TData | undefined, error: unknown, variables: TVars, context: TContext | undefined) => void;
|
|
215
|
+
}
|
|
216
|
+
/** The context an optimistic `onMutate` threads forward: the snapshot to roll back to on error. */
|
|
217
|
+
interface MutationContext {
|
|
218
|
+
snapshot: Snapshot;
|
|
219
|
+
}
|
|
220
|
+
/** A client narrowed to the per-type write methods the mutation factories drive. */
|
|
221
|
+
type WriteClient<D extends ApiDescriptor, A, W> = { [T in TypeName<D>]: {
|
|
222
|
+
create<const Inc extends readonly IncludePath<D, T>[] = [], const F extends FieldsMap<D> = {}>(input: CreateInput<D, W, T>, opts?: WriteOptions<D, T, Inc, F>): Promise<ReadResult<D, A, T, Inc, F>>;
|
|
223
|
+
id(id: string): {
|
|
224
|
+
update<const Inc extends readonly IncludePath<D, T>[] = [], const F extends FieldsMap<D> = {}>(patch: UpdateInput<D, W, T>, opts?: WriteOptions<D, T, Inc, F>): Promise<ReadResult<D, A, T, Inc, F>>;
|
|
225
|
+
delete(): Promise<void>;
|
|
226
|
+
rel(name: RelationName<D, T>): {
|
|
227
|
+
add(refs: readonly LinkageRef<string>[]): Promise<unknown>;
|
|
228
|
+
remove(refs: readonly LinkageRef<string>[]): Promise<unknown>;
|
|
229
|
+
replace(refs: readonly LinkageRef<string>[]): Promise<unknown>;
|
|
230
|
+
set(ref: LinkageRef<string> | null): Promise<unknown>;
|
|
231
|
+
};
|
|
232
|
+
};
|
|
233
|
+
} };
|
|
234
|
+
/**
|
|
235
|
+
* The create mutation (`POST /{type}`): `mutationFn` runs `client.<type>.create(input, opts)`;
|
|
236
|
+
* on settle the type's list subtree is invalidated (a new member changes collection membership —
|
|
237
|
+
* a patch can't insert it, ADR 0003). The fresh resource is also normalized on success so any
|
|
238
|
+
* query already holding the (server-assigned-id) resource reflects it.
|
|
239
|
+
*
|
|
240
|
+
* No optimistic insert by default: inserting into the right cached lists requires knowing each
|
|
241
|
+
* list's sort/filter/page, which is list-specific — we invalidate instead (the documented,
|
|
242
|
+
* always-correct default). A caller wanting optimism supplies their own `onMutate`.
|
|
243
|
+
*/
|
|
244
|
+
declare function createMutationOptions<D extends ApiDescriptor, A, W, T extends TypeName<D>, const Inc extends readonly IncludePath<D, T>[] = [], const F extends FieldsMap<D> = {}>(queryClient: QueryClient, client: WriteClient<D, A, W>, descriptor: D, type: T, opts?: WriteOptions<D, T, Inc, F>): MutationOptions<ReadResult<D, A, T, Inc, F>, CreateInput<D, W, T>>;
|
|
245
|
+
/**
|
|
246
|
+
* The update mutation (`PATCH /{type}/{id}`): `mutationFn` runs
|
|
247
|
+
* `client.<type>.id(id).update(patch, opts)`. An update only changes a node's attributes/linkage,
|
|
248
|
+
* so on success it PATCHES across the cache via {@link normalize} (no refetch). When optimistic,
|
|
249
|
+
* `onMutate` pre-applies the patch's attributes (those keys that are declared attributes of the
|
|
250
|
+
* type — relation slots are skipped) through the normalized patch and snapshots the touched
|
|
251
|
+
* queries; `onError` restores the snapshot.
|
|
252
|
+
*
|
|
253
|
+
* @param optimistic apply the patch's attributes immediately (rolled back on error). Default off.
|
|
254
|
+
*/
|
|
255
|
+
declare function updateMutationOptions<D extends ApiDescriptor, A, W, T extends TypeName<D>, const Inc extends readonly IncludePath<D, T>[] = [], const F extends FieldsMap<D> = {}>(queryClient: QueryClient, client: WriteClient<D, A, W>, descriptor: D, type: T, id: string, opts?: WriteOptions<D, T, Inc, F> & {
|
|
256
|
+
optimistic?: boolean;
|
|
257
|
+
}): MutationOptions<ReadResult<D, A, T, Inc, F>, UpdateInput<D, W, T>, MutationContext>;
|
|
258
|
+
/**
|
|
259
|
+
* The delete mutation (`DELETE /{type}/{id}`): `mutationFn` runs `client.<type>.id(id).delete()`
|
|
260
|
+
* (resolves `void`). On settle the type's list subtree AND that resource's reads are invalidated
|
|
261
|
+
* (a delete changes collection membership and orphans the resource's `get`, ADR 0003).
|
|
262
|
+
*/
|
|
263
|
+
declare function deleteMutationOptions<D extends ApiDescriptor, A, W, T extends TypeName<D>>(queryClient: QueryClient, client: WriteClient<D, A, W>, type: T, id: string): MutationOptions<void, void>;
|
|
264
|
+
/** Options for a relationship mutation: opt into an optimistic membership/linkage patch (default off). */
|
|
265
|
+
interface RelationshipMutationOpts {
|
|
266
|
+
/**
|
|
267
|
+
* Apply the membership change to the parent's cached related/relationship reads immediately
|
|
268
|
+
* (by key prefix — every page variant), snapshotting for automatic rollback on error. The factory
|
|
269
|
+
* still invalidates the relation subtree on settle so the server reconciles. Default off (a plain
|
|
270
|
+
* invalidate-on-settle). An optimistic `add` appends bare identifier members (`{type,id}` + any
|
|
271
|
+
* `$pivot` on the ref) — the settle refetch replaces them with the fully-hydrated resources.
|
|
272
|
+
*/
|
|
273
|
+
optimistic?: boolean;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* A to-one relationship `set` (`PATCH …/relationships/{rel}` with a single ref or `null`):
|
|
277
|
+
* `mutationFn` runs `client.<type>.id(id).rel(rel).set(ref)`. A `set` changes which resource the
|
|
278
|
+
* to-one points at — linkage, not collection membership and not a node attribute — so on settle
|
|
279
|
+
* we invalidate the PARENT's relations subtree (its `fetchRelationship`/`fetchRelated`/included
|
|
280
|
+
* reads refetch). The mutation response (linkage) is also normalized on success. When optimistic,
|
|
281
|
+
* `onMutate` swaps the parent's cached relationship/related reads to the new single value (or `null`)
|
|
282
|
+
* and rolls back on error.
|
|
283
|
+
*/
|
|
284
|
+
declare function setRelationshipMutationOptions<D extends ApiDescriptor, A, W, T extends TypeName<D>>(queryClient: QueryClient, client: WriteClient<D, A, W>, descriptor: D, type: T, id: string, rel: RelationName<D, T>, opts?: RelationshipMutationOpts): MutationOptions<unknown, LinkageRef<string> | null, MutationContext>;
|
|
285
|
+
/**
|
|
286
|
+
* A to-many relationship `replace` (`PATCH …/relationships/{rel}` with the full new set):
|
|
287
|
+
* `mutationFn` runs `client.<type>.id(id).rel(rel).replace(refs)`. A full replacement resets the
|
|
288
|
+
* relation's membership, so on settle the parent's relations subtree is invalidated. The
|
|
289
|
+
* mutation response (the new linkage) is normalized on success. When optimistic, the cached
|
|
290
|
+
* membership is swapped to `refs` and rolled back on error.
|
|
291
|
+
*/
|
|
292
|
+
declare function replaceRelationshipMutationOptions<D extends ApiDescriptor, A, W, T extends TypeName<D>>(queryClient: QueryClient, client: WriteClient<D, A, W>, descriptor: D, type: T, id: string, rel: RelationName<D, T>, opts?: RelationshipMutationOpts): MutationOptions<unknown, readonly LinkageRef<string>[], MutationContext>;
|
|
293
|
+
/**
|
|
294
|
+
* A to-many relationship `add` (`POST …/relationships/{rel}`): `mutationFn` runs
|
|
295
|
+
* `client.<type>.id(id).rel(rel).add(refs)`. Adding changes the relation's membership, so on
|
|
296
|
+
* settle the parent's relations subtree is invalidated (a patch can't insert linkage members).
|
|
297
|
+
* When optimistic, the added refs are appended to the cached membership (deduplicated by `type:id`)
|
|
298
|
+
* and rolled back on error.
|
|
299
|
+
*/
|
|
300
|
+
declare function addRelationshipMutationOptions<D extends ApiDescriptor, A, W, T extends TypeName<D>>(queryClient: QueryClient, client: WriteClient<D, A, W>, type: T, id: string, rel: RelationName<D, T>, opts?: RelationshipMutationOpts): MutationOptions<unknown, readonly LinkageRef<string>[], MutationContext>;
|
|
301
|
+
/**
|
|
302
|
+
* A to-many relationship `remove` (`DELETE …/relationships/{rel}`): `mutationFn` runs
|
|
303
|
+
* `client.<type>.id(id).rel(rel).remove(refs)`. Removing changes the relation's membership, so on
|
|
304
|
+
* settle the parent's relations subtree is invalidated. When optimistic, the removed refs are
|
|
305
|
+
* dropped from the cached membership and rolled back on error.
|
|
306
|
+
*/
|
|
307
|
+
declare function removeRelationshipMutationOptions<D extends ApiDescriptor, A, W, T extends TypeName<D>>(queryClient: QueryClient, client: WriteClient<D, A, W>, type: T, id: string, rel: RelationName<D, T>, opts?: RelationshipMutationOpts): MutationOptions<unknown, readonly LinkageRef<string>[], MutationContext>;
|
|
308
|
+
/**
|
|
309
|
+
* A thin atomic-batch mutation (`POST /operations`): `mutationFn` forwards the `build` callback to
|
|
310
|
+
* `client.atomic(build)`, preserving the client's per-op `const`-tuple result inference (the
|
|
311
|
+
* variables ARE the build callback). On success the materialised results are run through
|
|
312
|
+
* {@link normalize} so any updated resource patches across the cache.
|
|
313
|
+
*
|
|
314
|
+
* INVALIDATION is the caller's responsibility for atomic: a batch can mix creates/updates/deletes
|
|
315
|
+
* across many types, and the recorded ops aren't enumerable after the build runs, so the binding
|
|
316
|
+
* can't know which list subtrees changed membership. Updates self-heal via the success
|
|
317
|
+
* normalization; for a batch that creates/deletes, add an `onSettled` that invalidates the
|
|
318
|
+
* affected `operationKey(type, 'fetchMany')` subtrees (or `queryClient.invalidateQueries()` for a
|
|
319
|
+
* blanket refetch). Kept deliberately minimal — atomic is an escape hatch, not a normalized path.
|
|
320
|
+
*/
|
|
321
|
+
declare function atomicMutationOptions<D extends ApiDescriptor, A, W>(queryClient: QueryClient, client: WriteClient<D, A, W>, descriptor: D): MutationOptions<AtomicResult[], <const Ops>(tx: AtomicRecorder<D, W>) => Ops extends readonly AtomicHandle[] ? AtomicResults<D, A, Ops> : Ops>;
|
|
322
|
+
/** Extra options for an `update(...)` mutation: the write `include`/`fields` plus the optimistic toggle. */
|
|
323
|
+
type UpdateMutationOpts<D extends ApiDescriptor, T extends TypeName<D>, Inc extends readonly IncludePath<D, T>[] = [], F extends FieldsMap<D> = FieldsMap<D>> = WriteOptions<D, T, Inc, F> & {
|
|
324
|
+
optimistic?: boolean;
|
|
325
|
+
};
|
|
326
|
+
/**
|
|
327
|
+
* The relationship-mutation option factories for one relation (`api.<type>.id(id).rel(rel).add(...)`).
|
|
328
|
+
* Refs are typed loosely (`LinkageRef<string>`) at the `.rel(name)` boundary — parity with the
|
|
329
|
+
* read API, whose per-relation value is also loose there (the related type isn't recoverable from
|
|
330
|
+
* the relation name alone in the bound surface). Each accepts an optional
|
|
331
|
+
* {@link RelationshipMutationOpts} to opt into the optimistic membership/linkage patch.
|
|
332
|
+
*/
|
|
333
|
+
interface RelationMutationApi {
|
|
334
|
+
add(opts?: RelationshipMutationOpts): MutationOptions<unknown, readonly LinkageRef<string>[], MutationContext>;
|
|
335
|
+
remove(opts?: RelationshipMutationOpts): MutationOptions<unknown, readonly LinkageRef<string>[], MutationContext>;
|
|
336
|
+
replace(opts?: RelationshipMutationOpts): MutationOptions<unknown, readonly LinkageRef<string>[], MutationContext>;
|
|
337
|
+
set(opts?: RelationshipMutationOpts): MutationOptions<unknown, LinkageRef<string> | null, MutationContext>;
|
|
338
|
+
}
|
|
339
|
+
/** The id-scoped mutation option factories (`api.<type>.id(id).update(...)` etc.). */
|
|
340
|
+
interface HandleMutationApi<D extends ApiDescriptor, A, W, T extends TypeName<D>> {
|
|
341
|
+
update<const Inc extends readonly IncludePath<D, T>[] = [], const F extends FieldsMap<D> = {}>(opts?: UpdateMutationOpts<D, T, Inc, F>): MutationOptions<ReadResult<D, A, T, Inc, F>, UpdateInput<D, W, T>, MutationContext>;
|
|
342
|
+
delete(): MutationOptions<void, void>;
|
|
343
|
+
rel(name: RelationName<D, T>): RelationMutationApi;
|
|
344
|
+
}
|
|
345
|
+
/** The per-type mutation option factories, with `queryClient`/`client`/`descriptor`/`type` pre-applied. */
|
|
346
|
+
interface TypeMutationApi<D extends ApiDescriptor, A, W, T extends TypeName<D>> {
|
|
347
|
+
create<const Inc extends readonly IncludePath<D, T>[] = [], const F extends FieldsMap<D> = {}>(opts?: WriteOptions<D, T, Inc, F>): MutationOptions<ReadResult<D, A, T, Inc, F>, CreateInput<D, W, T>>;
|
|
348
|
+
id(id: string): HandleMutationApi<D, A, W, T>;
|
|
349
|
+
}
|
|
350
|
+
/** The bound mutation API: one {@link TypeMutationApi} per wire type (`api.albums.create()`). */
|
|
351
|
+
type MutationApi<D extends ApiDescriptor, A, W> = { [T in TypeName<D>]: TypeMutationApi<D, A, W, T> };
|
|
352
|
+
/**
|
|
353
|
+
* Bind a client + QueryClient to the per-type mutation option factories:
|
|
354
|
+
* `createMutationApi(queryClient, client, descriptor).albums.id('1').update({ optimistic: true })`
|
|
355
|
+
* returns the same `MutationOptions` as the standalone {@link updateMutationOptions}, with the
|
|
356
|
+
* common arguments pre-applied. A Proxy (descriptor-keyed type validity is enforced by the static
|
|
357
|
+
* `MutationApi` shape) — no per-type allocation until first access.
|
|
358
|
+
*/
|
|
359
|
+
declare function createMutationApi<D extends ApiDescriptor, A, W>(queryClient: QueryClient, client: WriteClient<D, A, W>, descriptor: D): MutationApi<D, A, W>;
|
|
360
|
+
//#endregion
|
|
361
|
+
//#region src/read.d.ts
|
|
362
|
+
/**
|
|
363
|
+
* The precise materialised result of `.rel(R).related()` / `.get()` — extracted (via `infer`)
|
|
364
|
+
* from the client's own {@link RelationshipAccessor} so the read factories carry the client's
|
|
365
|
+
* full per-relation narrowing (a `Collection` of hydrated members / identifier members, typed
|
|
366
|
+
* `$pivot`, polymorphic unions) instead of a loose `unknown` (D34). A suppressed endpoint (whose
|
|
367
|
+
* method the client types `never`) falls back to `unknown`.
|
|
368
|
+
*/
|
|
369
|
+
type RelatedResult<D extends ApiDescriptor, A, T extends TypeName<D>, R extends RelationName<D, T>> = RelationshipAccessor<D, A, T, R>['related'] extends ((...args: never[]) => Promise<infer V>) ? V : unknown;
|
|
370
|
+
type LinkageResult<D extends ApiDescriptor, A, T extends TypeName<D>, R extends RelationName<D, T>> = RelationshipAccessor<D, A, T, R>['get'] extends ((...args: never[]) => Promise<infer V>) ? V : unknown;
|
|
371
|
+
/**
|
|
372
|
+
* A TanStack-compatible query-options object: the deterministic {@link QueryKey} plus a
|
|
373
|
+
* zero-arg `queryFn` resolving the materialised result `R`. Structurally assignable to
|
|
374
|
+
* `query-core`'s `QueryOptions`/`UseQueryOptions` (the user merges in `staleTime` etc.), so the
|
|
375
|
+
* binding needn't import or re-export query-core's option type — it stays a peer.
|
|
376
|
+
*/
|
|
377
|
+
interface QueryOptions<R> {
|
|
378
|
+
queryKey: QueryKey;
|
|
379
|
+
queryFn: () => Promise<R>;
|
|
380
|
+
}
|
|
381
|
+
/** A client narrowed to its per-type accessors (drops the `atomic` member, which reads don't use). */
|
|
382
|
+
type TypedClient<D extends ApiDescriptor, A> = { [T in TypeName<D>]: {
|
|
383
|
+
list<const Inc extends readonly IncludePath<D, T>[] = [], const F extends FieldsMap<D> = {}>(query?: TypedReadQuery<D, T, Inc, F>): Promise<Collection<ReadResult<D, A, T, Inc, F>>>;
|
|
384
|
+
get<const Inc extends readonly IncludePath<D, T>[] = [], const F extends FieldsMap<D> = {}>(id: string, query?: SingleReadQuery<D, T, Inc, F>): Promise<ReadResult<D, A, T, Inc, F>>;
|
|
385
|
+
id(id: string): {
|
|
386
|
+
rel(name: RelationName<D, T>): {
|
|
387
|
+
get(query?: RelationReadQuery): Promise<unknown>;
|
|
388
|
+
related(query?: RelationReadQuery): Promise<unknown>;
|
|
389
|
+
};
|
|
390
|
+
};
|
|
391
|
+
} };
|
|
392
|
+
/**
|
|
393
|
+
* The collection-list read (`GET /{type}`): options resolving the typed `Collection`, narrowed by
|
|
394
|
+
* `include`/`fields` exactly as `client.<type>.list(query)`. The key is `[type, 'fetchMany',
|
|
395
|
+
* <params>]` — the normalised query rides the trailing segment, so two equal queries share a key.
|
|
396
|
+
*/
|
|
397
|
+
declare function listQueryOptions<D extends ApiDescriptor, A, T extends TypeName<D>, const Inc extends readonly IncludePath<D, T>[] = [], const F extends FieldsMap<D> = {}>(client: TypedClient<D, A>, type: T, query?: TypedReadQuery<D, T, Inc, F>): QueryOptions<Collection<ReadResult<D, A, T, Inc, F>>>;
|
|
398
|
+
/**
|
|
399
|
+
* The single-resource read (`GET /{type}/{id}`): options resolving the typed resource view,
|
|
400
|
+
* narrowed by `include`/`fields` as `client.<type>.get(id, query)`. Key: `[type, 'fetchOne', id,
|
|
401
|
+
* <params>]` — the `id` sits at a fixed position so {@link keyFor}'s prefix matches a resource's
|
|
402
|
+
* reads.
|
|
403
|
+
*/
|
|
404
|
+
declare function getQueryOptions<D extends ApiDescriptor, A, T extends TypeName<D>, const Inc extends readonly IncludePath<D, T>[] = [], const F extends FieldsMap<D> = {}>(client: TypedClient<D, A>, type: T, id: string, query?: SingleReadQuery<D, T, Inc, F>): QueryOptions<ReadResult<D, A, T, Inc, F>>;
|
|
405
|
+
/**
|
|
406
|
+
* The relationship-linkage read (`GET /{type}/{id}/relationships/{rel}`): options resolving the
|
|
407
|
+
* materialised linkage (identifier members), via `client.<type>.id(id).rel(rel).get(query)`. Key:
|
|
408
|
+
* `[type, 'fetchRelationship', id, rel, <params>]`. The result is the client's runtime linkage
|
|
409
|
+
* shape; the relationship endpoint's per-relation value is loose at the `.rel(name)` boundary, so
|
|
410
|
+
* the option resolves `unknown` unless the caller annotates it (parity with the client's runtime).
|
|
411
|
+
*/
|
|
412
|
+
declare function relationshipQueryOptions<D extends ApiDescriptor, A, T extends TypeName<D>, R extends RelationName<D, T>>(client: TypedClient<D, A>, type: T, id: string, rel: R, query?: RelationReadQuery): QueryOptions<LinkageResult<D, A, T, R>>;
|
|
413
|
+
/**
|
|
414
|
+
* The related-collection read (`GET /{type}/{id}/{rel}`): options resolving the materialised
|
|
415
|
+
* related resource(s), via `client.<type>.id(id).rel(rel).related(query)`. Key: `[type,
|
|
416
|
+
* 'fetchRelated', id, rel, <params>]`. As with linkage, the related value is loose at the
|
|
417
|
+
* `.rel(name)` boundary, so this resolves `unknown` (parity with the client runtime).
|
|
418
|
+
*/
|
|
419
|
+
declare function relatedQueryOptions<D extends ApiDescriptor, A, T extends TypeName<D>, R extends RelationName<D, T>>(client: TypedClient<D, A>, type: T, id: string, rel: R, query?: RelationReadQuery): QueryOptions<RelatedResult<D, A, T, R>>;
|
|
420
|
+
/** The per-type read-option factories, with `client`/`type` pre-applied (`api.<type>.list(...)`). */
|
|
421
|
+
interface TypeQueryApi<D extends ApiDescriptor, A, T extends TypeName<D>> {
|
|
422
|
+
list<const Inc extends readonly IncludePath<D, T>[] = [], const F extends FieldsMap<D> = {}>(query?: TypedReadQuery<D, T, Inc, F>): QueryOptions<Collection<ReadResult<D, A, T, Inc, F>>>;
|
|
423
|
+
get<const Inc extends readonly IncludePath<D, T>[] = [], const F extends FieldsMap<D> = {}>(id: string, query?: SingleReadQuery<D, T, Inc, F>): QueryOptions<ReadResult<D, A, T, Inc, F>>;
|
|
424
|
+
relationship<R extends RelationName<D, T>>(id: string, rel: R, query?: RelationReadQuery): QueryOptions<LinkageResult<D, A, T, R>>;
|
|
425
|
+
related<R extends RelationName<D, T>>(id: string, rel: R, query?: RelationReadQuery): QueryOptions<RelatedResult<D, A, T, R>>;
|
|
426
|
+
}
|
|
427
|
+
/** The bound query API: one {@link TypeQueryApi} per wire type (`api.albums.list(...)`). */
|
|
428
|
+
type QueryApi<D extends ApiDescriptor, A> = { [T in TypeName<D>]: TypeQueryApi<D, A, T> };
|
|
429
|
+
/**
|
|
430
|
+
* Bind a client to its per-type read-option factories: `createQueryApi(client).albums.list(query)`
|
|
431
|
+
* returns the same `{ queryKey, queryFn }` as `listQueryOptions(client, 'albums', query)`, with
|
|
432
|
+
* `client`/`type` pre-applied. A Proxy (descriptor-free — type validity is enforced by the static
|
|
433
|
+
* `QueryApi` shape) so no per-type allocation until first access.
|
|
434
|
+
*/
|
|
435
|
+
declare function createQueryApi<D extends ApiDescriptor, A>(client: TypedClient<D, A>): QueryApi<D, A>;
|
|
436
|
+
//#endregion
|
|
437
|
+
export { HandleMutationApi, KeyTarget, MembershipRef, MembershipTransform, MutationApi, MutationContext, MutationOptions, NormalizedParams, QueryApi, QueryKey, QueryKeyPart, QueryOptions, ReadOperation, RelationMutationApi, RelationshipMutationOpts, Snapshot, Teardown, TypeMutationApi, TypeQueryApi, UpdateMutationOpts, addRelationshipMutationOptions, applyOptimisticMembership, applyOptimisticPatch, applyOptimisticToOne, atomicMutationOptions, createMutationApi, createMutationOptions, createQueryApi, deleteMutationOptions, getQueryOptions, installNormalization, keyFor, keyHasPrefix, listQueryOptions, normalize, normalizeParams, operationKey, relatedQueryOptions, relationKey, relationReadKeys, relationshipQueryOptions, removeRelationshipMutationOptions, replaceRelationshipMutationOptions, resourceKey, sameRef, setRelationshipMutationOptions, typeKey, updateMutationOptions };
|
|
438
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/install.ts","../src/keys.ts","../src/normalize.ts","../src/mutate.ts","../src/read.ts"],"mappings":"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"}
|