teamplay 0.4.0-alpha.34 → 0.4.0-alpha.36
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/orm/Compat/README.md +8 -0
- package/orm/Compat/hooksCompat.js +41 -7
- package/package.json +2 -2
package/orm/Compat/README.md
CHANGED
|
@@ -589,6 +589,9 @@ They are designed to behave close to StartupJS hooks, but adapted to Teamplay’
|
|
|
589
589
|
General notes:
|
|
590
590
|
- Hooks should be used inside `observer()` components to get reactive updates.
|
|
591
591
|
- Sync hooks (`useDoc`, `useQuery`) use Suspense by default (via `useSub`).
|
|
592
|
+
- In compatibility mode, sync hooks are strict (`defer: false`) to match racer-like
|
|
593
|
+
semantics and avoid transient `undefined` / empty snapshots during fast navigation.
|
|
594
|
+
This is enforced by compat hooks (user `defer` option is ignored for sync hooks).
|
|
592
595
|
- Async hooks (`useAsyncDoc`, `useAsyncQuery`) never throw; they return `undefined` until ready.
|
|
593
596
|
- Batch hooks use a Suspense batch barrier (`useBatch`) and wait for both
|
|
594
597
|
subscribe promises and DataTree materialization readiness.
|
|
@@ -813,6 +816,11 @@ Async variant: no Suspense, returns `undefined` until ready.
|
|
|
813
816
|
- they register a **query readiness check**:
|
|
814
817
|
query ids must be materialized in DataTree, and each `collection.id` from ids must
|
|
815
818
|
be visible in DataTree (or explicitly missing).
|
|
819
|
+
- for `$aggregate` queries, readiness is query-level:
|
|
820
|
+
DataTree must have `$queries.<hash>.docs` (array, including empty), or `extra`.
|
|
821
|
+
Aggregate rows are not required to exist as `collection.<id>` docs.
|
|
822
|
+
Presence of `$queries.<hash>.ids` alone does not mark aggregate readiness.
|
|
823
|
+
For Teamplay aggregation subscriptions, `$aggregations.<hash>` also marks readiness.
|
|
816
824
|
|
|
817
825
|
### Query Helpers
|
|
818
826
|
|
|
@@ -6,6 +6,7 @@ import { getRaw } from '../dataTree.js'
|
|
|
6
6
|
import { getConnection } from '../connection.js'
|
|
7
7
|
import { isCompatEnv } from '../compatEnv.js'
|
|
8
8
|
import { hashQuery, QUERIES } from '../Query.js'
|
|
9
|
+
import { AGGREGATIONS } from '../Aggregation.js'
|
|
9
10
|
|
|
10
11
|
const $root = getRootSignal({ rootId: GLOBAL_ROOT_ID, rootFunction: universal$ })
|
|
11
12
|
|
|
@@ -84,7 +85,7 @@ export function useBatch () {
|
|
|
84
85
|
|
|
85
86
|
export function useDoc$ (collection, id, options) {
|
|
86
87
|
const $doc = getDocSignal(collection, id, 'useDoc')
|
|
87
|
-
const normalizedOptions = options
|
|
88
|
+
const normalizedOptions = normalizeSyncSubOptions(options)
|
|
88
89
|
return useSub($doc, undefined, normalizedOptions)
|
|
89
90
|
}
|
|
90
91
|
|
|
@@ -119,14 +120,14 @@ export function useAsyncDoc (collection, id, options) {
|
|
|
119
120
|
|
|
120
121
|
export function useQuery$ (collection, query, options) {
|
|
121
122
|
const $collection = getCollectionSignal(collection, query, 'useQuery')
|
|
122
|
-
const normalizedOptions = options
|
|
123
|
+
const normalizedOptions = normalizeSyncSubOptions(options)
|
|
123
124
|
const $query = useSub($collection, normalizeQuery(query, 'useQuery'), normalizedOptions)
|
|
124
125
|
return $query
|
|
125
126
|
}
|
|
126
127
|
|
|
127
128
|
export function useQuery (collection, query, options) {
|
|
128
129
|
const $collection = getCollectionSignal(collection, query, 'useQuery')
|
|
129
|
-
const normalizedOptions = options
|
|
130
|
+
const normalizedOptions = normalizeSyncSubOptions(options)
|
|
130
131
|
const $query = useSub($collection, normalizeQuery(query, 'useQuery'), normalizedOptions)
|
|
131
132
|
return [$query.get(), $collection]
|
|
132
133
|
}
|
|
@@ -324,6 +325,18 @@ const BATCH_SUB_OPTIONS = Object.freeze({
|
|
|
324
325
|
defer: false
|
|
325
326
|
})
|
|
326
327
|
|
|
328
|
+
function normalizeSyncSubOptions (options) {
|
|
329
|
+
if (!isCompatEnv()) {
|
|
330
|
+
return options ? { ...options, async: false } : options
|
|
331
|
+
}
|
|
332
|
+
return {
|
|
333
|
+
...(options || {}),
|
|
334
|
+
async: false,
|
|
335
|
+
// Compat sync hooks are strict by design: no deferred snapshots between route/tab switches.
|
|
336
|
+
defer: false
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
327
340
|
function getDocIdFromSignal ($doc) {
|
|
328
341
|
const path = typeof $doc?.path === 'function' ? $doc.path() : ''
|
|
329
342
|
const segments = path ? path.split('.').filter(Boolean) : []
|
|
@@ -359,16 +372,26 @@ function registerBatchQueryReadinessCheck (collection, query) {
|
|
|
359
372
|
if (!collection || !query || typeof query !== 'object') return
|
|
360
373
|
const hash = hashQuery(collection, query)
|
|
361
374
|
const idsSegments = [QUERIES, hash, 'ids']
|
|
375
|
+
const docsSegments = [QUERIES, hash, 'docs']
|
|
376
|
+
const extraSegments = [QUERIES, hash, 'extra']
|
|
377
|
+
const aggregationSegments = [AGGREGATIONS, hash]
|
|
378
|
+
const isAggregate = Array.isArray(query.$aggregate)
|
|
362
379
|
promiseBatcher.addCheck({
|
|
363
380
|
key: `query:${hash}`,
|
|
364
381
|
type: 'query',
|
|
365
|
-
details: { collection, hash, query },
|
|
366
|
-
isReady: () => isQueryReady(collection, idsSegments),
|
|
382
|
+
details: { collection, hash, query, isAggregate },
|
|
383
|
+
isReady: () => isQueryReady(collection, idsSegments, docsSegments, extraSegments, aggregationSegments, isAggregate),
|
|
367
384
|
getState: () => {
|
|
368
385
|
const ids = getRaw(idsSegments)
|
|
386
|
+
const docs = getRaw(docsSegments)
|
|
387
|
+
const extra = getRaw(extraSegments)
|
|
388
|
+
const aggregation = getRaw(aggregationSegments)
|
|
369
389
|
return {
|
|
370
390
|
ids,
|
|
371
|
-
|
|
391
|
+
queryDocs: docs,
|
|
392
|
+
extra,
|
|
393
|
+
aggregation,
|
|
394
|
+
idMaterialization: Array.isArray(ids)
|
|
372
395
|
? ids.map(id => ({
|
|
373
396
|
id,
|
|
374
397
|
raw: getRaw([collection, id])
|
|
@@ -379,10 +402,17 @@ function registerBatchQueryReadinessCheck (collection, query) {
|
|
|
379
402
|
})
|
|
380
403
|
}
|
|
381
404
|
|
|
382
|
-
function isQueryReady (collection, idsSegments) {
|
|
405
|
+
function isQueryReady (collection, idsSegments, docsSegments, extraSegments, aggregationSegments, isAggregate) {
|
|
406
|
+
if (isAggregate) {
|
|
407
|
+
const docs = getRaw(docsSegments)
|
|
408
|
+
if (Array.isArray(docs)) return true
|
|
409
|
+
if (getRaw(extraSegments) !== undefined) return true
|
|
410
|
+
return getRaw(aggregationSegments) !== undefined
|
|
411
|
+
}
|
|
383
412
|
const ids = getRaw(idsSegments)
|
|
384
413
|
if (!Array.isArray(ids)) return false
|
|
385
414
|
for (const id of ids) {
|
|
415
|
+
if (id == null) continue
|
|
386
416
|
if (!isDocReady([collection, id])) return false
|
|
387
417
|
}
|
|
388
418
|
return true
|
|
@@ -404,3 +434,7 @@ function getShareDoc (collection, id) {
|
|
|
404
434
|
return undefined
|
|
405
435
|
}
|
|
406
436
|
}
|
|
437
|
+
|
|
438
|
+
export const __COMPAT_BATCH_READY__ = {
|
|
439
|
+
isQueryReady
|
|
440
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "teamplay",
|
|
3
|
-
"version": "0.4.0-alpha.
|
|
3
|
+
"version": "0.4.0-alpha.36",
|
|
4
4
|
"description": "Full-stack signals ORM with multiplayer",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
]
|
|
82
82
|
},
|
|
83
83
|
"license": "MIT",
|
|
84
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "0f90958b39502634ec8fefc99d7e688f0ac4c4bc"
|
|
85
85
|
}
|