@beignet/react-query 0.0.52 → 0.0.54
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/CHANGELOG.md +17 -0
- package/README.md +147 -1
- package/dist/broadcasting.d.ts +17 -0
- package/dist/broadcasting.d.ts.map +1 -0
- package/dist/broadcasting.js +83 -0
- package/dist/broadcasting.js.map +1 -0
- package/dist/cache.d.ts +34 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +27 -0
- package/dist/cache.js.map +1 -0
- package/dist/index.d.ts +30 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +103 -5
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/skills/client/SKILL.md +47 -1
- package/src/broadcasting.ts +107 -0
- package/src/cache.ts +94 -0
- package/src/index.ts +175 -22
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @beignet/react-query
|
|
2
2
|
|
|
3
|
+
## 0.0.54
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- b71b34f: Add typed, authorized browser broadcasting with bounded SSE connections, memory
|
|
8
|
+
and Redis providers, reconnect reconciliation, React Query invalidation,
|
|
9
|
+
initiating-client exclusion, notification delivery, and transactional inbox
|
|
10
|
+
scaffolding. Raw routes now preserve context added by route hooks.
|
|
11
|
+
|
|
12
|
+
## 0.0.53
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- faf58ad: Clarify form adapter installation and migration, document TanStack Form UI
|
|
17
|
+
generator restrictions, and correct React Form reference examples.
|
|
18
|
+
- 4df0522: Add typed `cacheEntries` and `updateCachedQueries` helpers with partial parameter matching, and declarative, awaited mutation invalidation. Preserve native query metadata and snapshot success defaults for each executing mutation. Prevent recursive execution of composed mutation defaults. Append an `infinite` segment to generated infinite-query keys so manually seeded and hydrated infinite data stays separate from standard responses; discard persisted infinite caches from the old key format when upgrading. Reserve the `beignet` key prefix for contract data. Require TanStack React Query 5.102 or newer and align generated dependency ranges.
|
|
19
|
+
|
|
3
20
|
## 0.0.52
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -323,6 +323,129 @@ const todosInfiniteQuery = rq(listTodos).infiniteQueryOptions({
|
|
|
323
323
|
});
|
|
324
324
|
```
|
|
325
325
|
|
|
326
|
+
## Typed cache access
|
|
327
|
+
|
|
328
|
+
Use `cacheEntries(queryClient, match?)` to inspect cached standard queries with
|
|
329
|
+
contract-derived response and parameter types:
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
const todos = rq(listTodos);
|
|
333
|
+
const entries = todos.cacheEntries(queryClient);
|
|
334
|
+
|
|
335
|
+
for (const { queryKey, params, data } of entries) {
|
|
336
|
+
// data is the raw listTodos response, or undefined before data is available.
|
|
337
|
+
console.log(queryKey, params, data?.items);
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
`match` uses the same parameter-prefix matching as `filter(...)`. Path, query,
|
|
342
|
+
body, and header objects accept a subset of their top-level fields. For a
|
|
343
|
+
contract with both `workspaceId` and `id` path parameters, pass
|
|
344
|
+
`{ path: { workspaceId } }` to match every ID in that workspace. Actual query
|
|
345
|
+
and mutation requests still require complete parameters.
|
|
346
|
+
|
|
347
|
+
Returned parameters describe normalized cache identity, not complete request
|
|
348
|
+
arguments: nullish path/query fields are omitted, bodies
|
|
349
|
+
use their JSON representation, and headers contain only lowercased names
|
|
350
|
+
explicitly included through `keyHeaders`. Parameter objects are copied so
|
|
351
|
+
editing them cannot change a query key.
|
|
352
|
+
|
|
353
|
+
Update matching existing entries with `updateCachedQueries`:
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
todos.updateCachedQueries(queryClient, {
|
|
357
|
+
update: ({ data }) => {
|
|
358
|
+
if (!data) return undefined;
|
|
359
|
+
return {
|
|
360
|
+
...data,
|
|
361
|
+
items: data.items.map((todo) =>
|
|
362
|
+
todo.id === updatedTodo.id ? { ...todo, ...updatedTodo } : todo,
|
|
363
|
+
),
|
|
364
|
+
};
|
|
365
|
+
},
|
|
366
|
+
});
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
The updater receives `{ queryKey, params, data }` for each entry. It runs
|
|
370
|
+
synchronously against current data, must update immutably, and leaves an entry
|
|
371
|
+
alone when it returns `undefined`. The helper does not create missing entries.
|
|
372
|
+
Applications own list membership, sorting, pagination, optimistic rollback,
|
|
373
|
+
and coordination with in-flight requests.
|
|
374
|
+
|
|
375
|
+
Both helpers recognize standard queries using the contract's generated keys,
|
|
376
|
+
including entries seeded with `setQueryData(helper.key(...), data)`. Store only
|
|
377
|
+
the contract's raw response under these keys. Data is read before an observer's
|
|
378
|
+
`select` transformation. Infinite queries and custom keys are excluded.
|
|
379
|
+
|
|
380
|
+
Standard query keys keep their existing format. Generated infinite-query keys
|
|
381
|
+
append an `"infinite"` segment, so they remain distinct when manually seeded or
|
|
382
|
+
dehydrated and hydrated. Use the `queryKey` returned by `infiniteQueryOptions`
|
|
383
|
+
for direct reads, writes, and exact matching of infinite data. Namespace,
|
|
384
|
+
contract, and parameter-prefix filters still match both query types.
|
|
385
|
+
|
|
386
|
+
When upgrading, discard persisted infinite-query caches created with the old
|
|
387
|
+
key format. The `"beignet"` prefix is reserved: passing a custom `key` with that
|
|
388
|
+
prefix throws. Omit `key` to use a generated key, and use ordinary TanStack
|
|
389
|
+
cache APIs for custom keys and infinite-query data.
|
|
390
|
+
|
|
391
|
+
Beignet does not add query metadata. Global defaults, query-key defaults, and
|
|
392
|
+
explicit `meta` options retain TanStack's normal precedence.
|
|
393
|
+
|
|
394
|
+
## Declarative mutation invalidation
|
|
395
|
+
|
|
396
|
+
Pass `invalidates` to `mutationOptions` to select affected queries from the
|
|
397
|
+
successful response and mutation variables:
|
|
398
|
+
|
|
399
|
+
```typescript
|
|
400
|
+
const mutation = useMutation(
|
|
401
|
+
rq(updateTodo).mutationOptions({
|
|
402
|
+
invalidates: (_todo, variables) => [
|
|
403
|
+
rq(getTodo).filter({ path: variables.path }),
|
|
404
|
+
rq(listTodos).contractFilter(),
|
|
405
|
+
],
|
|
406
|
+
onSuccess: (todo) => {
|
|
407
|
+
// Optional application work runs before invalidation.
|
|
408
|
+
console.log("Saved", todo.id);
|
|
409
|
+
},
|
|
410
|
+
}),
|
|
411
|
+
);
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
The callback returns an array of ordinary TanStack invalidation filters and may
|
|
415
|
+
be asynchronous. An empty array requests no invalidation. Put shared filter
|
|
416
|
+
selection in a feature client function when mutations and realtime events
|
|
417
|
+
should refresh the same queries.
|
|
418
|
+
|
|
419
|
+
Beignet uses the executing mutation's `QueryClient`, waits for its configured
|
|
420
|
+
`onSuccess`, then attempts and awaits every requested invalidation before
|
|
421
|
+
`onSettled`. Client-wide and mutation-key success defaults are honored unless
|
|
422
|
+
overridden in `mutationOptions`. Success defaults are captured when the
|
|
423
|
+
generated mutation function first starts, and retained across retries; changes
|
|
424
|
+
to defaults while that request is pending apply to subsequent invocations.
|
|
425
|
+
|
|
426
|
+
Generated options can be composed and registered with `setMutationDefaults`.
|
|
427
|
+
When composition retains an earlier success wrapper, each wrapper runs its
|
|
428
|
+
invalidation once per mutation invocation, including when defaults refer back
|
|
429
|
+
to the composed options.
|
|
430
|
+
|
|
431
|
+
Default TanStack behavior marks matching queries stale and refetches active
|
|
432
|
+
eligible queries. Failed requests do not run `invalidates`.
|
|
433
|
+
|
|
434
|
+
Invalidation still runs when the configured `onSuccess` throws after a
|
|
435
|
+
successful request. Callback or invalidation failures follow TanStack's
|
|
436
|
+
post-success error handling and do not retry the successful HTTP write;
|
|
437
|
+
multiple failures are reported as an `AggregateError`. Normal TanStack refetch
|
|
438
|
+
error behavior remains in effect.
|
|
439
|
+
|
|
440
|
+
Pass lifecycle callbacks **inside** `mutationOptions({ ... })`. Spreading the
|
|
441
|
+
returned options and replacing `onSuccess` replaces the invalidation wrapper.
|
|
442
|
+
Callbacks passed to `mutate(variables, { onSuccess })` keep TanStack's normal
|
|
443
|
+
per-call behavior and run after the configured success handling.
|
|
444
|
+
|
|
445
|
+
These helpers require TanStack React Query **5.102.0 or newer in the v5 line**.
|
|
446
|
+
The executing client comes from TanStack's mutation callback context. They do
|
|
447
|
+
not add write locks or defer polling and realtime refreshes during mutations.
|
|
448
|
+
|
|
326
449
|
## API reference
|
|
327
450
|
|
|
328
451
|
### `createReactQuery(client, options?)`
|
|
@@ -704,7 +827,30 @@ Hook wrappers have been removed—use the options-first API for all queries and
|
|
|
704
827
|
- [`@beignet/core/contracts`](https://beignetjs.com/contracts) - Core contract definitions
|
|
705
828
|
- [`@beignet/core/client`](https://beignetjs.com/client) - HTTP client
|
|
706
829
|
- [`@beignet/nuqs`](https://beignetjs.com/nuqs) - URL query state integration
|
|
707
|
-
- [`@beignet/react-hook-form`](https://beignetjs.com/react-hook-form) - Form integration
|
|
830
|
+
- [`@beignet/react-hook-form`](https://beignetjs.com/react-hook-form) - React Hook Form integration
|
|
831
|
+
- [`@beignet/react-form`](https://beignetjs.com/react-form) - TanStack Form integration
|
|
832
|
+
|
|
833
|
+
## Broadcast query subscriptions
|
|
834
|
+
|
|
835
|
+
`createBroadcastQuerySubscription({ client, channel, params, queryClient,
|
|
836
|
+
invalidates, reconciles, onError?, onStatusChange? })` maps typed broadcasts to
|
|
837
|
+
TanStack Query filters. `invalidates(event)` returns the filters affected by one
|
|
838
|
+
hint; `reconciles` lists every query covered by the channel and runs after initial
|
|
839
|
+
readiness and every reconnect. Use contract-derived `contractFilter()`,
|
|
840
|
+
`filter(params)`, or `namespaceFilter()` rather than hand-built query keys.
|
|
841
|
+
|
|
842
|
+
The helper marks matching queries stale, coalesces hints, and performs a later
|
|
843
|
+
refetch if a hint arrives during an existing fetch. Active queries refetch;
|
|
844
|
+
inactive queries remain stale even when an earlier fetch completes after the
|
|
845
|
+
hint. Disabled and static queries retain TanStack's normal behavior. It
|
|
846
|
+
returns `unsubscribe()` and `getStatus()`. Unsubscribe removes its cache listener
|
|
847
|
+
and queued work without cancelling queries owned by other observers.
|
|
848
|
+
|
|
849
|
+
Share one `createBroadcastClient` from `@beignet/core/broadcasting/client` across
|
|
850
|
+
features, then close and recreate it on user/workspace changes. Reconcile
|
|
851
|
+
optimistic mutation state separately so a remote refetch does not overwrite an
|
|
852
|
+
in-flight edit. See the [broadcasting guide](https://beignetjs.com/broadcasting)
|
|
853
|
+
for complete channel and React Query examples.
|
|
708
854
|
|
|
709
855
|
## License
|
|
710
856
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ChannelDefinition, InferChannelEvent, InferChannelParams } from "@beignet/core/broadcasting";
|
|
2
|
+
import type { BroadcastClient, BroadcastClientStatus, BroadcastClientSubscription } from "@beignet/core/broadcasting/client";
|
|
3
|
+
import type { QueryClient, QueryFilters } from "@tanstack/react-query";
|
|
4
|
+
export interface BroadcastQuerySubscriptionOptions<C extends ChannelDefinition> {
|
|
5
|
+
client: BroadcastClient;
|
|
6
|
+
channel: C;
|
|
7
|
+
params: InferChannelParams<C>;
|
|
8
|
+
queryClient: QueryClient;
|
|
9
|
+
invalidates: (event: InferChannelEvent<C>) => readonly QueryFilters[];
|
|
10
|
+
/** All state covered by the channel, including unread counters and filtered lists. */
|
|
11
|
+
reconciles: readonly QueryFilters[];
|
|
12
|
+
onError?: (error: unknown) => void;
|
|
13
|
+
onStatusChange?: (status: BroadcastClientStatus) => void;
|
|
14
|
+
}
|
|
15
|
+
/** Invalidate hints and refetch after readiness. An event during a fetch schedules one later fetch. */
|
|
16
|
+
export declare function createBroadcastQuerySubscription<C extends ChannelDefinition>(options: BroadcastQuerySubscriptionOptions<C>): BroadcastClientSubscription;
|
|
17
|
+
//# sourceMappingURL=broadcasting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broadcasting.d.ts","sourceRoot":"","sources":["../src/broadcasting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACrB,2BAA2B,EAC5B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAS,WAAW,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE9E,MAAM,WAAW,iCAAiC,CAChD,CAAC,SAAS,iBAAiB;IAE3B,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAC9B,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,SAAS,YAAY,EAAE,CAAC;IACtE,sFAAsF;IACtF,UAAU,EAAE,SAAS,YAAY,EAAE,CAAC;IACpC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,IAAI,CAAC;CAC1D;AAED,uGAAuG;AACvG,wBAAgB,gCAAgC,CAAC,CAAC,SAAS,iBAAiB,EAC1E,OAAO,EAAE,iCAAiC,CAAC,CAAC,CAAC,GAC5C,2BAA2B,CA6E7B"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/** Invalidate hints and refetch after readiness. An event during a fetch schedules one later fetch. */
|
|
2
|
+
export function createBroadcastQuerySubscription(options) {
|
|
3
|
+
const cache = options.queryClient.getQueryCache();
|
|
4
|
+
const pending = new Set();
|
|
5
|
+
let closed = false;
|
|
6
|
+
let queued = false;
|
|
7
|
+
function flush() {
|
|
8
|
+
if (queued || closed)
|
|
9
|
+
return;
|
|
10
|
+
queued = true;
|
|
11
|
+
queueMicrotask(() => {
|
|
12
|
+
queued = false;
|
|
13
|
+
if (closed)
|
|
14
|
+
return;
|
|
15
|
+
for (const query of pending) {
|
|
16
|
+
if (query.state.fetchStatus !== "idle")
|
|
17
|
+
continue;
|
|
18
|
+
pending.delete(query);
|
|
19
|
+
// A completed fetch clears invalidation, even when it began before the hint.
|
|
20
|
+
query.invalidate();
|
|
21
|
+
// Inactive queries remain stale. TanStack owns enabled/static and observer behavior.
|
|
22
|
+
void options.queryClient
|
|
23
|
+
.refetchQueries({ queryKey: query.queryKey, exact: true, type: "active" }, { cancelRefetch: false, throwOnError: true })
|
|
24
|
+
.catch((error) => {
|
|
25
|
+
if (!closed) {
|
|
26
|
+
try {
|
|
27
|
+
options.onError?.(error);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
/* Reporting cannot disrupt query observers. */
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
const unsubscribeCache = cache.subscribe((event) => {
|
|
38
|
+
if (event.type === "removed")
|
|
39
|
+
pending.delete(event.query);
|
|
40
|
+
if (event.type === "updated" &&
|
|
41
|
+
event.query.state.fetchStatus === "idle" &&
|
|
42
|
+
pending.has(event.query))
|
|
43
|
+
flush();
|
|
44
|
+
});
|
|
45
|
+
function invalidate(filters) {
|
|
46
|
+
if (closed)
|
|
47
|
+
return;
|
|
48
|
+
for (const filter of filters)
|
|
49
|
+
for (const query of cache.findAll(filter)) {
|
|
50
|
+
pending.add(query);
|
|
51
|
+
query.invalidate();
|
|
52
|
+
}
|
|
53
|
+
flush();
|
|
54
|
+
}
|
|
55
|
+
let subscription;
|
|
56
|
+
try {
|
|
57
|
+
subscription = options.client.subscribe(options.channel, {
|
|
58
|
+
params: options.params,
|
|
59
|
+
onEvent: (event) => invalidate(options.invalidates(event)),
|
|
60
|
+
onSync: () => invalidate(options.reconciles),
|
|
61
|
+
onError: options.onError,
|
|
62
|
+
onStatusChange: options.onStatusChange,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
closed = true;
|
|
67
|
+
unsubscribeCache();
|
|
68
|
+
pending.clear();
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
getStatus: subscription.getStatus,
|
|
73
|
+
unsubscribe() {
|
|
74
|
+
if (closed)
|
|
75
|
+
return;
|
|
76
|
+
closed = true;
|
|
77
|
+
subscription.unsubscribe();
|
|
78
|
+
unsubscribeCache();
|
|
79
|
+
pending.clear();
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=broadcasting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broadcasting.js","sourceRoot":"","sources":["../src/broadcasting.ts"],"names":[],"mappings":"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"}
|
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { InferBody, InferPathParams, InferQuery, InferSuccessResponse } from "@beignet/core/client";
|
|
2
|
+
import type { HttpContractConfig } from "@beignet/core/contracts";
|
|
3
|
+
import { type Query, type QueryKey } from "@tanstack/react-query";
|
|
4
|
+
import type { ContractQueryKeyParams } from "./index.js";
|
|
5
|
+
type JsonCacheValue<T> = T extends {
|
|
6
|
+
toJSON: (...args: never[]) => infer Value;
|
|
7
|
+
} ? JsonCacheValue<Value> : T extends ((...args: never[]) => unknown) | symbol | bigint ? unknown : T extends readonly unknown[] ? {
|
|
8
|
+
[K in keyof T]: JsonCacheValue<T[K]> | (undefined extends T[K] ? null : never);
|
|
9
|
+
} : T extends object ? {
|
|
10
|
+
[K in keyof T as K extends string ? K : never]: JsonCacheValue<T[K]>;
|
|
11
|
+
} : T;
|
|
12
|
+
/** Normalized cache identity, not a complete set of arguments for a request. */
|
|
13
|
+
export type ContractCacheParams<TContract extends HttpContractConfig> = {
|
|
14
|
+
readonly path?: JsonCacheValue<Partial<NonNullable<InferPathParams<TContract>>>>;
|
|
15
|
+
readonly query?: JsonCacheValue<Partial<NonNullable<InferQuery<TContract>>>>;
|
|
16
|
+
readonly body?: JsonCacheValue<InferBody<TContract>>;
|
|
17
|
+
/** Only explicitly keyed headers, with lowercase names. */
|
|
18
|
+
readonly headers?: Readonly<Record<string, unknown>>;
|
|
19
|
+
};
|
|
20
|
+
/** One standard query using Beignet's generated contract key. */
|
|
21
|
+
export type ContractCacheEntry<TContract extends HttpContractConfig> = {
|
|
22
|
+
readonly queryKey: QueryKey;
|
|
23
|
+
readonly params: ContractCacheParams<TContract>;
|
|
24
|
+
/** The raw contract response, before any observer-level select. */
|
|
25
|
+
readonly data: InferSuccessResponse<TContract> | undefined;
|
|
26
|
+
};
|
|
27
|
+
/** Update existing entries immutably. Returning undefined leaves an entry alone. */
|
|
28
|
+
export type UpdateCachedQueriesOptions<TContract extends HttpContractConfig, TProvidedHeaders extends string = never> = {
|
|
29
|
+
match?: ContractQueryKeyParams<TContract, TProvidedHeaders>;
|
|
30
|
+
update(entry: ContractCacheEntry<TContract>): InferSuccessResponse<TContract> | undefined;
|
|
31
|
+
};
|
|
32
|
+
export declare function readCacheParams<TContract extends HttpContractConfig>(query: Query, contractKey: QueryKey): ContractCacheParams<TContract> | undefined;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EACf,UAAU,EACV,oBAAoB,EACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAW,KAAK,KAAK,EAAE,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEzD,KAAK,cAAc,CAAC,CAAC,IAAI,CAAC,SAAS;IAAE,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,MAAM,KAAK,CAAA;CAAE,GAC5E,cAAc,CAAC,KAAK,CAAC,GACrB,CAAC,SAAS,CAAC,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,GAAG,MAAM,GAAG,MAAM,GACzD,OAAO,GACP,CAAC,SAAS,SAAS,OAAO,EAAE,GAC1B;KACG,CAAC,IAAI,MAAM,CAAC,GACT,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACpB,CAAC,SAAS,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC;CAC5C,GACD,CAAC,SAAS,MAAM,GACd;KACG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,MAAM,GAAG,CAAC,GAAG,KAAK,GAAG,cAAc,CAC5D,CAAC,CAAC,CAAC,CAAC,CACL;CACF,GACD,CAAC,CAAC;AAEZ,gFAAgF;AAChF,MAAM,MAAM,mBAAmB,CAAC,SAAS,SAAS,kBAAkB,IAAI;IACtE,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,CAC5B,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,CACjD,CAAC;IACF,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7E,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;IACrD,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACtD,CAAC;AAEF,iEAAiE;AACjE,MAAM,MAAM,kBAAkB,CAAC,SAAS,SAAS,kBAAkB,IAAI;IACrE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAChD,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;CAC5D,CAAC;AAEF,oFAAoF;AACpF,MAAM,MAAM,0BAA0B,CACpC,SAAS,SAAS,kBAAkB,EACpC,gBAAgB,SAAS,MAAM,GAAG,KAAK,IACrC;IACF,KAAK,CAAC,EAAE,sBAAsB,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;IAC5D,MAAM,CACJ,KAAK,EAAE,kBAAkB,CAAC,SAAS,CAAC,GACnC,oBAAoB,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;CAChD,CAAC;AAMF,wBAAgB,eAAe,CAAC,SAAS,SAAS,kBAAkB,EAClE,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,QAAQ,GACpB,mBAAmB,CAAC,SAAS,CAAC,GAAG,SAAS,CA4B5C"}
|
package/dist/cache.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { hashKey } from "@tanstack/react-query";
|
|
2
|
+
function isRecord(value) {
|
|
3
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
export function readCacheParams(query, contractKey) {
|
|
6
|
+
const { queryKey } = query;
|
|
7
|
+
// Generated infinite keys have an extra suffix, even before TanStack has
|
|
8
|
+
// registered their options (for example, when seeded with setQueryData).
|
|
9
|
+
if (query.queryType === "infinite" ||
|
|
10
|
+
"initialPageParam" in query.options ||
|
|
11
|
+
(queryKey.length !== 4 && queryKey.length !== 5) ||
|
|
12
|
+
hashKey(queryKey.slice(0, 4)) !== hashKey(contractKey))
|
|
13
|
+
return undefined;
|
|
14
|
+
const params = queryKey[4] ?? {};
|
|
15
|
+
if (!isRecord(params) ||
|
|
16
|
+
Object.keys(params).some((key) => !["path", "query", "body", "headers"].includes(key)))
|
|
17
|
+
return undefined;
|
|
18
|
+
// Return the same JSON representation before and after hydration, and do
|
|
19
|
+
// not hand callers a mutable reference to parameters inside the cache key.
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(JSON.stringify(params));
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAA6B,MAAM,uBAAuB,CAAC;AAmD3E,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,KAAY,EACZ,WAAqB;IAErB,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAC3B,yEAAyE;IACzE,yEAAyE;IACzE,IACE,KAAK,CAAC,SAAS,KAAK,UAAU;QAC9B,kBAAkB,IAAI,KAAK,CAAC,OAAO;QACnC,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC;QAChD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,WAAW,CAAC;QAEtD,OAAO,SAAS,CAAC;IAEnB,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACjC,IACE,CAAC,QAAQ,CAAC,MAAM,CAAC;QACjB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CACtB,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAC7D;QAED,OAAO,SAAS,CAAC;IAEnB,yEAAyE;IACzE,2EAA2E;IAC3E,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAmC,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { Client, Endpoint, EndpointCallArgs, InferBody, InferEndpointContractError, InferPathParams, InferQuery, InferSuccessResponse } from "@beignet/core/client";
|
|
2
|
+
export { type BroadcastQuerySubscriptionOptions, createBroadcastQuerySubscription, } from "./broadcasting.js";
|
|
2
3
|
import { type ContractLike, type HttpContractConfig, type ResolveContract } from "@beignet/core/contracts";
|
|
3
4
|
import type { InfiniteData, InvalidateQueryFilters, QueryClient, QueryFunction, QueryKey, UseInfiniteQueryOptions, UseMutationOptions, UseQueryOptions } from "@tanstack/react-query";
|
|
5
|
+
import { type ContractCacheEntry, type UpdateCachedQueriesOptions } from "./cache.js";
|
|
6
|
+
export type { ContractCacheEntry, ContractCacheParams, UpdateCachedQueriesOptions, } from "./cache.js";
|
|
4
7
|
type EndpointQueryArgs<TContract extends HttpContractConfig, TProvidedHeaders extends string> = Omit<EndpointCallArgs<TContract, TProvidedHeaders>, "rawBody" | "signal" | "idempotencyKey">;
|
|
5
8
|
type EndpointArgValue<TArgs, TKey extends "path" | "query" | "body" | "headers"> = TKey extends keyof TArgs ? TArgs[TKey] : undefined;
|
|
6
9
|
type IsRequiredValue<T> = undefined extends T ? false : true;
|
|
@@ -28,11 +31,14 @@ export type ContractUseQueryOptions<TContract extends HttpContractConfig, TProvi
|
|
|
28
31
|
key?: readonly unknown[];
|
|
29
32
|
} & ContractQueryOptionsBase<TContract, TData>;
|
|
30
33
|
type ContractQueryOptionsCallArgs<TContract extends HttpContractConfig, TProvidedHeaders extends string, TData = InferSuccessResponse<TContract>> = RequiresQueryOptionsArgs<TContract, TProvidedHeaders> extends true ? [args: ContractUseQueryOptions<TContract, TProvidedHeaders, TData>] : [args?: ContractUseQueryOptions<TContract, TProvidedHeaders, TData>];
|
|
34
|
+
type PartialKeyValue<T> = T extends readonly unknown[] | {
|
|
35
|
+
toJSON: (...args: never[]) => unknown;
|
|
36
|
+
} ? T : T extends object ? Partial<T> : T;
|
|
31
37
|
export type ContractQueryKeyParams<TContract extends HttpContractConfig, TProvidedHeaders extends string = never> = {
|
|
32
|
-
path?: EndpointArgValue<EndpointQueryArgs<TContract, TProvidedHeaders>, "path"
|
|
33
|
-
query?: EndpointArgValue<EndpointQueryArgs<TContract, TProvidedHeaders>, "query"
|
|
34
|
-
body?: EndpointArgValue<EndpointQueryArgs<TContract, TProvidedHeaders>, "body"
|
|
35
|
-
headers?: EndpointArgValue<EndpointQueryArgs<TContract, TProvidedHeaders>, "headers"
|
|
38
|
+
path?: PartialKeyValue<EndpointArgValue<EndpointQueryArgs<TContract, TProvidedHeaders>, "path">>;
|
|
39
|
+
query?: PartialKeyValue<EndpointArgValue<EndpointQueryArgs<TContract, TProvidedHeaders>, "query">>;
|
|
40
|
+
body?: PartialKeyValue<EndpointArgValue<EndpointQueryArgs<TContract, TProvidedHeaders>, "body">>;
|
|
41
|
+
headers?: PartialKeyValue<EndpointArgValue<EndpointQueryArgs<TContract, TProvidedHeaders>, "headers">>;
|
|
36
42
|
};
|
|
37
43
|
/**
|
|
38
44
|
* Options accepted by `ReactQueryContractHelper.mutationOptions(...)`.
|
|
@@ -40,7 +46,13 @@ export type ContractQueryKeyParams<TContract extends HttpContractConfig, TProvid
|
|
|
40
46
|
* TanStack `mutationFn` is generated from the contract endpoint, so callers pass
|
|
41
47
|
* the normal TanStack mutation lifecycle options.
|
|
42
48
|
*/
|
|
43
|
-
export type ContractUseMutationOptions<TContract extends HttpContractConfig, TProvidedHeaders extends string = never> = Omit<UseMutationOptions<InferSuccessResponse<TContract>, InferEndpointContractError<TContract>, EndpointCallArgs<TContract, TProvidedHeaders>, unknown>, "mutationFn"
|
|
49
|
+
export type ContractUseMutationOptions<TContract extends HttpContractConfig, TProvidedHeaders extends string = never> = Omit<UseMutationOptions<InferSuccessResponse<TContract>, InferEndpointContractError<TContract>, EndpointCallArgs<TContract, TProvidedHeaders>, unknown>, "mutationFn"> & {
|
|
50
|
+
/**
|
|
51
|
+
* Queries to invalidate after a successful mutation and its onSuccess callback.
|
|
52
|
+
* Uses the executing mutation's QueryClient and awaits all invalidations.
|
|
53
|
+
*/
|
|
54
|
+
invalidates?: (data: InferSuccessResponse<TContract>, variables: EndpointCallArgs<TContract, TProvidedHeaders>) => readonly InvalidateQueryFilters<QueryKey>[] | Promise<readonly InvalidateQueryFilters<QueryKey>[]>;
|
|
55
|
+
};
|
|
44
56
|
/**
|
|
45
57
|
* Body input for infinite queries.
|
|
46
58
|
*
|
|
@@ -224,6 +236,16 @@ export declare class ReactQueryContractHelper<TContract extends HttpContractConf
|
|
|
224
236
|
* path/query/body params to target a single call or parameter prefix.
|
|
225
237
|
*/
|
|
226
238
|
invalidate(queryClient: QueryClient, params?: ContractQueryKeyParams<TContract, TProvidedHeaders>, options?: ContractQueryFilterOptions): Promise<void>;
|
|
239
|
+
/**
|
|
240
|
+
* Inspect matching standard queries using this contract's generated keys.
|
|
241
|
+
* Skips infinite queries and custom keys.
|
|
242
|
+
*/
|
|
243
|
+
cacheEntries(queryClient: QueryClient, match?: ContractQueryKeyParams<TContract, TProvidedHeaders>): ContractCacheEntry<TContract>[];
|
|
244
|
+
/**
|
|
245
|
+
* Update matching existing standard queries. Does not create entries or
|
|
246
|
+
* coordinate optimistic writes; updaters must return immutable data.
|
|
247
|
+
*/
|
|
248
|
+
updateCachedQueries(queryClient: QueryClient, options: UpdateCachedQueriesOptions<TContract, TProvidedHeaders>): void;
|
|
227
249
|
/**
|
|
228
250
|
* Create query options for TanStack Query.
|
|
229
251
|
*
|
|
@@ -261,6 +283,9 @@ export declare class ReactQueryContractHelper<TContract extends HttpContractConf
|
|
|
261
283
|
* The observed data defaults to `InfiniteData` of the contract response, so
|
|
262
284
|
* `useInfiniteQuery(...).data.pages` is typed per page. Pass `select` to
|
|
263
285
|
* narrow the observed data type.
|
|
286
|
+
*
|
|
287
|
+
* Generated keys append "infinite" to the standard key. Use the returned
|
|
288
|
+
* queryKey for direct cache access; parameter-prefix filters match both.
|
|
264
289
|
*/
|
|
265
290
|
infiniteQueryOptions<TPageParam = unknown, TData = InfiniteData<InferSuccessResponse<TContract>, TPageParam>>(args: ContractInfiniteQueryOptions<TContract, TPageParam, TProvidedHeaders, TData>): ContractInfiniteQueryOptionsResult<TContract, TPageParam, TData>;
|
|
266
291
|
/**
|
|
@@ -319,5 +344,4 @@ export declare function cursorPagination(): {
|
|
|
319
344
|
* persisted caches never store credentials.
|
|
320
345
|
*/
|
|
321
346
|
export declare function createReactQuery<TProvidedHeaders extends string = never>(client: Client<TProvidedHeaders>, options?: CreateReactQueryOptions): <TContractLike extends ContractLike>(contract: TContractLike) => ReactQueryContractHelper<ResolveContract<TContractLike>, TProvidedHeaders>;
|
|
322
|
-
export {};
|
|
323
347
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,QAAQ,EACR,gBAAgB,EAChB,SAAS,EACT,0BAA0B,EAC1B,eAAe,EACf,UAAU,EACV,oBAAoB,EACrB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
export { createBroadcastQuerySubscription, } from "./broadcasting.js";
|
|
1
2
|
import { resolveContract, } from "@beignet/core/contracts";
|
|
3
|
+
import { readCacheParams, } from "./cache.js";
|
|
2
4
|
function mergeParamObjects(base, patch) {
|
|
3
5
|
if (base == null)
|
|
4
6
|
return patch;
|
|
@@ -37,6 +39,11 @@ function normalizeBodyKeyValue(value) {
|
|
|
37
39
|
}
|
|
38
40
|
const BEIGNET_QUERY_KEY_SCOPE = "beignet";
|
|
39
41
|
const UNNAMESPACED_QUERY_KEY_NAMESPACE = null;
|
|
42
|
+
function assertCustomQueryKey(key) {
|
|
43
|
+
if (key?.[0] === BEIGNET_QUERY_KEY_SCOPE) {
|
|
44
|
+
throw new Error('Custom query keys must not use the reserved "beignet" prefix. Omit key to use the contract-generated key.');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
40
47
|
/**
|
|
41
48
|
* Generated idempotency keys keyed by mutation variables object identity.
|
|
42
49
|
*
|
|
@@ -46,6 +53,9 @@ const UNNAMESPACED_QUERY_KEY_NAMESPACE = null;
|
|
|
46
53
|
* object or an explicit `idempotencyKey` for a distinct logical command.
|
|
47
54
|
*/
|
|
48
55
|
const idempotencyKeyForVariables = new WeakMap();
|
|
56
|
+
// The invocation context survives retries and option updates during React
|
|
57
|
+
// renders, and stays distinct even when concurrent mutations reuse variables.
|
|
58
|
+
const successDefaults = new WeakMap();
|
|
49
59
|
/**
|
|
50
60
|
* Generate an idempotency key that works in non-secure browser contexts.
|
|
51
61
|
* `crypto.randomUUID` is undefined on plain `http://` hosts other than
|
|
@@ -228,6 +238,49 @@ export class ReactQueryContractHelper {
|
|
|
228
238
|
invalidate(queryClient, params, options) {
|
|
229
239
|
return queryClient.invalidateQueries(this.filter(params, options));
|
|
230
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* Inspect matching standard queries using this contract's generated keys.
|
|
243
|
+
* Skips infinite queries and custom keys.
|
|
244
|
+
*/
|
|
245
|
+
cacheEntries(queryClient, match) {
|
|
246
|
+
return queryClient
|
|
247
|
+
.getQueryCache()
|
|
248
|
+
.findAll(this.filter(match))
|
|
249
|
+
.flatMap((query) => {
|
|
250
|
+
const params = readCacheParams(query, this.contractKey());
|
|
251
|
+
return params === undefined
|
|
252
|
+
? []
|
|
253
|
+
: [
|
|
254
|
+
{
|
|
255
|
+
queryKey: query.queryKey,
|
|
256
|
+
params,
|
|
257
|
+
data: query.state.data,
|
|
258
|
+
},
|
|
259
|
+
];
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Update matching existing standard queries. Does not create entries or
|
|
264
|
+
* coordinate optimistic writes; updaters must return immutable data.
|
|
265
|
+
*/
|
|
266
|
+
updateCachedQueries(queryClient, options) {
|
|
267
|
+
const cache = queryClient.getQueryCache();
|
|
268
|
+
for (const query of cache.findAll(this.filter(options.match))) {
|
|
269
|
+
if (cache.get(query.queryHash) !== query)
|
|
270
|
+
continue;
|
|
271
|
+
const params = readCacheParams(query, this.contractKey());
|
|
272
|
+
if (params === undefined)
|
|
273
|
+
continue;
|
|
274
|
+
const data = options.update({
|
|
275
|
+
queryKey: query.queryKey,
|
|
276
|
+
params,
|
|
277
|
+
data: query.state.data,
|
|
278
|
+
});
|
|
279
|
+
if (data !== undefined && cache.get(query.queryHash) === query) {
|
|
280
|
+
query.setData(data, { manual: true });
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
231
284
|
/**
|
|
232
285
|
* Create query options for TanStack Query.
|
|
233
286
|
*
|
|
@@ -240,6 +293,7 @@ export class ReactQueryContractHelper {
|
|
|
240
293
|
queryOptions(...callArgs) {
|
|
241
294
|
const args = (callArgs[0] ?? {});
|
|
242
295
|
const { path, query, body, headers, key: customKey, ...rest } = args;
|
|
296
|
+
assertCustomQueryKey(customKey);
|
|
243
297
|
const queryKey = (customKey ||
|
|
244
298
|
this.key({ path, query, body, headers }));
|
|
245
299
|
const queryFn = async (context) => {
|
|
@@ -273,7 +327,11 @@ export class ReactQueryContractHelper {
|
|
|
273
327
|
*/
|
|
274
328
|
mutationOptions(args = {}) {
|
|
275
329
|
const hasIdempotencyMetadata = Boolean(this.contract.metadata?.idempotency);
|
|
276
|
-
const mutationFn = async (vars) => {
|
|
330
|
+
const mutationFn = async (vars, context) => {
|
|
331
|
+
if (context && !successDefaults.has(context)) {
|
|
332
|
+
const { onSuccess } = context.client.defaultMutationOptions({ mutationKey: context.mutationKey });
|
|
333
|
+
successDefaults.set(context, onSuccess);
|
|
334
|
+
}
|
|
277
335
|
let idempotencyKey = vars?.idempotencyKey;
|
|
278
336
|
if (!idempotencyKey &&
|
|
279
337
|
hasIdempotencyMetadata &&
|
|
@@ -291,10 +349,43 @@ export class ReactQueryContractHelper {
|
|
|
291
349
|
idempotencyKey,
|
|
292
350
|
});
|
|
293
351
|
};
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
mutationFn
|
|
352
|
+
const { invalidates, ...rest } = args;
|
|
353
|
+
if (!invalidates)
|
|
354
|
+
return { ...rest, mutationFn };
|
|
355
|
+
// Composed defaults can point back to an earlier wrapper. Each wrapper
|
|
356
|
+
// handles an invocation once, even when reached through that cycle.
|
|
357
|
+
const handledInvocations = new WeakSet();
|
|
358
|
+
const onSuccess = async (data, variables, onMutateResult, context) => {
|
|
359
|
+
if (handledInvocations.has(context))
|
|
360
|
+
return;
|
|
361
|
+
handledInvocations.add(context);
|
|
362
|
+
const errors = [];
|
|
363
|
+
try {
|
|
364
|
+
const callback = Object.hasOwn(rest, "onSuccess")
|
|
365
|
+
? rest.onSuccess
|
|
366
|
+
: successDefaults.get(context);
|
|
367
|
+
await callback?.(data, variables, onMutateResult, context);
|
|
368
|
+
}
|
|
369
|
+
catch (error) {
|
|
370
|
+
errors.push(error);
|
|
371
|
+
}
|
|
372
|
+
try {
|
|
373
|
+
const filters = await invalidates(data, variables);
|
|
374
|
+
const results = await Promise.allSettled(filters.map((filter) => Promise.resolve().then(() => context.client.invalidateQueries(filter))));
|
|
375
|
+
for (const result of results) {
|
|
376
|
+
if (result.status === "rejected")
|
|
377
|
+
errors.push(result.reason);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
catch (error) {
|
|
381
|
+
errors.push(error);
|
|
382
|
+
}
|
|
383
|
+
if (errors.length === 1)
|
|
384
|
+
throw errors[0];
|
|
385
|
+
if (errors.length > 1)
|
|
386
|
+
throw new AggregateError(errors, `Post-success handling failed for ${this.name}.`);
|
|
297
387
|
};
|
|
388
|
+
return { ...rest, mutationFn, onSuccess };
|
|
298
389
|
}
|
|
299
390
|
/**
|
|
300
391
|
* Create infinite query options for TanStack Query.
|
|
@@ -308,8 +399,12 @@ export class ReactQueryContractHelper {
|
|
|
308
399
|
* The observed data defaults to `InfiniteData` of the contract response, so
|
|
309
400
|
* `useInfiniteQuery(...).data.pages` is typed per page. Pass `select` to
|
|
310
401
|
* narrow the observed data type.
|
|
402
|
+
*
|
|
403
|
+
* Generated keys append "infinite" to the standard key. Use the returned
|
|
404
|
+
* queryKey for direct cache access; parameter-prefix filters match both.
|
|
311
405
|
*/
|
|
312
406
|
infiniteQueryOptions(args) {
|
|
407
|
+
assertCustomQueryKey(args.key);
|
|
313
408
|
let queryKey;
|
|
314
409
|
let rest;
|
|
315
410
|
let resolveParams;
|
|
@@ -324,7 +419,10 @@ export class ReactQueryContractHelper {
|
|
|
324
419
|
}
|
|
325
420
|
else {
|
|
326
421
|
const { path, query, body, headers, page, key, ...other } = args;
|
|
327
|
-
queryKey =
|
|
422
|
+
queryKey = key || [
|
|
423
|
+
...this.key({ path, query, body, headers }),
|
|
424
|
+
"infinite",
|
|
425
|
+
];
|
|
328
426
|
rest = other;
|
|
329
427
|
resolveParams = (context) => {
|
|
330
428
|
const pageParams = page?.(context);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beignet/react-query",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.54",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "TanStack Query integration for Beignet",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -57,12 +57,12 @@
|
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"@beignet/core": ">=0.0.3 <1.0.0",
|
|
60
|
-
"@tanstack/react-query": "^5.
|
|
60
|
+
"@tanstack/react-query": "^5.102.0",
|
|
61
61
|
"react": "^18.0.0 || ^19.0.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@beignet/core": "*",
|
|
65
|
-
"@tanstack/react-query": "^5.
|
|
65
|
+
"@tanstack/react-query": "^5.102.0",
|
|
66
66
|
"@testing-library/dom": "^9.3.4",
|
|
67
67
|
"@testing-library/react": "^14.3.1",
|
|
68
68
|
"@types/bun": "^1.4.0",
|
package/skills/client/SKILL.md
CHANGED
|
@@ -118,9 +118,34 @@ Call server behavior through Beignet contracts and typed clients.
|
|
|
118
118
|
filters.
|
|
119
119
|
- Generated keys omit nullish path, query, and opted-in header entries, but
|
|
120
120
|
preserve JSON body `null` values and empty objects. Reuse generated keys so
|
|
121
|
-
distinct request bodies do not share cache entries.
|
|
121
|
+
distinct request bodies do not share cache entries. Infinite-query keys
|
|
122
|
+
append an `"infinite"` segment; use `infiniteQueryOptions(...).queryKey` for
|
|
123
|
+
direct infinite-cache reads, writes, and exact matching. Prefix filters
|
|
124
|
+
still match both query types. Discard persisted infinite caches from the old
|
|
125
|
+
key format when upgrading.
|
|
122
126
|
- Use `rq(contract).invalidate(queryClient, params?, options?)` or the app's
|
|
123
127
|
existing key helper after successful mutations.
|
|
128
|
+
- Use `rq(contract).cacheEntries(queryClient, match?)` for typed standard-query
|
|
129
|
+
data and normalized key parameters, and `updateCachedQueries(queryClient,
|
|
130
|
+
{ match, update })` for immutable updates of existing entries. Returning
|
|
131
|
+
`undefined` skips an update. Match objects accept partial path, query, body,
|
|
132
|
+
and header fields. These helpers recognize generated keys, including entries
|
|
133
|
+
seeded with `setQueryData(helper.key(...), data)`; keep the data in the raw
|
|
134
|
+
contract response shape. Infinite queries and custom keys are excluded.
|
|
135
|
+
Custom keys must not use the reserved `"beignet"` prefix. Native query metadata
|
|
136
|
+
defaults remain intact. Keep sorting, list membership, optimistic rollback,
|
|
137
|
+
and request coordination app-owned.
|
|
138
|
+
- Use `mutationOptions({ invalidates: (data, variables) => filters })` for
|
|
139
|
+
declarative success invalidation. Filters may be selected asynchronously.
|
|
140
|
+
Beignet runs and awaits configured `onSuccess`, then all invalidations on
|
|
141
|
+
the executing QueryClient, including when `onSuccess` throws. Success defaults
|
|
142
|
+
are captured when the generated mutation function first starts and remain
|
|
143
|
+
stable across retries and changes to defaults during the request. It does not
|
|
144
|
+
retry a successful write when post-success handling fails. Pass callbacks
|
|
145
|
+
inside `mutationOptions`; replacing the returned `onSuccess` bypasses this
|
|
146
|
+
handling. Composed options can be registered with `setMutationDefaults`;
|
|
147
|
+
each retained success wrapper invalidates once per mutation invocation.
|
|
148
|
+
The integration requires TanStack React Query 5.102+ in v5.
|
|
124
149
|
- If the app configures `createReactQuery(apiClient, { keyHeaders })`, preserve
|
|
125
150
|
that when adding helpers so tenant or header-scoped caches stay distinct.
|
|
126
151
|
- Contracts with idempotency metadata get one generated idempotency key per
|
|
@@ -146,3 +171,24 @@ beignet lint
|
|
|
146
171
|
beignet doctor --strict
|
|
147
172
|
bun run typecheck
|
|
148
173
|
```
|
|
174
|
+
|
|
175
|
+
## Broadcast invalidation
|
|
176
|
+
|
|
177
|
+
Create one `createBroadcastClient` from `@beignet/core/broadcasting/client` in
|
|
178
|
+
browser lifecycle code and share it across features. Close and recreate it when
|
|
179
|
+
authenticated user/workspace changes. Import channel definitions from feature
|
|
180
|
+
`channels.ts`; never import `broadcasts.ts` or the broadcasting server subpath.
|
|
181
|
+
|
|
182
|
+
Use `createBroadcastQuerySubscription` with `client`, `channel`, `params`,
|
|
183
|
+
`queryClient`, `invalidates(event)`, and `reconciles`. Build filters through
|
|
184
|
+
`rq(contract).filter(...)`, `.contractFilter()`, or `.namespaceFilter()`.
|
|
185
|
+
`reconciles` covers all state in the channel because initial connection and
|
|
186
|
+
reconnection can miss events. Hints coalesce and schedule a follow-up refetch if
|
|
187
|
+
a fetch was already running. Inactive queries stay stale even when an earlier
|
|
188
|
+
fetch completes after a hint; disabled/static query behavior remains
|
|
189
|
+
TanStack-owned. Unsubscribe in effect cleanup.
|
|
190
|
+
|
|
191
|
+
Preserve optimistic mutation state while a mutation is pending and reconcile
|
|
192
|
+
versions after settlement. Broadcasting does not patch caches or resolve edit
|
|
193
|
+
conflicts. Merge `getRequestHeaders()` into the typed client's dynamic headers
|
|
194
|
+
only when the app opts into authenticated initiating-client exclusion.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ChannelDefinition,
|
|
3
|
+
InferChannelEvent,
|
|
4
|
+
InferChannelParams,
|
|
5
|
+
} from "@beignet/core/broadcasting";
|
|
6
|
+
import type {
|
|
7
|
+
BroadcastClient,
|
|
8
|
+
BroadcastClientStatus,
|
|
9
|
+
BroadcastClientSubscription,
|
|
10
|
+
} from "@beignet/core/broadcasting/client";
|
|
11
|
+
import type { Query, QueryClient, QueryFilters } from "@tanstack/react-query";
|
|
12
|
+
|
|
13
|
+
export interface BroadcastQuerySubscriptionOptions<
|
|
14
|
+
C extends ChannelDefinition,
|
|
15
|
+
> {
|
|
16
|
+
client: BroadcastClient;
|
|
17
|
+
channel: C;
|
|
18
|
+
params: InferChannelParams<C>;
|
|
19
|
+
queryClient: QueryClient;
|
|
20
|
+
invalidates: (event: InferChannelEvent<C>) => readonly QueryFilters[];
|
|
21
|
+
/** All state covered by the channel, including unread counters and filtered lists. */
|
|
22
|
+
reconciles: readonly QueryFilters[];
|
|
23
|
+
onError?: (error: unknown) => void;
|
|
24
|
+
onStatusChange?: (status: BroadcastClientStatus) => void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Invalidate hints and refetch after readiness. An event during a fetch schedules one later fetch. */
|
|
28
|
+
export function createBroadcastQuerySubscription<C extends ChannelDefinition>(
|
|
29
|
+
options: BroadcastQuerySubscriptionOptions<C>,
|
|
30
|
+
): BroadcastClientSubscription {
|
|
31
|
+
const cache = options.queryClient.getQueryCache();
|
|
32
|
+
const pending = new Set<Query>();
|
|
33
|
+
let closed = false;
|
|
34
|
+
let queued = false;
|
|
35
|
+
function flush() {
|
|
36
|
+
if (queued || closed) return;
|
|
37
|
+
queued = true;
|
|
38
|
+
queueMicrotask(() => {
|
|
39
|
+
queued = false;
|
|
40
|
+
if (closed) return;
|
|
41
|
+
for (const query of pending) {
|
|
42
|
+
if (query.state.fetchStatus !== "idle") continue;
|
|
43
|
+
pending.delete(query);
|
|
44
|
+
// A completed fetch clears invalidation, even when it began before the hint.
|
|
45
|
+
query.invalidate();
|
|
46
|
+
// Inactive queries remain stale. TanStack owns enabled/static and observer behavior.
|
|
47
|
+
void options.queryClient
|
|
48
|
+
.refetchQueries(
|
|
49
|
+
{ queryKey: query.queryKey, exact: true, type: "active" },
|
|
50
|
+
{ cancelRefetch: false, throwOnError: true },
|
|
51
|
+
)
|
|
52
|
+
.catch((error) => {
|
|
53
|
+
if (!closed) {
|
|
54
|
+
try {
|
|
55
|
+
options.onError?.(error);
|
|
56
|
+
} catch {
|
|
57
|
+
/* Reporting cannot disrupt query observers. */
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
const unsubscribeCache = cache.subscribe((event) => {
|
|
65
|
+
if (event.type === "removed") pending.delete(event.query);
|
|
66
|
+
if (
|
|
67
|
+
event.type === "updated" &&
|
|
68
|
+
event.query.state.fetchStatus === "idle" &&
|
|
69
|
+
pending.has(event.query)
|
|
70
|
+
)
|
|
71
|
+
flush();
|
|
72
|
+
});
|
|
73
|
+
function invalidate(filters: readonly QueryFilters[]) {
|
|
74
|
+
if (closed) return;
|
|
75
|
+
for (const filter of filters)
|
|
76
|
+
for (const query of cache.findAll(filter)) {
|
|
77
|
+
pending.add(query);
|
|
78
|
+
query.invalidate();
|
|
79
|
+
}
|
|
80
|
+
flush();
|
|
81
|
+
}
|
|
82
|
+
let subscription: BroadcastClientSubscription;
|
|
83
|
+
try {
|
|
84
|
+
subscription = options.client.subscribe(options.channel, {
|
|
85
|
+
params: options.params,
|
|
86
|
+
onEvent: (event) => invalidate(options.invalidates(event)),
|
|
87
|
+
onSync: () => invalidate(options.reconciles),
|
|
88
|
+
onError: options.onError,
|
|
89
|
+
onStatusChange: options.onStatusChange,
|
|
90
|
+
});
|
|
91
|
+
} catch (error) {
|
|
92
|
+
closed = true;
|
|
93
|
+
unsubscribeCache();
|
|
94
|
+
pending.clear();
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
getStatus: subscription.getStatus,
|
|
99
|
+
unsubscribe() {
|
|
100
|
+
if (closed) return;
|
|
101
|
+
closed = true;
|
|
102
|
+
subscription.unsubscribe();
|
|
103
|
+
unsubscribeCache();
|
|
104
|
+
pending.clear();
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
package/src/cache.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
InferBody,
|
|
3
|
+
InferPathParams,
|
|
4
|
+
InferQuery,
|
|
5
|
+
InferSuccessResponse,
|
|
6
|
+
} from "@beignet/core/client";
|
|
7
|
+
import type { HttpContractConfig } from "@beignet/core/contracts";
|
|
8
|
+
import { hashKey, type Query, type QueryKey } from "@tanstack/react-query";
|
|
9
|
+
import type { ContractQueryKeyParams } from "./index.js";
|
|
10
|
+
|
|
11
|
+
type JsonCacheValue<T> = T extends { toJSON: (...args: never[]) => infer Value }
|
|
12
|
+
? JsonCacheValue<Value>
|
|
13
|
+
: T extends ((...args: never[]) => unknown) | symbol | bigint
|
|
14
|
+
? unknown
|
|
15
|
+
: T extends readonly unknown[]
|
|
16
|
+
? {
|
|
17
|
+
[K in keyof T]:
|
|
18
|
+
| JsonCacheValue<T[K]>
|
|
19
|
+
| (undefined extends T[K] ? null : never);
|
|
20
|
+
}
|
|
21
|
+
: T extends object
|
|
22
|
+
? {
|
|
23
|
+
[K in keyof T as K extends string ? K : never]: JsonCacheValue<
|
|
24
|
+
T[K]
|
|
25
|
+
>;
|
|
26
|
+
}
|
|
27
|
+
: T;
|
|
28
|
+
|
|
29
|
+
/** Normalized cache identity, not a complete set of arguments for a request. */
|
|
30
|
+
export type ContractCacheParams<TContract extends HttpContractConfig> = {
|
|
31
|
+
readonly path?: JsonCacheValue<
|
|
32
|
+
Partial<NonNullable<InferPathParams<TContract>>>
|
|
33
|
+
>;
|
|
34
|
+
readonly query?: JsonCacheValue<Partial<NonNullable<InferQuery<TContract>>>>;
|
|
35
|
+
readonly body?: JsonCacheValue<InferBody<TContract>>;
|
|
36
|
+
/** Only explicitly keyed headers, with lowercase names. */
|
|
37
|
+
readonly headers?: Readonly<Record<string, unknown>>;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/** One standard query using Beignet's generated contract key. */
|
|
41
|
+
export type ContractCacheEntry<TContract extends HttpContractConfig> = {
|
|
42
|
+
readonly queryKey: QueryKey;
|
|
43
|
+
readonly params: ContractCacheParams<TContract>;
|
|
44
|
+
/** The raw contract response, before any observer-level select. */
|
|
45
|
+
readonly data: InferSuccessResponse<TContract> | undefined;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/** Update existing entries immutably. Returning undefined leaves an entry alone. */
|
|
49
|
+
export type UpdateCachedQueriesOptions<
|
|
50
|
+
TContract extends HttpContractConfig,
|
|
51
|
+
TProvidedHeaders extends string = never,
|
|
52
|
+
> = {
|
|
53
|
+
match?: ContractQueryKeyParams<TContract, TProvidedHeaders>;
|
|
54
|
+
update(
|
|
55
|
+
entry: ContractCacheEntry<TContract>,
|
|
56
|
+
): InferSuccessResponse<TContract> | undefined;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
60
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function readCacheParams<TContract extends HttpContractConfig>(
|
|
64
|
+
query: Query,
|
|
65
|
+
contractKey: QueryKey,
|
|
66
|
+
): ContractCacheParams<TContract> | undefined {
|
|
67
|
+
const { queryKey } = query;
|
|
68
|
+
// Generated infinite keys have an extra suffix, even before TanStack has
|
|
69
|
+
// registered their options (for example, when seeded with setQueryData).
|
|
70
|
+
if (
|
|
71
|
+
query.queryType === "infinite" ||
|
|
72
|
+
"initialPageParam" in query.options ||
|
|
73
|
+
(queryKey.length !== 4 && queryKey.length !== 5) ||
|
|
74
|
+
hashKey(queryKey.slice(0, 4)) !== hashKey(contractKey)
|
|
75
|
+
)
|
|
76
|
+
return undefined;
|
|
77
|
+
|
|
78
|
+
const params = queryKey[4] ?? {};
|
|
79
|
+
if (
|
|
80
|
+
!isRecord(params) ||
|
|
81
|
+
Object.keys(params).some(
|
|
82
|
+
(key) => !["path", "query", "body", "headers"].includes(key),
|
|
83
|
+
)
|
|
84
|
+
)
|
|
85
|
+
return undefined;
|
|
86
|
+
|
|
87
|
+
// Return the same JSON representation before and after hydration, and do
|
|
88
|
+
// not hand callers a mutable reference to parameters inside the cache key.
|
|
89
|
+
try {
|
|
90
|
+
return JSON.parse(JSON.stringify(params)) as ContractCacheParams<TContract>;
|
|
91
|
+
} catch {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,12 @@ import type {
|
|
|
8
8
|
InferQuery,
|
|
9
9
|
InferSuccessResponse,
|
|
10
10
|
} from "@beignet/core/client";
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
type BroadcastQuerySubscriptionOptions,
|
|
14
|
+
createBroadcastQuerySubscription,
|
|
15
|
+
} from "./broadcasting.js";
|
|
16
|
+
|
|
11
17
|
import {
|
|
12
18
|
type ContractLike,
|
|
13
19
|
type HttpContractConfig,
|
|
@@ -18,6 +24,7 @@ import {
|
|
|
18
24
|
import type {
|
|
19
25
|
InfiniteData,
|
|
20
26
|
InvalidateQueryFilters,
|
|
27
|
+
MutationFunctionContext,
|
|
21
28
|
QueryClient,
|
|
22
29
|
QueryFunction,
|
|
23
30
|
QueryKey,
|
|
@@ -25,6 +32,17 @@ import type {
|
|
|
25
32
|
UseMutationOptions,
|
|
26
33
|
UseQueryOptions,
|
|
27
34
|
} from "@tanstack/react-query";
|
|
35
|
+
import {
|
|
36
|
+
type ContractCacheEntry,
|
|
37
|
+
readCacheParams,
|
|
38
|
+
type UpdateCachedQueriesOptions,
|
|
39
|
+
} from "./cache.js";
|
|
40
|
+
|
|
41
|
+
export type {
|
|
42
|
+
ContractCacheEntry,
|
|
43
|
+
ContractCacheParams,
|
|
44
|
+
UpdateCachedQueriesOptions,
|
|
45
|
+
} from "./cache.js";
|
|
28
46
|
|
|
29
47
|
type EndpointQueryArgs<
|
|
30
48
|
TContract extends HttpContractConfig,
|
|
@@ -112,25 +130,29 @@ type ContractQueryOptionsCallArgs<
|
|
|
112
130
|
? [args: ContractUseQueryOptions<TContract, TProvidedHeaders, TData>]
|
|
113
131
|
: [args?: ContractUseQueryOptions<TContract, TProvidedHeaders, TData>];
|
|
114
132
|
|
|
133
|
+
type PartialKeyValue<T> = T extends
|
|
134
|
+
| readonly unknown[]
|
|
135
|
+
| { toJSON: (...args: never[]) => unknown }
|
|
136
|
+
? T
|
|
137
|
+
: T extends object
|
|
138
|
+
? Partial<T>
|
|
139
|
+
: T;
|
|
140
|
+
|
|
115
141
|
export type ContractQueryKeyParams<
|
|
116
142
|
TContract extends HttpContractConfig,
|
|
117
143
|
TProvidedHeaders extends string = never,
|
|
118
144
|
> = {
|
|
119
|
-
path?:
|
|
120
|
-
EndpointQueryArgs<TContract, TProvidedHeaders>,
|
|
121
|
-
"path"
|
|
145
|
+
path?: PartialKeyValue<
|
|
146
|
+
EndpointArgValue<EndpointQueryArgs<TContract, TProvidedHeaders>, "path">
|
|
122
147
|
>;
|
|
123
|
-
query?:
|
|
124
|
-
EndpointQueryArgs<TContract, TProvidedHeaders>,
|
|
125
|
-
"query"
|
|
148
|
+
query?: PartialKeyValue<
|
|
149
|
+
EndpointArgValue<EndpointQueryArgs<TContract, TProvidedHeaders>, "query">
|
|
126
150
|
>;
|
|
127
|
-
body?:
|
|
128
|
-
EndpointQueryArgs<TContract, TProvidedHeaders>,
|
|
129
|
-
"body"
|
|
151
|
+
body?: PartialKeyValue<
|
|
152
|
+
EndpointArgValue<EndpointQueryArgs<TContract, TProvidedHeaders>, "body">
|
|
130
153
|
>;
|
|
131
|
-
headers?:
|
|
132
|
-
EndpointQueryArgs<TContract, TProvidedHeaders>,
|
|
133
|
-
"headers"
|
|
154
|
+
headers?: PartialKeyValue<
|
|
155
|
+
EndpointArgValue<EndpointQueryArgs<TContract, TProvidedHeaders>, "headers">
|
|
134
156
|
>;
|
|
135
157
|
};
|
|
136
158
|
|
|
@@ -151,7 +173,18 @@ export type ContractUseMutationOptions<
|
|
|
151
173
|
unknown
|
|
152
174
|
>,
|
|
153
175
|
"mutationFn"
|
|
154
|
-
|
|
176
|
+
> & {
|
|
177
|
+
/**
|
|
178
|
+
* Queries to invalidate after a successful mutation and its onSuccess callback.
|
|
179
|
+
* Uses the executing mutation's QueryClient and awaits all invalidations.
|
|
180
|
+
*/
|
|
181
|
+
invalidates?: (
|
|
182
|
+
data: InferSuccessResponse<TContract>,
|
|
183
|
+
variables: EndpointCallArgs<TContract, TProvidedHeaders>,
|
|
184
|
+
) =>
|
|
185
|
+
| readonly InvalidateQueryFilters<QueryKey>[]
|
|
186
|
+
| Promise<readonly InvalidateQueryFilters<QueryKey>[]>;
|
|
187
|
+
};
|
|
155
188
|
|
|
156
189
|
/**
|
|
157
190
|
* Body input for infinite queries.
|
|
@@ -296,6 +329,14 @@ function normalizeBodyKeyValue(value: unknown): unknown | undefined {
|
|
|
296
329
|
const BEIGNET_QUERY_KEY_SCOPE = "beignet";
|
|
297
330
|
const UNNAMESPACED_QUERY_KEY_NAMESPACE = null;
|
|
298
331
|
|
|
332
|
+
function assertCustomQueryKey(key: QueryKey | undefined): void {
|
|
333
|
+
if (key?.[0] === BEIGNET_QUERY_KEY_SCOPE) {
|
|
334
|
+
throw new Error(
|
|
335
|
+
'Custom query keys must not use the reserved "beignet" prefix. Omit key to use the contract-generated key.',
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
299
340
|
/**
|
|
300
341
|
* Generated idempotency keys keyed by mutation variables object identity.
|
|
301
342
|
*
|
|
@@ -306,6 +347,13 @@ const UNNAMESPACED_QUERY_KEY_NAMESPACE = null;
|
|
|
306
347
|
*/
|
|
307
348
|
const idempotencyKeyForVariables = new WeakMap<object, string>();
|
|
308
349
|
|
|
350
|
+
// The invocation context survives retries and option updates during React
|
|
351
|
+
// renders, and stays distinct even when concurrent mutations reuse variables.
|
|
352
|
+
const successDefaults = new WeakMap<
|
|
353
|
+
MutationFunctionContext,
|
|
354
|
+
UseMutationOptions<unknown, unknown, unknown, unknown>["onSuccess"]
|
|
355
|
+
>();
|
|
356
|
+
|
|
309
357
|
/**
|
|
310
358
|
* Generate an idempotency key that works in non-secure browser contexts.
|
|
311
359
|
* `crypto.randomUUID` is undefined on plain `http://` hosts other than
|
|
@@ -586,6 +634,57 @@ export class ReactQueryContractHelper<
|
|
|
586
634
|
return queryClient.invalidateQueries(this.filter(params, options));
|
|
587
635
|
}
|
|
588
636
|
|
|
637
|
+
/**
|
|
638
|
+
* Inspect matching standard queries using this contract's generated keys.
|
|
639
|
+
* Skips infinite queries and custom keys.
|
|
640
|
+
*/
|
|
641
|
+
cacheEntries(
|
|
642
|
+
queryClient: QueryClient,
|
|
643
|
+
match?: ContractQueryKeyParams<TContract, TProvidedHeaders>,
|
|
644
|
+
): ContractCacheEntry<TContract>[] {
|
|
645
|
+
return queryClient
|
|
646
|
+
.getQueryCache()
|
|
647
|
+
.findAll(this.filter(match))
|
|
648
|
+
.flatMap((query) => {
|
|
649
|
+
const params = readCacheParams<TContract>(query, this.contractKey());
|
|
650
|
+
return params === undefined
|
|
651
|
+
? []
|
|
652
|
+
: [
|
|
653
|
+
{
|
|
654
|
+
queryKey: query.queryKey,
|
|
655
|
+
params,
|
|
656
|
+
data: query.state.data as
|
|
657
|
+
| InferSuccessResponse<TContract>
|
|
658
|
+
| undefined,
|
|
659
|
+
},
|
|
660
|
+
];
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* Update matching existing standard queries. Does not create entries or
|
|
666
|
+
* coordinate optimistic writes; updaters must return immutable data.
|
|
667
|
+
*/
|
|
668
|
+
updateCachedQueries(
|
|
669
|
+
queryClient: QueryClient,
|
|
670
|
+
options: UpdateCachedQueriesOptions<TContract, TProvidedHeaders>,
|
|
671
|
+
): void {
|
|
672
|
+
const cache = queryClient.getQueryCache();
|
|
673
|
+
for (const query of cache.findAll(this.filter(options.match))) {
|
|
674
|
+
if (cache.get(query.queryHash) !== query) continue;
|
|
675
|
+
const params = readCacheParams<TContract>(query, this.contractKey());
|
|
676
|
+
if (params === undefined) continue;
|
|
677
|
+
const data = options.update({
|
|
678
|
+
queryKey: query.queryKey,
|
|
679
|
+
params,
|
|
680
|
+
data: query.state.data as InferSuccessResponse<TContract> | undefined,
|
|
681
|
+
});
|
|
682
|
+
if (data !== undefined && cache.get(query.queryHash) === query) {
|
|
683
|
+
query.setData(data, { manual: true });
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
|
|
589
688
|
/**
|
|
590
689
|
* Create query options for TanStack Query.
|
|
591
690
|
*
|
|
@@ -608,6 +707,7 @@ export class ReactQueryContractHelper<
|
|
|
608
707
|
TData
|
|
609
708
|
>;
|
|
610
709
|
const { path, query, body, headers, key: customKey, ...rest } = args;
|
|
710
|
+
assertCustomQueryKey(customKey);
|
|
611
711
|
|
|
612
712
|
const queryKey = (customKey ||
|
|
613
713
|
this.key({ path, query, body, headers })) as QueryKey;
|
|
@@ -654,7 +754,14 @@ export class ReactQueryContractHelper<
|
|
|
654
754
|
const hasIdempotencyMetadata = Boolean(this.contract.metadata?.idempotency);
|
|
655
755
|
const mutationFn = async (
|
|
656
756
|
vars: EndpointCallArgs<TContract, TProvidedHeaders>,
|
|
757
|
+
context?: MutationFunctionContext,
|
|
657
758
|
) => {
|
|
759
|
+
if (context && !successDefaults.has(context)) {
|
|
760
|
+
const { onSuccess } = context.client.defaultMutationOptions<
|
|
761
|
+
UseMutationOptions<unknown, unknown, unknown, unknown>
|
|
762
|
+
>({ mutationKey: context.mutationKey });
|
|
763
|
+
successDefaults.set(context, onSuccess);
|
|
764
|
+
}
|
|
658
765
|
let idempotencyKey = vars?.idempotencyKey;
|
|
659
766
|
if (
|
|
660
767
|
!idempotencyKey &&
|
|
@@ -675,15 +782,54 @@ export class ReactQueryContractHelper<
|
|
|
675
782
|
} as EndpointCallArgs<TContract, TProvidedHeaders>);
|
|
676
783
|
};
|
|
677
784
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
InferSuccessResponse<TContract>,
|
|
683
|
-
InferEndpointContractError<TContract>,
|
|
684
|
-
EndpointCallArgs<TContract, TProvidedHeaders>,
|
|
685
|
-
unknown
|
|
785
|
+
const { invalidates, ...rest } = args;
|
|
786
|
+
if (!invalidates) return { ...rest, mutationFn };
|
|
787
|
+
type SuccessCallback = NonNullable<
|
|
788
|
+
ContractUseMutationOptions<TContract, TProvidedHeaders>["onSuccess"]
|
|
686
789
|
>;
|
|
790
|
+
// Composed defaults can point back to an earlier wrapper. Each wrapper
|
|
791
|
+
// handles an invocation once, even when reached through that cycle.
|
|
792
|
+
const handledInvocations = new WeakSet<MutationFunctionContext>();
|
|
793
|
+
const onSuccess: SuccessCallback = async (
|
|
794
|
+
data,
|
|
795
|
+
variables,
|
|
796
|
+
onMutateResult,
|
|
797
|
+
context,
|
|
798
|
+
) => {
|
|
799
|
+
if (handledInvocations.has(context)) return;
|
|
800
|
+
handledInvocations.add(context);
|
|
801
|
+
const errors: unknown[] = [];
|
|
802
|
+
try {
|
|
803
|
+
const callback = Object.hasOwn(rest, "onSuccess")
|
|
804
|
+
? rest.onSuccess
|
|
805
|
+
: successDefaults.get(context);
|
|
806
|
+
await callback?.(data, variables, onMutateResult, context);
|
|
807
|
+
} catch (error) {
|
|
808
|
+
errors.push(error);
|
|
809
|
+
}
|
|
810
|
+
try {
|
|
811
|
+
const filters = await invalidates(data, variables);
|
|
812
|
+
const results = await Promise.allSettled(
|
|
813
|
+
filters.map((filter) =>
|
|
814
|
+
Promise.resolve().then(() =>
|
|
815
|
+
context.client.invalidateQueries(filter),
|
|
816
|
+
),
|
|
817
|
+
),
|
|
818
|
+
);
|
|
819
|
+
for (const result of results) {
|
|
820
|
+
if (result.status === "rejected") errors.push(result.reason);
|
|
821
|
+
}
|
|
822
|
+
} catch (error) {
|
|
823
|
+
errors.push(error);
|
|
824
|
+
}
|
|
825
|
+
if (errors.length === 1) throw errors[0];
|
|
826
|
+
if (errors.length > 1)
|
|
827
|
+
throw new AggregateError(
|
|
828
|
+
errors,
|
|
829
|
+
`Post-success handling failed for ${this.name}.`,
|
|
830
|
+
);
|
|
831
|
+
};
|
|
832
|
+
return { ...rest, mutationFn, onSuccess };
|
|
687
833
|
}
|
|
688
834
|
|
|
689
835
|
/**
|
|
@@ -698,6 +844,9 @@ export class ReactQueryContractHelper<
|
|
|
698
844
|
* The observed data defaults to `InfiniteData` of the contract response, so
|
|
699
845
|
* `useInfiniteQuery(...).data.pages` is typed per page. Pass `select` to
|
|
700
846
|
* narrow the observed data type.
|
|
847
|
+
*
|
|
848
|
+
* Generated keys append "infinite" to the standard key. Use the returned
|
|
849
|
+
* queryKey for direct cache access; parameter-prefix filters match both.
|
|
701
850
|
*/
|
|
702
851
|
infiniteQueryOptions<
|
|
703
852
|
TPageParam = unknown,
|
|
@@ -710,6 +859,7 @@ export class ReactQueryContractHelper<
|
|
|
710
859
|
TData
|
|
711
860
|
>,
|
|
712
861
|
): ContractInfiniteQueryOptionsResult<TContract, TPageParam, TData> {
|
|
862
|
+
assertCustomQueryKey(args.key);
|
|
713
863
|
let queryKey: QueryKey;
|
|
714
864
|
let rest: Omit<
|
|
715
865
|
ContractInfiniteQueryOptions<
|
|
@@ -736,7 +886,10 @@ export class ReactQueryContractHelper<
|
|
|
736
886
|
resolveParams = params;
|
|
737
887
|
} else {
|
|
738
888
|
const { path, query, body, headers, page, key, ...other } = args;
|
|
739
|
-
queryKey =
|
|
889
|
+
queryKey = key || [
|
|
890
|
+
...this.key({ path, query, body, headers }),
|
|
891
|
+
"infinite",
|
|
892
|
+
];
|
|
740
893
|
rest = other;
|
|
741
894
|
resolveParams = (context) => {
|
|
742
895
|
const pageParams = page?.(context);
|