@instantdb/react-common 0.22.164 → 0.22.165
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/commonjs/InstantReactAbstractDatabase.d.ts +25 -0
- package/dist/commonjs/InstantReactAbstractDatabase.d.ts.map +1 -1
- package/dist/commonjs/InstantReactAbstractDatabase.js +32 -0
- package/dist/commonjs/InstantReactAbstractDatabase.js.map +1 -1
- package/dist/commonjs/useInfiniteQuerySubscription.d.ts +28 -0
- package/dist/commonjs/useInfiniteQuerySubscription.d.ts.map +1 -0
- package/dist/commonjs/useInfiniteQuerySubscription.js +58 -0
- package/dist/commonjs/useInfiniteQuerySubscription.js.map +1 -0
- package/dist/esm/InstantReactAbstractDatabase.d.ts +25 -0
- package/dist/esm/InstantReactAbstractDatabase.d.ts.map +1 -1
- package/dist/esm/InstantReactAbstractDatabase.js +32 -0
- package/dist/esm/InstantReactAbstractDatabase.js.map +1 -1
- package/dist/esm/useInfiniteQuerySubscription.d.ts +28 -0
- package/dist/esm/useInfiniteQuerySubscription.d.ts.map +1 -0
- package/dist/esm/useInfiniteQuerySubscription.js +55 -0
- package/dist/esm/useInfiniteQuerySubscription.js.map +1 -0
- package/dist/standalone/index.js +2402 -2038
- package/dist/standalone/index.umd.cjs +12 -12
- package/package.json +3 -3
- package/src/InstantReactAbstractDatabase.tsx +39 -0
- package/src/useInfiniteQuerySubscription.ts +127 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instantdb/react-common",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.165",
|
|
4
4
|
"description": "Instant DB shared components for React and React Native",
|
|
5
5
|
"homepage": "https://github.com/instantdb/instant/tree/main/client/packages/react-common",
|
|
6
6
|
"repository": {
|
|
@@ -53,8 +53,8 @@
|
|
|
53
53
|
"react": ">=16"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@instantdb/core": "0.22.
|
|
57
|
-
"@instantdb/version": "0.22.
|
|
56
|
+
"@instantdb/core": "0.22.165",
|
|
57
|
+
"@instantdb/version": "0.22.165"
|
|
58
58
|
},
|
|
59
59
|
"scripts": {
|
|
60
60
|
"test": "vitest",
|
|
@@ -32,6 +32,10 @@ import {
|
|
|
32
32
|
useSyncExternalStore,
|
|
33
33
|
} from 'react';
|
|
34
34
|
import { useQueryInternal } from './useQuery.ts';
|
|
35
|
+
import {
|
|
36
|
+
type InfiniteQueryResult,
|
|
37
|
+
useInfiniteQuerySubscription,
|
|
38
|
+
} from './useInfiniteQuerySubscription.ts';
|
|
35
39
|
import { InstantReactRoom, rooms } from './InstantReactRoom.ts';
|
|
36
40
|
|
|
37
41
|
const defaultAuthState = {
|
|
@@ -390,6 +394,41 @@ export default abstract class InstantReactAbstractDatabase<
|
|
|
390
394
|
return this.core.queryOnce(query, opts);
|
|
391
395
|
};
|
|
392
396
|
|
|
397
|
+
/**
|
|
398
|
+
* Subscribe to a query and incrementally load more items
|
|
399
|
+
*
|
|
400
|
+
* Only one top level namespace in the query is allowed.
|
|
401
|
+
*
|
|
402
|
+
* Changing the query or options while the subscription is active will
|
|
403
|
+
* reset the subscription and start over with new data.
|
|
404
|
+
* @example
|
|
405
|
+
* const {
|
|
406
|
+
* data,
|
|
407
|
+
* loadNextPage,
|
|
408
|
+
* canLoadNextPage,
|
|
409
|
+
* } = db.useInfiniteQuery({
|
|
410
|
+
* posts: {
|
|
411
|
+
* $: {
|
|
412
|
+
* limit: 20, // Load 20 posts at a time
|
|
413
|
+
* order: {
|
|
414
|
+
* createdAt: 'desc',
|
|
415
|
+
* },
|
|
416
|
+
* },
|
|
417
|
+
* },
|
|
418
|
+
* });
|
|
419
|
+
*/
|
|
420
|
+
useInfiniteQuery = <Q extends ValidQuery<Q, Schema>>(
|
|
421
|
+
query: Q,
|
|
422
|
+
opts?: InstaQLOptions,
|
|
423
|
+
): InfiniteQueryResult<Schema, Q, UseDates> => {
|
|
424
|
+
const result = useInfiniteQuerySubscription<Schema, Q, UseDates>({
|
|
425
|
+
core: this.core,
|
|
426
|
+
query: query,
|
|
427
|
+
opts,
|
|
428
|
+
});
|
|
429
|
+
return result;
|
|
430
|
+
};
|
|
431
|
+
|
|
393
432
|
/**
|
|
394
433
|
* Only render children if the user is signed in.
|
|
395
434
|
* @see https://instantdb.com/docs/auth
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type InfiniteQuerySubscription,
|
|
3
|
+
type InstantCoreDatabase,
|
|
4
|
+
type InstantSchemaDef,
|
|
5
|
+
type InstaQLOptions,
|
|
6
|
+
InstaQLResponse,
|
|
7
|
+
ValidQuery,
|
|
8
|
+
weakHash,
|
|
9
|
+
getInfiniteQueryInitialSnapshot,
|
|
10
|
+
} from '@instantdb/core';
|
|
11
|
+
import { useCallback, useRef, useSyncExternalStore } from 'react';
|
|
12
|
+
|
|
13
|
+
export type InfiniteQueryResult<
|
|
14
|
+
Schema extends InstantSchemaDef<any, any, any>,
|
|
15
|
+
Q extends ValidQuery<Q, Schema>,
|
|
16
|
+
UseDates extends boolean,
|
|
17
|
+
> =
|
|
18
|
+
| {
|
|
19
|
+
error: { message: string };
|
|
20
|
+
data: undefined;
|
|
21
|
+
isLoading: false;
|
|
22
|
+
canLoadNextPage: boolean;
|
|
23
|
+
loadNextPage: () => void;
|
|
24
|
+
}
|
|
25
|
+
| {
|
|
26
|
+
error: undefined;
|
|
27
|
+
data: undefined;
|
|
28
|
+
isLoading: true;
|
|
29
|
+
canLoadNextPage: boolean;
|
|
30
|
+
loadNextPage: () => void;
|
|
31
|
+
}
|
|
32
|
+
| {
|
|
33
|
+
error: undefined;
|
|
34
|
+
data: InstaQLResponse<Schema, Q, UseDates>;
|
|
35
|
+
isLoading: false;
|
|
36
|
+
canLoadNextPage: boolean;
|
|
37
|
+
loadNextPage: () => void;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const defaultState = {
|
|
41
|
+
error: undefined,
|
|
42
|
+
data: undefined,
|
|
43
|
+
isLoading: true,
|
|
44
|
+
canLoadNextPage: false,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export function useInfiniteQuerySubscription<
|
|
48
|
+
Schema extends InstantSchemaDef<any, any, any>,
|
|
49
|
+
Q extends ValidQuery<Q, Schema>,
|
|
50
|
+
UseDates extends boolean,
|
|
51
|
+
>({
|
|
52
|
+
core,
|
|
53
|
+
query,
|
|
54
|
+
opts,
|
|
55
|
+
}: {
|
|
56
|
+
core: InstantCoreDatabase<Schema, UseDates>;
|
|
57
|
+
query: Q | null;
|
|
58
|
+
opts?: InstaQLOptions;
|
|
59
|
+
}): InfiniteQueryResult<Schema, Q, UseDates> {
|
|
60
|
+
const subRef = useRef<InfiniteQuerySubscription | null>(null);
|
|
61
|
+
|
|
62
|
+
const queryHash = weakHash(query);
|
|
63
|
+
const optsHash = weakHash(opts);
|
|
64
|
+
const snapshot = getInfiniteQueryInitialSnapshot(core, query, opts);
|
|
65
|
+
|
|
66
|
+
const stateCacheRef = useRef<
|
|
67
|
+
Omit<InfiniteQueryResult<Schema, Q, UseDates>, 'loadNextPage'>
|
|
68
|
+
>({
|
|
69
|
+
...snapshot,
|
|
70
|
+
isLoading: !snapshot.data && !snapshot.error,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const subscribe = useCallback(
|
|
74
|
+
(cb: () => void) => {
|
|
75
|
+
subRef.current = null;
|
|
76
|
+
stateCacheRef.current = {
|
|
77
|
+
error: undefined,
|
|
78
|
+
data: undefined,
|
|
79
|
+
isLoading: true,
|
|
80
|
+
canLoadNextPage: false,
|
|
81
|
+
};
|
|
82
|
+
cb();
|
|
83
|
+
|
|
84
|
+
if (!query) {
|
|
85
|
+
return () => {};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const sub = core.subscribeInfiniteQuery(
|
|
89
|
+
query,
|
|
90
|
+
(resp) => {
|
|
91
|
+
stateCacheRef.current = {
|
|
92
|
+
...resp,
|
|
93
|
+
isLoading: false,
|
|
94
|
+
};
|
|
95
|
+
cb();
|
|
96
|
+
},
|
|
97
|
+
opts,
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
subRef.current = sub;
|
|
101
|
+
|
|
102
|
+
return () => {
|
|
103
|
+
sub.unsubscribe();
|
|
104
|
+
if (subRef.current === sub) {
|
|
105
|
+
subRef.current = null;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
},
|
|
109
|
+
[queryHash, optsHash],
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
const state = useSyncExternalStore(
|
|
113
|
+
subscribe,
|
|
114
|
+
() => stateCacheRef.current,
|
|
115
|
+
() => defaultState,
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
const loadNextPage = () => {
|
|
119
|
+
subRef.current?.loadNextPage();
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// @ts-expect-error union type
|
|
123
|
+
return {
|
|
124
|
+
...state,
|
|
125
|
+
loadNextPage,
|
|
126
|
+
};
|
|
127
|
+
}
|