cojson 0.19.21 → 0.20.0
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 +67 -0
- package/dist/CojsonMessageChannel/CojsonMessageChannel.d.ts +42 -0
- package/dist/CojsonMessageChannel/CojsonMessageChannel.d.ts.map +1 -0
- package/dist/CojsonMessageChannel/CojsonMessageChannel.js +261 -0
- package/dist/CojsonMessageChannel/CojsonMessageChannel.js.map +1 -0
- package/dist/CojsonMessageChannel/MessagePortOutgoingChannel.d.ts +18 -0
- package/dist/CojsonMessageChannel/MessagePortOutgoingChannel.d.ts.map +1 -0
- package/dist/CojsonMessageChannel/MessagePortOutgoingChannel.js +37 -0
- package/dist/CojsonMessageChannel/MessagePortOutgoingChannel.js.map +1 -0
- package/dist/CojsonMessageChannel/index.d.ts +3 -0
- package/dist/CojsonMessageChannel/index.d.ts.map +1 -0
- package/dist/CojsonMessageChannel/index.js +2 -0
- package/dist/CojsonMessageChannel/index.js.map +1 -0
- package/dist/CojsonMessageChannel/types.d.ts +149 -0
- package/dist/CojsonMessageChannel/types.d.ts.map +1 -0
- package/dist/CojsonMessageChannel/types.js +36 -0
- package/dist/CojsonMessageChannel/types.js.map +1 -0
- package/dist/GarbageCollector.d.ts +4 -2
- package/dist/GarbageCollector.d.ts.map +1 -1
- package/dist/GarbageCollector.js +5 -3
- package/dist/GarbageCollector.js.map +1 -1
- package/dist/SyncStateManager.d.ts +3 -3
- package/dist/SyncStateManager.d.ts.map +1 -1
- package/dist/SyncStateManager.js +4 -4
- package/dist/SyncStateManager.js.map +1 -1
- package/dist/coValueContentMessage.d.ts +0 -2
- package/dist/coValueContentMessage.d.ts.map +1 -1
- package/dist/coValueContentMessage.js +0 -8
- package/dist/coValueContentMessage.js.map +1 -1
- package/dist/coValueCore/SessionMap.d.ts +4 -2
- package/dist/coValueCore/SessionMap.d.ts.map +1 -1
- package/dist/coValueCore/SessionMap.js +30 -0
- package/dist/coValueCore/SessionMap.js.map +1 -1
- package/dist/coValueCore/coValueCore.d.ts +86 -4
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +318 -17
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValueCore/verifiedState.d.ts +6 -1
- package/dist/coValueCore/verifiedState.d.ts.map +1 -1
- package/dist/coValueCore/verifiedState.js +9 -0
- package/dist/coValueCore/verifiedState.js.map +1 -1
- package/dist/coValues/coList.d.ts +3 -2
- package/dist/coValues/coList.d.ts.map +1 -1
- package/dist/coValues/coList.js.map +1 -1
- package/dist/coValues/group.d.ts.map +1 -1
- package/dist/coValues/group.js +3 -6
- package/dist/coValues/group.js.map +1 -1
- package/dist/config.d.ts +0 -6
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -8
- package/dist/config.js.map +1 -1
- package/dist/crypto/NapiCrypto.d.ts +1 -2
- package/dist/crypto/NapiCrypto.d.ts.map +1 -1
- package/dist/crypto/NapiCrypto.js +19 -4
- package/dist/crypto/NapiCrypto.js.map +1 -1
- package/dist/crypto/RNCrypto.d.ts.map +1 -1
- package/dist/crypto/RNCrypto.js +19 -4
- package/dist/crypto/RNCrypto.js.map +1 -1
- package/dist/crypto/WasmCrypto.d.ts +11 -4
- package/dist/crypto/WasmCrypto.d.ts.map +1 -1
- package/dist/crypto/WasmCrypto.js +52 -10
- package/dist/crypto/WasmCrypto.js.map +1 -1
- package/dist/crypto/WasmCryptoEdge.d.ts +1 -0
- package/dist/crypto/WasmCryptoEdge.d.ts.map +1 -1
- package/dist/crypto/WasmCryptoEdge.js +4 -1
- package/dist/crypto/WasmCryptoEdge.js.map +1 -1
- package/dist/crypto/crypto.d.ts +3 -3
- package/dist/crypto/crypto.d.ts.map +1 -1
- package/dist/crypto/crypto.js +6 -1
- package/dist/crypto/crypto.js.map +1 -1
- package/dist/exports.d.ts +3 -2
- package/dist/exports.d.ts.map +1 -1
- package/dist/exports.js +3 -1
- package/dist/exports.js.map +1 -1
- package/dist/ids.d.ts +4 -1
- package/dist/ids.d.ts.map +1 -1
- package/dist/ids.js +4 -0
- package/dist/ids.js.map +1 -1
- package/dist/knownState.d.ts +2 -0
- package/dist/knownState.d.ts.map +1 -1
- package/dist/localNode.d.ts +13 -3
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +17 -2
- package/dist/localNode.js.map +1 -1
- package/dist/platformUtils.d.ts +3 -0
- package/dist/platformUtils.d.ts.map +1 -0
- package/dist/platformUtils.js +24 -0
- package/dist/platformUtils.js.map +1 -0
- package/dist/storage/DeletedCoValuesEraserScheduler.d.ts +30 -0
- package/dist/storage/DeletedCoValuesEraserScheduler.d.ts.map +1 -0
- package/dist/storage/DeletedCoValuesEraserScheduler.js +84 -0
- package/dist/storage/DeletedCoValuesEraserScheduler.js.map +1 -0
- package/dist/storage/sqlite/client.d.ts +3 -0
- package/dist/storage/sqlite/client.d.ts.map +1 -1
- package/dist/storage/sqlite/client.js +44 -0
- package/dist/storage/sqlite/client.js.map +1 -1
- package/dist/storage/sqlite/sqliteMigrations.d.ts.map +1 -1
- package/dist/storage/sqlite/sqliteMigrations.js +7 -0
- package/dist/storage/sqlite/sqliteMigrations.js.map +1 -1
- package/dist/storage/sqliteAsync/client.d.ts +3 -0
- package/dist/storage/sqliteAsync/client.d.ts.map +1 -1
- package/dist/storage/sqliteAsync/client.js +42 -0
- package/dist/storage/sqliteAsync/client.js.map +1 -1
- package/dist/storage/storageAsync.d.ts +15 -3
- package/dist/storage/storageAsync.d.ts.map +1 -1
- package/dist/storage/storageAsync.js +60 -3
- package/dist/storage/storageAsync.js.map +1 -1
- package/dist/storage/storageSync.d.ts +14 -3
- package/dist/storage/storageSync.d.ts.map +1 -1
- package/dist/storage/storageSync.js +54 -3
- package/dist/storage/storageSync.js.map +1 -1
- package/dist/storage/types.d.ts +64 -0
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/storage/types.js +12 -1
- package/dist/storage/types.js.map +1 -1
- package/dist/sync.d.ts +6 -0
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +69 -15
- package/dist/sync.js.map +1 -1
- package/dist/tests/CojsonMessageChannel.test.d.ts +2 -0
- package/dist/tests/CojsonMessageChannel.test.d.ts.map +1 -0
- package/dist/tests/CojsonMessageChannel.test.js +236 -0
- package/dist/tests/CojsonMessageChannel.test.js.map +1 -0
- package/dist/tests/DeletedCoValuesEraserScheduler.test.d.ts +2 -0
- package/dist/tests/DeletedCoValuesEraserScheduler.test.d.ts.map +1 -0
- package/dist/tests/DeletedCoValuesEraserScheduler.test.js +149 -0
- package/dist/tests/DeletedCoValuesEraserScheduler.test.js.map +1 -0
- package/dist/tests/GarbageCollector.test.js +91 -18
- package/dist/tests/GarbageCollector.test.js.map +1 -1
- package/dist/tests/StorageApiAsync.test.js +510 -146
- package/dist/tests/StorageApiAsync.test.js.map +1 -1
- package/dist/tests/StorageApiSync.test.js +531 -130
- package/dist/tests/StorageApiSync.test.js.map +1 -1
- package/dist/tests/SyncManager.processQueues.test.js +1 -1
- package/dist/tests/SyncManager.processQueues.test.js.map +1 -1
- package/dist/tests/SyncStateManager.test.js +1 -1
- package/dist/tests/SyncStateManager.test.js.map +1 -1
- package/dist/tests/WasmCrypto.test.js +6 -3
- package/dist/tests/WasmCrypto.test.js.map +1 -1
- package/dist/tests/coPlainText.test.js +1 -1
- package/dist/tests/coPlainText.test.js.map +1 -1
- package/dist/tests/coValueCore.loadFromStorage.test.js +4 -0
- package/dist/tests/coValueCore.loadFromStorage.test.js.map +1 -1
- package/dist/tests/coValueCore.test.js +34 -13
- package/dist/tests/coValueCore.test.js.map +1 -1
- package/dist/tests/coreWasm.test.js +127 -4
- package/dist/tests/coreWasm.test.js.map +1 -1
- package/dist/tests/crypto.test.js +89 -93
- package/dist/tests/crypto.test.js.map +1 -1
- package/dist/tests/deleteCoValue.test.d.ts +2 -0
- package/dist/tests/deleteCoValue.test.d.ts.map +1 -0
- package/dist/tests/deleteCoValue.test.js +313 -0
- package/dist/tests/deleteCoValue.test.js.map +1 -0
- package/dist/tests/group.removeMember.test.js +18 -30
- package/dist/tests/group.removeMember.test.js.map +1 -1
- package/dist/tests/knownState.lazyLoading.test.js +4 -0
- package/dist/tests/knownState.lazyLoading.test.js.map +1 -1
- package/dist/tests/sync.deleted.test.d.ts +2 -0
- package/dist/tests/sync.deleted.test.d.ts.map +1 -0
- package/dist/tests/sync.deleted.test.js +214 -0
- package/dist/tests/sync.deleted.test.js.map +1 -0
- package/dist/tests/sync.garbageCollection.test.js +56 -32
- package/dist/tests/sync.garbageCollection.test.js.map +1 -1
- package/dist/tests/sync.load.test.js +3 -5
- package/dist/tests/sync.load.test.js.map +1 -1
- package/dist/tests/sync.mesh.test.js +4 -3
- package/dist/tests/sync.mesh.test.js.map +1 -1
- package/dist/tests/sync.peerReconciliation.test.js +3 -3
- package/dist/tests/sync.peerReconciliation.test.js.map +1 -1
- package/dist/tests/sync.storage.test.js +12 -11
- package/dist/tests/sync.storage.test.js.map +1 -1
- package/dist/tests/sync.storageAsync.test.js +7 -7
- package/dist/tests/sync.storageAsync.test.js.map +1 -1
- package/dist/tests/sync.test.js +3 -2
- package/dist/tests/sync.test.js.map +1 -1
- package/dist/tests/sync.tracking.test.js +35 -4
- package/dist/tests/sync.tracking.test.js.map +1 -1
- package/dist/tests/testStorage.d.ts +3 -0
- package/dist/tests/testStorage.d.ts.map +1 -1
- package/dist/tests/testStorage.js +16 -2
- package/dist/tests/testStorage.js.map +1 -1
- package/dist/tests/testUtils.d.ts +29 -4
- package/dist/tests/testUtils.d.ts.map +1 -1
- package/dist/tests/testUtils.js +84 -9
- package/dist/tests/testUtils.js.map +1 -1
- package/package.json +6 -16
- package/src/CojsonMessageChannel/CojsonMessageChannel.ts +332 -0
- package/src/CojsonMessageChannel/MessagePortOutgoingChannel.ts +52 -0
- package/src/CojsonMessageChannel/index.ts +9 -0
- package/src/CojsonMessageChannel/types.ts +200 -0
- package/src/GarbageCollector.ts +5 -5
- package/src/SyncStateManager.ts +6 -6
- package/src/coValueContentMessage.ts +0 -14
- package/src/coValueCore/SessionMap.ts +43 -1
- package/src/coValueCore/coValueCore.ts +430 -15
- package/src/coValueCore/verifiedState.ts +26 -3
- package/src/coValues/coList.ts +5 -3
- package/src/coValues/group.ts +5 -6
- package/src/config.ts +0 -9
- package/src/crypto/NapiCrypto.ts +29 -13
- package/src/crypto/RNCrypto.ts +29 -11
- package/src/crypto/WasmCrypto.ts +67 -20
- package/src/crypto/WasmCryptoEdge.ts +5 -1
- package/src/crypto/crypto.ts +16 -4
- package/src/exports.ts +3 -0
- package/src/ids.ts +11 -1
- package/src/localNode.ts +18 -5
- package/src/platformUtils.ts +26 -0
- package/src/storage/DeletedCoValuesEraserScheduler.ts +124 -0
- package/src/storage/sqlite/client.ts +77 -0
- package/src/storage/sqlite/sqliteMigrations.ts +7 -0
- package/src/storage/sqliteAsync/client.ts +75 -0
- package/src/storage/storageAsync.ts +77 -4
- package/src/storage/storageSync.ts +73 -4
- package/src/storage/types.ts +75 -0
- package/src/sync.ts +84 -15
- package/src/tests/CojsonMessageChannel.test.ts +306 -0
- package/src/tests/DeletedCoValuesEraserScheduler.test.ts +185 -0
- package/src/tests/GarbageCollector.test.ts +119 -22
- package/src/tests/StorageApiAsync.test.ts +615 -156
- package/src/tests/StorageApiSync.test.ts +623 -137
- package/src/tests/SyncManager.processQueues.test.ts +1 -1
- package/src/tests/SyncStateManager.test.ts +1 -1
- package/src/tests/WasmCrypto.test.ts +8 -3
- package/src/tests/coPlainText.test.ts +1 -1
- package/src/tests/coValueCore.loadFromStorage.test.ts +8 -0
- package/src/tests/coValueCore.test.ts +49 -14
- package/src/tests/coreWasm.test.ts +319 -10
- package/src/tests/crypto.test.ts +141 -150
- package/src/tests/deleteCoValue.test.ts +528 -0
- package/src/tests/group.removeMember.test.ts +35 -35
- package/src/tests/knownState.lazyLoading.test.ts +8 -0
- package/src/tests/sync.deleted.test.ts +294 -0
- package/src/tests/sync.garbageCollection.test.ts +69 -36
- package/src/tests/sync.load.test.ts +3 -5
- package/src/tests/sync.mesh.test.ts +6 -3
- package/src/tests/sync.peerReconciliation.test.ts +3 -3
- package/src/tests/sync.storage.test.ts +14 -11
- package/src/tests/sync.storageAsync.test.ts +7 -7
- package/src/tests/sync.test.ts +5 -2
- package/src/tests/sync.tracking.test.ts +54 -4
- package/src/tests/testStorage.ts +30 -3
- package/src/tests/testUtils.ts +113 -15
- package/dist/crypto/PureJSCrypto.d.ts +0 -77
- package/dist/crypto/PureJSCrypto.d.ts.map +0 -1
- package/dist/crypto/PureJSCrypto.js +0 -236
- package/dist/crypto/PureJSCrypto.js.map +0 -1
- package/dist/tests/PureJSCrypto.test.d.ts +0 -2
- package/dist/tests/PureJSCrypto.test.d.ts.map +0 -1
- package/dist/tests/PureJSCrypto.test.js +0 -145
- package/dist/tests/PureJSCrypto.test.js.map +0 -1
- package/src/crypto/PureJSCrypto.ts +0 -429
- package/src/tests/PureJSCrypto.test.ts +0 -217
|
@@ -46,7 +46,7 @@ describe("SyncStateManager", () => {
|
|
|
46
46
|
const newPeerState = client.node.syncManager.peers[peerState.id]!;
|
|
47
47
|
|
|
48
48
|
expect(updateSpy).toHaveBeenCalledWith(
|
|
49
|
-
peerState.id,
|
|
49
|
+
expect.objectContaining({ id: peerState.id }),
|
|
50
50
|
newPeerState.getKnownState(map.core.id)!,
|
|
51
51
|
{ uploaded: true },
|
|
52
52
|
);
|
|
@@ -5,8 +5,9 @@ import {
|
|
|
5
5
|
setupTestNode,
|
|
6
6
|
setupTestAccount,
|
|
7
7
|
} from "./testUtils";
|
|
8
|
-
import {
|
|
8
|
+
import { Stringified } from "../jsonStringify";
|
|
9
9
|
import { WasmCrypto } from "../crypto/WasmCrypto";
|
|
10
|
+
import { JsonValue } from "../jsonValue";
|
|
10
11
|
|
|
11
12
|
const wasmCrypto = await WasmCrypto.create();
|
|
12
13
|
setCurrentTestCryptoProvider(wasmCrypto);
|
|
@@ -109,7 +110,9 @@ describe("WasmCrypto", () => {
|
|
|
109
110
|
[
|
|
110
111
|
{
|
|
111
112
|
privacy: "trusting",
|
|
112
|
-
changes:
|
|
113
|
+
changes: JSON.stringify([
|
|
114
|
+
{ op: "set", key: "count", value: 1 },
|
|
115
|
+
]) as Stringified<JsonValue[]>,
|
|
113
116
|
madeAt: Date.now(),
|
|
114
117
|
},
|
|
115
118
|
],
|
|
@@ -203,7 +206,9 @@ describe("WasmCrypto", () => {
|
|
|
203
206
|
[
|
|
204
207
|
{
|
|
205
208
|
privacy: "trusting",
|
|
206
|
-
changes:
|
|
209
|
+
changes: JSON.stringify([
|
|
210
|
+
{ op: "set", key: "count", value: 1 },
|
|
211
|
+
]) as Stringified<JsonValue[]>,
|
|
207
212
|
madeAt: Date.now(),
|
|
208
213
|
},
|
|
209
214
|
],
|
|
@@ -45,10 +45,17 @@ function createMockStorage(
|
|
|
45
45
|
callback: (unsyncedCoValueIDs: RawCoID[]) => void,
|
|
46
46
|
) => void;
|
|
47
47
|
stopTrackingSyncState?: (id: RawCoID) => void;
|
|
48
|
+
onCoValueUnmounted?: (id: RawCoID) => void;
|
|
48
49
|
close?: () => Promise<unknown> | undefined;
|
|
50
|
+
markDeleteAsValid?: (id: RawCoID) => void;
|
|
51
|
+
enableDeletedCoValuesErasure?: () => void;
|
|
52
|
+
eraseAllDeletedCoValues?: () => Promise<void>;
|
|
49
53
|
} = {},
|
|
50
54
|
): StorageAPI {
|
|
51
55
|
return {
|
|
56
|
+
markDeleteAsValid: opts.markDeleteAsValid || vi.fn(),
|
|
57
|
+
enableDeletedCoValuesErasure: opts.enableDeletedCoValuesErasure || vi.fn(),
|
|
58
|
+
eraseAllDeletedCoValues: opts.eraseAllDeletedCoValues || vi.fn(),
|
|
52
59
|
load: opts.load || vi.fn(),
|
|
53
60
|
store: opts.store || vi.fn(),
|
|
54
61
|
getKnownState: opts.getKnownState || vi.fn(),
|
|
@@ -58,6 +65,7 @@ function createMockStorage(
|
|
|
58
65
|
trackCoValuesSyncState: opts.trackCoValuesSyncState || vi.fn(),
|
|
59
66
|
getUnsyncedCoValueIDs: opts.getUnsyncedCoValueIDs || vi.fn(),
|
|
60
67
|
stopTrackingSyncState: opts.stopTrackingSyncState || vi.fn(),
|
|
68
|
+
onCoValueUnmounted: opts.onCoValueUnmounted || vi.fn(),
|
|
61
69
|
close: opts.close || vi.fn().mockResolvedValue(undefined),
|
|
62
70
|
};
|
|
63
71
|
}
|
|
@@ -9,13 +9,14 @@ import {
|
|
|
9
9
|
} from "vitest";
|
|
10
10
|
import { CoValueCore, idforHeader } from "../coValueCore/coValueCore.js";
|
|
11
11
|
import { WasmCrypto } from "../crypto/WasmCrypto.js";
|
|
12
|
-
import {
|
|
12
|
+
import { Stringified } from "../jsonStringify.js";
|
|
13
13
|
import { LocalNode } from "../localNode.js";
|
|
14
14
|
import {
|
|
15
15
|
agentAndSessionIDFromSecret,
|
|
16
16
|
createTestMetricReader,
|
|
17
17
|
createTestNode,
|
|
18
18
|
createTwoConnectedNodes,
|
|
19
|
+
createUnloadedCoValue,
|
|
19
20
|
loadCoValueOrFail,
|
|
20
21
|
nodeWithRandomAgentAndSessionID,
|
|
21
22
|
randomAgentAndSessionID,
|
|
@@ -25,7 +26,7 @@ import {
|
|
|
25
26
|
waitFor,
|
|
26
27
|
} from "./testUtils.js";
|
|
27
28
|
import { CO_VALUE_PRIORITY } from "../priority.js";
|
|
28
|
-
import {
|
|
29
|
+
import { JsonValue } from "../jsonValue.js";
|
|
29
30
|
|
|
30
31
|
const Crypto = await WasmCrypto.create();
|
|
31
32
|
|
|
@@ -89,14 +90,6 @@ test("transactions with wrong signature are rejected", () => {
|
|
|
89
90
|
});
|
|
90
91
|
|
|
91
92
|
describe("transactions that exceed the byte size limit are rejected", () => {
|
|
92
|
-
beforeEach(() => {
|
|
93
|
-
setMaxTxSizeBytes(1 * 1024);
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
afterEach(() => {
|
|
97
|
-
setMaxTxSizeBytes(1 * 1024 * 1024);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
93
|
test("makeTransaction should throw error when transaction exceeds byte size limit", () => {
|
|
101
94
|
const [agent, sessionID] = randomAgentAndSessionID();
|
|
102
95
|
const node = new LocalNode(agent.agentSecret, sessionID, Crypto);
|
|
@@ -108,7 +101,7 @@ describe("transactions that exceed the byte size limit are rejected", () => {
|
|
|
108
101
|
...Crypto.createdNowUnique(),
|
|
109
102
|
});
|
|
110
103
|
|
|
111
|
-
const largeBinaryData = "x".repeat(1024 + 100);
|
|
104
|
+
const largeBinaryData = "x".repeat(1024 * 1024 + 100);
|
|
112
105
|
|
|
113
106
|
expect(() => {
|
|
114
107
|
coValue.makeTransaction(
|
|
@@ -119,7 +112,9 @@ describe("transactions that exceed the byte size limit are rejected", () => {
|
|
|
119
112
|
],
|
|
120
113
|
"trusting",
|
|
121
114
|
);
|
|
122
|
-
}).toThrow(
|
|
115
|
+
}).toThrow(
|
|
116
|
+
/Transaction too large to be synced: 1048689 bytes > 1048576 bytes limit/,
|
|
117
|
+
);
|
|
123
118
|
});
|
|
124
119
|
|
|
125
120
|
test("makeTransaction should work for transactions under byte size limit", () => {
|
|
@@ -357,7 +352,9 @@ test("changing parent and child group trigger only one invalidation on the local
|
|
|
357
352
|
test("correctly records transactions", async () => {
|
|
358
353
|
const node = nodeWithRandomAgentAndSessionID();
|
|
359
354
|
|
|
360
|
-
const changes1 =
|
|
355
|
+
const changes1 = JSON.stringify([{ hello: "world" }]) as Stringified<
|
|
356
|
+
JsonValue[]
|
|
357
|
+
>;
|
|
361
358
|
node.syncManager.recordTransactionsSize(
|
|
362
359
|
[
|
|
363
360
|
{
|
|
@@ -376,7 +373,7 @@ test("correctly records transactions", async () => {
|
|
|
376
373
|
expect(value.count).toBe(1);
|
|
377
374
|
expect(value.sum).toBe(changes1.length);
|
|
378
375
|
|
|
379
|
-
const changes2 =
|
|
376
|
+
const changes2 = JSON.stringify([{ foo: "bar" }]) as Stringified<JsonValue[]>;
|
|
380
377
|
node.syncManager.recordTransactionsSize(
|
|
381
378
|
[
|
|
382
379
|
{
|
|
@@ -906,3 +903,41 @@ test("knownState should return the same object until the CoValue is modified", (
|
|
|
906
903
|
expect(knownState6).not.toBe(knownState4);
|
|
907
904
|
expect(knownState6).not.toBe(knownState1);
|
|
908
905
|
});
|
|
906
|
+
|
|
907
|
+
describe("provideHeader uniqueness validation", () => {
|
|
908
|
+
test("should reject number uniqueness", () => {
|
|
909
|
+
const node = createTestNode();
|
|
910
|
+
const { coValue, header } = createUnloadedCoValue(node);
|
|
911
|
+
|
|
912
|
+
const invalidHeader = {
|
|
913
|
+
...header,
|
|
914
|
+
uniqueness: 1.5 as any, // non-integer
|
|
915
|
+
};
|
|
916
|
+
|
|
917
|
+
expect(coValue.provideHeader(invalidHeader)).toBe(false);
|
|
918
|
+
});
|
|
919
|
+
|
|
920
|
+
test("should reject array uniqueness", () => {
|
|
921
|
+
const node = createTestNode();
|
|
922
|
+
const { coValue, header } = createUnloadedCoValue(node);
|
|
923
|
+
|
|
924
|
+
const invalidHeader = {
|
|
925
|
+
...header,
|
|
926
|
+
uniqueness: [1, 2, 3] as any,
|
|
927
|
+
};
|
|
928
|
+
|
|
929
|
+
expect(coValue.provideHeader(invalidHeader)).toBe(false);
|
|
930
|
+
});
|
|
931
|
+
|
|
932
|
+
test("should reject object uniqueness with non-string values", () => {
|
|
933
|
+
const node = createTestNode();
|
|
934
|
+
const { coValue, header } = createUnloadedCoValue(node);
|
|
935
|
+
|
|
936
|
+
const invalidHeader = {
|
|
937
|
+
...header,
|
|
938
|
+
uniqueness: { key: 123 } as any,
|
|
939
|
+
};
|
|
940
|
+
|
|
941
|
+
expect(coValue.provideHeader(invalidHeader)).toBe(false);
|
|
942
|
+
});
|
|
943
|
+
});
|
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
import { assert, describe, expect, it } from "vitest";
|
|
2
2
|
import { WasmCrypto } from "../crypto/WasmCrypto";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
randomAgentAndSessionID,
|
|
7
|
-
} from "./testUtils";
|
|
8
|
-
import { PureJSCrypto } from "../crypto/PureJSCrypto";
|
|
9
|
-
import { Encrypted } from "../crypto/crypto";
|
|
10
|
-
import { PrivateTransaction } from "../coValueCore/verifiedState";
|
|
3
|
+
import { LocalNode } from "../exports";
|
|
4
|
+
import { agentAndSessionIDFromSecret } from "./testUtils";
|
|
5
|
+
import { Transaction } from "../coValueCore/verifiedState";
|
|
11
6
|
|
|
12
7
|
const wasmCrypto = await WasmCrypto.create();
|
|
13
|
-
const jsCrypto = await PureJSCrypto.create();
|
|
14
8
|
|
|
15
9
|
const agentSecret =
|
|
16
10
|
"sealerSecret_zE3Nr7YFr1KkVbJSx4JDCzYn4ApYdm8kJ5ghNBxREHQya/signerSecret_z9fEu4eNG1eXHMak3YSzY7uLdoG8HESSJ8YW4xWdNNDSP";
|
|
@@ -20,7 +14,7 @@ function createTestNode() {
|
|
|
20
14
|
return {
|
|
21
15
|
agent,
|
|
22
16
|
session,
|
|
23
|
-
node: new LocalNode(agent.agentSecret, session,
|
|
17
|
+
node: new LocalNode(agent.agentSecret, session, wasmCrypto),
|
|
24
18
|
};
|
|
25
19
|
}
|
|
26
20
|
|
|
@@ -140,4 +134,319 @@ describe("SessionLog WASM", () => {
|
|
|
140
134
|
|
|
141
135
|
expect(decrypted).toEqual(fixtures.decrypted);
|
|
142
136
|
});
|
|
137
|
+
|
|
138
|
+
function shuffleObjectKeys<T extends object>(obj: T): T {
|
|
139
|
+
const keys = Object.keys(obj);
|
|
140
|
+
// Fisher-Yates shuffle
|
|
141
|
+
for (let i = keys.length - 1; i > 0; i--) {
|
|
142
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
143
|
+
[keys[i], keys[j]] = [keys[j]!, keys[i]!];
|
|
144
|
+
}
|
|
145
|
+
const result = {} as T;
|
|
146
|
+
for (const key of keys) {
|
|
147
|
+
(result as any)[key] = (obj as any)[key];
|
|
148
|
+
}
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function shuffleTransactions(transactions: Transaction[]): Transaction[] {
|
|
153
|
+
return transactions.map((t) => shuffleObjectKeys(t) as Transaction);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
describe("Signature validation after shuffling transaction keys", () => {
|
|
157
|
+
it("trusting transactions with 100 k/v entries", () => {
|
|
158
|
+
const { agent, session, node } = createTestNode();
|
|
159
|
+
|
|
160
|
+
const group = node.createGroup();
|
|
161
|
+
const map = group.createMap();
|
|
162
|
+
|
|
163
|
+
// Create 100 trusting transactions with explicit test data
|
|
164
|
+
for (let i = 0; i < 100; i++) {
|
|
165
|
+
map.core.makeTransaction(
|
|
166
|
+
[{ op: "set", key: `key${i}`, value: `value${i}` }],
|
|
167
|
+
"trusting",
|
|
168
|
+
undefined,
|
|
169
|
+
i * 1000,
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const sessionContent =
|
|
174
|
+
map.core.newContentSince(undefined)?.[0]?.new[session];
|
|
175
|
+
assert(sessionContent);
|
|
176
|
+
expect(sessionContent.newTransactions.length).toBe(100);
|
|
177
|
+
|
|
178
|
+
const log = wasmCrypto.createSessionLog(
|
|
179
|
+
map.id,
|
|
180
|
+
session,
|
|
181
|
+
agent.currentSignerID(),
|
|
182
|
+
);
|
|
183
|
+
const logShuffled = wasmCrypto.createSessionLog(
|
|
184
|
+
map.id,
|
|
185
|
+
session,
|
|
186
|
+
agent.currentSignerID(),
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
const shuffledTransactions = shuffleTransactions(
|
|
190
|
+
sessionContent.newTransactions,
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
expect(() =>
|
|
194
|
+
log.tryAdd(
|
|
195
|
+
sessionContent.newTransactions,
|
|
196
|
+
sessionContent.lastSignature,
|
|
197
|
+
false,
|
|
198
|
+
),
|
|
199
|
+
).not.toThrow();
|
|
200
|
+
|
|
201
|
+
expect(() =>
|
|
202
|
+
logShuffled.tryAdd(
|
|
203
|
+
shuffledTransactions,
|
|
204
|
+
sessionContent.lastSignature,
|
|
205
|
+
false,
|
|
206
|
+
),
|
|
207
|
+
).not.toThrow();
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it("private transactions with 100 k/v entries", () => {
|
|
211
|
+
const { agent, session, node } = createTestNode();
|
|
212
|
+
|
|
213
|
+
const group = node.createGroup();
|
|
214
|
+
const map = group.createMap();
|
|
215
|
+
|
|
216
|
+
// Create 100 private transactions with explicit test data
|
|
217
|
+
for (let i = 0; i < 100; i++) {
|
|
218
|
+
map.core.makeTransaction(
|
|
219
|
+
[{ op: "set", key: `secretKey${i}`, value: `secretValue${i}` }],
|
|
220
|
+
"private",
|
|
221
|
+
undefined,
|
|
222
|
+
i * 1000,
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const sessionContent =
|
|
227
|
+
map.core.newContentSince(undefined)?.[0]?.new[session];
|
|
228
|
+
assert(sessionContent);
|
|
229
|
+
expect(sessionContent.newTransactions.length).toBe(100);
|
|
230
|
+
|
|
231
|
+
// Verify transactions are actually private (encrypted)
|
|
232
|
+
const firstTx = sessionContent.newTransactions[0];
|
|
233
|
+
assert(firstTx);
|
|
234
|
+
expect(firstTx.privacy).toBe("private");
|
|
235
|
+
expect("encryptedChanges" in firstTx).toBe(true);
|
|
236
|
+
|
|
237
|
+
const log = wasmCrypto.createSessionLog(
|
|
238
|
+
map.id,
|
|
239
|
+
session,
|
|
240
|
+
agent.currentSignerID(),
|
|
241
|
+
);
|
|
242
|
+
const logShuffled = wasmCrypto.createSessionLog(
|
|
243
|
+
map.id,
|
|
244
|
+
session,
|
|
245
|
+
agent.currentSignerID(),
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
const shuffledTransactions = shuffleTransactions(
|
|
249
|
+
sessionContent.newTransactions,
|
|
250
|
+
);
|
|
251
|
+
|
|
252
|
+
expect(() =>
|
|
253
|
+
log.tryAdd(
|
|
254
|
+
sessionContent.newTransactions,
|
|
255
|
+
sessionContent.lastSignature,
|
|
256
|
+
false,
|
|
257
|
+
),
|
|
258
|
+
).not.toThrow();
|
|
259
|
+
|
|
260
|
+
expect(() =>
|
|
261
|
+
logShuffled.tryAdd(
|
|
262
|
+
shuffledTransactions,
|
|
263
|
+
sessionContent.lastSignature,
|
|
264
|
+
false,
|
|
265
|
+
),
|
|
266
|
+
).not.toThrow();
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it("trusting transactions with metas", () => {
|
|
270
|
+
const { agent, session, node } = createTestNode();
|
|
271
|
+
|
|
272
|
+
const group = node.createGroup();
|
|
273
|
+
const map = group.createMap();
|
|
274
|
+
|
|
275
|
+
// Create transactions with metas
|
|
276
|
+
for (let i = 0; i < 50; i++) {
|
|
277
|
+
map.core.makeTransaction(
|
|
278
|
+
[{ op: "set", key: `key${i}`, value: `value${i}` }],
|
|
279
|
+
"trusting",
|
|
280
|
+
{ index: i, timestamp: i * 1000, nested: { data: `meta${i}` } },
|
|
281
|
+
i * 1000,
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const sessionContent =
|
|
286
|
+
map.core.newContentSince(undefined)?.[0]?.new[session];
|
|
287
|
+
assert(sessionContent);
|
|
288
|
+
expect(sessionContent.newTransactions.length).toBe(50);
|
|
289
|
+
|
|
290
|
+
// Verify metas are present
|
|
291
|
+
const firstTx = sessionContent.newTransactions[0];
|
|
292
|
+
assert(firstTx);
|
|
293
|
+
expect(firstTx.meta).toBeDefined();
|
|
294
|
+
|
|
295
|
+
const log = wasmCrypto.createSessionLog(
|
|
296
|
+
map.id,
|
|
297
|
+
session,
|
|
298
|
+
agent.currentSignerID(),
|
|
299
|
+
);
|
|
300
|
+
const logShuffled = wasmCrypto.createSessionLog(
|
|
301
|
+
map.id,
|
|
302
|
+
session,
|
|
303
|
+
agent.currentSignerID(),
|
|
304
|
+
);
|
|
305
|
+
|
|
306
|
+
const shuffledTransactions = shuffleTransactions(
|
|
307
|
+
sessionContent.newTransactions,
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
expect(() =>
|
|
311
|
+
log.tryAdd(
|
|
312
|
+
sessionContent.newTransactions,
|
|
313
|
+
sessionContent.lastSignature,
|
|
314
|
+
false,
|
|
315
|
+
),
|
|
316
|
+
).not.toThrow();
|
|
317
|
+
|
|
318
|
+
expect(() =>
|
|
319
|
+
logShuffled.tryAdd(
|
|
320
|
+
shuffledTransactions,
|
|
321
|
+
sessionContent.lastSignature,
|
|
322
|
+
false,
|
|
323
|
+
),
|
|
324
|
+
).not.toThrow();
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
it("private transactions with metas", () => {
|
|
328
|
+
const { agent, session, node } = createTestNode();
|
|
329
|
+
|
|
330
|
+
const group = node.createGroup();
|
|
331
|
+
const map = group.createMap();
|
|
332
|
+
|
|
333
|
+
// Create private transactions with encrypted metas
|
|
334
|
+
for (let i = 0; i < 50; i++) {
|
|
335
|
+
map.core.makeTransaction(
|
|
336
|
+
[{ op: "set", key: `secretKey${i}`, value: `secretValue${i}` }],
|
|
337
|
+
"private",
|
|
338
|
+
{ index: i, secret: `confidential${i}` },
|
|
339
|
+
i * 1000,
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const sessionContent =
|
|
344
|
+
map.core.newContentSince(undefined)?.[0]?.new[session];
|
|
345
|
+
assert(sessionContent);
|
|
346
|
+
expect(sessionContent.newTransactions.length).toBe(50);
|
|
347
|
+
|
|
348
|
+
// Verify transactions are private with encrypted metas
|
|
349
|
+
const firstTx = sessionContent.newTransactions[0];
|
|
350
|
+
assert(firstTx);
|
|
351
|
+
expect(firstTx.privacy).toBe("private");
|
|
352
|
+
expect("encryptedChanges" in firstTx).toBe(true);
|
|
353
|
+
expect(firstTx.meta).toBeDefined();
|
|
354
|
+
|
|
355
|
+
const log = wasmCrypto.createSessionLog(
|
|
356
|
+
map.id,
|
|
357
|
+
session,
|
|
358
|
+
agent.currentSignerID(),
|
|
359
|
+
);
|
|
360
|
+
const logShuffled = wasmCrypto.createSessionLog(
|
|
361
|
+
map.id,
|
|
362
|
+
session,
|
|
363
|
+
agent.currentSignerID(),
|
|
364
|
+
);
|
|
365
|
+
|
|
366
|
+
const shuffledTransactions = shuffleTransactions(
|
|
367
|
+
sessionContent.newTransactions,
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
expect(() =>
|
|
371
|
+
log.tryAdd(
|
|
372
|
+
sessionContent.newTransactions,
|
|
373
|
+
sessionContent.lastSignature,
|
|
374
|
+
false,
|
|
375
|
+
),
|
|
376
|
+
).not.toThrow();
|
|
377
|
+
|
|
378
|
+
expect(() =>
|
|
379
|
+
logShuffled.tryAdd(
|
|
380
|
+
shuffledTransactions,
|
|
381
|
+
sessionContent.lastSignature,
|
|
382
|
+
false,
|
|
383
|
+
),
|
|
384
|
+
).not.toThrow();
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
it("mixed trusting and private transactions across multiple sessions", () => {
|
|
388
|
+
const { agent, session, node } = createTestNode();
|
|
389
|
+
|
|
390
|
+
const group = node.createGroup();
|
|
391
|
+
const map = group.createMap();
|
|
392
|
+
|
|
393
|
+
// Create alternating trusting and private transactions
|
|
394
|
+
for (let i = 0; i < 50; i++) {
|
|
395
|
+
const privacy = i % 2 === 0 ? "trusting" : "private";
|
|
396
|
+
const hasMeta = i % 3 === 0;
|
|
397
|
+
map.core.makeTransaction(
|
|
398
|
+
[{ op: "set", key: `mixedKey${i}`, value: `mixedValue${i}` }],
|
|
399
|
+
privacy,
|
|
400
|
+
hasMeta ? { iteration: i, type: privacy } : undefined,
|
|
401
|
+
i * 1000,
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const sessionContent =
|
|
406
|
+
map.core.newContentSince(undefined)?.[0]?.new[session];
|
|
407
|
+
assert(sessionContent);
|
|
408
|
+
expect(sessionContent.newTransactions.length).toBe(50);
|
|
409
|
+
|
|
410
|
+
// Verify we have a mix of trusting and private transactions
|
|
411
|
+
const trustingCount = sessionContent.newTransactions.filter(
|
|
412
|
+
(t) => t.privacy === "trusting",
|
|
413
|
+
).length;
|
|
414
|
+
const privateCount = sessionContent.newTransactions.filter(
|
|
415
|
+
(t) => t.privacy === "private",
|
|
416
|
+
).length;
|
|
417
|
+
expect(trustingCount).toBe(25);
|
|
418
|
+
expect(privateCount).toBe(25);
|
|
419
|
+
|
|
420
|
+
const log = wasmCrypto.createSessionLog(
|
|
421
|
+
map.id,
|
|
422
|
+
session,
|
|
423
|
+
agent.currentSignerID(),
|
|
424
|
+
);
|
|
425
|
+
const logShuffled = wasmCrypto.createSessionLog(
|
|
426
|
+
map.id,
|
|
427
|
+
session,
|
|
428
|
+
agent.currentSignerID(),
|
|
429
|
+
);
|
|
430
|
+
|
|
431
|
+
const shuffledTransactions = shuffleTransactions(
|
|
432
|
+
sessionContent.newTransactions,
|
|
433
|
+
);
|
|
434
|
+
|
|
435
|
+
expect(() =>
|
|
436
|
+
log.tryAdd(
|
|
437
|
+
sessionContent.newTransactions,
|
|
438
|
+
sessionContent.lastSignature,
|
|
439
|
+
false,
|
|
440
|
+
),
|
|
441
|
+
).not.toThrow();
|
|
442
|
+
|
|
443
|
+
expect(() =>
|
|
444
|
+
logShuffled.tryAdd(
|
|
445
|
+
shuffledTransactions,
|
|
446
|
+
sessionContent.lastSignature,
|
|
447
|
+
false,
|
|
448
|
+
),
|
|
449
|
+
).not.toThrow();
|
|
450
|
+
});
|
|
451
|
+
});
|
|
143
452
|
});
|