teamplay 0.1.13 → 0.1.14
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/Signal.js +50 -13
- package/orm/dataTree.js +1 -1
- package/orm/sub.js +32 -0
- package/package.json +8 -8
package/orm/Signal.js
CHANGED
|
@@ -12,13 +12,15 @@
|
|
|
12
12
|
* in the raw data tree which have the same name as signal's methods
|
|
13
13
|
*/
|
|
14
14
|
import uuid from '@teamplay/utils/uuid'
|
|
15
|
-
import { get as _get, set as _set, del as _del, setPublicDoc as _setPublicDoc } from './dataTree.js'
|
|
15
|
+
import { get as _get, set as _set, del as _del, setPublicDoc as _setPublicDoc, getRaw } from './dataTree.js'
|
|
16
16
|
import getSignal, { rawSignal } from './getSignal.js'
|
|
17
17
|
import { IS_QUERY, HASH, QUERIES } from './Query.js'
|
|
18
18
|
import { ROOT_FUNCTION, getRoot } from './Root.js'
|
|
19
19
|
import { publicOnly } from './connection.js'
|
|
20
20
|
|
|
21
21
|
export const SEGMENTS = Symbol('path segments targeting the particular node in the data tree')
|
|
22
|
+
export const ARRAY_METHOD = Symbol('run array method on the signal')
|
|
23
|
+
export const GET = Symbol('get the value of the signal - either observed or raw')
|
|
22
24
|
|
|
23
25
|
export default class Signal extends Function {
|
|
24
26
|
constructor (segments) {
|
|
@@ -36,13 +38,23 @@ export default class Signal extends Function {
|
|
|
36
38
|
return uuid()
|
|
37
39
|
}
|
|
38
40
|
|
|
39
|
-
|
|
40
|
-
if (arguments.length >
|
|
41
|
+
[GET] (method) {
|
|
42
|
+
if (arguments.length > 1) throw Error('Signal[GET]() only accepts method as an argument')
|
|
41
43
|
if (this[IS_QUERY]) {
|
|
42
44
|
const hash = this[HASH]
|
|
43
|
-
return
|
|
45
|
+
return method([QUERIES, hash, 'docs'])
|
|
44
46
|
}
|
|
45
|
-
return
|
|
47
|
+
return method(this[SEGMENTS])
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
get () {
|
|
51
|
+
if (arguments.length > 0) throw Error('Signal.get() does not accept any arguments')
|
|
52
|
+
return this[GET](_get)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
peek () {
|
|
56
|
+
if (arguments.length > 0) throw Error('Signal.peek() does not accept any arguments')
|
|
57
|
+
return this[GET](getRaw)
|
|
46
58
|
}
|
|
47
59
|
|
|
48
60
|
getId () {
|
|
@@ -62,19 +74,32 @@ export default class Signal extends Function {
|
|
|
62
74
|
}
|
|
63
75
|
}
|
|
64
76
|
|
|
65
|
-
|
|
77
|
+
[ARRAY_METHOD] (method, nonArrayReturnValue, ...args) {
|
|
66
78
|
if (this[IS_QUERY]) {
|
|
67
79
|
const collection = this[SEGMENTS][0]
|
|
68
80
|
const hash = this[HASH]
|
|
69
81
|
const ids = _get([QUERIES, hash, 'ids'])
|
|
70
|
-
return ids.map(
|
|
82
|
+
return ids.map(
|
|
83
|
+
id => getSignal(getRoot(this), [collection, id])
|
|
84
|
+
)[method](...args)
|
|
71
85
|
}
|
|
72
86
|
const items = _get(this[SEGMENTS])
|
|
73
|
-
if (!Array.isArray(items)) return
|
|
74
|
-
return Array(items.length)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
87
|
+
if (!Array.isArray(items)) return nonArrayReturnValue
|
|
88
|
+
return Array(items.length).fill().map(
|
|
89
|
+
(_, index) => getSignal(getRoot(this), [...this[SEGMENTS], index])
|
|
90
|
+
)[method](...args)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
map (...args) {
|
|
94
|
+
return this[ARRAY_METHOD]('map', [], ...args)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
reduce (...args) {
|
|
98
|
+
return this[ARRAY_METHOD]('reduce', undefined, ...args)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
find (...args) {
|
|
102
|
+
return this[ARRAY_METHOD]('find', undefined, ...args)
|
|
78
103
|
}
|
|
79
104
|
|
|
80
105
|
async set (value) {
|
|
@@ -104,7 +129,9 @@ export default class Signal extends Function {
|
|
|
104
129
|
if (this[IS_QUERY]) throw Error('Signal.pop() can\'t be used on a query signal')
|
|
105
130
|
const array = this.get()
|
|
106
131
|
if (!Array.isArray(array) || array.length === 0) return
|
|
132
|
+
const lastItem = array[array.length - 1]
|
|
107
133
|
await this[array.length - 1].del()
|
|
134
|
+
return lastItem
|
|
108
135
|
}
|
|
109
136
|
|
|
110
137
|
// TODO: implement a json0 operation for unshift
|
|
@@ -138,6 +165,7 @@ export default class Signal extends Function {
|
|
|
138
165
|
}
|
|
139
166
|
id ??= uuid()
|
|
140
167
|
await this[id].set(value)
|
|
168
|
+
return id
|
|
141
169
|
}
|
|
142
170
|
|
|
143
171
|
async del () {
|
|
@@ -178,7 +206,7 @@ export const regularBindings = {
|
|
|
178
206
|
}
|
|
179
207
|
}
|
|
180
208
|
|
|
181
|
-
const QUERY_METHODS = ['map', 'get']
|
|
209
|
+
const QUERY_METHODS = ['map', 'reduce', 'find', 'get']
|
|
182
210
|
|
|
183
211
|
// dot syntax always returns a child signal even if such method or property exists.
|
|
184
212
|
// The method is only called when the signal is explicitly called as a function,
|
|
@@ -201,6 +229,7 @@ export const extremelyLateBindings = {
|
|
|
201
229
|
if (typeof key === 'symbol') return Reflect.get(signal, key, receiver)
|
|
202
230
|
if (key === 'then') return undefined // handle checks for whether the symbol is a Promise
|
|
203
231
|
key = transformAlias(signal[SEGMENTS], key)
|
|
232
|
+
key = maybeTransformToArrayIndex(key)
|
|
204
233
|
if (signal[IS_QUERY]) {
|
|
205
234
|
if (key === 'ids') return getSignal(getRoot(signal), [QUERIES, signal[HASH], 'ids'])
|
|
206
235
|
if (QUERY_METHODS.includes(key)) return Reflect.get(signal, key, receiver)
|
|
@@ -209,6 +238,14 @@ export const extremelyLateBindings = {
|
|
|
209
238
|
}
|
|
210
239
|
}
|
|
211
240
|
|
|
241
|
+
const REGEX_POSITIVE_INTEGER = /^(?:0|[1-9]\d*)$/
|
|
242
|
+
// Transform the key to a number if it's a positive integer.
|
|
243
|
+
// Otherwise the key must be a string.
|
|
244
|
+
function maybeTransformToArrayIndex (key) {
|
|
245
|
+
if (typeof key === 'string' && REGEX_POSITIVE_INTEGER.test(key)) return +key
|
|
246
|
+
return key
|
|
247
|
+
}
|
|
248
|
+
|
|
212
249
|
const transformAlias = (({
|
|
213
250
|
collectionsMapping = {
|
|
214
251
|
session: '_session',
|
package/orm/dataTree.js
CHANGED
|
@@ -23,7 +23,7 @@ export function getRaw (segments) {
|
|
|
23
23
|
|
|
24
24
|
export function set (segments, value, tree = dataTree) {
|
|
25
25
|
let dataNode = tree
|
|
26
|
-
let dataNodeRaw = raw(
|
|
26
|
+
let dataNodeRaw = raw(tree)
|
|
27
27
|
for (let i = 0; i < segments.length - 1; i++) {
|
|
28
28
|
const segment = segments[i]
|
|
29
29
|
if (dataNode[segment] == null) {
|
package/orm/sub.js
CHANGED
|
@@ -3,9 +3,16 @@ import { docSubscriptions } from './Doc.js'
|
|
|
3
3
|
import { querySubscriptions, getQuerySignal } from './Query.js'
|
|
4
4
|
|
|
5
5
|
export default function sub ($signal, params) {
|
|
6
|
+
if (Array.isArray($signal)) {
|
|
7
|
+
const res = $signal.map(args => Array.isArray(args) ? sub(...args) : sub(args))
|
|
8
|
+
if (res.some($s => $s.then)) return Promise.all(res)
|
|
9
|
+
return res
|
|
10
|
+
}
|
|
6
11
|
if (isPublicDocumentSignal($signal)) {
|
|
12
|
+
if (arguments.length > 1) throw Error(ERRORS.subDocArguments(...arguments))
|
|
7
13
|
return doc$($signal)
|
|
8
14
|
} else if (isPublicCollectionSignal($signal)) {
|
|
15
|
+
if (arguments.length !== 2) throw Error(ERRORS.subQueryArguments(...arguments))
|
|
9
16
|
return query$($signal, params)
|
|
10
17
|
} else if (typeof $signal === 'function' && !($signal instanceof Signal)) {
|
|
11
18
|
return api$($signal, params)
|
|
@@ -21,6 +28,7 @@ function doc$ ($doc) {
|
|
|
21
28
|
}
|
|
22
29
|
|
|
23
30
|
function query$ ($collection, params) {
|
|
31
|
+
if (typeof params !== 'object') throw Error(ERRORS.queryParamsObject($collection, params))
|
|
24
32
|
const $query = getQuerySignal($collection[SEGMENTS], params)
|
|
25
33
|
const promise = querySubscriptions.subscribe($query)
|
|
26
34
|
if (!promise) return $query
|
|
@@ -30,3 +38,27 @@ function query$ ($collection, params) {
|
|
|
30
38
|
function api$ (fn, args) {
|
|
31
39
|
throw Error('sub() for async functions is not implemented yet')
|
|
32
40
|
}
|
|
41
|
+
|
|
42
|
+
const ERRORS = {
|
|
43
|
+
subDocArguments: ($signal, ...args) => `
|
|
44
|
+
sub($doc) accepts only 1 argument - the document signal to subscribe to
|
|
45
|
+
Doc: ${$signal[SEGMENTS]}
|
|
46
|
+
Got args: ${[$signal, ...args]}
|
|
47
|
+
`,
|
|
48
|
+
subQueryArguments: ($signal, params, ...args) => `
|
|
49
|
+
sub($collection, params) accepts 2 arguments - the collection signal and an object with query params.
|
|
50
|
+
If you want to subscribe to all documents in a collection, pass an empty object: sub($collection, {}).
|
|
51
|
+
Collection: ${$signal[SEGMENTS]}
|
|
52
|
+
Params: ${params}
|
|
53
|
+
Got args: ${[$signal, params, ...args]}
|
|
54
|
+
`,
|
|
55
|
+
queryParamsObject: ($collection, params) => `
|
|
56
|
+
sub($collection, params):
|
|
57
|
+
Params must be an object.
|
|
58
|
+
If you want to subscribe to all documents in a collection, pass an empty object: sub($collection, {}).
|
|
59
|
+
|
|
60
|
+
Got:
|
|
61
|
+
$collection: ${$collection[SEGMENTS]}
|
|
62
|
+
params: ${params}
|
|
63
|
+
`
|
|
64
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "teamplay",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"description": "Full-stack signals ORM with multiplayer",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@nx-js/observer-util": "^4.1.3",
|
|
26
|
-
"@teamplay/backend": "^0.1.
|
|
27
|
-
"@teamplay/cache": "^0.1.
|
|
28
|
-
"@teamplay/channel": "^0.1.
|
|
29
|
-
"@teamplay/debug": "^0.1.
|
|
30
|
-
"@teamplay/schema": "^0.1.
|
|
31
|
-
"@teamplay/utils": "^0.1.
|
|
26
|
+
"@teamplay/backend": "^0.1.14",
|
|
27
|
+
"@teamplay/cache": "^0.1.14",
|
|
28
|
+
"@teamplay/channel": "^0.1.14",
|
|
29
|
+
"@teamplay/debug": "^0.1.14",
|
|
30
|
+
"@teamplay/schema": "^0.1.14",
|
|
31
|
+
"@teamplay/utils": "^0.1.14",
|
|
32
32
|
"diff-match-patch": "^1.0.5",
|
|
33
33
|
"events": "^3.3.0",
|
|
34
34
|
"json0-ot-diff": "^1.1.2",
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
]
|
|
64
64
|
},
|
|
65
65
|
"license": "MIT",
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "edc77f39753ed2532266bbfea646cb3cb7ca6786"
|
|
67
67
|
}
|