cojson 0.9.9 → 0.9.11
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 +3 -3
- package/CHANGELOG.md +13 -0
- package/dist/native/PeerState.js +2 -1
- package/dist/native/PeerState.js.map +1 -1
- package/dist/native/PriorityBasedMessageQueue.js +54 -7
- package/dist/native/PriorityBasedMessageQueue.js.map +1 -1
- package/dist/native/base64url.js +0 -6
- package/dist/native/base64url.js.map +1 -1
- package/dist/native/coValue.js +27 -0
- package/dist/native/coValue.js.map +1 -1
- package/dist/native/coValueCore.js +30 -177
- package/dist/native/coValueCore.js.map +1 -1
- package/dist/native/coValueState.js +5 -4
- package/dist/native/coValueState.js.map +1 -1
- package/dist/native/coValues/account.js +2 -1
- package/dist/native/coValues/account.js.map +1 -1
- package/dist/native/coValues/coList.js +0 -7
- package/dist/native/coValues/coList.js.map +1 -1
- package/dist/native/coValues/coStream.js +3 -8
- package/dist/native/coValues/coStream.js.map +1 -1
- package/dist/native/coValues/group.js +3 -2
- package/dist/native/coValues/group.js.map +1 -1
- package/dist/native/coreToCoValue.js +2 -1
- package/dist/native/coreToCoValue.js.map +1 -1
- package/dist/native/crypto/PureJSCrypto.js +2 -1
- package/dist/native/crypto/PureJSCrypto.js.map +1 -1
- package/dist/native/crypto/WasmCrypto.js +2 -1
- package/dist/native/crypto/WasmCrypto.js.map +1 -1
- package/dist/native/crypto/crypto.js +2 -4
- package/dist/native/crypto/crypto.js.map +1 -1
- package/dist/native/exports.js +2 -1
- package/dist/native/exports.js.map +1 -1
- package/dist/native/localNode.js +5 -6
- package/dist/native/localNode.js.map +1 -1
- package/dist/native/logger.js +58 -0
- package/dist/native/logger.js.map +1 -0
- package/dist/native/permissions.js +3 -4
- package/dist/native/permissions.js.map +1 -1
- package/dist/native/storage/FileSystem.js +0 -10
- package/dist/native/storage/FileSystem.js.map +1 -1
- package/dist/native/storage/index.js +14 -23
- package/dist/native/storage/index.js.map +1 -1
- package/dist/native/sync.js +20 -28
- package/dist/native/sync.js.map +1 -1
- package/dist/web/PeerState.js +2 -1
- package/dist/web/PeerState.js.map +1 -1
- package/dist/web/PriorityBasedMessageQueue.js +54 -7
- package/dist/web/PriorityBasedMessageQueue.js.map +1 -1
- package/dist/web/base64url.js +0 -6
- package/dist/web/base64url.js.map +1 -1
- package/dist/web/coValue.js +27 -0
- package/dist/web/coValue.js.map +1 -1
- package/dist/web/coValueCore.js +30 -177
- package/dist/web/coValueCore.js.map +1 -1
- package/dist/web/coValueState.js +5 -4
- package/dist/web/coValueState.js.map +1 -1
- package/dist/web/coValues/account.js +2 -1
- package/dist/web/coValues/account.js.map +1 -1
- package/dist/web/coValues/coList.js +0 -7
- package/dist/web/coValues/coList.js.map +1 -1
- package/dist/web/coValues/coStream.js +3 -8
- package/dist/web/coValues/coStream.js.map +1 -1
- package/dist/web/coValues/group.js +3 -2
- package/dist/web/coValues/group.js.map +1 -1
- package/dist/web/coreToCoValue.js +2 -1
- package/dist/web/coreToCoValue.js.map +1 -1
- package/dist/web/crypto/PureJSCrypto.js +2 -1
- package/dist/web/crypto/PureJSCrypto.js.map +1 -1
- package/dist/web/crypto/WasmCrypto.js +2 -1
- package/dist/web/crypto/WasmCrypto.js.map +1 -1
- package/dist/web/crypto/crypto.js +2 -4
- package/dist/web/crypto/crypto.js.map +1 -1
- package/dist/web/exports.js +2 -1
- package/dist/web/exports.js.map +1 -1
- package/dist/web/localNode.js +5 -6
- package/dist/web/localNode.js.map +1 -1
- package/dist/web/logger.js +58 -0
- package/dist/web/logger.js.map +1 -0
- package/dist/web/permissions.js +3 -4
- package/dist/web/permissions.js.map +1 -1
- package/dist/web/storage/FileSystem.js +0 -10
- package/dist/web/storage/FileSystem.js.map +1 -1
- package/dist/web/storage/index.js +14 -23
- package/dist/web/storage/index.js.map +1 -1
- package/dist/web/sync.js +20 -28
- package/dist/web/sync.js.map +1 -1
- package/package.json +1 -1
- package/src/PeerState.ts +4 -3
- package/src/PriorityBasedMessageQueue.ts +67 -11
- package/src/base64url.ts +1 -6
- package/src/coValue.ts +37 -0
- package/src/coValueCore.ts +34 -180
- package/src/coValueState.ts +5 -4
- package/src/coValues/account.ts +2 -1
- package/src/coValues/coList.ts +0 -7
- package/src/coValues/coStream.ts +3 -8
- package/src/coValues/group.ts +3 -2
- package/src/coreToCoValue.ts +2 -1
- package/src/crypto/PureJSCrypto.ts +2 -1
- package/src/crypto/WasmCrypto.ts +2 -1
- package/src/crypto/crypto.ts +2 -4
- package/src/exports.ts +2 -0
- package/src/localNode.ts +5 -9
- package/src/logger.ts +78 -0
- package/src/permissions.ts +3 -5
- package/src/storage/FileSystem.ts +0 -12
- package/src/storage/index.ts +21 -37
- package/src/sync.ts +20 -29
- package/src/tests/PeerState.test.ts +0 -3
- package/src/tests/PriorityBasedMessageQueue.test.ts +1 -1
- package/src/tests/coValueCore.test.ts +32 -2
- package/src/tests/logger.test.ts +145 -0
- package/src/tests/sync.test.ts +43 -0
- package/src/tests/testUtils.ts +19 -0
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { expect, test, vi } from "vitest";
|
|
2
|
-
import { Transaction } from "../coValueCore.js";
|
|
2
|
+
import { CoValueCore, Transaction } from "../coValueCore.js";
|
|
3
3
|
import { MapOpPayload } from "../coValues/coMap.js";
|
|
4
4
|
import { WasmCrypto } from "../crypto/WasmCrypto.js";
|
|
5
5
|
import { stableStringify } from "../jsonStringify.js";
|
|
6
6
|
import { LocalNode } from "../localNode.js";
|
|
7
7
|
import { Role } from "../permissions.js";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
createTestNode,
|
|
10
|
+
randomAnonymousAccountAndSessionID,
|
|
11
|
+
} from "./testUtils.js";
|
|
9
12
|
|
|
10
13
|
const Crypto = await WasmCrypto.create();
|
|
11
14
|
|
|
@@ -191,3 +194,30 @@ test("New transactions in a group correctly update owned values, including subsc
|
|
|
191
194
|
|
|
192
195
|
expect(map.core.getValidSortedTransactions().length).toBe(0);
|
|
193
196
|
});
|
|
197
|
+
|
|
198
|
+
test("creating a coValue with a group should't trigger automatically a content creation (performance)", () => {
|
|
199
|
+
const node = createTestNode();
|
|
200
|
+
|
|
201
|
+
const group = node.createGroup();
|
|
202
|
+
|
|
203
|
+
const getCurrentContentSpy = vi.spyOn(
|
|
204
|
+
CoValueCore.prototype,
|
|
205
|
+
"getCurrentContent",
|
|
206
|
+
);
|
|
207
|
+
const groupSpy = vi.spyOn(group.core, "getCurrentContent");
|
|
208
|
+
|
|
209
|
+
getCurrentContentSpy.mockClear();
|
|
210
|
+
|
|
211
|
+
node.createCoValue({
|
|
212
|
+
type: "comap",
|
|
213
|
+
ruleset: { type: "ownedByGroup", group: group.id },
|
|
214
|
+
meta: null,
|
|
215
|
+
...Crypto.createdNowUnique(),
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
// It's called once for the group and never for the coValue
|
|
219
|
+
expect(getCurrentContentSpy).toHaveBeenCalledTimes(1);
|
|
220
|
+
expect(groupSpy).toHaveBeenCalledTimes(1);
|
|
221
|
+
|
|
222
|
+
getCurrentContentSpy.mockRestore();
|
|
223
|
+
});
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { describe, expect, test, vi } from "vitest";
|
|
2
|
+
import { LogLevel, Logger } from "../logger";
|
|
3
|
+
|
|
4
|
+
describe("Logger", () => {
|
|
5
|
+
describe("Log Level Filtering", () => {
|
|
6
|
+
test("should respect log level hierarchy", () => {
|
|
7
|
+
const mockLogSystem = {
|
|
8
|
+
debug: vi.fn(),
|
|
9
|
+
info: vi.fn(),
|
|
10
|
+
warn: vi.fn(),
|
|
11
|
+
error: vi.fn(),
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const logger = new Logger(LogLevel.WARN, mockLogSystem);
|
|
15
|
+
|
|
16
|
+
logger.debug("Debug message");
|
|
17
|
+
logger.info("Info message");
|
|
18
|
+
logger.warn("Warning message");
|
|
19
|
+
logger.error("Error message");
|
|
20
|
+
|
|
21
|
+
expect(mockLogSystem.debug).not.toHaveBeenCalled();
|
|
22
|
+
expect(mockLogSystem.info).not.toHaveBeenCalled();
|
|
23
|
+
expect(mockLogSystem.warn).toHaveBeenCalledWith("Warning message");
|
|
24
|
+
expect(mockLogSystem.error).toHaveBeenCalledWith("Error message");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("should pass additional arguments to log system", () => {
|
|
28
|
+
const mockLogSystem = {
|
|
29
|
+
debug: vi.fn(),
|
|
30
|
+
info: vi.fn(),
|
|
31
|
+
warn: vi.fn(),
|
|
32
|
+
error: vi.fn(),
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const logger = new Logger(LogLevel.DEBUG, mockLogSystem);
|
|
36
|
+
const additionalArgs = [{ foo: "bar" }, 42, "extra"];
|
|
37
|
+
|
|
38
|
+
logger.debug("Debug message", ...additionalArgs);
|
|
39
|
+
|
|
40
|
+
expect(mockLogSystem.debug).toHaveBeenCalledWith(
|
|
41
|
+
"Debug message",
|
|
42
|
+
...additionalArgs,
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe("Log System Configuration", () => {
|
|
48
|
+
test("should allow changing log level at runtime", () => {
|
|
49
|
+
const mockLogSystem = {
|
|
50
|
+
debug: vi.fn(),
|
|
51
|
+
info: vi.fn(),
|
|
52
|
+
warn: vi.fn(),
|
|
53
|
+
error: vi.fn(),
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const logger = new Logger(LogLevel.ERROR, mockLogSystem);
|
|
57
|
+
|
|
58
|
+
logger.warn("Warning 1"); // Should not log
|
|
59
|
+
expect(mockLogSystem.warn).not.toHaveBeenCalled();
|
|
60
|
+
|
|
61
|
+
logger.setLevel(LogLevel.WARN);
|
|
62
|
+
logger.warn("Warning 2"); // Should log
|
|
63
|
+
expect(mockLogSystem.warn).toHaveBeenCalledWith("Warning 2");
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("should allow changing log system at runtime", () => {
|
|
67
|
+
const mockLogSystem1 = {
|
|
68
|
+
debug: vi.fn(),
|
|
69
|
+
info: vi.fn(),
|
|
70
|
+
warn: vi.fn(),
|
|
71
|
+
error: vi.fn(),
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const mockLogSystem2 = {
|
|
75
|
+
debug: vi.fn(),
|
|
76
|
+
info: vi.fn(),
|
|
77
|
+
warn: vi.fn(),
|
|
78
|
+
error: vi.fn(),
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const logger = new Logger(LogLevel.INFO, mockLogSystem1);
|
|
82
|
+
|
|
83
|
+
logger.info("Message 1");
|
|
84
|
+
expect(mockLogSystem1.info).toHaveBeenCalledWith("Message 1");
|
|
85
|
+
expect(mockLogSystem2.info).not.toHaveBeenCalled();
|
|
86
|
+
|
|
87
|
+
logger.setLogSystem(mockLogSystem2);
|
|
88
|
+
logger.info("Message 2");
|
|
89
|
+
expect(mockLogSystem2.info).toHaveBeenCalledWith("Message 2");
|
|
90
|
+
expect(mockLogSystem1.info).toHaveBeenCalledTimes(1);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe("Default Console Log System", () => {
|
|
95
|
+
test("should use console methods by default", () => {
|
|
96
|
+
const consoleSpy = {
|
|
97
|
+
debug: vi.spyOn(console, "debug").mockImplementation(() => {}),
|
|
98
|
+
info: vi.spyOn(console, "info").mockImplementation(() => {}),
|
|
99
|
+
warn: vi.spyOn(console, "warn").mockImplementation(() => {}),
|
|
100
|
+
error: vi.spyOn(console, "error").mockImplementation(() => {}),
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const logger = new Logger();
|
|
104
|
+
logger.setLevel(LogLevel.DEBUG);
|
|
105
|
+
const testMessage = "Test message";
|
|
106
|
+
const testArgs = [{ data: "test" }, 123];
|
|
107
|
+
|
|
108
|
+
logger.debug(testMessage, ...testArgs);
|
|
109
|
+
logger.info(testMessage, ...testArgs);
|
|
110
|
+
logger.warn(testMessage, ...testArgs);
|
|
111
|
+
logger.error(testMessage, ...testArgs);
|
|
112
|
+
|
|
113
|
+
expect(consoleSpy.debug).toHaveBeenCalledWith(testMessage, ...testArgs);
|
|
114
|
+
expect(consoleSpy.info).toHaveBeenCalledWith(testMessage, ...testArgs);
|
|
115
|
+
expect(consoleSpy.warn).toHaveBeenCalledWith(testMessage, ...testArgs);
|
|
116
|
+
expect(consoleSpy.error).toHaveBeenCalledWith(testMessage, ...testArgs);
|
|
117
|
+
|
|
118
|
+
// Cleanup
|
|
119
|
+
Object.values(consoleSpy).forEach((spy) => spy.mockRestore());
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
describe("Log Level NONE", () => {
|
|
124
|
+
test("should not log anything when level is NONE", () => {
|
|
125
|
+
const mockLogSystem = {
|
|
126
|
+
debug: vi.fn(),
|
|
127
|
+
info: vi.fn(),
|
|
128
|
+
warn: vi.fn(),
|
|
129
|
+
error: vi.fn(),
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const logger = new Logger(LogLevel.NONE, mockLogSystem);
|
|
133
|
+
|
|
134
|
+
logger.debug("Debug message");
|
|
135
|
+
logger.info("Info message");
|
|
136
|
+
logger.warn("Warning message");
|
|
137
|
+
logger.error("Error message");
|
|
138
|
+
|
|
139
|
+
expect(mockLogSystem.debug).not.toHaveBeenCalled();
|
|
140
|
+
expect(mockLogSystem.info).not.toHaveBeenCalled();
|
|
141
|
+
expect(mockLogSystem.warn).not.toHaveBeenCalled();
|
|
142
|
+
expect(mockLogSystem.error).not.toHaveBeenCalled();
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|
package/src/tests/sync.test.ts
CHANGED
|
@@ -12,8 +12,10 @@ import { connectedPeers, newQueuePair } from "../streamUtils.js";
|
|
|
12
12
|
import type { SyncMessage } from "../sync.js";
|
|
13
13
|
import {
|
|
14
14
|
blockMessageTypeOnOutgoingPeer,
|
|
15
|
+
connectTwoPeers,
|
|
15
16
|
createTestMetricReader,
|
|
16
17
|
createTestNode,
|
|
18
|
+
loadCoValueOrFail,
|
|
17
19
|
randomAnonymousAccountAndSessionID,
|
|
18
20
|
tearDownTestMetricReader,
|
|
19
21
|
waitFor,
|
|
@@ -1645,6 +1647,28 @@ function createTwoConnectedNodes() {
|
|
|
1645
1647
|
};
|
|
1646
1648
|
}
|
|
1647
1649
|
|
|
1650
|
+
test("a value created on one node can be loaded on anotehr node even if not directly connected", async () => {
|
|
1651
|
+
const userA = createTestNode();
|
|
1652
|
+
const userB = createTestNode();
|
|
1653
|
+
const serverA = createTestNode();
|
|
1654
|
+
const serverB = createTestNode();
|
|
1655
|
+
const core = createTestNode();
|
|
1656
|
+
|
|
1657
|
+
connectTwoPeers(userA, serverA, "client", "server");
|
|
1658
|
+
connectTwoPeers(userB, serverB, "client", "server");
|
|
1659
|
+
connectTwoPeers(serverA, core, "client", "server");
|
|
1660
|
+
connectTwoPeers(serverB, core, "client", "server");
|
|
1661
|
+
|
|
1662
|
+
const group = userA.createGroup();
|
|
1663
|
+
const map = group.createMap();
|
|
1664
|
+
map.set("key1", "value1", "trusting");
|
|
1665
|
+
|
|
1666
|
+
await map.core.waitForSync();
|
|
1667
|
+
|
|
1668
|
+
const mapOnUserB = await loadCoValueOrFail(userB, map.id);
|
|
1669
|
+
expect(mapOnUserB.get("key1")).toBe("value1");
|
|
1670
|
+
});
|
|
1671
|
+
|
|
1648
1672
|
describe("SyncManager - knownStates vs optimisticKnownStates", () => {
|
|
1649
1673
|
test("knownStates and optimisticKnownStates are the same when the coValue is fully synced", async () => {
|
|
1650
1674
|
const { client, jazzCloud } = createTwoConnectedNodes();
|
|
@@ -1961,6 +1985,25 @@ describe("waitForSyncWithPeer", () => {
|
|
|
1961
1985
|
});
|
|
1962
1986
|
});
|
|
1963
1987
|
|
|
1988
|
+
test("Should not crash when syncing an unknown coValue type", async () => {
|
|
1989
|
+
const { client, jazzCloud } = createTwoConnectedNodes();
|
|
1990
|
+
|
|
1991
|
+
const coValue = client.createCoValue({
|
|
1992
|
+
type: "ooops" as any,
|
|
1993
|
+
ruleset: { type: "unsafeAllowAll" },
|
|
1994
|
+
meta: null,
|
|
1995
|
+
...Crypto.createdNowUnique(),
|
|
1996
|
+
});
|
|
1997
|
+
|
|
1998
|
+
await coValue.waitForSync();
|
|
1999
|
+
|
|
2000
|
+
const coValueOnTheOtherNode = await loadCoValueOrFail(
|
|
2001
|
+
jazzCloud,
|
|
2002
|
+
coValue.getCurrentContent().id,
|
|
2003
|
+
);
|
|
2004
|
+
expect(coValueOnTheOtherNode.id).toBe(coValue.id);
|
|
2005
|
+
});
|
|
2006
|
+
|
|
1964
2007
|
describe("metrics", () => {
|
|
1965
2008
|
afterEach(() => {
|
|
1966
2009
|
tearDownTestMetricReader();
|
package/src/tests/testUtils.ts
CHANGED
|
@@ -33,6 +33,25 @@ export function createTestNode() {
|
|
|
33
33
|
return new LocalNode(admin, session, Crypto);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
export function connectTwoPeers(
|
|
37
|
+
a: LocalNode,
|
|
38
|
+
b: LocalNode,
|
|
39
|
+
aRole: "client" | "server",
|
|
40
|
+
bRole: "client" | "server",
|
|
41
|
+
) {
|
|
42
|
+
const [aAsPeer, bAsPeer] = connectedPeers(
|
|
43
|
+
"peer:" + a.account.id,
|
|
44
|
+
"peer:" + b.account.id,
|
|
45
|
+
{
|
|
46
|
+
peer1role: aRole,
|
|
47
|
+
peer2role: bRole,
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
a.syncManager.addPeer(bAsPeer);
|
|
52
|
+
b.syncManager.addPeer(aAsPeer);
|
|
53
|
+
}
|
|
54
|
+
|
|
36
55
|
export async function createTwoConnectedNodes(
|
|
37
56
|
node1Role: Peer["role"],
|
|
38
57
|
node2Role: Peer["role"],
|