convex-helpers 0.1.90 → 0.1.91
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/package.json +1 -1
- package/react/cache/hooks.d.ts +57 -1
- package/react/cache/hooks.d.ts.map +1 -1
- package/react/cache/hooks.js +337 -3
- package/react/cache/hooks.ts +426 -4
- package/react/cache.d.ts +1 -1
- package/react/cache.d.ts.map +1 -1
- package/react/cache.js +1 -1
- package/react/cache.ts +1 -1
- package/server/migrations.d.ts +4 -4
- package/server/stream.d.ts.map +1 -1
- package/server/stream.js +26 -11
- package/server/stream.ts +29 -11
package/package.json
CHANGED
package/react/cache/hooks.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { OptionalRestArgsOrSkip, RequestForQueries } from "convex/react";
|
|
1
|
+
import type { OptionalRestArgsOrSkip, PaginatedQueryArgs, PaginatedQueryReference, RequestForQueries, UsePaginatedQueryReturnType } from "convex/react";
|
|
2
2
|
import type { FunctionReference, FunctionReturnType } from "convex/server";
|
|
3
3
|
/**
|
|
4
4
|
* Load a variable number of reactive Convex queries, utilizing
|
|
@@ -70,4 +70,60 @@ export declare function useQueries(queries: RequestForQueries): Record<string, a
|
|
|
70
70
|
* @public
|
|
71
71
|
*/
|
|
72
72
|
export declare function useQuery<Query extends FunctionReference<"query">>(query: Query, ...queryArgs: OptionalRestArgsOrSkip<Query>): FunctionReturnType<Query> | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* Load data reactively from a paginated query to a create a growing list.
|
|
75
|
+
*
|
|
76
|
+
* This can be used to power "infinite scroll" UIs.
|
|
77
|
+
*
|
|
78
|
+
* This hook must be used with public query references that match
|
|
79
|
+
* {@link PaginatedQueryReference}.
|
|
80
|
+
*
|
|
81
|
+
* `usePaginatedQuery` concatenates all the pages of results into a single list
|
|
82
|
+
* and manages the continuation cursors when requesting more items.
|
|
83
|
+
*
|
|
84
|
+
* Example usage:
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const { results, status, isLoading, loadMore } = usePaginatedQuery(
|
|
87
|
+
* api.messages.list,
|
|
88
|
+
* { channel: "#general" },
|
|
89
|
+
* { initialNumItems: 5 }
|
|
90
|
+
* );
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* If the query reference or arguments change, the pagination state will be reset
|
|
94
|
+
* to the first page. Similarly, if any of the pages result in an InvalidCursor
|
|
95
|
+
* error or an error associated with too much data, the pagination state will also
|
|
96
|
+
* reset to the first page.
|
|
97
|
+
*
|
|
98
|
+
* To learn more about pagination, see [Paginated Queries](https://docs.convex.dev/database/pagination).
|
|
99
|
+
*
|
|
100
|
+
* @param query - A FunctionReference to the public query function to run.
|
|
101
|
+
* @param args - The arguments object for the query function, excluding
|
|
102
|
+
* the `paginationOpts` property. That property is injected by this hook.
|
|
103
|
+
* @param options - An object specifying the `initialNumItems` to be loaded in
|
|
104
|
+
* the first page, and the `endCursorBehavior` to use.
|
|
105
|
+
* @param options.endCursorBehavior` controls how the `endCursor` is set on the
|
|
106
|
+
* last loaded page. The current behavior is to have the first request for a page
|
|
107
|
+
* "pin" the end of the page to the `endCursor` returned in the first request.
|
|
108
|
+
* This shows up as your first request growing as new items are added within
|
|
109
|
+
* the range of the initial page. This is tracked via a QueryJournal, which is
|
|
110
|
+
* not shared between clients and can have unexpected behavior, so we will be
|
|
111
|
+
* deprecating this behavior in favor of the new option `setOnLoadMore`.
|
|
112
|
+
* For `setOnLoadMore`, the `endCursor` is not inferred from the first request,
|
|
113
|
+
* instead the first call to `loadMore` will explicitly set the `endCursor` to
|
|
114
|
+
* the `continueCursor` of the last page. In the future this will not use the
|
|
115
|
+
* QueryJournal and will become the default behavior, resulting in the first
|
|
116
|
+
* page staying at the same size as `initialNumItems` until you call `loadMore`.
|
|
117
|
+
* Note: setting the `endCursor` on the request will re-request that page with
|
|
118
|
+
* the new argument, causing an effectively duplicate request per `loadMore`.
|
|
119
|
+
*
|
|
120
|
+
* @returns A {@link UsePaginatedQueryResult} that includes the currently loaded
|
|
121
|
+
* items, the status of the pagination, and a `loadMore` function.
|
|
122
|
+
*
|
|
123
|
+
* @public
|
|
124
|
+
*/
|
|
125
|
+
export declare function usePaginatedQuery<Query extends PaginatedQueryReference>(query: Query, args: PaginatedQueryArgs<Query> | "skip", options: {
|
|
126
|
+
initialNumItems: number;
|
|
127
|
+
endCursorBehavior?: "setOnLoadMore" | "legacyQueryJournal";
|
|
128
|
+
}): UsePaginatedQueryReturnType<Query>;
|
|
73
129
|
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EACjB,2BAA2B,EAC5B,MAAM,cAAc,CAAC;AAMtB,OAAO,KAAK,EAEV,iBAAiB,EACjB,kBAAkB,EAInB,MAAM,eAAe,CAAC;AAkBvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,iBAAiB,GACzB,MAAM,CAAC,MAAM,EAAE,GAAG,GAAG,SAAS,GAAG,KAAK,CAAC,CAiCzC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CAAC,KAAK,SAAS,iBAAiB,CAAC,OAAO,CAAC,EAC/D,KAAK,EAAE,KAAK,EACZ,GAAG,SAAS,EAAE,sBAAsB,CAAC,KAAK,CAAC,GAC1C,kBAAkB,CAAC,KAAK,CAAC,GAAG,SAAS,CAoBvC;AAoHD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,SAAS,uBAAuB,EACrE,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,kBAAkB,CAAC,KAAK,CAAC,GAAG,MAAM,EACxC,OAAO,EAAE;IACP,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,eAAe,GAAG,oBAAoB,CAAC;CAC5D,GACA,2BAA2B,CAAC,KAAK,CAAC,CAqPpC"}
|
package/react/cache/hooks.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ConvexProvider, useQueries as useQueriesCore } from "convex/react";
|
|
1
|
+
import { ConvexProvider, useConvex, useQueries as useQueriesCore, } from "convex/react";
|
|
2
2
|
import { getFunctionName } from "convex/server";
|
|
3
|
-
import { useContext, useEffect, useMemo } from "react";
|
|
3
|
+
import { useContext, useEffect, useMemo, useState } from "react";
|
|
4
4
|
import { ConvexQueryCacheContext } from "./provider.js";
|
|
5
|
-
import { convexToJson } from "convex/values";
|
|
5
|
+
import { ConvexError, convexToJson, } from "convex/values";
|
|
6
6
|
const uuid = typeof crypto !== "undefined" && crypto.randomUUID
|
|
7
7
|
? crypto.randomUUID.bind(crypto)
|
|
8
8
|
: () => Math.random().toString(36).substring(2) +
|
|
@@ -134,3 +134,337 @@ function createQueryKey(query, args) {
|
|
|
134
134
|
const queryKey = JSON.stringify(key);
|
|
135
135
|
return queryKey;
|
|
136
136
|
}
|
|
137
|
+
// NOTE!: We use the same ID so it's always cached, but it can mean a split is
|
|
138
|
+
// required off the bat if it's an old stale query result.
|
|
139
|
+
function nextPaginationId() {
|
|
140
|
+
return 0;
|
|
141
|
+
}
|
|
142
|
+
const splitQuery = (key, splitCursor, continueCursor) => (prevState) => {
|
|
143
|
+
const queries = { ...prevState.queries };
|
|
144
|
+
const splitKey1 = prevState.nextPageKey;
|
|
145
|
+
const splitKey2 = prevState.nextPageKey + 1;
|
|
146
|
+
const nextPageKey = prevState.nextPageKey + 2;
|
|
147
|
+
queries[splitKey1] = {
|
|
148
|
+
query: prevState.query,
|
|
149
|
+
args: {
|
|
150
|
+
...prevState.args,
|
|
151
|
+
paginationOpts: {
|
|
152
|
+
...prevState.queries[key].args.paginationOpts,
|
|
153
|
+
endCursor: splitCursor,
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
queries[splitKey2] = {
|
|
158
|
+
query: prevState.query,
|
|
159
|
+
args: {
|
|
160
|
+
...prevState.args,
|
|
161
|
+
paginationOpts: {
|
|
162
|
+
...prevState.queries[key].args.paginationOpts,
|
|
163
|
+
cursor: splitCursor,
|
|
164
|
+
endCursor: continueCursor,
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
const ongoingSplits = { ...prevState.ongoingSplits };
|
|
169
|
+
ongoingSplits[key] = [splitKey1, splitKey2];
|
|
170
|
+
return {
|
|
171
|
+
...prevState,
|
|
172
|
+
nextPageKey,
|
|
173
|
+
queries,
|
|
174
|
+
ongoingSplits,
|
|
175
|
+
};
|
|
176
|
+
};
|
|
177
|
+
const completeSplitQuery = (key) => (prevState) => {
|
|
178
|
+
const completedSplit = prevState.ongoingSplits[key];
|
|
179
|
+
if (completedSplit === undefined) {
|
|
180
|
+
return prevState;
|
|
181
|
+
}
|
|
182
|
+
const queries = { ...prevState.queries };
|
|
183
|
+
delete queries[key];
|
|
184
|
+
const ongoingSplits = { ...prevState.ongoingSplits };
|
|
185
|
+
delete ongoingSplits[key];
|
|
186
|
+
let pageKeys = prevState.pageKeys.slice();
|
|
187
|
+
const pageIndex = prevState.pageKeys.findIndex((v) => v === key);
|
|
188
|
+
if (pageIndex >= 0) {
|
|
189
|
+
pageKeys = [
|
|
190
|
+
...prevState.pageKeys.slice(0, pageIndex),
|
|
191
|
+
...completedSplit,
|
|
192
|
+
...prevState.pageKeys.slice(pageIndex + 1),
|
|
193
|
+
];
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
...prevState,
|
|
197
|
+
queries,
|
|
198
|
+
pageKeys,
|
|
199
|
+
ongoingSplits,
|
|
200
|
+
};
|
|
201
|
+
};
|
|
202
|
+
/**
|
|
203
|
+
* Load data reactively from a paginated query to a create a growing list.
|
|
204
|
+
*
|
|
205
|
+
* This can be used to power "infinite scroll" UIs.
|
|
206
|
+
*
|
|
207
|
+
* This hook must be used with public query references that match
|
|
208
|
+
* {@link PaginatedQueryReference}.
|
|
209
|
+
*
|
|
210
|
+
* `usePaginatedQuery` concatenates all the pages of results into a single list
|
|
211
|
+
* and manages the continuation cursors when requesting more items.
|
|
212
|
+
*
|
|
213
|
+
* Example usage:
|
|
214
|
+
* ```typescript
|
|
215
|
+
* const { results, status, isLoading, loadMore } = usePaginatedQuery(
|
|
216
|
+
* api.messages.list,
|
|
217
|
+
* { channel: "#general" },
|
|
218
|
+
* { initialNumItems: 5 }
|
|
219
|
+
* );
|
|
220
|
+
* ```
|
|
221
|
+
*
|
|
222
|
+
* If the query reference or arguments change, the pagination state will be reset
|
|
223
|
+
* to the first page. Similarly, if any of the pages result in an InvalidCursor
|
|
224
|
+
* error or an error associated with too much data, the pagination state will also
|
|
225
|
+
* reset to the first page.
|
|
226
|
+
*
|
|
227
|
+
* To learn more about pagination, see [Paginated Queries](https://docs.convex.dev/database/pagination).
|
|
228
|
+
*
|
|
229
|
+
* @param query - A FunctionReference to the public query function to run.
|
|
230
|
+
* @param args - The arguments object for the query function, excluding
|
|
231
|
+
* the `paginationOpts` property. That property is injected by this hook.
|
|
232
|
+
* @param options - An object specifying the `initialNumItems` to be loaded in
|
|
233
|
+
* the first page, and the `endCursorBehavior` to use.
|
|
234
|
+
* @param options.endCursorBehavior` controls how the `endCursor` is set on the
|
|
235
|
+
* last loaded page. The current behavior is to have the first request for a page
|
|
236
|
+
* "pin" the end of the page to the `endCursor` returned in the first request.
|
|
237
|
+
* This shows up as your first request growing as new items are added within
|
|
238
|
+
* the range of the initial page. This is tracked via a QueryJournal, which is
|
|
239
|
+
* not shared between clients and can have unexpected behavior, so we will be
|
|
240
|
+
* deprecating this behavior in favor of the new option `setOnLoadMore`.
|
|
241
|
+
* For `setOnLoadMore`, the `endCursor` is not inferred from the first request,
|
|
242
|
+
* instead the first call to `loadMore` will explicitly set the `endCursor` to
|
|
243
|
+
* the `continueCursor` of the last page. In the future this will not use the
|
|
244
|
+
* QueryJournal and will become the default behavior, resulting in the first
|
|
245
|
+
* page staying at the same size as `initialNumItems` until you call `loadMore`.
|
|
246
|
+
* Note: setting the `endCursor` on the request will re-request that page with
|
|
247
|
+
* the new argument, causing an effectively duplicate request per `loadMore`.
|
|
248
|
+
*
|
|
249
|
+
* @returns A {@link UsePaginatedQueryResult} that includes the currently loaded
|
|
250
|
+
* items, the status of the pagination, and a `loadMore` function.
|
|
251
|
+
*
|
|
252
|
+
* @public
|
|
253
|
+
*/
|
|
254
|
+
export function usePaginatedQuery(query, args, options) {
|
|
255
|
+
if (typeof options?.initialNumItems !== "number" ||
|
|
256
|
+
options.initialNumItems < 0) {
|
|
257
|
+
throw new Error(`\`options.initialNumItems\` must be a positive number. Received \`${options?.initialNumItems}\`.`);
|
|
258
|
+
}
|
|
259
|
+
const skip = args === "skip";
|
|
260
|
+
const argsObject = skip ? {} : args;
|
|
261
|
+
const queryName = getFunctionName(query);
|
|
262
|
+
const createInitialState = useMemo(() => {
|
|
263
|
+
return () => {
|
|
264
|
+
const id = nextPaginationId();
|
|
265
|
+
return {
|
|
266
|
+
query,
|
|
267
|
+
args: argsObject,
|
|
268
|
+
id,
|
|
269
|
+
nextPageKey: 1,
|
|
270
|
+
pageKeys: skip ? [] : [0],
|
|
271
|
+
queries: skip
|
|
272
|
+
? {}
|
|
273
|
+
: {
|
|
274
|
+
0: {
|
|
275
|
+
query,
|
|
276
|
+
args: {
|
|
277
|
+
...argsObject,
|
|
278
|
+
paginationOpts: {
|
|
279
|
+
numItems: options.initialNumItems,
|
|
280
|
+
cursor: null,
|
|
281
|
+
id,
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
ongoingSplits: {},
|
|
287
|
+
skip,
|
|
288
|
+
};
|
|
289
|
+
};
|
|
290
|
+
// ESLint doesn't like that we're stringifying the args. We do this because
|
|
291
|
+
// we want to avoid rerendering if the args are a different
|
|
292
|
+
// object that serializes to the same result.
|
|
293
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
294
|
+
}, [
|
|
295
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
296
|
+
JSON.stringify(convexToJson(argsObject)),
|
|
297
|
+
queryName,
|
|
298
|
+
options.initialNumItems,
|
|
299
|
+
skip,
|
|
300
|
+
]);
|
|
301
|
+
const [state, setState] = useState(createInitialState);
|
|
302
|
+
// `currState` is the state that we'll render based on.
|
|
303
|
+
let currState = state;
|
|
304
|
+
if (getFunctionName(query) !== getFunctionName(state.query) ||
|
|
305
|
+
JSON.stringify(convexToJson(argsObject)) !==
|
|
306
|
+
JSON.stringify(convexToJson(state.args)) ||
|
|
307
|
+
skip !== state.skip) {
|
|
308
|
+
currState = createInitialState();
|
|
309
|
+
setState(currState);
|
|
310
|
+
}
|
|
311
|
+
const convexClient = useConvex();
|
|
312
|
+
const logger = convexClient.logger;
|
|
313
|
+
const resultsObject = useQueries(currState.queries);
|
|
314
|
+
const [results, maybeLastResult] = useMemo(() => {
|
|
315
|
+
let currResult = undefined;
|
|
316
|
+
const allItems = [];
|
|
317
|
+
for (const pageKey of currState.pageKeys) {
|
|
318
|
+
currResult = resultsObject[pageKey];
|
|
319
|
+
if (currResult === undefined) {
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
if (currResult instanceof Error) {
|
|
323
|
+
if (currResult.message.includes("InvalidCursor") ||
|
|
324
|
+
(currResult instanceof ConvexError &&
|
|
325
|
+
typeof currResult.data === "object" &&
|
|
326
|
+
currResult.data?.isConvexSystemError === true &&
|
|
327
|
+
currResult.data?.paginationError === "InvalidCursor")) {
|
|
328
|
+
// - InvalidCursor: If the cursor is invalid, probably the paginated
|
|
329
|
+
// database query was data-dependent and changed underneath us. The
|
|
330
|
+
// cursor in the params or journal no longer matches the current
|
|
331
|
+
// database query.
|
|
332
|
+
// In all cases, we want to restart pagination to throw away all our
|
|
333
|
+
// existing cursors.
|
|
334
|
+
logger.warn("usePaginatedQuery hit error, resetting pagination state: " +
|
|
335
|
+
currResult.message);
|
|
336
|
+
setState(createInitialState);
|
|
337
|
+
return [[], undefined];
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
throw currResult;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
const ongoingSplit = currState.ongoingSplits[pageKey];
|
|
344
|
+
if (ongoingSplit !== undefined) {
|
|
345
|
+
if (resultsObject[ongoingSplit[0]] !== undefined &&
|
|
346
|
+
resultsObject[ongoingSplit[1]] !== undefined) {
|
|
347
|
+
// Both pages of the split have results now. Swap them in.
|
|
348
|
+
setState(completeSplitQuery(pageKey));
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
else if (currResult.splitCursor &&
|
|
352
|
+
(currResult.pageStatus === "SplitRecommended" ||
|
|
353
|
+
currResult.pageStatus === "SplitRequired" ||
|
|
354
|
+
currResult.page.length > options.initialNumItems * 2)) {
|
|
355
|
+
// If a single page has more than double the expected number of items,
|
|
356
|
+
// or if the server requests a split, split the page into two.
|
|
357
|
+
setState(splitQuery(pageKey, currResult.splitCursor, currResult.continueCursor));
|
|
358
|
+
}
|
|
359
|
+
if (currResult.pageStatus === "SplitRequired") {
|
|
360
|
+
// If pageStatus is 'SplitRequired', it means the server was not able to
|
|
361
|
+
// fetch the full page. So we stop results before the incomplete
|
|
362
|
+
// page and return 'LoadingMore' while the page is splitting.
|
|
363
|
+
return [allItems, undefined];
|
|
364
|
+
}
|
|
365
|
+
allItems.push(...currResult.page);
|
|
366
|
+
}
|
|
367
|
+
return [allItems, currResult];
|
|
368
|
+
}, [
|
|
369
|
+
resultsObject,
|
|
370
|
+
currState.pageKeys,
|
|
371
|
+
currState.ongoingSplits,
|
|
372
|
+
options.initialNumItems,
|
|
373
|
+
createInitialState,
|
|
374
|
+
logger,
|
|
375
|
+
]);
|
|
376
|
+
const statusObject = useMemo(() => {
|
|
377
|
+
if (maybeLastResult === undefined) {
|
|
378
|
+
if (currState.nextPageKey === 1) {
|
|
379
|
+
return {
|
|
380
|
+
status: "LoadingFirstPage",
|
|
381
|
+
isLoading: true,
|
|
382
|
+
loadMore: (_numItems) => {
|
|
383
|
+
// Intentional noop.
|
|
384
|
+
},
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
return {
|
|
389
|
+
status: "LoadingMore",
|
|
390
|
+
isLoading: true,
|
|
391
|
+
loadMore: (_numItems) => {
|
|
392
|
+
// Intentional noop.
|
|
393
|
+
},
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
if (maybeLastResult.isDone) {
|
|
398
|
+
return {
|
|
399
|
+
status: "Exhausted",
|
|
400
|
+
isLoading: false,
|
|
401
|
+
loadMore: (_numItems) => {
|
|
402
|
+
// Intentional noop.
|
|
403
|
+
},
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
const continueCursor = maybeLastResult.continueCursor;
|
|
407
|
+
let alreadyLoadingMore = false;
|
|
408
|
+
return {
|
|
409
|
+
status: "CanLoadMore",
|
|
410
|
+
isLoading: false,
|
|
411
|
+
loadMore: (numItems) => {
|
|
412
|
+
if (!alreadyLoadingMore) {
|
|
413
|
+
alreadyLoadingMore = true;
|
|
414
|
+
setState((prevState) => {
|
|
415
|
+
let nextPageKey = prevState.nextPageKey;
|
|
416
|
+
const queries = { ...prevState.queries };
|
|
417
|
+
let ongoingSplits = prevState.ongoingSplits;
|
|
418
|
+
let pageKeys = prevState.pageKeys;
|
|
419
|
+
if (options.endCursorBehavior === "setOnLoadMore") {
|
|
420
|
+
const lastPageKey = prevState.pageKeys.at(-1);
|
|
421
|
+
const boundLastPageKey = nextPageKey;
|
|
422
|
+
queries[boundLastPageKey] = {
|
|
423
|
+
query: prevState.query,
|
|
424
|
+
args: {
|
|
425
|
+
...prevState.args,
|
|
426
|
+
paginationOpts: {
|
|
427
|
+
...queries[lastPageKey].args
|
|
428
|
+
.paginationOpts,
|
|
429
|
+
endCursor: continueCursor,
|
|
430
|
+
},
|
|
431
|
+
},
|
|
432
|
+
};
|
|
433
|
+
nextPageKey++;
|
|
434
|
+
ongoingSplits = {
|
|
435
|
+
...ongoingSplits,
|
|
436
|
+
[lastPageKey]: [boundLastPageKey, nextPageKey],
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
pageKeys = [...prevState.pageKeys, nextPageKey];
|
|
441
|
+
}
|
|
442
|
+
queries[nextPageKey] = {
|
|
443
|
+
query: prevState.query,
|
|
444
|
+
args: {
|
|
445
|
+
...prevState.args,
|
|
446
|
+
paginationOpts: {
|
|
447
|
+
numItems,
|
|
448
|
+
cursor: continueCursor,
|
|
449
|
+
id: prevState.id,
|
|
450
|
+
},
|
|
451
|
+
},
|
|
452
|
+
};
|
|
453
|
+
nextPageKey++;
|
|
454
|
+
return {
|
|
455
|
+
...prevState,
|
|
456
|
+
pageKeys,
|
|
457
|
+
nextPageKey,
|
|
458
|
+
queries,
|
|
459
|
+
ongoingSplits,
|
|
460
|
+
};
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
},
|
|
464
|
+
};
|
|
465
|
+
}, [maybeLastResult, currState.nextPageKey, options.endCursorBehavior]);
|
|
466
|
+
return {
|
|
467
|
+
results,
|
|
468
|
+
...statusObject,
|
|
469
|
+
};
|
|
470
|
+
}
|
package/react/cache/hooks.ts
CHANGED
|
@@ -1,14 +1,32 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type {
|
|
2
|
+
OptionalRestArgsOrSkip,
|
|
3
|
+
PaginatedQueryArgs,
|
|
4
|
+
PaginatedQueryReference,
|
|
5
|
+
RequestForQueries,
|
|
6
|
+
UsePaginatedQueryReturnType,
|
|
7
|
+
} from "convex/react";
|
|
8
|
+
import {
|
|
9
|
+
ConvexProvider,
|
|
10
|
+
useConvex,
|
|
11
|
+
useQueries as useQueriesCore,
|
|
12
|
+
} from "convex/react";
|
|
3
13
|
import type {
|
|
4
14
|
FunctionArgs,
|
|
5
15
|
FunctionReference,
|
|
6
16
|
FunctionReturnType,
|
|
17
|
+
PaginationOptions,
|
|
18
|
+
paginationOptsValidator,
|
|
19
|
+
PaginationResult,
|
|
7
20
|
} from "convex/server";
|
|
8
21
|
import { getFunctionName } from "convex/server";
|
|
9
|
-
import { useContext, useEffect, useMemo } from "react";
|
|
22
|
+
import { useContext, useEffect, useMemo, useState } from "react";
|
|
10
23
|
import { ConvexQueryCacheContext } from "./provider.js";
|
|
11
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
ConvexError,
|
|
26
|
+
convexToJson,
|
|
27
|
+
type Infer,
|
|
28
|
+
type Value,
|
|
29
|
+
} from "convex/values";
|
|
12
30
|
|
|
13
31
|
const uuid =
|
|
14
32
|
typeof crypto !== "undefined" && crypto.randomUUID
|
|
@@ -162,3 +180,407 @@ function createQueryKey<Query extends FunctionReference<"query">>(
|
|
|
162
180
|
const queryKey = JSON.stringify(key);
|
|
163
181
|
return queryKey;
|
|
164
182
|
}
|
|
183
|
+
|
|
184
|
+
// NOTE!: We use the same ID so it's always cached, but it can mean a split is
|
|
185
|
+
// required off the bat if it's an old stale query result.
|
|
186
|
+
function nextPaginationId(): number {
|
|
187
|
+
return 0;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* NOTE: The below is copied verbatim from the convex package, using the cached
|
|
192
|
+
* useQueries implementation.
|
|
193
|
+
*/
|
|
194
|
+
|
|
195
|
+
// Incrementing integer for each page queried in the usePaginatedQuery hook.
|
|
196
|
+
type QueryPageKey = number;
|
|
197
|
+
|
|
198
|
+
type UsePaginatedQueryState = {
|
|
199
|
+
query: FunctionReference<"query">;
|
|
200
|
+
args: Record<string, Value>;
|
|
201
|
+
id: number;
|
|
202
|
+
nextPageKey: QueryPageKey;
|
|
203
|
+
pageKeys: QueryPageKey[];
|
|
204
|
+
queries: Record<
|
|
205
|
+
QueryPageKey,
|
|
206
|
+
{
|
|
207
|
+
query: FunctionReference<"query">;
|
|
208
|
+
// Use the validator type as a test that it matches the args
|
|
209
|
+
// we generate.
|
|
210
|
+
args: { paginationOpts: Infer<typeof paginationOptsValidator> };
|
|
211
|
+
}
|
|
212
|
+
>;
|
|
213
|
+
ongoingSplits: Record<QueryPageKey, [QueryPageKey, QueryPageKey]>;
|
|
214
|
+
skip: boolean;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
const splitQuery =
|
|
218
|
+
(key: QueryPageKey, splitCursor: string, continueCursor: string) =>
|
|
219
|
+
(prevState: UsePaginatedQueryState) => {
|
|
220
|
+
const queries = { ...prevState.queries };
|
|
221
|
+
const splitKey1 = prevState.nextPageKey;
|
|
222
|
+
const splitKey2 = prevState.nextPageKey + 1;
|
|
223
|
+
const nextPageKey = prevState.nextPageKey + 2;
|
|
224
|
+
queries[splitKey1] = {
|
|
225
|
+
query: prevState.query,
|
|
226
|
+
args: {
|
|
227
|
+
...prevState.args,
|
|
228
|
+
paginationOpts: {
|
|
229
|
+
...prevState.queries[key]!.args.paginationOpts,
|
|
230
|
+
endCursor: splitCursor,
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
queries[splitKey2] = {
|
|
235
|
+
query: prevState.query,
|
|
236
|
+
args: {
|
|
237
|
+
...prevState.args,
|
|
238
|
+
paginationOpts: {
|
|
239
|
+
...prevState.queries[key]!.args.paginationOpts,
|
|
240
|
+
cursor: splitCursor,
|
|
241
|
+
endCursor: continueCursor,
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
};
|
|
245
|
+
const ongoingSplits = { ...prevState.ongoingSplits };
|
|
246
|
+
ongoingSplits[key] = [splitKey1, splitKey2];
|
|
247
|
+
return {
|
|
248
|
+
...prevState,
|
|
249
|
+
nextPageKey,
|
|
250
|
+
queries,
|
|
251
|
+
ongoingSplits,
|
|
252
|
+
};
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
const completeSplitQuery =
|
|
256
|
+
(key: QueryPageKey) => (prevState: UsePaginatedQueryState) => {
|
|
257
|
+
const completedSplit = prevState.ongoingSplits[key];
|
|
258
|
+
if (completedSplit === undefined) {
|
|
259
|
+
return prevState;
|
|
260
|
+
}
|
|
261
|
+
const queries = { ...prevState.queries };
|
|
262
|
+
delete queries[key];
|
|
263
|
+
const ongoingSplits = { ...prevState.ongoingSplits };
|
|
264
|
+
delete ongoingSplits[key];
|
|
265
|
+
let pageKeys = prevState.pageKeys.slice();
|
|
266
|
+
const pageIndex = prevState.pageKeys.findIndex((v) => v === key);
|
|
267
|
+
if (pageIndex >= 0) {
|
|
268
|
+
pageKeys = [
|
|
269
|
+
...prevState.pageKeys.slice(0, pageIndex),
|
|
270
|
+
...completedSplit,
|
|
271
|
+
...prevState.pageKeys.slice(pageIndex + 1),
|
|
272
|
+
];
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
...prevState,
|
|
276
|
+
queries,
|
|
277
|
+
pageKeys,
|
|
278
|
+
ongoingSplits,
|
|
279
|
+
};
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Load data reactively from a paginated query to a create a growing list.
|
|
284
|
+
*
|
|
285
|
+
* This can be used to power "infinite scroll" UIs.
|
|
286
|
+
*
|
|
287
|
+
* This hook must be used with public query references that match
|
|
288
|
+
* {@link PaginatedQueryReference}.
|
|
289
|
+
*
|
|
290
|
+
* `usePaginatedQuery` concatenates all the pages of results into a single list
|
|
291
|
+
* and manages the continuation cursors when requesting more items.
|
|
292
|
+
*
|
|
293
|
+
* Example usage:
|
|
294
|
+
* ```typescript
|
|
295
|
+
* const { results, status, isLoading, loadMore } = usePaginatedQuery(
|
|
296
|
+
* api.messages.list,
|
|
297
|
+
* { channel: "#general" },
|
|
298
|
+
* { initialNumItems: 5 }
|
|
299
|
+
* );
|
|
300
|
+
* ```
|
|
301
|
+
*
|
|
302
|
+
* If the query reference or arguments change, the pagination state will be reset
|
|
303
|
+
* to the first page. Similarly, if any of the pages result in an InvalidCursor
|
|
304
|
+
* error or an error associated with too much data, the pagination state will also
|
|
305
|
+
* reset to the first page.
|
|
306
|
+
*
|
|
307
|
+
* To learn more about pagination, see [Paginated Queries](https://docs.convex.dev/database/pagination).
|
|
308
|
+
*
|
|
309
|
+
* @param query - A FunctionReference to the public query function to run.
|
|
310
|
+
* @param args - The arguments object for the query function, excluding
|
|
311
|
+
* the `paginationOpts` property. That property is injected by this hook.
|
|
312
|
+
* @param options - An object specifying the `initialNumItems` to be loaded in
|
|
313
|
+
* the first page, and the `endCursorBehavior` to use.
|
|
314
|
+
* @param options.endCursorBehavior` controls how the `endCursor` is set on the
|
|
315
|
+
* last loaded page. The current behavior is to have the first request for a page
|
|
316
|
+
* "pin" the end of the page to the `endCursor` returned in the first request.
|
|
317
|
+
* This shows up as your first request growing as new items are added within
|
|
318
|
+
* the range of the initial page. This is tracked via a QueryJournal, which is
|
|
319
|
+
* not shared between clients and can have unexpected behavior, so we will be
|
|
320
|
+
* deprecating this behavior in favor of the new option `setOnLoadMore`.
|
|
321
|
+
* For `setOnLoadMore`, the `endCursor` is not inferred from the first request,
|
|
322
|
+
* instead the first call to `loadMore` will explicitly set the `endCursor` to
|
|
323
|
+
* the `continueCursor` of the last page. In the future this will not use the
|
|
324
|
+
* QueryJournal and will become the default behavior, resulting in the first
|
|
325
|
+
* page staying at the same size as `initialNumItems` until you call `loadMore`.
|
|
326
|
+
* Note: setting the `endCursor` on the request will re-request that page with
|
|
327
|
+
* the new argument, causing an effectively duplicate request per `loadMore`.
|
|
328
|
+
*
|
|
329
|
+
* @returns A {@link UsePaginatedQueryResult} that includes the currently loaded
|
|
330
|
+
* items, the status of the pagination, and a `loadMore` function.
|
|
331
|
+
*
|
|
332
|
+
* @public
|
|
333
|
+
*/
|
|
334
|
+
export function usePaginatedQuery<Query extends PaginatedQueryReference>(
|
|
335
|
+
query: Query,
|
|
336
|
+
args: PaginatedQueryArgs<Query> | "skip",
|
|
337
|
+
options: {
|
|
338
|
+
initialNumItems: number;
|
|
339
|
+
endCursorBehavior?: "setOnLoadMore" | "legacyQueryJournal";
|
|
340
|
+
},
|
|
341
|
+
): UsePaginatedQueryReturnType<Query> {
|
|
342
|
+
if (
|
|
343
|
+
typeof options?.initialNumItems !== "number" ||
|
|
344
|
+
options.initialNumItems < 0
|
|
345
|
+
) {
|
|
346
|
+
throw new Error(
|
|
347
|
+
`\`options.initialNumItems\` must be a positive number. Received \`${options?.initialNumItems}\`.`,
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
const skip = args === "skip";
|
|
351
|
+
const argsObject = skip ? {} : args;
|
|
352
|
+
const queryName = getFunctionName(query);
|
|
353
|
+
const createInitialState = useMemo(() => {
|
|
354
|
+
return () => {
|
|
355
|
+
const id = nextPaginationId();
|
|
356
|
+
return {
|
|
357
|
+
query,
|
|
358
|
+
args: argsObject as Record<string, Value>,
|
|
359
|
+
id,
|
|
360
|
+
nextPageKey: 1,
|
|
361
|
+
pageKeys: skip ? [] : [0],
|
|
362
|
+
queries: skip
|
|
363
|
+
? ({} as UsePaginatedQueryState["queries"])
|
|
364
|
+
: {
|
|
365
|
+
0: {
|
|
366
|
+
query,
|
|
367
|
+
args: {
|
|
368
|
+
...argsObject,
|
|
369
|
+
paginationOpts: {
|
|
370
|
+
numItems: options.initialNumItems,
|
|
371
|
+
cursor: null,
|
|
372
|
+
id,
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
},
|
|
376
|
+
},
|
|
377
|
+
ongoingSplits: {},
|
|
378
|
+
skip,
|
|
379
|
+
};
|
|
380
|
+
};
|
|
381
|
+
// ESLint doesn't like that we're stringifying the args. We do this because
|
|
382
|
+
// we want to avoid rerendering if the args are a different
|
|
383
|
+
// object that serializes to the same result.
|
|
384
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
385
|
+
}, [
|
|
386
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
387
|
+
JSON.stringify(convexToJson(argsObject as Value)),
|
|
388
|
+
queryName,
|
|
389
|
+
options.initialNumItems,
|
|
390
|
+
skip,
|
|
391
|
+
]);
|
|
392
|
+
|
|
393
|
+
const [state, setState] =
|
|
394
|
+
useState<UsePaginatedQueryState>(createInitialState);
|
|
395
|
+
|
|
396
|
+
// `currState` is the state that we'll render based on.
|
|
397
|
+
let currState = state;
|
|
398
|
+
if (
|
|
399
|
+
getFunctionName(query) !== getFunctionName(state.query) ||
|
|
400
|
+
JSON.stringify(convexToJson(argsObject as Value)) !==
|
|
401
|
+
JSON.stringify(convexToJson(state.args)) ||
|
|
402
|
+
skip !== state.skip
|
|
403
|
+
) {
|
|
404
|
+
currState = createInitialState();
|
|
405
|
+
setState(currState);
|
|
406
|
+
}
|
|
407
|
+
const convexClient = useConvex();
|
|
408
|
+
const logger = convexClient.logger;
|
|
409
|
+
|
|
410
|
+
const resultsObject = useQueries(currState.queries);
|
|
411
|
+
|
|
412
|
+
const [results, maybeLastResult]: [
|
|
413
|
+
Value[],
|
|
414
|
+
undefined | PaginationResult<Value>,
|
|
415
|
+
] = useMemo(() => {
|
|
416
|
+
let currResult: PaginationResult<Value> | undefined = undefined;
|
|
417
|
+
|
|
418
|
+
const allItems: Value[] = [];
|
|
419
|
+
for (const pageKey of currState.pageKeys) {
|
|
420
|
+
currResult = resultsObject[pageKey];
|
|
421
|
+
if (currResult === undefined) {
|
|
422
|
+
break;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
if (currResult instanceof Error) {
|
|
426
|
+
if (
|
|
427
|
+
currResult.message.includes("InvalidCursor") ||
|
|
428
|
+
(currResult instanceof ConvexError &&
|
|
429
|
+
typeof currResult.data === "object" &&
|
|
430
|
+
currResult.data?.isConvexSystemError === true &&
|
|
431
|
+
currResult.data?.paginationError === "InvalidCursor")
|
|
432
|
+
) {
|
|
433
|
+
// - InvalidCursor: If the cursor is invalid, probably the paginated
|
|
434
|
+
// database query was data-dependent and changed underneath us. The
|
|
435
|
+
// cursor in the params or journal no longer matches the current
|
|
436
|
+
// database query.
|
|
437
|
+
|
|
438
|
+
// In all cases, we want to restart pagination to throw away all our
|
|
439
|
+
// existing cursors.
|
|
440
|
+
logger.warn(
|
|
441
|
+
"usePaginatedQuery hit error, resetting pagination state: " +
|
|
442
|
+
currResult.message,
|
|
443
|
+
);
|
|
444
|
+
setState(createInitialState);
|
|
445
|
+
return [[], undefined];
|
|
446
|
+
} else {
|
|
447
|
+
throw currResult;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
const ongoingSplit = currState.ongoingSplits[pageKey];
|
|
451
|
+
if (ongoingSplit !== undefined) {
|
|
452
|
+
if (
|
|
453
|
+
resultsObject[ongoingSplit[0]] !== undefined &&
|
|
454
|
+
resultsObject[ongoingSplit[1]] !== undefined
|
|
455
|
+
) {
|
|
456
|
+
// Both pages of the split have results now. Swap them in.
|
|
457
|
+
setState(completeSplitQuery(pageKey));
|
|
458
|
+
}
|
|
459
|
+
} else if (
|
|
460
|
+
currResult.splitCursor &&
|
|
461
|
+
(currResult.pageStatus === "SplitRecommended" ||
|
|
462
|
+
currResult.pageStatus === "SplitRequired" ||
|
|
463
|
+
currResult.page.length > options.initialNumItems * 2)
|
|
464
|
+
) {
|
|
465
|
+
// If a single page has more than double the expected number of items,
|
|
466
|
+
// or if the server requests a split, split the page into two.
|
|
467
|
+
setState(
|
|
468
|
+
splitQuery(
|
|
469
|
+
pageKey,
|
|
470
|
+
currResult.splitCursor,
|
|
471
|
+
currResult.continueCursor,
|
|
472
|
+
),
|
|
473
|
+
);
|
|
474
|
+
}
|
|
475
|
+
if (currResult.pageStatus === "SplitRequired") {
|
|
476
|
+
// If pageStatus is 'SplitRequired', it means the server was not able to
|
|
477
|
+
// fetch the full page. So we stop results before the incomplete
|
|
478
|
+
// page and return 'LoadingMore' while the page is splitting.
|
|
479
|
+
return [allItems, undefined];
|
|
480
|
+
}
|
|
481
|
+
allItems.push(...currResult.page);
|
|
482
|
+
}
|
|
483
|
+
return [allItems, currResult];
|
|
484
|
+
}, [
|
|
485
|
+
resultsObject,
|
|
486
|
+
currState.pageKeys,
|
|
487
|
+
currState.ongoingSplits,
|
|
488
|
+
options.initialNumItems,
|
|
489
|
+
createInitialState,
|
|
490
|
+
logger,
|
|
491
|
+
]);
|
|
492
|
+
|
|
493
|
+
const statusObject = useMemo(() => {
|
|
494
|
+
if (maybeLastResult === undefined) {
|
|
495
|
+
if (currState.nextPageKey === 1) {
|
|
496
|
+
return {
|
|
497
|
+
status: "LoadingFirstPage",
|
|
498
|
+
isLoading: true,
|
|
499
|
+
loadMore: (_numItems: number) => {
|
|
500
|
+
// Intentional noop.
|
|
501
|
+
},
|
|
502
|
+
} as const;
|
|
503
|
+
} else {
|
|
504
|
+
return {
|
|
505
|
+
status: "LoadingMore",
|
|
506
|
+
isLoading: true,
|
|
507
|
+
loadMore: (_numItems: number) => {
|
|
508
|
+
// Intentional noop.
|
|
509
|
+
},
|
|
510
|
+
} as const;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
if (maybeLastResult.isDone) {
|
|
514
|
+
return {
|
|
515
|
+
status: "Exhausted",
|
|
516
|
+
isLoading: false,
|
|
517
|
+
loadMore: (_numItems: number) => {
|
|
518
|
+
// Intentional noop.
|
|
519
|
+
},
|
|
520
|
+
} as const;
|
|
521
|
+
}
|
|
522
|
+
const continueCursor = maybeLastResult.continueCursor;
|
|
523
|
+
let alreadyLoadingMore = false;
|
|
524
|
+
return {
|
|
525
|
+
status: "CanLoadMore",
|
|
526
|
+
isLoading: false,
|
|
527
|
+
loadMore: (numItems: number) => {
|
|
528
|
+
if (!alreadyLoadingMore) {
|
|
529
|
+
alreadyLoadingMore = true;
|
|
530
|
+
setState((prevState) => {
|
|
531
|
+
let nextPageKey = prevState.nextPageKey;
|
|
532
|
+
const queries = { ...prevState.queries };
|
|
533
|
+
let ongoingSplits = prevState.ongoingSplits;
|
|
534
|
+
let pageKeys = prevState.pageKeys;
|
|
535
|
+
if (options.endCursorBehavior === "setOnLoadMore") {
|
|
536
|
+
const lastPageKey = prevState.pageKeys.at(-1)!;
|
|
537
|
+
const boundLastPageKey = nextPageKey;
|
|
538
|
+
queries[boundLastPageKey] = {
|
|
539
|
+
query: prevState.query,
|
|
540
|
+
args: {
|
|
541
|
+
...prevState.args,
|
|
542
|
+
paginationOpts: {
|
|
543
|
+
...(queries[lastPageKey]!.args
|
|
544
|
+
.paginationOpts as unknown as PaginationOptions),
|
|
545
|
+
endCursor: continueCursor,
|
|
546
|
+
},
|
|
547
|
+
},
|
|
548
|
+
};
|
|
549
|
+
nextPageKey++;
|
|
550
|
+
ongoingSplits = {
|
|
551
|
+
...ongoingSplits,
|
|
552
|
+
[lastPageKey]: [boundLastPageKey, nextPageKey],
|
|
553
|
+
};
|
|
554
|
+
} else {
|
|
555
|
+
pageKeys = [...prevState.pageKeys, nextPageKey];
|
|
556
|
+
}
|
|
557
|
+
queries[nextPageKey] = {
|
|
558
|
+
query: prevState.query,
|
|
559
|
+
args: {
|
|
560
|
+
...prevState.args,
|
|
561
|
+
paginationOpts: {
|
|
562
|
+
numItems,
|
|
563
|
+
cursor: continueCursor,
|
|
564
|
+
id: prevState.id,
|
|
565
|
+
},
|
|
566
|
+
},
|
|
567
|
+
};
|
|
568
|
+
nextPageKey++;
|
|
569
|
+
return {
|
|
570
|
+
...prevState,
|
|
571
|
+
pageKeys,
|
|
572
|
+
nextPageKey,
|
|
573
|
+
queries,
|
|
574
|
+
ongoingSplits,
|
|
575
|
+
};
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
},
|
|
579
|
+
} as const;
|
|
580
|
+
}, [maybeLastResult, currState.nextPageKey, options.endCursorBehavior]);
|
|
581
|
+
|
|
582
|
+
return {
|
|
583
|
+
results,
|
|
584
|
+
...statusObject,
|
|
585
|
+
};
|
|
586
|
+
}
|
package/react/cache.d.ts
CHANGED
package/react/cache.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
|
package/react/cache.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { ConvexQueryCacheProvider } from "./cache/provider.js";
|
|
2
|
-
export { useQuery, useQueries } from "./cache/hooks.js";
|
|
2
|
+
export { useQuery, useQueries, usePaginatedQuery } from "./cache/hooks.js";
|
package/react/cache.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { ConvexQueryCacheProvider } from "./cache/provider.js";
|
|
2
|
-
export { useQuery, useQueries } from "./cache/hooks.js";
|
|
2
|
+
export { useQuery, useQueries, usePaginatedQuery } from "./cache/hooks.js";
|
package/server/migrations.d.ts
CHANGED
|
@@ -116,8 +116,8 @@ export declare const migrationsTable: import("convex/server").TableDefinition<im
|
|
|
116
116
|
latestEnd?: number | undefined;
|
|
117
117
|
cursor: string | null;
|
|
118
118
|
name: string;
|
|
119
|
-
table: string;
|
|
120
119
|
isDone: boolean;
|
|
120
|
+
table: string;
|
|
121
121
|
processed: number;
|
|
122
122
|
latestStart: number;
|
|
123
123
|
}, {
|
|
@@ -129,7 +129,7 @@ export declare const migrationsTable: import("convex/server").TableDefinition<im
|
|
|
129
129
|
processed: import("convex/values").VFloat64<number, "required">;
|
|
130
130
|
latestStart: import("convex/values").VFloat64<number, "required">;
|
|
131
131
|
latestEnd: import("convex/values").VFloat64<number | undefined, "optional">;
|
|
132
|
-
}, "required", "cursor" | "name" | "
|
|
132
|
+
}, "required", "cursor" | "name" | "isDone" | "table" | "workerId" | "processed" | "latestStart" | "latestEnd">, {
|
|
133
133
|
name: ["name", "_creationTime"];
|
|
134
134
|
}, {}, {}>;
|
|
135
135
|
declare const migrationArgs: {
|
|
@@ -284,8 +284,8 @@ export declare function cancelMigration<DataModel extends GenericDataModel>(ctx:
|
|
|
284
284
|
latestEnd?: number | undefined;
|
|
285
285
|
cursor: string | null;
|
|
286
286
|
name: string;
|
|
287
|
-
table: string;
|
|
288
287
|
isDone: boolean;
|
|
288
|
+
table: string;
|
|
289
289
|
processed: number;
|
|
290
290
|
latestStart: number;
|
|
291
291
|
} | {
|
|
@@ -294,8 +294,8 @@ export declare function cancelMigration<DataModel extends GenericDataModel>(ctx:
|
|
|
294
294
|
latestEnd?: number | undefined;
|
|
295
295
|
cursor: string | null;
|
|
296
296
|
name: string;
|
|
297
|
-
table: string;
|
|
298
297
|
isDone: boolean;
|
|
298
|
+
table: string;
|
|
299
299
|
processed: number;
|
|
300
300
|
latestStart: number;
|
|
301
301
|
}>;
|
package/server/stream.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["stream.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["stream.ts"],"names":[],"mappings":"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"}
|
package/server/stream.js
CHANGED
|
@@ -22,7 +22,9 @@ function makeExclusive(boundType) {
|
|
|
22
22
|
* 2. q.eq("f1", 1).gt("f2", 2).lt("f2", 3)
|
|
23
23
|
* 3. q.eq("f1", 1).eq("f2", 3).lte("f3", 2)
|
|
24
24
|
*/
|
|
25
|
-
function splitRange(indexFields,
|
|
25
|
+
function splitRange(indexFields,
|
|
26
|
+
// For descending queries, the resulting queries are reversed.
|
|
27
|
+
order, startBound, endBound, startBoundType, endBoundType) {
|
|
26
28
|
// Three parts to the split:
|
|
27
29
|
// 1. reduce down from startBound to common prefix
|
|
28
30
|
// 2. range with common prefix
|
|
@@ -79,7 +81,11 @@ function splitRange(indexFields, startBound, endBound, startBoundType, endBoundT
|
|
|
79
81
|
middleRange.push([startBoundType, indexFields[0], startValue]);
|
|
80
82
|
middleRange.push([endBoundType, indexFields[0], endValue]);
|
|
81
83
|
}
|
|
82
|
-
|
|
84
|
+
const ranges = [...startRanges, middleRange, ...endRanges];
|
|
85
|
+
if (order === "desc") {
|
|
86
|
+
ranges.reverse();
|
|
87
|
+
}
|
|
88
|
+
return ranges;
|
|
83
89
|
}
|
|
84
90
|
function rangeToQuery(range) {
|
|
85
91
|
return (q) => {
|
|
@@ -226,6 +232,18 @@ class QueryStream {
|
|
|
226
232
|
throw new Error("Cannot call .filter on query stream. use .filterWith instead.");
|
|
227
233
|
}
|
|
228
234
|
async paginate(opts) {
|
|
235
|
+
if (opts.numItems === 0) {
|
|
236
|
+
if (opts.cursor === null) {
|
|
237
|
+
throw new Error(".paginate called with cursor of null and 0 for numItems. " +
|
|
238
|
+
"This is not supported, as null is not a valid continueCursor. " +
|
|
239
|
+
"Advice: avoid calling paginate entirely in these cases.");
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
page: [],
|
|
243
|
+
isDone: false,
|
|
244
|
+
continueCursor: opts.cursor,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
229
247
|
const order = this.getOrder();
|
|
230
248
|
let newStartKey = {
|
|
231
249
|
key: [],
|
|
@@ -242,7 +260,7 @@ class QueryStream {
|
|
|
242
260
|
inclusive: true,
|
|
243
261
|
};
|
|
244
262
|
const maxRowsToRead = opts.maximumRowsRead;
|
|
245
|
-
const softMaxRowsToRead =
|
|
263
|
+
const softMaxRowsToRead = opts.numItems + 1;
|
|
246
264
|
let maxRows = opts.numItems;
|
|
247
265
|
if (opts.endCursor) {
|
|
248
266
|
newEndKey = {
|
|
@@ -545,14 +563,11 @@ export class OrderedStreamQuery extends StreamableQuery {
|
|
|
545
563
|
*/
|
|
546
564
|
export function streamIndexRange(db, schema, table, index, bounds, order) {
|
|
547
565
|
const indexFields = getIndexFields(table, index, schema);
|
|
548
|
-
const splitBounds = splitRange(indexFields, bounds.lowerBound, bounds.upperBound, bounds.lowerBoundInclusive ? "gte" : "gt", bounds.upperBoundInclusive ? "lte" : "lt");
|
|
549
|
-
const subQueries =
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
.withIndex(index, rangeToQuery(splitBound))
|
|
554
|
-
.order(order));
|
|
555
|
-
}
|
|
566
|
+
const splitBounds = splitRange(indexFields, order, bounds.lowerBound, bounds.upperBound, bounds.lowerBoundInclusive ? "gte" : "gt", bounds.upperBoundInclusive ? "lte" : "lt");
|
|
567
|
+
const subQueries = splitBounds.map((splitBound) => stream(db, schema)
|
|
568
|
+
.query(table)
|
|
569
|
+
.withIndex(index, rangeToQuery(splitBound))
|
|
570
|
+
.order(order));
|
|
556
571
|
return new ConcatStreams(...subQueries);
|
|
557
572
|
}
|
|
558
573
|
class ReflectIndexRange {
|
package/server/stream.ts
CHANGED
|
@@ -52,6 +52,8 @@ type Bound = ["gt" | "lt" | "gte" | "lte" | "eq", string, Value];
|
|
|
52
52
|
*/
|
|
53
53
|
function splitRange(
|
|
54
54
|
indexFields: string[],
|
|
55
|
+
// For descending queries, the resulting queries are reversed.
|
|
56
|
+
order: "asc" | "desc",
|
|
55
57
|
startBound: IndexKey,
|
|
56
58
|
endBound: IndexKey,
|
|
57
59
|
startBoundType: "gt" | "lt" | "gte" | "lte",
|
|
@@ -116,7 +118,11 @@ function splitRange(
|
|
|
116
118
|
middleRange.push([startBoundType, indexFields[0]!, startValue]);
|
|
117
119
|
middleRange.push([endBoundType, indexFields[0]!, endValue]);
|
|
118
120
|
}
|
|
119
|
-
|
|
121
|
+
const ranges = [...startRanges, middleRange, ...endRanges];
|
|
122
|
+
if (order === "desc") {
|
|
123
|
+
ranges.reverse();
|
|
124
|
+
}
|
|
125
|
+
return ranges;
|
|
120
126
|
}
|
|
121
127
|
|
|
122
128
|
function rangeToQuery(range: Bound[]) {
|
|
@@ -321,6 +327,20 @@ abstract class QueryStream<T extends GenericStreamItem>
|
|
|
321
327
|
maximumRowsRead?: number;
|
|
322
328
|
},
|
|
323
329
|
): Promise<PaginationResult<T>> {
|
|
330
|
+
if (opts.numItems === 0) {
|
|
331
|
+
if (opts.cursor === null) {
|
|
332
|
+
throw new Error(
|
|
333
|
+
".paginate called with cursor of null and 0 for numItems. " +
|
|
334
|
+
"This is not supported, as null is not a valid continueCursor. " +
|
|
335
|
+
"Advice: avoid calling paginate entirely in these cases.",
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
return {
|
|
339
|
+
page: [],
|
|
340
|
+
isDone: false,
|
|
341
|
+
continueCursor: opts.cursor,
|
|
342
|
+
};
|
|
343
|
+
}
|
|
324
344
|
const order = this.getOrder();
|
|
325
345
|
let newStartKey = {
|
|
326
346
|
key: [] as IndexKey,
|
|
@@ -337,7 +357,7 @@ abstract class QueryStream<T extends GenericStreamItem>
|
|
|
337
357
|
inclusive: true,
|
|
338
358
|
};
|
|
339
359
|
const maxRowsToRead = opts.maximumRowsRead;
|
|
340
|
-
const softMaxRowsToRead =
|
|
360
|
+
const softMaxRowsToRead = opts.numItems + 1;
|
|
341
361
|
let maxRows: number | undefined = opts.numItems;
|
|
342
362
|
if (opts.endCursor) {
|
|
343
363
|
newEndKey = {
|
|
@@ -821,20 +841,18 @@ export function streamIndexRange<
|
|
|
821
841
|
const indexFields = getIndexFields(table, index, schema);
|
|
822
842
|
const splitBounds = splitRange(
|
|
823
843
|
indexFields,
|
|
844
|
+
order,
|
|
824
845
|
bounds.lowerBound,
|
|
825
846
|
bounds.upperBound,
|
|
826
847
|
bounds.lowerBoundInclusive ? "gte" : "gt",
|
|
827
848
|
bounds.upperBoundInclusive ? "lte" : "lt",
|
|
828
849
|
);
|
|
829
|
-
const subQueries
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
.order(order),
|
|
836
|
-
);
|
|
837
|
-
}
|
|
850
|
+
const subQueries = splitBounds.map((splitBound) =>
|
|
851
|
+
stream(db, schema)
|
|
852
|
+
.query(table)
|
|
853
|
+
.withIndex(index, rangeToQuery(splitBound))
|
|
854
|
+
.order(order),
|
|
855
|
+
);
|
|
838
856
|
return new ConcatStreams(...subQueries);
|
|
839
857
|
}
|
|
840
858
|
|