cojson 0.0.11 → 0.0.13

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.
Files changed (75) hide show
  1. package/README.md +2 -2
  2. package/dist/account.d.ts +57 -0
  3. package/dist/account.js +76 -0
  4. package/dist/account.js.map +1 -0
  5. package/dist/account.test.d.ts +1 -0
  6. package/dist/account.test.js +40 -0
  7. package/dist/account.test.js.map +1 -0
  8. package/dist/coValue.d.ts +17 -36
  9. package/dist/coValue.js +53 -117
  10. package/dist/coValue.js.map +1 -1
  11. package/dist/coValue.test.js +16 -16
  12. package/dist/coValue.test.js.map +1 -1
  13. package/dist/contentType.d.ts +9 -9
  14. package/dist/contentType.js.map +1 -1
  15. package/dist/contentType.test.js +13 -17
  16. package/dist/contentType.test.js.map +1 -1
  17. package/dist/contentTypes/coList.d.ts +3 -3
  18. package/dist/contentTypes/coList.js.map +1 -1
  19. package/dist/contentTypes/coMap.d.ts +31 -21
  20. package/dist/contentTypes/coMap.js +28 -0
  21. package/dist/contentTypes/coMap.js.map +1 -1
  22. package/dist/contentTypes/coStream.d.ts +3 -3
  23. package/dist/contentTypes/coStream.js.map +1 -1
  24. package/dist/contentTypes/static.d.ts +4 -4
  25. package/dist/contentTypes/static.js.map +1 -1
  26. package/dist/crypto.d.ts +45 -39
  27. package/dist/crypto.js +68 -49
  28. package/dist/crypto.js.map +1 -1
  29. package/dist/crypto.test.js +45 -49
  30. package/dist/crypto.test.js.map +1 -1
  31. package/dist/ids.d.ts +5 -3
  32. package/dist/ids.js +3 -1
  33. package/dist/ids.js.map +1 -1
  34. package/dist/index.d.ts +12 -14
  35. package/dist/index.js +6 -8
  36. package/dist/index.js.map +1 -1
  37. package/dist/jsonValue.d.ts +2 -2
  38. package/dist/node.d.ts +25 -15
  39. package/dist/node.js +88 -33
  40. package/dist/node.js.map +1 -1
  41. package/dist/permissions.d.ts +27 -33
  42. package/dist/permissions.js +55 -47
  43. package/dist/permissions.js.map +1 -1
  44. package/dist/permissions.test.js +231 -314
  45. package/dist/permissions.test.js.map +1 -1
  46. package/dist/sync.d.ts +27 -30
  47. package/dist/sync.js +68 -64
  48. package/dist/sync.js.map +1 -1
  49. package/dist/sync.test.js +181 -305
  50. package/dist/sync.test.js.map +1 -1
  51. package/dist/testUtils.d.ts +37 -0
  52. package/dist/testUtils.js +157 -0
  53. package/dist/testUtils.js.map +1 -0
  54. package/package.json +1 -1
  55. package/src/account.test.ts +67 -0
  56. package/src/account.ts +152 -0
  57. package/src/coValue.test.ts +17 -31
  58. package/src/coValue.ts +98 -185
  59. package/src/contentType.test.ts +18 -45
  60. package/src/contentType.ts +15 -13
  61. package/src/contentTypes/coList.ts +4 -4
  62. package/src/contentTypes/coMap.ts +55 -29
  63. package/src/contentTypes/coStream.ts +4 -4
  64. package/src/contentTypes/static.ts +5 -5
  65. package/src/crypto.test.ts +53 -59
  66. package/src/crypto.ts +123 -95
  67. package/src/ids.ts +9 -3
  68. package/src/index.ts +14 -25
  69. package/src/jsonValue.ts +2 -2
  70. package/src/node.ts +189 -61
  71. package/src/permissions.test.ts +370 -404
  72. package/src/permissions.ts +126 -109
  73. package/src/sync.test.ts +262 -440
  74. package/src/sync.ts +96 -101
  75. package/src/testUtils.ts +229 -0
package/dist/sync.test.js CHANGED
@@ -1,11 +1,10 @@
1
- import { getAgent, getAgentID, newRandomAgentCredential, newRandomSessionID, } from './coValue.js';
2
- import { LocalNode } from './node.js';
3
- import { expectMap } from './contentType.js';
4
- import { ReadableStream, WritableStream, TransformStream, } from "isomorphic-streams";
1
+ import { newRandomSessionID } from "./coValue.js";
2
+ import { LocalNode } from "./node.js";
3
+ import { expectMap } from "./contentType.js";
4
+ import { connectedPeers, newStreamPair, randomAnonymousAccountAndSessionID, shouldNotResolve, } from "./testUtils.js";
5
5
  test("Node replies with initial tx and header to empty subscribe", async () => {
6
- const admin = newRandomAgentCredential("admin");
7
- const adminID = getAgentID(getAgent(admin));
8
- const node = new LocalNode(admin, newRandomSessionID(adminID));
6
+ const [admin, session] = randomAnonymousAccountAndSessionID();
7
+ const node = new LocalNode(admin, session);
9
8
  const team = node.createTeam();
10
9
  const map = team.createMap();
11
10
  map.edit((editable) => {
@@ -21,34 +20,33 @@ test("Node replies with initial tx and header to empty subscribe", async () => {
21
20
  });
22
21
  const writer = inTx.getWriter();
23
22
  await writer.write({
24
- action: "subscribe",
25
- coValueID: map.coValue.id,
23
+ action: "load",
24
+ id: map.coValue.id,
26
25
  header: false,
27
26
  sessions: {},
28
27
  });
29
28
  const reader = outRx.getReader();
30
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
29
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
31
30
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
32
31
  const mapTellKnownStateMsg = await reader.read();
33
32
  expect(mapTellKnownStateMsg.value).toEqual({
34
- action: "tellKnownState",
33
+ action: "known",
35
34
  ...map.coValue.knownState(),
36
35
  });
37
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
36
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
38
37
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
39
38
  const newContentMsg = await reader.read();
40
39
  expect(newContentMsg.value).toEqual({
41
- action: "newContent",
42
- coValueID: map.coValue.id,
40
+ action: "content",
41
+ id: map.coValue.id,
43
42
  header: {
44
43
  type: "comap",
45
44
  ruleset: { type: "ownedByTeam", team: team.id },
46
45
  meta: null,
47
46
  createdAt: map.coValue.header.createdAt,
48
47
  uniqueness: map.coValue.header.uniqueness,
49
- publicNickname: "map",
50
48
  },
51
- newContent: {
49
+ new: {
52
50
  [node.ownSessionID]: {
53
51
  after: 0,
54
52
  newTransactions: [
@@ -65,16 +63,14 @@ test("Node replies with initial tx and header to empty subscribe", async () => {
65
63
  ],
66
64
  },
67
65
  ],
68
- lastHash: map.coValue.sessions[node.ownSessionID].lastHash,
69
66
  lastSignature: map.coValue.sessions[node.ownSessionID].lastSignature,
70
67
  },
71
68
  },
72
69
  });
73
70
  });
74
71
  test("Node replies with only new tx to subscribe with some known state", async () => {
75
- const admin = newRandomAgentCredential("admin");
76
- const adminID = getAgentID(getAgent(admin));
77
- const node = new LocalNode(admin, newRandomSessionID(adminID));
72
+ const [admin, session] = randomAnonymousAccountAndSessionID();
73
+ const node = new LocalNode(admin, session);
78
74
  const team = node.createTeam();
79
75
  const map = team.createMap();
80
76
  map.edit((editable) => {
@@ -91,29 +87,29 @@ test("Node replies with only new tx to subscribe with some known state", async (
91
87
  });
92
88
  const writer = inTx.getWriter();
93
89
  await writer.write({
94
- action: "subscribe",
95
- coValueID: map.coValue.id,
90
+ action: "load",
91
+ id: map.coValue.id,
96
92
  header: true,
97
93
  sessions: {
98
94
  [node.ownSessionID]: 1,
99
95
  },
100
96
  });
101
97
  const reader = outRx.getReader();
102
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
98
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
103
99
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
104
100
  const mapTellKnownStateMsg = await reader.read();
105
101
  expect(mapTellKnownStateMsg.value).toEqual({
106
- action: "tellKnownState",
102
+ action: "known",
107
103
  ...map.coValue.knownState(),
108
104
  });
109
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
105
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
110
106
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
111
107
  const mapNewContentMsg = await reader.read();
112
108
  expect(mapNewContentMsg.value).toEqual({
113
- action: "newContent",
114
- coValueID: map.coValue.id,
109
+ action: "content",
110
+ id: map.coValue.id,
115
111
  header: undefined,
116
- newContent: {
112
+ new: {
117
113
  [node.ownSessionID]: {
118
114
  after: 1,
119
115
  newTransactions: [
@@ -130,7 +126,6 @@ test("Node replies with only new tx to subscribe with some known state", async (
130
126
  ],
131
127
  },
132
128
  ],
133
- lastHash: map.coValue.sessions[node.ownSessionID].lastHash,
134
129
  lastSignature: map.coValue.sessions[node.ownSessionID].lastSignature,
135
130
  },
136
131
  },
@@ -138,9 +133,8 @@ test("Node replies with only new tx to subscribe with some known state", async (
138
133
  });
139
134
  test.todo("TODO: node only replies with new tx to subscribe with some known state, even in the depended on coValues");
140
135
  test("After subscribing, node sends own known state and new txs to peer", async () => {
141
- const admin = newRandomAgentCredential("admin");
142
- const adminID = getAgentID(getAgent(admin));
143
- const node = new LocalNode(admin, newRandomSessionID(adminID));
136
+ const [admin, session] = randomAnonymousAccountAndSessionID();
137
+ const node = new LocalNode(admin, session);
144
138
  const team = node.createTeam();
145
139
  const map = team.createMap();
146
140
  const [inRx, inTx] = newStreamPair();
@@ -153,38 +147,38 @@ test("After subscribing, node sends own known state and new txs to peer", async
153
147
  });
154
148
  const writer = inTx.getWriter();
155
149
  await writer.write({
156
- action: "subscribe",
157
- coValueID: map.coValue.id,
150
+ action: "load",
151
+ id: map.coValue.id,
158
152
  header: false,
159
153
  sessions: {
160
154
  [node.ownSessionID]: 0,
161
155
  },
162
156
  });
163
157
  const reader = outRx.getReader();
164
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
158
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
165
159
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
166
160
  const mapTellKnownStateMsg = await reader.read();
167
161
  expect(mapTellKnownStateMsg.value).toEqual({
168
- action: "tellKnownState",
162
+ action: "known",
169
163
  ...map.coValue.knownState(),
170
164
  });
171
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
165
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
172
166
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
173
167
  const mapNewContentHeaderOnlyMsg = await reader.read();
174
168
  expect(mapNewContentHeaderOnlyMsg.value).toEqual({
175
- action: "newContent",
176
- coValueID: map.coValue.id,
169
+ action: "content",
170
+ id: map.coValue.id,
177
171
  header: map.coValue.header,
178
- newContent: {},
172
+ new: {},
179
173
  });
180
174
  map.edit((editable) => {
181
175
  editable.set("hello", "world", "trusting");
182
176
  });
183
177
  const mapEditMsg1 = await reader.read();
184
178
  expect(mapEditMsg1.value).toEqual({
185
- action: "newContent",
186
- coValueID: map.coValue.id,
187
- newContent: {
179
+ action: "content",
180
+ id: map.coValue.id,
181
+ new: {
188
182
  [node.ownSessionID]: {
189
183
  after: 0,
190
184
  newTransactions: [
@@ -201,7 +195,6 @@ test("After subscribing, node sends own known state and new txs to peer", async
201
195
  ],
202
196
  },
203
197
  ],
204
- lastHash: map.coValue.sessions[node.ownSessionID].lastHash,
205
198
  lastSignature: map.coValue.sessions[node.ownSessionID].lastSignature,
206
199
  },
207
200
  },
@@ -211,9 +204,9 @@ test("After subscribing, node sends own known state and new txs to peer", async
211
204
  });
212
205
  const mapEditMsg2 = await reader.read();
213
206
  expect(mapEditMsg2.value).toEqual({
214
- action: "newContent",
215
- coValueID: map.coValue.id,
216
- newContent: {
207
+ action: "content",
208
+ id: map.coValue.id,
209
+ new: {
217
210
  [node.ownSessionID]: {
218
211
  after: 1,
219
212
  newTransactions: [
@@ -230,16 +223,14 @@ test("After subscribing, node sends own known state and new txs to peer", async
230
223
  ],
231
224
  },
232
225
  ],
233
- lastHash: map.coValue.sessions[node.ownSessionID].lastHash,
234
226
  lastSignature: map.coValue.sessions[node.ownSessionID].lastSignature,
235
227
  },
236
228
  },
237
229
  });
238
230
  });
239
231
  test("Client replies with known new content to tellKnownState from server", async () => {
240
- const admin = newRandomAgentCredential("admin");
241
- const adminID = getAgentID(getAgent(admin));
242
- const node = new LocalNode(admin, newRandomSessionID(adminID));
232
+ const [admin, session] = randomAnonymousAccountAndSessionID();
233
+ const node = new LocalNode(admin, session);
243
234
  const team = node.createTeam();
244
235
  const map = team.createMap();
245
236
  map.edit((editable) => {
@@ -257,28 +248,28 @@ test("Client replies with known new content to tellKnownState from server", asyn
257
248
  // expect((await reader.read()).value).toMatchObject(teamStateEx(team));
258
249
  const writer = inTx.getWriter();
259
250
  await writer.write({
260
- action: "tellKnownState",
261
- coValueID: map.coValue.id,
251
+ action: "known",
252
+ id: map.coValue.id,
262
253
  header: false,
263
254
  sessions: {
264
255
  [node.ownSessionID]: 0,
265
256
  },
266
257
  });
267
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
258
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
268
259
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
269
260
  const mapTellKnownStateMsg = await reader.read();
270
261
  expect(mapTellKnownStateMsg.value).toEqual({
271
- action: "tellKnownState",
262
+ action: "known",
272
263
  ...map.coValue.knownState(),
273
264
  });
274
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
265
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
275
266
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
276
267
  const mapNewContentMsg = await reader.read();
277
268
  expect(mapNewContentMsg.value).toEqual({
278
- action: "newContent",
279
- coValueID: map.coValue.id,
269
+ action: "content",
270
+ id: map.coValue.id,
280
271
  header: map.coValue.header,
281
- newContent: {
272
+ new: {
282
273
  [node.ownSessionID]: {
283
274
  after: 0,
284
275
  newTransactions: [
@@ -295,16 +286,14 @@ test("Client replies with known new content to tellKnownState from server", asyn
295
286
  ],
296
287
  },
297
288
  ],
298
- lastHash: map.coValue.sessions[node.ownSessionID].lastHash,
299
289
  lastSignature: map.coValue.sessions[node.ownSessionID].lastSignature,
300
290
  },
301
291
  },
302
292
  });
303
293
  });
304
294
  test("No matter the optimistic known state, node respects invalid known state messages and resyncs", async () => {
305
- const admin = newRandomAgentCredential("admin");
306
- const adminID = getAgentID(getAgent(admin));
307
- const node = new LocalNode(admin, newRandomSessionID(adminID));
295
+ const [admin, session] = randomAnonymousAccountAndSessionID();
296
+ const node = new LocalNode(admin, session);
308
297
  const team = node.createTeam();
309
298
  const map = team.createMap();
310
299
  const [inRx, inTx] = newStreamPair();
@@ -317,29 +306,29 @@ test("No matter the optimistic known state, node respects invalid known state me
317
306
  });
318
307
  const writer = inTx.getWriter();
319
308
  await writer.write({
320
- action: "subscribe",
321
- coValueID: map.coValue.id,
309
+ action: "load",
310
+ id: map.coValue.id,
322
311
  header: false,
323
312
  sessions: {
324
313
  [node.ownSessionID]: 0,
325
314
  },
326
315
  });
327
316
  const reader = outRx.getReader();
328
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
317
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
329
318
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
330
319
  const mapTellKnownStateMsg = await reader.read();
331
320
  expect(mapTellKnownStateMsg.value).toEqual({
332
- action: "tellKnownState",
321
+ action: "known",
333
322
  ...map.coValue.knownState(),
334
323
  });
335
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
324
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
336
325
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
337
326
  const mapNewContentHeaderOnlyMsg = await reader.read();
338
327
  expect(mapNewContentHeaderOnlyMsg.value).toEqual({
339
- action: "newContent",
340
- coValueID: map.coValue.id,
328
+ action: "content",
329
+ id: map.coValue.id,
341
330
  header: map.coValue.header,
342
- newContent: {},
331
+ new: {},
343
332
  });
344
333
  map.edit((editable) => {
345
334
  editable.set("hello", "world", "trusting");
@@ -350,8 +339,9 @@ test("No matter the optimistic known state, node respects invalid known state me
350
339
  const _mapEditMsg1 = await reader.read();
351
340
  const _mapEditMsg2 = await reader.read();
352
341
  await writer.write({
353
- action: "wrongAssumedKnownState",
354
- coValueID: map.coValue.id,
342
+ action: "known",
343
+ isCorrection: true,
344
+ id: map.coValue.id,
355
345
  header: true,
356
346
  sessions: {
357
347
  [node.ownSessionID]: 1,
@@ -359,10 +349,10 @@ test("No matter the optimistic known state, node respects invalid known state me
359
349
  });
360
350
  const newContentAfterWrongAssumedState = await reader.read();
361
351
  expect(newContentAfterWrongAssumedState.value).toEqual({
362
- action: "newContent",
363
- coValueID: map.coValue.id,
352
+ action: "content",
353
+ id: map.coValue.id,
364
354
  header: undefined,
365
- newContent: {
355
+ new: {
366
356
  [node.ownSessionID]: {
367
357
  after: 1,
368
358
  newTransactions: [
@@ -379,16 +369,14 @@ test("No matter the optimistic known state, node respects invalid known state me
379
369
  ],
380
370
  },
381
371
  ],
382
- lastHash: map.coValue.sessions[node.ownSessionID].lastHash,
383
372
  lastSignature: map.coValue.sessions[node.ownSessionID].lastSignature,
384
373
  },
385
374
  },
386
375
  });
387
376
  });
388
377
  test("If we add a peer, but it never subscribes to a coValue, it won't get any messages", async () => {
389
- const admin = newRandomAgentCredential("admin");
390
- const adminID = getAgentID(getAgent(admin));
391
- const node = new LocalNode(admin, newRandomSessionID(adminID));
378
+ const [admin, session] = randomAnonymousAccountAndSessionID();
379
+ const node = new LocalNode(admin, session);
392
380
  const team = node.createTeam();
393
381
  const map = team.createMap();
394
382
  const [inRx, _inTx] = newStreamPair();
@@ -406,9 +394,8 @@ test("If we add a peer, but it never subscribes to a coValue, it won't get any m
406
394
  await expect(shouldNotResolve(reader.read(), { timeout: 100 })).resolves.toBeUndefined();
407
395
  });
408
396
  test("If we add a server peer, all updates to all coValues are sent to it, even if it doesn't subscribe", async () => {
409
- const admin = newRandomAgentCredential("admin");
410
- const adminID = getAgentID(getAgent(admin));
411
- const node = new LocalNode(admin, newRandomSessionID(adminID));
397
+ const [admin, session] = randomAnonymousAccountAndSessionID();
398
+ const node = new LocalNode(admin, session);
412
399
  const team = node.createTeam();
413
400
  const map = team.createMap();
414
401
  const [inRx, _inTx] = newStreamPair();
@@ -420,32 +407,32 @@ test("If we add a server peer, all updates to all coValues are sent to it, even
420
407
  role: "server",
421
408
  });
422
409
  const reader = outRx.getReader();
410
+ // expect((await reader.read()).value).toMatchObject({
411
+ // action: "load",
412
+ // id: adminID,
413
+ // });
423
414
  expect((await reader.read()).value).toMatchObject({
424
- action: "subscribe",
425
- coValueID: adminID,
426
- });
427
- expect((await reader.read()).value).toMatchObject({
428
- action: "subscribe",
429
- coValueID: team.teamMap.coValue.id,
415
+ action: "load",
416
+ id: team.teamMap.coValue.id,
430
417
  });
431
418
  const mapSubscribeMsg = await reader.read();
432
419
  expect(mapSubscribeMsg.value).toEqual({
433
- action: "subscribe",
434
- coValueID: map.coValue.id,
420
+ action: "load",
421
+ id: map.coValue.id,
435
422
  header: true,
436
423
  sessions: {},
437
424
  });
438
425
  map.edit((editable) => {
439
426
  editable.set("hello", "world", "trusting");
440
427
  });
441
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
428
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
442
429
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
443
430
  const mapNewContentMsg = await reader.read();
444
431
  expect(mapNewContentMsg.value).toEqual({
445
- action: "newContent",
446
- coValueID: map.coValue.id,
432
+ action: "content",
433
+ id: map.coValue.id,
447
434
  header: map.coValue.header,
448
- newContent: {
435
+ new: {
449
436
  [node.ownSessionID]: {
450
437
  after: 0,
451
438
  newTransactions: [
@@ -462,16 +449,14 @@ test("If we add a server peer, all updates to all coValues are sent to it, even
462
449
  ],
463
450
  },
464
451
  ],
465
- lastHash: map.coValue.sessions[node.ownSessionID].lastHash,
466
452
  lastSignature: map.coValue.sessions[node.ownSessionID].lastSignature,
467
453
  },
468
454
  },
469
455
  });
470
456
  });
471
457
  test("If we add a server peer, newly created coValues are auto-subscribed to", async () => {
472
- const admin = newRandomAgentCredential("admin");
473
- const adminID = getAgentID(getAgent(admin));
474
- const node = new LocalNode(admin, newRandomSessionID(adminID));
458
+ const [admin, session] = randomAnonymousAccountAndSessionID();
459
+ const node = new LocalNode(admin, session);
475
460
  const team = node.createTeam();
476
461
  const [inRx, _inTx] = newStreamPair();
477
462
  const [outRx, outTx] = newStreamPair();
@@ -482,35 +467,34 @@ test("If we add a server peer, newly created coValues are auto-subscribed to", a
482
467
  role: "server",
483
468
  });
484
469
  const reader = outRx.getReader();
470
+ // expect((await reader.read()).value).toMatchObject({
471
+ // action: "load",
472
+ // id: admin.id,
473
+ // });
485
474
  expect((await reader.read()).value).toMatchObject({
486
- action: "subscribe",
487
- coValueID: adminID,
488
- });
489
- expect((await reader.read()).value).toMatchObject({
490
- action: "subscribe",
491
- coValueID: team.teamMap.coValue.id,
475
+ action: "load",
476
+ id: team.teamMap.coValue.id,
492
477
  });
493
478
  const map = team.createMap();
494
479
  const mapSubscribeMsg = await reader.read();
495
480
  expect(mapSubscribeMsg.value).toEqual({
496
- action: "subscribe",
481
+ action: "load",
497
482
  ...map.coValue.knownState(),
498
483
  });
499
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
484
+ // expect((await reader.read()).value).toMatchObject(admContEx(adminID));
500
485
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
501
486
  const mapContentMsg = await reader.read();
502
487
  expect(mapContentMsg.value).toEqual({
503
- action: "newContent",
504
- coValueID: map.coValue.id,
488
+ action: "content",
489
+ id: map.coValue.id,
505
490
  header: map.coValue.header,
506
- newContent: {},
491
+ new: {},
507
492
  });
508
493
  });
509
494
  test.todo("TODO: when receiving a subscribe response that is behind our optimistic state (due to already sent content), we ignore it");
510
495
  test("When we connect a new server peer, we try to sync all existing coValues to it", async () => {
511
- const admin = newRandomAgentCredential("admin");
512
- const adminID = getAgentID(getAgent(admin));
513
- const node = new LocalNode(admin, newRandomSessionID(adminID));
496
+ const [admin, session] = randomAnonymousAccountAndSessionID();
497
+ const node = new LocalNode(admin, session);
514
498
  const team = node.createTeam();
515
499
  const map = team.createMap();
516
500
  const [inRx, _inTx] = newStreamPair();
@@ -522,22 +506,21 @@ test("When we connect a new server peer, we try to sync all existing coValues to
522
506
  role: "server",
523
507
  });
524
508
  const reader = outRx.getReader();
525
- const _adminSubscribeMessage = await reader.read();
509
+ // const _adminSubscribeMessage = await reader.read();
526
510
  const teamSubscribeMessage = await reader.read();
527
511
  expect(teamSubscribeMessage.value).toEqual({
528
- action: "subscribe",
512
+ action: "load",
529
513
  ...team.teamMap.coValue.knownState(),
530
514
  });
531
515
  const secondMessage = await reader.read();
532
516
  expect(secondMessage.value).toEqual({
533
- action: "subscribe",
517
+ action: "load",
534
518
  ...map.coValue.knownState(),
535
519
  });
536
520
  });
537
521
  test("When receiving a subscribe with a known state that is ahead of our own, peers should respond with a corresponding subscribe response message", async () => {
538
- const admin = newRandomAgentCredential("admin");
539
- const adminID = getAgentID(getAgent(admin));
540
- const node = new LocalNode(admin, newRandomSessionID(adminID));
522
+ const [admin, session] = randomAnonymousAccountAndSessionID();
523
+ const node = new LocalNode(admin, session);
541
524
  const team = node.createTeam();
542
525
  const map = team.createMap();
543
526
  const [inRx, inTx] = newStreamPair();
@@ -550,27 +533,26 @@ test("When receiving a subscribe with a known state that is ahead of our own, pe
550
533
  });
551
534
  const writer = inTx.getWriter();
552
535
  await writer.write({
553
- action: "subscribe",
554
- coValueID: map.coValue.id,
536
+ action: "load",
537
+ id: map.coValue.id,
555
538
  header: true,
556
539
  sessions: {
557
540
  [node.ownSessionID]: 1,
558
541
  },
559
542
  });
560
543
  const reader = outRx.getReader();
561
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
544
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
562
545
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
563
546
  const mapTellKnownState = await reader.read();
564
547
  expect(mapTellKnownState.value).toEqual({
565
- action: "tellKnownState",
548
+ action: "known",
566
549
  ...map.coValue.knownState(),
567
550
  });
568
551
  });
569
552
  test.skip("When replaying creation and transactions of a coValue as new content, the receiving peer integrates this information", async () => {
570
553
  // TODO: this test is mostly correct but also slightly unrealistic, make sure we pass all messages back and forth as expected and then it should work
571
- const admin = newRandomAgentCredential("admin");
572
- const adminID = getAgentID(getAgent(admin));
573
- const node1 = new LocalNode(admin, newRandomSessionID(adminID));
554
+ const [admin, session] = randomAnonymousAccountAndSessionID();
555
+ const node1 = new LocalNode(admin, session);
574
556
  const team = node1.createTeam();
575
557
  const [inRx1, inTx1] = newStreamPair();
576
558
  const [outRx1, outTx1] = newStreamPair();
@@ -582,7 +564,7 @@ test.skip("When replaying creation and transactions of a coValue as new content,
582
564
  });
583
565
  const to1 = inTx1.getWriter();
584
566
  const from1 = outRx1.getReader();
585
- const node2 = new LocalNode(admin, newRandomSessionID(adminID));
567
+ const node2 = new LocalNode(admin, newRandomSessionID(admin.id));
586
568
  const [inRx2, inTx2] = newStreamPair();
587
569
  const [outRx2, outTx2] = newStreamPair();
588
570
  node2.sync.addPeer({
@@ -595,47 +577,47 @@ test.skip("When replaying creation and transactions of a coValue as new content,
595
577
  const from2 = outRx2.getReader();
596
578
  const adminSubscribeMessage = await from1.read();
597
579
  expect(adminSubscribeMessage.value).toMatchObject({
598
- action: "subscribe",
599
- coValueID: adminID,
580
+ action: "load",
581
+ id: admin.id,
600
582
  });
601
583
  const teamSubscribeMsg = await from1.read();
602
584
  expect(teamSubscribeMsg.value).toMatchObject({
603
- action: "subscribe",
604
- coValueID: team.teamMap.coValue.id,
585
+ action: "load",
586
+ id: team.teamMap.coValue.id,
605
587
  });
606
588
  await to2.write(adminSubscribeMessage.value);
607
589
  await to2.write(teamSubscribeMsg.value);
608
- const adminTellKnownStateMsg = await from2.read();
609
- expect(adminTellKnownStateMsg.value).toMatchObject(admStateEx(adminID));
590
+ // const adminTellKnownStateMsg = await from2.read();
591
+ // expect(adminTellKnownStateMsg.value).toMatchObject(admStateEx(admin.id));
610
592
  const teamTellKnownStateMsg = await from2.read();
611
593
  expect(teamTellKnownStateMsg.value).toMatchObject(teamStateEx(team));
612
594
  expect(node2.sync.peers["test1"].optimisticKnownStates[team.teamMap.coValue.id]).toBeDefined();
613
- await to1.write(adminTellKnownStateMsg.value);
595
+ // await to1.write(adminTellKnownStateMsg.value!);
614
596
  await to1.write(teamTellKnownStateMsg.value);
615
- const adminContentMsg = await from1.read();
616
- expect(adminContentMsg.value).toMatchObject(admContEx(adminID));
597
+ // const adminContentMsg = await from1.read();
598
+ // expect(adminContentMsg.value).toMatchObject(admContEx(admin.id));
617
599
  const teamContentMsg = await from1.read();
618
600
  expect(teamContentMsg.value).toMatchObject(teamContentEx(team));
619
- await to2.write(adminContentMsg.value);
601
+ // await to2.write(adminContentMsg.value!);
620
602
  await to2.write(teamContentMsg.value);
621
603
  const map = team.createMap();
622
604
  const mapSubscriptionMsg = await from1.read();
623
605
  expect(mapSubscriptionMsg.value).toMatchObject({
624
- action: "subscribe",
625
- coValueID: map.coValue.id,
606
+ action: "load",
607
+ id: map.coValue.id,
626
608
  });
627
609
  const mapNewContentMsg = await from1.read();
628
610
  expect(mapNewContentMsg.value).toEqual({
629
- action: "newContent",
630
- coValueID: map.coValue.id,
611
+ action: "content",
612
+ id: map.coValue.id,
631
613
  header: map.coValue.header,
632
- newContent: {},
614
+ new: {},
633
615
  });
634
616
  await to2.write(mapSubscriptionMsg.value);
635
617
  const mapTellKnownStateMsg = await from2.read();
636
618
  expect(mapTellKnownStateMsg.value).toEqual({
637
- action: "tellKnownState",
638
- coValueID: map.coValue.id,
619
+ action: "known",
620
+ id: map.coValue.id,
639
621
  header: false,
640
622
  sessions: {},
641
623
  });
@@ -651,15 +633,14 @@ test.skip("When replaying creation and transactions of a coValue as new content,
651
633
  });
652
634
  test.skip("When loading a coValue on one node, the server node it is requested from replies with all the necessary depended on coValues to make it work", async () => {
653
635
  // TODO: this test is mostly correct but also slightly unrealistic, make sure we pass all messages back and forth as expected and then it should work
654
- const admin = newRandomAgentCredential("admin");
655
- const adminID = getAgentID(getAgent(admin));
656
- const node1 = new LocalNode(admin, newRandomSessionID(adminID));
636
+ const [admin, session] = randomAnonymousAccountAndSessionID();
637
+ const node1 = new LocalNode(admin, session);
657
638
  const team = node1.createTeam();
658
639
  const map = team.createMap();
659
640
  map.edit((editable) => {
660
641
  editable.set("hello", "world", "trusting");
661
642
  });
662
- const node2 = new LocalNode(admin, newRandomSessionID(adminID));
643
+ const node2 = new LocalNode(admin, newRandomSessionID(admin.id));
663
644
  const [node1asPeer, node2asPeer] = connectedPeers("peer1", "peer2");
664
645
  node1.sync.addPeer(node2asPeer);
665
646
  node2.sync.addPeer(node1asPeer);
@@ -667,24 +648,22 @@ test.skip("When loading a coValue on one node, the server node it is requested f
667
648
  expect(expectMap(node2.expectCoValueLoaded(map.coValue.id).getCurrentContent()).get("hello")).toEqual("world");
668
649
  });
669
650
  test("Can sync a coValue through a server to another client", async () => {
670
- const admin = newRandomAgentCredential("admin");
671
- const adminID = getAgentID(getAgent(admin));
672
- const client1 = new LocalNode(admin, newRandomSessionID(adminID));
651
+ const [admin, session] = randomAnonymousAccountAndSessionID();
652
+ const client1 = new LocalNode(admin, session);
673
653
  const team = client1.createTeam();
674
654
  const map = team.createMap();
675
655
  map.edit((editable) => {
676
656
  editable.set("hello", "world", "trusting");
677
657
  });
678
- const serverUser = newRandomAgentCredential("serverUser");
679
- const serverUserID = getAgentID(getAgent(serverUser));
680
- const server = new LocalNode(serverUser, newRandomSessionID(serverUserID));
658
+ const [serverUser, serverSession] = randomAnonymousAccountAndSessionID();
659
+ const server = new LocalNode(serverUser, serverSession);
681
660
  const [serverAsPeer, client1AsPeer] = connectedPeers("server", "client1", {
682
661
  peer1role: "server",
683
662
  peer2role: "client",
684
663
  });
685
664
  client1.sync.addPeer(serverAsPeer);
686
665
  server.sync.addPeer(client1AsPeer);
687
- const client2 = new LocalNode(admin, newRandomSessionID(adminID));
666
+ const client2 = new LocalNode(admin, newRandomSessionID(admin.id));
688
667
  const [serverAsOtherPeer, client2AsPeer] = connectedPeers("server", "client2", { peer1role: "server", peer2role: "client" });
689
668
  client2.sync.addPeer(serverAsOtherPeer);
690
669
  server.sync.addPeer(client2AsPeer);
@@ -692,17 +671,15 @@ test("Can sync a coValue through a server to another client", async () => {
692
671
  expect(expectMap(mapOnClient2.getCurrentContent()).get("hello")).toEqual("world");
693
672
  });
694
673
  test("Can sync a coValue with private transactions through a server to another client", async () => {
695
- const admin = newRandomAgentCredential("admin");
696
- const adminID = getAgentID(getAgent(admin));
697
- const client1 = new LocalNode(admin, newRandomSessionID(adminID));
674
+ const [admin, session] = randomAnonymousAccountAndSessionID();
675
+ const client1 = new LocalNode(admin, session);
698
676
  const team = client1.createTeam();
699
677
  const map = team.createMap();
700
678
  map.edit((editable) => {
701
679
  editable.set("hello", "world", "private");
702
680
  });
703
- const serverUser = newRandomAgentCredential("serverUser");
704
- const serverUserID = getAgentID(getAgent(serverUser));
705
- const server = new LocalNode(serverUser, newRandomSessionID(serverUserID));
681
+ const [serverUser, serverSession] = randomAnonymousAccountAndSessionID();
682
+ const server = new LocalNode(serverUser, serverSession);
706
683
  const [serverAsPeer, client1AsPeer] = connectedPeers("server", "client1", {
707
684
  trace: true,
708
685
  peer1role: "server",
@@ -710,7 +687,7 @@ test("Can sync a coValue with private transactions through a server to another c
710
687
  });
711
688
  client1.sync.addPeer(serverAsPeer);
712
689
  server.sync.addPeer(client1AsPeer);
713
- const client2 = new LocalNode(admin, newRandomSessionID(adminID));
690
+ const client2 = new LocalNode(admin, newRandomSessionID(admin.id));
714
691
  const [serverAsOtherPeer, client2AsPeer] = connectedPeers("server", "client2", { trace: true, peer1role: "server", peer2role: "client" });
715
692
  client2.sync.addPeer(serverAsOtherPeer);
716
693
  server.sync.addPeer(client2AsPeer);
@@ -718,9 +695,8 @@ test("Can sync a coValue with private transactions through a server to another c
718
695
  expect(expectMap(mapOnClient2.getCurrentContent()).get("hello")).toEqual("world");
719
696
  });
720
697
  test("When a peer's incoming/readable stream closes, we remove the peer", async () => {
721
- const admin = newRandomAgentCredential("admin");
722
- const adminID = getAgentID(getAgent(admin));
723
- const node = new LocalNode(admin, newRandomSessionID(adminID));
698
+ const [admin, session] = randomAnonymousAccountAndSessionID();
699
+ const node = new LocalNode(admin, session);
724
700
  const team = node.createTeam();
725
701
  const [inRx, inTx] = newStreamPair();
726
702
  const [outRx, outTx] = newStreamPair();
@@ -731,37 +707,36 @@ test("When a peer's incoming/readable stream closes, we remove the peer", async
731
707
  role: "server",
732
708
  });
733
709
  const reader = outRx.getReader();
710
+ // expect((await reader.read()).value).toMatchObject({
711
+ // action: "load",
712
+ // id: admin.id,
713
+ // });
734
714
  expect((await reader.read()).value).toMatchObject({
735
- action: "subscribe",
736
- coValueID: adminID,
737
- });
738
- expect((await reader.read()).value).toMatchObject({
739
- action: "subscribe",
740
- coValueID: team.teamMap.coValue.id,
715
+ action: "load",
716
+ id: team.teamMap.coValue.id,
741
717
  });
742
718
  const map = team.createMap();
743
719
  const mapSubscribeMsg = await reader.read();
744
720
  expect(mapSubscribeMsg.value).toEqual({
745
- action: "subscribe",
721
+ action: "load",
746
722
  ...map.coValue.knownState(),
747
723
  });
748
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
724
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
749
725
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
750
726
  const mapContentMsg = await reader.read();
751
727
  expect(mapContentMsg.value).toEqual({
752
- action: "newContent",
753
- coValueID: map.coValue.id,
728
+ action: "content",
729
+ id: map.coValue.id,
754
730
  header: map.coValue.header,
755
- newContent: {},
731
+ new: {},
756
732
  });
757
733
  await inTx.abort();
758
734
  await new Promise((resolve) => setTimeout(resolve, 100));
759
735
  expect(node.sync.peers["test"]).toBeUndefined();
760
736
  });
761
737
  test("When a peer's outgoing/writable stream closes, we remove the peer", async () => {
762
- const admin = newRandomAgentCredential("admin");
763
- const adminID = getAgentID(getAgent(admin));
764
- const node = new LocalNode(admin, newRandomSessionID(adminID));
738
+ const [admin, session] = randomAnonymousAccountAndSessionID();
739
+ const node = new LocalNode(admin, session);
765
740
  const team = node.createTeam();
766
741
  const [inRx, inTx] = newStreamPair();
767
742
  const [outRx, outTx] = newStreamPair();
@@ -772,28 +747,28 @@ test("When a peer's outgoing/writable stream closes, we remove the peer", async
772
747
  role: "server",
773
748
  });
774
749
  const reader = outRx.getReader();
750
+ // expect((await reader.read()).value).toMatchObject({
751
+ // action: "load",
752
+ // id: admin.id,
753
+ // });
775
754
  expect((await reader.read()).value).toMatchObject({
776
- action: "subscribe",
777
- coValueID: adminID,
778
- });
779
- expect((await reader.read()).value).toMatchObject({
780
- action: "subscribe",
781
- coValueID: team.teamMap.coValue.id,
755
+ action: "load",
756
+ id: team.teamMap.coValue.id,
782
757
  });
783
758
  const map = team.createMap();
784
759
  const mapSubscribeMsg = await reader.read();
785
760
  expect(mapSubscribeMsg.value).toEqual({
786
- action: "subscribe",
761
+ action: "load",
787
762
  ...map.coValue.knownState(),
788
763
  });
789
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
764
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
790
765
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
791
766
  const mapContentMsg = await reader.read();
792
767
  expect(mapContentMsg.value).toEqual({
793
- action: "newContent",
794
- coValueID: map.coValue.id,
768
+ action: "content",
769
+ id: map.coValue.id,
795
770
  header: map.coValue.header,
796
- newContent: {},
771
+ new: {},
797
772
  });
798
773
  reader.releaseLock();
799
774
  await outRx.cancel();
@@ -804,16 +779,19 @@ test("When a peer's outgoing/writable stream closes, we remove the peer", async
804
779
  expect(node.sync.peers["test"]).toBeUndefined();
805
780
  });
806
781
  test("If we start loading a coValue before connecting to a peer that has it, it will load it once we connect", async () => {
807
- const admin = newRandomAgentCredential("admin");
808
- const adminID = getAgentID(getAgent(admin));
809
- const node1 = new LocalNode(admin, newRandomSessionID(adminID));
782
+ const [admin, session] = randomAnonymousAccountAndSessionID();
783
+ const node1 = new LocalNode(admin, session);
810
784
  const team = node1.createTeam();
811
785
  const map = team.createMap();
812
786
  map.edit((editable) => {
813
787
  editable.set("hello", "world", "trusting");
814
788
  });
815
- const node2 = new LocalNode(admin, newRandomSessionID(adminID));
816
- const [node1asPeer, node2asPeer] = connectedPeers("peer1", "peer2", { peer1role: 'server', peer2role: 'client', trace: true });
789
+ const node2 = new LocalNode(admin, newRandomSessionID(admin.id));
790
+ const [node1asPeer, node2asPeer] = connectedPeers("peer1", "peer2", {
791
+ peer1role: "server",
792
+ peer2role: "client",
793
+ trace: true,
794
+ });
817
795
  node1.sync.addPeer(node2asPeer);
818
796
  const mapOnNode2Promise = node2.loadCoValue(map.coValue.id);
819
797
  expect(node2.coValues[map.coValue.id]?.state).toEqual("loading");
@@ -823,128 +801,26 @@ test("If we start loading a coValue before connecting to a peer that has it, it
823
801
  });
824
802
  function teamContentEx(team) {
825
803
  return {
826
- action: "newContent",
827
- coValueID: team.teamMap.coValue.id,
804
+ action: "content",
805
+ id: team.teamMap.coValue.id,
828
806
  };
829
807
  }
830
808
  function admContEx(adminID) {
831
809
  return {
832
- action: "newContent",
833
- coValueID: adminID,
810
+ action: "content",
811
+ id: adminID,
834
812
  };
835
813
  }
836
814
  function teamStateEx(team) {
837
815
  return {
838
- action: "tellKnownState",
839
- coValueID: team.teamMap.coValue.id,
816
+ action: "known",
817
+ id: team.teamMap.coValue.id,
840
818
  };
841
819
  }
842
820
  function admStateEx(adminID) {
843
821
  return {
844
- action: "tellKnownState",
845
- coValueID: adminID,
846
- };
847
- }
848
- function newStreamPair() {
849
- const queue = [];
850
- let resolveNextItemReady = () => { };
851
- let nextItemReady = new Promise((resolve) => {
852
- resolveNextItemReady = resolve;
853
- });
854
- let writerClosed = false;
855
- let readerClosed = false;
856
- const readable = new ReadableStream({
857
- async pull(controller) {
858
- let retriesLeft = 3;
859
- while (retriesLeft > 0) {
860
- if (writerClosed) {
861
- controller.close();
862
- return;
863
- }
864
- retriesLeft--;
865
- if (queue.length > 0) {
866
- controller.enqueue(queue.shift());
867
- if (queue.length === 0) {
868
- nextItemReady = new Promise((resolve) => {
869
- resolveNextItemReady = resolve;
870
- });
871
- }
872
- return;
873
- }
874
- else {
875
- await nextItemReady;
876
- }
877
- }
878
- throw new Error("Should only use one retry to get next item in queue.");
879
- },
880
- cancel(reason) {
881
- console.log("Manually closing reader");
882
- readerClosed = true;
883
- },
884
- });
885
- const writable = new WritableStream({
886
- write(chunk, controller) {
887
- if (readerClosed) {
888
- console.log("Reader closed, not writing chunk", chunk);
889
- throw new Error("Reader closed, not writing chunk");
890
- }
891
- queue.push(chunk);
892
- if (queue.length === 1) {
893
- // make sure that await write resolves before corresponding read
894
- process.nextTick(() => resolveNextItemReady());
895
- }
896
- },
897
- abort(reason) {
898
- console.log("Manually closing writer");
899
- writerClosed = true;
900
- resolveNextItemReady();
901
- return Promise.resolve();
902
- },
903
- });
904
- return [readable, writable];
905
- }
906
- function shouldNotResolve(promise, ops) {
907
- return new Promise((resolve, reject) => {
908
- promise
909
- .then((v) => reject(new Error("Should not have resolved, but resolved to " +
910
- JSON.stringify(v))))
911
- .catch(reject);
912
- setTimeout(resolve, ops.timeout);
913
- });
914
- }
915
- function connectedPeers(peer1id, peer2id, { trace = false, peer1role = "peer", peer2role = "peer", } = {}) {
916
- const [inRx1, inTx1] = newStreamPair();
917
- const [outRx1, outTx1] = newStreamPair();
918
- const [inRx2, inTx2] = newStreamPair();
919
- const [outRx2, outTx2] = newStreamPair();
920
- void outRx2
921
- .pipeThrough(new TransformStream({
922
- transform(chunk, controller) {
923
- trace && console.log(`${peer2id} -> ${peer1id}`, chunk);
924
- controller.enqueue(chunk);
925
- },
926
- }))
927
- .pipeTo(inTx1);
928
- void outRx1
929
- .pipeThrough(new TransformStream({
930
- transform(chunk, controller) {
931
- trace && console.log(`${peer1id} -> ${peer2id}`, chunk);
932
- controller.enqueue(chunk);
933
- },
934
- }))
935
- .pipeTo(inTx2);
936
- const peer2AsPeer = {
937
- id: peer2id,
938
- incoming: inRx1,
939
- outgoing: outTx1,
940
- role: peer2role,
941
- };
942
- const peer1AsPeer = {
943
- id: peer1id,
944
- incoming: inRx2,
945
- outgoing: outTx2,
946
- role: peer1role,
822
+ action: "known",
823
+ id: adminID,
947
824
  };
948
- return [peer1AsPeer, peer2AsPeer];
949
825
  }
950
826
  //# sourceMappingURL=sync.test.js.map