@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.
@@ -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.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/install.ts","../src/keys.ts","../src/normalize.ts","../src/mutate.ts","../src/read.ts"],"mappings":"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"}