entangld 2.1.6 → 2.3.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/.eslintrc.json +29 -0
- package/README.hbs +1 -0
- package/README.md +490 -421
- package/generate_docs.js +3 -3
- package/index.js +8 -1333
- package/lib/Datastore.js +855 -0
- package/lib/Message.js +148 -0
- package/lib/Subscription.js +216 -0
- package/lib/error.js +43 -0
- package/lib/utils.js +263 -0
- package/package.json +8 -9
- package/test/circular.js +3 -7
- package/test/events.js +39 -0
- package/test/sockets.js +19 -19
- package/test/subscriptions.js +51 -51
- package/test/tests.js +382 -383
package/test/tests.js
CHANGED
|
@@ -1,119 +1,118 @@
|
|
|
1
|
-
var Entangld=require("../
|
|
1
|
+
var Entangld=require("../lib/Datastore.js");
|
|
2
|
+
var { partial_copy, dereferenced_copy } = require("../lib/utils.js");
|
|
2
3
|
var assert=require("assert");
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
describe("Internal functions",()=>{
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
describe("partial_copy",()=>{
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
// Create a data tree
|
|
11
|
+
let v={
|
|
12
|
+
a: {
|
|
13
|
+
b: {
|
|
14
|
+
c: 6
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
d: {
|
|
18
|
+
e: [
|
|
19
|
+
{
|
|
20
|
+
f: {
|
|
21
|
+
g: 7
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
h: 4
|
|
27
|
+
};
|
|
10
28
|
|
|
11
|
-
|
|
12
|
-
let v={
|
|
13
|
-
a: {
|
|
14
|
-
b: {
|
|
15
|
-
c: 6
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
d: {
|
|
19
|
-
e: [
|
|
20
|
-
{
|
|
21
|
-
f: {
|
|
22
|
-
g: 7
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
]
|
|
26
|
-
},
|
|
27
|
-
h: 4
|
|
28
|
-
};
|
|
29
|
+
it("returns original object when depth is unspecified",()=>{
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
assert.deepStrictEqual(partial_copy(v), v);
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
});
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
it("max_depth==0",()=>{
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
assert.deepStrictEqual(partial_copy(v,0), {a: {}, d:{}, h:4});
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
});
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
it("max_depth==1",()=>{
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
assert.deepStrictEqual(partial_copy(v,1), {a: { b: {} }, d:{ e: [] }, h:4});
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
});
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
it("max_depth==2",()=>{
|
|
47
48
|
|
|
48
|
-
|
|
49
|
+
assert.deepStrictEqual(partial_copy(v,2), {a: { b: { c: 6 } }, d:{ e: [ {} ] }, h:4 });
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
});
|
|
51
52
|
|
|
52
|
-
|
|
53
|
+
it("max_depth==3",()=>{
|
|
53
54
|
|
|
54
|
-
|
|
55
|
+
assert.deepStrictEqual(partial_copy(v,3), {a: { b: { c: 6 } }, d:{ e: [ { f: {} } ] }, h:4 });
|
|
55
56
|
|
|
56
|
-
|
|
57
|
+
});
|
|
57
58
|
|
|
58
|
-
|
|
59
|
+
it("max_depth==4",()=>{
|
|
59
60
|
|
|
60
|
-
|
|
61
|
+
assert.deepStrictEqual(partial_copy(v,4), {a: { b: { c: 6 } }, d:{ e: [ { f: { g: 7 } } ] }, h:4 });
|
|
61
62
|
|
|
62
|
-
|
|
63
|
+
});
|
|
64
|
+
});
|
|
63
65
|
|
|
64
|
-
|
|
65
|
-
});
|
|
66
|
+
describe("dereferenced_copy",()=>{
|
|
66
67
|
|
|
67
|
-
|
|
68
|
+
let o={
|
|
68
69
|
|
|
69
|
-
|
|
70
|
+
"data" : {
|
|
71
|
+
"some" : "data",
|
|
72
|
+
"more_data" : {
|
|
70
73
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
+
"more" : "data",
|
|
75
|
+
"func" : function(){ return "sasquatch!"; },
|
|
76
|
+
"promise" : function() { return new Promise((resolve)=>{ resolve("tomatoes"); }); }
|
|
77
|
+
}
|
|
78
|
+
}
|
|
74
79
|
|
|
75
|
-
|
|
76
|
-
"func" : function(){ return "sasquatch!"; },
|
|
77
|
-
"promise" : function() { return new Promise((resolve)=>{ resolve("tomatoes"); }); }
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
+
};
|
|
80
81
|
|
|
81
|
-
|
|
82
|
+
it("convert embedded functions to values",()=>{
|
|
82
83
|
|
|
83
|
-
|
|
84
|
+
return dereferenced_copy(o).then((val)=>{
|
|
84
85
|
|
|
85
|
-
|
|
86
|
+
assert.deepStrictEqual(val,
|
|
87
|
+
{
|
|
86
88
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
"data" : {
|
|
90
|
+
"some" : "data",
|
|
91
|
+
"more_data" : {
|
|
89
92
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
+
"more" : "data",
|
|
94
|
+
"func" : "sasquatch!",
|
|
95
|
+
"promise" : "tomatoes"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
);
|
|
93
100
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
"promise" : "tomatoes"
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
);
|
|
101
|
+
return Promise.resolve;
|
|
102
|
+
});
|
|
101
103
|
|
|
102
|
-
|
|
103
|
-
});
|
|
104
|
+
});
|
|
104
105
|
|
|
105
|
-
|
|
106
|
+
it("undefined passes through",()=>{
|
|
106
107
|
|
|
107
|
-
|
|
108
|
+
return dereferenced_copy(undefined).then((val)=>{
|
|
108
109
|
|
|
109
|
-
|
|
110
|
+
assert.strictEqual(val, undefined);
|
|
111
|
+
return Promise.resolve;
|
|
112
|
+
});
|
|
113
|
+
});
|
|
110
114
|
|
|
111
|
-
|
|
112
|
-
return Promise.resolve;
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
});
|
|
115
|
+
});
|
|
117
116
|
|
|
118
117
|
});
|
|
119
118
|
|
|
@@ -122,468 +121,468 @@ describe("Internal functions",()=>{
|
|
|
122
121
|
|
|
123
122
|
describe("Local storage",()=>{
|
|
124
123
|
|
|
125
|
-
|
|
124
|
+
it("Set/get value",()=>{
|
|
126
125
|
|
|
127
|
-
|
|
128
|
-
|
|
126
|
+
let s=new Entangld();
|
|
127
|
+
s.set("a.b.c.d",{ "key" : "value" });
|
|
129
128
|
|
|
130
|
-
|
|
129
|
+
return s.get("a.b.c.d").then((val)=>{
|
|
131
130
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
131
|
+
assert.deepStrictEqual(val,{ "key" : "value" });
|
|
132
|
+
return Promise.resolve();
|
|
133
|
+
});
|
|
134
|
+
});
|
|
136
135
|
|
|
137
|
-
|
|
136
|
+
it(".push()",()=>{
|
|
138
137
|
|
|
139
|
-
|
|
140
|
-
|
|
138
|
+
let s=new Entangld();
|
|
139
|
+
s.set("arr",[]);
|
|
141
140
|
|
|
142
|
-
|
|
143
|
-
|
|
141
|
+
s.push("arr",1);
|
|
142
|
+
s.push("arr",2);
|
|
144
143
|
|
|
145
|
-
|
|
144
|
+
return s.get("arr").then((val)=>{
|
|
146
145
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
146
|
+
assert.strictEqual(val.length,2);
|
|
147
|
+
return Promise.resolve();
|
|
148
|
+
});
|
|
149
|
+
});
|
|
151
150
|
|
|
152
|
-
|
|
151
|
+
it(".push() to non-array throws error",(done)=>{
|
|
153
152
|
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
let s=new Entangld();
|
|
154
|
+
s.set("arr",2); // It's a number, not an array
|
|
156
155
|
|
|
157
|
-
|
|
156
|
+
try {
|
|
158
157
|
|
|
159
|
-
|
|
158
|
+
s.push("arr",1);
|
|
160
159
|
|
|
161
|
-
|
|
160
|
+
} catch(e) {
|
|
162
161
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
162
|
+
assert.strictEqual(e.message, "You cannot .push() to that object");
|
|
163
|
+
done();
|
|
164
|
+
}
|
|
166
165
|
|
|
167
|
-
|
|
166
|
+
});
|
|
168
167
|
|
|
169
|
-
|
|
168
|
+
it("Set/get trivial value",()=>{
|
|
170
169
|
|
|
171
|
-
|
|
172
|
-
|
|
170
|
+
let s=new Entangld();
|
|
171
|
+
s.set("temperature",33);
|
|
173
172
|
|
|
174
|
-
|
|
173
|
+
return s.get("temperature").then((val)=>{
|
|
175
174
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
175
|
+
assert.strictEqual(val,33);
|
|
176
|
+
return Promise.resolve();
|
|
177
|
+
});
|
|
178
|
+
});
|
|
180
179
|
|
|
181
180
|
|
|
182
|
-
|
|
181
|
+
it("Set entire tree at empty path",()=>{
|
|
183
182
|
|
|
184
|
-
|
|
185
|
-
|
|
183
|
+
let s=new Entangld();
|
|
184
|
+
s.set("",{ "key" : "value" });
|
|
186
185
|
|
|
187
|
-
|
|
186
|
+
return s.get("key").then((val)=>{
|
|
188
187
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
188
|
+
assert.deepStrictEqual(val,"value");
|
|
189
|
+
return Promise.resolve();
|
|
190
|
+
});
|
|
191
|
+
});
|
|
193
192
|
|
|
194
|
-
|
|
193
|
+
it("set() accepts function (RPC mode, object as parameter)",()=>{
|
|
195
194
|
|
|
196
|
-
|
|
195
|
+
let s=new Entangld();
|
|
197
196
|
|
|
198
|
-
|
|
199
|
-
|
|
197
|
+
// Assign a function to "a.b.c.d"
|
|
198
|
+
s.set("a.b.c.d",(params)=>({ "doubled" : 2*params.value }));
|
|
200
199
|
|
|
201
|
-
|
|
200
|
+
return s.get("a.b.c.d", {"value": 5}).then((val)=>{
|
|
202
201
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
202
|
+
assert.deepStrictEqual(val,{ "doubled" : 10 });
|
|
203
|
+
return Promise.resolve();
|
|
204
|
+
});
|
|
205
|
+
});
|
|
207
206
|
|
|
208
|
-
|
|
207
|
+
it("set() accepts function (RPC mode, bare value as parameter)",()=>{
|
|
209
208
|
|
|
210
|
-
|
|
209
|
+
let s=new Entangld();
|
|
211
210
|
|
|
212
|
-
|
|
213
|
-
|
|
211
|
+
// Assign a function to "a.b.c.d"
|
|
212
|
+
s.set("a.b.c.d",(param)=>( 2*param));
|
|
214
213
|
|
|
215
|
-
|
|
214
|
+
return s.get("a.b.c.d", 5).then((val)=>{
|
|
216
215
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
216
|
+
assert.strictEqual(val,10);
|
|
217
|
+
return Promise.resolve();
|
|
218
|
+
});
|
|
219
|
+
});
|
|
221
220
|
|
|
222
|
-
|
|
221
|
+
it("get() subpath below function returns properly",()=>{
|
|
223
222
|
|
|
224
|
-
|
|
223
|
+
let s=new Entangld();
|
|
225
224
|
|
|
226
|
-
|
|
227
|
-
|
|
225
|
+
// Assign a function to "a.b.c.d"
|
|
226
|
+
s.set("a.b.c.d",()=>{ return { "sub" : "path" }; });
|
|
228
227
|
|
|
229
|
-
|
|
228
|
+
return s.get("a.b.c.d.sub").then((val)=>{
|
|
230
229
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
230
|
+
assert.strictEqual(val,"path");
|
|
231
|
+
return Promise.resolve();
|
|
232
|
+
});
|
|
233
|
+
});
|
|
235
234
|
|
|
236
|
-
|
|
235
|
+
it("get() accepts optional max_depth parameter",()=>{
|
|
237
236
|
|
|
238
|
-
|
|
237
|
+
let s=new Entangld();
|
|
239
238
|
|
|
240
|
-
|
|
241
|
-
|
|
239
|
+
// Create a data tree
|
|
240
|
+
let tree={
|
|
242
241
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
242
|
+
a: {
|
|
243
|
+
b: {
|
|
244
|
+
c: 6
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
d: {
|
|
248
|
+
e: {
|
|
249
|
+
f: 7
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
};
|
|
254
253
|
|
|
255
|
-
|
|
256
|
-
|
|
254
|
+
// Assign tree
|
|
255
|
+
s.set("tree",tree);
|
|
257
256
|
|
|
258
|
-
|
|
257
|
+
return s.get("tree").then((val)=>{
|
|
259
258
|
|
|
260
|
-
|
|
261
|
-
|
|
259
|
+
// Make sure we get the whole tree
|
|
260
|
+
assert.deepStrictEqual(val,tree);
|
|
262
261
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
262
|
+
return s.get("tree",0);
|
|
263
|
+
})
|
|
264
|
+
.then((val)=>{
|
|
266
265
|
|
|
267
|
-
|
|
268
|
-
|
|
266
|
+
// Make sure we get the first layer (depth 0)
|
|
267
|
+
assert.deepStrictEqual(val,{a:{}, d:{}});
|
|
269
268
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
269
|
+
return s.get("tree",1);
|
|
270
|
+
})
|
|
271
|
+
.then((val)=>{
|
|
273
272
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
273
|
+
// Make sure we get the first and second layers (depth 1)
|
|
274
|
+
assert.deepStrictEqual(val,{a:{ b: {} }, d:{ e: {} }});
|
|
275
|
+
return Promise.resolve();
|
|
276
|
+
});
|
|
277
|
+
});
|
|
279
278
|
|
|
280
|
-
|
|
279
|
+
it("Get invalid path returns undefined",()=>{
|
|
281
280
|
|
|
282
|
-
|
|
283
|
-
|
|
281
|
+
let s=new Entangld();
|
|
282
|
+
return s.get("a.b.c.d").then((val)=>{
|
|
284
283
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
284
|
+
assert(val===undefined);
|
|
285
|
+
return Promise.resolve();
|
|
286
|
+
});
|
|
287
|
+
});
|
|
289
288
|
|
|
290
|
-
|
|
289
|
+
it("get() invalid path below function returns undefined",()=>{
|
|
291
290
|
|
|
292
|
-
|
|
291
|
+
let s=new Entangld();
|
|
293
292
|
|
|
294
|
-
|
|
295
|
-
|
|
293
|
+
// Assign a function to "a.b.c.d"
|
|
294
|
+
s.set("a.b.c.d",()=>{ return { "sub" : "path" }; });
|
|
296
295
|
|
|
297
|
-
|
|
296
|
+
return s.get("a.b.c.d.doesnotexist").then((val)=>{
|
|
298
297
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
298
|
+
assert(val===undefined);
|
|
299
|
+
return Promise.resolve();
|
|
300
|
+
});
|
|
301
|
+
});
|
|
303
302
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
303
|
+
it("push() limit reduces the size of the target array",()=>{
|
|
304
|
+
let s=new Entangld();
|
|
305
|
+
s.set("array", [1, 2, 3, 4]);
|
|
307
306
|
|
|
308
|
-
|
|
309
|
-
|
|
307
|
+
// Push '5' to the array, but limit it to 4 elements
|
|
308
|
+
s.push("array", 5, 4);
|
|
310
309
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
310
|
+
return s.get("array").then((val) => {
|
|
311
|
+
// Expected: [2, 3, 4, 5]
|
|
312
|
+
assert(val.includes(5));
|
|
313
|
+
assert(val.length == 4);
|
|
314
|
+
});
|
|
315
|
+
});
|
|
317
316
|
});
|
|
318
317
|
|
|
319
318
|
|
|
320
319
|
describe("Multiplexed stores",()=>{
|
|
321
320
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
321
|
+
var s=new Entangld();
|
|
322
|
+
var a=new Entangld();
|
|
323
|
+
var b=new Entangld();
|
|
324
|
+
var c=new Entangld(); // attached later
|
|
326
325
|
|
|
327
|
-
|
|
328
|
-
|
|
326
|
+
s.attach("a",a);
|
|
327
|
+
s.attach("b",b);
|
|
329
328
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
329
|
+
s.transmit((msg, store)=>store.receive(msg));
|
|
330
|
+
a.transmit((msg)=>s.receive(msg, a));
|
|
331
|
+
b.transmit((msg)=>s.receive(msg, b));
|
|
333
332
|
|
|
334
|
-
|
|
333
|
+
it("Remote set into child store", ()=>{
|
|
335
334
|
|
|
336
|
-
|
|
337
|
-
|
|
335
|
+
s.set("a.system.voltage",33);
|
|
336
|
+
return a.get("system.voltage").then((val)=>{
|
|
338
337
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
338
|
+
assert.strictEqual(val, 33);
|
|
339
|
+
return Promise.resolve();
|
|
340
|
+
});
|
|
341
|
+
});
|
|
343
342
|
|
|
344
|
-
|
|
343
|
+
it("Remote get from child store", ()=>{
|
|
345
344
|
|
|
346
|
-
|
|
347
|
-
|
|
345
|
+
a.set("system.speed",45);
|
|
346
|
+
return s.get("a.system.speed").then((val)=>{
|
|
348
347
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
348
|
+
assert.strictEqual(val, 45);
|
|
349
|
+
return Promise.resolve();
|
|
350
|
+
});
|
|
352
351
|
|
|
353
|
-
|
|
352
|
+
});
|
|
354
353
|
|
|
355
|
-
|
|
354
|
+
it("Removes internal _requests reference after get", ()=>{
|
|
356
355
|
|
|
357
|
-
|
|
356
|
+
var request_length = Object.keys(s._requests).length;
|
|
358
357
|
|
|
359
|
-
|
|
358
|
+
return s.get("a.system.speed").then(()=>{
|
|
360
359
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
360
|
+
assert.strictEqual(request_length, Object.keys(s._requests).length);
|
|
361
|
+
return Promise.resolve();
|
|
362
|
+
});
|
|
363
|
+
});
|
|
365
364
|
|
|
366
|
-
|
|
365
|
+
it("Remote set single root value into child store", ()=>{
|
|
367
366
|
|
|
368
|
-
|
|
369
|
-
|
|
367
|
+
s.set("b.something",99);
|
|
368
|
+
return b.get("something").then((val)=>{
|
|
370
369
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
370
|
+
assert.strictEqual(val, 99);
|
|
371
|
+
return Promise.resolve();
|
|
372
|
+
});
|
|
373
|
+
});
|
|
375
374
|
|
|
376
|
-
|
|
375
|
+
it("null is an allowed value", ()=>{
|
|
377
376
|
|
|
378
|
-
|
|
379
|
-
|
|
377
|
+
b.set("system.n_ull",null);
|
|
378
|
+
return s.get("b.system.n_ull").then((val)=>{
|
|
380
379
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
380
|
+
assert.strictEqual(val, null);
|
|
381
|
+
return Promise.resolve();
|
|
382
|
+
});
|
|
383
|
+
});
|
|
385
384
|
|
|
386
385
|
|
|
387
|
-
|
|
386
|
+
it("Remote get root (everything) from child store", ()=>{
|
|
388
387
|
|
|
389
|
-
|
|
388
|
+
return s.get("a").then((val)=>{
|
|
390
389
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
390
|
+
assert.deepStrictEqual(val,{system: {voltage: 33, speed: 45}});
|
|
391
|
+
return Promise.resolve();
|
|
392
|
+
});
|
|
394
393
|
|
|
395
|
-
|
|
394
|
+
});
|
|
396
395
|
|
|
397
|
-
|
|
396
|
+
it("Remote get from child setter (bare value as parameter)", ()=>{
|
|
398
397
|
|
|
399
|
-
|
|
400
|
-
|
|
398
|
+
b.set("system.doubled",(param=1)=>param*2);
|
|
399
|
+
return s.get("b.system.doubled", 15).then((val)=>{
|
|
401
400
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
401
|
+
assert.strictEqual(val, 30);
|
|
402
|
+
return Promise.resolve();
|
|
403
|
+
});
|
|
404
|
+
});
|
|
406
405
|
|
|
407
|
-
|
|
406
|
+
it("Remote get from child setter (object as parameter)", ()=>{
|
|
408
407
|
|
|
409
|
-
|
|
410
|
-
|
|
408
|
+
a.set("system.doubled",(param=1)=>({ doubled: param.value*2}));
|
|
409
|
+
return s.get("a.system.doubled", {value: 4}).then((val)=>{
|
|
411
410
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
411
|
+
assert.deepStrictEqual(val, {doubled: 8});
|
|
412
|
+
return Promise.resolve();
|
|
413
|
+
});
|
|
414
|
+
});
|
|
416
415
|
|
|
417
416
|
|
|
418
|
-
|
|
417
|
+
it("Remote push to attached child", ()=>{
|
|
419
418
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
419
|
+
s.set("a.arr",[]);
|
|
420
|
+
s.push("a.arr",1);
|
|
421
|
+
return s.get("a.arr").then((val)=>{
|
|
423
422
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
423
|
+
assert.strictEqual(val.length, 1);
|
|
424
|
+
return Promise.resolve();
|
|
425
|
+
});
|
|
426
|
+
});
|
|
428
427
|
|
|
429
|
-
|
|
428
|
+
it("Setter visible in _deref_mode", ()=>{
|
|
430
429
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
430
|
+
b.set("system.five",()=>5);
|
|
431
|
+
b._deref_mode=true;
|
|
432
|
+
return s.get("b.system").then((val)=>{
|
|
434
433
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
434
|
+
assert.deepStrictEqual(val, { n_ull: null, doubled: 2, five: 5 });
|
|
435
|
+
b._deref_mode=false;
|
|
436
|
+
return Promise.resolve();
|
|
437
|
+
});
|
|
439
438
|
|
|
440
|
-
|
|
439
|
+
});
|
|
441
440
|
|
|
442
441
|
|
|
443
|
-
|
|
442
|
+
it("Get invalid child value returns undefined", ()=>{
|
|
444
443
|
|
|
445
|
-
|
|
444
|
+
return s.get("b.system.speed").then((val)=>{
|
|
446
445
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
446
|
+
assert.strictEqual(val, undefined);
|
|
447
|
+
return Promise.resolve();
|
|
448
|
+
});
|
|
450
449
|
|
|
451
|
-
|
|
450
|
+
});
|
|
452
451
|
|
|
453
|
-
|
|
452
|
+
it("Child read from parent", ()=>{
|
|
454
453
|
|
|
455
|
-
|
|
456
|
-
|
|
454
|
+
b.attach("__parent", s);
|
|
455
|
+
s.set("eyes", "blue");
|
|
457
456
|
|
|
458
|
-
|
|
457
|
+
return b.get("__parent.eyes").then((val)=>{
|
|
459
458
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
459
|
+
assert.strictEqual(val, "blue");
|
|
460
|
+
return Promise.resolve;
|
|
461
|
+
});
|
|
463
462
|
|
|
464
|
-
|
|
463
|
+
});
|
|
465
464
|
|
|
466
|
-
|
|
465
|
+
it("Child read from sibling", ()=>{
|
|
467
466
|
|
|
468
|
-
|
|
469
|
-
|
|
467
|
+
a.set("system.tea","Earl Grey. Hot.");
|
|
468
|
+
return b.get("__parent.a.system.tea").then((val)=>{
|
|
470
469
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
470
|
+
assert.strictEqual(val, "Earl Grey. Hot.");
|
|
471
|
+
return Promise.resolve;
|
|
472
|
+
});
|
|
474
473
|
|
|
475
|
-
|
|
476
|
-
|
|
474
|
+
});
|
|
475
|
+
it(".namespaces getter", ()=>{
|
|
477
476
|
|
|
478
|
-
|
|
479
|
-
|
|
477
|
+
assert.deepStrictEqual(s.namespaces,["a","b"]);
|
|
478
|
+
});
|
|
480
479
|
|
|
481
|
-
|
|
480
|
+
it(".detach() by namespace", ()=>{
|
|
482
481
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
482
|
+
assert.strictEqual(s.detach("a"), true);
|
|
483
|
+
assert.deepStrictEqual(s.namespaces,["b"]);
|
|
484
|
+
});
|
|
486
485
|
|
|
487
|
-
|
|
486
|
+
it(".detach() by store", ()=>{
|
|
488
487
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
488
|
+
assert.strictEqual(s.detach(null, b), true);
|
|
489
|
+
assert.deepStrictEqual(s.namespaces,[]);
|
|
490
|
+
});
|
|
492
491
|
|
|
493
|
-
|
|
492
|
+
it("non-root child store", ()=>{
|
|
494
493
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
494
|
+
// Set up store C (declared earlier)
|
|
495
|
+
c.transmit((msg)=>s.receive(msg, c));
|
|
496
|
+
c.set("val",33);
|
|
498
497
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
498
|
+
// Attach c to s at s.more_stores.c
|
|
499
|
+
s.set("more_stores",{"title": "store C is located at this level", "c": null});
|
|
500
|
+
s.attach("more_stores.c",c);
|
|
502
501
|
|
|
503
|
-
|
|
502
|
+
return s.get("more_stores.c.val").then((val)=>{
|
|
504
503
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
504
|
+
assert.strictEqual(val, 33);
|
|
505
|
+
return Promise.resolve();
|
|
506
|
+
});
|
|
507
|
+
});
|
|
509
508
|
|
|
510
|
-
|
|
509
|
+
it("Remote set into non root child store", ()=>{
|
|
511
510
|
|
|
512
|
-
|
|
513
|
-
|
|
511
|
+
s.set("more_stores.c.system.voltage",33);
|
|
512
|
+
return c.get("system.voltage").then((val)=>{
|
|
514
513
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
514
|
+
assert.strictEqual(val, 33);
|
|
515
|
+
return Promise.resolve();
|
|
516
|
+
});
|
|
517
|
+
});
|
|
519
518
|
|
|
520
|
-
|
|
519
|
+
it("Remote get from non root child store", ()=>{
|
|
521
520
|
|
|
522
|
-
|
|
523
|
-
|
|
521
|
+
c.set("system.speed",45);
|
|
522
|
+
return s.get("more_stores.c.system.speed").then((val)=>{
|
|
524
523
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
524
|
+
assert.strictEqual(val, 45);
|
|
525
|
+
return Promise.resolve();
|
|
526
|
+
});
|
|
528
527
|
|
|
529
|
-
|
|
528
|
+
});
|
|
530
529
|
|
|
531
|
-
|
|
530
|
+
it("Parent .get() shows attached child namespaces as empty objects", ()=>{
|
|
532
531
|
|
|
533
|
-
|
|
532
|
+
return s.get("").then((val)=>{
|
|
534
533
|
|
|
535
|
-
|
|
534
|
+
assert.deepStrictEqual(val,
|
|
536
535
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
536
|
+
{
|
|
537
|
+
eyes: "blue",
|
|
538
|
+
more_stores: {
|
|
539
|
+
c: {},
|
|
540
|
+
title: "store C is located at this level"
|
|
541
|
+
}
|
|
542
|
+
});
|
|
544
543
|
|
|
545
|
-
|
|
546
|
-
|
|
544
|
+
return Promise.resolve();
|
|
545
|
+
});
|
|
547
546
|
|
|
548
|
-
|
|
547
|
+
});
|
|
549
548
|
|
|
550
|
-
|
|
549
|
+
it("set() on parent of attached store throws Error", ()=>{
|
|
551
550
|
|
|
552
|
-
|
|
551
|
+
return new Promise((resolve)=>{
|
|
553
552
|
|
|
554
|
-
|
|
553
|
+
try{
|
|
555
554
|
|
|
556
|
-
|
|
555
|
+
s.set("more_stores",{});
|
|
557
556
|
|
|
558
|
-
|
|
557
|
+
} catch(e) {
|
|
559
558
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
559
|
+
assert(e.message.match(/would overwrite/));
|
|
560
|
+
resolve();
|
|
561
|
+
}
|
|
562
|
+
});
|
|
564
563
|
|
|
565
564
|
|
|
566
|
-
|
|
565
|
+
});
|
|
567
566
|
|
|
568
567
|
|
|
569
|
-
|
|
568
|
+
it("detaching child namespace causes its name to disappear from the tree", ()=>{
|
|
570
569
|
|
|
571
|
-
|
|
572
|
-
|
|
570
|
+
s.detach(null,c);
|
|
571
|
+
return s.get("").then((val)=>{
|
|
573
572
|
|
|
574
|
-
|
|
573
|
+
assert.deepStrictEqual(val,
|
|
575
574
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
575
|
+
{
|
|
576
|
+
eyes: "blue",
|
|
577
|
+
more_stores: {
|
|
578
|
+
title: "store C is located at this level"
|
|
579
|
+
}
|
|
580
|
+
});
|
|
582
581
|
|
|
583
|
-
|
|
584
|
-
|
|
582
|
+
return Promise.resolve();
|
|
583
|
+
});
|
|
585
584
|
|
|
586
|
-
|
|
585
|
+
});
|
|
587
586
|
|
|
588
|
-
|
|
587
|
+
// TODO: Add a triple multiplexed store test
|
|
589
588
|
});
|