cojson 0.19.1 → 0.19.3

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.
@@ -0,0 +1,491 @@
1
+ import { assert, beforeEach, describe, expect, test } from "vitest";
2
+
3
+ import { expectList, expectMap } from "../coValue";
4
+ import { WasmCrypto } from "../crypto/WasmCrypto";
5
+ import {
6
+ SyncMessagesLog,
7
+ TEST_NODE_CONFIG,
8
+ fillCoMapWithLargeData,
9
+ loadCoValueOrFail,
10
+ setupTestNode,
11
+ waitFor,
12
+ } from "./testUtils";
13
+ import { RawCoMap } from "../coValues/coMap";
14
+
15
+ // We want to simulate a real world communication that happens asynchronously
16
+ TEST_NODE_CONFIG.withAsyncPeers = true;
17
+
18
+ const Crypto = await WasmCrypto.create();
19
+ let server1: ReturnType<typeof setupTestNode>;
20
+ let server2: ReturnType<typeof setupTestNode>;
21
+
22
+ beforeEach(async () => {
23
+ SyncMessagesLog.clear();
24
+ server1 = setupTestNode();
25
+ server2 = setupTestNode();
26
+ });
27
+
28
+ function connectServers(client: ReturnType<typeof setupTestNode>) {
29
+ client.connectToSyncServer({
30
+ ourName: "client",
31
+ syncServerName: "server1",
32
+ syncServer: server1.node,
33
+ });
34
+ client.connectToSyncServer({
35
+ ourName: "client",
36
+ syncServerName: "server2",
37
+ syncServer: server2.node,
38
+ });
39
+ }
40
+
41
+ describe("multiple servers peers", () => {
42
+ test("coValue uploading", async () => {
43
+ const client = setupTestNode();
44
+ connectServers(client);
45
+
46
+ const group = client.node.createGroup();
47
+ const map = group.createMap();
48
+ map.set("hello", "world", "trusting");
49
+
50
+ await map.core.waitForSync();
51
+
52
+ expect(
53
+ SyncMessagesLog.getMessages({
54
+ Group: group.core,
55
+ Map: map.core,
56
+ }),
57
+ ).toMatchInlineSnapshot(`
58
+ [
59
+ "client -> server1 | CONTENT Group header: true new: After: 0 New: 3",
60
+ "client -> server2 | CONTENT Group header: true new: After: 0 New: 3",
61
+ "client -> server1 | CONTENT Map header: true new: After: 0 New: 1",
62
+ "client -> server2 | CONTENT Map header: true new: After: 0 New: 1",
63
+ "server1 -> client | KNOWN Group sessions: header/3",
64
+ "server2 -> client | KNOWN Group sessions: header/3",
65
+ "server1 -> client | KNOWN Map sessions: header/1",
66
+ "server2 -> client | KNOWN Map sessions: header/1",
67
+ ]
68
+ `);
69
+
70
+ const mapOnServer1 = server1.node.getCoValue(map.id);
71
+ const mapOnServer2 = server2.node.getCoValue(map.id);
72
+
73
+ expect(mapOnServer1.knownState()).toEqual(map.core.knownState());
74
+ expect(mapOnServer2.knownState()).toEqual(map.core.knownState());
75
+ });
76
+
77
+ test("coValue sync across clients", async () => {
78
+ const client = setupTestNode();
79
+ connectServers(client);
80
+
81
+ const group = client.node.createGroup();
82
+ const map = group.createMap();
83
+ map.set("count", 1, "trusting");
84
+
85
+ const session2 = client.spawnNewSession();
86
+ connectServers(session2);
87
+
88
+ const mapOnSession2 = await loadCoValueOrFail(session2.node, map.id);
89
+ mapOnSession2.set("count", 2, "trusting");
90
+
91
+ map.set("count", 3, "trusting");
92
+
93
+ await new Promise((resolve) => setTimeout(resolve, 10));
94
+
95
+ mapOnSession2.set("count", 4, "trusting");
96
+
97
+ await waitFor(() => {
98
+ expect(map.get("count")).toEqual(4);
99
+ expect(mapOnSession2.get("count")).toEqual(4);
100
+ });
101
+
102
+ expect(
103
+ SyncMessagesLog.getMessages({
104
+ Group: group.core,
105
+ Map: map.core,
106
+ }),
107
+ ).toMatchInlineSnapshot(`
108
+ [
109
+ "client -> server1 | LOAD Map sessions: empty",
110
+ "client -> server2 | LOAD Map sessions: empty",
111
+ "client -> server1 | CONTENT Group header: true new: After: 0 New: 3",
112
+ "client -> server2 | CONTENT Group header: true new: After: 0 New: 3",
113
+ "client -> server1 | CONTENT Map header: true new: After: 0 New: 1",
114
+ "client -> server2 | CONTENT Map header: true new: After: 0 New: 1",
115
+ "server1 -> client | KNOWN Map sessions: empty",
116
+ "server2 -> client | KNOWN Map sessions: empty",
117
+ "server1 -> client | KNOWN Group sessions: header/3",
118
+ "server2 -> client | KNOWN Group sessions: header/3",
119
+ "server1 -> client | KNOWN Map sessions: header/1",
120
+ "server1 -> client | CONTENT Group header: true new: After: 0 New: 3",
121
+ "server1 -> client | CONTENT Map header: true new: After: 0 New: 1",
122
+ "server2 -> client | KNOWN Map sessions: header/1",
123
+ "server2 -> client | CONTENT Group header: true new: After: 0 New: 3",
124
+ "server2 -> client | CONTENT Map header: true new: After: 0 New: 1",
125
+ "client -> server1 | KNOWN Group sessions: header/3",
126
+ "client -> server2 | LOAD Group sessions: header/3",
127
+ "client -> server1 | KNOWN Map sessions: header/1",
128
+ "client -> server2 | CONTENT Map header: true new: After: 0 New: 1",
129
+ "client -> server1 | CONTENT Map header: false new: After: 0 New: 1",
130
+ "client -> server2 | CONTENT Map header: false new: After: 0 New: 1",
131
+ "client -> server1 | CONTENT Map header: false new: After: 1 New: 1",
132
+ "client -> server2 | CONTENT Map header: false new: After: 1 New: 1",
133
+ "client -> server2 | KNOWN Group sessions: header/3",
134
+ "client -> server2 | CONTENT Group header: false new: After: 0 New: 3",
135
+ "client -> server2 | KNOWN Map sessions: header/2",
136
+ "server2 -> client | KNOWN Map sessions: header/1",
137
+ "server1 -> client | KNOWN Map sessions: header/2",
138
+ "server1 -> client | CONTENT Map header: false new: After: 0 New: 1",
139
+ "server2 -> client | KNOWN Map sessions: header/2",
140
+ "server2 -> client | CONTENT Map header: false new: After: 0 New: 1",
141
+ "server1 -> client | KNOWN Map sessions: header/3",
142
+ "server1 -> client | CONTENT Map header: false new: After: 1 New: 1",
143
+ "server2 -> client | KNOWN Map sessions: header/3",
144
+ "server2 -> client | CONTENT Map header: false new: After: 1 New: 1",
145
+ "server2 -> client | KNOWN Group sessions: header/3",
146
+ "client -> server1 | KNOWN Map sessions: header/3",
147
+ "client -> server2 | CONTENT Map header: false new: After: 0 New: 1",
148
+ "client -> server2 | KNOWN Map sessions: header/3",
149
+ "client -> server1 | KNOWN Map sessions: header/3",
150
+ "client -> server2 | CONTENT Map header: false new: After: 1 New: 1",
151
+ "client -> server2 | KNOWN Map sessions: header/3",
152
+ "server2 -> client | KNOWN Map sessions: header/3",
153
+ "server2 -> client | KNOWN Map sessions: header/3",
154
+ "client -> server1 | CONTENT Map header: false new: After: 1 New: 1",
155
+ "client -> server2 | CONTENT Map header: false new: After: 1 New: 1",
156
+ "server1 -> client | KNOWN Map sessions: header/4",
157
+ "server1 -> client | CONTENT Map header: false new: After: 1 New: 1",
158
+ "server2 -> client | KNOWN Map sessions: header/4",
159
+ "server2 -> client | CONTENT Map header: false new: After: 1 New: 1",
160
+ "client -> server1 | KNOWN Map sessions: header/4",
161
+ "client -> server2 | CONTENT Map header: false new: After: 1 New: 1",
162
+ "client -> server2 | KNOWN Map sessions: header/4",
163
+ "server2 -> client | KNOWN Map sessions: header/4",
164
+ ]
165
+ `);
166
+
167
+ const mapOnServer1 = server1.node.getCoValue(map.id);
168
+ const mapOnServer2 = server2.node.getCoValue(map.id);
169
+
170
+ expect(mapOnServer1.knownState()).toEqual(map.core.knownState());
171
+ expect(mapOnServer2.knownState()).toEqual(map.core.knownState());
172
+ });
173
+
174
+ test("coValue with parent groups uploading", async () => {
175
+ const client = setupTestNode();
176
+ connectServers(client);
177
+
178
+ const group = client.node.createGroup();
179
+ const parentGroup = client.node.createGroup();
180
+ parentGroup.addMember("everyone", "reader");
181
+
182
+ group.extend(parentGroup);
183
+
184
+ const map = group.createMap();
185
+ map.set("hello", "world", "trusting");
186
+
187
+ await map.core.waitForSync();
188
+
189
+ expect(
190
+ SyncMessagesLog.getMessages({
191
+ ParentGroup: parentGroup.core,
192
+ Group: group.core,
193
+ Map: map.core,
194
+ }),
195
+ ).toMatchInlineSnapshot(`
196
+ [
197
+ "client -> server1 | CONTENT Group header: true new: After: 0 New: 3",
198
+ "client -> server2 | CONTENT Group header: true new: After: 0 New: 3",
199
+ "client -> server1 | CONTENT ParentGroup header: true new: After: 0 New: 5",
200
+ "client -> server2 | CONTENT ParentGroup header: true new: After: 0 New: 5",
201
+ "client -> server1 | CONTENT Group header: false new: After: 3 New: 2",
202
+ "client -> server2 | CONTENT Group header: false new: After: 3 New: 2",
203
+ "client -> server1 | CONTENT Map header: true new: After: 0 New: 1",
204
+ "client -> server2 | CONTENT Map header: true new: After: 0 New: 1",
205
+ "server1 -> client | KNOWN Group sessions: header/3",
206
+ "server2 -> client | KNOWN Group sessions: header/3",
207
+ "server1 -> client | KNOWN ParentGroup sessions: header/5",
208
+ "server2 -> client | KNOWN ParentGroup sessions: header/5",
209
+ "server1 -> client | KNOWN Group sessions: header/5",
210
+ "server2 -> client | KNOWN Group sessions: header/5",
211
+ "server1 -> client | KNOWN Map sessions: header/1",
212
+ "server2 -> client | KNOWN Map sessions: header/1",
213
+ ]
214
+ `);
215
+
216
+ const mapOnServer1 = server1.node.getCoValue(map.id);
217
+ const mapOnServer2 = server2.node.getCoValue(map.id);
218
+
219
+ expect(mapOnServer1.knownState()).toEqual(map.core.knownState());
220
+ expect(mapOnServer2.knownState()).toEqual(map.core.knownState());
221
+ });
222
+
223
+ test("wrong optimistic known state should be corrected", async () => {
224
+ const client = setupTestNode();
225
+ connectServers(client);
226
+
227
+ const group = client.node.createGroup();
228
+ group.addMember("everyone", "writer");
229
+
230
+ const map = group.createMap({
231
+ fromServer: "initial",
232
+ fromClient: "initial",
233
+ });
234
+
235
+ // Load the coValue on the client
236
+ await map.core.waitForSync();
237
+
238
+ // Forcefully delete the coValue from server1 (simulating some data loss)
239
+ server1.node.internalDeleteCoValue(map.id);
240
+
241
+ map.set("fromClient", "updated", "trusting");
242
+
243
+ await waitFor(() => {
244
+ const mapOnServer1 = server1.node.getCoValue(map.id);
245
+ const mapOnServer2 = server2.node.getCoValue(map.id);
246
+
247
+ expect(mapOnServer1.knownState()).toEqual(map.core.knownState());
248
+ expect(mapOnServer2.knownState()).toEqual(map.core.knownState());
249
+ });
250
+
251
+ expect(
252
+ SyncMessagesLog.getMessages({
253
+ Group: group.core,
254
+ Map: map.core,
255
+ }),
256
+ ).toMatchInlineSnapshot(`
257
+ [
258
+ "client -> server1 | CONTENT Group header: true new: After: 0 New: 5",
259
+ "client -> server2 | CONTENT Group header: true new: After: 0 New: 5",
260
+ "client -> server1 | CONTENT Map header: true new: After: 0 New: 1",
261
+ "client -> server2 | CONTENT Map header: true new: After: 0 New: 1",
262
+ "server1 -> client | KNOWN Group sessions: header/5",
263
+ "server2 -> client | KNOWN Group sessions: header/5",
264
+ "server1 -> client | KNOWN Map sessions: header/1",
265
+ "server2 -> client | KNOWN Map sessions: header/1",
266
+ "client -> server1 | CONTENT Map header: false new: After: 1 New: 1",
267
+ "client -> server2 | CONTENT Map header: false new: After: 1 New: 1",
268
+ "server1 -> client | KNOWN CORRECTION Map sessions: empty",
269
+ "server2 -> client | KNOWN Map sessions: header/2",
270
+ "client -> server1 | CONTENT Map header: true new: After: 0 New: 2",
271
+ "server1 -> client | KNOWN Map sessions: header/2",
272
+ ]
273
+ `);
274
+ });
275
+
276
+ test("local updates batching", async () => {
277
+ const client = setupTestNode();
278
+ connectServers(client);
279
+
280
+ const group = client.node.createGroup();
281
+ const initialMap = group.createMap();
282
+
283
+ const child = group.createMap();
284
+ child.set("parent", initialMap.id);
285
+ initialMap.set("child", child.id);
286
+
287
+ await initialMap.core.waitForSync();
288
+
289
+ expect(
290
+ SyncMessagesLog.getMessages({
291
+ Group: group.core,
292
+ InitialMap: initialMap.core,
293
+ ChildMap: child.core,
294
+ }),
295
+ ).toMatchInlineSnapshot(`
296
+ [
297
+ "client -> server1 | CONTENT Group header: true new: After: 0 New: 3",
298
+ "client -> server2 | CONTENT Group header: true new: After: 0 New: 3",
299
+ "client -> server1 | CONTENT InitialMap header: true new: ",
300
+ "client -> server2 | CONTENT InitialMap header: true new: ",
301
+ "client -> server1 | CONTENT ChildMap header: true new: After: 0 New: 1",
302
+ "client -> server2 | CONTENT ChildMap header: true new: After: 0 New: 1",
303
+ "client -> server1 | CONTENT InitialMap header: false new: After: 0 New: 1",
304
+ "client -> server2 | CONTENT InitialMap header: false new: After: 0 New: 1",
305
+ "server1 -> client | KNOWN Group sessions: header/3",
306
+ "server2 -> client | KNOWN Group sessions: header/3",
307
+ "server1 -> client | KNOWN InitialMap sessions: header/0",
308
+ "server2 -> client | KNOWN InitialMap sessions: header/0",
309
+ "server1 -> client | KNOWN ChildMap sessions: header/1",
310
+ "server2 -> client | KNOWN ChildMap sessions: header/1",
311
+ "server1 -> client | KNOWN InitialMap sessions: header/1",
312
+ "server2 -> client | KNOWN InitialMap sessions: header/1",
313
+ ]
314
+ `);
315
+ });
316
+
317
+ test("large coValue upload streaming", async () => {
318
+ const client = setupTestNode();
319
+ connectServers(client);
320
+
321
+ const group = client.node.createGroup();
322
+ group.addMember("everyone", "writer");
323
+
324
+ const largeMap = group.createMap();
325
+
326
+ fillCoMapWithLargeData(largeMap);
327
+
328
+ await largeMap.core.waitForSync();
329
+
330
+ expect(
331
+ SyncMessagesLog.getMessages({
332
+ Group: group.core,
333
+ Map: largeMap.core,
334
+ }),
335
+ ).toMatchInlineSnapshot(`
336
+ [
337
+ "client -> server1 | CONTENT Group header: true new: After: 0 New: 5",
338
+ "client -> server2 | CONTENT Group header: true new: After: 0 New: 5",
339
+ "client -> server1 | CONTENT Map header: true new: After: 0 New: 73 expectContentUntil: header/200",
340
+ "client -> server2 | CONTENT Map header: true new: After: 0 New: 73 expectContentUntil: header/200",
341
+ "client -> server1 | CONTENT Map header: false new: After: 73 New: 73",
342
+ "client -> server2 | CONTENT Map header: false new: After: 73 New: 73",
343
+ "client -> server1 | CONTENT Map header: false new: After: 146 New: 54",
344
+ "client -> server2 | CONTENT Map header: false new: After: 146 New: 54",
345
+ "server1 -> client | KNOWN Group sessions: header/5",
346
+ "server2 -> client | KNOWN Group sessions: header/5",
347
+ "server1 -> client | KNOWN Map sessions: header/73",
348
+ "server2 -> client | KNOWN Map sessions: header/73",
349
+ "server1 -> client | KNOWN Map sessions: header/146",
350
+ "server2 -> client | KNOWN Map sessions: header/146",
351
+ "server1 -> client | KNOWN Map sessions: header/200",
352
+ "server2 -> client | KNOWN Map sessions: header/200",
353
+ ]
354
+ `);
355
+ });
356
+
357
+ test("uploading a large update", async () => {
358
+ const client = setupTestNode();
359
+ connectServers(client);
360
+
361
+ const group = client.node.createGroup();
362
+ group.addMember("everyone", "writer");
363
+
364
+ const largeMap = group.createMap();
365
+
366
+ await largeMap.core.waitForSync();
367
+
368
+ fillCoMapWithLargeData(largeMap);
369
+
370
+ await largeMap.core.waitForSync();
371
+
372
+ expect(
373
+ SyncMessagesLog.getMessages({
374
+ Group: group.core,
375
+ Map: largeMap.core,
376
+ }),
377
+ ).toMatchInlineSnapshot(`
378
+ [
379
+ "client -> server1 | CONTENT Group header: true new: After: 0 New: 5",
380
+ "client -> server2 | CONTENT Group header: true new: After: 0 New: 5",
381
+ "client -> server1 | CONTENT Map header: true new: ",
382
+ "client -> server2 | CONTENT Map header: true new: ",
383
+ "client -> server1 | CONTENT Map header: false new: After: 0 New: 73 expectContentUntil: header/200",
384
+ "client -> server2 | CONTENT Map header: false new: After: 0 New: 73 expectContentUntil: header/200",
385
+ "client -> server1 | CONTENT Map header: false new: After: 73 New: 73",
386
+ "client -> server2 | CONTENT Map header: false new: After: 73 New: 73",
387
+ "client -> server1 | CONTENT Map header: false new: After: 146 New: 54",
388
+ "client -> server2 | CONTENT Map header: false new: After: 146 New: 54",
389
+ "server1 -> client | KNOWN Group sessions: header/5",
390
+ "server2 -> client | KNOWN Group sessions: header/5",
391
+ "server1 -> client | KNOWN Map sessions: header/0",
392
+ "server2 -> client | KNOWN Map sessions: header/0",
393
+ "server1 -> client | KNOWN Map sessions: header/73",
394
+ "server2 -> client | KNOWN Map sessions: header/73",
395
+ "server1 -> client | KNOWN Map sessions: header/146",
396
+ "server2 -> client | KNOWN Map sessions: header/146",
397
+ "server1 -> client | KNOWN Map sessions: header/200",
398
+ "server2 -> client | KNOWN Map sessions: header/200",
399
+ ]
400
+ `);
401
+ });
402
+
403
+ test("uploading a large update between two clients", async () => {
404
+ const client = setupTestNode();
405
+ connectServers(client);
406
+ const client2 = setupTestNode();
407
+ connectServers(client2);
408
+
409
+ const group = client.node.createGroup();
410
+ group.addMember("everyone", "writer");
411
+
412
+ const largeMap = group.createMap();
413
+ const largeMapOnClient2 = await loadCoValueOrFail(
414
+ client2.node,
415
+ largeMap.id,
416
+ );
417
+
418
+ fillCoMapWithLargeData(largeMap);
419
+
420
+ await waitFor(() => {
421
+ expect(largeMapOnClient2.core.knownState()).toEqual(
422
+ largeMap.core.knownState(),
423
+ );
424
+ });
425
+
426
+ expect(
427
+ SyncMessagesLog.getMessages({
428
+ Group: group.core,
429
+ Map: largeMap.core,
430
+ }),
431
+ ).toMatchInlineSnapshot(`
432
+ [
433
+ "client -> server1 | LOAD Map sessions: empty",
434
+ "client -> server2 | LOAD Map sessions: empty",
435
+ "client -> server1 | CONTENT Group header: true new: After: 0 New: 5",
436
+ "client -> server2 | CONTENT Group header: true new: After: 0 New: 5",
437
+ "client -> server1 | CONTENT Map header: true new: ",
438
+ "client -> server2 | CONTENT Map header: true new: ",
439
+ "server1 -> client | KNOWN Map sessions: empty",
440
+ "server2 -> client | KNOWN Map sessions: empty",
441
+ "server1 -> client | KNOWN Group sessions: header/5",
442
+ "server2 -> client | KNOWN Group sessions: header/5",
443
+ "server1 -> client | KNOWN Map sessions: header/0",
444
+ "server1 -> client | CONTENT Group header: true new: After: 0 New: 5",
445
+ "server1 -> client | CONTENT Map header: true new: ",
446
+ "server2 -> client | KNOWN Map sessions: header/0",
447
+ "server2 -> client | CONTENT Group header: true new: After: 0 New: 5",
448
+ "server2 -> client | CONTENT Map header: true new: ",
449
+ "client -> server1 | KNOWN Group sessions: header/5",
450
+ "client -> server2 | LOAD Group sessions: header/5",
451
+ "client -> server1 | KNOWN Map sessions: header/0",
452
+ "client -> server2 | CONTENT Map header: true new: ",
453
+ "client -> server1 | CONTENT Map header: false new: After: 0 New: 73 expectContentUntil: header/200",
454
+ "client -> server2 | CONTENT Map header: false new: After: 0 New: 73 expectContentUntil: header/200",
455
+ "client -> server1 | CONTENT Map header: false new: After: 73 New: 73",
456
+ "client -> server2 | CONTENT Map header: false new: After: 73 New: 73",
457
+ "client -> server1 | CONTENT Map header: false new: After: 146 New: 54",
458
+ "client -> server2 | CONTENT Map header: false new: After: 146 New: 54",
459
+ "client -> server2 | KNOWN Group sessions: header/5",
460
+ "client -> server2 | CONTENT Group header: false new: After: 0 New: 5",
461
+ "client -> server2 | KNOWN Map sessions: header/0",
462
+ "server2 -> client | KNOWN Map sessions: header/0",
463
+ "server1 -> client | KNOWN Map sessions: header/73",
464
+ "server1 -> client | CONTENT Map header: false new: After: 0 New: 73",
465
+ "server2 -> client | KNOWN Map sessions: header/73",
466
+ "server2 -> client | CONTENT Map header: false new: After: 0 New: 73",
467
+ "server1 -> client | KNOWN Map sessions: header/146",
468
+ "server1 -> client | CONTENT Map header: false new: After: 73 New: 73",
469
+ "server2 -> client | KNOWN Map sessions: header/146",
470
+ "server2 -> client | CONTENT Map header: false new: After: 73 New: 73",
471
+ "server1 -> client | KNOWN Map sessions: header/200",
472
+ "server1 -> client | CONTENT Map header: false new: After: 146 New: 54",
473
+ "server2 -> client | KNOWN Map sessions: header/200",
474
+ "server2 -> client | CONTENT Map header: false new: After: 146 New: 54",
475
+ "server2 -> client | KNOWN Group sessions: header/5",
476
+ "client -> server1 | KNOWN Map sessions: header/73",
477
+ "client -> server2 | CONTENT Map header: false new: After: 0 New: 73",
478
+ "client -> server2 | KNOWN Map sessions: header/73",
479
+ "client -> server1 | KNOWN Map sessions: header/146",
480
+ "client -> server2 | CONTENT Map header: false new: After: 73 New: 73",
481
+ "client -> server2 | KNOWN Map sessions: header/146",
482
+ "client -> server1 | KNOWN Map sessions: header/200",
483
+ "client -> server2 | CONTENT Map header: false new: After: 146 New: 54",
484
+ "client -> server2 | KNOWN Map sessions: header/200",
485
+ "server2 -> client | KNOWN Map sessions: header/200",
486
+ "server2 -> client | KNOWN Map sessions: header/200",
487
+ "server2 -> client | KNOWN Map sessions: header/200",
488
+ ]
489
+ `);
490
+ });
491
+ });