cojson 0.17.12 → 0.17.13
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/coValueCore/SessionMap.d.ts +4 -3
- package/dist/coValueCore/SessionMap.d.ts.map +1 -1
- package/dist/coValueCore/SessionMap.js +15 -4
- package/dist/coValueCore/SessionMap.js.map +1 -1
- package/dist/coValueCore/coValueCore.d.ts +2 -2
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +33 -32
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValueCore/utils.d.ts.map +1 -1
- package/dist/coValueCore/utils.js.map +1 -1
- package/dist/coValueCore/verifiedState.d.ts +8 -2
- package/dist/coValueCore/verifiedState.d.ts.map +1 -1
- package/dist/coValueCore/verifiedState.js +7 -4
- package/dist/coValueCore/verifiedState.js.map +1 -1
- package/dist/crypto/PureJSCrypto.d.ts +4 -3
- package/dist/crypto/PureJSCrypto.d.ts.map +1 -1
- package/dist/crypto/PureJSCrypto.js +34 -2
- package/dist/crypto/PureJSCrypto.js.map +1 -1
- package/dist/crypto/WasmCrypto.d.ts +4 -3
- package/dist/crypto/WasmCrypto.d.ts.map +1 -1
- package/dist/crypto/WasmCrypto.js +10 -4
- package/dist/crypto/WasmCrypto.js.map +1 -1
- package/dist/crypto/crypto.d.ts +4 -3
- package/dist/crypto/crypto.d.ts.map +1 -1
- package/dist/sync.d.ts +2 -2
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +9 -13
- package/dist/sync.js.map +1 -1
- package/dist/tests/PureJSCrypto.test.js +43 -0
- package/dist/tests/PureJSCrypto.test.js.map +1 -1
- package/dist/tests/WasmCrypto.test.js +55 -0
- package/dist/tests/WasmCrypto.test.js.map +1 -1
- package/dist/tests/coList.test.js +13 -0
- package/dist/tests/coList.test.js.map +1 -1
- package/dist/tests/coMap.test.js +14 -0
- package/dist/tests/coMap.test.js.map +1 -1
- package/dist/tests/coPlainText.test.js +13 -0
- package/dist/tests/coPlainText.test.js.map +1 -1
- package/dist/tests/coStream.test.js +25 -0
- package/dist/tests/coStream.test.js.map +1 -1
- package/dist/tests/coValueCore.test.js +28 -2
- package/dist/tests/coValueCore.test.js.map +1 -1
- package/dist/tests/coreWasm.test.js +1 -1
- package/dist/tests/coreWasm.test.js.map +1 -1
- package/dist/tests/sync.sharding.test.js +35 -1
- package/dist/tests/sync.sharding.test.js.map +1 -1
- package/dist/tests/sync.storage.test.js +31 -1
- package/dist/tests/sync.storage.test.js.map +1 -1
- package/dist/tests/sync.storageAsync.test.js +1 -1
- package/dist/tests/sync.storageAsync.test.js.map +1 -1
- package/dist/tests/sync.test.js +2 -2
- package/dist/tests/sync.test.js.map +1 -1
- package/dist/tests/sync.upload.test.js +26 -0
- package/dist/tests/sync.upload.test.js.map +1 -1
- package/dist/tests/testUtils.d.ts.map +1 -1
- package/dist/tests/testUtils.js +3 -1
- package/dist/tests/testUtils.js.map +1 -1
- package/package.json +2 -2
- package/src/coValueCore/SessionMap.ts +24 -1
- package/src/coValueCore/coValueCore.ts +46 -41
- package/src/coValueCore/utils.ts +0 -1
- package/src/coValueCore/verifiedState.ts +14 -3
- package/src/crypto/PureJSCrypto.ts +49 -1
- package/src/crypto/WasmCrypto.ts +15 -1
- package/src/crypto/crypto.ts +7 -1
- package/src/sync.ts +9 -14
- package/src/tests/PureJSCrypto.test.ts +66 -0
- package/src/tests/WasmCrypto.test.ts +88 -0
- package/src/tests/coList.test.ts +19 -0
- package/src/tests/coMap.test.ts +21 -0
- package/src/tests/coPlainText.test.ts +18 -0
- package/src/tests/coStream.test.ts +36 -0
- package/src/tests/coValueCore.test.ts +49 -0
- package/src/tests/coreWasm.test.ts +1 -0
- package/src/tests/sync.sharding.test.ts +44 -1
- package/src/tests/sync.storage.test.ts +43 -1
- package/src/tests/sync.storageAsync.test.ts +1 -1
- package/src/tests/sync.test.ts +6 -2
- package/src/tests/sync.upload.test.ts +35 -0
- package/src/tests/testUtils.ts +3 -1
|
@@ -126,6 +126,72 @@ describe("PureJSCrypto", () => {
|
|
|
126
126
|
|
|
127
127
|
expect(map.get("count")).toEqual(0);
|
|
128
128
|
});
|
|
129
|
+
|
|
130
|
+
it("can add a meta to a private transaction", async () => {
|
|
131
|
+
const client = setupTestNode({
|
|
132
|
+
connected: true,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const group = client.node.createGroup();
|
|
136
|
+
const map = group.createMap();
|
|
137
|
+
|
|
138
|
+
map.core.makeTransaction([], "private", {
|
|
139
|
+
meta: {
|
|
140
|
+
count: 1,
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
await map.core.waitForSync();
|
|
145
|
+
|
|
146
|
+
const session2 = client.spawnNewSession();
|
|
147
|
+
|
|
148
|
+
const mapInOtherSession = await loadCoValueOrFail(session2.node, map.id);
|
|
149
|
+
|
|
150
|
+
const decryptedMeta =
|
|
151
|
+
mapInOtherSession.core.verified.decryptTransactionMeta(
|
|
152
|
+
client.node.currentSessionID,
|
|
153
|
+
0,
|
|
154
|
+
map.core.getCurrentReadKey().secret!,
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
expect(decryptedMeta).toEqual({
|
|
158
|
+
meta: {
|
|
159
|
+
count: 1,
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it("can add a meta to a trusting transaction", async () => {
|
|
165
|
+
const client = setupTestNode({
|
|
166
|
+
connected: true,
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
const group = client.node.createGroup();
|
|
170
|
+
const map = group.createMap();
|
|
171
|
+
|
|
172
|
+
map.core.makeTransaction([], "trusting", {
|
|
173
|
+
meta: {
|
|
174
|
+
count: 1,
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
await map.core.waitForSync();
|
|
179
|
+
|
|
180
|
+
const session2 = client.spawnNewSession();
|
|
181
|
+
|
|
182
|
+
const mapInOtherSession = await loadCoValueOrFail(session2.node, map.id);
|
|
183
|
+
|
|
184
|
+
const transferredMeta = JSON.parse(
|
|
185
|
+
mapInOtherSession.core.verified.sessions.get(client.node.currentSessionID)
|
|
186
|
+
?.transactions[0]?.meta!,
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
expect(transferredMeta).toEqual({
|
|
190
|
+
meta: {
|
|
191
|
+
count: 1,
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
});
|
|
129
195
|
});
|
|
130
196
|
|
|
131
197
|
describe("PureJSSessionLog", () => {
|
|
@@ -125,4 +125,92 @@ describe("WasmCrypto", () => {
|
|
|
125
125
|
|
|
126
126
|
expect(map.get("count")).toEqual(0);
|
|
127
127
|
});
|
|
128
|
+
|
|
129
|
+
it("can add a meta to a private transaction", async () => {
|
|
130
|
+
const client = setupTestNode({
|
|
131
|
+
connected: true,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
const group = client.node.createGroup();
|
|
135
|
+
const map = group.createMap();
|
|
136
|
+
|
|
137
|
+
map.core.makeTransaction([], "private", {
|
|
138
|
+
meta: {
|
|
139
|
+
count: 1,
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
await map.core.waitForSync();
|
|
144
|
+
|
|
145
|
+
const session2 = client.spawnNewSession();
|
|
146
|
+
|
|
147
|
+
const mapInOtherSession = await loadCoValueOrFail(session2.node, map.id);
|
|
148
|
+
|
|
149
|
+
const decryptedMeta =
|
|
150
|
+
mapInOtherSession.core.verified.decryptTransactionMeta(
|
|
151
|
+
client.node.currentSessionID,
|
|
152
|
+
0,
|
|
153
|
+
mapInOtherSession.core.getCurrentReadKey().secret!,
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
expect(decryptedMeta).toEqual({
|
|
157
|
+
meta: {
|
|
158
|
+
count: 1,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it("can add a meta to a trusting transaction", async () => {
|
|
164
|
+
const client = setupTestNode({
|
|
165
|
+
connected: true,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const group = client.node.createGroup();
|
|
169
|
+
const map = group.createMap();
|
|
170
|
+
|
|
171
|
+
map.core.makeTransaction([], "trusting", {
|
|
172
|
+
meta: {
|
|
173
|
+
count: 1,
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
await map.core.waitForSync();
|
|
178
|
+
|
|
179
|
+
const session2 = client.spawnNewSession();
|
|
180
|
+
|
|
181
|
+
const mapInOtherSession = await loadCoValueOrFail(session2.node, map.id);
|
|
182
|
+
|
|
183
|
+
const transferredMeta = JSON.parse(
|
|
184
|
+
mapInOtherSession.core.verified.sessions.get(client.node.currentSessionID)
|
|
185
|
+
?.transactions[0]?.meta!,
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
expect(transferredMeta).toEqual({
|
|
189
|
+
meta: {
|
|
190
|
+
count: 1,
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it("fails to verify signatures without a signer ID", async () => {
|
|
196
|
+
const agentSecret = wasmCrypto.newRandomAgentSecret();
|
|
197
|
+
const sessionID = wasmCrypto.newRandomSessionID(
|
|
198
|
+
wasmCrypto.getAgentID(agentSecret),
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
const sessionLog = wasmCrypto.createSessionLog("co_z12345678", sessionID);
|
|
202
|
+
expect(() =>
|
|
203
|
+
sessionLog.tryAdd(
|
|
204
|
+
[
|
|
205
|
+
{
|
|
206
|
+
privacy: "trusting",
|
|
207
|
+
changes: stableStringify([{ op: "set", key: "count", value: 1 }]),
|
|
208
|
+
madeAt: Date.now(),
|
|
209
|
+
},
|
|
210
|
+
],
|
|
211
|
+
"signature_z12345678",
|
|
212
|
+
false,
|
|
213
|
+
),
|
|
214
|
+
).toThrow(expect.stringContaining("Signature verification failed"));
|
|
215
|
+
});
|
|
128
216
|
});
|
package/src/tests/coList.test.ts
CHANGED
|
@@ -409,3 +409,22 @@ test("totalValidTransactions should return the number of valid transactions proc
|
|
|
409
409
|
listOnOtherClient.core.getCurrentContent().totalValidTransactions,
|
|
410
410
|
).toEqual(2);
|
|
411
411
|
});
|
|
412
|
+
|
|
413
|
+
test("Should ignore unknown meta transactions", () => {
|
|
414
|
+
const node = nodeWithRandomAgentAndSessionID();
|
|
415
|
+
|
|
416
|
+
const coValue = node.createCoValue({
|
|
417
|
+
type: "colist",
|
|
418
|
+
ruleset: { type: "unsafeAllowAll" },
|
|
419
|
+
meta: null,
|
|
420
|
+
...Crypto.createdNowUnique(),
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
coValue.makeTransaction([], "trusting", { unknownMeta: 1 });
|
|
424
|
+
|
|
425
|
+
const content = expectList(coValue.getCurrentContent());
|
|
426
|
+
|
|
427
|
+
content.append("first", 0, "trusting");
|
|
428
|
+
|
|
429
|
+
expect(content.toJSON()).toEqual(["first"]);
|
|
430
|
+
});
|
package/src/tests/coMap.test.ts
CHANGED
|
@@ -217,6 +217,27 @@ test("Can set items in bulk with assign", () => {
|
|
|
217
217
|
});
|
|
218
218
|
});
|
|
219
219
|
|
|
220
|
+
test("Should ignore unknown meta transactions", () => {
|
|
221
|
+
const node = nodeWithRandomAgentAndSessionID();
|
|
222
|
+
|
|
223
|
+
const coValue = node.createCoValue({
|
|
224
|
+
type: "comap",
|
|
225
|
+
ruleset: { type: "unsafeAllowAll" },
|
|
226
|
+
meta: null,
|
|
227
|
+
...Crypto.createdNowUnique(),
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
coValue.makeTransaction([], "trusting", { unknownMeta: 1 });
|
|
231
|
+
|
|
232
|
+
const content = expectMap(coValue.getCurrentContent());
|
|
233
|
+
|
|
234
|
+
expect(content.type).toEqual("comap");
|
|
235
|
+
|
|
236
|
+
content.set("key1", "set1", "trusting");
|
|
237
|
+
|
|
238
|
+
expect(content.get("key1")).toEqual("set1");
|
|
239
|
+
});
|
|
240
|
+
|
|
220
241
|
test("totalValidTransactions should return the number of valid transactions processed", async () => {
|
|
221
242
|
const client = setupTestNode({
|
|
222
243
|
connected: true,
|
|
@@ -298,6 +298,24 @@ test("Splits into and from grapheme string arrays", () => {
|
|
|
298
298
|
expect(text).toEqual("👋 안녕!");
|
|
299
299
|
});
|
|
300
300
|
|
|
301
|
+
test("Should ignore unknown meta transactions", () => {
|
|
302
|
+
const node = nodeWithRandomAgentAndSessionID();
|
|
303
|
+
|
|
304
|
+
const coValue = node.createCoValue({
|
|
305
|
+
type: "coplaintext",
|
|
306
|
+
ruleset: { type: "unsafeAllowAll" },
|
|
307
|
+
meta: null,
|
|
308
|
+
...Crypto.createdNowUnique(),
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
coValue.makeTransaction([], "trusting", { unknownMeta: 1 });
|
|
312
|
+
|
|
313
|
+
const content = expectPlainText(coValue.getCurrentContent());
|
|
314
|
+
|
|
315
|
+
content.insertAfter(0, "hello", "trusting");
|
|
316
|
+
expect(content.toString()).toEqual("hello");
|
|
317
|
+
});
|
|
318
|
+
|
|
301
319
|
test("chunks transactions when when the chars are longer than MAX_RECOMMENDED_TX_SIZE", async () => {
|
|
302
320
|
setMaxRecommendedTxSize(5);
|
|
303
321
|
|
|
@@ -127,6 +127,42 @@ test("Can push into RawBinaryCoStream", () => {
|
|
|
127
127
|
});
|
|
128
128
|
});
|
|
129
129
|
|
|
130
|
+
test("Should ignore meta transactions on RawBinaryCoStream", () => {
|
|
131
|
+
const node = nodeWithRandomAgentAndSessionID();
|
|
132
|
+
|
|
133
|
+
const coValue = node.createCoValue({
|
|
134
|
+
type: "costream",
|
|
135
|
+
ruleset: { type: "unsafeAllowAll" },
|
|
136
|
+
meta: { type: "binary" },
|
|
137
|
+
...Crypto.createdNowUnique(),
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
coValue.makeTransaction([], "trusting", { unknownMeta: 1 });
|
|
141
|
+
|
|
142
|
+
const content = coValue.getCurrentContent();
|
|
143
|
+
|
|
144
|
+
if (
|
|
145
|
+
content.type !== "costream" ||
|
|
146
|
+
content.headerMeta?.type !== "binary" ||
|
|
147
|
+
!(content instanceof RawBinaryCoStream)
|
|
148
|
+
) {
|
|
149
|
+
throw new Error("Expected binary stream");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
content.startBinaryStream(
|
|
153
|
+
{ mimeType: "text/plain", fileName: "test.txt" },
|
|
154
|
+
"trusting",
|
|
155
|
+
);
|
|
156
|
+
content.pushBinaryStreamChunk(new Uint8Array([1, 2, 3]), "trusting");
|
|
157
|
+
content.endBinaryStream("trusting");
|
|
158
|
+
expect(content.getBinaryChunks()).toEqual({
|
|
159
|
+
mimeType: "text/plain",
|
|
160
|
+
fileName: "test.txt",
|
|
161
|
+
chunks: [new Uint8Array([1, 2, 3])],
|
|
162
|
+
finished: true,
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
|
|
130
166
|
test("When adding large transactions (small fraction of MAX_RECOMMENDED_TX_SIZE), we store an inbetween signature every time we reach MAX_RECOMMENDED_TX_SIZE and split up newContentSince accordingly", () => {
|
|
131
167
|
const node = nodeWithRandomAgentAndSessionID();
|
|
132
168
|
|
|
@@ -20,9 +20,11 @@ import {
|
|
|
20
20
|
loadCoValueOrFail,
|
|
21
21
|
nodeWithRandomAgentAndSessionID,
|
|
22
22
|
randomAgentAndSessionID,
|
|
23
|
+
setupTestNode,
|
|
23
24
|
tearDownTestMetricReader,
|
|
24
25
|
} from "./testUtils.js";
|
|
25
26
|
import { CO_VALUE_PRIORITY } from "../priority.js";
|
|
27
|
+
import { determineValidTransactions } from "../permissions.js";
|
|
26
28
|
|
|
27
29
|
const Crypto = await WasmCrypto.create();
|
|
28
30
|
|
|
@@ -32,6 +34,7 @@ const agentSecret =
|
|
|
32
34
|
|
|
33
35
|
beforeEach(() => {
|
|
34
36
|
metricReader = createTestMetricReader();
|
|
37
|
+
setupTestNode({ isSyncServer: true });
|
|
35
38
|
});
|
|
36
39
|
|
|
37
40
|
afterEach(() => {
|
|
@@ -53,6 +56,7 @@ test("transactions with wrong signature are rejected", () => {
|
|
|
53
56
|
node.currentSessionID,
|
|
54
57
|
node.getCurrentAgent(),
|
|
55
58
|
[{ hello: "world" }],
|
|
59
|
+
undefined,
|
|
56
60
|
);
|
|
57
61
|
|
|
58
62
|
transaction.madeAt = Date.now() + 1000;
|
|
@@ -264,6 +268,51 @@ test("listeners are notified even if the previous listener threw an error", asyn
|
|
|
264
268
|
errorLog.mockRestore();
|
|
265
269
|
});
|
|
266
270
|
|
|
271
|
+
test("creates a transaction with trusting meta information", async () => {
|
|
272
|
+
const client = setupTestNode();
|
|
273
|
+
|
|
274
|
+
const group = client.node.createGroup();
|
|
275
|
+
const map = group.createMap();
|
|
276
|
+
map.core.makeTransaction([], "trusting", {
|
|
277
|
+
meta: true,
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
const validTransactions = determineValidTransactions(map.core);
|
|
281
|
+
|
|
282
|
+
expect(validTransactions[0]?.tx.meta).toBe(`{"meta":true}`);
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
test("creates a transaction with private meta information", async () => {
|
|
286
|
+
const client = setupTestNode({ connected: true });
|
|
287
|
+
|
|
288
|
+
const group = client.node.createGroup();
|
|
289
|
+
const map = group.createMap();
|
|
290
|
+
map.core.makeTransaction([], "private", {
|
|
291
|
+
meta: true,
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
const localTransactionMeta = map.core.verified.decryptTransactionMeta(
|
|
295
|
+
client.node.currentSessionID,
|
|
296
|
+
0,
|
|
297
|
+
map.core.getCurrentReadKey().secret!,
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
expect(localTransactionMeta).toEqual({ meta: true });
|
|
301
|
+
|
|
302
|
+
const newSession = client.spawnNewSession();
|
|
303
|
+
|
|
304
|
+
const mapOnNewSession = await loadCoValueOrFail(newSession.node, map.id);
|
|
305
|
+
|
|
306
|
+
const syncedTransactionMeta =
|
|
307
|
+
mapOnNewSession.core.verified.decryptTransactionMeta(
|
|
308
|
+
client.node.currentSessionID,
|
|
309
|
+
0,
|
|
310
|
+
mapOnNewSession.core.getCurrentReadKey().secret!,
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
expect(syncedTransactionMeta).toEqual({ meta: true });
|
|
314
|
+
});
|
|
315
|
+
|
|
267
316
|
test("getValidTransactions should skip private transactions with invalid JSON", () => {
|
|
268
317
|
const [agent, sessionID] = agentAndSessionIDFromSecret(agentSecret);
|
|
269
318
|
const node = new LocalNode(agent.agentSecret, sessionID, Crypto);
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
SyncMessagesLog,
|
|
5
5
|
TEST_NODE_CONFIG,
|
|
6
6
|
blockMessageTypeOnOutgoingPeer,
|
|
7
|
+
connectedPeersWithMessagesTracking,
|
|
7
8
|
getSyncServerConnectedPeer,
|
|
8
9
|
loadCoValueOrFail,
|
|
9
10
|
setupTestAccount,
|
|
@@ -47,7 +48,6 @@ describe("sharding", () => {
|
|
|
47
48
|
const firstAlphabetical: ServerPeerSelector = (id, serverPeers) => {
|
|
48
49
|
return serverPeers.sort((a, b) => a.id.localeCompare(b.id)).slice(0, 1);
|
|
49
50
|
};
|
|
50
|
-
|
|
51
51
|
const { node: client } = setupTestNode({
|
|
52
52
|
connected: false,
|
|
53
53
|
});
|
|
@@ -73,4 +73,47 @@ describe("sharding", () => {
|
|
|
73
73
|
allPeers.sort((a, b) => a.id.localeCompare(b.id))[0]!.id,
|
|
74
74
|
);
|
|
75
75
|
});
|
|
76
|
+
|
|
77
|
+
test("getPeers respects the serverPeerSelector", async () => {
|
|
78
|
+
const firstPeer: ServerPeerSelector = (id, serverPeers) => {
|
|
79
|
+
return serverPeers.slice(0, 1);
|
|
80
|
+
};
|
|
81
|
+
const { node: edge } = setupTestNode({
|
|
82
|
+
connected: false,
|
|
83
|
+
});
|
|
84
|
+
edge.syncManager.serverPeerSelector = firstPeer;
|
|
85
|
+
|
|
86
|
+
// Connect 2 clients to edge
|
|
87
|
+
for (let i = 0; i < 2; i++) {
|
|
88
|
+
const client = await setupTestAccount({});
|
|
89
|
+
const { peer1, peer2 } = connectedPeersWithMessagesTracking({
|
|
90
|
+
peer1: {
|
|
91
|
+
id: client.node.getCurrentAgent().id,
|
|
92
|
+
role: "client",
|
|
93
|
+
},
|
|
94
|
+
peer2: {
|
|
95
|
+
id: edge.getCurrentAgent().id,
|
|
96
|
+
role: "server",
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
edge.syncManager.addPeer(peer1);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Connect edge to 3 core nodes
|
|
104
|
+
for (let i = 0; i < 3; i++) {
|
|
105
|
+
const syncServer = await setupTestAccount({ isSyncServer: true });
|
|
106
|
+
|
|
107
|
+
const { peer } = getSyncServerConnectedPeer({
|
|
108
|
+
peerId: edge.getCurrentAgent().id,
|
|
109
|
+
syncServer: syncServer.node,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
edge.syncManager.addPeer(peer);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
expect(edge.syncManager.getPeers("co_z12345").length).toBe(
|
|
116
|
+
2 + 1, // 2 clients + 1 selected core
|
|
117
|
+
);
|
|
118
|
+
});
|
|
76
119
|
});
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
waitFor,
|
|
21
21
|
} from "./testUtils";
|
|
22
22
|
import { stableStringify } from "../jsonStringify";
|
|
23
|
+
import { determineValidTransactions } from "../permissions";
|
|
23
24
|
|
|
24
25
|
// We want to simulate a real world communication that happens asynchronously
|
|
25
26
|
TEST_NODE_CONFIG.withAsyncPeers = true;
|
|
@@ -151,6 +152,47 @@ describe("client with storage syncs with server", () => {
|
|
|
151
152
|
`);
|
|
152
153
|
});
|
|
153
154
|
|
|
155
|
+
test("persists meta information", async () => {
|
|
156
|
+
const client = setupTestNode();
|
|
157
|
+
|
|
158
|
+
const { storage } = client.addStorage();
|
|
159
|
+
|
|
160
|
+
const group = client.node.createGroup();
|
|
161
|
+
const map = group.createMap();
|
|
162
|
+
map.core.makeTransaction([], "trusting", {
|
|
163
|
+
meta: true,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
await map.core.waitForSync();
|
|
167
|
+
|
|
168
|
+
client.restart();
|
|
169
|
+
|
|
170
|
+
client.addStorage({
|
|
171
|
+
storage,
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
const loadedValue = await loadCoValueOrFail(client.node, map.id);
|
|
175
|
+
|
|
176
|
+
const validTransactions = determineValidTransactions(loadedValue.core);
|
|
177
|
+
|
|
178
|
+
expect(validTransactions[0]?.tx.meta).toBe(`{"meta":true}`);
|
|
179
|
+
|
|
180
|
+
expect(
|
|
181
|
+
SyncMessagesLog.getMessages({
|
|
182
|
+
Group: group.core,
|
|
183
|
+
Map: map.core,
|
|
184
|
+
}),
|
|
185
|
+
).toMatchInlineSnapshot(`
|
|
186
|
+
[
|
|
187
|
+
"client -> storage | CONTENT Group header: true new: After: 0 New: 3",
|
|
188
|
+
"client -> storage | CONTENT Map header: true new: After: 0 New: 1",
|
|
189
|
+
"client -> storage | LOAD Map sessions: empty",
|
|
190
|
+
"storage -> client | CONTENT Group header: true new: After: 0 New: 3",
|
|
191
|
+
"storage -> client | CONTENT Map header: true new: After: 0 New: 1",
|
|
192
|
+
]
|
|
193
|
+
`);
|
|
194
|
+
});
|
|
195
|
+
|
|
154
196
|
test("updating a coValue while offline", async () => {
|
|
155
197
|
const client = setupTestNode();
|
|
156
198
|
|
|
@@ -164,7 +206,7 @@ describe("client with storage syncs with server", () => {
|
|
|
164
206
|
const mapOnClient = await loadCoValueOrFail(client.node, map.id);
|
|
165
207
|
expect(mapOnClient.get("hello")).toEqual("world");
|
|
166
208
|
|
|
167
|
-
client.node.syncManager.getPeers()[0]?.gracefulShutdown();
|
|
209
|
+
client.node.syncManager.getPeers(map.id)[0]?.gracefulShutdown();
|
|
168
210
|
|
|
169
211
|
SyncMessagesLog.clear();
|
|
170
212
|
map.set("hello", "updated", "trusting");
|
|
@@ -156,7 +156,7 @@ describe("client with storage syncs with server", () => {
|
|
|
156
156
|
const mapOnClient = await loadCoValueOrFail(client.node, map.id);
|
|
157
157
|
expect(mapOnClient.get("hello")).toEqual("world");
|
|
158
158
|
|
|
159
|
-
client.node.syncManager.getPeers()[0]?.gracefulShutdown();
|
|
159
|
+
client.node.syncManager.getPeers(map.id)[0]?.gracefulShutdown();
|
|
160
160
|
|
|
161
161
|
SyncMessagesLog.clear();
|
|
162
162
|
map.set("hello", "updated", "trusting");
|
package/src/tests/sync.test.ts
CHANGED
|
@@ -599,8 +599,12 @@ describe("SyncManager - knownStates vs optimisticKnownStates", () => {
|
|
|
599
599
|
// Wait for the full sync to complete
|
|
600
600
|
await mapOnClient.core.waitForSync();
|
|
601
601
|
|
|
602
|
-
const peerStateClient = client.syncManager.getPeers(
|
|
603
|
-
|
|
602
|
+
const peerStateClient = client.syncManager.getPeers(
|
|
603
|
+
mapOnClient.core.id,
|
|
604
|
+
)[0]!;
|
|
605
|
+
const peerStateJazzCloud = jazzCloud.node.syncManager.getPeers(
|
|
606
|
+
mapOnClient.core.id,
|
|
607
|
+
)[0]!;
|
|
604
608
|
|
|
605
609
|
// The optimisticKnownStates should be the same as the knownStates after the full sync is complete
|
|
606
610
|
expect(
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
setupTestNode,
|
|
10
10
|
waitFor,
|
|
11
11
|
} from "./testUtils";
|
|
12
|
+
import { determineValidTransactions } from "../permissions";
|
|
12
13
|
|
|
13
14
|
// We want to simulate a real world communication that happens asynchronously
|
|
14
15
|
TEST_NODE_CONFIG.withAsyncPeers = true;
|
|
@@ -51,6 +52,40 @@ describe("client to server upload", () => {
|
|
|
51
52
|
`);
|
|
52
53
|
});
|
|
53
54
|
|
|
55
|
+
test("syncs meta information", async () => {
|
|
56
|
+
const client = setupTestNode({
|
|
57
|
+
connected: true,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const group = client.node.createGroup();
|
|
61
|
+
const map = group.createMap();
|
|
62
|
+
map.core.makeTransaction([], "trusting", {
|
|
63
|
+
meta: true,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
await map.core.waitForSync();
|
|
67
|
+
|
|
68
|
+
const loadedValue = await loadCoValueOrFail(jazzCloud.node, map.id);
|
|
69
|
+
|
|
70
|
+
const validTransactions = determineValidTransactions(loadedValue.core);
|
|
71
|
+
|
|
72
|
+
expect(validTransactions[0]?.tx.meta).toBe(`{"meta":true}`);
|
|
73
|
+
|
|
74
|
+
expect(
|
|
75
|
+
SyncMessagesLog.getMessages({
|
|
76
|
+
Group: group.core,
|
|
77
|
+
Map: map.core,
|
|
78
|
+
}),
|
|
79
|
+
).toMatchInlineSnapshot(`
|
|
80
|
+
[
|
|
81
|
+
"client -> server | CONTENT Group header: true new: After: 0 New: 3",
|
|
82
|
+
"client -> server | CONTENT Map header: true new: After: 0 New: 1",
|
|
83
|
+
"server -> client | KNOWN Group sessions: header/3",
|
|
84
|
+
"server -> client | KNOWN Map sessions: header/1",
|
|
85
|
+
]
|
|
86
|
+
`);
|
|
87
|
+
});
|
|
88
|
+
|
|
54
89
|
test("coValue with parent groups uploading", async () => {
|
|
55
90
|
const client = setupTestNode({
|
|
56
91
|
connected: true,
|
package/src/tests/testUtils.ts
CHANGED
|
@@ -669,9 +669,11 @@ export async function setupTestAccount(
|
|
|
669
669
|
addStorage,
|
|
670
670
|
addAsyncStorage,
|
|
671
671
|
disconnect: () => {
|
|
672
|
-
ctx.node.syncManager.getPeers(
|
|
672
|
+
const allPeers = ctx.node.syncManager.getPeers(ctx.accountID);
|
|
673
|
+
allPeers.forEach((peer) => {
|
|
673
674
|
peer.gracefulShutdown();
|
|
674
675
|
});
|
|
676
|
+
ctx.node.syncManager.peers = {};
|
|
675
677
|
},
|
|
676
678
|
};
|
|
677
679
|
}
|