cojson 0.19.4 → 0.19.6
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 +15 -0
- package/dist/coValues/coMap.d.ts +3 -2
- package/dist/coValues/coMap.d.ts.map +1 -1
- package/dist/coValues/coMap.js +8 -10
- package/dist/coValues/coMap.js.map +1 -1
- package/dist/coValues/group.d.ts +7 -3
- package/dist/coValues/group.d.ts.map +1 -1
- package/dist/coValues/group.js +70 -24
- package/dist/coValues/group.js.map +1 -1
- package/dist/crypto/PureJSCrypto.d.ts +6 -3
- package/dist/crypto/PureJSCrypto.d.ts.map +1 -1
- package/dist/crypto/PureJSCrypto.js +6 -3
- package/dist/crypto/PureJSCrypto.js.map +1 -1
- package/dist/tests/account.test.js +21 -39
- package/dist/tests/account.test.js.map +1 -1
- package/dist/tests/group.parentGroupCache.test.d.ts +2 -0
- package/dist/tests/group.parentGroupCache.test.d.ts.map +1 -0
- package/dist/tests/group.parentGroupCache.test.js +216 -0
- package/dist/tests/group.parentGroupCache.test.js.map +1 -0
- package/package.json +3 -3
- package/src/coValues/coMap.ts +15 -11
- package/src/coValues/group.ts +99 -24
- package/src/crypto/PureJSCrypto.ts +12 -4
- package/src/tests/account.test.ts +24 -43
- package/src/tests/group.parentGroupCache.test.ts +293 -0
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { expect, test } from "vitest";
|
|
1
|
+
import { beforeEach, expect, test } from "vitest";
|
|
2
2
|
import { expectAccount } from "../coValues/account.js";
|
|
3
3
|
import { WasmCrypto } from "../crypto/WasmCrypto.js";
|
|
4
4
|
import { LocalNode } from "../localNode.js";
|
|
5
5
|
import { connectedPeers } from "../streamUtils.js";
|
|
6
6
|
import { createAsyncStorage } from "./testStorage.js";
|
|
7
|
+
import { setupTestAccount, setupTestNode } from "./testUtils.js";
|
|
7
8
|
const Crypto = await WasmCrypto.create();
|
|
9
|
+
beforeEach(async () => {
|
|
10
|
+
await setupTestNode({ isSyncServer: true });
|
|
11
|
+
});
|
|
8
12
|
test("Can create a node while creating a new account with profile", async () => {
|
|
9
13
|
const { node, accountID, accountSecret, sessionID } = await LocalNode.withNewlyCreatedAccount({
|
|
10
14
|
creationProps: { name: "Hermes Puggington" },
|
|
@@ -56,53 +60,31 @@ test("Can create account with one node, and then load it on another", async () =
|
|
|
56
60
|
expect(map2.get("foo")).toEqual("bar");
|
|
57
61
|
});
|
|
58
62
|
test("Should migrate the root from private to trusting", async () => {
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
crypto: Crypto,
|
|
62
|
-
});
|
|
63
|
-
const group = await node.createGroup();
|
|
63
|
+
const session1 = await setupTestAccount({ connected: true });
|
|
64
|
+
const group = session1.node.createGroup();
|
|
64
65
|
expect(group).not.toBeNull();
|
|
65
66
|
const map = group.createMap();
|
|
66
67
|
map.set("foo", "bar", "private");
|
|
67
68
|
expect(map.get("foo")).toEqual("bar");
|
|
68
|
-
const
|
|
69
|
-
peer1role: "server",
|
|
70
|
-
peer2role: "client",
|
|
71
|
-
});
|
|
72
|
-
const account = await node.load(accountID);
|
|
69
|
+
const account = await session1.node.load(session1.accountID);
|
|
73
70
|
if (account === "unavailable")
|
|
74
71
|
throw new Error("Account unavailable");
|
|
75
72
|
account.set("root", map.id, "private");
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
crypto: Crypto,
|
|
83
|
-
});
|
|
84
|
-
const account2 = await node2.load(accountID);
|
|
85
|
-
if (account2 === "unavailable")
|
|
73
|
+
// Waiting to ensure that the migration is always applied on a different timestamp
|
|
74
|
+
// to make the test more stable
|
|
75
|
+
await new Promise((resolve) => setTimeout(resolve, 4));
|
|
76
|
+
const session2 = await session1.spawnNewSession();
|
|
77
|
+
const accountInNewSession = await session2.node.load(session1.accountID);
|
|
78
|
+
if (accountInNewSession === "unavailable")
|
|
86
79
|
throw new Error("Account unavailable");
|
|
87
|
-
expect(
|
|
88
|
-
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
});
|
|
93
|
-
node.syncManager.addPeer(peers2[1]);
|
|
94
|
-
const node3 = await LocalNode.withLoadedAccount({
|
|
95
|
-
accountID,
|
|
96
|
-
accountSecret,
|
|
97
|
-
sessionID: Crypto.newRandomSessionID(accountID),
|
|
98
|
-
peers: [peers2[0]],
|
|
99
|
-
crypto: Crypto,
|
|
100
|
-
});
|
|
101
|
-
const account3 = await node3.load(accountID);
|
|
102
|
-
if (account3 === "unavailable")
|
|
80
|
+
expect(accountInNewSession.getRaw("root")?.trusting).toEqual(true);
|
|
81
|
+
await accountInNewSession.core.waitForSync();
|
|
82
|
+
const session3 = await session2.spawnNewSession();
|
|
83
|
+
const accountInNewSession2 = await session3.node.load(session1.accountID);
|
|
84
|
+
if (accountInNewSession2 === "unavailable")
|
|
103
85
|
throw new Error("Account unavailable");
|
|
104
|
-
expect(
|
|
105
|
-
expect(
|
|
86
|
+
expect(accountInNewSession2.getRaw("root")?.trusting).toEqual(true);
|
|
87
|
+
expect(accountInNewSession2.ops).toEqual(accountInNewSession.ops); // No new transactions were made
|
|
106
88
|
});
|
|
107
89
|
test("myRole returns 'admin' for the current account", async () => {
|
|
108
90
|
const { node, accountID } = await LocalNode.withNewlyCreatedAccount({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account.test.js","sourceRoot":"","sources":["../../src/tests/account.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"account.test.js","sourceRoot":"","sources":["../../src/tests/account.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group.parentGroupCache.test.d.ts","sourceRoot":"","sources":["../../src/tests/group.parentGroupCache.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, test } from "vitest";
|
|
2
|
+
import { setupTestAccount, setupTestNode, hotSleep, loadCoValueOrFail, } from "./testUtils";
|
|
3
|
+
let jazzCloud;
|
|
4
|
+
beforeEach(async () => {
|
|
5
|
+
jazzCloud = setupTestNode({ isSyncServer: true });
|
|
6
|
+
});
|
|
7
|
+
describe("Parent Group Cache", () => {
|
|
8
|
+
describe("Property 1: Parent group cache update correctness", () => {
|
|
9
|
+
test("cache contains correct entries after processing parent group reference transactions", async () => {
|
|
10
|
+
const account = await setupTestAccount({
|
|
11
|
+
connected: true,
|
|
12
|
+
});
|
|
13
|
+
const parentGroup = account.node.createGroup();
|
|
14
|
+
const childGroup = account.node.createGroup();
|
|
15
|
+
// Initially no parent groups
|
|
16
|
+
expect(childGroup.getParentGroups()).toEqual([]);
|
|
17
|
+
// Extend parent group
|
|
18
|
+
childGroup.extend(parentGroup);
|
|
19
|
+
expect(childGroup.getParentGroups()).toEqual([parentGroup]);
|
|
20
|
+
});
|
|
21
|
+
test("cache handles multiple updates to same parent group", async () => {
|
|
22
|
+
const account = await setupTestAccount({
|
|
23
|
+
connected: true,
|
|
24
|
+
});
|
|
25
|
+
const parentGroup = account.node.createGroup();
|
|
26
|
+
const childGroup = account.node.createGroup();
|
|
27
|
+
childGroup.extend(parentGroup);
|
|
28
|
+
expect(childGroup.getParentGroups()).toEqual([parentGroup]);
|
|
29
|
+
// Revoke and re-extend
|
|
30
|
+
childGroup.revokeExtend(parentGroup);
|
|
31
|
+
expect(childGroup.getParentGroups()).toEqual([]);
|
|
32
|
+
childGroup.extend(parentGroup, "admin");
|
|
33
|
+
expect(childGroup.getParentGroups()).toEqual([parentGroup]);
|
|
34
|
+
});
|
|
35
|
+
test("cache correctly handles empty state (no parent groups)", async () => {
|
|
36
|
+
const account = await setupTestAccount({
|
|
37
|
+
connected: true,
|
|
38
|
+
});
|
|
39
|
+
const group = account.node.createGroup();
|
|
40
|
+
expect(group.getParentGroups()).toEqual([]);
|
|
41
|
+
});
|
|
42
|
+
test("cache only contains parent groups that have reference transactions", async () => {
|
|
43
|
+
const account = await setupTestAccount({
|
|
44
|
+
connected: true,
|
|
45
|
+
});
|
|
46
|
+
const parentGroup1 = account.node.createGroup();
|
|
47
|
+
const parentGroup2 = account.node.createGroup();
|
|
48
|
+
const childGroup = account.node.createGroup();
|
|
49
|
+
// Only extend one parent group
|
|
50
|
+
childGroup.extend(parentGroup1);
|
|
51
|
+
const parentGroups = childGroup.getParentGroups();
|
|
52
|
+
expect(parentGroups).toHaveLength(1);
|
|
53
|
+
expect(parentGroups[0]?.id).toEqual(parentGroup1.id);
|
|
54
|
+
});
|
|
55
|
+
test("cache handles multiple parent groups", async () => {
|
|
56
|
+
const account = await setupTestAccount({
|
|
57
|
+
connected: true,
|
|
58
|
+
});
|
|
59
|
+
const parentGroup1 = account.node.createGroup();
|
|
60
|
+
const parentGroup2 = account.node.createGroup();
|
|
61
|
+
const parentGroup3 = account.node.createGroup();
|
|
62
|
+
const childGroup = account.node.createGroup();
|
|
63
|
+
childGroup.extend(parentGroup1);
|
|
64
|
+
childGroup.extend(parentGroup2);
|
|
65
|
+
childGroup.extend(parentGroup3);
|
|
66
|
+
const parentGroups = childGroup.getParentGroups();
|
|
67
|
+
expect(parentGroups).toHaveLength(3);
|
|
68
|
+
expect(parentGroups.map((g) => g.id).sort()).toEqual([parentGroup1.id, parentGroup2.id, parentGroup3.id].sort());
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
describe("Property 2: Parent group cache chronological ordering", () => {
|
|
72
|
+
test("multiple parent group changes are stored in chronological order", async () => {
|
|
73
|
+
const account = await setupTestAccount({
|
|
74
|
+
connected: true,
|
|
75
|
+
});
|
|
76
|
+
const parentGroup = account.node.createGroup();
|
|
77
|
+
const childGroup = account.node.createGroup();
|
|
78
|
+
const t1 = hotSleep(10);
|
|
79
|
+
childGroup.extend(parentGroup, "reader");
|
|
80
|
+
const t2 = hotSleep(10);
|
|
81
|
+
childGroup.extend(parentGroup, "writer");
|
|
82
|
+
const t3 = hotSleep(10);
|
|
83
|
+
childGroup.extend(parentGroup, "admin");
|
|
84
|
+
// Check time travel queries return correct historical states
|
|
85
|
+
expect(childGroup.atTime(t1).getParentGroups()).toEqual([]);
|
|
86
|
+
expect(childGroup.atTime(t2).getParentGroups()).toEqual([
|
|
87
|
+
parentGroup.atTime(t2),
|
|
88
|
+
]);
|
|
89
|
+
expect(childGroup.atTime(t3).getParentGroups()).toEqual([
|
|
90
|
+
parentGroup.atTime(t3),
|
|
91
|
+
]);
|
|
92
|
+
// Current state should have admin role
|
|
93
|
+
expect(childGroup.getParentGroups()).toEqual([parentGroup]);
|
|
94
|
+
});
|
|
95
|
+
test("out-of-order transaction processing maintains chronological order", async () => {
|
|
96
|
+
const account = await setupTestAccount({
|
|
97
|
+
connected: true,
|
|
98
|
+
});
|
|
99
|
+
const parentGroup = account.node.createGroup();
|
|
100
|
+
const childGroup = account.node.createGroup();
|
|
101
|
+
// Create transactions with different timestamps
|
|
102
|
+
const t1 = hotSleep(10);
|
|
103
|
+
const t2 = hotSleep(10);
|
|
104
|
+
childGroup.core.makeTransaction([
|
|
105
|
+
{
|
|
106
|
+
op: "set",
|
|
107
|
+
key: `parent_${parentGroup.id}`,
|
|
108
|
+
value: "revoked",
|
|
109
|
+
},
|
|
110
|
+
], "private", undefined, t2);
|
|
111
|
+
childGroup.core.makeTransaction([
|
|
112
|
+
{
|
|
113
|
+
op: "set",
|
|
114
|
+
key: `parent_${parentGroup.id}`,
|
|
115
|
+
value: "extend",
|
|
116
|
+
},
|
|
117
|
+
], "private", undefined, t1);
|
|
118
|
+
// Verify chronological ordering through time travel
|
|
119
|
+
const groupAtT1 = childGroup.atTime(t1);
|
|
120
|
+
const groupAtT2 = childGroup.atTime(t2);
|
|
121
|
+
expect(groupAtT1.getParentGroups()).toEqual([parentGroup.atTime(t1)]);
|
|
122
|
+
expect(groupAtT2.getParentGroups()).toEqual([]);
|
|
123
|
+
});
|
|
124
|
+
test("chronological ordering after rebuild", async () => {
|
|
125
|
+
const account = await setupTestAccount({
|
|
126
|
+
connected: true,
|
|
127
|
+
});
|
|
128
|
+
const parentGroup = account.node.createGroup();
|
|
129
|
+
const childGroup = account.node.createGroup();
|
|
130
|
+
const t1 = hotSleep(10);
|
|
131
|
+
childGroup.extend(parentGroup, "reader");
|
|
132
|
+
const t2 = hotSleep(10);
|
|
133
|
+
childGroup.extend(parentGroup, "writer");
|
|
134
|
+
// Rebuild should maintain chronological order
|
|
135
|
+
childGroup.rebuildFromCore();
|
|
136
|
+
const groupAtT1 = childGroup.atTime(t1);
|
|
137
|
+
const groupAtT2 = childGroup.atTime(t2);
|
|
138
|
+
expect(groupAtT1.getParentGroups()).toEqual([]);
|
|
139
|
+
expect(groupAtT2.getParentGroups()).toEqual([parentGroup.atTime(t2)]);
|
|
140
|
+
expect(childGroup.getParentGroups()).toEqual([parentGroup]);
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
describe("Property 3: Rebuild round-trip", () => {
|
|
144
|
+
test("cache is cleared after rebuildFromCore", async () => {
|
|
145
|
+
const account = await setupTestAccount({
|
|
146
|
+
connected: true,
|
|
147
|
+
});
|
|
148
|
+
const parentGroup = account.node.createGroup();
|
|
149
|
+
const childGroup = account.node.createGroup();
|
|
150
|
+
childGroup.extend(parentGroup);
|
|
151
|
+
expect(childGroup.getParentGroups()).toEqual([parentGroup]);
|
|
152
|
+
// Rebuild should clear cache and rebuild it
|
|
153
|
+
childGroup.rebuildFromCore();
|
|
154
|
+
// Cache should be rebuilt and still work
|
|
155
|
+
expect(childGroup.getParentGroups()).toEqual([parentGroup]);
|
|
156
|
+
});
|
|
157
|
+
test("cache is rebuilt correctly after clear", async () => {
|
|
158
|
+
const account = await setupTestAccount({
|
|
159
|
+
connected: true,
|
|
160
|
+
});
|
|
161
|
+
const parentGroup1 = account.node.createGroup();
|
|
162
|
+
const parentGroup2 = account.node.createGroup();
|
|
163
|
+
const childGroup = account.node.createGroup();
|
|
164
|
+
childGroup.extend(parentGroup1);
|
|
165
|
+
childGroup.extend(parentGroup2);
|
|
166
|
+
expect(childGroup.getParentGroups()).toHaveLength(2);
|
|
167
|
+
// Rebuild
|
|
168
|
+
childGroup.rebuildFromCore();
|
|
169
|
+
// Cache should be rebuilt with all parent groups
|
|
170
|
+
const parentGroups = childGroup.getParentGroups();
|
|
171
|
+
expect(parentGroups).toHaveLength(2);
|
|
172
|
+
expect(parentGroups.map((g) => g.id).sort()).toEqual([parentGroup1.id, parentGroup2.id].sort());
|
|
173
|
+
});
|
|
174
|
+
test("parent group lookups work correctly after rebuild", async () => {
|
|
175
|
+
const alice = await setupTestAccount({
|
|
176
|
+
connected: true,
|
|
177
|
+
});
|
|
178
|
+
const bob = await setupTestAccount({
|
|
179
|
+
connected: true,
|
|
180
|
+
});
|
|
181
|
+
const parentGroup = alice.node.createGroup();
|
|
182
|
+
const childGroup = alice.node.createGroup();
|
|
183
|
+
parentGroup.addMember(await loadCoValueOrFail(alice.node, bob.accountID), "writer");
|
|
184
|
+
childGroup.extend(parentGroup);
|
|
185
|
+
// Check role inheritance before rebuild
|
|
186
|
+
expect(childGroup.roleOf(bob.accountID)).toEqual("writer");
|
|
187
|
+
// Rebuild
|
|
188
|
+
childGroup.rebuildFromCore();
|
|
189
|
+
// Role inheritance should still work after rebuild
|
|
190
|
+
expect(childGroup.roleOf(bob.accountID)).toEqual("writer");
|
|
191
|
+
expect(childGroup.getParentGroups()).toEqual([parentGroup]);
|
|
192
|
+
});
|
|
193
|
+
test("rebuild maintains chronological ordering", async () => {
|
|
194
|
+
const alice = await setupTestAccount({
|
|
195
|
+
connected: true,
|
|
196
|
+
});
|
|
197
|
+
const bob = await setupTestAccount({
|
|
198
|
+
connected: true,
|
|
199
|
+
});
|
|
200
|
+
const parentGroup = alice.node.createGroup();
|
|
201
|
+
const childGroup = alice.node.createGroup();
|
|
202
|
+
parentGroup.addMember(await loadCoValueOrFail(alice.node, bob.accountID), "writer");
|
|
203
|
+
const t1 = hotSleep(10);
|
|
204
|
+
childGroup.extend(parentGroup, "reader");
|
|
205
|
+
const t2 = hotSleep(10);
|
|
206
|
+
childGroup.extend(parentGroup, "writer");
|
|
207
|
+
// Rebuild
|
|
208
|
+
childGroup.rebuildFromCore();
|
|
209
|
+
// Chronological ordering should be maintained
|
|
210
|
+
expect(childGroup.atTime(t1).roleOf(bob.accountID)).toEqual(undefined);
|
|
211
|
+
expect(childGroup.atTime(t2).roleOf(bob.accountID)).toEqual("reader");
|
|
212
|
+
expect(childGroup.atTime(Date.now()).roleOf(bob.accountID)).toEqual("writer");
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
//# sourceMappingURL=group.parentGroupCache.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group.parentGroupCache.test.js","sourceRoot":"","sources":["../../src/tests/group.parentGroupCache.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"type": "module",
|
|
35
35
|
"license": "MIT",
|
|
36
|
-
"version": "0.19.
|
|
36
|
+
"version": "0.19.6",
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@opentelemetry/sdk-metrics": "^2.0.0",
|
|
39
39
|
"libsql": "^0.5.13",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"@opentelemetry/api": "^1.9.0",
|
|
47
47
|
"@scure/base": "1.2.1",
|
|
48
48
|
"unicode-segmenter": "^0.12.0",
|
|
49
|
-
"cojson-core-wasm": "0.19.
|
|
50
|
-
"cojson-core-napi": "0.19.
|
|
49
|
+
"cojson-core-wasm": "0.19.6",
|
|
50
|
+
"cojson-core-napi": "0.19.6"
|
|
51
51
|
},
|
|
52
52
|
"gitHead": "33c27053293b4801b968c61d5c4c989f93a67d13",
|
|
53
53
|
"scripts": {
|
package/src/coValues/coMap.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { CoID, RawCoValue } from "../coValue.js";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
AvailableCoValueCore,
|
|
4
|
+
DecryptedTransaction,
|
|
5
|
+
} from "../coValueCore/coValueCore.js";
|
|
3
6
|
import { AgentID, RawCoID, TransactionID } from "../ids.js";
|
|
4
7
|
import { JsonObject, JsonValue } from "../jsonValue.js";
|
|
5
8
|
import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfromSessionID.js";
|
|
@@ -64,7 +67,7 @@ export class RawCoMap<
|
|
|
64
67
|
totalValidTransactions: number = 0;
|
|
65
68
|
version: number = 0;
|
|
66
69
|
|
|
67
|
-
|
|
70
|
+
protected resetInternalState() {
|
|
68
71
|
this.ops = {};
|
|
69
72
|
this.latest = {};
|
|
70
73
|
this.knownTransactions = { [this.core.id]: 0 };
|
|
@@ -115,7 +118,8 @@ export class RawCoMap<
|
|
|
115
118
|
NonNullable<(typeof ops)[keyof typeof ops]>
|
|
116
119
|
>();
|
|
117
120
|
|
|
118
|
-
for (const
|
|
121
|
+
for (const transaction of newValidTransactions) {
|
|
122
|
+
const { txID, changes, madeAt, tx } = transaction;
|
|
119
123
|
for (let changeIdx = 0; changeIdx < changes.length; changeIdx++) {
|
|
120
124
|
const change = changes[changeIdx] as MapOpPayload<
|
|
121
125
|
keyof Shape & string,
|
|
@@ -139,6 +143,8 @@ export class RawCoMap<
|
|
|
139
143
|
changedEntries.set(change.key, entries);
|
|
140
144
|
}
|
|
141
145
|
}
|
|
146
|
+
|
|
147
|
+
this.handleNewTransaction(transaction);
|
|
142
148
|
}
|
|
143
149
|
|
|
144
150
|
for (const entries of changedEntries.values()) {
|
|
@@ -152,6 +158,8 @@ export class RawCoMap<
|
|
|
152
158
|
this.totalValidTransactions += newValidTransactions.length;
|
|
153
159
|
}
|
|
154
160
|
|
|
161
|
+
handleNewTransaction(transaction: DecryptedTransaction) {}
|
|
162
|
+
|
|
155
163
|
rebuildFromCore() {
|
|
156
164
|
this.version += 1;
|
|
157
165
|
|
|
@@ -175,16 +183,12 @@ export class RawCoMap<
|
|
|
175
183
|
|
|
176
184
|
/** @category 4. Time travel */
|
|
177
185
|
atTime(time: number): this {
|
|
178
|
-
|
|
179
|
-
return this;
|
|
180
|
-
} else {
|
|
181
|
-
const clone = Object.create(this) as RawCoMap<Shape, Meta>;
|
|
186
|
+
const clone = Object.create(this) as RawCoMap<Shape, Meta>;
|
|
182
187
|
|
|
183
|
-
|
|
184
|
-
|
|
188
|
+
clone.atTimeFilter = time;
|
|
189
|
+
clone.latest = {};
|
|
185
190
|
|
|
186
|
-
|
|
187
|
-
}
|
|
191
|
+
return clone as this;
|
|
188
192
|
}
|
|
189
193
|
|
|
190
194
|
/** @internal */
|
package/src/coValues/group.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { CoID } from "../coValue.js";
|
|
|
3
3
|
import type {
|
|
4
4
|
AvailableCoValueCore,
|
|
5
5
|
CoValueCore,
|
|
6
|
+
DecryptedTransaction,
|
|
6
7
|
} from "../coValueCore/coValueCore.js";
|
|
7
8
|
import type { CoValueUniqueness } from "../coValueCore/verifiedState.js";
|
|
8
9
|
import type {
|
|
@@ -161,6 +162,40 @@ function rotateReadKeyIfNeeded(group: RawGroup) {
|
|
|
161
162
|
}
|
|
162
163
|
}
|
|
163
164
|
|
|
165
|
+
class TimeBasedEntry<T> {
|
|
166
|
+
changes: { madeAt: number; value: T }[] = [];
|
|
167
|
+
|
|
168
|
+
addChange(madeAt: number, value: T) {
|
|
169
|
+
const changes = this.changes;
|
|
170
|
+
const newChange = { madeAt, value };
|
|
171
|
+
// Insert the change in chronological order
|
|
172
|
+
// Find the correct position by searching backwards from the end
|
|
173
|
+
let insertIndex = changes.length;
|
|
174
|
+
while (insertIndex > 0 && changes[insertIndex - 1]!.madeAt > madeAt) {
|
|
175
|
+
insertIndex--;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Insert at the correct position to maintain chronological order
|
|
179
|
+
if (insertIndex === changes.length) {
|
|
180
|
+
changes.push(newChange);
|
|
181
|
+
} else {
|
|
182
|
+
changes.splice(insertIndex, 0, newChange);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
getLatest() {
|
|
187
|
+
return this.changes[this.changes.length - 1]?.value;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
getAtTime(atTime?: number) {
|
|
191
|
+
if (atTime === undefined) {
|
|
192
|
+
return this.getLatest();
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return this.changes.findLast((change) => change.madeAt <= atTime)?.value;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
164
199
|
/** A `Group` is a scope for permissions of its members (`"reader" | "writer" | "admin"`), applying to objects owned by that group.
|
|
165
200
|
*
|
|
166
201
|
* A `Group` object exposes methods for permission management and allows you to create new CoValues owned by that group.
|
|
@@ -189,6 +224,19 @@ export class RawGroup<
|
|
|
189
224
|
|
|
190
225
|
_lastReadableKeyId?: KeyID;
|
|
191
226
|
|
|
227
|
+
// Not using class field initializers because they run after that the CoMap constructor
|
|
228
|
+
// calls processNewTransactions, which would reset the parentGroupsChanges map
|
|
229
|
+
private declare parentGroupsChanges: Map<
|
|
230
|
+
CoID<RawGroup>,
|
|
231
|
+
TimeBasedEntry<ParentGroupReferenceRole>
|
|
232
|
+
>;
|
|
233
|
+
|
|
234
|
+
protected resetInternalState() {
|
|
235
|
+
super.resetInternalState();
|
|
236
|
+
this.parentGroupsChanges = new Map();
|
|
237
|
+
this._lastReadableKeyId = undefined;
|
|
238
|
+
}
|
|
239
|
+
|
|
192
240
|
constructor(
|
|
193
241
|
core: AvailableCoValueCore,
|
|
194
242
|
options?: {
|
|
@@ -200,6 +248,45 @@ export class RawGroup<
|
|
|
200
248
|
this.migrate();
|
|
201
249
|
}
|
|
202
250
|
|
|
251
|
+
// We override the handleNewTransaction hook from CoMap to build the parent group cache
|
|
252
|
+
override handleNewTransaction(transaction: DecryptedTransaction): void {
|
|
253
|
+
if (!this.parentGroupsChanges) {
|
|
254
|
+
this.parentGroupsChanges = new Map();
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Build parent group cache incrementally
|
|
258
|
+
for (const changeValue of transaction.changes) {
|
|
259
|
+
const change = changeValue as {
|
|
260
|
+
op: "set" | "del";
|
|
261
|
+
key: string;
|
|
262
|
+
value?: any;
|
|
263
|
+
};
|
|
264
|
+
if (change.op === "set" && isParentGroupReference(change.key)) {
|
|
265
|
+
this.updateParentGroupCache(
|
|
266
|
+
change.key,
|
|
267
|
+
change.value as ParentGroupReferenceRole,
|
|
268
|
+
transaction.madeAt,
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
private updateParentGroupCache(
|
|
275
|
+
key: string,
|
|
276
|
+
value: any,
|
|
277
|
+
timestamp: number,
|
|
278
|
+
): void {
|
|
279
|
+
const parentGroupId = key.substring(7) as CoID<RawGroup>; // Remove 'parent_' prefix
|
|
280
|
+
|
|
281
|
+
let entry = this.parentGroupsChanges.get(parentGroupId);
|
|
282
|
+
if (!entry) {
|
|
283
|
+
entry = new TimeBasedEntry<ParentGroupReferenceRole>();
|
|
284
|
+
this.parentGroupsChanges.set(parentGroupId, entry);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
entry.addChange(timestamp, value as ParentGroupReferenceRole);
|
|
288
|
+
}
|
|
289
|
+
|
|
203
290
|
migrate() {
|
|
204
291
|
if (!this.core.isGroup()) {
|
|
205
292
|
return;
|
|
@@ -247,15 +334,13 @@ export class RawGroup<
|
|
|
247
334
|
|
|
248
335
|
let roleInfo: Role | undefined = roleHere;
|
|
249
336
|
|
|
250
|
-
for (const
|
|
251
|
-
|
|
337
|
+
for (const [parentGroupId, entry] of this.parentGroupsChanges.entries()) {
|
|
338
|
+
const role = entry.getAtTime(this.atTimeFilter);
|
|
252
339
|
|
|
253
|
-
|
|
340
|
+
if (!role || role === "revoked") continue;
|
|
254
341
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
const role = this.get(key) ?? "extend";
|
|
258
|
-
const parentRole = group.roleOfInternal(accountID);
|
|
342
|
+
const parentGroup = this.getParentGroup(parentGroupId, this.atTimeFilter);
|
|
343
|
+
const parentRole = parentGroup.roleOfInternal(accountID);
|
|
259
344
|
|
|
260
345
|
if (!isInheritableRole(parentRole)) {
|
|
261
346
|
continue;
|
|
@@ -277,13 +362,9 @@ export class RawGroup<
|
|
|
277
362
|
return roleInfo;
|
|
278
363
|
}
|
|
279
364
|
|
|
280
|
-
|
|
281
|
-
if (this.get(key) === "revoked") {
|
|
282
|
-
return null;
|
|
283
|
-
}
|
|
284
|
-
|
|
365
|
+
getParentGroup(id: CoID<RawGroup>, atTime?: number) {
|
|
285
366
|
const parent = this.core.node.expectCoValueLoaded(
|
|
286
|
-
|
|
367
|
+
id,
|
|
287
368
|
"Expected parent group to be loaded",
|
|
288
369
|
);
|
|
289
370
|
|
|
@@ -296,21 +377,15 @@ export class RawGroup<
|
|
|
296
377
|
}
|
|
297
378
|
}
|
|
298
379
|
|
|
299
|
-
getParentGroups(
|
|
380
|
+
getParentGroups() {
|
|
300
381
|
const groups: RawGroup[] = [];
|
|
301
382
|
|
|
302
|
-
for (const
|
|
303
|
-
|
|
383
|
+
for (const [parentGroupId, entry] of this.parentGroupsChanges.entries()) {
|
|
384
|
+
const role = entry.getAtTime(this.atTimeFilter);
|
|
304
385
|
|
|
305
|
-
|
|
386
|
+
if (!role || role === "revoked") continue;
|
|
306
387
|
|
|
307
|
-
|
|
308
|
-
if (atTime) {
|
|
309
|
-
groups.push(group.atTime(atTime));
|
|
310
|
-
} else {
|
|
311
|
-
groups.push(group);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
388
|
+
groups.push(this.getParentGroup(parentGroupId, this.atTimeFilter));
|
|
314
389
|
}
|
|
315
390
|
|
|
316
391
|
return groups;
|