@questpie/tanstack-query 3.14.0 → 3.15.1
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/dist/index.d.mts +21 -2
- package/dist/index.mjs +45 -35
- package/package.json +3 -2
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DefaultError, QueryKey, UseMutationOptions, UseQueryOptions } from "@tanstack/react-query";
|
|
2
2
|
import { ApplyQuery, CollectionRelations, CollectionSelect, FindManyOptions, FindOneOptionsBase, FindResult, GetCollection, GetGlobal, GlobalRelations, GlobalSelect, QuestpieApp, QuestpieClient, RealtimeAPI, ResolveRelationsDeep, TopicConfig, With, buildCollectionTopic, buildGlobalTopic } from "questpie/client";
|
|
3
|
+
import { AnyChannelDefinition, ChannelParamsOf, ChannelPresenceOf } from "questpie/channels";
|
|
3
4
|
|
|
4
5
|
//#region src/index.d.ts
|
|
5
6
|
type QuestpieQueryErrorMap = (error: unknown) => unknown;
|
|
@@ -20,8 +21,8 @@ type QueryBuilder<TFn extends AnyAsyncFn> = HasArgs<TFn> extends false ? () => U
|
|
|
20
21
|
type RealtimeQueryConfig = {
|
|
21
22
|
/**
|
|
22
23
|
* Subscribe the query to live snapshots over the multiplexed SSE stream.
|
|
23
|
-
*
|
|
24
|
-
*
|
|
24
|
+
* The server supplies both the initial value and later full snapshots through
|
|
25
|
+
* the same stream (via `experimental_streamedQuery`).
|
|
25
26
|
*/
|
|
26
27
|
realtime?: boolean;
|
|
27
28
|
};
|
|
@@ -37,6 +38,23 @@ type MutationBuilder<TVariables, TData> = () => UseMutationOptions<TData, Defaul
|
|
|
37
38
|
type CollectionKeys<TApp extends QuestpieApp> = Extract<keyof QuestpieClient<TApp>["collections"], string>;
|
|
38
39
|
/** Extract global keys from QuestpieClient */
|
|
39
40
|
type GlobalKeys<TApp extends QuestpieApp> = Extract<keyof QuestpieClient<TApp>["globals"], string>;
|
|
41
|
+
/** Extract generated channel registry keys without client control properties. */
|
|
42
|
+
type ChannelKeys<TApp extends QuestpieApp> = Extract<keyof NonNullable<TApp["channels"]>, string>;
|
|
43
|
+
type ChannelIter<TApp extends QuestpieApp, K$1 extends ChannelKeys<TApp>> = QuestpieClient<TApp>["channels"][K$1] extends {
|
|
44
|
+
iter: infer TIter;
|
|
45
|
+
} ? TIter extends ((...args: infer _TArgs) => AsyncGenerator<unknown, void, unknown>) ? TIter : never : never;
|
|
46
|
+
type ChannelIterMessage<TIter> = TIter extends ((...args: infer _TArgs) => AsyncGenerator<infer TMessage, void, unknown>) ? TMessage : never;
|
|
47
|
+
type ChannelDefinition<TApp extends QuestpieApp, K$1 extends ChannelKeys<TApp>> = NonNullable<TApp["channels"]>[K$1] extends AnyChannelDefinition ? NonNullable<TApp["channels"]>[K$1] : never;
|
|
48
|
+
type ChannelPresenceOptionsAPI<TApp extends QuestpieApp, K$1 extends ChannelKeys<TApp>> = [ChannelPresenceOf<ChannelDefinition<TApp, K$1>>] extends [never] ? {} : keyof ChannelParamsOf<ChannelDefinition<TApp, K$1>> extends never ? {
|
|
49
|
+
presence: () => UseQueryOptions<readonly ChannelPresenceOf<ChannelDefinition<TApp, K$1>>[]>;
|
|
50
|
+
} : {
|
|
51
|
+
presence: (params: ChannelParamsOf<ChannelDefinition<TApp, K$1>>) => UseQueryOptions<readonly ChannelPresenceOf<ChannelDefinition<TApp, K$1>>[]>;
|
|
52
|
+
};
|
|
53
|
+
type ChannelSubscriptionOptionsAPI<TApp extends QuestpieApp, K$1 extends ChannelKeys<TApp>> = (keyof ChannelParamsOf<ChannelDefinition<TApp, K$1>> extends never ? {
|
|
54
|
+
subscription: () => UseQueryOptions<readonly ChannelIterMessage<ChannelIter<TApp, K$1>>[]>;
|
|
55
|
+
} : {
|
|
56
|
+
subscription: (params: ChannelParamsOf<ChannelDefinition<TApp, K$1>>) => UseQueryOptions<readonly ChannelIterMessage<ChannelIter<TApp, K$1>>[]>;
|
|
57
|
+
}) & ChannelPresenceOptionsAPI<TApp, K$1>;
|
|
40
58
|
type CollectionSelectOf<TApp extends QuestpieApp, K$1 extends CollectionKeys<TApp>> = CollectionSelect<GetCollection<TApp["collections"], K$1>>;
|
|
41
59
|
type CollectionRelationsOf<TApp extends QuestpieApp, K$1 extends CollectionKeys<TApp>> = ResolveRelationsDeep<CollectionRelations<GetCollection<TApp["collections"], K$1>>, TApp["collections"]>;
|
|
42
60
|
type GlobalSelectOf<TApp extends QuestpieApp, K$1 extends GlobalKeys<TApp>> = GlobalSelect<GetGlobal<NonNullable<TApp["globals"]>, K$1>>;
|
|
@@ -120,6 +138,7 @@ type GlobalQueryOptionsAPI<TApp extends QuestpieApp, K$1 extends GlobalKeys<TApp
|
|
|
120
138
|
type QuestpieQueryOptionsProxy<TApp extends QuestpieApp = QuestpieApp> = {
|
|
121
139
|
collections: { [K in CollectionKeys<TApp>]: CollectionQueryOptionsAPI<TApp, K> };
|
|
122
140
|
globals: { [K in GlobalKeys<TApp>]: GlobalQueryOptionsAPI<TApp, K> };
|
|
141
|
+
channels: { [K in ChannelKeys<TApp>]: ChannelSubscriptionOptionsAPI<TApp, K> };
|
|
123
142
|
routes: RoutesQueryOptionsAPI<QuestpieClient<TApp>["routes"]>;
|
|
124
143
|
custom: {
|
|
125
144
|
query: <TData>(config: {
|
package/dist/index.mjs
CHANGED
|
@@ -39,37 +39,11 @@ const wrapMutationFn = (mutationFn, errorMap) => {
|
|
|
39
39
|
};
|
|
40
40
|
};
|
|
41
41
|
async function* streamRealtimeQuery(options) {
|
|
42
|
-
const {
|
|
43
|
-
const queue = [];
|
|
44
|
-
let resolveNext = null;
|
|
45
|
-
const notify = () => {
|
|
46
|
-
resolveNext?.();
|
|
47
|
-
resolveNext = null;
|
|
48
|
-
};
|
|
49
|
-
const handleAbort = () => notify();
|
|
50
|
-
const unsubscribe = realtime.subscribe(topic, (data) => {
|
|
51
|
-
queue.push(data);
|
|
52
|
-
notify();
|
|
53
|
-
}, signal);
|
|
54
|
-
signal?.addEventListener("abort", handleAbort, { once: true });
|
|
42
|
+
const { realtime, topic, signal, errorMap } = options;
|
|
55
43
|
try {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
throw errorMap(error);
|
|
60
|
-
}
|
|
61
|
-
while (!signal?.aborted) {
|
|
62
|
-
while (queue.length > 0) yield queue.shift();
|
|
63
|
-
if (signal?.aborted) break;
|
|
64
|
-
await new Promise((resolve) => {
|
|
65
|
-
resolveNext = resolve;
|
|
66
|
-
});
|
|
67
|
-
resolveNext = null;
|
|
68
|
-
}
|
|
69
|
-
} finally {
|
|
70
|
-
signal?.removeEventListener("abort", handleAbort);
|
|
71
|
-
unsubscribe();
|
|
72
|
-
resolveNext = null;
|
|
44
|
+
for await (const snapshot of realtime.stream(topic, signal)) yield snapshot;
|
|
45
|
+
} catch (error) {
|
|
46
|
+
throw errorMap(error);
|
|
73
47
|
}
|
|
74
48
|
}
|
|
75
49
|
/**
|
|
@@ -118,7 +92,6 @@ function createQuestpieQueryOptions(client, config = {}) {
|
|
|
118
92
|
queryKey: qKey,
|
|
119
93
|
queryFn: experimental_streamedQuery({
|
|
120
94
|
streamFn: ({ signal }) => streamRealtimeQuery({
|
|
121
|
-
initialFetch: () => collection.find(options),
|
|
122
95
|
realtime: client.realtime,
|
|
123
96
|
topic,
|
|
124
97
|
signal,
|
|
@@ -144,18 +117,17 @@ function createQuestpieQueryOptions(client, config = {}) {
|
|
|
144
117
|
normalizeQueryKeyOptions(options)
|
|
145
118
|
]);
|
|
146
119
|
if (queryConfig?.realtime && client.realtime) {
|
|
147
|
-
const topic = buildCollectionTopic$1(collectionName, options);
|
|
120
|
+
const topic = buildCollectionTopic$1(collectionName, options, "count");
|
|
148
121
|
return queryOptions({
|
|
149
122
|
queryKey: qKey,
|
|
150
123
|
queryFn: experimental_streamedQuery({
|
|
151
124
|
streamFn: ({ signal }) => streamRealtimeQuery({
|
|
152
|
-
initialFetch: () => collection.count(options),
|
|
153
125
|
realtime: client.realtime,
|
|
154
126
|
topic,
|
|
155
127
|
signal,
|
|
156
128
|
errorMap
|
|
157
129
|
}),
|
|
158
|
-
reducer: (_, chunk) =>
|
|
130
|
+
reducer: (_, chunk) => chunk,
|
|
159
131
|
initialValue: void 0,
|
|
160
132
|
refetchMode: "append"
|
|
161
133
|
})
|
|
@@ -306,7 +278,6 @@ function createQuestpieQueryOptions(client, config = {}) {
|
|
|
306
278
|
queryKey: qKey,
|
|
307
279
|
queryFn: experimental_streamedQuery({
|
|
308
280
|
streamFn: ({ signal }) => streamRealtimeQuery({
|
|
309
|
-
initialFetch: () => global.get(options),
|
|
310
281
|
realtime: client.realtime,
|
|
311
282
|
topic,
|
|
312
283
|
signal,
|
|
@@ -377,6 +348,44 @@ function createQuestpieQueryOptions(client, config = {}) {
|
|
|
377
348
|
})
|
|
378
349
|
};
|
|
379
350
|
} });
|
|
351
|
+
const channels = new Proxy({}, { get: (_target, channelName) => {
|
|
352
|
+
if (typeof channelName !== "string") return void 0;
|
|
353
|
+
const channel = Reflect.get(client.channels, channelName);
|
|
354
|
+
return {
|
|
355
|
+
subscription: (...args) => {
|
|
356
|
+
return queryOptions({
|
|
357
|
+
queryKey: buildKey(keyPrefix, [
|
|
358
|
+
"channels",
|
|
359
|
+
channelName,
|
|
360
|
+
"subscription",
|
|
361
|
+
normalizeQueryKeyOptions(args)
|
|
362
|
+
]),
|
|
363
|
+
queryFn: experimental_streamedQuery({
|
|
364
|
+
streamFn: ({ signal }) => channel.iter(...args, { signal }),
|
|
365
|
+
reducer: (messages, message) => [...messages, message],
|
|
366
|
+
initialValue: [],
|
|
367
|
+
refetchMode: "reset"
|
|
368
|
+
})
|
|
369
|
+
});
|
|
370
|
+
},
|
|
371
|
+
presence: (...args) => {
|
|
372
|
+
return queryOptions({
|
|
373
|
+
queryKey: buildKey(keyPrefix, [
|
|
374
|
+
"channels",
|
|
375
|
+
channelName,
|
|
376
|
+
"presence",
|
|
377
|
+
normalizeQueryKeyOptions(args)
|
|
378
|
+
]),
|
|
379
|
+
queryFn: experimental_streamedQuery({
|
|
380
|
+
streamFn: ({ signal }) => channel.presenceIter(...args, { signal }),
|
|
381
|
+
reducer: (_roster, snapshot) => snapshot,
|
|
382
|
+
initialValue: [],
|
|
383
|
+
refetchMode: "reset"
|
|
384
|
+
})
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
} });
|
|
380
389
|
/**
|
|
381
390
|
* Resolve a nested route caller from the client by traversing dot segments.
|
|
382
391
|
*/
|
|
@@ -422,6 +431,7 @@ function createQuestpieQueryOptions(client, config = {}) {
|
|
|
422
431
|
return {
|
|
423
432
|
collections,
|
|
424
433
|
globals,
|
|
434
|
+
channels,
|
|
425
435
|
routes: new Proxy({}, { get: (_target, prop) => {
|
|
426
436
|
if (typeof prop !== "string") return void 0;
|
|
427
437
|
return createRouteNodeProxy([prop]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@questpie/tanstack-query",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.15.1",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/questpie/questpie.git",
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"bun-types": "latest",
|
|
39
|
-
"tsdown": "^0.18.3"
|
|
39
|
+
"tsdown": "^0.18.3",
|
|
40
|
+
"zod": "^4.2.1"
|
|
40
41
|
},
|
|
41
42
|
"peerDependencies": {
|
|
42
43
|
"@tanstack/react-query": "^5.0.0",
|