teamplay 0.4.0-alpha.98 → 0.4.0
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 +58 -17
- package/orm/Compat/hooksCompat.js +32 -22
- package/orm/Compat/startStopCompat.js +41 -2
- package/orm/Doc.js +34 -0
- package/orm/dataTree.js +49 -29
- package/package.json +8 -8
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { raw, observe, unobserve } from '@nx-js/observer-util'
|
|
2
|
+
import arrayDiff from 'arraydiff'
|
|
2
3
|
import {
|
|
3
4
|
Signal,
|
|
4
5
|
GETTERS,
|
|
@@ -974,14 +975,14 @@ async function diffDeepCompat ($signal, before, after) {
|
|
|
974
975
|
if (before === after) return
|
|
975
976
|
|
|
976
977
|
if (Array.isArray(before) && Array.isArray(after)) {
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
978
|
+
const diff = arrayDiff(before, after, deepEqualCompat)
|
|
979
|
+
if (!diff.length) return
|
|
980
|
+
const index = getSingleArrayReplacementIndex(diff)
|
|
981
|
+
if (index != null) {
|
|
981
982
|
await diffDeepCompat(getChildSignal($signal, index), before[index], after[index])
|
|
982
983
|
return
|
|
983
984
|
}
|
|
984
|
-
await
|
|
985
|
+
await applyArrayDiffCompat($signal, diff)
|
|
985
986
|
return
|
|
986
987
|
}
|
|
987
988
|
|
|
@@ -1003,14 +1004,14 @@ function diffDeepCompatSync ($signal, before, after) {
|
|
|
1003
1004
|
if (before === after) return
|
|
1004
1005
|
|
|
1005
1006
|
if (Array.isArray(before) && Array.isArray(after)) {
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1007
|
+
const diff = arrayDiff(before, after, deepEqualCompat)
|
|
1008
|
+
if (!diff.length) return
|
|
1009
|
+
const index = getSingleArrayReplacementIndex(diff)
|
|
1010
|
+
if (index != null) {
|
|
1010
1011
|
diffDeepCompatSync(getChildSignal($signal, index), before[index], after[index])
|
|
1011
1012
|
return
|
|
1012
1013
|
}
|
|
1013
|
-
|
|
1014
|
+
applyArrayDiffCompatSync($signal, diff)
|
|
1014
1015
|
return
|
|
1015
1016
|
}
|
|
1016
1017
|
|
|
@@ -1035,14 +1036,54 @@ function isDiffableObject (before, after) {
|
|
|
1035
1036
|
return true
|
|
1036
1037
|
}
|
|
1037
1038
|
|
|
1038
|
-
function
|
|
1039
|
-
if (!Array.isArray(
|
|
1040
|
-
const
|
|
1041
|
-
const
|
|
1042
|
-
|
|
1043
|
-
|
|
1039
|
+
function getSingleArrayReplacementIndex (diff) {
|
|
1040
|
+
if (!Array.isArray(diff) || diff.length !== 2) return null
|
|
1041
|
+
const first = diff[0]
|
|
1042
|
+
const second = diff[1]
|
|
1043
|
+
if (
|
|
1044
|
+
first instanceof arrayDiff.RemoveDiff &&
|
|
1045
|
+
second instanceof arrayDiff.InsertDiff &&
|
|
1046
|
+
first.index === second.index &&
|
|
1047
|
+
first.howMany === 1 &&
|
|
1048
|
+
second.values.length === 1
|
|
1049
|
+
) {
|
|
1050
|
+
return first.index
|
|
1051
|
+
}
|
|
1052
|
+
return null
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
async function applyArrayDiffCompat ($signal, diff) {
|
|
1056
|
+
for (const item of diff) {
|
|
1057
|
+
if (item instanceof arrayDiff.InsertDiff) {
|
|
1058
|
+
await arrayInsertOnSignal($signal, item.index, item.values)
|
|
1059
|
+
continue
|
|
1060
|
+
}
|
|
1061
|
+
if (item instanceof arrayDiff.RemoveDiff) {
|
|
1062
|
+
await arrayRemoveOnSignal($signal, item.index, item.howMany)
|
|
1063
|
+
continue
|
|
1064
|
+
}
|
|
1065
|
+
if (item instanceof arrayDiff.MoveDiff) {
|
|
1066
|
+
await arrayMoveOnSignal($signal, item.from, item.to, item.howMany)
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
function applyArrayDiffCompatSync ($signal, diff) {
|
|
1072
|
+
const segments = ensureArrayTarget($signal)
|
|
1073
|
+
const rootId = getOwningRootId($signal)
|
|
1074
|
+
for (const item of diff) {
|
|
1075
|
+
if (item instanceof arrayDiff.InsertDiff) {
|
|
1076
|
+
arrayInsertPrivateData(rootId, segments, item.index, item.values)
|
|
1077
|
+
continue
|
|
1078
|
+
}
|
|
1079
|
+
if (item instanceof arrayDiff.RemoveDiff) {
|
|
1080
|
+
arrayRemovePrivateData(rootId, segments, item.index, item.howMany)
|
|
1081
|
+
continue
|
|
1082
|
+
}
|
|
1083
|
+
if (item instanceof arrayDiff.MoveDiff) {
|
|
1084
|
+
arrayMovePrivateData(rootId, segments, item.from, item.to, item.howMany)
|
|
1085
|
+
}
|
|
1044
1086
|
}
|
|
1045
|
-
return changed
|
|
1046
1087
|
}
|
|
1047
1088
|
|
|
1048
1089
|
function getChildSignal ($parent, key) {
|
|
@@ -115,48 +115,54 @@ export function useAsyncDoc (collection, id, options) {
|
|
|
115
115
|
return [$doc.get(), $doc]
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
function useSubscribedQuery (collection, query, options, hookName, subscribe) {
|
|
119
|
+
const normalizedQuery = normalizeQuery(query, hookName)
|
|
120
|
+
const $collection = getCollectionSignal(collection, query, hookName)
|
|
121
|
+
const $query = subscribe($collection, normalizedQuery, options)
|
|
122
|
+
return {
|
|
123
|
+
normalizedQuery,
|
|
124
|
+
$collection,
|
|
125
|
+
$query: getExtraQuerySignal($query, normalizedQuery)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function getExtraQuerySignal ($query, normalizedQuery) {
|
|
130
|
+
if (!$query) return $query
|
|
131
|
+
return isExtraQuery(normalizedQuery) ? $query.extra : $query
|
|
132
|
+
}
|
|
133
|
+
|
|
118
134
|
export function useQuery$ (collection, query, options) {
|
|
119
|
-
const normalizedQuery = normalizeQuery(query, 'useQuery')
|
|
120
|
-
const $collection = getCollectionSignal(collection, query, 'useQuery')
|
|
121
135
|
const normalizedOptions = normalizeSyncSubOptions(options)
|
|
122
|
-
const $query =
|
|
123
|
-
return
|
|
136
|
+
const { $query } = useSubscribedQuery(collection, query, normalizedOptions, 'useQuery', useSub)
|
|
137
|
+
return $query
|
|
124
138
|
}
|
|
125
139
|
|
|
126
140
|
export function useQuery (collection, query, options) {
|
|
127
|
-
const $collection = getCollectionSignal(collection, query, 'useQuery')
|
|
128
141
|
const normalizedOptions = normalizeSyncSubOptions(options)
|
|
129
|
-
const $query =
|
|
142
|
+
const { $collection, $query } = useSubscribedQuery(collection, query, normalizedOptions, 'useQuery', useSub)
|
|
130
143
|
return [$query.get(), $collection]
|
|
131
144
|
}
|
|
132
145
|
|
|
133
146
|
export function useAsyncQuery$ (collection, query, options) {
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
const $query = useAsyncSub($collection, normalizedQuery, options)
|
|
137
|
-
if (!$query) return $query
|
|
138
|
-
return isExtraQuery(normalizedQuery) ? $query.extra : $query
|
|
147
|
+
const { $query } = useSubscribedQuery(collection, query, options, 'useAsyncQuery', useAsyncSub)
|
|
148
|
+
return $query
|
|
139
149
|
}
|
|
140
150
|
|
|
141
151
|
export function useAsyncQuery (collection, query, options) {
|
|
142
|
-
const $collection =
|
|
143
|
-
const $query = useAsyncSub($collection, normalizeQuery(query, 'useAsyncQuery'), options)
|
|
152
|
+
const { $collection, $query } = useSubscribedQuery(collection, query, options, 'useAsyncQuery', useAsyncSub)
|
|
144
153
|
if (!$query) return [undefined, $collection]
|
|
145
154
|
return [$query.get(), $collection]
|
|
146
155
|
}
|
|
147
156
|
|
|
148
157
|
export function useBatchQuery$ (collection, query, _options) {
|
|
149
|
-
const
|
|
150
|
-
const $
|
|
151
|
-
|
|
152
|
-
const $query = useSub($collection, normalizedQuery, options)
|
|
153
|
-
if (!$query) return $query
|
|
154
|
-
return isExtraQuery(normalizedQuery) ? $query.extra : $query
|
|
158
|
+
const options = normalizeBatchSubOptions(_options)
|
|
159
|
+
const { $query } = useSubscribedQuery(collection, query, options, 'useBatchQuery', useSub)
|
|
160
|
+
return $query
|
|
155
161
|
}
|
|
156
162
|
|
|
157
|
-
export function useBatchQuery (collection, query,
|
|
158
|
-
const
|
|
159
|
-
const $query =
|
|
163
|
+
export function useBatchQuery (collection, query, _options) {
|
|
164
|
+
const options = normalizeBatchSubOptions(_options)
|
|
165
|
+
const { $collection, $query } = useSubscribedQuery(collection, query, options, 'useBatchQuery', useSub)
|
|
160
166
|
if (!$query) return [undefined, $collection]
|
|
161
167
|
return [$query.get(), $collection]
|
|
162
168
|
}
|
|
@@ -359,6 +365,10 @@ function normalizeSyncSubOptions (options) {
|
|
|
359
365
|
}
|
|
360
366
|
}
|
|
361
367
|
|
|
368
|
+
function normalizeBatchSubOptions (options) {
|
|
369
|
+
return options ? { ...options, ...BATCH_SUB_OPTIONS } : BATCH_SUB_OPTIONS
|
|
370
|
+
}
|
|
371
|
+
|
|
362
372
|
export const __COMPAT_BATCH_READY__ = {
|
|
363
373
|
isQueryReady
|
|
364
374
|
}
|
|
@@ -24,6 +24,7 @@ export function compatStartOnRoot ($root, targetPath, ...depsAndGetter) {
|
|
|
24
24
|
const existing = store.get(targetKey)
|
|
25
25
|
if (existing) existing.stop()
|
|
26
26
|
|
|
27
|
+
let lastSourceSnapshot = UNSET
|
|
27
28
|
const reaction = observe(() => {
|
|
28
29
|
const resolvedDeps = []
|
|
29
30
|
for (const dep of deps) {
|
|
@@ -38,13 +39,22 @@ export function compatStartOnRoot ($root, targetPath, ...depsAndGetter) {
|
|
|
38
39
|
if (isThenable(err)) return
|
|
39
40
|
throw err
|
|
40
41
|
}
|
|
41
|
-
const
|
|
42
|
+
const sourceSnapshot = detachStartValue(nextValue)
|
|
43
|
+
if (lastSourceSnapshot !== UNSET && deepEqualStartValue(lastSourceSnapshot, sourceSnapshot)) {
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
lastSourceSnapshot = sourceSnapshot
|
|
47
|
+
const detachedValue = detachStartValue(sourceSnapshot)
|
|
42
48
|
// Keep the detached snapshot to avoid aliasing source and target.
|
|
43
49
|
// Old racer start() writes through diffDeep by default. In compat mode we must preserve
|
|
44
50
|
// that behavior, but also avoid reading the target reactively inside start(), otherwise
|
|
45
51
|
// start() subscribes to its own output and local child edits get immediately overwritten.
|
|
46
52
|
const maybePromise = $target.setDiffDeep(detachedValue)
|
|
47
|
-
if (maybePromise?.
|
|
53
|
+
if (maybePromise?.then) {
|
|
54
|
+
maybePromise
|
|
55
|
+
.then(() => {})
|
|
56
|
+
.catch(ignorePromiseRejection)
|
|
57
|
+
}
|
|
48
58
|
}, { scheduler: scheduleReaction })
|
|
49
59
|
store.set(targetKey, { stop: () => unobserve(reaction) })
|
|
50
60
|
return $target
|
|
@@ -134,6 +144,8 @@ function isThenable (value) {
|
|
|
134
144
|
return !!value && typeof value.then === 'function'
|
|
135
145
|
}
|
|
136
146
|
|
|
147
|
+
const UNSET = Symbol('compat start unset')
|
|
148
|
+
|
|
137
149
|
function detachStartValue (value) {
|
|
138
150
|
const rawValue = raw(value)
|
|
139
151
|
if (!rawValue || typeof rawValue !== 'object') return rawValue
|
|
@@ -166,3 +178,30 @@ function racerDeepCopy (value) {
|
|
|
166
178
|
}
|
|
167
179
|
return value
|
|
168
180
|
}
|
|
181
|
+
|
|
182
|
+
function deepEqualStartValue (left, right) {
|
|
183
|
+
if (left === right) return true
|
|
184
|
+
if (Number.isNaN(left) && Number.isNaN(right)) return true
|
|
185
|
+
if (left instanceof Date || right instanceof Date) {
|
|
186
|
+
return left instanceof Date && right instanceof Date && left.getTime() === right.getTime()
|
|
187
|
+
}
|
|
188
|
+
if (!left || !right || typeof left !== 'object' || typeof right !== 'object') return false
|
|
189
|
+
|
|
190
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
191
|
+
if (!Array.isArray(left) || !Array.isArray(right)) return false
|
|
192
|
+
if (left.length !== right.length) return false
|
|
193
|
+
for (let i = 0; i < left.length; i++) {
|
|
194
|
+
if (!deepEqualStartValue(left[i], right[i])) return false
|
|
195
|
+
}
|
|
196
|
+
return true
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const leftKeys = Object.keys(left)
|
|
200
|
+
const rightKeys = Object.keys(right)
|
|
201
|
+
if (leftKeys.length !== rightKeys.length) return false
|
|
202
|
+
for (const key of leftKeys) {
|
|
203
|
+
if (!Object.prototype.hasOwnProperty.call(right, key)) return false
|
|
204
|
+
if (!deepEqualStartValue(left[key], right[key])) return false
|
|
205
|
+
}
|
|
206
|
+
return true
|
|
207
|
+
}
|
package/orm/Doc.js
CHANGED
|
@@ -35,6 +35,34 @@ function getOwningRootId ($doc) {
|
|
|
35
35
|
return rootId
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
function deepEqualDocData (left, right) {
|
|
39
|
+
if (left === right) return true
|
|
40
|
+
if (left == null || right == null) return left === right
|
|
41
|
+
|
|
42
|
+
const leftIsArray = Array.isArray(left)
|
|
43
|
+
if (leftIsArray || Array.isArray(right)) {
|
|
44
|
+
if (!leftIsArray || !Array.isArray(right)) return false
|
|
45
|
+
if (left.length !== right.length) return false
|
|
46
|
+
for (let i = 0; i < left.length; i++) {
|
|
47
|
+
if (!deepEqualDocData(left[i], right[i])) return false
|
|
48
|
+
}
|
|
49
|
+
return true
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (typeof left !== 'object' || typeof right !== 'object') return false
|
|
53
|
+
|
|
54
|
+
const leftKeys = Object.keys(left)
|
|
55
|
+
const rightKeys = Object.keys(right)
|
|
56
|
+
if (leftKeys.length !== rightKeys.length) return false
|
|
57
|
+
|
|
58
|
+
for (const key of leftKeys) {
|
|
59
|
+
if (!Object.prototype.hasOwnProperty.call(right, key)) return false
|
|
60
|
+
if (!deepEqualDocData(left[key], right[key])) return false
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return true
|
|
64
|
+
}
|
|
65
|
+
|
|
38
66
|
class Doc {
|
|
39
67
|
initialized
|
|
40
68
|
|
|
@@ -162,6 +190,12 @@ class Doc {
|
|
|
162
190
|
if (isPlainObject(doc.data)) injectIdFields(doc.data, idFields, this.docId)
|
|
163
191
|
const path = [this.collection, this.docId]
|
|
164
192
|
const data = isObservable(doc.data) ? raw(doc.data) : doc.data
|
|
193
|
+
const current = _getRaw(path)
|
|
194
|
+
if (deepEqualDocData(current, data)) {
|
|
195
|
+
if (current != null && current !== raw(doc.data)) doc.data = current
|
|
196
|
+
if (!isObservable(doc.data)) doc.data = observable(doc.data)
|
|
197
|
+
return
|
|
198
|
+
}
|
|
165
199
|
_set(path, data)
|
|
166
200
|
const synced = _getRaw(path)
|
|
167
201
|
if (synced != null && synced !== raw(doc.data)) doc.data = synced
|
package/orm/dataTree.js
CHANGED
|
@@ -73,7 +73,7 @@ export function set (segments, value, tree = dataTree, eventContext) {
|
|
|
73
73
|
const shouldEmit = shouldEmitModelEvents(tree, eventContext)
|
|
74
74
|
const prevValue = shouldEmit ? get(segments, getTreeRaw(tree)) : undefined
|
|
75
75
|
let dataNode = writableTree
|
|
76
|
-
let dataNodeRaw =
|
|
76
|
+
let dataNodeRaw = getTreeRaw(writableTree)
|
|
77
77
|
for (let i = 0; i < segments.length - 1; i++) {
|
|
78
78
|
const segment = segments[i]
|
|
79
79
|
const nextSegment = segments[i + 1]
|
|
@@ -84,34 +84,15 @@ export function set (segments, value, tree = dataTree, eventContext) {
|
|
|
84
84
|
else dataNode[segment] = {}
|
|
85
85
|
}
|
|
86
86
|
dataNode = dataNode[segment]
|
|
87
|
-
dataNodeRaw =
|
|
87
|
+
dataNodeRaw = getTreeRaw(dataNode)
|
|
88
88
|
}
|
|
89
89
|
const key = segments[segments.length - 1]
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
// handle when the value didn't change
|
|
98
|
-
if (value === dataNodeRaw[key]) return
|
|
99
|
-
// handle setting undefined value
|
|
100
|
-
if (value == null) {
|
|
101
|
-
if (Array.isArray(dataNodeRaw)) {
|
|
102
|
-
// if parent is an array -- we set array element to undefined
|
|
103
|
-
// IMPORTANT: JSON serialization will replace `undefined` with `null`
|
|
104
|
-
// so if the data will go to the server, it will be serialized as `null`.
|
|
105
|
-
// And when it comes back from the server it will be still `null`.
|
|
106
|
-
// This can lead to confusion since when you set `undefined` the value
|
|
107
|
-
// might end up becoming `null` for seemingly no reason (like in this case).
|
|
108
|
-
dataNode[key] = undefined
|
|
109
|
-
} else {
|
|
110
|
-
// if parent is an object -- we completely delete the property.
|
|
111
|
-
// Deleting the property is better for the JSON serialization
|
|
112
|
-
// since JSON does not have `undefined` values and replaces them with `null`.
|
|
113
|
-
delete dataNode[key]
|
|
114
|
-
}
|
|
90
|
+
const keyExists = hasOwnDataKey(dataNodeRaw, key)
|
|
91
|
+
// Preserve racer local semantics: assigning undefined creates/keeps the slot/key
|
|
92
|
+
// instead of deleting it, and sparse array writes keep holes intact.
|
|
93
|
+
if (keyExists && value === dataNodeRaw[key]) return
|
|
94
|
+
if (value == null || typeof value !== 'object') {
|
|
95
|
+
dataNode[key] = value
|
|
115
96
|
emitModelEvent(segments, prevValue, { op: 'set' }, tree, eventContext)
|
|
116
97
|
return
|
|
117
98
|
}
|
|
@@ -124,6 +105,12 @@ export function set (segments, value, tree = dataTree, eventContext) {
|
|
|
124
105
|
emitModelEvent(segments, prevValue, { op: 'set' }, tree, eventContext)
|
|
125
106
|
}
|
|
126
107
|
|
|
108
|
+
function hasOwnDataKey (node, key) {
|
|
109
|
+
if (node == null) return false
|
|
110
|
+
if (Array.isArray(node)) return key in node
|
|
111
|
+
return Object.prototype.hasOwnProperty.call(node, key)
|
|
112
|
+
}
|
|
113
|
+
|
|
127
114
|
// Like set(), but always assigns the value without equality checks or delete-on-null behavior
|
|
128
115
|
export function setReplace (segments, value, tree = dataTree, eventContext) {
|
|
129
116
|
const writableTree = getWritableTree(tree)
|
|
@@ -253,7 +240,7 @@ export async function setPublicDoc (segments, value, deleteValue = false) {
|
|
|
253
240
|
if (deleteValue) {
|
|
254
241
|
del(segments.slice(2), newDoc)
|
|
255
242
|
} else {
|
|
256
|
-
set(segments.slice(2), value, newDoc)
|
|
243
|
+
set(segments.slice(2), normalizeUndefined(value), newDoc)
|
|
257
244
|
}
|
|
258
245
|
const diff = jsonDiff(oldDoc, newDoc, diffMatchPatch)
|
|
259
246
|
return new Promise((resolve, reject) => {
|
|
@@ -349,7 +336,13 @@ export async function setPublicDocReplace (segments, value) {
|
|
|
349
336
|
return new Promise((resolve, reject) => {
|
|
350
337
|
doc.submitOp(op, err => {
|
|
351
338
|
if (err) return reject(err)
|
|
352
|
-
|
|
339
|
+
syncLocalDocAfterPublicWrite({
|
|
340
|
+
collection,
|
|
341
|
+
docId,
|
|
342
|
+
doc,
|
|
343
|
+
idFields,
|
|
344
|
+
relativePath
|
|
345
|
+
})
|
|
353
346
|
resolve()
|
|
354
347
|
})
|
|
355
348
|
})
|
|
@@ -447,6 +440,33 @@ function ensureLocalDocSyncedWithShareDoc ({
|
|
|
447
440
|
setReplace([collection, docId], shared)
|
|
448
441
|
}
|
|
449
442
|
|
|
443
|
+
function syncLocalDocAfterPublicWrite ({
|
|
444
|
+
collection,
|
|
445
|
+
docId,
|
|
446
|
+
doc,
|
|
447
|
+
idFields,
|
|
448
|
+
relativePath = []
|
|
449
|
+
}) {
|
|
450
|
+
if (!Array.isArray(relativePath) || relativePath.length === 0) {
|
|
451
|
+
ensureLocalDocSyncedWithShareDoc({ collection, docId, doc, idFields })
|
|
452
|
+
return
|
|
453
|
+
}
|
|
454
|
+
if (isMissingShareDoc(doc)) return
|
|
455
|
+
if (doc?.data == null) return
|
|
456
|
+
const shared = raw(doc.data)
|
|
457
|
+
const nextValue = get(relativePath, shared)
|
|
458
|
+
setReplace([collection, docId, ...relativePath], clonePublicLocalSyncValue(nextValue))
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
function clonePublicLocalSyncValue (value) {
|
|
462
|
+
const rawValue = raw(value)
|
|
463
|
+
if (rawValue == null || typeof rawValue !== 'object') return rawValue
|
|
464
|
+
if (typeof globalThis.structuredClone === 'function') {
|
|
465
|
+
return globalThis.structuredClone(rawValue)
|
|
466
|
+
}
|
|
467
|
+
return JSON.parse(JSON.stringify(rawValue))
|
|
468
|
+
}
|
|
469
|
+
|
|
450
470
|
function normalizeUndefined (value) {
|
|
451
471
|
return value === undefined ? null : value
|
|
452
472
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "teamplay",
|
|
3
|
-
"version": "0.4.0
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Full-stack signals ORM with multiplayer",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@nx-js/observer-util": "^4.1.3",
|
|
37
37
|
"@startupjs/sharedb-mingo-memory": "^4.0.0-2",
|
|
38
|
-
"@teamplay/backend": "^0.4.0
|
|
39
|
-
"@teamplay/cache": "^0.4.0
|
|
40
|
-
"@teamplay/channel": "^0.4.0
|
|
41
|
-
"@teamplay/debug": "^0.4.0
|
|
42
|
-
"@teamplay/schema": "^0.4.0
|
|
43
|
-
"@teamplay/utils": "^0.4.0
|
|
38
|
+
"@teamplay/backend": "^0.4.0",
|
|
39
|
+
"@teamplay/cache": "^0.4.0",
|
|
40
|
+
"@teamplay/channel": "^0.4.0",
|
|
41
|
+
"@teamplay/debug": "^0.4.0",
|
|
42
|
+
"@teamplay/schema": "^0.4.0",
|
|
43
|
+
"@teamplay/utils": "^0.4.0",
|
|
44
44
|
"diff-match-patch": "^1.0.5",
|
|
45
45
|
"events": "^3.3.0",
|
|
46
46
|
"json0-ot-diff": "^1.1.2",
|
|
@@ -83,5 +83,5 @@
|
|
|
83
83
|
]
|
|
84
84
|
},
|
|
85
85
|
"license": "MIT",
|
|
86
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "c944a34b27e2dbbe5c81b1c39739caa012212e3f"
|
|
87
87
|
}
|