cojson 0.18.34 → 0.18.35

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 (45) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +8 -0
  3. package/dist/coValueContentMessage.d.ts +5 -2
  4. package/dist/coValueContentMessage.d.ts.map +1 -1
  5. package/dist/coValueContentMessage.js +15 -0
  6. package/dist/coValueContentMessage.js.map +1 -1
  7. package/dist/coValueCore/SessionMap.d.ts +4 -3
  8. package/dist/coValueCore/SessionMap.d.ts.map +1 -1
  9. package/dist/coValueCore/SessionMap.js +12 -15
  10. package/dist/coValueCore/SessionMap.js.map +1 -1
  11. package/dist/coValueCore/coValueCore.d.ts +14 -6
  12. package/dist/coValueCore/coValueCore.d.ts.map +1 -1
  13. package/dist/coValueCore/coValueCore.js +29 -48
  14. package/dist/coValueCore/coValueCore.js.map +1 -1
  15. package/dist/coValueCore/verifiedState.d.ts +3 -3
  16. package/dist/coValueCore/verifiedState.d.ts.map +1 -1
  17. package/dist/coValueCore/verifiedState.js +18 -10
  18. package/dist/coValueCore/verifiedState.js.map +1 -1
  19. package/dist/coValues/group.d.ts.map +1 -1
  20. package/dist/coValues/group.js +20 -15
  21. package/dist/coValues/group.js.map +1 -1
  22. package/dist/knownState.d.ts.map +1 -1
  23. package/dist/knownState.js.map +1 -1
  24. package/dist/localNode.d.ts +7 -2
  25. package/dist/localNode.d.ts.map +1 -1
  26. package/dist/localNode.js +8 -14
  27. package/dist/localNode.js.map +1 -1
  28. package/dist/sync.d.ts.map +1 -1
  29. package/dist/sync.js +15 -18
  30. package/dist/sync.js.map +1 -1
  31. package/dist/tests/coValueContentMessage.test.js +130 -1
  32. package/dist/tests/coValueContentMessage.test.js.map +1 -1
  33. package/dist/tests/coValueCore.test.js +3 -6
  34. package/dist/tests/coValueCore.test.js.map +1 -1
  35. package/package.json +3 -4
  36. package/src/coValueContentMessage.ts +29 -2
  37. package/src/coValueCore/SessionMap.ts +23 -16
  38. package/src/coValueCore/coValueCore.ts +37 -63
  39. package/src/coValueCore/verifiedState.ts +25 -15
  40. package/src/coValues/group.ts +40 -27
  41. package/src/knownState.ts +3 -12
  42. package/src/localNode.ts +10 -18
  43. package/src/sync.ts +24 -25
  44. package/src/tests/coValueContentMessage.test.ts +197 -2
  45. package/src/tests/coValueCore.test.ts +7 -10
@@ -1,10 +1,15 @@
1
1
  import { describe, expect, test } from "vitest";
2
- import { knownStateFromContent } from "../coValueContentMessage.js";
2
+ import {
3
+ getNewTransactionsFromContentMessage,
4
+ knownStateFromContent,
5
+ } from "../coValueContentMessage.js";
3
6
  import { emptyKnownState } from "../knownState.js";
4
- import { NewContentMessage } from "../sync.js";
7
+ import { NewContentMessage, SessionNewContent } from "../sync.js";
5
8
  import type { RawCoID, SessionID } from "../ids.js";
6
9
  import { stableStringify } from "../jsonStringify.js";
7
10
  import { CO_VALUE_PRIORITY } from "../priority.js";
11
+ import { CoValueKnownState } from "../knownState.js";
12
+ import { Transaction } from "../coValueCore/verifiedState.js";
8
13
 
9
14
  describe("knownStateFromContent", () => {
10
15
  const mockCoID: RawCoID = "co_z1234567890abcdef";
@@ -213,3 +218,193 @@ describe("knownStateFromContent", () => {
213
218
  expect(result.sessions[mockSessionID1]).toBe(1); // 0 + 1
214
219
  });
215
220
  });
221
+
222
+ describe("getNewTransactionsFromContentMessage", () => {
223
+ const mockCoID: RawCoID = "co_z1234567890abcdef";
224
+ const mockSessionID: SessionID = "sealer_z123/signer_z456_session_z789";
225
+
226
+ function createTransaction(): Transaction {
227
+ return {
228
+ privacy: "trusting",
229
+ madeAt: Date.now(),
230
+ changes: stableStringify([{ op: "set", key: "test", value: "value" }]),
231
+ };
232
+ }
233
+
234
+ function createKnownState(
235
+ sessionTxIdx: number | undefined,
236
+ ): CoValueKnownState {
237
+ const knownState = emptyKnownState(mockCoID);
238
+ knownState.header = true;
239
+ if (sessionTxIdx !== undefined) {
240
+ knownState.sessions[mockSessionID] = sessionTxIdx;
241
+ }
242
+ return knownState;
243
+ }
244
+
245
+ test("returns all transactions when we know none (ourKnownTxIdx = 0, theirFirstNewTxIdx = 0)", () => {
246
+ const transactions = [createTransaction(), createTransaction()];
247
+ const content: SessionNewContent = {
248
+ after: 0,
249
+ newTransactions: transactions,
250
+ lastSignature: "signature_z1234",
251
+ };
252
+ const knownState = createKnownState(undefined); // defaults to 0
253
+
254
+ const result = getNewTransactionsFromContentMessage(
255
+ content,
256
+ knownState,
257
+ mockSessionID,
258
+ );
259
+
260
+ expect(result).toEqual(transactions);
261
+ expect(result).toHaveLength(2);
262
+ });
263
+
264
+ test("returns subset of transactions when we know some (ourKnownTxIdx = 3, theirFirstNewTxIdx = 0)", () => {
265
+ const transactions = [
266
+ createTransaction(),
267
+ createTransaction(),
268
+ createTransaction(),
269
+ createTransaction(),
270
+ createTransaction(),
271
+ ];
272
+ const content: SessionNewContent = {
273
+ after: 0,
274
+ newTransactions: transactions,
275
+ lastSignature: "signature_z1234",
276
+ };
277
+ const knownState = createKnownState(3); // we already know txs 0, 1, 2
278
+
279
+ const result = getNewTransactionsFromContentMessage(
280
+ content,
281
+ knownState,
282
+ mockSessionID,
283
+ );
284
+
285
+ expect(result).toEqual(transactions.slice(3));
286
+ expect(result).toHaveLength(2);
287
+ });
288
+
289
+ test("returns undefined when we're missing transactions (ourKnownTxIdx = 2, theirFirstNewTxIdx = 5)", () => {
290
+ const transactions = [createTransaction(), createTransaction()];
291
+ const content: SessionNewContent = {
292
+ after: 5, // they're sending txs starting from idx 5
293
+ newTransactions: transactions,
294
+ lastSignature: "signature_z1234",
295
+ };
296
+ const knownState = createKnownState(2); // but we only know up to idx 2
297
+
298
+ const result = getNewTransactionsFromContentMessage(
299
+ content,
300
+ knownState,
301
+ mockSessionID,
302
+ );
303
+
304
+ expect(result).toBeUndefined();
305
+ });
306
+
307
+ test("returns empty array when we know all transactions (ourKnownTxIdx = 5, theirFirstNewTxIdx = 2)", () => {
308
+ const transactions = [
309
+ createTransaction(),
310
+ createTransaction(),
311
+ createTransaction(),
312
+ ];
313
+ const content: SessionNewContent = {
314
+ after: 2, // they're sending txs 2, 3, 4
315
+ newTransactions: transactions,
316
+ lastSignature: "signature_z1234",
317
+ };
318
+ const knownState = createKnownState(5); // we already know txs up to idx 5
319
+
320
+ const result = getNewTransactionsFromContentMessage(
321
+ content,
322
+ knownState,
323
+ mockSessionID,
324
+ );
325
+
326
+ expect(result).toEqual([]);
327
+ expect(result).toHaveLength(0);
328
+ });
329
+
330
+ test("returns all transactions when ourKnownTxIdx equals theirFirstNewTxIdx", () => {
331
+ const transactions = [createTransaction(), createTransaction()];
332
+ const content: SessionNewContent = {
333
+ after: 3,
334
+ newTransactions: transactions,
335
+ lastSignature: "signature_z1234",
336
+ };
337
+ const knownState = createKnownState(3); // we know up to idx 3
338
+
339
+ const result = getNewTransactionsFromContentMessage(
340
+ content,
341
+ knownState,
342
+ mockSessionID,
343
+ );
344
+
345
+ expect(result).toEqual(transactions);
346
+ expect(result).toHaveLength(2);
347
+ });
348
+
349
+ test("handles session not in knownState (defaults to 0)", () => {
350
+ const transactions = [createTransaction()];
351
+ const content: SessionNewContent = {
352
+ after: 1,
353
+ newTransactions: transactions,
354
+ lastSignature: "signature_z1234",
355
+ };
356
+ const knownState = emptyKnownState(mockCoID);
357
+ knownState.header = true;
358
+ // no sessions defined, so mockSessionID defaults to 0
359
+
360
+ const result = getNewTransactionsFromContentMessage(
361
+ content,
362
+ knownState,
363
+ mockSessionID,
364
+ );
365
+
366
+ // ourKnownTxIdx = 0, theirFirstNewTxIdx = 1, so 0 < 1 -> undefined
367
+ expect(result).toBeUndefined();
368
+ });
369
+
370
+ test("returns single transaction when offset is length - 1", () => {
371
+ const transactions = [
372
+ createTransaction(),
373
+ createTransaction(),
374
+ createTransaction(),
375
+ ];
376
+ const content: SessionNewContent = {
377
+ after: 5,
378
+ newTransactions: transactions,
379
+ lastSignature: "signature_z1234",
380
+ };
381
+ const knownState = createKnownState(7); // we know up to idx 7 (5 + 2 transactions)
382
+
383
+ const result = getNewTransactionsFromContentMessage(
384
+ content,
385
+ knownState,
386
+ mockSessionID,
387
+ );
388
+
389
+ expect(result).toEqual([transactions[2]]);
390
+ expect(result).toHaveLength(1);
391
+ });
392
+
393
+ test("handles empty newTransactions array", () => {
394
+ const content: SessionNewContent = {
395
+ after: 5,
396
+ newTransactions: [],
397
+ lastSignature: "signature_z1234",
398
+ };
399
+ const knownState = createKnownState(5);
400
+
401
+ const result = getNewTransactionsFromContentMessage(
402
+ content,
403
+ knownState,
404
+ mockSessionID,
405
+ );
406
+
407
+ expect(result).toEqual([]);
408
+ expect(result).toHaveLength(0);
409
+ });
410
+ });
@@ -78,14 +78,13 @@ test("transactions with wrong signature are rejected", () => {
78
78
 
79
79
  const newEntry = node.getCoValue(coValue.id);
80
80
 
81
- // eslint-disable-next-line neverthrow/must-use-result
82
- const result = newEntry.tryAddTransactions(
81
+ const error = newEntry.tryAddTransactions(
83
82
  node.currentSessionID,
84
83
  [transaction],
85
84
  signature,
86
85
  );
87
86
 
88
- expect(result.isErr()).toBe(true);
87
+ expect(Boolean(error)).toBe(true);
89
88
  expect(newEntry.getValidSortedTransactions().length).toBe(0);
90
89
  });
91
90
 
@@ -448,13 +447,11 @@ test("getValidTransactions should skip private transactions with invalid JSON",
448
447
  map.set("hello", "world");
449
448
 
450
449
  // This should fail silently, because the encryptedChanges will be outputted as gibberish
451
- map.core
452
- .tryAddTransactions(
453
- fixtures.session,
454
- [fixtures.transaction],
455
- fixtures.signature,
456
- )
457
- ._unsafeUnwrap();
450
+ map.core.tryAddTransactions(
451
+ fixtures.session,
452
+ [fixtures.transaction],
453
+ fixtures.signature,
454
+ );
458
455
 
459
456
  // Get valid transactions - should only include the valid one
460
457
  const validTransactions = map.core.getValidTransactions();