@contember/bindx-react 0.1.51 → 0.1.53
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.
|
@@ -54,8 +54,10 @@ export type NotFoundEntityResult = UseEntityResultBase & {
|
|
|
54
54
|
/**
|
|
55
55
|
* Ready state — full EntityAccessor with status metadata.
|
|
56
56
|
*
|
|
57
|
-
* `$isRefetching` is `true` while
|
|
58
|
-
*
|
|
57
|
+
* `$isRefetching` is `true` while the data answers an earlier query: from the re-fetch
|
|
58
|
+
* that a `queryKey` change starts, while ready data is already present, until its result
|
|
59
|
+
* arrives. Unlike `useEntityList`, the flag turns on when the re-fetch starts, one render
|
|
60
|
+
* after the change, not on the render that changes the query.
|
|
59
61
|
* The accessor identity and field values remain stable until the new data
|
|
60
62
|
* arrives, so the subtree does not unmount — useful for stale-while-revalidate
|
|
61
63
|
* indicators (subtle spinner, "stale" badge, etc.).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEntity.d.ts","sourceRoot":"","sources":["../../src/hooks/useEntity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,SAAS,EACT,iBAAiB,EAEjB,cAAc,EACd,aAAa,EACb,UAAU,EAIV,YAAY,EACZ,cAAc,EACd,SAAS,EACT,cAAc,EACd,MAAM,kBAAkB,CAAA;AAgBzB;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC,sFAAsF;IACtF,EAAE,EAAE,iBAAiB,CAAA;IACrB,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;OAIG;IACH,SAAS,CAAC,EAAE,aAAa,CAAA;IACzB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAA;CACjB;AAMD;;;GAGG;AACH,UAAU,mBAAmB;IAC5B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB,MAAM,IAAI,IAAI,CAAA;CACd;AAED,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,GAAG;IACvD,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAA;IACzB,QAAQ,CAAC,aAAa,EAAE,KAAK,CAAA;IAC7B,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG,mBAAmB,GAAG;IACrD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAA;IAC1B,QAAQ,CAAC,aAAa,EAAE,KAAK,CAAA;IAC7B,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAA;IACvB,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,mBAAmB,GAAG;IACxD,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAA;IAC1B,QAAQ,CAAC,aAAa,EAAE,KAAK,CAAA;IAC7B,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CACnB,CAAA;AAED
|
|
1
|
+
{"version":3,"file":"useEntity.d.ts","sourceRoot":"","sources":["../../src/hooks/useEntity.ts"],"names":[],"mappings":"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"}
|
|
@@ -40,8 +40,8 @@ export type ErrorEntityListResult = EntityListResultBase & {
|
|
|
40
40
|
readonly $error: FieldError;
|
|
41
41
|
};
|
|
42
42
|
/**
|
|
43
|
-
* `$isRefetching` is `true` while
|
|
44
|
-
*
|
|
43
|
+
* `$isRefetching` is `true` while the items answer an earlier query: from the render
|
|
44
|
+
* that changes the options or the `queryKey` until the re-fetch returns.
|
|
45
45
|
* The accessor identity stays stable so the subtree does not unmount —
|
|
46
46
|
* stale-while-revalidate semantics.
|
|
47
47
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEntityList.d.ts","sourceRoot":"","sources":["../../src/hooks/useEntityList.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,UAAU,EAAkB,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAUrK;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,+BAA+B;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,wBAAwB;IACxB,OAAO,CAAC,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IAC5C,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,sBAAsB;IACtB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;OAIG;IACH,SAAS,CAAC,EAAE,aAAa,CAAA;IACzB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAA;CACjB;AAMD,UAAU,oBAAoB;IAC7B,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IAC5B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/C;AAED,MAAM,MAAM,uBAAuB,GAAG,oBAAoB,GAAG;IAC5D,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAA;IACzB,QAAQ,CAAC,aAAa,EAAE,KAAK,CAAA;IAC7B,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,oBAAoB,GAAG;IAC1D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAA;IAC1B,QAAQ,CAAC,aAAa,EAAE,KAAK,CAAA;IAC7B,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;CAC3B,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,MAAM,IAAI,oBAAoB,GAAG;IAC5E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAA;IAC1B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAA;IACxC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,MAAM,IAC7C,uBAAuB,GACvB,qBAAqB,GACrB,qBAAqB,CAAC,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"useEntityList.d.ts","sourceRoot":"","sources":["../../src/hooks/useEntityList.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contember/bindx-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.53",
|
|
4
4
|
"description": "Type-safe React data binding framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"react": ">=18.0.0"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@contember/bindx": "0.1.
|
|
19
|
-
"@contember/bindx-client": "0.1.
|
|
18
|
+
"@contember/bindx": "0.1.53",
|
|
19
|
+
"@contember/bindx-client": "0.1.53",
|
|
20
20
|
"@contember/graphql-client": "^2.1.0-beta.1",
|
|
21
21
|
"@radix-ui/primitive": "^1.1.3",
|
|
22
22
|
"@radix-ui/react-slot": "^1.2.4"
|
package/src/hooks/useEntity.ts
CHANGED
|
@@ -93,8 +93,10 @@ export type NotFoundEntityResult = UseEntityResultBase & {
|
|
|
93
93
|
/**
|
|
94
94
|
* Ready state — full EntityAccessor with status metadata.
|
|
95
95
|
*
|
|
96
|
-
* `$isRefetching` is `true` while
|
|
97
|
-
*
|
|
96
|
+
* `$isRefetching` is `true` while the data answers an earlier query: from the re-fetch
|
|
97
|
+
* that a `queryKey` change starts, while ready data is already present, until its result
|
|
98
|
+
* arrives. Unlike `useEntityList`, the flag turns on when the re-fetch starts, one render
|
|
99
|
+
* after the change, not on the render that changes the query.
|
|
98
100
|
* The accessor identity and field values remain stable until the new data
|
|
99
101
|
* arrives, so the subtree does not unmount — useful for stale-while-revalidate
|
|
100
102
|
* indicators (subtle spinner, "stale" badge, etc.).
|
|
@@ -290,12 +292,14 @@ export function useEntity(
|
|
|
290
292
|
if (result.type === 'get' && result.data === null) {
|
|
291
293
|
dispatcher.dispatch(setLoadState(entityType, id, 'not_found'))
|
|
292
294
|
} else if (result.type === 'get' && result.data) {
|
|
295
|
+
store.indexServerResponse(entityType, result.data, selectionMeta, schemaRegistry)
|
|
296
|
+
const data = store.resolveServerOccurrence(result.data)
|
|
293
297
|
// Revalidation: advance the server baseline but keep local dirty
|
|
294
298
|
// edits intact (see EntitySnapshotStore.refreshServerData).
|
|
295
|
-
|
|
296
|
-
refreshServerData(entityType, id,
|
|
297
|
-
|
|
298
|
-
|
|
299
|
+
store.batchNotifications(() => {
|
|
300
|
+
dispatcher.dispatch(refreshServerData(entityType, id, data))
|
|
301
|
+
dispatcher.dispatch(setLoadState(entityType, id, 'success'))
|
|
302
|
+
})
|
|
299
303
|
}
|
|
300
304
|
} catch (error) {
|
|
301
305
|
if (abortController.signal.aborted) return
|
|
@@ -320,7 +324,7 @@ export function useEntity(
|
|
|
320
324
|
fetchingRef.current = null
|
|
321
325
|
}
|
|
322
326
|
}
|
|
323
|
-
}, [entityType, id, byKey, effectiveQueryKey, options.cache, batcher, store, dispatcher, selectionMeta])
|
|
327
|
+
}, [entityType, id, byKey, effectiveQueryKey, options.cache, batcher, store, dispatcher, selectionMeta, schemaRegistry])
|
|
324
328
|
|
|
325
329
|
// --- EntityHandle ---
|
|
326
330
|
// The handle keeps a stable identity across data changes — it is a stateless live view over the
|
|
@@ -58,8 +58,8 @@ export type ErrorEntityListResult = EntityListResultBase & {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
|
-
* `$isRefetching` is `true` while
|
|
62
|
-
*
|
|
61
|
+
* `$isRefetching` is `true` while the items answer an earlier query: from the render
|
|
62
|
+
* that changes the options or the `queryKey` until the re-fetch returns.
|
|
63
63
|
* The accessor identity stays stable so the subtree does not unmount —
|
|
64
64
|
* stale-while-revalidate semantics.
|
|
65
65
|
*/
|
|
@@ -96,6 +96,12 @@ function createLoadingListResult(): LoadingEntityListResult {
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
function getRowId(entityType: string, row: Record<string, unknown>): string {
|
|
100
|
+
const id = row['id']
|
|
101
|
+
if (typeof id !== 'string') throw new Error(`${entityType} list row has no string id`)
|
|
102
|
+
return id
|
|
103
|
+
}
|
|
104
|
+
|
|
99
105
|
function createErrorListResult(error: FieldError): ErrorEntityListResult {
|
|
100
106
|
return {
|
|
101
107
|
$status: 'error',
|
|
@@ -211,16 +217,24 @@ export function useEntityList(
|
|
|
211
217
|
return `${entityType}:${selectionContentKey}`
|
|
212
218
|
}, [options.queryKey, selectionContentKey, entityType])
|
|
213
219
|
|
|
220
|
+
const requestKey = useMemo(
|
|
221
|
+
() => JSON.stringify([effectiveQueryKey, optionsKey]),
|
|
222
|
+
[effectiveQueryKey, optionsKey],
|
|
223
|
+
)
|
|
224
|
+
|
|
214
225
|
// --- List state tracking ---
|
|
215
226
|
const listStateRef = useRef<{
|
|
216
227
|
status: 'loading' | 'error' | 'ready'
|
|
217
228
|
items: Array<{ id: string; data: object }>
|
|
218
229
|
error?: FieldError
|
|
219
230
|
isRefetching: boolean
|
|
231
|
+
/** The request the items were loaded for. */
|
|
232
|
+
requestKey: string | null
|
|
220
233
|
}>({
|
|
221
234
|
status: 'loading',
|
|
222
235
|
items: [],
|
|
223
236
|
isRefetching: false,
|
|
237
|
+
requestKey: null,
|
|
224
238
|
})
|
|
225
239
|
|
|
226
240
|
const versionRef = useRef(0)
|
|
@@ -344,6 +358,9 @@ export function useEntityList(
|
|
|
344
358
|
const state = listStateRef.current
|
|
345
359
|
const version = versionRef.current
|
|
346
360
|
const storeVersion = store.getVersion()
|
|
361
|
+
// Until the data-loading effect marks the refetch, the items of the previous request are
|
|
362
|
+
// already stale on the render that changed it.
|
|
363
|
+
const isRefetching = state.isRefetching || state.requestKey !== requestKey
|
|
347
364
|
|
|
348
365
|
const cache = listCacheRef.current
|
|
349
366
|
if (
|
|
@@ -351,7 +368,7 @@ export function useEntityList(
|
|
|
351
368
|
cache.version === version &&
|
|
352
369
|
cache.storeVersion === storeVersion &&
|
|
353
370
|
cache.status === state.status &&
|
|
354
|
-
cache.isRefetching ===
|
|
371
|
+
cache.isRefetching === isRefetching &&
|
|
355
372
|
cache.accessorCache === itemAccessorCache
|
|
356
373
|
) {
|
|
357
374
|
return cache.result
|
|
@@ -376,7 +393,7 @@ export function useEntityList(
|
|
|
376
393
|
result = {
|
|
377
394
|
$status: 'ready',
|
|
378
395
|
$isLoading: false,
|
|
379
|
-
$isRefetching:
|
|
396
|
+
$isRefetching: isRefetching,
|
|
380
397
|
$isError: false,
|
|
381
398
|
$error: null,
|
|
382
399
|
$isDirty: false,
|
|
@@ -392,13 +409,13 @@ export function useEntityList(
|
|
|
392
409
|
version,
|
|
393
410
|
storeVersion,
|
|
394
411
|
status: state.status,
|
|
395
|
-
isRefetching
|
|
412
|
+
isRefetching,
|
|
396
413
|
accessorCache: itemAccessorCache,
|
|
397
414
|
result,
|
|
398
415
|
}
|
|
399
416
|
|
|
400
417
|
return result
|
|
401
|
-
}, [store, itemAccessorCache, addItem, removeItem, moveItem, resolveItemId])
|
|
418
|
+
}, [store, requestKey, itemAccessorCache, addItem, removeItem, moveItem, resolveItemId])
|
|
402
419
|
|
|
403
420
|
const isEqual = useCallback(
|
|
404
421
|
(a: UseEntityListResult<any>, b: UseEntityListResult<any>): boolean => {
|
|
@@ -423,7 +440,7 @@ export function useEntityList(
|
|
|
423
440
|
if (prev.status === 'ready') {
|
|
424
441
|
listStateRef.current = { ...prev, isRefetching: true }
|
|
425
442
|
} else {
|
|
426
|
-
listStateRef.current = { status: 'loading', items: [], isRefetching: false }
|
|
443
|
+
listStateRef.current = { status: 'loading', items: [], isRefetching: false, requestKey: null }
|
|
427
444
|
}
|
|
428
445
|
versionRef.current++
|
|
429
446
|
store.notify()
|
|
@@ -456,19 +473,17 @@ export function useEntityList(
|
|
|
456
473
|
throw new Error('Unexpected query result type')
|
|
457
474
|
}
|
|
458
475
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
refreshServerData(entityType, id, data)
|
|
465
|
-
|
|
466
|
-
|
|
476
|
+
store.indexServerResponse(entityType, result.data, selectionMeta, schemaRegistry)
|
|
477
|
+
const items = result.data.map(data => ({ id: getRowId(entityType, data), data: store.resolveServerOccurrence(data) }))
|
|
478
|
+
store.batchNotifications(() => {
|
|
479
|
+
for (const item of items) {
|
|
480
|
+
// Revalidation preserves local edits while advancing the server baseline.
|
|
481
|
+
dispatcher.dispatch(refreshServerData(entityType, item.id, item.data))
|
|
482
|
+
}
|
|
483
|
+
listStateRef.current = { status: 'ready', items, isRefetching: false, requestKey }
|
|
484
|
+
versionRef.current++
|
|
485
|
+
store.notify()
|
|
467
486
|
})
|
|
468
|
-
|
|
469
|
-
listStateRef.current = { status: 'ready', items, isRefetching: false }
|
|
470
|
-
versionRef.current++
|
|
471
|
-
store.notify()
|
|
472
487
|
} catch (error) {
|
|
473
488
|
if (abortController.signal.aborted) return
|
|
474
489
|
|
|
@@ -478,6 +493,7 @@ export function useEntityList(
|
|
|
478
493
|
items: [],
|
|
479
494
|
error: createLoadError(normalizedError),
|
|
480
495
|
isRefetching: false,
|
|
496
|
+
requestKey,
|
|
481
497
|
}
|
|
482
498
|
versionRef.current++
|
|
483
499
|
store.notify()
|
|
@@ -489,7 +505,7 @@ export function useEntityList(
|
|
|
489
505
|
return () => {
|
|
490
506
|
abortController.abort()
|
|
491
507
|
}
|
|
492
|
-
}, [entityType, optionsKey,
|
|
508
|
+
}, [entityType, optionsKey, requestKey, batcher, dispatcher, store, selectionMeta, schemaRegistry])
|
|
493
509
|
|
|
494
510
|
return accessor
|
|
495
511
|
}
|