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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +8 -0
- package/dist/coValueContentMessage.d.ts +5 -2
- package/dist/coValueContentMessage.d.ts.map +1 -1
- package/dist/coValueContentMessage.js +15 -0
- package/dist/coValueContentMessage.js.map +1 -1
- package/dist/coValueCore/SessionMap.d.ts +4 -3
- package/dist/coValueCore/SessionMap.d.ts.map +1 -1
- package/dist/coValueCore/SessionMap.js +12 -15
- package/dist/coValueCore/SessionMap.js.map +1 -1
- package/dist/coValueCore/coValueCore.d.ts +14 -6
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +29 -48
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValueCore/verifiedState.d.ts +3 -3
- package/dist/coValueCore/verifiedState.d.ts.map +1 -1
- package/dist/coValueCore/verifiedState.js +18 -10
- package/dist/coValueCore/verifiedState.js.map +1 -1
- package/dist/coValues/group.d.ts.map +1 -1
- package/dist/coValues/group.js +20 -15
- package/dist/coValues/group.js.map +1 -1
- package/dist/knownState.d.ts.map +1 -1
- package/dist/knownState.js.map +1 -1
- package/dist/localNode.d.ts +7 -2
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +8 -14
- package/dist/localNode.js.map +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +15 -18
- package/dist/sync.js.map +1 -1
- package/dist/tests/coValueContentMessage.test.js +130 -1
- package/dist/tests/coValueContentMessage.test.js.map +1 -1
- package/dist/tests/coValueCore.test.js +3 -6
- package/dist/tests/coValueCore.test.js.map +1 -1
- package/package.json +3 -4
- package/src/coValueContentMessage.ts +29 -2
- package/src/coValueCore/SessionMap.ts +23 -16
- package/src/coValueCore/coValueCore.ts +37 -63
- package/src/coValueCore/verifiedState.ts +25 -15
- package/src/coValues/group.ts +40 -27
- package/src/knownState.ts +3 -12
- package/src/localNode.ts +10 -18
- package/src/sync.ts +24 -25
- package/src/tests/coValueContentMessage.test.ts +197 -2
- package/src/tests/coValueCore.test.ts +7 -10
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { describe, expect, test } from "vitest";
|
|
2
|
-
import {
|
|
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
|
-
|
|
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(
|
|
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
|
-
.
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
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();
|