cojson 0.0.11 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/README.md +2 -2
  2. package/dist/account.d.ts +57 -0
  3. package/dist/account.js +76 -0
  4. package/dist/account.js.map +1 -0
  5. package/dist/account.test.d.ts +1 -0
  6. package/dist/account.test.js +40 -0
  7. package/dist/account.test.js.map +1 -0
  8. package/dist/coValue.d.ts +17 -36
  9. package/dist/coValue.js +53 -117
  10. package/dist/coValue.js.map +1 -1
  11. package/dist/coValue.test.js +16 -16
  12. package/dist/coValue.test.js.map +1 -1
  13. package/dist/contentType.d.ts +9 -9
  14. package/dist/contentType.js.map +1 -1
  15. package/dist/contentType.test.js +13 -17
  16. package/dist/contentType.test.js.map +1 -1
  17. package/dist/contentTypes/coList.d.ts +3 -3
  18. package/dist/contentTypes/coList.js.map +1 -1
  19. package/dist/contentTypes/coMap.d.ts +31 -21
  20. package/dist/contentTypes/coMap.js +28 -0
  21. package/dist/contentTypes/coMap.js.map +1 -1
  22. package/dist/contentTypes/coStream.d.ts +3 -3
  23. package/dist/contentTypes/coStream.js.map +1 -1
  24. package/dist/contentTypes/static.d.ts +4 -4
  25. package/dist/contentTypes/static.js.map +1 -1
  26. package/dist/crypto.d.ts +45 -39
  27. package/dist/crypto.js +68 -49
  28. package/dist/crypto.js.map +1 -1
  29. package/dist/crypto.test.js +45 -49
  30. package/dist/crypto.test.js.map +1 -1
  31. package/dist/ids.d.ts +5 -3
  32. package/dist/ids.js +3 -1
  33. package/dist/ids.js.map +1 -1
  34. package/dist/index.d.ts +12 -14
  35. package/dist/index.js +6 -8
  36. package/dist/index.js.map +1 -1
  37. package/dist/jsonValue.d.ts +2 -2
  38. package/dist/node.d.ts +25 -15
  39. package/dist/node.js +88 -33
  40. package/dist/node.js.map +1 -1
  41. package/dist/permissions.d.ts +27 -33
  42. package/dist/permissions.js +55 -47
  43. package/dist/permissions.js.map +1 -1
  44. package/dist/permissions.test.js +231 -314
  45. package/dist/permissions.test.js.map +1 -1
  46. package/dist/sync.d.ts +27 -30
  47. package/dist/sync.js +68 -64
  48. package/dist/sync.js.map +1 -1
  49. package/dist/sync.test.js +181 -305
  50. package/dist/sync.test.js.map +1 -1
  51. package/dist/testUtils.d.ts +37 -0
  52. package/dist/testUtils.js +157 -0
  53. package/dist/testUtils.js.map +1 -0
  54. package/package.json +1 -1
  55. package/src/account.test.ts +67 -0
  56. package/src/account.ts +152 -0
  57. package/src/coValue.test.ts +17 -31
  58. package/src/coValue.ts +98 -185
  59. package/src/contentType.test.ts +18 -45
  60. package/src/contentType.ts +15 -13
  61. package/src/contentTypes/coList.ts +4 -4
  62. package/src/contentTypes/coMap.ts +55 -29
  63. package/src/contentTypes/coStream.ts +4 -4
  64. package/src/contentTypes/static.ts +5 -5
  65. package/src/crypto.test.ts +53 -59
  66. package/src/crypto.ts +123 -95
  67. package/src/ids.ts +9 -3
  68. package/src/index.ts +14 -25
  69. package/src/jsonValue.ts +2 -2
  70. package/src/node.ts +189 -61
  71. package/src/permissions.test.ts +370 -404
  72. package/src/permissions.ts +126 -109
  73. package/src/sync.test.ts +262 -440
  74. package/src/sync.ts +96 -101
  75. package/src/testUtils.ts +229 -0
package/src/sync.test.ts CHANGED
@@ -1,115 +1,106 @@
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));
24
-
25
- const node = new LocalNode(admin, newRandomSessionID(adminID));
12
+ import {
13
+ connectedPeers,
14
+ newStreamPair,
15
+ randomAnonymousAccountAndSessionID,
16
+ shouldNotResolve,
17
+ } from "./testUtils.js";
18
+ import { AccountID } from "./account.js";
26
19
 
27
- const team = node.createTeam();
20
+ test("Node replies with initial tx and header to empty subscribe", async () => {
21
+ const [admin, session] = randomAnonymousAccountAndSessionID();
22
+ const node = new LocalNode(admin, session);
28
23
 
29
- const map = team.createMap();
24
+ const team = node.createTeam();
30
25
 
31
- map.edit((editable) => {
32
- editable.set("hello", "world", "trusting");
33
- });
26
+ const map = team.createMap();
34
27
 
35
- const [inRx, inTx] = newStreamPair<SyncMessage>();
36
- const [outRx, outTx] = newStreamPair<SyncMessage>();
28
+ map.edit((editable) => {
29
+ editable.set("hello", "world", "trusting");
30
+ });
37
31
 
38
- node.sync.addPeer({
39
- id: "test",
40
- incoming: inRx,
41
- outgoing: outTx,
42
- role: "peer",
43
- });
32
+ const [inRx, inTx] = newStreamPair<SyncMessage>();
33
+ const [outRx, outTx] = newStreamPair<SyncMessage>();
44
34
 
45
- const writer = inTx.getWriter();
35
+ node.sync.addPeer({
36
+ id: "test",
37
+ incoming: inRx,
38
+ outgoing: outTx,
39
+ role: "peer",
40
+ });
46
41
 
47
- await writer.write({
48
- action: "subscribe",
49
- coValueID: map.coValue.id,
50
- header: false,
51
- sessions: {},
52
- });
42
+ const writer = inTx.getWriter();
53
43
 
54
- const reader = outRx.getReader();
44
+ await writer.write({
45
+ action: "load",
46
+ id: map.coValue.id,
47
+ header: false,
48
+ sessions: {},
49
+ });
55
50
 
56
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
57
- expect((await reader.read()).value).toMatchObject(teamStateEx(team));
51
+ const reader = outRx.getReader();
58
52
 
59
- const mapTellKnownStateMsg = await reader.read();
60
- expect(mapTellKnownStateMsg.value).toEqual({
61
- action: "tellKnownState",
62
- ...map.coValue.knownState(),
63
- } satisfies SyncMessage);
53
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
54
+ expect((await reader.read()).value).toMatchObject(teamStateEx(team));
64
55
 
65
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
66
- expect((await reader.read()).value).toMatchObject(teamContentEx(team));
56
+ const mapTellKnownStateMsg = await reader.read();
57
+ expect(mapTellKnownStateMsg.value).toEqual({
58
+ action: "known",
59
+ ...map.coValue.knownState(),
60
+ } satisfies SyncMessage);
67
61
 
68
- const newContentMsg = await reader.read();
62
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
63
+ expect((await reader.read()).value).toMatchObject(teamContentEx(team));
69
64
 
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
- },
65
+ const newContentMsg = await reader.read();
66
+
67
+ expect(newContentMsg.value).toEqual({
68
+ action: "content",
69
+ id: map.coValue.id,
70
+ header: {
71
+ type: "comap",
72
+ ruleset: { type: "ownedByTeam", team: team.id },
73
+ meta: null,
74
+ createdAt: map.coValue.header.createdAt,
75
+ uniqueness: map.coValue.header.uniqueness,
76
+ },
77
+ new: {
78
+ [node.ownSessionID]: {
79
+ after: 0,
80
+ newTransactions: [
81
+ {
82
+ privacy: "trusting" as const,
83
+ madeAt: map.coValue.sessions[node.ownSessionID]!
84
+ .transactions[0]!.madeAt,
85
+ changes: [
86
+ {
87
+ op: "insert",
88
+ key: "hello",
89
+ value: "world",
90
+ } satisfies MapOpPayload<string, string>,
91
+ ],
92
+ },
93
+ ],
94
+ lastSignature:
95
+ map.coValue.sessions[node.ownSessionID]!.lastSignature!,
103
96
  },
104
- } satisfies SyncMessage);
105
- },
106
- );
97
+ },
98
+ } satisfies SyncMessage);
99
+ });
107
100
 
108
101
  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));
102
+ const [admin, session] = randomAnonymousAccountAndSessionID();
103
+ const node = new LocalNode(admin, session);
113
104
 
114
105
  const team = node.createTeam();
115
106
 
@@ -133,8 +124,8 @@ test("Node replies with only new tx to subscribe with some known state", async (
133
124
  const writer = inTx.getWriter();
134
125
 
135
126
  await writer.write({
136
- action: "subscribe",
137
- coValueID: map.coValue.id,
127
+ action: "load",
128
+ id: map.coValue.id,
138
129
  header: true,
139
130
  sessions: {
140
131
  [node.ownSessionID]: 1,
@@ -143,30 +134,30 @@ test("Node replies with only new tx to subscribe with some known state", async (
143
134
 
144
135
  const reader = outRx.getReader();
145
136
 
146
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
137
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
147
138
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
148
139
 
149
140
  const mapTellKnownStateMsg = await reader.read();
150
141
  expect(mapTellKnownStateMsg.value).toEqual({
151
- action: "tellKnownState",
142
+ action: "known",
152
143
  ...map.coValue.knownState(),
153
144
  } satisfies SyncMessage);
154
145
 
155
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
146
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
156
147
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
157
148
 
158
149
  const mapNewContentMsg = await reader.read();
159
150
 
160
151
  expect(mapNewContentMsg.value).toEqual({
161
- action: "newContent",
162
- coValueID: map.coValue.id,
152
+ action: "content",
153
+ id: map.coValue.id,
163
154
  header: undefined,
164
- newContent: {
155
+ new: {
165
156
  [node.ownSessionID]: {
166
157
  after: 1,
167
158
  newTransactions: [
168
159
  {
169
- privacy: "trusting",
160
+ privacy: "trusting" as const,
170
161
  madeAt: map.coValue.sessions[node.ownSessionID]!
171
162
  .transactions[1]!.madeAt,
172
163
  changes: [
@@ -178,7 +169,6 @@ test("Node replies with only new tx to subscribe with some known state", async (
178
169
  ],
179
170
  },
180
171
  ],
181
- lastHash: map.coValue.sessions[node.ownSessionID]!.lastHash!,
182
172
  lastSignature:
183
173
  map.coValue.sessions[node.ownSessionID]!.lastSignature!,
184
174
  },
@@ -187,14 +177,12 @@ test("Node replies with only new tx to subscribe with some known state", async (
187
177
  });
188
178
 
189
179
  test.todo(
190
- "TODO: node only replies with new tx to subscribe with some known state, even in the depended on coValues",
180
+ "TODO: node only replies with new tx to subscribe with some known state, even in the depended on coValues"
191
181
  );
192
182
 
193
183
  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));
184
+ const [admin, session] = randomAnonymousAccountAndSessionID();
185
+ const node = new LocalNode(admin, session);
198
186
 
199
187
  const team = node.createTeam();
200
188
 
@@ -213,8 +201,8 @@ test("After subscribing, node sends own known state and new txs to peer", async
213
201
  const writer = inTx.getWriter();
214
202
 
215
203
  await writer.write({
216
- action: "subscribe",
217
- coValueID: map.coValue.id,
204
+ action: "load",
205
+ id: map.coValue.id,
218
206
  header: false,
219
207
  sessions: {
220
208
  [node.ownSessionID]: 0,
@@ -223,25 +211,25 @@ test("After subscribing, node sends own known state and new txs to peer", async
223
211
 
224
212
  const reader = outRx.getReader();
225
213
 
226
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
214
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
227
215
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
228
216
 
229
217
  const mapTellKnownStateMsg = await reader.read();
230
218
  expect(mapTellKnownStateMsg.value).toEqual({
231
- action: "tellKnownState",
219
+ action: "known",
232
220
  ...map.coValue.knownState(),
233
221
  } satisfies SyncMessage);
234
222
 
235
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
223
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
236
224
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
237
225
 
238
226
  const mapNewContentHeaderOnlyMsg = await reader.read();
239
227
 
240
228
  expect(mapNewContentHeaderOnlyMsg.value).toEqual({
241
- action: "newContent",
242
- coValueID: map.coValue.id,
229
+ action: "content",
230
+ id: map.coValue.id,
243
231
  header: map.coValue.header,
244
- newContent: {},
232
+ new: {},
245
233
  } satisfies SyncMessage);
246
234
 
247
235
  map.edit((editable) => {
@@ -251,14 +239,14 @@ test("After subscribing, node sends own known state and new txs to peer", async
251
239
  const mapEditMsg1 = await reader.read();
252
240
 
253
241
  expect(mapEditMsg1.value).toEqual({
254
- action: "newContent",
255
- coValueID: map.coValue.id,
256
- newContent: {
242
+ action: "content",
243
+ id: map.coValue.id,
244
+ new: {
257
245
  [node.ownSessionID]: {
258
246
  after: 0,
259
247
  newTransactions: [
260
248
  {
261
- privacy: "trusting",
249
+ privacy: "trusting" as const,
262
250
  madeAt: map.coValue.sessions[node.ownSessionID]!
263
251
  .transactions[0]!.madeAt,
264
252
  changes: [
@@ -270,7 +258,6 @@ test("After subscribing, node sends own known state and new txs to peer", async
270
258
  ],
271
259
  },
272
260
  ],
273
- lastHash: map.coValue.sessions[node.ownSessionID]!.lastHash!,
274
261
  lastSignature:
275
262
  map.coValue.sessions[node.ownSessionID]!.lastSignature!,
276
263
  },
@@ -284,14 +271,14 @@ test("After subscribing, node sends own known state and new txs to peer", async
284
271
  const mapEditMsg2 = await reader.read();
285
272
 
286
273
  expect(mapEditMsg2.value).toEqual({
287
- action: "newContent",
288
- coValueID: map.coValue.id,
289
- newContent: {
274
+ action: "content",
275
+ id: map.coValue.id,
276
+ new: {
290
277
  [node.ownSessionID]: {
291
278
  after: 1,
292
279
  newTransactions: [
293
280
  {
294
- privacy: "trusting",
281
+ privacy: "trusting" as const,
295
282
  madeAt: map.coValue.sessions[node.ownSessionID]!
296
283
  .transactions[1]!.madeAt,
297
284
  changes: [
@@ -303,7 +290,6 @@ test("After subscribing, node sends own known state and new txs to peer", async
303
290
  ],
304
291
  },
305
292
  ],
306
- lastHash: map.coValue.sessions[node.ownSessionID]!.lastHash!,
307
293
  lastSignature:
308
294
  map.coValue.sessions[node.ownSessionID]!.lastSignature!,
309
295
  },
@@ -312,10 +298,8 @@ test("After subscribing, node sends own known state and new txs to peer", async
312
298
  });
313
299
 
314
300
  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));
301
+ const [admin, session] = randomAnonymousAccountAndSessionID();
302
+ const node = new LocalNode(admin, session);
319
303
 
320
304
  const team = node.createTeam();
321
305
 
@@ -342,38 +326,38 @@ test("Client replies with known new content to tellKnownState from server", asyn
342
326
  const writer = inTx.getWriter();
343
327
 
344
328
  await writer.write({
345
- action: "tellKnownState",
346
- coValueID: map.coValue.id,
329
+ action: "known",
330
+ id: map.coValue.id,
347
331
  header: false,
348
332
  sessions: {
349
333
  [node.ownSessionID]: 0,
350
334
  },
351
335
  });
352
336
 
353
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
337
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
354
338
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
355
339
 
356
340
  const mapTellKnownStateMsg = await reader.read();
357
341
  expect(mapTellKnownStateMsg.value).toEqual({
358
- action: "tellKnownState",
342
+ action: "known",
359
343
  ...map.coValue.knownState(),
360
344
  } satisfies SyncMessage);
361
345
 
362
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
346
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
363
347
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
364
348
 
365
349
  const mapNewContentMsg = await reader.read();
366
350
 
367
351
  expect(mapNewContentMsg.value).toEqual({
368
- action: "newContent",
369
- coValueID: map.coValue.id,
352
+ action: "content",
353
+ id: map.coValue.id,
370
354
  header: map.coValue.header,
371
- newContent: {
355
+ new: {
372
356
  [node.ownSessionID]: {
373
357
  after: 0,
374
358
  newTransactions: [
375
359
  {
376
- privacy: "trusting",
360
+ privacy: "trusting" as const,
377
361
  madeAt: map.coValue.sessions[node.ownSessionID]!
378
362
  .transactions[0]!.madeAt,
379
363
  changes: [
@@ -385,7 +369,6 @@ test("Client replies with known new content to tellKnownState from server", asyn
385
369
  ],
386
370
  },
387
371
  ],
388
- lastHash: map.coValue.sessions[node.ownSessionID]!.lastHash!,
389
372
  lastSignature:
390
373
  map.coValue.sessions[node.ownSessionID]!.lastSignature!,
391
374
  },
@@ -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: [
@@ -490,7 +472,6 @@ test("No matter the optimistic known state, node respects invalid known state me
490
472
  ],
491
473
  },
492
474
  ],
493
- lastHash: map.coValue.sessions[node.ownSessionID]!.lastHash!,
494
475
  lastSignature:
495
476
  map.coValue.sessions[node.ownSessionID]!.lastSignature!,
496
477
  },
@@ -499,10 +480,8 @@ test("No matter the optimistic known state, node respects invalid known state me
499
480
  });
500
481
 
501
482
  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));
483
+ const [admin, session] = randomAnonymousAccountAndSessionID();
484
+ const node = new LocalNode(admin, session);
506
485
 
507
486
  const team = node.createTeam();
508
487
 
@@ -524,14 +503,14 @@ test("If we add a peer, but it never subscribes to a coValue, it won't get any m
524
503
 
525
504
  const reader = outRx.getReader();
526
505
 
527
- await expect(shouldNotResolve(reader.read(), {timeout: 100})).resolves.toBeUndefined();
506
+ await expect(
507
+ shouldNotResolve(reader.read(), { timeout: 100 })
508
+ ).resolves.toBeUndefined();
528
509
  });
529
510
 
530
511
  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));
512
+ const [admin, session] = randomAnonymousAccountAndSessionID();
513
+ const node = new LocalNode(admin, session);
535
514
 
536
515
  const team = node.createTeam();
537
516
 
@@ -548,20 +527,20 @@ test("If we add a server peer, all updates to all coValues are sent to it, even
548
527
  });
549
528
 
550
529
  const reader = outRx.getReader();
530
+ // expect((await reader.read()).value).toMatchObject({
531
+ // action: "load",
532
+ // id: adminID,
533
+ // });
551
534
  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,
535
+ action: "load",
536
+ id: team.teamMap.coValue.id,
558
537
  });
559
538
 
560
539
  const mapSubscribeMsg = await reader.read();
561
540
 
562
541
  expect(mapSubscribeMsg.value).toEqual({
563
- action: "subscribe",
564
- coValueID: map.coValue.id,
542
+ action: "load",
543
+ id: map.coValue.id,
565
544
  header: true,
566
545
  sessions: {},
567
546
  } satisfies SyncMessage);
@@ -570,21 +549,21 @@ test("If we add a server peer, all updates to all coValues are sent to it, even
570
549
  editable.set("hello", "world", "trusting");
571
550
  });
572
551
 
573
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
552
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
574
553
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
575
554
 
576
555
  const mapNewContentMsg = await reader.read();
577
556
 
578
557
  expect(mapNewContentMsg.value).toEqual({
579
- action: "newContent",
580
- coValueID: map.coValue.id,
558
+ action: "content",
559
+ id: map.coValue.id,
581
560
  header: map.coValue.header,
582
- newContent: {
561
+ new: {
583
562
  [node.ownSessionID]: {
584
563
  after: 0,
585
564
  newTransactions: [
586
565
  {
587
- privacy: "trusting",
566
+ privacy: "trusting" as const,
588
567
  madeAt: map.coValue.sessions[node.ownSessionID]!
589
568
  .transactions[0]!.madeAt,
590
569
  changes: [
@@ -596,7 +575,6 @@ test("If we add a server peer, all updates to all coValues are sent to it, even
596
575
  ],
597
576
  },
598
577
  ],
599
- lastHash: map.coValue.sessions[node.ownSessionID]!.lastHash!,
600
578
  lastSignature:
601
579
  map.coValue.sessions[node.ownSessionID]!.lastSignature!,
602
580
  },
@@ -605,10 +583,8 @@ test("If we add a server peer, all updates to all coValues are sent to it, even
605
583
  });
606
584
 
607
585
  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));
586
+ const [admin, session] = randomAnonymousAccountAndSessionID();
587
+ const node = new LocalNode(admin, session);
612
588
 
613
589
  const team = node.createTeam();
614
590
 
@@ -623,13 +599,13 @@ test("If we add a server peer, newly created coValues are auto-subscribed to", a
623
599
  });
624
600
 
625
601
  const reader = outRx.getReader();
602
+ // expect((await reader.read()).value).toMatchObject({
603
+ // action: "load",
604
+ // id: admin.id,
605
+ // });
626
606
  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,
607
+ action: "load",
608
+ id: team.teamMap.coValue.id,
633
609
  });
634
610
 
635
611
  const map = team.createMap();
@@ -637,32 +613,30 @@ test("If we add a server peer, newly created coValues are auto-subscribed to", a
637
613
  const mapSubscribeMsg = await reader.read();
638
614
 
639
615
  expect(mapSubscribeMsg.value).toEqual({
640
- action: "subscribe",
616
+ action: "load",
641
617
  ...map.coValue.knownState(),
642
618
  } satisfies SyncMessage);
643
619
 
644
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
620
+ // expect((await reader.read()).value).toMatchObject(admContEx(adminID));
645
621
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
646
622
 
647
623
  const mapContentMsg = await reader.read();
648
624
 
649
625
  expect(mapContentMsg.value).toEqual({
650
- action: "newContent",
651
- coValueID: map.coValue.id,
626
+ action: "content",
627
+ id: map.coValue.id,
652
628
  header: map.coValue.header,
653
- newContent: {},
629
+ new: {},
654
630
  } satisfies SyncMessage);
655
631
  });
656
632
 
657
633
  test.todo(
658
- "TODO: when receiving a subscribe response that is behind our optimistic state (due to already sent content), we ignore it",
634
+ "TODO: when receiving a subscribe response that is behind our optimistic state (due to already sent content), we ignore it"
659
635
  );
660
636
 
661
637
  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));
638
+ const [admin, session] = randomAnonymousAccountAndSessionID();
639
+ const node = new LocalNode(admin, session);
666
640
 
667
641
  const team = node.createTeam();
668
642
 
@@ -680,27 +654,25 @@ test("When we connect a new server peer, we try to sync all existing coValues to
680
654
 
681
655
  const reader = outRx.getReader();
682
656
 
683
- const _adminSubscribeMessage = await reader.read();
657
+ // const _adminSubscribeMessage = await reader.read();
684
658
  const teamSubscribeMessage = await reader.read();
685
659
 
686
660
  expect(teamSubscribeMessage.value).toEqual({
687
- action: "subscribe",
661
+ action: "load",
688
662
  ...team.teamMap.coValue.knownState(),
689
663
  } satisfies SyncMessage);
690
664
 
691
665
  const secondMessage = await reader.read();
692
666
 
693
667
  expect(secondMessage.value).toEqual({
694
- action: "subscribe",
668
+ action: "load",
695
669
  ...map.coValue.knownState(),
696
670
  } satisfies SyncMessage);
697
671
  });
698
672
 
699
673
  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));
674
+ const [admin, session] = randomAnonymousAccountAndSessionID();
675
+ const node = new LocalNode(admin, session);
704
676
 
705
677
  const team = node.createTeam();
706
678
 
@@ -719,8 +691,8 @@ test("When receiving a subscribe with a known state that is ahead of our own, pe
719
691
  const writer = inTx.getWriter();
720
692
 
721
693
  await writer.write({
722
- action: "subscribe",
723
- coValueID: map.coValue.id,
694
+ action: "load",
695
+ id: map.coValue.id,
724
696
  header: true,
725
697
  sessions: {
726
698
  [node.ownSessionID]: 1,
@@ -729,22 +701,21 @@ test("When receiving a subscribe with a known state that is ahead of our own, pe
729
701
 
730
702
  const reader = outRx.getReader();
731
703
 
732
- expect((await reader.read()).value).toMatchObject(admStateEx(adminID));
704
+ // expect((await reader.read()).value).toMatchObject(admStateEx(admin.id));
733
705
  expect((await reader.read()).value).toMatchObject(teamStateEx(team));
734
706
  const mapTellKnownState = await reader.read();
735
707
 
736
708
  expect(mapTellKnownState.value).toEqual({
737
- action: "tellKnownState",
709
+ action: "known",
738
710
  ...map.coValue.knownState(),
739
711
  } satisfies SyncMessage);
740
712
  });
741
713
 
742
714
  test.skip("When replaying creation and transactions of a coValue as new content, the receiving peer integrates this information", async () => {
743
715
  // 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));
716
+ const [admin, session] = randomAnonymousAccountAndSessionID();
746
717
 
747
- const node1 = new LocalNode(admin, newRandomSessionID(adminID));
718
+ const node1 = new LocalNode(admin, session);
748
719
 
749
720
  const team = node1.createTeam();
750
721
 
@@ -761,7 +732,7 @@ test.skip("When replaying creation and transactions of a coValue as new content,
761
732
  const to1 = inTx1.getWriter();
762
733
  const from1 = outRx1.getReader();
763
734
 
764
- const node2 = new LocalNode(admin, newRandomSessionID(adminID));
735
+ const node2 = new LocalNode(admin, newRandomSessionID(admin.id));
765
736
 
766
737
  const [inRx2, inTx2] = newStreamPair<SyncMessage>();
767
738
  const [outRx2, outTx2] = newStreamPair<SyncMessage>();
@@ -778,20 +749,20 @@ test.skip("When replaying creation and transactions of a coValue as new content,
778
749
 
779
750
  const adminSubscribeMessage = await from1.read();
780
751
  expect(adminSubscribeMessage.value).toMatchObject({
781
- action: "subscribe",
782
- coValueID: adminID,
752
+ action: "load",
753
+ id: admin.id,
783
754
  });
784
755
  const teamSubscribeMsg = await from1.read();
785
756
  expect(teamSubscribeMsg.value).toMatchObject({
786
- action: "subscribe",
787
- coValueID: team.teamMap.coValue.id,
757
+ action: "load",
758
+ id: team.teamMap.coValue.id,
788
759
  });
789
760
 
790
761
  await to2.write(adminSubscribeMessage.value!);
791
762
  await to2.write(teamSubscribeMsg.value!);
792
763
 
793
- const adminTellKnownStateMsg = await from2.read();
794
- expect(adminTellKnownStateMsg.value).toMatchObject(admStateEx(adminID));
764
+ // const adminTellKnownStateMsg = await from2.read();
765
+ // expect(adminTellKnownStateMsg.value).toMatchObject(admStateEx(admin.id));
795
766
 
796
767
  const teamTellKnownStateMsg = await from2.read();
797
768
  expect(teamTellKnownStateMsg.value).toMatchObject(teamStateEx(team));
@@ -802,40 +773,40 @@ test.skip("When replaying creation and transactions of a coValue as new content,
802
773
  ]
803
774
  ).toBeDefined();
804
775
 
805
- await to1.write(adminTellKnownStateMsg.value!);
776
+ // await to1.write(adminTellKnownStateMsg.value!);
806
777
  await to1.write(teamTellKnownStateMsg.value!);
807
778
 
808
- const adminContentMsg = await from1.read();
809
- expect(adminContentMsg.value).toMatchObject(admContEx(adminID));
779
+ // const adminContentMsg = await from1.read();
780
+ // expect(adminContentMsg.value).toMatchObject(admContEx(admin.id));
810
781
 
811
782
  const teamContentMsg = await from1.read();
812
783
  expect(teamContentMsg.value).toMatchObject(teamContentEx(team));
813
784
 
814
- await to2.write(adminContentMsg.value!);
785
+ // await to2.write(adminContentMsg.value!);
815
786
  await to2.write(teamContentMsg.value!);
816
787
 
817
788
  const map = team.createMap();
818
789
 
819
790
  const mapSubscriptionMsg = await from1.read();
820
791
  expect(mapSubscriptionMsg.value).toMatchObject({
821
- action: "subscribe",
822
- coValueID: map.coValue.id,
792
+ action: "load",
793
+ id: map.coValue.id,
823
794
  });
824
795
 
825
796
  const mapNewContentMsg = await from1.read();
826
797
  expect(mapNewContentMsg.value).toEqual({
827
- action: "newContent",
828
- coValueID: map.coValue.id,
798
+ action: "content",
799
+ id: map.coValue.id,
829
800
  header: map.coValue.header,
830
- newContent: {},
801
+ new: {},
831
802
  } satisfies SyncMessage);
832
803
 
833
804
  await to2.write(mapSubscriptionMsg.value!);
834
805
 
835
806
  const mapTellKnownStateMsg = await from2.read();
836
807
  expect(mapTellKnownStateMsg.value).toEqual({
837
- action: "tellKnownState",
838
- coValueID: map.coValue.id,
808
+ action: "known",
809
+ id: map.coValue.id,
839
810
  header: false,
840
811
  sessions: {},
841
812
  } satisfies SyncMessage);
@@ -863,10 +834,9 @@ test.skip("When replaying creation and transactions of a coValue as new content,
863
834
 
864
835
  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
836
  // 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));
837
+ const [admin, session] = randomAnonymousAccountAndSessionID();
868
838
 
869
- const node1 = new LocalNode(admin, newRandomSessionID(adminID));
839
+ const node1 = new LocalNode(admin, session);
870
840
 
871
841
  const team = node1.createTeam();
872
842
 
@@ -875,7 +845,7 @@ test.skip("When loading a coValue on one node, the server node it is requested f
875
845
  editable.set("hello", "world", "trusting");
876
846
  });
877
847
 
878
- const node2 = new LocalNode(admin, newRandomSessionID(adminID));
848
+ const node2 = new LocalNode(admin, newRandomSessionID(admin.id));
879
849
 
880
850
  const [node1asPeer, node2asPeer] = connectedPeers("peer1", "peer2");
881
851
 
@@ -892,10 +862,9 @@ test.skip("When loading a coValue on one node, the server node it is requested f
892
862
  });
893
863
 
894
864
  test("Can sync a coValue through a server to another client", async () => {
895
- const admin = newRandomAgentCredential("admin");
896
- const adminID = getAgentID(getAgent(admin));
865
+ const [admin, session] = randomAnonymousAccountAndSessionID();
897
866
 
898
- const client1 = new LocalNode(admin, newRandomSessionID(adminID));
867
+ const client1 = new LocalNode(admin, session);
899
868
 
900
869
  const team = client1.createTeam();
901
870
 
@@ -904,10 +873,9 @@ test("Can sync a coValue through a server to another client", async () => {
904
873
  editable.set("hello", "world", "trusting");
905
874
  });
906
875
 
907
- const serverUser = newRandomAgentCredential("serverUser");
908
- const serverUserID = getAgentID(getAgent(serverUser));
876
+ const [serverUser, serverSession] = randomAnonymousAccountAndSessionID();
909
877
 
910
- const server = new LocalNode(serverUser, newRandomSessionID(serverUserID));
878
+ const server = new LocalNode(serverUser, serverSession);
911
879
 
912
880
  const [serverAsPeer, client1AsPeer] = connectedPeers("server", "client1", {
913
881
  peer1role: "server",
@@ -917,7 +885,7 @@ test("Can sync a coValue through a server to another client", async () => {
917
885
  client1.sync.addPeer(serverAsPeer);
918
886
  server.sync.addPeer(client1AsPeer);
919
887
 
920
- const client2 = new LocalNode(admin, newRandomSessionID(adminID));
888
+ const client2 = new LocalNode(admin, newRandomSessionID(admin.id));
921
889
 
922
890
  const [serverAsOtherPeer, client2AsPeer] = connectedPeers(
923
891
  "server",
@@ -936,10 +904,9 @@ test("Can sync a coValue through a server to another client", async () => {
936
904
  });
937
905
 
938
906
  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));
907
+ const [admin, session] = randomAnonymousAccountAndSessionID();
941
908
 
942
- const client1 = new LocalNode(admin, newRandomSessionID(adminID));
909
+ const client1 = new LocalNode(admin, session);
943
910
 
944
911
  const team = client1.createTeam();
945
912
 
@@ -948,10 +915,9 @@ test("Can sync a coValue with private transactions through a server to another c
948
915
  editable.set("hello", "world", "private");
949
916
  });
950
917
 
951
- const serverUser = newRandomAgentCredential("serverUser");
952
- const serverUserID = getAgentID(getAgent(serverUser));
918
+ const [serverUser, serverSession] = randomAnonymousAccountAndSessionID();
953
919
 
954
- const server = new LocalNode(serverUser, newRandomSessionID(serverUserID));
920
+ const server = new LocalNode(serverUser, serverSession);
955
921
 
956
922
  const [serverAsPeer, client1AsPeer] = connectedPeers("server", "client1", {
957
923
  trace: true,
@@ -962,7 +928,7 @@ test("Can sync a coValue with private transactions through a server to another c
962
928
  client1.sync.addPeer(serverAsPeer);
963
929
  server.sync.addPeer(client1AsPeer);
964
930
 
965
- const client2 = new LocalNode(admin, newRandomSessionID(adminID));
931
+ const client2 = new LocalNode(admin, newRandomSessionID(admin.id));
966
932
 
967
933
  const [serverAsOtherPeer, client2AsPeer] = connectedPeers(
968
934
  "server",
@@ -981,10 +947,8 @@ test("Can sync a coValue with private transactions through a server to another c
981
947
  });
982
948
 
983
949
  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));
950
+ const [admin, session] = randomAnonymousAccountAndSessionID();
951
+ const node = new LocalNode(admin, session);
988
952
 
989
953
  const team = node.createTeam();
990
954
 
@@ -999,13 +963,13 @@ test("When a peer's incoming/readable stream closes, we remove the peer", async
999
963
  });
1000
964
 
1001
965
  const reader = outRx.getReader();
966
+ // expect((await reader.read()).value).toMatchObject({
967
+ // action: "load",
968
+ // id: admin.id,
969
+ // });
1002
970
  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,
971
+ action: "load",
972
+ id: team.teamMap.coValue.id,
1009
973
  });
1010
974
 
1011
975
  const map = team.createMap();
@@ -1013,20 +977,20 @@ test("When a peer's incoming/readable stream closes, we remove the peer", async
1013
977
  const mapSubscribeMsg = await reader.read();
1014
978
 
1015
979
  expect(mapSubscribeMsg.value).toEqual({
1016
- action: "subscribe",
980
+ action: "load",
1017
981
  ...map.coValue.knownState(),
1018
982
  } satisfies SyncMessage);
1019
983
 
1020
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
984
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
1021
985
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
1022
986
 
1023
987
  const mapContentMsg = await reader.read();
1024
988
 
1025
989
  expect(mapContentMsg.value).toEqual({
1026
- action: "newContent",
1027
- coValueID: map.coValue.id,
990
+ action: "content",
991
+ id: map.coValue.id,
1028
992
  header: map.coValue.header,
1029
- newContent: {},
993
+ new: {},
1030
994
  } satisfies SyncMessage);
1031
995
 
1032
996
  await inTx.abort();
@@ -1037,10 +1001,8 @@ test("When a peer's incoming/readable stream closes, we remove the peer", async
1037
1001
  });
1038
1002
 
1039
1003
  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));
1004
+ const [admin, session] = randomAnonymousAccountAndSessionID();
1005
+ const node = new LocalNode(admin, session);
1044
1006
 
1045
1007
  const team = node.createTeam();
1046
1008
 
@@ -1055,13 +1017,13 @@ test("When a peer's outgoing/writable stream closes, we remove the peer", async
1055
1017
  });
1056
1018
 
1057
1019
  const reader = outRx.getReader();
1020
+ // expect((await reader.read()).value).toMatchObject({
1021
+ // action: "load",
1022
+ // id: admin.id,
1023
+ // });
1058
1024
  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,
1025
+ action: "load",
1026
+ id: team.teamMap.coValue.id,
1065
1027
  });
1066
1028
 
1067
1029
  const map = team.createMap();
@@ -1069,20 +1031,20 @@ test("When a peer's outgoing/writable stream closes, we remove the peer", async
1069
1031
  const mapSubscribeMsg = await reader.read();
1070
1032
 
1071
1033
  expect(mapSubscribeMsg.value).toEqual({
1072
- action: "subscribe",
1034
+ action: "load",
1073
1035
  ...map.coValue.knownState(),
1074
1036
  } satisfies SyncMessage);
1075
1037
 
1076
- expect((await reader.read()).value).toMatchObject(admContEx(adminID));
1038
+ // expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
1077
1039
  expect((await reader.read()).value).toMatchObject(teamContentEx(team));
1078
1040
 
1079
1041
  const mapContentMsg = await reader.read();
1080
1042
 
1081
1043
  expect(mapContentMsg.value).toEqual({
1082
- action: "newContent",
1083
- coValueID: map.coValue.id,
1044
+ action: "content",
1045
+ id: map.coValue.id,
1084
1046
  header: map.coValue.header,
1085
- newContent: {},
1047
+ new: {},
1086
1048
  } satisfies SyncMessage);
1087
1049
 
1088
1050
  reader.releaseLock();
@@ -1095,13 +1057,12 @@ test("When a peer's outgoing/writable stream closes, we remove the peer", async
1095
1057
  await new Promise((resolve) => setTimeout(resolve, 100));
1096
1058
 
1097
1059
  expect(node.sync.peers["test"]).toBeUndefined();
1098
- })
1060
+ });
1099
1061
 
1100
1062
  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));
1063
+ const [admin, session] = randomAnonymousAccountAndSessionID();
1103
1064
 
1104
- const node1 = new LocalNode(admin, newRandomSessionID(adminID));
1065
+ const node1 = new LocalNode(admin, session);
1105
1066
 
1106
1067
  const team = node1.createTeam();
1107
1068
 
@@ -1110,9 +1071,13 @@ test("If we start loading a coValue before connecting to a peer that has it, it
1110
1071
  editable.set("hello", "world", "trusting");
1111
1072
  });
1112
1073
 
1113
- const node2 = new LocalNode(admin, newRandomSessionID(adminID));
1074
+ const node2 = new LocalNode(admin, newRandomSessionID(admin.id));
1114
1075
 
1115
- const [node1asPeer, node2asPeer] = connectedPeers("peer1", "peer2", {peer1role: 'server', peer2role: 'client', trace: true});
1076
+ const [node1asPeer, node2asPeer] = connectedPeers("peer1", "peer2", {
1077
+ peer1role: "server",
1078
+ peer2role: "client",
1079
+ trace: true,
1080
+ });
1116
1081
 
1117
1082
  node1.sync.addPeer(node2asPeer);
1118
1083
 
@@ -1127,175 +1092,32 @@ test("If we start loading a coValue before connecting to a peer that has it, it
1127
1092
  expect(expectMap(mapOnNode2.getCurrentContent()).get("hello")).toEqual(
1128
1093
  "world"
1129
1094
  );
1130
- })
1095
+ });
1131
1096
 
1132
1097
  function teamContentEx(team: Team) {
1133
1098
  return {
1134
- action: "newContent",
1135
- coValueID: team.teamMap.coValue.id,
1099
+ action: "content",
1100
+ id: team.teamMap.coValue.id,
1136
1101
  };
1137
1102
  }
1138
1103
 
1139
- function admContEx(adminID: AgentID) {
1104
+ function admContEx(adminID: AccountID) {
1140
1105
  return {
1141
- action: "newContent",
1142
- coValueID: adminID,
1106
+ action: "content",
1107
+ id: adminID,
1143
1108
  };
1144
1109
  }
1145
1110
 
1146
1111
  function teamStateEx(team: Team) {
1147
1112
  return {
1148
- action: "tellKnownState",
1149
- coValueID: team.teamMap.coValue.id,
1113
+ action: "known",
1114
+ id: team.teamMap.coValue.id,
1150
1115
  };
1151
1116
  }
1152
1117
 
1153
- function admStateEx(adminID: AgentID) {
1118
+ function admStateEx(adminID: AccountID) {
1154
1119
  return {
1155
- action: "tellKnownState",
1156
- coValueID: adminID,
1157
- };
1158
- }
1159
-
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
-
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,
1120
+ action: "known",
1121
+ id: adminID,
1298
1122
  };
1299
-
1300
- return [peer1AsPeer, peer2AsPeer];
1301
1123
  }