cojson 0.7.23 → 0.7.26

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.
@@ -4,42 +4,40 @@ import { randomAnonymousAccountAndSessionID } from "./testUtils.js";
4
4
  import { connectedPeers, newQueuePair } from "../streamUtils.js";
5
5
  import { stableStringify } from "../jsonStringify.js";
6
6
  import { WasmCrypto } from "../crypto/WasmCrypto.js";
7
- import { Effect, Queue, Sink, Stream } from "effect";
8
- import { newRandomSessionID } from "../coValueCore.js";
9
7
  import { expectMap } from "../coValue.js";
8
+ import { newRandomSessionID } from "../coValueCore.js";
10
9
  const Crypto = await WasmCrypto.create();
11
- test("Node replies with initial tx and header to empty subscribe", () => Effect.gen(function* () {
10
+ test("Node replies with initial tx and header to empty subscribe", async () => {
12
11
  const [admin, session] = randomAnonymousAccountAndSessionID();
13
12
  const node = new LocalNode(admin, session, Crypto);
14
13
  const group = node.createGroup();
15
14
  const map = group.createMap();
16
15
  map.set("hello", "world", "trusting");
17
- const [inRx, inTx] = yield* newQueuePair();
18
- const [outRx, outTx] = yield* newQueuePair();
19
- const outRxQ = yield* Queue.unbounded();
20
- yield* Effect.fork(Stream.run(outRx, Sink.fromQueue(outRxQ)));
16
+ const [inRx, inTx] = newQueuePair();
17
+ const [outRx, outTx] = newQueuePair();
18
+ const outRxQ = outRx[Symbol.asyncIterator]();
21
19
  node.syncManager.addPeer({
22
20
  id: "test",
23
21
  incoming: inRx,
24
22
  outgoing: outTx,
25
23
  role: "peer",
26
24
  });
27
- yield* Queue.offer(inTx, {
25
+ await inTx.push({
28
26
  action: "load",
29
27
  id: map.core.id,
30
28
  header: false,
31
29
  sessions: {},
32
30
  });
33
- // expect((yield* Queue.take(outRxQ))).toMatchObject(admStateEx(admin.id));
34
- expect(yield* Queue.take(outRxQ)).toMatchObject(groupStateEx(group));
35
- const mapTellKnownStateMsg = yield* Queue.take(outRxQ);
31
+ // expect((await outRxQ.next()).value).toMatchObject(admStateEx(admin.id));
32
+ expect((await outRxQ.next()).value).toMatchObject(groupStateEx(group));
33
+ const mapTellKnownStateMsg = (await outRxQ.next()).value;
36
34
  expect(mapTellKnownStateMsg).toEqual({
37
35
  action: "known",
38
36
  ...map.core.knownState(),
39
37
  });
40
- // expect((yield * Queue.take(outRxQ))).toMatchObject(admContEx(admin.id));
41
- expect(yield* Queue.take(outRxQ)).toMatchObject(groupContentEx(group));
42
- const newContentMsg = yield* Queue.take(outRxQ);
38
+ // expect((await outRxQ.next()).value).toMatchObject(admContEx(admin.id));
39
+ expect((await outRxQ.next()).value).toMatchObject(groupContentEx(group));
40
+ const newContentMsg = (await outRxQ.next()).value;
43
41
  expect(newContentMsg).toEqual({
44
42
  action: "content",
45
43
  id: map.core.id,
@@ -56,7 +54,8 @@ test("Node replies with initial tx and header to empty subscribe", () => Effect.
56
54
  newTransactions: [
57
55
  {
58
56
  privacy: "trusting",
59
- madeAt: map.core.sessionLogs.get(node.currentSessionID).transactions[0].madeAt,
57
+ madeAt: map.core.sessionLogs.get(node.currentSessionID)
58
+ .transactions[0].madeAt,
60
59
  changes: stableStringify([
61
60
  {
62
61
  op: "set",
@@ -66,29 +65,29 @@ test("Node replies with initial tx and header to empty subscribe", () => Effect.
66
65
  ]),
67
66
  },
68
67
  ],
69
- lastSignature: map.core.sessionLogs.get(node.currentSessionID).lastSignature,
68
+ lastSignature: map.core.sessionLogs.get(node.currentSessionID)
69
+ .lastSignature,
70
70
  },
71
71
  },
72
72
  });
73
- }).pipe(Effect.scoped, Effect.runPromise));
74
- test("Node replies with only new tx to subscribe with some known state", () => Effect.gen(function* () {
73
+ });
74
+ test("Node replies with only new tx to subscribe with some known state", async () => {
75
75
  const [admin, session] = randomAnonymousAccountAndSessionID();
76
76
  const node = new LocalNode(admin, session, Crypto);
77
77
  const group = node.createGroup();
78
78
  const map = group.createMap();
79
79
  map.set("hello", "world", "trusting");
80
80
  map.set("goodbye", "world", "trusting");
81
- const [inRx, inTx] = yield* newQueuePair();
82
- const [outRx, outTx] = yield* newQueuePair();
83
- const outRxQ = yield* Queue.unbounded();
84
- yield* Effect.fork(Stream.run(outRx, Sink.fromQueue(outRxQ)));
81
+ const [inRx, inTx] = newQueuePair();
82
+ const [outRx, outTx] = newQueuePair();
83
+ const outRxQ = outRx[Symbol.asyncIterator]();
85
84
  node.syncManager.addPeer({
86
85
  id: "test",
87
86
  incoming: inRx,
88
87
  outgoing: outTx,
89
88
  role: "peer",
90
89
  });
91
- yield* Queue.offer(inTx, {
90
+ await inTx.push({
92
91
  action: "load",
93
92
  id: map.core.id,
94
93
  header: true,
@@ -96,16 +95,16 @@ test("Node replies with only new tx to subscribe with some known state", () => E
96
95
  [node.currentSessionID]: 1,
97
96
  },
98
97
  });
99
- // expect(yield* Queue.take(outRxQ)).toMatchObject(admStateEx(admin.id));
100
- expect(yield* Queue.take(outRxQ)).toMatchObject(groupStateEx(group));
101
- const mapTellKnownStateMsg = yield* Queue.take(outRxQ);
98
+ // expect((await outRxQ.next()).value).toMatchObject(admStateEx(admin.id));
99
+ expect((await outRxQ.next()).value).toMatchObject(groupStateEx(group));
100
+ const mapTellKnownStateMsg = (await outRxQ.next()).value;
102
101
  expect(mapTellKnownStateMsg).toEqual({
103
102
  action: "known",
104
103
  ...map.core.knownState(),
105
104
  });
106
- // expect(yield* Queue.take(outRxQ))).toMatchObject(admContEx(admin.id));
107
- expect(yield* Queue.take(outRxQ)).toMatchObject(groupContentEx(group));
108
- const mapNewContentMsg = yield* Queue.take(outRxQ);
105
+ // expect((await outRxQ.next()).value).toMatchObject(admContEx(admin.id));
106
+ expect((await outRxQ.next()).value).toMatchObject(groupContentEx(group));
107
+ const mapNewContentMsg = (await outRxQ.next()).value;
109
108
  expect(mapNewContentMsg).toEqual({
110
109
  action: "content",
111
110
  id: map.core.id,
@@ -116,7 +115,8 @@ test("Node replies with only new tx to subscribe with some known state", () => E
116
115
  newTransactions: [
117
116
  {
118
117
  privacy: "trusting",
119
- madeAt: map.core.sessionLogs.get(node.currentSessionID).transactions[1].madeAt,
118
+ madeAt: map.core.sessionLogs.get(node.currentSessionID)
119
+ .transactions[1].madeAt,
120
120
  changes: stableStringify([
121
121
  {
122
122
  op: "set",
@@ -126,28 +126,28 @@ test("Node replies with only new tx to subscribe with some known state", () => E
126
126
  ]),
127
127
  },
128
128
  ],
129
- lastSignature: map.core.sessionLogs.get(node.currentSessionID).lastSignature,
129
+ lastSignature: map.core.sessionLogs.get(node.currentSessionID)
130
+ .lastSignature,
130
131
  },
131
132
  },
132
133
  });
133
- }).pipe(Effect.scoped, Effect.runPromise));
134
+ });
134
135
  test.todo("TODO: node only replies with new tx to subscribe with some known state, even in the depended on coValues");
135
- test("After subscribing, node sends own known state and new txs to peer", () => Effect.gen(function* () {
136
+ test("After subscribing, node sends own known state and new txs to peer", async () => {
136
137
  const [admin, session] = randomAnonymousAccountAndSessionID();
137
138
  const node = new LocalNode(admin, session, Crypto);
138
139
  const group = node.createGroup();
139
140
  const map = group.createMap();
140
- const [inRx, inTx] = yield* newQueuePair();
141
- const [outRx, outTx] = yield* newQueuePair();
142
- const outRxQ = yield* Queue.unbounded();
143
- yield* Effect.fork(Stream.run(outRx, Sink.fromQueue(outRxQ)));
141
+ const [inRx, inTx] = newQueuePair();
142
+ const [outRx, outTx] = newQueuePair();
143
+ const outRxQ = outRx[Symbol.asyncIterator]();
144
144
  node.syncManager.addPeer({
145
145
  id: "test",
146
146
  incoming: inRx,
147
147
  outgoing: outTx,
148
148
  role: "peer",
149
149
  });
150
- yield* Queue.offer(inTx, {
150
+ await inTx.push({
151
151
  action: "load",
152
152
  id: map.core.id,
153
153
  header: false,
@@ -155,16 +155,16 @@ test("After subscribing, node sends own known state and new txs to peer", () =>
155
155
  [node.currentSessionID]: 0,
156
156
  },
157
157
  });
158
- // expect(yield* Queue.take(outRxQ)).toMatchObject(admStateEx(admin.id));
159
- expect(yield* Queue.take(outRxQ)).toMatchObject(groupStateEx(group));
160
- const mapTellKnownStateMsg = yield* Queue.take(outRxQ);
158
+ // expect((await outRxQ.next()).value).toMatchObject(admStateEx(admin.id));
159
+ expect((await outRxQ.next()).value).toMatchObject(groupStateEx(group));
160
+ const mapTellKnownStateMsg = (await outRxQ.next()).value;
161
161
  expect(mapTellKnownStateMsg).toEqual({
162
162
  action: "known",
163
163
  ...map.core.knownState(),
164
164
  });
165
- // expect(yield* Queue.take(outRxQ)).toMatchObject(admContEx(admin.id));
166
- expect(yield* Queue.take(outRxQ)).toMatchObject(groupContentEx(group));
167
- const mapNewContentHeaderOnlyMsg = yield* Queue.take(outRxQ);
165
+ // expect((await outRxQ.next()).value).toMatchObject(admContEx(admin.id));
166
+ expect((await outRxQ.next()).value).toMatchObject(groupContentEx(group));
167
+ const mapNewContentHeaderOnlyMsg = (await outRxQ.next()).value;
168
168
  expect(mapNewContentHeaderOnlyMsg).toEqual({
169
169
  action: "content",
170
170
  id: map.core.id,
@@ -172,7 +172,7 @@ test("After subscribing, node sends own known state and new txs to peer", () =>
172
172
  new: {},
173
173
  });
174
174
  map.set("hello", "world", "trusting");
175
- const mapEditMsg1 = yield* Queue.take(outRxQ);
175
+ const mapEditMsg1 = (await outRxQ.next()).value;
176
176
  expect(mapEditMsg1).toEqual({
177
177
  action: "content",
178
178
  id: map.core.id,
@@ -182,7 +182,8 @@ test("After subscribing, node sends own known state and new txs to peer", () =>
182
182
  newTransactions: [
183
183
  {
184
184
  privacy: "trusting",
185
- madeAt: map.core.sessionLogs.get(node.currentSessionID).transactions[0].madeAt,
185
+ madeAt: map.core.sessionLogs.get(node.currentSessionID)
186
+ .transactions[0].madeAt,
186
187
  changes: stableStringify([
187
188
  {
188
189
  op: "set",
@@ -192,12 +193,13 @@ test("After subscribing, node sends own known state and new txs to peer", () =>
192
193
  ]),
193
194
  },
194
195
  ],
195
- lastSignature: map.core.sessionLogs.get(node.currentSessionID).lastSignature,
196
+ lastSignature: map.core.sessionLogs.get(node.currentSessionID)
197
+ .lastSignature,
196
198
  },
197
199
  },
198
200
  });
199
201
  map.set("goodbye", "world", "trusting");
200
- const mapEditMsg2 = yield* Queue.take(outRxQ);
202
+ const mapEditMsg2 = (await outRxQ.next()).value;
201
203
  expect(mapEditMsg2).toEqual({
202
204
  action: "content",
203
205
  id: map.core.id,
@@ -207,7 +209,8 @@ test("After subscribing, node sends own known state and new txs to peer", () =>
207
209
  newTransactions: [
208
210
  {
209
211
  privacy: "trusting",
210
- madeAt: map.core.sessionLogs.get(node.currentSessionID).transactions[1].madeAt,
212
+ madeAt: map.core.sessionLogs.get(node.currentSessionID)
213
+ .transactions[1].madeAt,
211
214
  changes: stableStringify([
212
215
  {
213
216
  op: "set",
@@ -217,29 +220,29 @@ test("After subscribing, node sends own known state and new txs to peer", () =>
217
220
  ]),
218
221
  },
219
222
  ],
220
- lastSignature: map.core.sessionLogs.get(node.currentSessionID).lastSignature,
223
+ lastSignature: map.core.sessionLogs.get(node.currentSessionID)
224
+ .lastSignature,
221
225
  },
222
226
  },
223
227
  });
224
- }).pipe(Effect.scoped, Effect.runPromise));
225
- test("Client replies with known new content to tellKnownState from server", () => Effect.gen(function* () {
228
+ });
229
+ test("Client replies with known new content to tellKnownState from server", async () => {
226
230
  const [admin, session] = randomAnonymousAccountAndSessionID();
227
231
  const node = new LocalNode(admin, session, Crypto);
228
232
  const group = node.createGroup();
229
233
  const map = group.createMap();
230
234
  map.set("hello", "world", "trusting");
231
- const [inRx, inTx] = yield* newQueuePair();
232
- const [outRx, outTx] = yield* newQueuePair();
233
- const outRxQ = yield* Queue.unbounded();
234
- yield* Effect.fork(Stream.run(outRx, Sink.fromQueue(outRxQ)));
235
+ const [inRx, inTx] = newQueuePair();
236
+ const [outRx, outTx] = newQueuePair();
237
+ const outRxQ = outRx[Symbol.asyncIterator]();
235
238
  node.syncManager.addPeer({
236
239
  id: "test",
237
240
  incoming: inRx,
238
241
  outgoing: outTx,
239
242
  role: "peer",
240
243
  });
241
- // expect(yield* Queue.take(outRxQ)).toMatchObject(groupStateEx(group));
242
- yield* Queue.offer(inTx, {
244
+ // expect((await outRxQ.next()).value).toMatchObject(groupStateEx(group));
245
+ await inTx.push({
243
246
  action: "known",
244
247
  id: map.core.id,
245
248
  header: false,
@@ -247,16 +250,16 @@ test("Client replies with known new content to tellKnownState from server", () =
247
250
  [node.currentSessionID]: 0,
248
251
  },
249
252
  });
250
- // expect(yield* Queue.take(outRxQ)).toMatchObject(admStateEx(admin.id));
251
- expect(yield* Queue.take(outRxQ)).toMatchObject(groupStateEx(group));
252
- const mapTellKnownStateMsg = yield* Queue.take(outRxQ);
253
+ // expect((await outRxQ.next()).value).toMatchObject(admStateEx(admin.id));
254
+ expect((await outRxQ.next()).value).toMatchObject(groupStateEx(group));
255
+ const mapTellKnownStateMsg = (await outRxQ.next()).value;
253
256
  expect(mapTellKnownStateMsg).toEqual({
254
257
  action: "known",
255
258
  ...map.core.knownState(),
256
259
  });
257
- // expect(yield* Queue.take(outRxQ)).toMatchObject(admContEx(admin.id));
258
- expect(yield* Queue.take(outRxQ)).toMatchObject(groupContentEx(group));
259
- const mapNewContentMsg = yield* Queue.take(outRxQ);
260
+ // expect((await outRxQ.next()).value).toMatchObject(admContEx(admin.id));
261
+ expect((await outRxQ.next()).value).toMatchObject(groupContentEx(group));
262
+ const mapNewContentMsg = (await outRxQ.next()).value;
260
263
  expect(mapNewContentMsg).toEqual({
261
264
  action: "content",
262
265
  id: map.core.id,
@@ -267,7 +270,8 @@ test("Client replies with known new content to tellKnownState from server", () =
267
270
  newTransactions: [
268
271
  {
269
272
  privacy: "trusting",
270
- madeAt: map.core.sessionLogs.get(node.currentSessionID).transactions[0].madeAt,
273
+ madeAt: map.core.sessionLogs.get(node.currentSessionID)
274
+ .transactions[0].madeAt,
271
275
  changes: stableStringify([
272
276
  {
273
277
  op: "set",
@@ -277,27 +281,27 @@ test("Client replies with known new content to tellKnownState from server", () =
277
281
  ]),
278
282
  },
279
283
  ],
280
- lastSignature: map.core.sessionLogs.get(node.currentSessionID).lastSignature,
284
+ lastSignature: map.core.sessionLogs.get(node.currentSessionID)
285
+ .lastSignature,
281
286
  },
282
287
  },
283
288
  });
284
- }).pipe(Effect.scoped, Effect.runPromise));
285
- test("No matter the optimistic known state, node respects invalid known state messages and resyncs", () => Effect.gen(function* () {
289
+ });
290
+ test("No matter the optimistic known state, node respects invalid known state messages and resyncs", async () => {
286
291
  const [admin, session] = randomAnonymousAccountAndSessionID();
287
292
  const node = new LocalNode(admin, session, Crypto);
288
293
  const group = node.createGroup();
289
294
  const map = group.createMap();
290
- const [inRx, inTx] = yield* newQueuePair();
291
- const [outRx, outTx] = yield* newQueuePair();
292
- const outRxQ = yield* Queue.unbounded();
293
- yield* Effect.fork(Stream.run(outRx, Sink.fromQueue(outRxQ)));
295
+ const [inRx, inTx] = newQueuePair();
296
+ const [outRx, outTx] = newQueuePair();
297
+ const outRxQ = outRx[Symbol.asyncIterator]();
294
298
  node.syncManager.addPeer({
295
299
  id: "test",
296
300
  incoming: inRx,
297
301
  outgoing: outTx,
298
302
  role: "peer",
299
303
  });
300
- yield* Queue.offer(inTx, {
304
+ await inTx.push({
301
305
  action: "load",
302
306
  id: map.core.id,
303
307
  header: false,
@@ -305,16 +309,16 @@ test("No matter the optimistic known state, node respects invalid known state me
305
309
  [node.currentSessionID]: 0,
306
310
  },
307
311
  });
308
- // expect(yield* Queue.take(outRxQ)).toMatchObject(admStateEx(admin.id));
309
- expect(yield* Queue.take(outRxQ)).toMatchObject(groupStateEx(group));
310
- const mapTellKnownStateMsg = yield* Queue.take(outRxQ);
312
+ // expect((await outRxQ.next()).value).toMatchObject(admStateEx(admin.id));
313
+ expect((await outRxQ.next()).value).toMatchObject(groupStateEx(group));
314
+ const mapTellKnownStateMsg = (await outRxQ.next()).value;
311
315
  expect(mapTellKnownStateMsg).toEqual({
312
316
  action: "known",
313
317
  ...map.core.knownState(),
314
318
  });
315
- // expect(yield* Queue.take(outRxQ)).toMatchObject(admContEx(admin.id));
316
- expect(yield* Queue.take(outRxQ)).toMatchObject(groupContentEx(group));
317
- const mapNewContentHeaderOnlyMsg = yield* Queue.take(outRxQ);
319
+ // expect((await outRxQ.next()).value).toMatchObject(admContEx(admin.id));
320
+ expect((await outRxQ.next()).value).toMatchObject(groupContentEx(group));
321
+ const mapNewContentHeaderOnlyMsg = (await outRxQ.next()).value;
318
322
  expect(mapNewContentHeaderOnlyMsg).toEqual({
319
323
  action: "content",
320
324
  id: map.core.id,
@@ -323,9 +327,9 @@ test("No matter the optimistic known state, node respects invalid known state me
323
327
  });
324
328
  map.set("hello", "world", "trusting");
325
329
  map.set("goodbye", "world", "trusting");
326
- const _mapEditMsgs = yield* Queue.take(outRxQ);
330
+ const _mapEditMsgs = (await outRxQ.next()).value;
327
331
  console.log("Sending correction");
328
- yield* Queue.offer(inTx, {
332
+ await inTx.push({
329
333
  action: "known",
330
334
  isCorrection: true,
331
335
  id: map.core.id,
@@ -334,7 +338,7 @@ test("No matter the optimistic known state, node respects invalid known state me
334
338
  [node.currentSessionID]: 1,
335
339
  },
336
340
  });
337
- const newContentAfterWrongAssumedState = yield* Queue.take(outRxQ);
341
+ const newContentAfterWrongAssumedState = (await outRxQ.next()).value;
338
342
  expect(newContentAfterWrongAssumedState).toEqual({
339
343
  action: "content",
340
344
  id: map.core.id,
@@ -345,7 +349,8 @@ test("No matter the optimistic known state, node respects invalid known state me
345
349
  newTransactions: [
346
350
  {
347
351
  privacy: "trusting",
348
- madeAt: map.core.sessionLogs.get(node.currentSessionID).transactions[1].madeAt,
352
+ madeAt: map.core.sessionLogs.get(node.currentSessionID)
353
+ .transactions[1].madeAt,
349
354
  changes: stableStringify([
350
355
  {
351
356
  op: "set",
@@ -355,20 +360,20 @@ test("No matter the optimistic known state, node respects invalid known state me
355
360
  ]),
356
361
  },
357
362
  ],
358
- lastSignature: map.core.sessionLogs.get(node.currentSessionID).lastSignature,
363
+ lastSignature: map.core.sessionLogs.get(node.currentSessionID)
364
+ .lastSignature,
359
365
  },
360
366
  },
361
367
  });
362
- }).pipe(Effect.scoped, Effect.runPromise));
363
- test("If we add a peer, but it never subscribes to a coValue, it won't get any messages", () => Effect.gen(function* () {
368
+ });
369
+ test("If we add a peer, but it never subscribes to a coValue, it won't get any messages", async () => {
364
370
  const [admin, session] = randomAnonymousAccountAndSessionID();
365
371
  const node = new LocalNode(admin, session, Crypto);
366
372
  const group = node.createGroup();
367
373
  const map = group.createMap();
368
- const [inRx, _inTx] = yield* newQueuePair();
369
- const [outRx, outTx] = yield* newQueuePair();
370
- const outRxQ = yield* Queue.unbounded();
371
- yield* Effect.fork(Stream.run(outRx, Sink.fromQueue(outRxQ)));
374
+ const [inRx, _inTx] = newQueuePair();
375
+ const [outRx, outTx] = newQueuePair();
376
+ const outRxQ = outRx[Symbol.asyncIterator]();
372
377
  node.syncManager.addPeer({
373
378
  id: "test",
374
379
  incoming: inRx,
@@ -376,35 +381,36 @@ test("If we add a peer, but it never subscribes to a coValue, it won't get any m
376
381
  role: "peer",
377
382
  });
378
383
  map.set("hello", "world", "trusting");
379
- expect(yield* Queue.take(outRxQ).pipe(Effect.timeout(100), Effect.catch("_tag", {
380
- failure: "TimeoutException",
381
- onFailure: () => Effect.succeed("neverHappened"),
382
- }))).toEqual("neverHappened");
383
- }).pipe(Effect.scoped, Effect.runPromise));
384
- test.todo("If we add a server peer, all updates to all coValues are sent to it, even if it doesn't subscribe", () => Effect.gen(function* () {
384
+ const timeoutPromise = new Promise((resolve) => setTimeout(() => resolve("neverHappened"), 100));
385
+ const result = await Promise.race([
386
+ outRxQ.next().then((value) => value.value),
387
+ timeoutPromise,
388
+ ]);
389
+ expect(result).toEqual("neverHappened");
390
+ });
391
+ test.todo("If we add a server peer, all updates to all coValues are sent to it, even if it doesn't subscribe", async () => {
385
392
  const [admin, session] = randomAnonymousAccountAndSessionID();
386
393
  const node = new LocalNode(admin, session, Crypto);
387
394
  const group = node.createGroup();
388
395
  const map = group.createMap();
389
- const [inRx, _inTx] = yield* newQueuePair();
390
- const [outRx, outTx] = yield* newQueuePair();
391
- const outRxQ = yield* Queue.unbounded();
392
- yield* Effect.fork(Stream.run(outRx, Sink.fromQueue(outRxQ)));
396
+ const [inRx, _inTx] = newQueuePair();
397
+ const [outRx, outTx] = newQueuePair();
398
+ const outRxQ = outRx[Symbol.asyncIterator]();
393
399
  node.syncManager.addPeer({
394
400
  id: "test",
395
401
  incoming: inRx,
396
402
  outgoing: outTx,
397
403
  role: "server",
398
404
  });
399
- // expect(yield* Queue.take(outRxQ)).toMatchObject({
405
+ // expect((await outRxQ.next()).value).toMatchObject({
400
406
  // action: "load",
401
407
  // id: adminID,
402
408
  // });
403
- expect(yield* Queue.take(outRxQ)).toMatchObject({
409
+ expect((await outRxQ.next()).value).toMatchObject({
404
410
  action: "load",
405
411
  id: group.core.id,
406
412
  });
407
- const mapSubscribeMsg = Queue.take(outRxQ);
413
+ const mapSubscribeMsg = (await outRxQ.next()).value;
408
414
  expect(mapSubscribeMsg).toEqual({
409
415
  action: "load",
410
416
  id: map.core.id,
@@ -412,9 +418,9 @@ test.todo("If we add a server peer, all updates to all coValues are sent to it,
412
418
  sessions: {},
413
419
  });
414
420
  map.set("hello", "world", "trusting");
415
- // expect(yield* Queue.take(outRxQ)).toMatchObject(admContEx(admin.id));
416
- expect(yield* Queue.take(outRxQ)).toMatchObject(groupContentEx(group));
417
- const mapNewContentMsg = Queue.take(outRxQ);
421
+ // expect((await outRxQ.next()).value).toMatchObject(admContEx(admin.id));
422
+ expect((await outRxQ.next()).value).toMatchObject(groupContentEx(group));
423
+ const mapNewContentMsg = (await outRxQ.next()).value;
418
424
  expect(mapNewContentMsg).toEqual({
419
425
  action: "content",
420
426
  id: map.core.id,
@@ -439,89 +445,86 @@ test.todo("If we add a server peer, all updates to all coValues are sent to it,
439
445
  },
440
446
  },
441
447
  });
442
- }).pipe(Effect.scoped, Effect.runPromise));
443
- test.skip("If we add a server peer, newly created coValues are auto-subscribed to", () => Effect.gen(function* () {
448
+ });
449
+ test.skip("If we add a server peer, newly created coValues are auto-subscribed to", async () => {
444
450
  const [admin, session] = randomAnonymousAccountAndSessionID();
445
451
  const node = new LocalNode(admin, session, Crypto);
446
452
  const group = node.createGroup();
447
- const [inRx, _inTx] = yield* newQueuePair();
448
- const [outRx, outTx] = yield* newQueuePair();
449
- const outRxQ = yield* Queue.unbounded();
450
- yield* Effect.fork(Stream.run(outRx, Sink.fromQueue(outRxQ)));
453
+ const [inRx, _inTx] = newQueuePair();
454
+ const [outRx, outTx] = newQueuePair();
455
+ const outRxQ = outRx[Symbol.asyncIterator]();
451
456
  node.syncManager.addPeer({
452
457
  id: "test",
453
458
  incoming: inRx,
454
459
  outgoing: outTx,
455
460
  role: "server",
456
461
  });
457
- // expect(yield* Queue.take(outRxQ)).toMatchObject({
462
+ // expect((await outRxQ.next()).value).toMatchObject({
458
463
  // action: "load",
459
464
  // id: admin.id,
460
465
  // });
461
- expect(yield* Queue.take(outRxQ)).toMatchObject({
466
+ expect((await outRxQ.next()).value).toMatchObject({
462
467
  action: "load",
463
468
  id: group.core.id,
464
469
  });
465
470
  const map = group.createMap();
466
- const mapSubscribeMsg = Queue.take(outRxQ);
471
+ const mapSubscribeMsg = (await outRxQ.next()).value;
467
472
  expect(mapSubscribeMsg).toEqual({
468
473
  action: "load",
469
474
  ...map.core.knownState(),
470
475
  });
471
- // expect(yield* Queue.take(outRxQ)).toMatchObject(admContEx(adminID));
472
- expect(yield* Queue.take(outRxQ)).toMatchObject(groupContentEx(group));
473
- const mapContentMsg = Queue.take(outRxQ);
476
+ // expect((await outRxQ.next()).value).toMatchObject(admContEx(adminID));
477
+ expect((await outRxQ.next()).value).toMatchObject(groupContentEx(group));
478
+ const mapContentMsg = (await outRxQ.next()).value;
474
479
  expect(mapContentMsg).toEqual({
475
480
  action: "content",
476
481
  id: map.core.id,
477
482
  header: map.core.header,
478
483
  new: {},
479
484
  });
480
- }).pipe(Effect.scoped, Effect.runPromise));
485
+ });
481
486
  test.todo("TODO: when receiving a subscribe response that is behind our optimistic state (due to already sent content), we ignore it");
482
- test("When we connect a new server peer, we try to sync all existing coValues to it", () => Effect.gen(function* () {
487
+ test("When we connect a new server peer, we try to sync all existing coValues to it", async () => {
483
488
  const [admin, session] = randomAnonymousAccountAndSessionID();
484
489
  const node = new LocalNode(admin, session, Crypto);
485
490
  const group = node.createGroup();
486
491
  const map = group.createMap();
487
- const [inRx, _inTx] = yield* newQueuePair();
488
- const [outRx, outTx] = yield* newQueuePair();
489
- const outRxQ = yield* Queue.unbounded();
490
- yield* Effect.fork(Stream.run(outRx, Sink.fromQueue(outRxQ)));
492
+ const [inRx, _inTx] = newQueuePair();
493
+ const [outRx, outTx] = newQueuePair();
494
+ const outRxQ = outRx[Symbol.asyncIterator]();
491
495
  node.syncManager.addPeer({
492
496
  id: "test",
493
497
  incoming: inRx,
494
498
  outgoing: outTx,
495
499
  role: "server",
496
500
  });
497
- // const _adminSubscribeMessage = yield* Queue.take(outRxQ);
498
- const groupSubscribeMessage = yield* Queue.take(outRxQ);
501
+ // const _adminSubscribeMessage = await outRxQ.next();
502
+ const groupSubscribeMessage = (await outRxQ.next()).value;
499
503
  expect(groupSubscribeMessage).toEqual({
500
504
  action: "load",
501
505
  ...group.core.knownState(),
502
506
  });
503
- const secondMessage = yield* Queue.take(outRxQ);
507
+ const secondMessage = (await outRxQ.next()).value;
504
508
  expect(secondMessage).toEqual({
505
509
  action: "load",
506
510
  ...map.core.knownState(),
507
511
  });
508
- }).pipe(Effect.scoped, Effect.runPromise));
509
- test("When receiving a subscribe with a known state that is ahead of our own, peers should respond with a corresponding subscribe response message", () => Effect.gen(function* () {
512
+ });
513
+ 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 () => {
510
514
  const [admin, session] = randomAnonymousAccountAndSessionID();
511
515
  const node = new LocalNode(admin, session, Crypto);
512
516
  const group = node.createGroup();
513
517
  const map = group.createMap();
514
- const [inRx, inTx] = yield* newQueuePair();
515
- const [outRx, outTx] = yield* newQueuePair();
516
- const outRxQ = yield* Queue.unbounded();
517
- yield* Effect.fork(Stream.run(outRx, Sink.fromQueue(outRxQ)));
518
+ const [inRx, inTx] = newQueuePair();
519
+ const [outRx, outTx] = newQueuePair();
520
+ const outRxQ = outRx[Symbol.asyncIterator]();
518
521
  node.syncManager.addPeer({
519
522
  id: "test",
520
523
  incoming: inRx,
521
524
  outgoing: outTx,
522
525
  role: "peer",
523
526
  });
524
- yield* Queue.offer(inTx, {
527
+ await inTx.push({
525
528
  action: "load",
526
529
  id: map.core.id,
527
530
  header: true,
@@ -529,23 +532,22 @@ test("When receiving a subscribe with a known state that is ahead of our own, pe
529
532
  [node.currentSessionID]: 1,
530
533
  },
531
534
  });
532
- // expect(yield* Queue.take(outRxQ)).toMatchObject(admStateEx(admin.id));
533
- expect(yield* Queue.take(outRxQ)).toMatchObject(groupStateEx(group));
534
- const mapTellKnownState = yield* Queue.take(outRxQ);
535
+ // expect((await outRxQ.next()).value).toMatchObject(admStateEx(admin.id));
536
+ expect((await outRxQ.next()).value).toMatchObject(groupStateEx(group));
537
+ const mapTellKnownState = (await outRxQ.next()).value;
535
538
  expect(mapTellKnownState).toEqual({
536
539
  action: "known",
537
540
  ...map.core.knownState(),
538
541
  });
539
- }).pipe(Effect.scoped, Effect.runPromise));
540
- test.skip("When replaying creation and transactions of a coValue as new content, the receiving peer integrates this information", () => Effect.gen(function* () {
542
+ });
543
+ test.skip("When replaying creation and transactions of a coValue as new content, the receiving peer integrates this information", async () => {
541
544
  // 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
542
545
  const [admin, session] = randomAnonymousAccountAndSessionID();
543
546
  const node1 = new LocalNode(admin, session, Crypto);
544
547
  const group = node1.createGroup();
545
- const [inRx1, inTx1] = yield* newQueuePair();
546
- const [outRx1, outTx1] = yield* newQueuePair();
547
- const outRxQ1 = yield* Queue.unbounded();
548
- yield* Effect.fork(Stream.run(outRx1, Sink.fromQueue(outRxQ1)));
548
+ const [inRx1, inTx1] = newQueuePair();
549
+ const [outRx1, outTx1] = newQueuePair();
550
+ const outRxQ1 = outRx1[Symbol.asyncIterator]();
549
551
  node1.syncManager.addPeer({
550
552
  id: "test2",
551
553
  incoming: inRx1,
@@ -553,56 +555,55 @@ test.skip("When replaying creation and transactions of a coValue as new content,
553
555
  role: "server",
554
556
  });
555
557
  const node2 = new LocalNode(admin, newRandomSessionID(admin.id), Crypto);
556
- const [inRx2, inTx2] = yield* newQueuePair();
557
- const [outRx2, outTx2] = yield* newQueuePair();
558
- const outRxQ2 = yield* Queue.unbounded();
559
- yield* Effect.fork(Stream.run(outRx2, Sink.fromQueue(outRxQ1)));
558
+ const [inRx2, inTx2] = newQueuePair();
559
+ const [outRx2, outTx2] = newQueuePair();
560
+ const outRxQ2 = outRx2[Symbol.asyncIterator]();
560
561
  node2.syncManager.addPeer({
561
562
  id: "test1",
562
563
  incoming: inRx2,
563
564
  outgoing: outTx2,
564
565
  role: "client",
565
566
  });
566
- const adminSubscribeMessage = yield* Queue.take(outRxQ1);
567
+ const adminSubscribeMessage = (await outRxQ1.next()).value;
567
568
  expect(adminSubscribeMessage).toMatchObject({
568
569
  action: "load",
569
570
  id: admin.id,
570
571
  });
571
- const groupSubscribeMsg = yield* Queue.take(outRxQ1);
572
+ const groupSubscribeMsg = (await outRxQ1.next()).value;
572
573
  expect(groupSubscribeMsg).toMatchObject({
573
574
  action: "load",
574
575
  id: group.core.id,
575
576
  });
576
- yield* Queue.offer(inTx2, adminSubscribeMessage);
577
- yield* Queue.offer(inTx2, groupSubscribeMsg);
578
- // const adminTellKnownStateMsg = yield* Queue.take(outRxQ2);
577
+ await inTx2.push(adminSubscribeMessage);
578
+ await inTx2.push(groupSubscribeMsg);
579
+ // const adminTellKnownStateMsg = (await outRxQ2.next()).value;
579
580
  // expect(adminTellKnownStateMsg).toMatchObject(admStateEx(admin.id));
580
- const groupTellKnownStateMsg = yield* Queue.take(outRxQ2);
581
+ const groupTellKnownStateMsg = (await outRxQ2.next()).value;
581
582
  expect(groupTellKnownStateMsg).toMatchObject(groupStateEx(group));
582
583
  expect(node2.syncManager.peers["test1"].optimisticKnownStates[group.core.id]).toBeDefined();
583
- // yield* Queue.offer(inTx1, adminTellKnownStateMsg);
584
- yield* Queue.offer(inTx1, groupTellKnownStateMsg);
585
- // const adminContentMsg = yield* Queue.take(outRxQ1);
584
+ // await inTx1.push(adminTellKnownStateMsg);
585
+ await inTx1.push(groupTellKnownStateMsg);
586
+ // const adminContentMsg = (await outRxQ1.next()).value;
586
587
  // expect(adminContentMsg).toMatchObject(admContEx(admin.id));
587
- const groupContentMsg = yield* Queue.take(outRxQ1);
588
+ const groupContentMsg = (await outRxQ1.next()).value;
588
589
  expect(groupContentMsg).toMatchObject(groupContentEx(group));
589
- // yield* Queue.offer(inTx2, adminContentMsg);
590
- yield* Queue.offer(inTx2, groupContentMsg);
590
+ // await inTx2.push(adminContentMsg);
591
+ await inTx2.push(groupContentMsg);
591
592
  const map = group.createMap();
592
- const mapSubscriptionMsg = yield* Queue.take(outRxQ1);
593
+ const mapSubscriptionMsg = (await outRxQ1.next()).value;
593
594
  expect(mapSubscriptionMsg).toMatchObject({
594
595
  action: "load",
595
596
  id: map.core.id,
596
597
  });
597
- const mapNewContentMsg = yield* Queue.take(outRxQ1);
598
+ const mapNewContentMsg = (await outRxQ1.next()).value;
598
599
  expect(mapNewContentMsg).toEqual({
599
600
  action: "content",
600
601
  id: map.core.id,
601
602
  header: map.core.header,
602
603
  new: {},
603
604
  });
604
- yield* Queue.offer(inTx2, mapSubscriptionMsg);
605
- const mapTellKnownStateMsg = yield* Queue.take(outRxQ2);
605
+ await inTx2.push(mapSubscriptionMsg);
606
+ const mapTellKnownStateMsg = (await outRxQ2.next()).value;
606
607
  expect(mapTellKnownStateMsg).toEqual({
607
608
  action: "known",
608
609
  id: map.core.id,
@@ -610,13 +611,13 @@ test.skip("When replaying creation and transactions of a coValue as new content,
610
611
  sessions: {},
611
612
  });
612
613
  expect(node2.coValues[map.core.id]?.state).toEqual("loading");
613
- yield* Queue.offer(inTx2, mapNewContentMsg);
614
+ await inTx2.push(mapNewContentMsg);
614
615
  map.set("hello", "world", "trusting");
615
- const mapEditMsg = yield* Queue.take(outRxQ1);
616
- yield* Queue.offer(inTx2, mapEditMsg);
617
- yield* Effect.sleep(100);
616
+ const mapEditMsg = (await outRxQ1.next()).value;
617
+ await inTx2.push(mapEditMsg);
618
+ await new Promise((resolve) => setTimeout(resolve, 100));
618
619
  expect(expectMap(node2.expectCoValueLoaded(map.core.id).getCurrentContent()).get("hello")).toEqual("world");
619
- }).pipe(Effect.scoped, Effect.runPromise));
620
+ });
620
621
  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 () => {
621
622
  /*
622
623
  // 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
@@ -645,7 +646,7 @@ test.skip("When loading a coValue on one node, the server node it is requested f
645
646
  ).toEqual("world");
646
647
  */
647
648
  });
648
- test("Can sync a coValue through a server to another client", () => Effect.gen(function* () {
649
+ test("Can sync a coValue through a server to another client", async () => {
649
650
  const [admin, session] = randomAnonymousAccountAndSessionID();
650
651
  const client1 = new LocalNode(admin, session, Crypto);
651
652
  const group = client1.createGroup();
@@ -653,7 +654,7 @@ test("Can sync a coValue through a server to another client", () => Effect.gen(f
653
654
  map.set("hello", "world", "trusting");
654
655
  const [serverUser, serverSession] = randomAnonymousAccountAndSessionID();
655
656
  const server = new LocalNode(serverUser, serverSession, Crypto);
656
- const [serverAsPeerForClient1, client1AsPeer] = yield* connectedPeers("serverFor1", "client1", {
657
+ const [serverAsPeerForClient1, client1AsPeer] = await connectedPeers("serverFor1", "client1", {
657
658
  peer1role: "server",
658
659
  peer2role: "client",
659
660
  trace: true,
@@ -661,20 +662,20 @@ test("Can sync a coValue through a server to another client", () => Effect.gen(f
661
662
  client1.syncManager.addPeer(serverAsPeerForClient1);
662
663
  server.syncManager.addPeer(client1AsPeer);
663
664
  const client2 = new LocalNode(admin, newRandomSessionID(admin.id), Crypto);
664
- const [serverAsPeerForClient2, client2AsPeer] = yield* connectedPeers("serverFor2", "client2", {
665
+ const [serverAsPeerForClient2, client2AsPeer] = connectedPeers("serverFor2", "client2", {
665
666
  peer1role: "server",
666
667
  peer2role: "client",
667
668
  trace: true,
668
669
  });
669
670
  client2.syncManager.addPeer(serverAsPeerForClient2);
670
671
  server.syncManager.addPeer(client2AsPeer);
671
- const mapOnClient2 = yield* Effect.promise(() => client2.loadCoValueCore(map.core.id));
672
+ const mapOnClient2 = await client2.loadCoValueCore(map.core.id);
672
673
  if (mapOnClient2 === "unavailable") {
673
674
  throw new Error("Map is unavailable");
674
675
  }
675
676
  expect(expectMap(mapOnClient2.getCurrentContent()).get("hello")).toEqual("world");
676
- }).pipe(Effect.scoped, Effect.runPromise));
677
- test("Can sync a coValue with private transactions through a server to another client", () => Effect.gen(function* () {
677
+ });
678
+ test("Can sync a coValue with private transactions through a server to another client", async () => {
678
679
  const [admin, session] = randomAnonymousAccountAndSessionID();
679
680
  const client1 = new LocalNode(admin, session, Crypto);
680
681
  const group = client1.createGroup();
@@ -682,7 +683,7 @@ test("Can sync a coValue with private transactions through a server to another c
682
683
  map.set("hello", "world", "private");
683
684
  const [serverUser, serverSession] = randomAnonymousAccountAndSessionID();
684
685
  const server = new LocalNode(serverUser, serverSession, Crypto);
685
- const [serverAsPeer, client1AsPeer] = yield* connectedPeers("server", "client1", {
686
+ const [serverAsPeer, client1AsPeer] = await connectedPeers("server", "client1", {
686
687
  trace: true,
687
688
  peer1role: "server",
688
689
  peer2role: "client",
@@ -690,19 +691,19 @@ test("Can sync a coValue with private transactions through a server to another c
690
691
  client1.syncManager.addPeer(serverAsPeer);
691
692
  server.syncManager.addPeer(client1AsPeer);
692
693
  const client2 = new LocalNode(admin, newRandomSessionID(admin.id), Crypto);
693
- const [serverAsOtherPeer, client2AsPeer] = yield* connectedPeers("server", "client2", {
694
+ const [serverAsOtherPeer, client2AsPeer] = await connectedPeers("server", "client2", {
694
695
  trace: true,
695
696
  peer1role: "server",
696
697
  peer2role: "client",
697
698
  });
698
699
  client2.syncManager.addPeer(serverAsOtherPeer);
699
700
  server.syncManager.addPeer(client2AsPeer);
700
- const mapOnClient2 = yield* Effect.promise(() => client2.loadCoValueCore(map.core.id));
701
+ const mapOnClient2 = await client2.loadCoValueCore(map.core.id);
701
702
  if (mapOnClient2 === "unavailable") {
702
703
  throw new Error("Map is unavailable");
703
704
  }
704
705
  expect(expectMap(mapOnClient2.getCurrentContent()).get("hello")).toEqual("world");
705
- }).pipe(Effect.scoped, Effect.runPromise));
706
+ });
706
707
  test.skip("When a peer's incoming/readable stream closes, we remove the peer", async () => {
707
708
  /*
708
709
  const [admin, session] = randomAnonymousAccountAndSessionID();
@@ -814,14 +815,14 @@ test.skip("When a peer's outgoing/writable stream closes, we remove the peer", a
814
815
  expect(node.syncManager.peers["test"]).toBeUndefined();
815
816
  */
816
817
  });
817
- test("If we start loading a coValue before connecting to a peer that has it, it will load it once we connect", () => Effect.gen(function* () {
818
+ test("If we start loading a coValue before connecting to a peer that has it, it will load it once we connect", async () => {
818
819
  const [admin, session] = randomAnonymousAccountAndSessionID();
819
820
  const node1 = new LocalNode(admin, session, Crypto);
820
821
  const group = node1.createGroup();
821
822
  const map = group.createMap();
822
823
  map.set("hello", "world", "trusting");
823
824
  const node2 = new LocalNode(admin, newRandomSessionID(admin.id), Crypto);
824
- const [node1asPeer, node2asPeer] = yield* connectedPeers("peer1", "peer2", {
825
+ const [node1asPeer, node2asPeer] = await connectedPeers("peer1", "peer2", {
825
826
  peer1role: "server",
826
827
  peer2role: "client",
827
828
  trace: true,
@@ -830,12 +831,12 @@ test("If we start loading a coValue before connecting to a peer that has it, it
830
831
  const mapOnNode2Promise = node2.loadCoValueCore(map.core.id);
831
832
  expect(node2.coValues[map.core.id]?.state).toEqual("loading");
832
833
  node2.syncManager.addPeer(node1asPeer);
833
- const mapOnNode2 = yield* Effect.promise(() => mapOnNode2Promise);
834
+ const mapOnNode2 = await mapOnNode2Promise;
834
835
  if (mapOnNode2 === "unavailable") {
835
836
  throw new Error("Map is unavailable");
836
837
  }
837
838
  expect(expectMap(mapOnNode2.getCurrentContent()).get("hello")).toEqual("world");
838
- }).pipe(Effect.scoped, Effect.runPromise));
839
+ });
839
840
  function groupContentEx(group) {
840
841
  return {
841
842
  action: "content",