@pylonsync/react 0.3.200 → 0.3.202
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 +3 -3
- package/src/hooks.ts +32 -4
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.3.
|
|
6
|
+
"version": "0.3.202",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "src/index.ts",
|
|
9
9
|
"types": "src/index.ts",
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
"check": "tsc -p tsconfig.json --noEmit"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@pylonsync/sdk": "0.3.
|
|
16
|
-
"@pylonsync/sync": "0.3.
|
|
15
|
+
"@pylonsync/sdk": "0.3.202",
|
|
16
|
+
"@pylonsync/sync": "0.3.202"
|
|
17
17
|
},
|
|
18
18
|
"peerDependencies": {
|
|
19
19
|
"react": ">=19.0.0"
|
package/src/hooks.ts
CHANGED
|
@@ -74,7 +74,15 @@ export function useQuery<T = Row>(
|
|
|
74
74
|
entity: string,
|
|
75
75
|
options?: QueryOptions
|
|
76
76
|
): UseQueryReturn<T> {
|
|
77
|
-
|
|
77
|
+
// `loading` is true only while we genuinely don't know yet — i.e.,
|
|
78
|
+
// the engine hasn't drained IndexedDB into the in-memory store. Once
|
|
79
|
+
// hydrated, an empty list is a real empty (not "still fetching"), so
|
|
80
|
+
// refreshes with cached data don't flash "Loading…" before the rows
|
|
81
|
+
// render. The engine's `isHydrated()` exposes a synchronous gate that
|
|
82
|
+
// flips true after `loadAllEntities()` settles.
|
|
83
|
+
const loading = useRef<boolean>(
|
|
84
|
+
!sync.isHydrated() && sync.store.list(entity).length === 0,
|
|
85
|
+
);
|
|
78
86
|
const error = useRef<Error | null>(null);
|
|
79
87
|
const optionsKey = JSON.stringify(options || {});
|
|
80
88
|
|
|
@@ -104,7 +112,16 @@ export function useQuery<T = Row>(
|
|
|
104
112
|
if (sig !== snapshotCache.current.sig) {
|
|
105
113
|
snapshotCache.current = { rows: filtered as T[], sig };
|
|
106
114
|
}
|
|
107
|
-
|
|
115
|
+
// Loading is false the moment hydration finishes — even when the
|
|
116
|
+
// disk replica is empty (a real "no rows yet" state, not "still
|
|
117
|
+
// fetching"). The previous gate only flipped when rows arrived,
|
|
118
|
+
// so an entity with zero cached rows stayed in loading=true
|
|
119
|
+
// forever until a server pull / WS event populated it. After:
|
|
120
|
+
// hydration completion fires store.notify() → getSnapshot re-runs
|
|
121
|
+
// → loading goes false immediately, the empty state renders.
|
|
122
|
+
if (loading.current && (rows.length > 0 || sync.isHydrated())) {
|
|
123
|
+
loading.current = false;
|
|
124
|
+
}
|
|
108
125
|
return snapshotCache.current.rows;
|
|
109
126
|
}, [sync, entity, optionsKey, options]);
|
|
110
127
|
|
|
@@ -140,7 +157,12 @@ export function useQueryOne<T = Row>(
|
|
|
140
157
|
entity: string,
|
|
141
158
|
id: string
|
|
142
159
|
): UseQueryOneReturn<T> {
|
|
143
|
-
|
|
160
|
+
// Same hydration-aware loading semantics as useQuery — see the
|
|
161
|
+
// comment there. Without this, a refreshed page flashes "Loading…"
|
|
162
|
+
// for the row even when it's already in IndexedDB.
|
|
163
|
+
const loading = useRef<boolean>(
|
|
164
|
+
!sync.isHydrated() && sync.store.get(entity, id) === null,
|
|
165
|
+
);
|
|
144
166
|
const error = useRef<Error | null>(null);
|
|
145
167
|
|
|
146
168
|
const subscribe = useMemo(
|
|
@@ -165,7 +187,13 @@ export function useQueryOne<T = Row>(
|
|
|
165
187
|
if (sig !== snapshotCache.current.sig) {
|
|
166
188
|
snapshotCache.current = { row: (row as T) ?? null, sig };
|
|
167
189
|
}
|
|
168
|
-
|
|
190
|
+
// Mirror useQuery: loading flips false on hydration completion
|
|
191
|
+
// even when the row is missing (not "still fetching" — genuinely
|
|
192
|
+
// not present yet). Without the isHydrated() check, a missing
|
|
193
|
+
// row stuck loading=true forever.
|
|
194
|
+
if (loading.current && (row !== null || sync.isHydrated())) {
|
|
195
|
+
loading.current = false;
|
|
196
|
+
}
|
|
169
197
|
return snapshotCache.current.row;
|
|
170
198
|
}, [sync, entity, id]);
|
|
171
199
|
|