@peerbit/react 0.0.24 → 0.0.25
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/lib/esm/useQuery.d.ts +6 -3
- package/lib/esm/useQuery.js +55 -58
- package/lib/esm/useQuery.js.map +1 -1
- package/package.json +2 -2
- package/src/useQuery.tsx +77 -72
package/lib/esm/useQuery.d.ts
CHANGED
|
@@ -9,8 +9,11 @@ type QueryOptions = {
|
|
|
9
9
|
query: QueryLike;
|
|
10
10
|
id?: string;
|
|
11
11
|
};
|
|
12
|
-
type
|
|
12
|
+
type RemoteQueryOptions = {
|
|
13
13
|
warmup?: number;
|
|
14
|
+
joining?: {
|
|
15
|
+
waitFor?: number;
|
|
16
|
+
};
|
|
14
17
|
eager?: boolean;
|
|
15
18
|
};
|
|
16
19
|
export declare const useQuery: <T extends Record<string, any>, I extends Record<string, any>, R extends boolean | undefined = true, RT = R extends false ? WithContext<I> : WithIndexedContext<T, I>>(db?: Documents<T, I>, options?: {
|
|
@@ -28,10 +31,10 @@ export declare const useQuery: <T extends Record<string, any>, I extends Record<
|
|
|
28
31
|
update?: (prev: RT[], change: DocumentsChange<T, I>) => RT[];
|
|
29
32
|
};
|
|
30
33
|
local?: boolean;
|
|
31
|
-
remote?: boolean |
|
|
34
|
+
remote?: boolean | RemoteQueryOptions;
|
|
32
35
|
} & QueryOptions) => {
|
|
33
36
|
items: RT[];
|
|
34
|
-
loadMore: () => Promise<boolean | undefined>;
|
|
37
|
+
loadMore: (n?: number, pollEvenIfWasEmpty?: boolean) => Promise<boolean | undefined>;
|
|
35
38
|
isLoading: boolean;
|
|
36
39
|
empty: () => boolean;
|
|
37
40
|
id: string | undefined;
|
package/lib/esm/useQuery.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState, useEffect, useRef
|
|
1
|
+
import { useState, useEffect, useRef } from "react";
|
|
2
2
|
import { ClosedError, } from "@peerbit/document";
|
|
3
3
|
import { AbortError } from "@peerbit/time";
|
|
4
4
|
import { NoPeersError } from "@peerbit/shared-log";
|
|
@@ -14,9 +14,7 @@ export const useQuery = (db, options) => {
|
|
|
14
14
|
const emptyResultsRef = useRef(false);
|
|
15
15
|
const closeControllerRef = useRef(null);
|
|
16
16
|
const waitedOnceRef = useRef(false);
|
|
17
|
-
const resetResultsOnReset = useRef(true);
|
|
18
17
|
const [id, setId] = useState(undefined);
|
|
19
|
-
const [resetCounter, invokeReset] = useReducer((n) => n + 1, 0);
|
|
20
18
|
const reverseRef = useRef(options?.reverse);
|
|
21
19
|
useEffect(() => {
|
|
22
20
|
reverseRef.current = options?.reverse;
|
|
@@ -44,17 +42,14 @@ export const useQuery = (db, options) => {
|
|
|
44
42
|
closeControllerRef.current = new AbortController();
|
|
45
43
|
emptyResultsRef.current = false;
|
|
46
44
|
toClose?.iterator.close();
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
setAll([]);
|
|
50
|
-
}
|
|
45
|
+
allRef.current = [];
|
|
46
|
+
setAll([]);
|
|
51
47
|
setIsLoading(false);
|
|
52
48
|
loadingMoreRef.current = false;
|
|
53
|
-
log(
|
|
49
|
+
log("Iterator reset", toClose?.id, fromRef?.id);
|
|
54
50
|
setId(undefined);
|
|
55
51
|
};
|
|
56
52
|
useEffect(() => {
|
|
57
|
-
resetResultsOnReset.current = true;
|
|
58
53
|
waitedOnceRef.current = false;
|
|
59
54
|
}, [db, options?.id ?? options?.query, options?.resolve, options?.reverse]);
|
|
60
55
|
/* ────────────── effect: (re)create iterator ────────────── */
|
|
@@ -65,16 +60,30 @@ export const useQuery = (db, options) => {
|
|
|
65
60
|
}
|
|
66
61
|
const initIterator = () => {
|
|
67
62
|
let id = options?.id ?? uuid();
|
|
63
|
+
let remoteQueryOptions = options.remote == null || options.remote === false
|
|
64
|
+
? false
|
|
65
|
+
: {
|
|
66
|
+
...(typeof options.remote === "object"
|
|
67
|
+
? options.remote
|
|
68
|
+
: {}),
|
|
69
|
+
joining: typeof options.remote === "object" &&
|
|
70
|
+
options.remote.joining?.waitFor !== undefined
|
|
71
|
+
? {
|
|
72
|
+
waitFor: options.remote.joining?.waitFor ??
|
|
73
|
+
5e3,
|
|
74
|
+
onMissedResults: ({ amount }) => {
|
|
75
|
+
loadMore(amount, true);
|
|
76
|
+
},
|
|
77
|
+
}
|
|
78
|
+
: undefined,
|
|
79
|
+
};
|
|
68
80
|
const ref = {
|
|
69
81
|
id,
|
|
70
82
|
iterator: db.index.iterate(options.query ?? {}, {
|
|
71
83
|
local: options?.local ?? true,
|
|
72
|
-
remote:
|
|
73
|
-
? false
|
|
74
|
-
: typeof options.remote === "object"
|
|
75
|
-
? options.remote
|
|
76
|
-
: true,
|
|
84
|
+
remote: remoteQueryOptions,
|
|
77
85
|
resolve: options?.resolve,
|
|
86
|
+
signal: closeControllerRef.current?.signal,
|
|
78
87
|
}),
|
|
79
88
|
itemsConsumed: 0,
|
|
80
89
|
};
|
|
@@ -95,7 +104,7 @@ export const useQuery = (db, options) => {
|
|
|
95
104
|
? options.onChange.merge
|
|
96
105
|
: (c) => c;
|
|
97
106
|
handleChange = async (e) => {
|
|
98
|
-
log(
|
|
107
|
+
log("Merge change", e.detail, "iterator", newIteratorRef.id);
|
|
99
108
|
const filtered = await mergeFn(e.detail);
|
|
100
109
|
if (!filtered ||
|
|
101
110
|
(filtered.added.length === 0 &&
|
|
@@ -109,13 +118,13 @@ export const useQuery = (db, options) => {
|
|
|
109
118
|
}
|
|
110
119
|
else {
|
|
111
120
|
merged = await db.index.updateResults(allRef.current, filtered, options.query || {}, options.resolve ?? true);
|
|
112
|
-
log(
|
|
121
|
+
log("After update", allRef.current, merged);
|
|
113
122
|
const expectedDiff = filtered.added.length - filtered.removed.length;
|
|
114
123
|
if (merged === allRef.current ||
|
|
115
124
|
(expectedDiff !== 0 &&
|
|
116
125
|
merged.length === allRef.current.length)) {
|
|
117
126
|
// no change
|
|
118
|
-
log(
|
|
127
|
+
log("no change after merge");
|
|
119
128
|
return;
|
|
120
129
|
}
|
|
121
130
|
}
|
|
@@ -133,7 +142,6 @@ export const useQuery = (db, options) => {
|
|
|
133
142
|
options?.id ?? options?.query,
|
|
134
143
|
options?.resolve,
|
|
135
144
|
options?.reverse,
|
|
136
|
-
resetCounter,
|
|
137
145
|
]);
|
|
138
146
|
/* ────────────── loadMore (once-wait aware) ────────────── */
|
|
139
147
|
const batchSize = options?.batchSize ?? 10;
|
|
@@ -152,19 +160,13 @@ export const useQuery = (db, options) => {
|
|
|
152
160
|
}
|
|
153
161
|
return true;
|
|
154
162
|
};
|
|
155
|
-
const reloadAfterTime = () => {
|
|
156
|
-
if (typeof options?.remote === "object" && options.remote.eager) {
|
|
157
|
-
return options.remote.warmup ?? db?.log.timeUntilRoleMaturity;
|
|
158
|
-
}
|
|
159
|
-
return undefined;
|
|
160
|
-
};
|
|
161
163
|
const markWaited = () => {
|
|
162
164
|
waitedOnceRef.current = true;
|
|
163
165
|
};
|
|
164
|
-
const loadMore = async () => {
|
|
166
|
+
const loadMore = async (n = batchSize, pollEvenIfWasEmpty = false) => {
|
|
165
167
|
const iterator = iteratorRef.current;
|
|
166
168
|
if (!iterator ||
|
|
167
|
-
emptyResultsRef.current ||
|
|
169
|
+
(emptyResultsRef.current && !pollEvenIfWasEmpty) ||
|
|
168
170
|
iterator.iterator.done() ||
|
|
169
171
|
loadingMoreRef.current) {
|
|
170
172
|
return false;
|
|
@@ -174,49 +176,44 @@ export const useQuery = (db, options) => {
|
|
|
174
176
|
try {
|
|
175
177
|
/* ── optional replicate-wait ── */
|
|
176
178
|
if (shouldWait()) {
|
|
177
|
-
log(
|
|
178
|
-
let
|
|
179
|
-
const
|
|
179
|
+
log("Wait for replicators", iterator.id);
|
|
180
|
+
let t0 = Date.now();
|
|
181
|
+
const warmup = typeof options?.remote === "object" &&
|
|
180
182
|
typeof options?.remote.warmup === "number"
|
|
181
183
|
? options?.remote.warmup
|
|
182
|
-
:
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
invokeReset();
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
if (!shouldResetAfterMaturity) {
|
|
203
|
-
await promise;
|
|
184
|
+
: undefined;
|
|
185
|
+
if (warmup) {
|
|
186
|
+
await db?.log
|
|
187
|
+
.waitForReplicators({
|
|
188
|
+
timeout: warmup,
|
|
189
|
+
signal: closeControllerRef.current?.signal,
|
|
190
|
+
})
|
|
191
|
+
.catch((e) => {
|
|
192
|
+
if (e instanceof AbortError ||
|
|
193
|
+
e instanceof NoPeersError)
|
|
194
|
+
return;
|
|
195
|
+
console.warn("Remote replicators not ready", e);
|
|
196
|
+
})
|
|
197
|
+
.finally(() => {
|
|
198
|
+
log("Wait for replicators done", iterator.id, "time", Date.now() - t0);
|
|
199
|
+
markWaited();
|
|
200
|
+
});
|
|
204
201
|
}
|
|
205
202
|
}
|
|
206
203
|
else {
|
|
207
|
-
log(
|
|
204
|
+
log("Skip wait for replicators", iterator.id);
|
|
208
205
|
}
|
|
209
206
|
/* ── fetch next batch ── */
|
|
210
|
-
log(
|
|
211
|
-
let newItems = await iterator.iterator.next(
|
|
207
|
+
log("Retrieve next batch", iterator.id);
|
|
208
|
+
let newItems = await iterator.iterator.next(n);
|
|
212
209
|
if (options?.transform) {
|
|
213
|
-
log(
|
|
210
|
+
log("Transform start", iterator.id);
|
|
214
211
|
newItems = await Promise.all(newItems.map(options.transform));
|
|
215
|
-
log(
|
|
212
|
+
log("Transform end", iterator.id);
|
|
216
213
|
}
|
|
217
214
|
/* iterator might have been reset while we were async… */
|
|
218
215
|
if (iteratorRef.current !== iterator) {
|
|
219
|
-
log(
|
|
216
|
+
log("Iterator reset while loading more");
|
|
220
217
|
return false;
|
|
221
218
|
}
|
|
222
219
|
iterator.itemsConsumed += newItems.length;
|
|
@@ -234,7 +231,7 @@ export const useQuery = (db, options) => {
|
|
|
234
231
|
updateAll(combined);
|
|
235
232
|
}
|
|
236
233
|
else {
|
|
237
|
-
log(
|
|
234
|
+
log("No new items", iterator.id);
|
|
238
235
|
}
|
|
239
236
|
return !iterator.iterator.done();
|
|
240
237
|
}
|
package/lib/esm/useQuery.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useQuery.js","sourceRoot":"","sources":["../../src/useQuery.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"useQuery.js","sourceRoot":"","sources":["../../src/useQuery.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peerbit/react",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.25",
|
|
4
4
|
"homepage": "https://dao-xyz.github.io/peerbit-examples",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "lib/esm/index.js",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"last 1 safari version"
|
|
71
71
|
]
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "d7fd86e2cb51f20c3e4bfec72dab274caf0bde72"
|
|
74
74
|
}
|
package/src/useQuery.tsx
CHANGED
|
@@ -11,6 +11,7 @@ import { AbortError } from "@peerbit/time";
|
|
|
11
11
|
import { NoPeersError } from "@peerbit/shared-log";
|
|
12
12
|
import { v4 as uuid } from "uuid";
|
|
13
13
|
import { WithIndexedContext } from "@peerbit/document/dist/src/search";
|
|
14
|
+
import { on } from "events";
|
|
14
15
|
/* ────────────── helper types ────────────── */
|
|
15
16
|
type QueryLike = {
|
|
16
17
|
query?: indexerTypes.Query[] | indexerTypes.QueryLike;
|
|
@@ -18,7 +19,11 @@ type QueryLike = {
|
|
|
18
19
|
};
|
|
19
20
|
type QueryOptions = { query: QueryLike; id?: string };
|
|
20
21
|
|
|
21
|
-
type
|
|
22
|
+
type RemoteQueryOptions = {
|
|
23
|
+
warmup?: number;
|
|
24
|
+
joining?: { waitFor?: number };
|
|
25
|
+
eager?: boolean;
|
|
26
|
+
};
|
|
22
27
|
|
|
23
28
|
/* ────────────── main hook ────────────── */
|
|
24
29
|
export const useQuery = <
|
|
@@ -48,7 +53,7 @@ export const useQuery = <
|
|
|
48
53
|
update?: (prev: RT[], change: DocumentsChange<T, I>) => RT[];
|
|
49
54
|
};
|
|
50
55
|
local?: boolean;
|
|
51
|
-
remote?: boolean |
|
|
56
|
+
remote?: boolean | RemoteQueryOptions;
|
|
52
57
|
} & QueryOptions
|
|
53
58
|
) => {
|
|
54
59
|
/* ── «Item» is the concrete element type flowing through the hook ── */
|
|
@@ -67,10 +72,8 @@ export const useQuery = <
|
|
|
67
72
|
const emptyResultsRef = useRef(false);
|
|
68
73
|
const closeControllerRef = useRef<AbortController | null>(null);
|
|
69
74
|
const waitedOnceRef = useRef(false);
|
|
70
|
-
const resetResultsOnReset = useRef(true);
|
|
71
75
|
|
|
72
76
|
const [id, setId] = useState<string | undefined>(undefined);
|
|
73
|
-
const [resetCounter, invokeReset] = useReducer((n) => n + 1, 0);
|
|
74
77
|
|
|
75
78
|
const reverseRef = useRef(options?.reverse);
|
|
76
79
|
useEffect(() => {
|
|
@@ -108,19 +111,16 @@ export const useQuery = <
|
|
|
108
111
|
|
|
109
112
|
toClose?.iterator.close();
|
|
110
113
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
setAll([]);
|
|
114
|
-
}
|
|
114
|
+
allRef.current = [];
|
|
115
|
+
setAll([]);
|
|
115
116
|
|
|
116
117
|
setIsLoading(false);
|
|
117
118
|
loadingMoreRef.current = false;
|
|
118
|
-
log(
|
|
119
|
+
log("Iterator reset", toClose?.id, fromRef?.id);
|
|
119
120
|
setId(undefined);
|
|
120
121
|
};
|
|
121
122
|
|
|
122
123
|
useEffect(() => {
|
|
123
|
-
resetResultsOnReset.current = true;
|
|
124
124
|
waitedOnceRef.current = false;
|
|
125
125
|
}, [db, options?.id ?? options?.query, options?.resolve, options?.reverse]);
|
|
126
126
|
|
|
@@ -133,17 +133,33 @@ export const useQuery = <
|
|
|
133
133
|
|
|
134
134
|
const initIterator = () => {
|
|
135
135
|
let id = options?.id ?? uuid();
|
|
136
|
+
let remoteQueryOptions =
|
|
137
|
+
options.remote == null || options.remote === false
|
|
138
|
+
? false
|
|
139
|
+
: {
|
|
140
|
+
...(typeof options.remote === "object"
|
|
141
|
+
? options.remote
|
|
142
|
+
: {}),
|
|
143
|
+
joining:
|
|
144
|
+
typeof options.remote === "object" &&
|
|
145
|
+
options.remote.joining?.waitFor !== undefined
|
|
146
|
+
? {
|
|
147
|
+
waitFor:
|
|
148
|
+
options.remote.joining?.waitFor ??
|
|
149
|
+
5e3,
|
|
150
|
+
onMissedResults: ({ amount }) => {
|
|
151
|
+
loadMore(amount, true);
|
|
152
|
+
},
|
|
153
|
+
}
|
|
154
|
+
: undefined,
|
|
155
|
+
};
|
|
136
156
|
const ref = {
|
|
137
157
|
id,
|
|
138
158
|
iterator: db.index.iterate(options.query ?? {}, {
|
|
139
159
|
local: options?.local ?? true,
|
|
140
|
-
remote:
|
|
141
|
-
options.remote == null || options.remote === false
|
|
142
|
-
? false
|
|
143
|
-
: typeof options.remote === "object"
|
|
144
|
-
? options.remote
|
|
145
|
-
: true,
|
|
160
|
+
remote: remoteQueryOptions,
|
|
146
161
|
resolve: options?.resolve,
|
|
162
|
+
signal: closeControllerRef.current?.signal,
|
|
147
163
|
}) as ResultsIterator<Item>,
|
|
148
164
|
itemsConsumed: 0,
|
|
149
165
|
};
|
|
@@ -172,13 +188,7 @@ export const useQuery = <
|
|
|
172
188
|
: (c: DocumentsChange<T, I>) => c;
|
|
173
189
|
|
|
174
190
|
handleChange = async (e: CustomEvent<DocumentsChange<T, I>>) => {
|
|
175
|
-
log(
|
|
176
|
-
options,
|
|
177
|
-
"Merge change",
|
|
178
|
-
e.detail,
|
|
179
|
-
"iterator",
|
|
180
|
-
newIteratorRef.id
|
|
181
|
-
);
|
|
191
|
+
log("Merge change", e.detail, "iterator", newIteratorRef.id);
|
|
182
192
|
const filtered = await mergeFn(e.detail);
|
|
183
193
|
if (
|
|
184
194
|
!filtered ||
|
|
@@ -200,7 +210,7 @@ export const useQuery = <
|
|
|
200
210
|
options.resolve ?? true
|
|
201
211
|
);
|
|
202
212
|
|
|
203
|
-
log(
|
|
213
|
+
log("After update", allRef.current, merged);
|
|
204
214
|
const expectedDiff =
|
|
205
215
|
filtered.added.length - filtered.removed.length;
|
|
206
216
|
|
|
@@ -210,7 +220,7 @@ export const useQuery = <
|
|
|
210
220
|
merged.length === allRef.current.length)
|
|
211
221
|
) {
|
|
212
222
|
// no change
|
|
213
|
-
log(
|
|
223
|
+
log("no change after merge");
|
|
214
224
|
return;
|
|
215
225
|
}
|
|
216
226
|
}
|
|
@@ -231,7 +241,6 @@ export const useQuery = <
|
|
|
231
241
|
options?.id ?? options?.query,
|
|
232
242
|
options?.resolve,
|
|
233
243
|
options?.reverse,
|
|
234
|
-
resetCounter,
|
|
235
244
|
]);
|
|
236
245
|
|
|
237
246
|
/* ────────────── loadMore (once-wait aware) ────────────── */
|
|
@@ -250,22 +259,18 @@ export const useQuery = <
|
|
|
250
259
|
return true;
|
|
251
260
|
};
|
|
252
261
|
|
|
253
|
-
const reloadAfterTime = (): number | undefined => {
|
|
254
|
-
if (typeof options?.remote === "object" && options.remote.eager) {
|
|
255
|
-
return options.remote.warmup ?? db?.log.timeUntilRoleMaturity;
|
|
256
|
-
}
|
|
257
|
-
return undefined;
|
|
258
|
-
};
|
|
259
|
-
|
|
260
262
|
const markWaited = () => {
|
|
261
263
|
waitedOnceRef.current = true;
|
|
262
264
|
};
|
|
263
265
|
|
|
264
|
-
const loadMore = async (
|
|
266
|
+
const loadMore = async (
|
|
267
|
+
n: number = batchSize,
|
|
268
|
+
pollEvenIfWasEmpty = false
|
|
269
|
+
) => {
|
|
265
270
|
const iterator = iteratorRef.current;
|
|
266
271
|
if (
|
|
267
272
|
!iterator ||
|
|
268
|
-
emptyResultsRef.current ||
|
|
273
|
+
(emptyResultsRef.current && !pollEvenIfWasEmpty) ||
|
|
269
274
|
iterator.iterator.done() ||
|
|
270
275
|
loadingMoreRef.current
|
|
271
276
|
) {
|
|
@@ -278,59 +283,59 @@ export const useQuery = <
|
|
|
278
283
|
try {
|
|
279
284
|
/* ── optional replicate-wait ── */
|
|
280
285
|
if (shouldWait()) {
|
|
281
|
-
log(
|
|
286
|
+
log("Wait for replicators", iterator.id);
|
|
287
|
+
let t0 = Date.now();
|
|
282
288
|
|
|
283
|
-
|
|
284
|
-
typeof options?.remote === "object" && options.remote.eager;
|
|
285
|
-
const waitTimeout =
|
|
289
|
+
const warmup =
|
|
286
290
|
typeof options?.remote === "object" &&
|
|
287
291
|
typeof options?.remote.warmup === "number"
|
|
288
292
|
? options?.remote.warmup
|
|
289
|
-
:
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
await promise;
|
|
293
|
+
: undefined;
|
|
294
|
+
|
|
295
|
+
if (warmup) {
|
|
296
|
+
await db?.log
|
|
297
|
+
.waitForReplicators({
|
|
298
|
+
timeout: warmup,
|
|
299
|
+
signal: closeControllerRef.current?.signal,
|
|
300
|
+
})
|
|
301
|
+
.catch((e) => {
|
|
302
|
+
if (
|
|
303
|
+
e instanceof AbortError ||
|
|
304
|
+
e instanceof NoPeersError
|
|
305
|
+
)
|
|
306
|
+
return;
|
|
307
|
+
console.warn("Remote replicators not ready", e);
|
|
308
|
+
})
|
|
309
|
+
.finally(() => {
|
|
310
|
+
log(
|
|
311
|
+
"Wait for replicators done",
|
|
312
|
+
iterator.id,
|
|
313
|
+
"time",
|
|
314
|
+
Date.now() - t0
|
|
315
|
+
);
|
|
316
|
+
markWaited();
|
|
317
|
+
});
|
|
315
318
|
}
|
|
316
319
|
} else {
|
|
317
|
-
log(
|
|
320
|
+
log("Skip wait for replicators", iterator.id);
|
|
318
321
|
}
|
|
319
322
|
|
|
320
323
|
/* ── fetch next batch ── */
|
|
321
|
-
log(
|
|
322
|
-
|
|
324
|
+
log("Retrieve next batch", iterator.id);
|
|
325
|
+
|
|
326
|
+
let newItems = await iterator.iterator.next(n);
|
|
327
|
+
|
|
323
328
|
if (options?.transform) {
|
|
324
|
-
log(
|
|
329
|
+
log("Transform start", iterator.id);
|
|
325
330
|
|
|
326
331
|
newItems = await Promise.all(newItems.map(options.transform));
|
|
327
|
-
log(
|
|
332
|
+
log("Transform end", iterator.id);
|
|
328
333
|
}
|
|
329
334
|
|
|
330
335
|
/* iterator might have been reset while we were async… */
|
|
331
336
|
|
|
332
337
|
if (iteratorRef.current !== iterator) {
|
|
333
|
-
log(
|
|
338
|
+
log("Iterator reset while loading more");
|
|
334
339
|
return false;
|
|
335
340
|
}
|
|
336
341
|
|
|
@@ -367,7 +372,7 @@ export const useQuery = <
|
|
|
367
372
|
: [...prev, ...unique];
|
|
368
373
|
updateAll(combined);
|
|
369
374
|
} else {
|
|
370
|
-
log(
|
|
375
|
+
log("No new items", iterator.id);
|
|
371
376
|
}
|
|
372
377
|
return !iterator.iterator.done();
|
|
373
378
|
} catch (e) {
|