teamplay 0.4.0-alpha.76 → 0.4.0-alpha.78
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/SignalCompat.js +16 -5
- package/orm/Compat/hooksCompat.js +1 -47
- package/orm/Compat/queryReadiness.js +165 -0
- package/orm/SignalBase.js +12 -19
- package/orm/dataTree.js +3 -3
- package/orm/idFields.js +33 -2
- package/package.json +2 -2
|
@@ -13,7 +13,7 @@ import { publicOnly, fetchOnly, setFetchOnly } from '../connection.js'
|
|
|
13
13
|
import { docSubscriptions } from '../Doc.js'
|
|
14
14
|
import { IS_QUERY, getQuerySignal, querySubscriptions } from '../Query.js'
|
|
15
15
|
import { IS_AGGREGATION, aggregationSubscriptions, getAggregationSignal } from '../Aggregation.js'
|
|
16
|
-
import { getIdFieldsForSegments, isIdFieldPath, normalizeIdFields, isPlainObject } from '../idFields.js'
|
|
16
|
+
import { getIdFieldsForSegments, isIdFieldPath, isPublicDocPath, normalizeIdFields, isPlainObject } from '../idFields.js'
|
|
17
17
|
import {
|
|
18
18
|
del as _del,
|
|
19
19
|
setReplace as _setReplace,
|
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
stringRemovePublic as _stringRemovePublic
|
|
39
39
|
} from '../dataTree.js'
|
|
40
40
|
import { on as onCustomEvent, removeListener as removeCustomEventListener } from './eventsCompat.js'
|
|
41
|
+
import { waitForImperativeQueryReady } from './queryReadiness.js'
|
|
41
42
|
import { normalizePattern, onModelEvent, removeModelListener } from './modelEvents.js'
|
|
42
43
|
import { setRefLink, removeRefLink, getRefLinks } from './refRegistry.js'
|
|
43
44
|
import { REF_TARGET, resolveRefSignalSafe, resolveRefSegmentsSafe } from './refFallback.js'
|
|
@@ -1014,7 +1015,7 @@ function setReplacePrivateCompatSync ($signal, value) {
|
|
|
1014
1015
|
if (segments.length === 0) throw Error('Can\'t set the root signal data')
|
|
1015
1016
|
const idFields = getIdFieldsForSegments(segments)
|
|
1016
1017
|
if (isIdFieldPath(segments, idFields)) return
|
|
1017
|
-
if (segments
|
|
1018
|
+
if (isPublicDocPath(segments)) {
|
|
1018
1019
|
value = normalizeIdFields(value, idFields, segments[1])
|
|
1019
1020
|
}
|
|
1020
1021
|
_setReplace(segments, value)
|
|
@@ -1064,7 +1065,7 @@ async function setReplaceOnSignal ($signal, value) {
|
|
|
1064
1065
|
if (segments.length === 0) throw Error('Can\'t set the root signal data')
|
|
1065
1066
|
const idFields = getIdFieldsForSegments(segments)
|
|
1066
1067
|
if (isIdFieldPath(segments, idFields)) return
|
|
1067
|
-
if (segments
|
|
1068
|
+
if (isPublicDocPath(segments)) {
|
|
1068
1069
|
value = normalizeIdFields(value, idFields, segments[1])
|
|
1069
1070
|
}
|
|
1070
1071
|
if (isPublicCollection(segments[0])) {
|
|
@@ -1284,8 +1285,18 @@ function flattenItems (items, result = []) {
|
|
|
1284
1285
|
}
|
|
1285
1286
|
|
|
1286
1287
|
function subscribeSelf ($signal) {
|
|
1287
|
-
if ($signal[IS_QUERY])
|
|
1288
|
-
|
|
1288
|
+
if ($signal[IS_QUERY]) {
|
|
1289
|
+
return (async () => {
|
|
1290
|
+
await querySubscriptions.subscribe($signal)
|
|
1291
|
+
await waitForImperativeQueryReady($signal)
|
|
1292
|
+
})()
|
|
1293
|
+
}
|
|
1294
|
+
if ($signal[IS_AGGREGATION]) {
|
|
1295
|
+
return (async () => {
|
|
1296
|
+
await aggregationSubscriptions.subscribe($signal)
|
|
1297
|
+
await waitForImperativeQueryReady($signal)
|
|
1298
|
+
})()
|
|
1299
|
+
}
|
|
1289
1300
|
if (isPublicDocumentSignal($signal)) return docSubscriptions.subscribe($signal)
|
|
1290
1301
|
if (isPublicCollectionSignal($signal)) {
|
|
1291
1302
|
throw Error('Signal.subscribe() expects a query signal. Use .query() for collections.')
|
|
@@ -2,10 +2,8 @@ import { getRootSignal, GLOBAL_ROOT_ID } from '../Root.js'
|
|
|
2
2
|
import useSub, { useAsyncSub } from '../../react/useSub.js'
|
|
3
3
|
import universal$ from '../../react/universal$.js'
|
|
4
4
|
import * as promiseBatcher from '../../react/promiseBatcher.js'
|
|
5
|
-
import { getRaw } from '../dataTree.js'
|
|
6
|
-
import { getConnection } from '../connection.js'
|
|
7
5
|
import { isCompatEnv } from '../compatEnv.js'
|
|
8
|
-
import {
|
|
6
|
+
import { isQueryReady } from './queryReadiness.js'
|
|
9
7
|
|
|
10
8
|
const $root = getRootSignal({ rootId: GLOBAL_ROOT_ID, rootFunction: universal$ })
|
|
11
9
|
const emittedCompatWarnings = new Set()
|
|
@@ -361,50 +359,6 @@ function normalizeSyncSubOptions (options) {
|
|
|
361
359
|
}
|
|
362
360
|
}
|
|
363
361
|
|
|
364
|
-
function isQueryReady (
|
|
365
|
-
collection,
|
|
366
|
-
idsSegments,
|
|
367
|
-
docsSegments,
|
|
368
|
-
extraSegments,
|
|
369
|
-
aggregationSegments,
|
|
370
|
-
isAggregate,
|
|
371
|
-
hasExtraResult
|
|
372
|
-
) {
|
|
373
|
-
if (hasExtraResult) {
|
|
374
|
-
return getRaw(extraSegments) !== undefined
|
|
375
|
-
}
|
|
376
|
-
if (isAggregate) {
|
|
377
|
-
const docs = getRaw(docsSegments)
|
|
378
|
-
if (Array.isArray(docs)) return true
|
|
379
|
-
if (getRaw(extraSegments) !== undefined) return true
|
|
380
|
-
return getRaw(aggregationSegments) !== undefined
|
|
381
|
-
}
|
|
382
|
-
const ids = getRaw(idsSegments)
|
|
383
|
-
if (!Array.isArray(ids)) return false
|
|
384
|
-
for (const id of ids) {
|
|
385
|
-
if (id == null) continue
|
|
386
|
-
if (!isDocReady([collection, id])) return false
|
|
387
|
-
}
|
|
388
|
-
return true
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
function isDocReady (segments) {
|
|
392
|
-
const rawDoc = getRaw(segments)
|
|
393
|
-
if (rawDoc !== undefined) return true
|
|
394
|
-
const [collection, id] = segments
|
|
395
|
-
const shareDoc = getShareDoc(collection, id)
|
|
396
|
-
// Missing docs should not block the batch barrier forever.
|
|
397
|
-
return isMissingShareDoc(shareDoc)
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
function getShareDoc (collection, id) {
|
|
401
|
-
try {
|
|
402
|
-
return getConnection().get(collection, id)
|
|
403
|
-
} catch {
|
|
404
|
-
return undefined
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
|
|
408
362
|
export const __COMPAT_BATCH_READY__ = {
|
|
409
363
|
isQueryReady
|
|
410
364
|
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { getRaw, set as _set } from '../dataTree.js'
|
|
2
|
+
import { getConnection } from '../connection.js'
|
|
3
|
+
import { isMissingShareDoc } from '../missingDoc.js'
|
|
4
|
+
import { QUERIES, HASH, PARAMS, COLLECTION_NAME } from '../Query.js'
|
|
5
|
+
import { AGGREGATIONS, IS_AGGREGATION } from '../Aggregation.js'
|
|
6
|
+
|
|
7
|
+
let imperativeQueryReadyTimeoutMs = 1000
|
|
8
|
+
|
|
9
|
+
export function isQueryReady (
|
|
10
|
+
collection,
|
|
11
|
+
idsSegments,
|
|
12
|
+
docsSegments,
|
|
13
|
+
extraSegments,
|
|
14
|
+
aggregationSegments,
|
|
15
|
+
isAggregate,
|
|
16
|
+
hasExtraResult
|
|
17
|
+
) {
|
|
18
|
+
if (hasExtraResult) {
|
|
19
|
+
return getRaw(extraSegments) !== undefined
|
|
20
|
+
}
|
|
21
|
+
if (isAggregate) {
|
|
22
|
+
const docs = getRaw(docsSegments)
|
|
23
|
+
if (Array.isArray(docs)) return true
|
|
24
|
+
if (getRaw(extraSegments) !== undefined) return true
|
|
25
|
+
return getRaw(aggregationSegments) !== undefined
|
|
26
|
+
}
|
|
27
|
+
const ids = getRaw(idsSegments)
|
|
28
|
+
if (!Array.isArray(ids)) return false
|
|
29
|
+
for (const id of ids) {
|
|
30
|
+
if (id == null) continue
|
|
31
|
+
if (!isDocReady([collection, id])) return false
|
|
32
|
+
}
|
|
33
|
+
return true
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function isDocReady (segments) {
|
|
37
|
+
const rawDoc = getRaw(segments)
|
|
38
|
+
if (rawDoc !== undefined) return true
|
|
39
|
+
const [collection, id] = segments
|
|
40
|
+
const shareDoc = getShareDoc(collection, id)
|
|
41
|
+
// Missing docs should not block the batch barrier forever.
|
|
42
|
+
return isMissingShareDoc(shareDoc)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export async function waitForImperativeQueryReady ($query) {
|
|
46
|
+
const timeoutMs = imperativeQueryReadyTimeoutMs
|
|
47
|
+
const startedAt = Date.now()
|
|
48
|
+
while (true) {
|
|
49
|
+
if (isImperativeQueryReady($query)) {
|
|
50
|
+
syncQueryDocsFromCollection($query)
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
if (Date.now() - startedAt >= timeoutMs) {
|
|
54
|
+
throw createImperativeQueryReadinessError($query, timeoutMs)
|
|
55
|
+
}
|
|
56
|
+
await new Promise(resolve => setTimeout(resolve, 0))
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function __setImperativeQueryReadyTimeoutForTests (timeoutMs) {
|
|
61
|
+
imperativeQueryReadyTimeoutMs = timeoutMs
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function __resetImperativeQueryReadyTimeoutForTests () {
|
|
65
|
+
imperativeQueryReadyTimeoutMs = 1000
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function isImperativeQueryReady ($query) {
|
|
69
|
+
const collection = $query[COLLECTION_NAME]
|
|
70
|
+
const hash = $query[HASH]
|
|
71
|
+
const params = $query[PARAMS]
|
|
72
|
+
const hasExtraResult = isExtraQuery(params)
|
|
73
|
+
if (hasExtraResult) return getRaw([QUERIES, hash, 'extra']) !== undefined
|
|
74
|
+
|
|
75
|
+
const isAggregate = !!$query[IS_AGGREGATION] || isAggregationQuery(params)
|
|
76
|
+
if (isAggregate) {
|
|
77
|
+
return isQueryReady(
|
|
78
|
+
collection,
|
|
79
|
+
[QUERIES, hash, 'ids'],
|
|
80
|
+
[QUERIES, hash, 'docs'],
|
|
81
|
+
[QUERIES, hash, 'extra'],
|
|
82
|
+
[AGGREGATIONS, hash],
|
|
83
|
+
true,
|
|
84
|
+
false
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const ids = getRaw([QUERIES, hash, 'ids'])
|
|
89
|
+
if (!Array.isArray(ids)) return false
|
|
90
|
+
for (const id of ids) {
|
|
91
|
+
if (id == null) continue
|
|
92
|
+
if (getRaw([collection, id]) === undefined) return false
|
|
93
|
+
}
|
|
94
|
+
return true
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function syncQueryDocsFromCollection ($query) {
|
|
98
|
+
const params = $query[PARAMS]
|
|
99
|
+
if ($query[IS_AGGREGATION] || isAggregationQuery(params) || isExtraQuery(params)) return
|
|
100
|
+
|
|
101
|
+
const collection = $query[COLLECTION_NAME]
|
|
102
|
+
const hash = $query[HASH]
|
|
103
|
+
const ids = getRaw([QUERIES, hash, 'ids'])
|
|
104
|
+
if (!Array.isArray(ids)) return
|
|
105
|
+
|
|
106
|
+
const docs = []
|
|
107
|
+
for (const id of ids) {
|
|
108
|
+
if (id == null) continue
|
|
109
|
+
const doc = getRaw([collection, id])
|
|
110
|
+
if (doc === undefined) {
|
|
111
|
+
throw createImperativeQueryReadinessError($query, imperativeQueryReadyTimeoutMs)
|
|
112
|
+
}
|
|
113
|
+
docs.push(doc)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
_set([QUERIES, hash, 'docs'], docs)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function createImperativeQueryReadinessError ($query, timeoutMs) {
|
|
120
|
+
const collection = $query[COLLECTION_NAME]
|
|
121
|
+
const hash = $query[HASH]
|
|
122
|
+
const params = $query[PARAMS]
|
|
123
|
+
const ids = getRaw([QUERIES, hash, 'ids'])
|
|
124
|
+
const missingDocs = []
|
|
125
|
+
|
|
126
|
+
if (Array.isArray(ids)) {
|
|
127
|
+
for (const id of ids) {
|
|
128
|
+
if (id == null) continue
|
|
129
|
+
const doc = getRaw([collection, id])
|
|
130
|
+
if (doc !== undefined) continue
|
|
131
|
+
const shareDoc = getShareDoc(collection, id)
|
|
132
|
+
missingDocs.push({
|
|
133
|
+
id,
|
|
134
|
+
missingShareDoc: isMissingShareDoc(shareDoc)
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return Error(`
|
|
140
|
+
Compat query did not fully materialize within ${timeoutMs}ms.
|
|
141
|
+
Collection: ${collection}
|
|
142
|
+
Params: ${JSON.stringify(params)}
|
|
143
|
+
Hash: ${hash}
|
|
144
|
+
Ids: ${JSON.stringify(ids)}
|
|
145
|
+
Missing docs: ${JSON.stringify(missingDocs)}
|
|
146
|
+
`)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function getShareDoc (collection, id) {
|
|
150
|
+
try {
|
|
151
|
+
return getConnection().get(collection, id)
|
|
152
|
+
} catch {
|
|
153
|
+
return undefined
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function isExtraQuery (query) {
|
|
158
|
+
if (!query || typeof query !== 'object') return false
|
|
159
|
+
return !!(query.$count || query.$queryName)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function isAggregationQuery (query) {
|
|
163
|
+
if (!query || typeof query !== 'object') return false
|
|
164
|
+
return !!(query.$aggregate || query.$aggregationName)
|
|
165
|
+
}
|
package/orm/SignalBase.js
CHANGED
|
@@ -45,7 +45,15 @@ import { IS_QUERY, HASH, QUERIES } from './Query.js'
|
|
|
45
45
|
import { AGGREGATIONS, IS_AGGREGATION, getAggregationCollectionName, getAggregationDocId } from './Aggregation.js'
|
|
46
46
|
import { ROOT_FUNCTION, getRoot } from './Root.js'
|
|
47
47
|
import { publicOnly } from './connection.js'
|
|
48
|
-
import {
|
|
48
|
+
import {
|
|
49
|
+
DEFAULT_ID_FIELDS,
|
|
50
|
+
getIdFieldsForSegments,
|
|
51
|
+
isIdFieldPath,
|
|
52
|
+
isPublicDocPath,
|
|
53
|
+
normalizeIdFields,
|
|
54
|
+
prepareAddPayload,
|
|
55
|
+
resolveAddDocId
|
|
56
|
+
} from './idFields.js'
|
|
49
57
|
import { isCompatEnv } from './compatEnv.js'
|
|
50
58
|
import { resolveRefSegmentsSafe, resolveRefSignalSafe } from './Compat/refFallback.js'
|
|
51
59
|
import { compatStartOnRoot, compatStopOnRoot, joinScopePath } from './Compat/startStopCompat.js'
|
|
@@ -262,7 +270,7 @@ export class Signal extends Function {
|
|
|
262
270
|
if (this[SEGMENTS].length === 0) throw Error('Can\'t set the root signal data')
|
|
263
271
|
const idFields = getIdFieldsForSegments(this[SEGMENTS])
|
|
264
272
|
if (isIdFieldPath(this[SEGMENTS], idFields)) return
|
|
265
|
-
if (this[SEGMENTS]
|
|
273
|
+
if (isPublicDocPath(this[SEGMENTS])) {
|
|
266
274
|
value = normalizeIdFields(value, idFields, this[SEGMENTS][1])
|
|
267
275
|
}
|
|
268
276
|
if (isPublicCollection(this[SEGMENTS][0])) {
|
|
@@ -424,24 +432,9 @@ export class Signal extends Function {
|
|
|
424
432
|
|
|
425
433
|
async add (value) {
|
|
426
434
|
if (arguments.length > 1) throw Error('Signal.add() expects a single argument')
|
|
427
|
-
|
|
428
|
-
const hasId = value.id != null
|
|
429
|
-
const hasUnderscoreId = value._id != null
|
|
430
|
-
if (hasId && hasUnderscoreId && value.id !== value._id) {
|
|
431
|
-
throw Error(
|
|
432
|
-
`Signal.add() got conflicting "id" (${JSON.stringify(value.id)}) and "_id" (${JSON.stringify(value._id)})`
|
|
433
|
-
)
|
|
434
|
-
}
|
|
435
|
-
let id = value.id ?? value._id
|
|
436
|
-
id ??= uuid()
|
|
435
|
+
const id = resolveAddDocId(value, uuid)
|
|
437
436
|
const idFields = getIdFieldsForSegments([this[SEGMENTS][0], id])
|
|
438
|
-
|
|
439
|
-
if (idFields.includes('id')) {
|
|
440
|
-
value.id = id
|
|
441
|
-
} else if (value.id === id) {
|
|
442
|
-
delete value.id
|
|
443
|
-
}
|
|
444
|
-
await this[id].set(value)
|
|
437
|
+
await this[id].set(prepareAddPayload(value, idFields, id))
|
|
445
438
|
return id
|
|
446
439
|
}
|
|
447
440
|
|
package/orm/dataTree.js
CHANGED
|
@@ -3,7 +3,7 @@ import jsonDiff from 'json0-ot-diff'
|
|
|
3
3
|
import diffMatchPatch from 'diff-match-patch'
|
|
4
4
|
import { getConnection } from './connection.js'
|
|
5
5
|
import setDiffDeep from '../utils/setDiffDeep.js'
|
|
6
|
-
import { getIdFieldsForSegments, injectIdFields, stripIdFields, isPlainObject } from './idFields.js'
|
|
6
|
+
import { getIdFieldsForSegments, injectIdFields, stripIdFields, isPlainObject, isIdFieldPath } from './idFields.js'
|
|
7
7
|
import { emitModelChange, isModelEventsEnabled } from './Compat/modelEvents.js'
|
|
8
8
|
import { isSilentContextActive } from './Compat/silentContext.js'
|
|
9
9
|
import { isCompatEnv } from './compatEnv.js'
|
|
@@ -158,7 +158,7 @@ export async function setPublicDoc (segments, value, deleteValue = false) {
|
|
|
158
158
|
if (docId === 'undefined') throw Error(ERRORS.publicDocIdUndefined(segments))
|
|
159
159
|
if (!(collection && docId)) throw Error(ERRORS.publicDoc(segments))
|
|
160
160
|
const idFields = getIdFieldsForSegments([collection, docId])
|
|
161
|
-
if (segments
|
|
161
|
+
if (isIdFieldPath(segments, idFields)) return
|
|
162
162
|
const doc = getConnection().get(collection, docId)
|
|
163
163
|
let docState = resolvePublicDocState({ collection, docId, doc, idFields, hydrateCompatDocData: true })
|
|
164
164
|
if (!docState.exists && segments.length > 2) {
|
|
@@ -247,7 +247,7 @@ export async function setPublicDocReplace (segments, value) {
|
|
|
247
247
|
if (docId === 'undefined') throw Error(ERRORS.publicDocIdUndefined(segments))
|
|
248
248
|
if (!(collection && docId)) throw Error(ERRORS.publicDoc(segments))
|
|
249
249
|
const idFields = getIdFieldsForSegments([collection, docId])
|
|
250
|
-
if (segments
|
|
250
|
+
if (isIdFieldPath(segments, idFields)) return
|
|
251
251
|
const doc = getConnection().get(collection, docId)
|
|
252
252
|
let docState = resolvePublicDocState({ collection, docId, doc, idFields, hydrateCompatDocData: true })
|
|
253
253
|
if (!docState.exists && segments.length > 2) {
|
package/orm/idFields.js
CHANGED
|
@@ -50,8 +50,39 @@ export function stripIdFields (value, idFields) {
|
|
|
50
50
|
return next
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
export function resolveAddDocId (value, getDefaultId) {
|
|
54
|
+
if (!value || typeof value !== 'object') throw Error('Signal.add() expects an object argument')
|
|
55
|
+
const hasId = value.id != null
|
|
56
|
+
const hasUnderscoreId = value._id != null
|
|
57
|
+
if (hasId && hasUnderscoreId && value.id !== value._id) {
|
|
58
|
+
throw Error(
|
|
59
|
+
`Signal.add() got conflicting "id" (${JSON.stringify(value.id)}) and "_id" (${JSON.stringify(value._id)})`
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
return value.id ?? value._id ?? getDefaultId()
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function prepareAddPayload (value, idFields, docId) {
|
|
66
|
+
if (idFields.includes('_id')) value._id = docId
|
|
67
|
+
if (idFields.includes('id')) {
|
|
68
|
+
value.id = docId
|
|
69
|
+
} else if (value.id === docId) {
|
|
70
|
+
delete value.id
|
|
71
|
+
}
|
|
72
|
+
return value
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function isPublicDocPath (segments) {
|
|
76
|
+
if (!Array.isArray(segments) || segments.length !== 2) return false
|
|
77
|
+
const [collection, docId] = segments
|
|
78
|
+
if (typeof collection !== 'string' || !collection) return false
|
|
79
|
+
if (collection[0] === '_' || collection[0] === '$') return false
|
|
80
|
+
return docId != null
|
|
81
|
+
}
|
|
82
|
+
|
|
53
83
|
export function isIdFieldPath (segments, idFields) {
|
|
54
|
-
if (segments.length
|
|
55
|
-
|
|
84
|
+
if (!Array.isArray(segments) || segments.length !== 3) return false
|
|
85
|
+
if (!isPublicDocPath(segments.slice(0, 2))) return false
|
|
86
|
+
const last = segments[2]
|
|
56
87
|
return idFields.includes(last)
|
|
57
88
|
}
|
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.78",
|
|
4
4
|
"description": "Full-stack signals ORM with multiplayer",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -83,5 +83,5 @@
|
|
|
83
83
|
]
|
|
84
84
|
},
|
|
85
85
|
"license": "MIT",
|
|
86
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "6ced13d745e3ccb000b2fc9c34a31e51810cadbc"
|
|
87
87
|
}
|