cojson 0.0.11 → 0.0.12

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 +16 -35
  9. package/dist/coValue.js +49 -112
  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 +26 -28
  47. package/dist/sync.js +67 -63
  48. package/dist/sync.js.map +1 -1
  49. package/dist/sync.test.js +181 -298
  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 +93 -179
  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 +258 -432
  74. package/src/sync.ts +95 -98
  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: [
@@ -72,9 +70,8 @@ test("Node replies with initial tx and header to empty subscribe", async () => {
72
70
  });
73
71
  });
74
72
  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));
73
+ const [admin, session] = randomAnonymousAccountAndSessionID();
74
+ const node = new LocalNode(admin, session);
78
75
  const team = node.createTeam();
79
76
  const map = team.createMap();
80
77
  map.edit((editable) => {
@@ -91,29 +88,29 @@ test("Node replies with only new tx to subscribe with some known state", async (
91
88
  });
92
89
  const writer = inTx.getWriter();
93
90
  await writer.write({
94
- action: "subscribe",
95
- coValueID: map.coValue.id,
91
+ action: "load",
92
+ id: map.coValue.id,
96
93
  header: true,
97
94
  sessions: {
98
95
  [node.ownSessionID]: 1,
99
96
  },
100
97
  });
101
98
  const reader = outRx.getReader();
102
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
99
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
103
100
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
104
101
  const mapTellKnownStateMsg = await reader.read();
105
102
  expect(mapTellKnownStateMsg.value).toEqual({
106
- action: "tellKnownState",
103
+ action: "known",
107
104
  ...map.coValue.knownState(),
108
105
  });
109
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
106
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
110
107
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
111
108
  const mapNewContentMsg = await reader.read();
112
109
  expect(mapNewContentMsg.value).toEqual({
113
- action: "newContent",
114
- coValueID: map.coValue.id,
110
+ action: "content",
111
+ id: map.coValue.id,
115
112
  header: undefined,
116
- newContent: {
113
+ new: {
117
114
  [node.ownSessionID]: {
118
115
  after: 1,
119
116
  newTransactions: [
@@ -138,9 +135,8 @@ test("Node replies with only new tx to subscribe with some known state", async (
138
135
  });
139
136
  test.todo("TODO: node only replies with new tx to subscribe with some known state, even in the depended on coValues");
140
137
  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));
138
+ const [admin, session] = randomAnonymousAccountAndSessionID();
139
+ const node = new LocalNode(admin, session);
144
140
  const team = node.createTeam();
145
141
  const map = team.createMap();
146
142
  const [inRx, inTx] = newStreamPair();
@@ -153,38 +149,38 @@ test("After subscribing, node sends own known state and new txs to peer", async
153
149
  });
154
150
  const writer = inTx.getWriter();
155
151
  await writer.write({
156
- action: "subscribe",
157
- coValueID: map.coValue.id,
152
+ action: "load",
153
+ id: map.coValue.id,
158
154
  header: false,
159
155
  sessions: {
160
156
  [node.ownSessionID]: 0,
161
157
  },
162
158
  });
163
159
  const reader = outRx.getReader();
164
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
160
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
165
161
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
166
162
  const mapTellKnownStateMsg = await reader.read();
167
163
  expect(mapTellKnownStateMsg.value).toEqual({
168
- action: "tellKnownState",
164
+ action: "known",
169
165
  ...map.coValue.knownState(),
170
166
  });
171
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
167
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
172
168
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
173
169
  const mapNewContentHeaderOnlyMsg = await reader.read();
174
170
  expect(mapNewContentHeaderOnlyMsg.value).toEqual({
175
- action: "newContent",
176
- coValueID: map.coValue.id,
171
+ action: "content",
172
+ id: map.coValue.id,
177
173
  header: map.coValue.header,
178
- newContent: {},
174
+ new: {},
179
175
  });
180
176
  map.edit((editable) => {
181
177
  editable.set("hello", "world", "trusting");
182
178
  });
183
179
  const mapEditMsg1 = await reader.read();
184
180
  expect(mapEditMsg1.value).toEqual({
185
- action: "newContent",
186
- coValueID: map.coValue.id,
187
- newContent: {
181
+ action: "content",
182
+ id: map.coValue.id,
183
+ new: {
188
184
  [node.ownSessionID]: {
189
185
  after: 0,
190
186
  newTransactions: [
@@ -211,9 +207,9 @@ test("After subscribing, node sends own known state and new txs to peer", async
211
207
  });
212
208
  const mapEditMsg2 = await reader.read();
213
209
  expect(mapEditMsg2.value).toEqual({
214
- action: "newContent",
215
- coValueID: map.coValue.id,
216
- newContent: {
210
+ action: "content",
211
+ id: map.coValue.id,
212
+ new: {
217
213
  [node.ownSessionID]: {
218
214
  after: 1,
219
215
  newTransactions: [
@@ -237,9 +233,8 @@ test("After subscribing, node sends own known state and new txs to peer", async
237
233
  });
238
234
  });
239
235
  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));
236
+ const [admin, session] = randomAnonymousAccountAndSessionID();
237
+ const node = new LocalNode(admin, session);
243
238
  const team = node.createTeam();
244
239
  const map = team.createMap();
245
240
  map.edit((editable) => {
@@ -257,28 +252,28 @@ test("Client replies with known new content to tellKnownState from server", asyn
257
252
  // expect((await reader.read()).value).toMatchObject(teamStateEx(team));
258
253
  const writer = inTx.getWriter();
259
254
  await writer.write({
260
- action: "tellKnownState",
261
- coValueID: map.coValue.id,
255
+ action: "known",
256
+ id: map.coValue.id,
262
257
  header: false,
263
258
  sessions: {
264
259
  [node.ownSessionID]: 0,
265
260
  },
266
261
  });
267
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
262
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
268
263
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
269
264
  const mapTellKnownStateMsg = await reader.read();
270
265
  expect(mapTellKnownStateMsg.value).toEqual({
271
- action: "tellKnownState",
266
+ action: "known",
272
267
  ...map.coValue.knownState(),
273
268
  });
274
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
269
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
275
270
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
276
271
  const mapNewContentMsg = await reader.read();
277
272
  expect(mapNewContentMsg.value).toEqual({
278
- action: "newContent",
279
- coValueID: map.coValue.id,
273
+ action: "content",
274
+ id: map.coValue.id,
280
275
  header: map.coValue.header,
281
- newContent: {
276
+ new: {
282
277
  [node.ownSessionID]: {
283
278
  after: 0,
284
279
  newTransactions: [
@@ -302,9 +297,8 @@ test("Client replies with known new content to tellKnownState from server", asyn
302
297
  });
303
298
  });
304
299
  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));
300
+ const [admin, session] = randomAnonymousAccountAndSessionID();
301
+ const node = new LocalNode(admin, session);
308
302
  const team = node.createTeam();
309
303
  const map = team.createMap();
310
304
  const [inRx, inTx] = newStreamPair();
@@ -317,29 +311,29 @@ test("No matter the optimistic known state, node respects invalid known state me
317
311
  });
318
312
  const writer = inTx.getWriter();
319
313
  await writer.write({
320
- action: "subscribe",
321
- coValueID: map.coValue.id,
314
+ action: "load",
315
+ id: map.coValue.id,
322
316
  header: false,
323
317
  sessions: {
324
318
  [node.ownSessionID]: 0,
325
319
  },
326
320
  });
327
321
  const reader = outRx.getReader();
328
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
322
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
329
323
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
330
324
  const mapTellKnownStateMsg = await reader.read();
331
325
  expect(mapTellKnownStateMsg.value).toEqual({
332
- action: "tellKnownState",
326
+ action: "known",
333
327
  ...map.coValue.knownState(),
334
328
  });
335
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
329
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
336
330
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
337
331
  const mapNewContentHeaderOnlyMsg = await reader.read();
338
332
  expect(mapNewContentHeaderOnlyMsg.value).toEqual({
339
- action: "newContent",
340
- coValueID: map.coValue.id,
333
+ action: "content",
334
+ id: map.coValue.id,
341
335
  header: map.coValue.header,
342
- newContent: {},
336
+ new: {},
343
337
  });
344
338
  map.edit((editable) => {
345
339
  editable.set("hello", "world", "trusting");
@@ -350,8 +344,9 @@ test("No matter the optimistic known state, node respects invalid known state me
350
344
  const _mapEditMsg1 = await reader.read();
351
345
  const _mapEditMsg2 = await reader.read();
352
346
  await writer.write({
353
- action: "wrongAssumedKnownState",
354
- coValueID: map.coValue.id,
347
+ action: "known",
348
+ isCorrection: true,
349
+ id: map.coValue.id,
355
350
  header: true,
356
351
  sessions: {
357
352
  [node.ownSessionID]: 1,
@@ -359,10 +354,10 @@ test("No matter the optimistic known state, node respects invalid known state me
359
354
  });
360
355
  const newContentAfterWrongAssumedState = await reader.read();
361
356
  expect(newContentAfterWrongAssumedState.value).toEqual({
362
- action: "newContent",
363
- coValueID: map.coValue.id,
357
+ action: "content",
358
+ id: map.coValue.id,
364
359
  header: undefined,
365
- newContent: {
360
+ new: {
366
361
  [node.ownSessionID]: {
367
362
  after: 1,
368
363
  newTransactions: [
@@ -386,9 +381,8 @@ test("No matter the optimistic known state, node respects invalid known state me
386
381
  });
387
382
  });
388
383
  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));
384
+ const [admin, session] = randomAnonymousAccountAndSessionID();
385
+ const node = new LocalNode(admin, session);
392
386
  const team = node.createTeam();
393
387
  const map = team.createMap();
394
388
  const [inRx, _inTx] = newStreamPair();
@@ -406,9 +400,8 @@ test("If we add a peer, but it never subscribes to a coValue, it won't get any m
406
400
  await expect(shouldNotResolve(reader.read(), { timeout: 100 })).resolves.toBeUndefined();
407
401
  });
408
402
  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));
403
+ const [admin, session] = randomAnonymousAccountAndSessionID();
404
+ const node = new LocalNode(admin, session);
412
405
  const team = node.createTeam();
413
406
  const map = team.createMap();
414
407
  const [inRx, _inTx] = newStreamPair();
@@ -420,32 +413,32 @@ test("If we add a server peer, all updates to all coValues are sent to it, even
420
413
  role: "server",
421
414
  });
422
415
  const reader = outRx.getReader();
416
+ // expect((await reader.read()).value).toMatchObject({
417
+ // action: "load",
418
+ // id: adminID,
419
+ // });
423
420
  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,
421
+ action: "load",
422
+ id: team.teamMap.coValue.id,
430
423
  });
431
424
  const mapSubscribeMsg = await reader.read();
432
425
  expect(mapSubscribeMsg.value).toEqual({
433
- action: "subscribe",
434
- coValueID: map.coValue.id,
426
+ action: "load",
427
+ id: map.coValue.id,
435
428
  header: true,
436
429
  sessions: {},
437
430
  });
438
431
  map.edit((editable) => {
439
432
  editable.set("hello", "world", "trusting");
440
433
  });
441
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
434
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
442
435
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
443
436
  const mapNewContentMsg = await reader.read();
444
437
  expect(mapNewContentMsg.value).toEqual({
445
- action: "newContent",
446
- coValueID: map.coValue.id,
438
+ action: "content",
439
+ id: map.coValue.id,
447
440
  header: map.coValue.header,
448
- newContent: {
441
+ new: {
449
442
  [node.ownSessionID]: {
450
443
  after: 0,
451
444
  newTransactions: [
@@ -469,9 +462,8 @@ test("If we add a server peer, all updates to all coValues are sent to it, even
469
462
  });
470
463
  });
471
464
  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));
465
+ const [admin, session] = randomAnonymousAccountAndSessionID();
466
+ const node = new LocalNode(admin, session);
475
467
  const team = node.createTeam();
476
468
  const [inRx, _inTx] = newStreamPair();
477
469
  const [outRx, outTx] = newStreamPair();
@@ -482,35 +474,34 @@ test("If we add a server peer, newly created coValues are auto-subscribed to", a
482
474
  role: "server",
483
475
  });
484
476
  const reader = outRx.getReader();
477
+ // expect((await reader.read()).value).toMatchObject({
478
+ // action: "load",
479
+ // id: admin.id,
480
+ // });
485
481
  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,
482
+ action: "load",
483
+ id: team.teamMap.coValue.id,
492
484
  });
493
485
  const map = team.createMap();
494
486
  const mapSubscribeMsg = await reader.read();
495
487
  expect(mapSubscribeMsg.value).toEqual({
496
- action: "subscribe",
488
+ action: "load",
497
489
  ...map.coValue.knownState(),
498
490
  });
499
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
491
+ // expect((await reader.read()).value).toMatchObject(admContEx(adminID));
500
492
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
501
493
  const mapContentMsg = await reader.read();
502
494
  expect(mapContentMsg.value).toEqual({
503
- action: "newContent",
504
- coValueID: map.coValue.id,
495
+ action: "content",
496
+ id: map.coValue.id,
505
497
  header: map.coValue.header,
506
- newContent: {},
498
+ new: {},
507
499
  });
508
500
  });
509
501
  test.todo("TODO: when receiving a subscribe response that is behind our optimistic state (due to already sent content), we ignore it");
510
502
  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));
503
+ const [admin, session] = randomAnonymousAccountAndSessionID();
504
+ const node = new LocalNode(admin, session);
514
505
  const team = node.createTeam();
515
506
  const map = team.createMap();
516
507
  const [inRx, _inTx] = newStreamPair();
@@ -522,22 +513,21 @@ test("When we connect a new server peer, we try to sync all existing coValues to
522
513
  role: "server",
523
514
  });
524
515
  const reader = outRx.getReader();
525
- const _adminSubscribeMessage = await reader.read();
516
+ // const _adminSubscribeMessage = await reader.read();
526
517
  const teamSubscribeMessage = await reader.read();
527
518
  expect(teamSubscribeMessage.value).toEqual({
528
- action: "subscribe",
519
+ action: "load",
529
520
  ...team.teamMap.coValue.knownState(),
530
521
  });
531
522
  const secondMessage = await reader.read();
532
523
  expect(secondMessage.value).toEqual({
533
- action: "subscribe",
524
+ action: "load",
534
525
  ...map.coValue.knownState(),
535
526
  });
536
527
  });
537
528
  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));
529
+ const [admin, session] = randomAnonymousAccountAndSessionID();
530
+ const node = new LocalNode(admin, session);
541
531
  const team = node.createTeam();
542
532
  const map = team.createMap();
543
533
  const [inRx, inTx] = newStreamPair();
@@ -550,27 +540,26 @@ test("When receiving a subscribe with a known state that is ahead of our own, pe
550
540
  });
551
541
  const writer = inTx.getWriter();
552
542
  await writer.write({
553
- action: "subscribe",
554
- coValueID: map.coValue.id,
543
+ action: "load",
544
+ id: map.coValue.id,
555
545
  header: true,
556
546
  sessions: {
557
547
  [node.ownSessionID]: 1,
558
548
  },
559
549
  });
560
550
  const reader = outRx.getReader();
561
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
551
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
562
552
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
563
553
  const mapTellKnownState = await reader.read();
564
554
  expect(mapTellKnownState.value).toEqual({
565
- action: "tellKnownState",
555
+ action: "known",
566
556
  ...map.coValue.knownState(),
567
557
  });
568
558
  });
569
559
  test.skip("When replaying creation and transactions of a coValue as new content, the receiving peer integrates this information", async () => {
570
560
  // 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));
561
+ const [admin, session] = randomAnonymousAccountAndSessionID();
562
+ const node1 = new LocalNode(admin, session);
574
563
  const team = node1.createTeam();
575
564
  const [inRx1, inTx1] = newStreamPair();
576
565
  const [outRx1, outTx1] = newStreamPair();
@@ -582,7 +571,7 @@ test.skip("When replaying creation and transactions of a coValue as new content,
582
571
  });
583
572
  const to1 = inTx1.getWriter();
584
573
  const from1 = outRx1.getReader();
585
- const node2 = new LocalNode(admin, newRandomSessionID(adminID));
574
+ const node2 = new LocalNode(admin, newRandomSessionID(admin.id));
586
575
  const [inRx2, inTx2] = newStreamPair();
587
576
  const [outRx2, outTx2] = newStreamPair();
588
577
  node2.sync.addPeer({
@@ -595,47 +584,47 @@ test.skip("When replaying creation and transactions of a coValue as new content,
595
584
  const from2 = outRx2.getReader();
596
585
  const adminSubscribeMessage = await from1.read();
597
586
  expect(adminSubscribeMessage.value).toMatchObject({
598
- action: "subscribe",
599
- coValueID: adminID,
587
+ action: "load",
588
+ id: admin.id,
600
589
  });
601
590
  const teamSubscribeMsg = await from1.read();
602
591
  expect(teamSubscribeMsg.value).toMatchObject({
603
- action: "subscribe",
604
- coValueID: team.teamMap.coValue.id,
592
+ action: "load",
593
+ id: team.teamMap.coValue.id,
605
594
  });
606
595
  await to2.write(adminSubscribeMessage.value);
607
596
  await to2.write(teamSubscribeMsg.value);
608
- const adminTellKnownStateMsg = await from2.read();
609
- expect(adminTellKnownStateMsg.value).toMatchObject(admStateEx(adminID));
597
+ // const adminTellKnownStateMsg = await from2.read();
598
+ // expect(adminTellKnownStateMsg.value).toMatchObject(admStateEx(admin.id));
610
599
  const teamTellKnownStateMsg = await from2.read();
611
600
  expect(teamTellKnownStateMsg.value).toMatchObject(teamStateEx(team));
612
601
  expect(node2.sync.peers["test1"].optimisticKnownStates[team.teamMap.coValue.id]).toBeDefined();
613
- await to1.write(adminTellKnownStateMsg.value);
602
+ // await to1.write(adminTellKnownStateMsg.value!);
614
603
  await to1.write(teamTellKnownStateMsg.value);
615
- const adminContentMsg = await from1.read();
616
- expect(adminContentMsg.value).toMatchObject(admContEx(adminID));
604
+ // const adminContentMsg = await from1.read();
605
+ // expect(adminContentMsg.value).toMatchObject(admContEx(admin.id));
617
606
  const teamContentMsg = await from1.read();
618
607
  expect(teamContentMsg.value).toMatchObject(teamContentEx(team));
619
- await to2.write(adminContentMsg.value);
608
+ // await to2.write(adminContentMsg.value!);
620
609
  await to2.write(teamContentMsg.value);
621
610
  const map = team.createMap();
622
611
  const mapSubscriptionMsg = await from1.read();
623
612
  expect(mapSubscriptionMsg.value).toMatchObject({
624
- action: "subscribe",
625
- coValueID: map.coValue.id,
613
+ action: "load",
614
+ id: map.coValue.id,
626
615
  });
627
616
  const mapNewContentMsg = await from1.read();
628
617
  expect(mapNewContentMsg.value).toEqual({
629
- action: "newContent",
630
- coValueID: map.coValue.id,
618
+ action: "content",
619
+ id: map.coValue.id,
631
620
  header: map.coValue.header,
632
- newContent: {},
621
+ new: {},
633
622
  });
634
623
  await to2.write(mapSubscriptionMsg.value);
635
624
  const mapTellKnownStateMsg = await from2.read();
636
625
  expect(mapTellKnownStateMsg.value).toEqual({
637
- action: "tellKnownState",
638
- coValueID: map.coValue.id,
626
+ action: "known",
627
+ id: map.coValue.id,
639
628
  header: false,
640
629
  sessions: {},
641
630
  });
@@ -651,15 +640,14 @@ test.skip("When replaying creation and transactions of a coValue as new content,
651
640
  });
652
641
  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
642
  // 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));
643
+ const [admin, session] = randomAnonymousAccountAndSessionID();
644
+ const node1 = new LocalNode(admin, session);
657
645
  const team = node1.createTeam();
658
646
  const map = team.createMap();
659
647
  map.edit((editable) => {
660
648
  editable.set("hello", "world", "trusting");
661
649
  });
662
- const node2 = new LocalNode(admin, newRandomSessionID(adminID));
650
+ const node2 = new LocalNode(admin, newRandomSessionID(admin.id));
663
651
  const [node1asPeer, node2asPeer] = connectedPeers("peer1", "peer2");
664
652
  node1.sync.addPeer(node2asPeer);
665
653
  node2.sync.addPeer(node1asPeer);
@@ -667,24 +655,22 @@ test.skip("When loading a coValue on one node, the server node it is requested f
667
655
  expect(expectMap(node2.expectCoValueLoaded(map.coValue.id).getCurrentContent()).get("hello")).toEqual("world");
668
656
  });
669
657
  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));
658
+ const [admin, session] = randomAnonymousAccountAndSessionID();
659
+ const client1 = new LocalNode(admin, session);
673
660
  const team = client1.createTeam();
674
661
  const map = team.createMap();
675
662
  map.edit((editable) => {
676
663
  editable.set("hello", "world", "trusting");
677
664
  });
678
- const serverUser = newRandomAgentCredential("serverUser");
679
- const serverUserID = getAgentID(getAgent(serverUser));
680
- const server = new LocalNode(serverUser, newRandomSessionID(serverUserID));
665
+ const [serverUser, serverSession] = randomAnonymousAccountAndSessionID();
666
+ const server = new LocalNode(serverUser, serverSession);
681
667
  const [serverAsPeer, client1AsPeer] = connectedPeers("server", "client1", {
682
668
  peer1role: "server",
683
669
  peer2role: "client",
684
670
  });
685
671
  client1.sync.addPeer(serverAsPeer);
686
672
  server.sync.addPeer(client1AsPeer);
687
- const client2 = new LocalNode(admin, newRandomSessionID(adminID));
673
+ const client2 = new LocalNode(admin, newRandomSessionID(admin.id));
688
674
  const [serverAsOtherPeer, client2AsPeer] = connectedPeers("server", "client2", { peer1role: "server", peer2role: "client" });
689
675
  client2.sync.addPeer(serverAsOtherPeer);
690
676
  server.sync.addPeer(client2AsPeer);
@@ -692,17 +678,15 @@ test("Can sync a coValue through a server to another client", async () => {
692
678
  expect(expectMap(mapOnClient2.getCurrentContent()).get("hello")).toEqual("world");
693
679
  });
694
680
  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));
681
+ const [admin, session] = randomAnonymousAccountAndSessionID();
682
+ const client1 = new LocalNode(admin, session);
698
683
  const team = client1.createTeam();
699
684
  const map = team.createMap();
700
685
  map.edit((editable) => {
701
686
  editable.set("hello", "world", "private");
702
687
  });
703
- const serverUser = newRandomAgentCredential("serverUser");
704
- const serverUserID = getAgentID(getAgent(serverUser));
705
- const server = new LocalNode(serverUser, newRandomSessionID(serverUserID));
688
+ const [serverUser, serverSession] = randomAnonymousAccountAndSessionID();
689
+ const server = new LocalNode(serverUser, serverSession);
706
690
  const [serverAsPeer, client1AsPeer] = connectedPeers("server", "client1", {
707
691
  trace: true,
708
692
  peer1role: "server",
@@ -710,7 +694,7 @@ test("Can sync a coValue with private transactions through a server to another c
710
694
  });
711
695
  client1.sync.addPeer(serverAsPeer);
712
696
  server.sync.addPeer(client1AsPeer);
713
- const client2 = new LocalNode(admin, newRandomSessionID(adminID));
697
+ const client2 = new LocalNode(admin, newRandomSessionID(admin.id));
714
698
  const [serverAsOtherPeer, client2AsPeer] = connectedPeers("server", "client2", { trace: true, peer1role: "server", peer2role: "client" });
715
699
  client2.sync.addPeer(serverAsOtherPeer);
716
700
  server.sync.addPeer(client2AsPeer);
@@ -718,9 +702,8 @@ test("Can sync a coValue with private transactions through a server to another c
718
702
  expect(expectMap(mapOnClient2.getCurrentContent()).get("hello")).toEqual("world");
719
703
  });
720
704
  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));
705
+ const [admin, session] = randomAnonymousAccountAndSessionID();
706
+ const node = new LocalNode(admin, session);
724
707
  const team = node.createTeam();
725
708
  const [inRx, inTx] = newStreamPair();
726
709
  const [outRx, outTx] = newStreamPair();
@@ -731,37 +714,36 @@ test("When a peer's incoming/readable stream closes, we remove the peer", async
731
714
  role: "server",
732
715
  });
733
716
  const reader = outRx.getReader();
717
+ // expect((await reader.read()).value).toMatchObject({
718
+ // action: "load",
719
+ // id: admin.id,
720
+ // });
734
721
  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,
722
+ action: "load",
723
+ id: team.teamMap.coValue.id,
741
724
  });
742
725
  const map = team.createMap();
743
726
  const mapSubscribeMsg = await reader.read();
744
727
  expect(mapSubscribeMsg.value).toEqual({
745
- action: "subscribe",
728
+ action: "load",
746
729
  ...map.coValue.knownState(),
747
730
  });
748
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
731
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
749
732
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
750
733
  const mapContentMsg = await reader.read();
751
734
  expect(mapContentMsg.value).toEqual({
752
- action: "newContent",
753
- coValueID: map.coValue.id,
735
+ action: "content",
736
+ id: map.coValue.id,
754
737
  header: map.coValue.header,
755
- newContent: {},
738
+ new: {},
756
739
  });
757
740
  await inTx.abort();
758
741
  await new Promise((resolve) => setTimeout(resolve, 100));
759
742
  expect(node.sync.peers["test"]).toBeUndefined();
760
743
  });
761
744
  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));
745
+ const [admin, session] = randomAnonymousAccountAndSessionID();
746
+ const node = new LocalNode(admin, session);
765
747
  const team = node.createTeam();
766
748
  const [inRx, inTx] = newStreamPair();
767
749
  const [outRx, outTx] = newStreamPair();
@@ -772,28 +754,28 @@ test("When a peer's outgoing/writable stream closes, we remove the peer", async
772
754
  role: "server",
773
755
  });
774
756
  const reader = outRx.getReader();
757
+ // expect((await reader.read()).value).toMatchObject({
758
+ // action: "load",
759
+ // id: admin.id,
760
+ // });
775
761
  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,
762
+ action: "load",
763
+ id: team.teamMap.coValue.id,
782
764
  });
783
765
  const map = team.createMap();
784
766
  const mapSubscribeMsg = await reader.read();
785
767
  expect(mapSubscribeMsg.value).toEqual({
786
- action: "subscribe",
768
+ action: "load",
787
769
  ...map.coValue.knownState(),
788
770
  });
789
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
771
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
790
772
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
791
773
  const mapContentMsg = await reader.read();
792
774
  expect(mapContentMsg.value).toEqual({
793
- action: "newContent",
794
- coValueID: map.coValue.id,
775
+ action: "content",
776
+ id: map.coValue.id,
795
777
  header: map.coValue.header,
796
- newContent: {},
778
+ new: {},
797
779
  });
798
780
  reader.releaseLock();
799
781
  await outRx.cancel();
@@ -804,16 +786,19 @@ test("When a peer's outgoing/writable stream closes, we remove the peer", async
804
786
  expect(node.sync.peers["test"]).toBeUndefined();
805
787
  });
806
788
  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));
789
+ const [admin, session] = randomAnonymousAccountAndSessionID();
790
+ const node1 = new LocalNode(admin, session);
810
791
  const team = node1.createTeam();
811
792
  const map = team.createMap();
812
793
  map.edit((editable) => {
813
794
  editable.set("hello", "world", "trusting");
814
795
  });
815
- const node2 = new LocalNode(admin, newRandomSessionID(adminID));
816
- const [node1asPeer, node2asPeer] = connectedPeers("peer1", "peer2", { peer1role: 'server', peer2role: 'client', trace: true });
796
+ const node2 = new LocalNode(admin, newRandomSessionID(admin.id));
797
+ const [node1asPeer, node2asPeer] = connectedPeers("peer1", "peer2", {
798
+ peer1role: "server",
799
+ peer2role: "client",
800
+ trace: true,
801
+ });
817
802
  node1.sync.addPeer(node2asPeer);
818
803
  const mapOnNode2Promise = node2.loadCoValue(map.coValue.id);
819
804
  expect(node2.coValues[map.coValue.id]?.state).toEqual("loading");
@@ -823,128 +808,26 @@ test("If we start loading a coValue before connecting to a peer that has it, it
823
808
  });
824
809
  function teamContentEx(team) {
825
810
  return {
826
- action: "newContent",
827
- coValueID: team.teamMap.coValue.id,
811
+ action: "content",
812
+ id: team.teamMap.coValue.id,
828
813
  };
829
814
  }
830
815
  function admContEx(adminID) {
831
816
  return {
832
- action: "newContent",
833
- coValueID: adminID,
817
+ action: "content",
818
+ id: adminID,
834
819
  };
835
820
  }
836
821
  function teamStateEx(team) {
837
822
  return {
838
- action: "tellKnownState",
839
- coValueID: team.teamMap.coValue.id,
823
+ action: "known",
824
+ id: team.teamMap.coValue.id,
840
825
  };
841
826
  }
842
827
  function admStateEx(adminID) {
843
828
  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,
829
+ action: "known",
830
+ id: adminID,
947
831
  };
948
- return [peer1AsPeer, peer2AsPeer];
949
832
  }
950
833
  //# sourceMappingURL=sync.test.js.map