cojson 0.20.7 → 0.20.8
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 +18 -0
- package/dist/SyncStateManager.d.ts.map +1 -1
- package/dist/SyncStateManager.js +0 -2
- package/dist/SyncStateManager.js.map +1 -1
- package/dist/base64url.d.ts +15 -0
- package/dist/base64url.d.ts.map +1 -1
- package/dist/base64url.js +101 -5
- package/dist/base64url.js.map +1 -1
- package/dist/base64url.test.js +76 -1
- package/dist/base64url.test.js.map +1 -1
- package/dist/coValue.d.ts +2 -1
- package/dist/coValue.d.ts.map +1 -1
- package/dist/coValue.js.map +1 -1
- package/dist/coValueCore/coValueCore.d.ts +9 -11
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +92 -65
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValueCore/verifiedState.d.ts +38 -7
- package/dist/coValueCore/verifiedState.d.ts.map +1 -1
- package/dist/coValueCore/verifiedState.js +226 -30
- package/dist/coValueCore/verifiedState.js.map +1 -1
- package/dist/coValues/binaryCoStream.d.ts +63 -0
- package/dist/coValues/binaryCoStream.d.ts.map +1 -0
- package/dist/coValues/binaryCoStream.js +125 -0
- package/dist/coValues/binaryCoStream.js.map +1 -0
- package/dist/coValues/coList.d.ts +3 -1
- package/dist/coValues/coList.d.ts.map +1 -1
- package/dist/coValues/coList.js +15 -6
- package/dist/coValues/coList.js.map +1 -1
- package/dist/coValues/coMap.d.ts +1 -1
- package/dist/coValues/coMap.d.ts.map +1 -1
- package/dist/coValues/coMap.js +2 -2
- package/dist/coValues/coMap.js.map +1 -1
- package/dist/coValues/coStream.d.ts +0 -38
- package/dist/coValues/coStream.d.ts.map +1 -1
- package/dist/coValues/coStream.js +0 -86
- package/dist/coValues/coStream.js.map +1 -1
- package/dist/coValues/group.d.ts +44 -6
- package/dist/coValues/group.d.ts.map +1 -1
- package/dist/coValues/group.js +198 -17
- package/dist/coValues/group.js.map +1 -1
- package/dist/coreToCoValue.d.ts +2 -1
- package/dist/coreToCoValue.d.ts.map +1 -1
- package/dist/coreToCoValue.js +2 -1
- package/dist/coreToCoValue.js.map +1 -1
- package/dist/crypto/NapiCrypto.d.ts +18 -24
- package/dist/crypto/NapiCrypto.d.ts.map +1 -1
- package/dist/crypto/NapiCrypto.js +98 -60
- package/dist/crypto/NapiCrypto.js.map +1 -1
- package/dist/crypto/RNCrypto.d.ts +16 -3
- package/dist/crypto/RNCrypto.d.ts.map +1 -1
- package/dist/crypto/RNCrypto.js +117 -54
- package/dist/crypto/RNCrypto.js.map +1 -1
- package/dist/crypto/WasmCrypto.d.ts +18 -24
- package/dist/crypto/WasmCrypto.d.ts.map +1 -1
- package/dist/crypto/WasmCrypto.js +100 -61
- package/dist/crypto/WasmCrypto.js.map +1 -1
- package/dist/crypto/crypto.d.ts +55 -19
- package/dist/crypto/crypto.d.ts.map +1 -1
- package/dist/crypto/crypto.js +14 -3
- package/dist/crypto/crypto.js.map +1 -1
- package/dist/exports.d.ts +7 -3
- package/dist/exports.d.ts.map +1 -1
- package/dist/exports.js +4 -2
- package/dist/exports.js.map +1 -1
- package/dist/localNode.d.ts +3 -1
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +10 -3
- package/dist/localNode.js.map +1 -1
- package/dist/media.d.ts +1 -1
- package/dist/media.d.ts.map +1 -1
- package/dist/permissions.d.ts +2 -1
- package/dist/permissions.d.ts.map +1 -1
- package/dist/permissions.js +19 -3
- package/dist/permissions.js.map +1 -1
- package/dist/storage/sqliteAsync/client.d.ts +24 -12
- package/dist/storage/sqliteAsync/client.d.ts.map +1 -1
- package/dist/storage/sqliteAsync/client.js +70 -58
- package/dist/storage/sqliteAsync/client.js.map +1 -1
- package/dist/storage/sqliteAsync/types.d.ts +1 -1
- package/dist/storage/sqliteAsync/types.d.ts.map +1 -1
- package/dist/storage/types.d.ts +1 -0
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +7 -1
- package/dist/sync.js.map +1 -1
- package/dist/tests/CojsonMessageChannel.test.js +2 -2
- package/dist/tests/SQLiteClientAsync.test.d.ts +2 -0
- package/dist/tests/SQLiteClientAsync.test.d.ts.map +1 -0
- package/dist/tests/SQLiteClientAsync.test.js +64 -0
- package/dist/tests/SQLiteClientAsync.test.js.map +1 -0
- package/dist/tests/StorageApiAsync.test.js +2 -8
- package/dist/tests/StorageApiAsync.test.js.map +1 -1
- package/dist/tests/SyncStateManager.test.js +2 -2
- package/dist/tests/WasmCrypto.test.js +1 -15
- package/dist/tests/WasmCrypto.test.js.map +1 -1
- package/dist/tests/coList.test.js +24 -5
- package/dist/tests/coList.test.js.map +1 -1
- package/dist/tests/coStream.test.js +4 -3
- package/dist/tests/coStream.test.js.map +1 -1
- package/dist/tests/coValueCore.initTransaction.test.d.ts +2 -0
- package/dist/tests/coValueCore.initTransaction.test.d.ts.map +1 -0
- package/dist/tests/coValueCore.initTransaction.test.js +438 -0
- package/dist/tests/coValueCore.initTransaction.test.js.map +1 -0
- package/dist/tests/coValueCore.test.js +11 -19
- package/dist/tests/coValueCore.test.js.map +1 -1
- package/dist/tests/crypto.test.js +83 -0
- package/dist/tests/crypto.test.js.map +1 -1
- package/dist/tests/deleteCoValue.test.js +5 -5
- package/dist/tests/deleteCoValue.test.js.map +1 -1
- package/dist/tests/group.inheritance.test.js +11 -0
- package/dist/tests/group.inheritance.test.js.map +1 -1
- package/dist/tests/group.test.js +24 -1
- package/dist/tests/group.test.js.map +1 -1
- package/dist/tests/groupSealer.test.d.ts +2 -0
- package/dist/tests/groupSealer.test.d.ts.map +1 -0
- package/dist/tests/groupSealer.test.js +913 -0
- package/dist/tests/groupSealer.test.js.map +1 -0
- package/dist/tests/setup.js +5 -0
- package/dist/tests/setup.js.map +1 -1
- package/dist/tests/sync.auth.test.js +10 -10
- package/dist/tests/sync.concurrentLoad.test.js +12 -12
- package/dist/tests/sync.deleted.test.js +8 -8
- package/dist/tests/sync.garbageCollection.test.js +10 -10
- package/dist/tests/sync.invite.test.js +12 -12
- package/dist/tests/sync.known.test.js +2 -2
- package/dist/tests/sync.load.test.js +107 -107
- package/dist/tests/sync.mesh.test.js +164 -46
- package/dist/tests/sync.mesh.test.js.map +1 -1
- package/dist/tests/sync.multipleServers.test.js +43 -43
- package/dist/tests/sync.peerReconciliation.test.js +29 -29
- package/dist/tests/sync.sharding.test.js +3 -3
- package/dist/tests/sync.storage.test.js +104 -104
- package/dist/tests/sync.storage.test.js.map +1 -1
- package/dist/tests/sync.storageAsync.test.js +56 -56
- package/dist/tests/sync.upload.test.js +22 -22
- package/dist/tests/testStorage.d.ts +2 -0
- package/dist/tests/testStorage.d.ts.map +1 -1
- package/dist/tests/testStorage.js +30 -6
- package/dist/tests/testStorage.js.map +1 -1
- package/dist/typeUtils/isCoValue.js +1 -1
- package/dist/typeUtils/isCoValue.js.map +1 -1
- package/package.json +4 -4
- package/src/SyncStateManager.ts +0 -2
- package/src/base64url.test.ts +89 -1
- package/src/base64url.ts +134 -6
- package/src/coValue.ts +2 -1
- package/src/coValueCore/coValueCore.ts +126 -84
- package/src/coValueCore/verifiedState.ts +335 -53
- package/src/coValues/binaryCoStream.ts +217 -0
- package/src/coValues/coList.ts +21 -8
- package/src/coValues/coMap.ts +3 -0
- package/src/coValues/coStream.ts +0 -170
- package/src/coValues/group.ts +270 -21
- package/src/coreToCoValue.ts +2 -1
- package/src/crypto/NapiCrypto.ts +198 -95
- package/src/crypto/RNCrypto.ts +229 -102
- package/src/crypto/WasmCrypto.ts +201 -95
- package/src/crypto/crypto.ts +118 -45
- package/src/exports.ts +11 -5
- package/src/localNode.ts +17 -1
- package/src/media.ts +1 -1
- package/src/permissions.ts +30 -7
- package/src/storage/sqliteAsync/client.ts +136 -115
- package/src/storage/sqliteAsync/types.ts +3 -1
- package/src/storage/types.ts +4 -0
- package/src/sync.ts +10 -1
- package/src/tests/CojsonMessageChannel.test.ts +2 -2
- package/src/tests/SQLiteClientAsync.test.ts +75 -0
- package/src/tests/StorageApiAsync.test.ts +4 -9
- package/src/tests/SyncStateManager.test.ts +2 -2
- package/src/tests/WasmCrypto.test.ts +1 -25
- package/src/tests/coList.test.ts +39 -5
- package/src/tests/coStream.test.ts +4 -5
- package/src/tests/coValueCore.initTransaction.test.ts +836 -0
- package/src/tests/coValueCore.test.ts +11 -22
- package/src/tests/crypto.test.ts +107 -0
- package/src/tests/deleteCoValue.test.ts +5 -5
- package/src/tests/group.inheritance.test.ts +16 -0
- package/src/tests/group.test.ts +29 -1
- package/src/tests/groupSealer.test.ts +1473 -0
- package/src/tests/setup.ts +6 -0
- package/src/tests/sync.auth.test.ts +10 -10
- package/src/tests/sync.concurrentLoad.test.ts +12 -12
- package/src/tests/sync.deleted.test.ts +8 -8
- package/src/tests/sync.garbageCollection.test.ts +10 -10
- package/src/tests/sync.invite.test.ts +12 -12
- package/src/tests/sync.known.test.ts +2 -2
- package/src/tests/sync.load.test.ts +107 -107
- package/src/tests/sync.mesh.test.ts +189 -46
- package/src/tests/sync.multipleServers.test.ts +43 -43
- package/src/tests/sync.peerReconciliation.test.ts +29 -29
- package/src/tests/sync.sharding.test.ts +3 -3
- package/src/tests/sync.storage.test.ts +104 -104
- package/src/tests/sync.storageAsync.test.ts +56 -56
- package/src/tests/sync.upload.test.ts +22 -22
- package/src/tests/testStorage.ts +39 -9
- package/src/typeUtils/isCoValue.ts +1 -1
- package/dist/coValueCore/SessionMap.d.ts +0 -55
- package/dist/coValueCore/SessionMap.d.ts.map +0 -1
- package/dist/coValueCore/SessionMap.js +0 -206
- package/dist/coValueCore/SessionMap.js.map +0 -1
- package/dist/tests/coreWasm.test.d.ts +0 -2
- package/dist/tests/coreWasm.test.d.ts.map +0 -1
- package/dist/tests/coreWasm.test.js +0 -203
- package/dist/tests/coreWasm.test.js.map +0 -1
- package/src/coValueCore/SessionMap.ts +0 -394
- package/src/tests/coreWasm.test.ts +0 -452
|
@@ -403,7 +403,8 @@ test("(smoke test) records transactions from local node", async () => {
|
|
|
403
403
|
});
|
|
404
404
|
|
|
405
405
|
assert(typeof value !== "number" && !!value?.count);
|
|
406
|
-
|
|
406
|
+
// Creating a group now creates 4 transactions: admin member, key revelation, readKey, and groupSealer
|
|
407
|
+
expect(value.count).toBe(4);
|
|
407
408
|
});
|
|
408
409
|
|
|
409
410
|
test("creating a coValue with a group should't trigger automatically a content creation (performance)", () => {
|
|
@@ -866,42 +867,30 @@ describe("markErrored and isErroredInPeer", () => {
|
|
|
866
867
|
});
|
|
867
868
|
});
|
|
868
869
|
|
|
869
|
-
test("knownState should
|
|
870
|
+
test("knownState should reflect modifications", () => {
|
|
870
871
|
const [agent, sessionID] = randomAgentAndSessionID();
|
|
871
872
|
const node = new LocalNode(agent.agentSecret, sessionID, Crypto);
|
|
872
873
|
|
|
873
874
|
const group = node.createGroup();
|
|
874
875
|
const map = group.createMap();
|
|
875
876
|
|
|
876
|
-
// Get the knownState
|
|
877
|
+
// Get the knownState before any modification
|
|
877
878
|
const knownState1 = map.core.knownState();
|
|
878
879
|
|
|
879
|
-
// Get the knownState again - should be the same object
|
|
880
|
-
const knownState2 = map.core.knownState();
|
|
881
|
-
expect(knownState2).toBe(knownState1);
|
|
882
|
-
|
|
883
|
-
// Call it multiple times to ensure it's always the same object
|
|
884
|
-
const knownState3 = map.core.knownState();
|
|
885
|
-
expect(knownState3).toBe(knownState1);
|
|
886
|
-
|
|
887
880
|
// Now modify the CoValue by making a transaction
|
|
888
881
|
map.set("hello", "world");
|
|
889
882
|
|
|
890
|
-
// Get the knownState after modification - should
|
|
891
|
-
const
|
|
892
|
-
expect(
|
|
893
|
-
|
|
894
|
-
// Verify that subsequent calls still return the same (new) object
|
|
895
|
-
const knownState5 = map.core.knownState();
|
|
896
|
-
expect(knownState5).toBe(knownState4);
|
|
883
|
+
// Get the knownState after modification - should have updated sessions
|
|
884
|
+
const knownState2 = map.core.knownState();
|
|
885
|
+
expect(knownState2).not.toEqual(knownState1);
|
|
897
886
|
|
|
898
887
|
// Make another modification
|
|
899
888
|
map.set("foo", "bar");
|
|
900
889
|
|
|
901
|
-
// Get the knownState after second modification - should
|
|
902
|
-
const
|
|
903
|
-
expect(
|
|
904
|
-
expect(
|
|
890
|
+
// Get the knownState after second modification - should have updated sessions again
|
|
891
|
+
const knownState3 = map.core.knownState();
|
|
892
|
+
expect(knownState3).not.toEqual(knownState2);
|
|
893
|
+
expect(knownState3).not.toEqual(knownState1);
|
|
905
894
|
});
|
|
906
895
|
|
|
907
896
|
describe("provideHeader uniqueness validation", () => {
|
package/src/tests/crypto.test.ts
CHANGED
|
@@ -3,9 +3,11 @@ import { x25519 } from "@noble/curves/ed25519";
|
|
|
3
3
|
import { blake3 } from "@noble/hashes/blake3";
|
|
4
4
|
import { base58, base64url } from "@scure/base";
|
|
5
5
|
import { expect, test, vi } from "vitest";
|
|
6
|
+
import { shortHashLength } from "../crypto/crypto.js";
|
|
6
7
|
import { WasmCrypto } from "../crypto/WasmCrypto.js";
|
|
7
8
|
import { SessionID } from "../ids.js";
|
|
8
9
|
import { stableStringify } from "../jsonStringify.js";
|
|
10
|
+
import { JsonValue } from "../jsonValue.js";
|
|
9
11
|
|
|
10
12
|
const crypto = await WasmCrypto.create();
|
|
11
13
|
|
|
@@ -167,3 +169,108 @@ test(`Unsealing malformed JSON logs error [${name}]`, () => {
|
|
|
167
169
|
"Failed to decrypt/parse sealed message",
|
|
168
170
|
);
|
|
169
171
|
});
|
|
172
|
+
|
|
173
|
+
// ============================================================================
|
|
174
|
+
// shortHash implementation consistency tests
|
|
175
|
+
// ============================================================================
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Compute shortHash using the base TypeScript implementation (reference).
|
|
179
|
+
* This mirrors the CryptoProvider.shortHash method exactly.
|
|
180
|
+
*/
|
|
181
|
+
function referenceShortHash(value: JsonValue): string {
|
|
182
|
+
const textEncoder = new TextEncoder();
|
|
183
|
+
return `shortHash_z${base58.encode(
|
|
184
|
+
blake3(textEncoder.encode(stableStringify(value))).slice(
|
|
185
|
+
0,
|
|
186
|
+
shortHashLength,
|
|
187
|
+
),
|
|
188
|
+
)}`;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
test(`shortHash WASM implementation matches TypeScript reference [${name}]`, () => {
|
|
192
|
+
// Test with simple object
|
|
193
|
+
const simpleObj = { hello: "world" };
|
|
194
|
+
expect(crypto.shortHash(simpleObj)).toBe(referenceShortHash(simpleObj));
|
|
195
|
+
|
|
196
|
+
// Test with object where key order differs (should produce same hash due to stableStringify)
|
|
197
|
+
const objA = { b: "world", a: "hello" };
|
|
198
|
+
const objB = { a: "hello", b: "world" };
|
|
199
|
+
expect(crypto.shortHash(objA)).toBe(referenceShortHash(objA));
|
|
200
|
+
expect(crypto.shortHash(objB)).toBe(referenceShortHash(objB));
|
|
201
|
+
expect(crypto.shortHash(objA)).toBe(crypto.shortHash(objB));
|
|
202
|
+
|
|
203
|
+
// Test with nested objects
|
|
204
|
+
const nestedObj = { outer: { inner: { deep: "value" } }, top: 123 };
|
|
205
|
+
expect(crypto.shortHash(nestedObj)).toBe(referenceShortHash(nestedObj));
|
|
206
|
+
|
|
207
|
+
// Test with arrays
|
|
208
|
+
const arrayValue = [1, 2, 3, "four", { five: 5 }];
|
|
209
|
+
expect(crypto.shortHash(arrayValue)).toBe(referenceShortHash(arrayValue));
|
|
210
|
+
|
|
211
|
+
// Test with primitives
|
|
212
|
+
expect(crypto.shortHash("string")).toBe(referenceShortHash("string"));
|
|
213
|
+
expect(crypto.shortHash(42)).toBe(referenceShortHash(42));
|
|
214
|
+
expect(crypto.shortHash(true)).toBe(referenceShortHash(true));
|
|
215
|
+
expect(crypto.shortHash(null)).toBe(referenceShortHash(null));
|
|
216
|
+
|
|
217
|
+
// Test with empty structures
|
|
218
|
+
expect(crypto.shortHash({})).toBe(referenceShortHash({}));
|
|
219
|
+
expect(crypto.shortHash([])).toBe(referenceShortHash([]));
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
test(`shortHash produces correct format [${name}]`, () => {
|
|
223
|
+
const value = { test: "data" };
|
|
224
|
+
const hash = crypto.shortHash(value);
|
|
225
|
+
|
|
226
|
+
// Should start with "shortHash_z" prefix
|
|
227
|
+
expect(hash).toMatch(/^shortHash_z/);
|
|
228
|
+
|
|
229
|
+
// The base58 encoded part should be reasonable length (19 bytes base58 encoded)
|
|
230
|
+
const base58Part = hash.substring("shortHash_z".length);
|
|
231
|
+
expect(base58Part.length).toBeGreaterThan(0);
|
|
232
|
+
|
|
233
|
+
// Should only contain valid base58 characters
|
|
234
|
+
expect(base58Part).toMatch(
|
|
235
|
+
/^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+$/,
|
|
236
|
+
);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
test(`shortHash with complex nested structure matches reference [${name}]`, () => {
|
|
240
|
+
const complexValue = {
|
|
241
|
+
users: [
|
|
242
|
+
{ id: 1, name: "Alice", active: true },
|
|
243
|
+
{ id: 2, name: "Bob", active: false },
|
|
244
|
+
],
|
|
245
|
+
metadata: {
|
|
246
|
+
created: 1234567890,
|
|
247
|
+
tags: ["important", "test"],
|
|
248
|
+
config: {
|
|
249
|
+
nested: {
|
|
250
|
+
deeply: {
|
|
251
|
+
value: "found",
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
nullField: null,
|
|
257
|
+
emptyArray: [],
|
|
258
|
+
emptyObject: {},
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
expect(crypto.shortHash(complexValue)).toBe(referenceShortHash(complexValue));
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
test(`shortHash with special characters matches reference [${name}]`, () => {
|
|
265
|
+
// Test with unicode
|
|
266
|
+
const unicodeValue = { emoji: "🎉", chinese: "你好", arabic: "مرحبا" };
|
|
267
|
+
expect(crypto.shortHash(unicodeValue)).toBe(referenceShortHash(unicodeValue));
|
|
268
|
+
|
|
269
|
+
// Test with escape sequences
|
|
270
|
+
const escapeValue = {
|
|
271
|
+
quote: 'has "quotes"',
|
|
272
|
+
newline: "has\nnewline",
|
|
273
|
+
tab: "has\ttab",
|
|
274
|
+
};
|
|
275
|
+
expect(crypto.shortHash(escapeValue)).toBe(referenceShortHash(escapeValue));
|
|
276
|
+
});
|
|
@@ -22,7 +22,7 @@ function makeDeleteMarkerTransaction(core: CoValueCore, madeAt?: number) {
|
|
|
22
22
|
(sessionID) => isDeleteSessionID(sessionID as SessionID),
|
|
23
23
|
) as SessionID;
|
|
24
24
|
assert(deleteSessionID);
|
|
25
|
-
const log = core.verified?.
|
|
25
|
+
const log = core.verified?.getSession(deleteSessionID);
|
|
26
26
|
assert(log?.lastSignature);
|
|
27
27
|
const tx = log.transactions.at(-1);
|
|
28
28
|
assert(tx);
|
|
@@ -123,7 +123,7 @@ test("rejects delete marker ingestion from non-admin (ownedByGroup, skipVerify=f
|
|
|
123
123
|
reason: "NotAdmin",
|
|
124
124
|
});
|
|
125
125
|
expect(map.core.isDeleted).toBe(false);
|
|
126
|
-
expect(map.core.verified?.
|
|
126
|
+
expect(map.core.verified?.getSession(deleteSessionID)).toBeUndefined();
|
|
127
127
|
});
|
|
128
128
|
|
|
129
129
|
test("accepts delete marker ingestion from admin (ownedByGroup, skipVerify=false) and marks deleted", async () => {
|
|
@@ -187,7 +187,7 @@ test("rejects delete session ingestion when attempting to append a second transa
|
|
|
187
187
|
expect(first).toBeUndefined();
|
|
188
188
|
expect(mapOnBob.core.isDeleted).toBe(true);
|
|
189
189
|
expect(
|
|
190
|
-
mapOnBob.core.verified?.
|
|
190
|
+
mapOnBob.core.verified?.getSession(deleteSessionID)?.transactions,
|
|
191
191
|
).toHaveLength(1);
|
|
192
192
|
|
|
193
193
|
const second = mapOnBob.core.tryAddTransactions(
|
|
@@ -210,7 +210,7 @@ test("rejects delete session ingestion when attempting to append a second transa
|
|
|
210
210
|
);
|
|
211
211
|
}
|
|
212
212
|
expect(
|
|
213
|
-
mapOnBob.core.verified?.
|
|
213
|
+
mapOnBob.core.verified?.getSession(deleteSessionID)?.transactions,
|
|
214
214
|
).toHaveLength(1);
|
|
215
215
|
});
|
|
216
216
|
|
|
@@ -253,7 +253,7 @@ test("rejects delete session ingestion when attempting to add multiple delete tr
|
|
|
253
253
|
/Delete transaction must be the only transaction in the session/,
|
|
254
254
|
);
|
|
255
255
|
}
|
|
256
|
-
expect(mapOnBob.core.verified?.
|
|
256
|
+
expect(mapOnBob.core.verified?.getSession(deleteSessionID)).toBeUndefined();
|
|
257
257
|
});
|
|
258
258
|
|
|
259
259
|
test("skipVerify=true ingestion marks deleted even for non-admin delete marker", async () => {
|
|
@@ -468,6 +468,9 @@ describe("extend", () => {
|
|
|
468
468
|
const childGroup = node1.node.createGroup();
|
|
469
469
|
childGroup.extend(parentGroup, "admin");
|
|
470
470
|
|
|
471
|
+
// Wait for childGroup to sync so node3 sees the groupSealer field
|
|
472
|
+
await childGroup.core.waitForSync();
|
|
473
|
+
|
|
471
474
|
const sharedGroup = node3.node.createGroup();
|
|
472
475
|
|
|
473
476
|
// Account3 does not have permissions over the childGroup being extended
|
|
@@ -485,6 +488,9 @@ describe("extend", () => {
|
|
|
485
488
|
const testMap = sharedGroup.createMap();
|
|
486
489
|
testMap.set("name", "Test");
|
|
487
490
|
|
|
491
|
+
// Wait for sharedGroup to sync so other nodes can resolve keys via groupSealer
|
|
492
|
+
await sharedGroup.core.waitForSync();
|
|
493
|
+
|
|
488
494
|
// node1 should be able to access the map because it is admin of the childGroup
|
|
489
495
|
const testMapOnNode1 = expectMap(
|
|
490
496
|
await loadCoValueOrFail(node1.node, testMap.id),
|
|
@@ -520,6 +526,9 @@ describe("extend", () => {
|
|
|
520
526
|
const childGroup = node1.node.createGroup();
|
|
521
527
|
childGroup.extend(parentGroup, "admin");
|
|
522
528
|
|
|
529
|
+
// Wait for childGroup to sync so node3 sees the groupSealer field
|
|
530
|
+
await childGroup.core.waitForSync();
|
|
531
|
+
|
|
523
532
|
const sharedGroup = node3.node.createGroup();
|
|
524
533
|
|
|
525
534
|
// Account3 does not have permissions over the childGroup being extended
|
|
@@ -538,10 +547,17 @@ describe("extend", () => {
|
|
|
538
547
|
newParentGroup.addMember(account4OnNode1, "admin");
|
|
539
548
|
childGroup.extend(newParentGroup);
|
|
540
549
|
|
|
550
|
+
// Wait for sharedGroup and childGroup updates to sync
|
|
551
|
+
await sharedGroup.core.waitForSync();
|
|
552
|
+
await childGroup.core.waitForSync();
|
|
553
|
+
|
|
541
554
|
// Create a map owned by sharedGroup
|
|
542
555
|
const testMap = sharedGroup.createMap();
|
|
543
556
|
testMap.set("name", "Test");
|
|
544
557
|
|
|
558
|
+
// Wait for map to sync
|
|
559
|
+
await testMap.core.waitForSync();
|
|
560
|
+
|
|
545
561
|
// Account4 should be able to access the map because it is admin of newParentGroup
|
|
546
562
|
const testMapOnNode4 = expectMap(
|
|
547
563
|
await loadCoValueOrFail(node4.node, testMap.id),
|
package/src/tests/group.test.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { describe, expect, test } from "vitest";
|
|
|
2
2
|
import { RawCoList } from "../coValues/coList.js";
|
|
3
3
|
import { RawCoMap } from "../coValues/coMap.js";
|
|
4
4
|
import { RawCoStream } from "../coValues/coStream.js";
|
|
5
|
-
import { RawBinaryCoStream } from "../coValues/
|
|
5
|
+
import { RawBinaryCoStream } from "../coValues/binaryCoStream.js";
|
|
6
6
|
import type { RawCoValue, RawGroup } from "../exports.js";
|
|
7
7
|
import type { NewContentMessage } from "../sync.js";
|
|
8
8
|
import {
|
|
@@ -70,6 +70,34 @@ test("Can create a FileStream in a group", () => {
|
|
|
70
70
|
expect(stream instanceof RawBinaryCoStream).toEqual(true);
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
+
test("Group without name has name undefined", () => {
|
|
74
|
+
const node = nodeWithRandomAgentAndSessionID();
|
|
75
|
+
const group = node.createGroup();
|
|
76
|
+
expect(group.name).toBeUndefined();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("Group created with name returns that name", () => {
|
|
80
|
+
const node = nodeWithRandomAgentAndSessionID();
|
|
81
|
+
const group = node.createGroup(undefined, { name: "My Group" });
|
|
82
|
+
expect(group.name).toBe("My Group");
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test("Group created with empty name has name undefined (meta not set)", () => {
|
|
86
|
+
const node = nodeWithRandomAgentAndSessionID();
|
|
87
|
+
const group = node.createGroup(undefined, { name: "" });
|
|
88
|
+
expect(group.name).toBeUndefined();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test("Group with name persists after sync and load", async () => {
|
|
92
|
+
const { node1, node2 } = await createTwoConnectedNodes("server", "server");
|
|
93
|
+
const group = node1.node.createGroup(undefined, { name: "Synced Group" });
|
|
94
|
+
expect(group.name).toBe("Synced Group");
|
|
95
|
+
await group.core.waitForSync();
|
|
96
|
+
|
|
97
|
+
const loaded = expectGroup(await loadCoValueOrFail(node2.node, group.id));
|
|
98
|
+
expect(loaded.name).toBe("Synced Group");
|
|
99
|
+
});
|
|
100
|
+
|
|
73
101
|
test("Remove a member from a group where the admin role is inherited", async () => {
|
|
74
102
|
const { node1, node2, node3 } = await createThreeConnectedNodes(
|
|
75
103
|
"server",
|