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/src/sync.test.ts CHANGED
@@ -1,115 +1,102 @@
1
- import {
2
- getAgent,
3
- getAgentID,
4
- newRandomAgentCredential,
5
- newRandomSessionID,
6
- } from './coValue.js';
7
- import { LocalNode } from './node.js';
8
- import { Peer, PeerID, SyncMessage } from './sync.js';
9
- import { expectMap } from './contentType.js';
10
- import { MapOpPayload } from './contentTypes/coMap.js';
11
- import { Team } from './permissions.js';
1
+ import { newRandomSessionID } from "./coValue.js";
2
+ import { LocalNode } from "./node.js";
3
+ import { Peer, PeerID, SyncMessage } from "./sync.js";
4
+ import { expectMap } from "./contentType.js";
5
+ import { MapOpPayload } from "./contentTypes/coMap.js";
6
+ import { Team } from "./permissions.js";
12
7
  import {
13
8
  ReadableStream,
14
9
  WritableStream,
15
10
  TransformStream,
16
11
  } from "isomorphic-streams";
17
- import { AgentID } from './ids.js';
18
-
19
- test(
20
- "Node replies with initial tx and header to empty subscribe",
21
- async () => {
22
- const admin = newRandomAgentCredential("admin");
23
- const adminID = getAgentID(getAgent(admin));
12
+ import { connectedPeers, newStreamPair, randomAnonymousAccountAndSessionID, shouldNotResolve } from "./testUtils.js";
13
+ import { AccountID } from "./account.js";
24
14
 
25
- const node = new LocalNode(admin, newRandomSessionID(adminID));
15
+ test("Node replies with initial tx and header to empty subscribe", async () => {
16
+ const [admin, session] = randomAnonymousAccountAndSessionID();
17
+ const node = new LocalNode(admin, session);
26
18
 
27
- const team = node.createTeam();
28
-
29
- const map = team.createMap();
19
+ const team = node.createTeam();
30
20
 
31
- map.edit((editable) => {
32
- editable.set("hello", "world", "trusting");
33
- });
21
+ const map = team.createMap();
34
22
 
35
- const [inRx, inTx] = newStreamPair<SyncMessage>();
36
- const [outRx, outTx] = newStreamPair<SyncMessage>();
23
+ map.edit((editable) => {
24
+ editable.set("hello", "world", "trusting");
25
+ });
37
26
 
38
- node.sync.addPeer({
39
- id: "test",
40
- incoming: inRx,
41
- outgoing: outTx,
42
- role: "peer",
43
- });
27
+ const [inRx, inTx] = newStreamPair<SyncMessage>();
28
+ const [outRx, outTx] = newStreamPair<SyncMessage>();
44
29
 
45
- const writer = inTx.getWriter();
30
+ node.sync.addPeer({
31
+ id: "test",
32
+ incoming: inRx,
33
+ outgoing: outTx,
34
+ role: "peer",
35
+ });
46
36
 
47
- await writer.write({
48
- action: "subscribe",
49
- coValueID: map.coValue.id,
50
- header: false,
51
- sessions: {},
52
- });
37
+ const writer = inTx.getWriter();
53
38
 
54
- const reader = outRx.getReader();
39
+ await writer.write({
40
+ action: "load",
41
+ id: map.coValue.id,
42
+ header: false,
43
+ sessions: {},
44
+ });
55
45
 
56
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
57
- expect((await reader.read()).value).toMatchObject(teamStateEx(team));
46
+ const reader = outRx.getReader();
58
47
 
59
- const mapTellKnownStateMsg = await reader.read();
60
- expect(mapTellKnownStateMsg.value).toEqual({
61
- action: "tellKnownState",
62
- ...map.coValue.knownState(),
63
- } satisfies SyncMessage);
48
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
49
+ expect((await reader.read()).value).toMatchObject(teamStateEx(team));
64
50
 
65
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
66
- expect((await reader.read()).value).toMatchObject(teamContentEx(team));
51
+ const mapTellKnownStateMsg = await reader.read();
52
+ expect(mapTellKnownStateMsg.value).toEqual({
53
+ action: "known",
54
+ ...map.coValue.knownState(),
55
+ } satisfies SyncMessage);
67
56
 
68
- const newContentMsg = await reader.read();
57
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
58
+ expect((await reader.read()).value).toMatchObject(teamContentEx(team));
69
59
 
70
- expect(newContentMsg.value).toEqual({
71
- action: "newContent",
72
- coValueID: map.coValue.id,
73
- header: {
74
- type: "comap",
75
- ruleset: { type: "ownedByTeam", team: team.id },
76
- meta: null,
77
- createdAt: map.coValue.header.createdAt,
78
- uniqueness: map.coValue.header.uniqueness,
79
- publicNickname: "map",
80
- },
81
- newContent: {
82
- [node.ownSessionID]: {
83
- after: 0,
84
- newTransactions: [
85
- {
86
- privacy: "trusting",
87
- madeAt: map.coValue.sessions[node.ownSessionID]!
88
- .transactions[0]!.madeAt,
89
- changes: [
90
- {
91
- op: "insert",
92
- key: "hello",
93
- value: "world",
94
- } satisfies MapOpPayload<string, string>,
95
- ],
96
- },
97
- ],
98
- lastHash:
99
- map.coValue.sessions[node.ownSessionID]!.lastHash!,
100
- lastSignature:
101
- map.coValue.sessions[node.ownSessionID]!.lastSignature!,
102
- },
60
+ const newContentMsg = await reader.read();
61
+
62
+ expect(newContentMsg.value).toEqual({
63
+ action: "content",
64
+ id: map.coValue.id,
65
+ header: {
66
+ type: "comap",
67
+ ruleset: { type: "ownedByTeam", team: team.id },
68
+ meta: null,
69
+ createdAt: map.coValue.header.createdAt,
70
+ uniqueness: map.coValue.header.uniqueness,
71
+ },
72
+ new: {
73
+ [node.ownSessionID]: {
74
+ after: 0,
75
+ newTransactions: [
76
+ {
77
+ privacy: "trusting" as const,
78
+ madeAt: map.coValue.sessions[node.ownSessionID]!
79
+ .transactions[0]!.madeAt,
80
+ changes: [
81
+ {
82
+ op: "insert",
83
+ key: "hello",
84
+ value: "world",
85
+ } satisfies MapOpPayload<string, string>,
86
+ ],
87
+ },
88
+ ],
89
+ lastHash: map.coValue.sessions[node.ownSessionID]!.lastHash!,
90
+ lastSignature:
91
+ map.coValue.sessions[node.ownSessionID]!.lastSignature!,
103
92
  },
104
- } satisfies SyncMessage);
105
- },
106
- );
93
+ },
94
+ } satisfies SyncMessage);
95
+ });
107
96
 
108
97
  test("Node replies with only new tx to subscribe with some known state", async () => {
109
- const admin = newRandomAgentCredential("admin");
110
- const adminID = getAgentID(getAgent(admin));
111
-
112
- const node = new LocalNode(admin, newRandomSessionID(adminID));
98
+ const [admin, session] = randomAnonymousAccountAndSessionID();
99
+ const node = new LocalNode(admin, session);
113
100
 
114
101
  const team = node.createTeam();
115
102
 
@@ -133,8 +120,8 @@ test("Node replies with only new tx to subscribe with some known state", async (
133
120
  const writer = inTx.getWriter();
134
121
 
135
122
  await writer.write({
136
- action: "subscribe",
137
- coValueID: map.coValue.id,
123
+ action: "load",
124
+ id: map.coValue.id,
138
125
  header: true,
139
126
  sessions: {
140
127
  [node.ownSessionID]: 1,
@@ -143,30 +130,30 @@ test("Node replies with only new tx to subscribe with some known state", async (
143
130
 
144
131
  const reader = outRx.getReader();
145
132
 
146
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
133
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
147
134
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
148
135
 
149
136
  const mapTellKnownStateMsg = await reader.read();
150
137
  expect(mapTellKnownStateMsg.value).toEqual({
151
- action: "tellKnownState",
138
+ action: "known",
152
139
  ...map.coValue.knownState(),
153
140
  } satisfies SyncMessage);
154
141
 
155
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
142
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
156
143
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
157
144
 
158
145
  const mapNewContentMsg = await reader.read();
159
146
 
160
147
  expect(mapNewContentMsg.value).toEqual({
161
- action: "newContent",
162
- coValueID: map.coValue.id,
148
+ action: "content",
149
+ id: map.coValue.id,
163
150
  header: undefined,
164
- newContent: {
151
+ new: {
165
152
  [node.ownSessionID]: {
166
153
  after: 1,
167
154
  newTransactions: [
168
155
  {
169
- privacy: "trusting",
156
+ privacy: "trusting" as const,
170
157
  madeAt: map.coValue.sessions[node.ownSessionID]!
171
158
  .transactions[1]!.madeAt,
172
159
  changes: [
@@ -187,14 +174,12 @@ test("Node replies with only new tx to subscribe with some known state", async (
187
174
  });
188
175
 
189
176
  test.todo(
190
- "TODO: node only replies with new tx to subscribe with some known state, even in the depended on coValues",
177
+ "TODO: node only replies with new tx to subscribe with some known state, even in the depended on coValues"
191
178
  );
192
179
 
193
180
  test("After subscribing, node sends own known state and new txs to peer", async () => {
194
- const admin = newRandomAgentCredential("admin");
195
- const adminID = getAgentID(getAgent(admin));
196
-
197
- const node = new LocalNode(admin, newRandomSessionID(adminID));
181
+ const [admin, session] = randomAnonymousAccountAndSessionID();
182
+ const node = new LocalNode(admin, session);
198
183
 
199
184
  const team = node.createTeam();
200
185
 
@@ -213,8 +198,8 @@ test("After subscribing, node sends own known state and new txs to peer", async
213
198
  const writer = inTx.getWriter();
214
199
 
215
200
  await writer.write({
216
- action: "subscribe",
217
- coValueID: map.coValue.id,
201
+ action: "load",
202
+ id: map.coValue.id,
218
203
  header: false,
219
204
  sessions: {
220
205
  [node.ownSessionID]: 0,
@@ -223,25 +208,25 @@ test("After subscribing, node sends own known state and new txs to peer", async
223
208
 
224
209
  const reader = outRx.getReader();
225
210
 
226
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
211
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
227
212
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
228
213
 
229
214
  const mapTellKnownStateMsg = await reader.read();
230
215
  expect(mapTellKnownStateMsg.value).toEqual({
231
- action: "tellKnownState",
216
+ action: "known",
232
217
  ...map.coValue.knownState(),
233
218
  } satisfies SyncMessage);
234
219
 
235
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
220
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
236
221
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
237
222
 
238
223
  const mapNewContentHeaderOnlyMsg = await reader.read();
239
224
 
240
225
  expect(mapNewContentHeaderOnlyMsg.value).toEqual({
241
- action: "newContent",
242
- coValueID: map.coValue.id,
226
+ action: "content",
227
+ id: map.coValue.id,
243
228
  header: map.coValue.header,
244
- newContent: {},
229
+ new: {},
245
230
  } satisfies SyncMessage);
246
231
 
247
232
  map.edit((editable) => {
@@ -251,14 +236,14 @@ test("After subscribing, node sends own known state and new txs to peer", async
251
236
  const mapEditMsg1 = await reader.read();
252
237
 
253
238
  expect(mapEditMsg1.value).toEqual({
254
- action: "newContent",
255
- coValueID: map.coValue.id,
256
- newContent: {
239
+ action: "content",
240
+ id: map.coValue.id,
241
+ new: {
257
242
  [node.ownSessionID]: {
258
243
  after: 0,
259
244
  newTransactions: [
260
245
  {
261
- privacy: "trusting",
246
+ privacy: "trusting" as const,
262
247
  madeAt: map.coValue.sessions[node.ownSessionID]!
263
248
  .transactions[0]!.madeAt,
264
249
  changes: [
@@ -284,14 +269,14 @@ test("After subscribing, node sends own known state and new txs to peer", async
284
269
  const mapEditMsg2 = await reader.read();
285
270
 
286
271
  expect(mapEditMsg2.value).toEqual({
287
- action: "newContent",
288
- coValueID: map.coValue.id,
289
- newContent: {
272
+ action: "content",
273
+ id: map.coValue.id,
274
+ new: {
290
275
  [node.ownSessionID]: {
291
276
  after: 1,
292
277
  newTransactions: [
293
278
  {
294
- privacy: "trusting",
279
+ privacy: "trusting" as const,
295
280
  madeAt: map.coValue.sessions[node.ownSessionID]!
296
281
  .transactions[1]!.madeAt,
297
282
  changes: [
@@ -312,10 +297,8 @@ test("After subscribing, node sends own known state and new txs to peer", async
312
297
  });
313
298
 
314
299
  test("Client replies with known new content to tellKnownState from server", async () => {
315
- const admin = newRandomAgentCredential("admin");
316
- const adminID = getAgentID(getAgent(admin));
317
-
318
- const node = new LocalNode(admin, newRandomSessionID(adminID));
300
+ const [admin, session] = randomAnonymousAccountAndSessionID();
301
+ const node = new LocalNode(admin, session);
319
302
 
320
303
  const team = node.createTeam();
321
304
 
@@ -342,38 +325,38 @@ test("Client replies with known new content to tellKnownState from server", asyn
342
325
  const writer = inTx.getWriter();
343
326
 
344
327
  await writer.write({
345
- action: "tellKnownState",
346
- coValueID: map.coValue.id,
328
+ action: "known",
329
+ id: map.coValue.id,
347
330
  header: false,
348
331
  sessions: {
349
332
  [node.ownSessionID]: 0,
350
333
  },
351
334
  });
352
335
 
353
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
336
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
354
337
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
355
338
 
356
339
  const mapTellKnownStateMsg = await reader.read();
357
340
  expect(mapTellKnownStateMsg.value).toEqual({
358
- action: "tellKnownState",
341
+ action: "known",
359
342
  ...map.coValue.knownState(),
360
343
  } satisfies SyncMessage);
361
344
 
362
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
345
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
363
346
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
364
347
 
365
348
  const mapNewContentMsg = await reader.read();
366
349
 
367
350
  expect(mapNewContentMsg.value).toEqual({
368
- action: "newContent",
369
- coValueID: map.coValue.id,
351
+ action: "content",
352
+ id: map.coValue.id,
370
353
  header: map.coValue.header,
371
- newContent: {
354
+ new: {
372
355
  [node.ownSessionID]: {
373
356
  after: 0,
374
357
  newTransactions: [
375
358
  {
376
- privacy: "trusting",
359
+ privacy: "trusting" as const,
377
360
  madeAt: map.coValue.sessions[node.ownSessionID]!
378
361
  .transactions[0]!.madeAt,
379
362
  changes: [
@@ -394,10 +377,8 @@ test("Client replies with known new content to tellKnownState from server", asyn
394
377
  });
395
378
 
396
379
  test("No matter the optimistic known state, node respects invalid known state messages and resyncs", async () => {
397
- const admin = newRandomAgentCredential("admin");
398
- const adminID = getAgentID(getAgent(admin));
399
-
400
- const node = new LocalNode(admin, newRandomSessionID(adminID));
380
+ const [admin, session] = randomAnonymousAccountAndSessionID();
381
+ const node = new LocalNode(admin, session);
401
382
 
402
383
  const team = node.createTeam();
403
384
 
@@ -416,8 +397,8 @@ test("No matter the optimistic known state, node respects invalid known state me
416
397
  const writer = inTx.getWriter();
417
398
 
418
399
  await writer.write({
419
- action: "subscribe",
420
- coValueID: map.coValue.id,
400
+ action: "load",
401
+ id: map.coValue.id,
421
402
  header: false,
422
403
  sessions: {
423
404
  [node.ownSessionID]: 0,
@@ -426,25 +407,25 @@ test("No matter the optimistic known state, node respects invalid known state me
426
407
 
427
408
  const reader = outRx.getReader();
428
409
 
429
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
410
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
430
411
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
431
412
 
432
413
  const mapTellKnownStateMsg = await reader.read();
433
414
  expect(mapTellKnownStateMsg.value).toEqual({
434
- action: "tellKnownState",
415
+ action: "known",
435
416
  ...map.coValue.knownState(),
436
417
  } satisfies SyncMessage);
437
418
 
438
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
419
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
439
420
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
440
421
 
441
422
  const mapNewContentHeaderOnlyMsg = await reader.read();
442
423
 
443
424
  expect(mapNewContentHeaderOnlyMsg.value).toEqual({
444
- action: "newContent",
445
- coValueID: map.coValue.id,
425
+ action: "content",
426
+ id: map.coValue.id,
446
427
  header: map.coValue.header,
447
- newContent: {},
428
+ new: {},
448
429
  } satisfies SyncMessage);
449
430
 
450
431
  map.edit((editable) => {
@@ -459,8 +440,9 @@ test("No matter the optimistic known state, node respects invalid known state me
459
440
  const _mapEditMsg2 = await reader.read();
460
441
 
461
442
  await writer.write({
462
- action: "wrongAssumedKnownState",
463
- coValueID: map.coValue.id,
443
+ action: "known",
444
+ isCorrection: true,
445
+ id: map.coValue.id,
464
446
  header: true,
465
447
  sessions: {
466
448
  [node.ownSessionID]: 1,
@@ -470,15 +452,15 @@ test("No matter the optimistic known state, node respects invalid known state me
470
452
  const newContentAfterWrongAssumedState = await reader.read();
471
453
 
472
454
  expect(newContentAfterWrongAssumedState.value).toEqual({
473
- action: "newContent",
474
- coValueID: map.coValue.id,
455
+ action: "content",
456
+ id: map.coValue.id,
475
457
  header: undefined,
476
- newContent: {
458
+ new: {
477
459
  [node.ownSessionID]: {
478
460
  after: 1,
479
461
  newTransactions: [
480
462
  {
481
- privacy: "trusting",
463
+ privacy: "trusting" as const,
482
464
  madeAt: map.coValue.sessions[node.ownSessionID]!
483
465
  .transactions[1]!.madeAt,
484
466
  changes: [
@@ -499,10 +481,8 @@ test("No matter the optimistic known state, node respects invalid known state me
499
481
  });
500
482
 
501
483
  test("If we add a peer, but it never subscribes to a coValue, it won't get any messages", async () => {
502
- const admin = newRandomAgentCredential("admin");
503
- const adminID = getAgentID(getAgent(admin));
504
-
505
- const node = new LocalNode(admin, newRandomSessionID(adminID));
484
+ const [admin, session] = randomAnonymousAccountAndSessionID();
485
+ const node = new LocalNode(admin, session);
506
486
 
507
487
  const team = node.createTeam();
508
488
 
@@ -524,14 +504,14 @@ test("If we add a peer, but it never subscribes to a coValue, it won't get any m
524
504
 
525
505
  const reader = outRx.getReader();
526
506
 
527
- await expect(shouldNotResolve(reader.read(), {timeout: 100})).resolves.toBeUndefined();
507
+ await expect(
508
+ shouldNotResolve(reader.read(), { timeout: 100 })
509
+ ).resolves.toBeUndefined();
528
510
  });
529
511
 
530
512
  test("If we add a server peer, all updates to all coValues are sent to it, even if it doesn't subscribe", async () => {
531
- const admin = newRandomAgentCredential("admin");
532
- const adminID = getAgentID(getAgent(admin));
533
-
534
- const node = new LocalNode(admin, newRandomSessionID(adminID));
513
+ const [admin, session] = randomAnonymousAccountAndSessionID();
514
+ const node = new LocalNode(admin, session);
535
515
 
536
516
  const team = node.createTeam();
537
517
 
@@ -548,20 +528,20 @@ test("If we add a server peer, all updates to all coValues are sent to it, even
548
528
  });
549
529
 
550
530
  const reader = outRx.getReader();
531
+ // expect((await reader.read()).value).toMatchObject({
532
+ // action: "load",
533
+ // id: adminID,
534
+ // });
551
535
  expect((await reader.read()).value).toMatchObject({
552
- action: "subscribe",
553
- coValueID: adminID,
554
- });
555
- expect((await reader.read()).value).toMatchObject({
556
- action: "subscribe",
557
- coValueID: team.teamMap.coValue.id,
536
+ action: "load",
537
+ id: team.teamMap.coValue.id,
558
538
  });
559
539
 
560
540
  const mapSubscribeMsg = await reader.read();
561
541
 
562
542
  expect(mapSubscribeMsg.value).toEqual({
563
- action: "subscribe",
564
- coValueID: map.coValue.id,
543
+ action: "load",
544
+ id: map.coValue.id,
565
545
  header: true,
566
546
  sessions: {},
567
547
  } satisfies SyncMessage);
@@ -570,21 +550,21 @@ test("If we add a server peer, all updates to all coValues are sent to it, even
570
550
  editable.set("hello", "world", "trusting");
571
551
  });
572
552
 
573
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
553
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
574
554
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
575
555
 
576
556
  const mapNewContentMsg = await reader.read();
577
557
 
578
558
  expect(mapNewContentMsg.value).toEqual({
579
- action: "newContent",
580
- coValueID: map.coValue.id,
559
+ action: "content",
560
+ id: map.coValue.id,
581
561
  header: map.coValue.header,
582
- newContent: {
562
+ new: {
583
563
  [node.ownSessionID]: {
584
564
  after: 0,
585
565
  newTransactions: [
586
566
  {
587
- privacy: "trusting",
567
+ privacy: "trusting" as const,
588
568
  madeAt: map.coValue.sessions[node.ownSessionID]!
589
569
  .transactions[0]!.madeAt,
590
570
  changes: [
@@ -605,10 +585,8 @@ test("If we add a server peer, all updates to all coValues are sent to it, even
605
585
  });
606
586
 
607
587
  test("If we add a server peer, newly created coValues are auto-subscribed to", async () => {
608
- const admin = newRandomAgentCredential("admin");
609
- const adminID = getAgentID(getAgent(admin));
610
-
611
- const node = new LocalNode(admin, newRandomSessionID(adminID));
588
+ const [admin, session] = randomAnonymousAccountAndSessionID();
589
+ const node = new LocalNode(admin, session);
612
590
 
613
591
  const team = node.createTeam();
614
592
 
@@ -623,13 +601,13 @@ test("If we add a server peer, newly created coValues are auto-subscribed to", a
623
601
  });
624
602
 
625
603
  const reader = outRx.getReader();
604
+ // expect((await reader.read()).value).toMatchObject({
605
+ // action: "load",
606
+ // id: admin.id,
607
+ // });
626
608
  expect((await reader.read()).value).toMatchObject({
627
- action: "subscribe",
628
- coValueID: adminID,
629
- });
630
- expect((await reader.read()).value).toMatchObject({
631
- action: "subscribe",
632
- coValueID: team.teamMap.coValue.id,
609
+ action: "load",
610
+ id: team.teamMap.coValue.id,
633
611
  });
634
612
 
635
613
  const map = team.createMap();
@@ -637,32 +615,30 @@ test("If we add a server peer, newly created coValues are auto-subscribed to", a
637
615
  const mapSubscribeMsg = await reader.read();
638
616
 
639
617
  expect(mapSubscribeMsg.value).toEqual({
640
- action: "subscribe",
618
+ action: "load",
641
619
  ...map.coValue.knownState(),
642
620
  } satisfies SyncMessage);
643
621
 
644
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
622
+ // expect((await reader.read()).value).toMatchObject(admContEx(adminID));
645
623
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
646
624
 
647
625
  const mapContentMsg = await reader.read();
648
626
 
649
627
  expect(mapContentMsg.value).toEqual({
650
- action: "newContent",
651
- coValueID: map.coValue.id,
628
+ action: "content",
629
+ id: map.coValue.id,
652
630
  header: map.coValue.header,
653
- newContent: {},
631
+ new: {},
654
632
  } satisfies SyncMessage);
655
633
  });
656
634
 
657
635
  test.todo(
658
- "TODO: when receiving a subscribe response that is behind our optimistic state (due to already sent content), we ignore it",
636
+ "TODO: when receiving a subscribe response that is behind our optimistic state (due to already sent content), we ignore it"
659
637
  );
660
638
 
661
639
  test("When we connect a new server peer, we try to sync all existing coValues to it", async () => {
662
- const admin = newRandomAgentCredential("admin");
663
- const adminID = getAgentID(getAgent(admin));
664
-
665
- const node = new LocalNode(admin, newRandomSessionID(adminID));
640
+ const [admin, session] = randomAnonymousAccountAndSessionID();
641
+ const node = new LocalNode(admin, session);
666
642
 
667
643
  const team = node.createTeam();
668
644
 
@@ -680,27 +656,25 @@ test("When we connect a new server peer, we try to sync all existing coValues to
680
656
 
681
657
  const reader = outRx.getReader();
682
658
 
683
- const _adminSubscribeMessage = await reader.read();
659
+ // const _adminSubscribeMessage = await reader.read();
684
660
  const teamSubscribeMessage = await reader.read();
685
661
 
686
662
  expect(teamSubscribeMessage.value).toEqual({
687
- action: "subscribe",
663
+ action: "load",
688
664
  ...team.teamMap.coValue.knownState(),
689
665
  } satisfies SyncMessage);
690
666
 
691
667
  const secondMessage = await reader.read();
692
668
 
693
669
  expect(secondMessage.value).toEqual({
694
- action: "subscribe",
670
+ action: "load",
695
671
  ...map.coValue.knownState(),
696
672
  } satisfies SyncMessage);
697
673
  });
698
674
 
699
675
  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 () => {
700
- const admin = newRandomAgentCredential("admin");
701
- const adminID = getAgentID(getAgent(admin));
702
-
703
- const node = new LocalNode(admin, newRandomSessionID(adminID));
676
+ const [admin, session] = randomAnonymousAccountAndSessionID();
677
+ const node = new LocalNode(admin, session);
704
678
 
705
679
  const team = node.createTeam();
706
680
 
@@ -719,8 +693,8 @@ test("When receiving a subscribe with a known state that is ahead of our own, pe
719
693
  const writer = inTx.getWriter();
720
694
 
721
695
  await writer.write({
722
- action: "subscribe",
723
- coValueID: map.coValue.id,
696
+ action: "load",
697
+ id: map.coValue.id,
724
698
  header: true,
725
699
  sessions: {
726
700
  [node.ownSessionID]: 1,
@@ -729,22 +703,21 @@ test("When receiving a subscribe with a known state that is ahead of our own, pe
729
703
 
730
704
  const reader = outRx.getReader();
731
705
 
732
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
706
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
733
707
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
734
708
  const mapTellKnownState = await reader.read();
735
709
 
736
710
  expect(mapTellKnownState.value).toEqual({
737
- action: "tellKnownState",
711
+ action: "known",
738
712
  ...map.coValue.knownState(),
739
713
  } satisfies SyncMessage);
740
714
  });
741
715
 
742
716
  test.skip("When replaying creation and transactions of a coValue as new content, the receiving peer integrates this information", async () => {
743
717
  // 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
744
- const admin = newRandomAgentCredential("admin");
745
- const adminID = getAgentID(getAgent(admin));
718
+ const [admin, session] = randomAnonymousAccountAndSessionID();
746
719
 
747
- const node1 = new LocalNode(admin, newRandomSessionID(adminID));
720
+ const node1 = new LocalNode(admin, session);
748
721
 
749
722
  const team = node1.createTeam();
750
723
 
@@ -761,7 +734,7 @@ test.skip("When replaying creation and transactions of a coValue as new content,
761
734
  const to1 = inTx1.getWriter();
762
735
  const from1 = outRx1.getReader();
763
736
 
764
- const node2 = new LocalNode(admin, newRandomSessionID(adminID));
737
+ const node2 = new LocalNode(admin, newRandomSessionID(admin.id));
765
738
 
766
739
  const [inRx2, inTx2] = newStreamPair<SyncMessage>();
767
740
  const [outRx2, outTx2] = newStreamPair<SyncMessage>();
@@ -778,20 +751,20 @@ test.skip("When replaying creation and transactions of a coValue as new content,
778
751
 
779
752
  const adminSubscribeMessage = await from1.read();
780
753
  expect(adminSubscribeMessage.value).toMatchObject({
781
- action: "subscribe",
782
- coValueID: adminID,
754
+ action: "load",
755
+ id: admin.id,
783
756
  });
784
757
  const teamSubscribeMsg = await from1.read();
785
758
  expect(teamSubscribeMsg.value).toMatchObject({
786
- action: "subscribe",
787
- coValueID: team.teamMap.coValue.id,
759
+ action: "load",
760
+ id: team.teamMap.coValue.id,
788
761
  });
789
762
 
790
763
  await to2.write(adminSubscribeMessage.value!);
791
764
  await to2.write(teamSubscribeMsg.value!);
792
765
 
793
- const adminTellKnownStateMsg = await from2.read();
794
- expect(adminTellKnownStateMsg.value).toMatchObject(admStateEx(adminID));
766
+ // const adminTellKnownStateMsg = await from2.read();
767
+ // expect(adminTellKnownStateMsg.value).toMatchObject(admStateEx(admin.id));
795
768
 
796
769
  const teamTellKnownStateMsg = await from2.read();
797
770
  expect(teamTellKnownStateMsg.value).toMatchObject(teamStateEx(team));
@@ -802,40 +775,40 @@ test.skip("When replaying creation and transactions of a coValue as new content,
802
775
  ]
803
776
  ).toBeDefined();
804
777
 
805
- await to1.write(adminTellKnownStateMsg.value!);
778
+ // await to1.write(adminTellKnownStateMsg.value!);
806
779
  await to1.write(teamTellKnownStateMsg.value!);
807
780
 
808
- const adminContentMsg = await from1.read();
809
- expect(adminContentMsg.value).toMatchObject(admContEx(adminID));
781
+ // const adminContentMsg = await from1.read();
782
+ // expect(adminContentMsg.value).toMatchObject(admContEx(admin.id));
810
783
 
811
784
  const teamContentMsg = await from1.read();
812
785
  expect(teamContentMsg.value).toMatchObject(teamContentEx(team));
813
786
 
814
- await to2.write(adminContentMsg.value!);
787
+ // await to2.write(adminContentMsg.value!);
815
788
  await to2.write(teamContentMsg.value!);
816
789
 
817
790
  const map = team.createMap();
818
791
 
819
792
  const mapSubscriptionMsg = await from1.read();
820
793
  expect(mapSubscriptionMsg.value).toMatchObject({
821
- action: "subscribe",
822
- coValueID: map.coValue.id,
794
+ action: "load",
795
+ id: map.coValue.id,
823
796
  });
824
797
 
825
798
  const mapNewContentMsg = await from1.read();
826
799
  expect(mapNewContentMsg.value).toEqual({
827
- action: "newContent",
828
- coValueID: map.coValue.id,
800
+ action: "content",
801
+ id: map.coValue.id,
829
802
  header: map.coValue.header,
830
- newContent: {},
803
+ new: {},
831
804
  } satisfies SyncMessage);
832
805
 
833
806
  await to2.write(mapSubscriptionMsg.value!);
834
807
 
835
808
  const mapTellKnownStateMsg = await from2.read();
836
809
  expect(mapTellKnownStateMsg.value).toEqual({
837
- action: "tellKnownState",
838
- coValueID: map.coValue.id,
810
+ action: "known",
811
+ id: map.coValue.id,
839
812
  header: false,
840
813
  sessions: {},
841
814
  } satisfies SyncMessage);
@@ -863,10 +836,9 @@ test.skip("When replaying creation and transactions of a coValue as new content,
863
836
 
864
837
  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 () => {
865
838
  // 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
866
- const admin = newRandomAgentCredential("admin");
867
- const adminID = getAgentID(getAgent(admin));
839
+ const [admin, session] = randomAnonymousAccountAndSessionID();
868
840
 
869
- const node1 = new LocalNode(admin, newRandomSessionID(adminID));
841
+ const node1 = new LocalNode(admin, session);
870
842
 
871
843
  const team = node1.createTeam();
872
844
 
@@ -875,7 +847,7 @@ test.skip("When loading a coValue on one node, the server node it is requested f
875
847
  editable.set("hello", "world", "trusting");
876
848
  });
877
849
 
878
- const node2 = new LocalNode(admin, newRandomSessionID(adminID));
850
+ const node2 = new LocalNode(admin, newRandomSessionID(admin.id));
879
851
 
880
852
  const [node1asPeer, node2asPeer] = connectedPeers("peer1", "peer2");
881
853
 
@@ -892,10 +864,9 @@ test.skip("When loading a coValue on one node, the server node it is requested f
892
864
  });
893
865
 
894
866
  test("Can sync a coValue through a server to another client", async () => {
895
- const admin = newRandomAgentCredential("admin");
896
- const adminID = getAgentID(getAgent(admin));
867
+ const [admin, session] = randomAnonymousAccountAndSessionID();
897
868
 
898
- const client1 = new LocalNode(admin, newRandomSessionID(adminID));
869
+ const client1 = new LocalNode(admin, session);
899
870
 
900
871
  const team = client1.createTeam();
901
872
 
@@ -904,10 +875,9 @@ test("Can sync a coValue through a server to another client", async () => {
904
875
  editable.set("hello", "world", "trusting");
905
876
  });
906
877
 
907
- const serverUser = newRandomAgentCredential("serverUser");
908
- const serverUserID = getAgentID(getAgent(serverUser));
878
+ const [serverUser, serverSession] = randomAnonymousAccountAndSessionID();
909
879
 
910
- const server = new LocalNode(serverUser, newRandomSessionID(serverUserID));
880
+ const server = new LocalNode(serverUser, serverSession);
911
881
 
912
882
  const [serverAsPeer, client1AsPeer] = connectedPeers("server", "client1", {
913
883
  peer1role: "server",
@@ -917,7 +887,7 @@ test("Can sync a coValue through a server to another client", async () => {
917
887
  client1.sync.addPeer(serverAsPeer);
918
888
  server.sync.addPeer(client1AsPeer);
919
889
 
920
- const client2 = new LocalNode(admin, newRandomSessionID(adminID));
890
+ const client2 = new LocalNode(admin, newRandomSessionID(admin.id));
921
891
 
922
892
  const [serverAsOtherPeer, client2AsPeer] = connectedPeers(
923
893
  "server",
@@ -936,10 +906,9 @@ test("Can sync a coValue through a server to another client", async () => {
936
906
  });
937
907
 
938
908
  test("Can sync a coValue with private transactions through a server to another client", async () => {
939
- const admin = newRandomAgentCredential("admin");
940
- const adminID = getAgentID(getAgent(admin));
909
+ const [admin, session] = randomAnonymousAccountAndSessionID();
941
910
 
942
- const client1 = new LocalNode(admin, newRandomSessionID(adminID));
911
+ const client1 = new LocalNode(admin, session);
943
912
 
944
913
  const team = client1.createTeam();
945
914
 
@@ -948,10 +917,9 @@ test("Can sync a coValue with private transactions through a server to another c
948
917
  editable.set("hello", "world", "private");
949
918
  });
950
919
 
951
- const serverUser = newRandomAgentCredential("serverUser");
952
- const serverUserID = getAgentID(getAgent(serverUser));
920
+ const [serverUser, serverSession] = randomAnonymousAccountAndSessionID();
953
921
 
954
- const server = new LocalNode(serverUser, newRandomSessionID(serverUserID));
922
+ const server = new LocalNode(serverUser, serverSession);
955
923
 
956
924
  const [serverAsPeer, client1AsPeer] = connectedPeers("server", "client1", {
957
925
  trace: true,
@@ -962,7 +930,7 @@ test("Can sync a coValue with private transactions through a server to another c
962
930
  client1.sync.addPeer(serverAsPeer);
963
931
  server.sync.addPeer(client1AsPeer);
964
932
 
965
- const client2 = new LocalNode(admin, newRandomSessionID(adminID));
933
+ const client2 = new LocalNode(admin, newRandomSessionID(admin.id));
966
934
 
967
935
  const [serverAsOtherPeer, client2AsPeer] = connectedPeers(
968
936
  "server",
@@ -981,10 +949,8 @@ test("Can sync a coValue with private transactions through a server to another c
981
949
  });
982
950
 
983
951
  test("When a peer's incoming/readable stream closes, we remove the peer", async () => {
984
- const admin = newRandomAgentCredential("admin");
985
- const adminID = getAgentID(getAgent(admin));
986
-
987
- const node = new LocalNode(admin, newRandomSessionID(adminID));
952
+ const [admin, session] = randomAnonymousAccountAndSessionID();
953
+ const node = new LocalNode(admin, session);
988
954
 
989
955
  const team = node.createTeam();
990
956
 
@@ -999,13 +965,13 @@ test("When a peer's incoming/readable stream closes, we remove the peer", async
999
965
  });
1000
966
 
1001
967
  const reader = outRx.getReader();
968
+ // expect((await reader.read()).value).toMatchObject({
969
+ // action: "load",
970
+ // id: admin.id,
971
+ // });
1002
972
  expect((await reader.read()).value).toMatchObject({
1003
- action: "subscribe",
1004
- coValueID: adminID,
1005
- });
1006
- expect((await reader.read()).value).toMatchObject({
1007
- action: "subscribe",
1008
- coValueID: team.teamMap.coValue.id,
973
+ action: "load",
974
+ id: team.teamMap.coValue.id,
1009
975
  });
1010
976
 
1011
977
  const map = team.createMap();
@@ -1013,20 +979,20 @@ test("When a peer's incoming/readable stream closes, we remove the peer", async
1013
979
  const mapSubscribeMsg = await reader.read();
1014
980
 
1015
981
  expect(mapSubscribeMsg.value).toEqual({
1016
- action: "subscribe",
982
+ action: "load",
1017
983
  ...map.coValue.knownState(),
1018
984
  } satisfies SyncMessage);
1019
985
 
1020
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
986
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
1021
987
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
1022
988
 
1023
989
  const mapContentMsg = await reader.read();
1024
990
 
1025
991
  expect(mapContentMsg.value).toEqual({
1026
- action: "newContent",
1027
- coValueID: map.coValue.id,
992
+ action: "content",
993
+ id: map.coValue.id,
1028
994
  header: map.coValue.header,
1029
- newContent: {},
995
+ new: {},
1030
996
  } satisfies SyncMessage);
1031
997
 
1032
998
  await inTx.abort();
@@ -1037,10 +1003,8 @@ test("When a peer's incoming/readable stream closes, we remove the peer", async
1037
1003
  });
1038
1004
 
1039
1005
  test("When a peer's outgoing/writable stream closes, we remove the peer", async () => {
1040
- const admin = newRandomAgentCredential("admin");
1041
- const adminID = getAgentID(getAgent(admin));
1042
-
1043
- const node = new LocalNode(admin, newRandomSessionID(adminID));
1006
+ const [admin, session] = randomAnonymousAccountAndSessionID();
1007
+ const node = new LocalNode(admin, session);
1044
1008
 
1045
1009
  const team = node.createTeam();
1046
1010
 
@@ -1055,13 +1019,13 @@ test("When a peer's outgoing/writable stream closes, we remove the peer", async
1055
1019
  });
1056
1020
 
1057
1021
  const reader = outRx.getReader();
1022
+ // expect((await reader.read()).value).toMatchObject({
1023
+ // action: "load",
1024
+ // id: admin.id,
1025
+ // });
1058
1026
  expect((await reader.read()).value).toMatchObject({
1059
- action: "subscribe",
1060
- coValueID: adminID,
1061
- });
1062
- expect((await reader.read()).value).toMatchObject({
1063
- action: "subscribe",
1064
- coValueID: team.teamMap.coValue.id,
1027
+ action: "load",
1028
+ id: team.teamMap.coValue.id,
1065
1029
  });
1066
1030
 
1067
1031
  const map = team.createMap();
@@ -1069,20 +1033,20 @@ test("When a peer's outgoing/writable stream closes, we remove the peer", async
1069
1033
  const mapSubscribeMsg = await reader.read();
1070
1034
 
1071
1035
  expect(mapSubscribeMsg.value).toEqual({
1072
- action: "subscribe",
1036
+ action: "load",
1073
1037
  ...map.coValue.knownState(),
1074
1038
  } satisfies SyncMessage);
1075
1039
 
1076
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
1040
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
1077
1041
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
1078
1042
 
1079
1043
  const mapContentMsg = await reader.read();
1080
1044
 
1081
1045
  expect(mapContentMsg.value).toEqual({
1082
- action: "newContent",
1083
- coValueID: map.coValue.id,
1046
+ action: "content",
1047
+ id: map.coValue.id,
1084
1048
  header: map.coValue.header,
1085
- newContent: {},
1049
+ new: {},
1086
1050
  } satisfies SyncMessage);
1087
1051
 
1088
1052
  reader.releaseLock();
@@ -1095,13 +1059,12 @@ test("When a peer's outgoing/writable stream closes, we remove the peer", async
1095
1059
  await new Promise((resolve) => setTimeout(resolve, 100));
1096
1060
 
1097
1061
  expect(node.sync.peers["test"]).toBeUndefined();
1098
- })
1062
+ });
1099
1063
 
1100
1064
  test("If we start loading a coValue before connecting to a peer that has it, it will load it once we connect", async () => {
1101
- const admin = newRandomAgentCredential("admin");
1102
- const adminID = getAgentID(getAgent(admin));
1065
+ const [admin, session] = randomAnonymousAccountAndSessionID();
1103
1066
 
1104
- const node1 = new LocalNode(admin, newRandomSessionID(adminID));
1067
+ const node1 = new LocalNode(admin, session);
1105
1068
 
1106
1069
  const team = node1.createTeam();
1107
1070
 
@@ -1110,9 +1073,13 @@ test("If we start loading a coValue before connecting to a peer that has it, it
1110
1073
  editable.set("hello", "world", "trusting");
1111
1074
  });
1112
1075
 
1113
- const node2 = new LocalNode(admin, newRandomSessionID(adminID));
1076
+ const node2 = new LocalNode(admin, newRandomSessionID(admin.id));
1114
1077
 
1115
- const [node1asPeer, node2asPeer] = connectedPeers("peer1", "peer2", {peer1role: 'server', peer2role: 'client', trace: true});
1078
+ const [node1asPeer, node2asPeer] = connectedPeers("peer1", "peer2", {
1079
+ peer1role: "server",
1080
+ peer2role: "client",
1081
+ trace: true,
1082
+ });
1116
1083
 
1117
1084
  node1.sync.addPeer(node2asPeer);
1118
1085
 
@@ -1127,175 +1094,34 @@ test("If we start loading a coValue before connecting to a peer that has it, it
1127
1094
  expect(expectMap(mapOnNode2.getCurrentContent()).get("hello")).toEqual(
1128
1095
  "world"
1129
1096
  );
1130
- })
1097
+ });
1131
1098
 
1132
1099
  function teamContentEx(team: Team) {
1133
1100
  return {
1134
- action: "newContent",
1135
- coValueID: team.teamMap.coValue.id,
1101
+ action: "content",
1102
+ id: team.teamMap.coValue.id,
1136
1103
  };
1137
1104
  }
1138
1105
 
1139
- function admContEx(adminID: AgentID) {
1106
+ function admContEx(adminID: AccountID) {
1140
1107
  return {
1141
- action: "newContent",
1142
- coValueID: adminID,
1108
+ action: "content",
1109
+ id: adminID,
1143
1110
  };
1144
1111
  }
1145
1112
 
1146
1113
  function teamStateEx(team: Team) {
1147
1114
  return {
1148
- action: "tellKnownState",
1149
- coValueID: team.teamMap.coValue.id,
1115
+ action: "known",
1116
+ id: team.teamMap.coValue.id,
1150
1117
  };
1151
1118
  }
1152
1119
 
1153
- function admStateEx(adminID: AgentID) {
1120
+ function admStateEx(adminID: AccountID) {
1154
1121
  return {
1155
- action: "tellKnownState",
1156
- coValueID: adminID,
1122
+ action: "known",
1123
+ id: adminID,
1157
1124
  };
1158
1125
  }
1159
1126
 
1160
- function newStreamPair<T>(): [ReadableStream<T>, WritableStream<T>] {
1161
- const queue: T[] = [];
1162
- let resolveNextItemReady: () => void = () => {};
1163
- let nextItemReady: Promise<void> = new Promise((resolve) => {
1164
- resolveNextItemReady = resolve;
1165
- });
1166
-
1167
- let writerClosed = false;
1168
- let readerClosed = false;
1169
-
1170
- const readable = new ReadableStream<T>({
1171
- async pull(controller) {
1172
- let retriesLeft = 3;
1173
- while (retriesLeft > 0) {
1174
- if (writerClosed) {
1175
- controller.close();
1176
- return;
1177
- }
1178
- retriesLeft--;
1179
- if (queue.length > 0) {
1180
- controller.enqueue(queue.shift()!);
1181
- if (queue.length === 0) {
1182
- nextItemReady = new Promise((resolve) => {
1183
- resolveNextItemReady = resolve;
1184
- });
1185
- }
1186
- return;
1187
- } else {
1188
- await nextItemReady;
1189
- }
1190
- }
1191
- throw new Error("Should only use one retry to get next item in queue.")
1192
- },
1193
1127
 
1194
- cancel(reason) {
1195
- console.log("Manually closing reader")
1196
- readerClosed = true;
1197
- },
1198
- });
1199
-
1200
- const writable = new WritableStream<T>({
1201
- write(chunk, controller) {
1202
- if (readerClosed) {
1203
- console.log("Reader closed, not writing chunk", chunk);
1204
- throw new Error("Reader closed, not writing chunk");
1205
- }
1206
- queue.push(chunk);
1207
- if (queue.length === 1) {
1208
- // make sure that await write resolves before corresponding read
1209
- process.nextTick(() => resolveNextItemReady());
1210
- }
1211
- },
1212
- abort(reason) {
1213
- console.log("Manually closing writer")
1214
- writerClosed = true;
1215
- resolveNextItemReady();
1216
- return Promise.resolve();
1217
- },
1218
- });
1219
-
1220
- return [readable, writable];
1221
- }
1222
-
1223
- function shouldNotResolve<T>(promise: Promise<T>, ops: { timeout: number }): Promise<void> {
1224
- return new Promise((resolve, reject) => {
1225
- promise
1226
- .then((v) =>
1227
- reject(
1228
- new Error(
1229
- "Should not have resolved, but resolved to " +
1230
- JSON.stringify(v)
1231
- )
1232
- )
1233
- )
1234
- .catch(reject);
1235
- setTimeout(resolve, ops.timeout);
1236
- });
1237
- }
1238
-
1239
- function connectedPeers(
1240
- peer1id: PeerID,
1241
- peer2id: PeerID,
1242
- {
1243
- trace = false,
1244
- peer1role = "peer",
1245
- peer2role = "peer",
1246
- }: {
1247
- trace?: boolean;
1248
- peer1role?: Peer["role"];
1249
- peer2role?: Peer["role"];
1250
- } = {}
1251
- ): [Peer, Peer] {
1252
- const [inRx1, inTx1] = newStreamPair<SyncMessage>();
1253
- const [outRx1, outTx1] = newStreamPair<SyncMessage>();
1254
-
1255
- const [inRx2, inTx2] = newStreamPair<SyncMessage>();
1256
- const [outRx2, outTx2] = newStreamPair<SyncMessage>();
1257
-
1258
- void outRx2
1259
- .pipeThrough(
1260
- new TransformStream({
1261
- transform(
1262
- chunk: SyncMessage,
1263
- controller: { enqueue: (msg: SyncMessage) => void }
1264
- ) {
1265
- trace && console.log(`${peer2id} -> ${peer1id}`, chunk);
1266
- controller.enqueue(chunk);
1267
- },
1268
- })
1269
- )
1270
- .pipeTo(inTx1);
1271
-
1272
- void outRx1
1273
- .pipeThrough(
1274
- new TransformStream({
1275
- transform(
1276
- chunk: SyncMessage,
1277
- controller: { enqueue: (msg: SyncMessage) => void }
1278
- ) {
1279
- trace && console.log(`${peer1id} -> ${peer2id}`, chunk);
1280
- controller.enqueue(chunk);
1281
- },
1282
- })
1283
- )
1284
- .pipeTo(inTx2);
1285
-
1286
- const peer2AsPeer: Peer = {
1287
- id: peer2id,
1288
- incoming: inRx1,
1289
- outgoing: outTx1,
1290
- role: peer2role,
1291
- };
1292
-
1293
- const peer1AsPeer: Peer = {
1294
- id: peer1id,
1295
- incoming: inRx2,
1296
- outgoing: outTx2,
1297
- role: peer1role,
1298
- };
1299
-
1300
- return [peer1AsPeer, peer2AsPeer];
1301
- }