cojson 0.0.21 → 0.0.22
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/dist/account.d.ts +1 -1
- package/dist/account.js +1 -1
- package/dist/account.js.map +1 -1
- package/dist/coValue.d.ts +3 -2
- package/dist/coValue.js +10 -9
- package/dist/coValue.js.map +1 -1
- package/dist/contentTypes/coMap.d.ts +2 -2
- package/dist/contentTypes/coMap.js +6 -6
- package/dist/contentTypes/coMap.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +2 -1
- package/dist/node.js +43 -3
- package/dist/node.js.map +1 -1
- package/dist/permissions.d.ts +4 -32
- package/dist/permissions.js +42 -106
- package/dist/permissions.js.map +1 -1
- package/dist/team.d.ts +35 -0
- package/dist/team.js +110 -0
- package/dist/team.js.map +1 -0
- package/dist/testUtils.d.ts +2 -2
- package/dist/testUtils.js +1 -1
- package/dist/testUtils.js.map +1 -1
- package/package.json +2 -2
- package/src/account.ts +1 -1
- package/src/coValue.ts +10 -11
- package/src/contentTypes/coMap.ts +8 -8
- package/src/crypto.test.ts +10 -9
- package/src/index.ts +5 -0
- package/src/node.ts +113 -11
- package/src/permissions.test.ts +503 -3
- package/src/permissions.ts +70 -206
- package/src/sync.test.ts +8 -8
- package/src/team.ts +225 -0
- package/src/testUtils.ts +1 -1
- package/tsconfig.json +1 -0
- package/dist/account.test.d.ts +0 -1
- package/dist/account.test.js +0 -40
- package/dist/account.test.js.map +0 -1
- package/dist/coValue.test.d.ts +0 -1
- package/dist/coValue.test.js +0 -78
- package/dist/coValue.test.js.map +0 -1
- package/dist/contentType.test.d.ts +0 -1
- package/dist/contentType.test.js +0 -145
- package/dist/contentType.test.js.map +0 -1
- package/dist/crypto.test.d.ts +0 -1
- package/dist/crypto.test.js +0 -111
- package/dist/crypto.test.js.map +0 -1
- package/dist/permissions.test.d.ts +0 -1
- package/dist/permissions.test.js +0 -711
- package/dist/permissions.test.js.map +0 -1
- package/dist/sync.test.d.ts +0 -1
- package/dist/sync.test.js +0 -827
- package/dist/sync.test.js.map +0 -1
package/dist/permissions.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { createdNowUnique, newRandomKeySecret, seal, encryptKeySecret, getAgentSealerID, } from "./crypto.js";
|
|
2
1
|
import { accountOrAgentIDfromSessionID, } from "./coValue.js";
|
|
3
|
-
import { isAgentID } from "./ids.js";
|
|
4
2
|
export function determineValidTransactions(coValue) {
|
|
5
3
|
if (coValue.header.ruleset.type === "team") {
|
|
6
4
|
const allTrustingTransactionsSorted = Object.entries(coValue.sessions).flatMap(([sessionID, sessionLog]) => {
|
|
@@ -33,7 +31,7 @@ export function determineValidTransactions(coValue) {
|
|
|
33
31
|
console.warn("Team transaction must have exactly one change");
|
|
34
32
|
continue;
|
|
35
33
|
}
|
|
36
|
-
if (change.op !== "
|
|
34
|
+
if (change.op !== "set") {
|
|
37
35
|
console.warn("Team transaction must set a role or readKey");
|
|
38
36
|
continue;
|
|
39
37
|
}
|
|
@@ -45,7 +43,7 @@ export function determineValidTransactions(coValue) {
|
|
|
45
43
|
validTransactions.push({ txID: { sessionID, txIndex }, tx });
|
|
46
44
|
continue;
|
|
47
45
|
}
|
|
48
|
-
else if (change.key ===
|
|
46
|
+
else if (change.key === "profile") {
|
|
49
47
|
if (memberState[transactor] !== "admin") {
|
|
50
48
|
console.warn("Only admins can set profile");
|
|
51
49
|
continue;
|
|
@@ -53,8 +51,12 @@ export function determineValidTransactions(coValue) {
|
|
|
53
51
|
validTransactions.push({ txID: { sessionID, txIndex }, tx });
|
|
54
52
|
continue;
|
|
55
53
|
}
|
|
56
|
-
else if (isKeyForKeyField(change.key) ||
|
|
57
|
-
|
|
54
|
+
else if (isKeyForKeyField(change.key) ||
|
|
55
|
+
isKeyForAccountField(change.key)) {
|
|
56
|
+
if (memberState[transactor] !== "admin" &&
|
|
57
|
+
memberState[transactor] !== "adminInvite" &&
|
|
58
|
+
memberState[transactor] !== "writerInvite" &&
|
|
59
|
+
memberState[transactor] !== "readerInvite") {
|
|
58
60
|
console.warn("Only admins can reveal keys");
|
|
59
61
|
continue;
|
|
60
62
|
}
|
|
@@ -67,24 +69,47 @@ export function determineValidTransactions(coValue) {
|
|
|
67
69
|
if (change.value !== "admin" &&
|
|
68
70
|
change.value !== "writer" &&
|
|
69
71
|
change.value !== "reader" &&
|
|
70
|
-
change.value !== "revoked"
|
|
72
|
+
change.value !== "revoked" &&
|
|
73
|
+
change.value !== "adminInvite" &&
|
|
74
|
+
change.value !== "writerInvite" &&
|
|
75
|
+
change.value !== "readerInvite") {
|
|
71
76
|
console.warn("Team transaction must set a valid role");
|
|
72
77
|
continue;
|
|
73
78
|
}
|
|
74
79
|
const isFirstSelfAppointment = !memberState[transactor] &&
|
|
75
80
|
transactor === initialAdmin &&
|
|
76
|
-
change.op === "
|
|
81
|
+
change.op === "set" &&
|
|
77
82
|
change.key === transactor &&
|
|
78
83
|
change.value === "admin";
|
|
79
84
|
if (!isFirstSelfAppointment) {
|
|
80
|
-
if (memberState[transactor]
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
if (memberState[transactor] === "admin") {
|
|
86
|
+
if (memberState[affectedMember] === "admin" &&
|
|
87
|
+
affectedMember !== transactor &&
|
|
88
|
+
assignedRole !== "admin") {
|
|
89
|
+
console.warn("Admins can only demote themselves.");
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else if (memberState[transactor] === "adminInvite") {
|
|
94
|
+
if (change.value !== "admin") {
|
|
95
|
+
console.warn("AdminInvites can only create admins.");
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
83
98
|
}
|
|
84
|
-
if (memberState[
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
99
|
+
else if (memberState[transactor] === "writerInvite") {
|
|
100
|
+
if (change.value !== "writer") {
|
|
101
|
+
console.warn("WriterInvites can only create writers.");
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else if (memberState[transactor] === "readerInvite") {
|
|
106
|
+
if (change.value !== "reader") {
|
|
107
|
+
console.warn("ReaderInvites can only create reader.");
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
console.warn("Team transaction must be made by current admin or invite");
|
|
88
113
|
continue;
|
|
89
114
|
}
|
|
90
115
|
}
|
|
@@ -127,100 +152,11 @@ export function determineValidTransactions(coValue) {
|
|
|
127
152
|
throw new Error("Unknown ruleset type " + coValue.header.ruleset.type);
|
|
128
153
|
}
|
|
129
154
|
}
|
|
130
|
-
export function expectTeamContent(content) {
|
|
131
|
-
if (content.type !== "comap") {
|
|
132
|
-
throw new Error("Expected map");
|
|
133
|
-
}
|
|
134
|
-
return content;
|
|
135
|
-
}
|
|
136
|
-
export class Team {
|
|
137
|
-
constructor(teamMap, node) {
|
|
138
|
-
this.teamMap = teamMap;
|
|
139
|
-
this.node = node;
|
|
140
|
-
}
|
|
141
|
-
get id() {
|
|
142
|
-
return this.teamMap.id;
|
|
143
|
-
}
|
|
144
|
-
addMember(accountID, role) {
|
|
145
|
-
this.teamMap = this.teamMap.edit((map) => {
|
|
146
|
-
const currentReadKey = this.teamMap.coValue.getCurrentReadKey();
|
|
147
|
-
if (!currentReadKey.secret) {
|
|
148
|
-
throw new Error("Can't add member without read key secret");
|
|
149
|
-
}
|
|
150
|
-
const agent = this.node.resolveAccountAgent(accountID, "Expected to know agent to add them to team");
|
|
151
|
-
map.set(accountID, role, "trusting");
|
|
152
|
-
if (map.get(accountID) !== role) {
|
|
153
|
-
throw new Error("Failed to set role");
|
|
154
|
-
}
|
|
155
|
-
map.set(`${currentReadKey.id}_for_${accountID}`, seal(currentReadKey.secret, this.teamMap.coValue.node.account.currentSealerSecret(), getAgentSealerID(agent), {
|
|
156
|
-
in: this.teamMap.coValue.id,
|
|
157
|
-
tx: this.teamMap.coValue.nextTransactionID(),
|
|
158
|
-
}), "trusting");
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
rotateReadKey() {
|
|
162
|
-
const currentlyPermittedReaders = this.teamMap.keys().filter((key) => {
|
|
163
|
-
if (key.startsWith("co_") || isAgentID(key)) {
|
|
164
|
-
const role = this.teamMap.get(key);
|
|
165
|
-
return (role === "admin" || role === "writer" || role === "reader");
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
return false;
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
const maybeCurrentReadKey = this.teamMap.coValue.getCurrentReadKey();
|
|
172
|
-
if (!maybeCurrentReadKey.secret) {
|
|
173
|
-
throw new Error("Can't rotate read key secret we don't have access to");
|
|
174
|
-
}
|
|
175
|
-
const currentReadKey = {
|
|
176
|
-
id: maybeCurrentReadKey.id,
|
|
177
|
-
secret: maybeCurrentReadKey.secret,
|
|
178
|
-
};
|
|
179
|
-
const newReadKey = newRandomKeySecret();
|
|
180
|
-
this.teamMap = this.teamMap.edit((map) => {
|
|
181
|
-
for (const readerID of currentlyPermittedReaders) {
|
|
182
|
-
const reader = this.node.resolveAccountAgent(readerID, "Expected to know currently permitted reader");
|
|
183
|
-
map.set(`${newReadKey.id}_for_${readerID}`, seal(newReadKey.secret, this.teamMap.coValue.node.account.currentSealerSecret(), getAgentSealerID(reader), {
|
|
184
|
-
in: this.teamMap.coValue.id,
|
|
185
|
-
tx: this.teamMap.coValue.nextTransactionID(),
|
|
186
|
-
}), "trusting");
|
|
187
|
-
}
|
|
188
|
-
map.set(`${currentReadKey.id}_for_${newReadKey.id}`, encryptKeySecret({
|
|
189
|
-
encrypting: newReadKey,
|
|
190
|
-
toEncrypt: currentReadKey,
|
|
191
|
-
}).encrypted, "trusting");
|
|
192
|
-
map.set("readKey", newReadKey.id, "trusting");
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
removeMember(accountID) {
|
|
196
|
-
this.teamMap = this.teamMap.edit((map) => {
|
|
197
|
-
map.set(accountID, "revoked", "trusting");
|
|
198
|
-
});
|
|
199
|
-
this.rotateReadKey();
|
|
200
|
-
}
|
|
201
|
-
createMap(meta) {
|
|
202
|
-
return this.node
|
|
203
|
-
.createCoValue({
|
|
204
|
-
type: "comap",
|
|
205
|
-
ruleset: {
|
|
206
|
-
type: "ownedByTeam",
|
|
207
|
-
team: this.teamMap.id,
|
|
208
|
-
},
|
|
209
|
-
meta: meta || null,
|
|
210
|
-
...createdNowUnique(),
|
|
211
|
-
})
|
|
212
|
-
.getCurrentContent();
|
|
213
|
-
}
|
|
214
|
-
testWithDifferentAccount(account, sessionId) {
|
|
215
|
-
return new Team(expectTeamContent(this.teamMap.coValue
|
|
216
|
-
.testWithDifferentAccount(account, sessionId)
|
|
217
|
-
.getCurrentContent()), this.node);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
155
|
export function isKeyForKeyField(field) {
|
|
221
156
|
return field.startsWith("key_") && field.includes("_for_key");
|
|
222
157
|
}
|
|
223
158
|
export function isKeyForAccountField(field) {
|
|
224
|
-
return field.startsWith("key_") &&
|
|
159
|
+
return (field.startsWith("key_") &&
|
|
160
|
+
(field.includes("_for_sealer") || field.includes("_for_co")));
|
|
225
161
|
}
|
|
226
162
|
//# sourceMappingURL=permissions.js.map
|
package/dist/permissions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"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"}
|
package/dist/team.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { CoID, ContentType } from "./contentType.js";
|
|
2
|
+
import { CoMap } from "./contentTypes/coMap.js";
|
|
3
|
+
import { JsonObject, JsonValue } from "./jsonValue.js";
|
|
4
|
+
import { Encrypted, KeyID, KeySecret, Sealed } from "./crypto.js";
|
|
5
|
+
import { LocalNode } from "./node.js";
|
|
6
|
+
import { SessionID } from "./ids.js";
|
|
7
|
+
import { AccountIDOrAgentID, GeneralizedControlledAccount, Profile } from "./account.js";
|
|
8
|
+
import { Role } from "./permissions.js";
|
|
9
|
+
export type TeamContent = {
|
|
10
|
+
profile: CoID<Profile> | null;
|
|
11
|
+
[key: AccountIDOrAgentID]: Role;
|
|
12
|
+
readKey: KeyID;
|
|
13
|
+
[revelationFor: `${KeyID}_for_${AccountIDOrAgentID}`]: Sealed<KeySecret>;
|
|
14
|
+
[oldKeyForNewKey: `${KeyID}_for_${KeyID}`]: Encrypted<KeySecret, {
|
|
15
|
+
encryptedID: KeyID;
|
|
16
|
+
encryptingID: KeyID;
|
|
17
|
+
}>;
|
|
18
|
+
};
|
|
19
|
+
export declare function expectTeamContent(content: ContentType): CoMap<TeamContent, JsonObject | null>;
|
|
20
|
+
export declare class Team {
|
|
21
|
+
teamMap: CoMap<TeamContent, JsonObject | null>;
|
|
22
|
+
node: LocalNode;
|
|
23
|
+
constructor(teamMap: CoMap<TeamContent, JsonObject | null>, node: LocalNode);
|
|
24
|
+
get id(): CoID<CoMap<TeamContent, JsonObject | null>>;
|
|
25
|
+
addMember(accountID: AccountIDOrAgentID, role: Role): void;
|
|
26
|
+
createInvite(role: "reader" | "writer" | "admin"): InviteSecret;
|
|
27
|
+
rotateReadKey(): void;
|
|
28
|
+
removeMember(accountID: AccountIDOrAgentID): void;
|
|
29
|
+
createMap<M extends {
|
|
30
|
+
[key: string]: JsonValue;
|
|
31
|
+
}, Meta extends JsonObject | null = null>(meta?: Meta): CoMap<M, Meta>;
|
|
32
|
+
testWithDifferentAccount(account: GeneralizedControlledAccount, sessionId: SessionID): Team;
|
|
33
|
+
}
|
|
34
|
+
export type InviteSecret = `inviteSecret_z${string}`;
|
|
35
|
+
export declare function secretSeedFromInviteSecret(inviteSecret: InviteSecret): Uint8Array;
|
package/dist/team.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { createdNowUnique, newRandomKeySecret, seal, encryptKeySecret, getAgentSealerID, newRandomSecretSeed, agentSecretFromSecretSeed, getAgentID, } from "./crypto.js";
|
|
2
|
+
import { isAgentID } from "./ids.js";
|
|
3
|
+
import { base58 } from "@scure/base";
|
|
4
|
+
export function expectTeamContent(content) {
|
|
5
|
+
if (content.type !== "comap") {
|
|
6
|
+
throw new Error("Expected map");
|
|
7
|
+
}
|
|
8
|
+
return content;
|
|
9
|
+
}
|
|
10
|
+
export class Team {
|
|
11
|
+
constructor(teamMap, node) {
|
|
12
|
+
this.teamMap = teamMap;
|
|
13
|
+
this.node = node;
|
|
14
|
+
}
|
|
15
|
+
get id() {
|
|
16
|
+
return this.teamMap.id;
|
|
17
|
+
}
|
|
18
|
+
addMember(accountID, role) {
|
|
19
|
+
this.teamMap = this.teamMap.edit((map) => {
|
|
20
|
+
const currentReadKey = this.teamMap.coValue.getCurrentReadKey();
|
|
21
|
+
if (!currentReadKey.secret) {
|
|
22
|
+
throw new Error("Can't add member without read key secret");
|
|
23
|
+
}
|
|
24
|
+
const agent = this.node.resolveAccountAgent(accountID, "Expected to know agent to add them to team");
|
|
25
|
+
map.set(accountID, role, "trusting");
|
|
26
|
+
if (map.get(accountID) !== role) {
|
|
27
|
+
throw new Error("Failed to set role");
|
|
28
|
+
}
|
|
29
|
+
map.set(`${currentReadKey.id}_for_${accountID}`, seal(currentReadKey.secret, this.teamMap.coValue.node.account.currentSealerSecret(), getAgentSealerID(agent), {
|
|
30
|
+
in: this.teamMap.coValue.id,
|
|
31
|
+
tx: this.teamMap.coValue.nextTransactionID(),
|
|
32
|
+
}), "trusting");
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
createInvite(role) {
|
|
36
|
+
const secretSeed = newRandomSecretSeed();
|
|
37
|
+
const inviteSecret = agentSecretFromSecretSeed(secretSeed);
|
|
38
|
+
const inviteID = getAgentID(inviteSecret);
|
|
39
|
+
this.addMember(inviteID, `${role}Invite`);
|
|
40
|
+
return inviteSecretFromSecretSeed(secretSeed);
|
|
41
|
+
}
|
|
42
|
+
rotateReadKey() {
|
|
43
|
+
const currentlyPermittedReaders = this.teamMap.keys().filter((key) => {
|
|
44
|
+
if (key.startsWith("co_") || isAgentID(key)) {
|
|
45
|
+
const role = this.teamMap.get(key);
|
|
46
|
+
return (role === "admin" || role === "writer" || role === "reader");
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
const maybeCurrentReadKey = this.teamMap.coValue.getCurrentReadKey();
|
|
53
|
+
if (!maybeCurrentReadKey.secret) {
|
|
54
|
+
throw new Error("Can't rotate read key secret we don't have access to");
|
|
55
|
+
}
|
|
56
|
+
const currentReadKey = {
|
|
57
|
+
id: maybeCurrentReadKey.id,
|
|
58
|
+
secret: maybeCurrentReadKey.secret,
|
|
59
|
+
};
|
|
60
|
+
const newReadKey = newRandomKeySecret();
|
|
61
|
+
this.teamMap = this.teamMap.edit((map) => {
|
|
62
|
+
for (const readerID of currentlyPermittedReaders) {
|
|
63
|
+
const reader = this.node.resolveAccountAgent(readerID, "Expected to know currently permitted reader");
|
|
64
|
+
map.set(`${newReadKey.id}_for_${readerID}`, seal(newReadKey.secret, this.teamMap.coValue.node.account.currentSealerSecret(), getAgentSealerID(reader), {
|
|
65
|
+
in: this.teamMap.coValue.id,
|
|
66
|
+
tx: this.teamMap.coValue.nextTransactionID(),
|
|
67
|
+
}), "trusting");
|
|
68
|
+
}
|
|
69
|
+
map.set(`${currentReadKey.id}_for_${newReadKey.id}`, encryptKeySecret({
|
|
70
|
+
encrypting: newReadKey,
|
|
71
|
+
toEncrypt: currentReadKey,
|
|
72
|
+
}).encrypted, "trusting");
|
|
73
|
+
map.set("readKey", newReadKey.id, "trusting");
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
removeMember(accountID) {
|
|
77
|
+
this.teamMap = this.teamMap.edit((map) => {
|
|
78
|
+
map.set(accountID, "revoked", "trusting");
|
|
79
|
+
});
|
|
80
|
+
this.rotateReadKey();
|
|
81
|
+
}
|
|
82
|
+
createMap(meta) {
|
|
83
|
+
return this.node
|
|
84
|
+
.createCoValue({
|
|
85
|
+
type: "comap",
|
|
86
|
+
ruleset: {
|
|
87
|
+
type: "ownedByTeam",
|
|
88
|
+
team: this.teamMap.id,
|
|
89
|
+
},
|
|
90
|
+
meta: meta || null,
|
|
91
|
+
...createdNowUnique(),
|
|
92
|
+
})
|
|
93
|
+
.getCurrentContent();
|
|
94
|
+
}
|
|
95
|
+
testWithDifferentAccount(account, sessionId) {
|
|
96
|
+
return new Team(expectTeamContent(this.teamMap.coValue
|
|
97
|
+
.testWithDifferentAccount(account, sessionId)
|
|
98
|
+
.getCurrentContent()), this.node);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function inviteSecretFromSecretSeed(secretSeed) {
|
|
102
|
+
return `inviteSecret_z${base58.encode(secretSeed)}`;
|
|
103
|
+
}
|
|
104
|
+
export function secretSeedFromInviteSecret(inviteSecret) {
|
|
105
|
+
if (!inviteSecret.startsWith("inviteSecret_z")) {
|
|
106
|
+
throw new Error("Invalid invite secret");
|
|
107
|
+
}
|
|
108
|
+
return base58.decode(inviteSecret.slice("inviteSecret_z".length));
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=team.js.map
|
package/dist/team.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team.js","sourceRoot":"","sources":["../src/team.ts"],"names":[],"mappings":"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"}
|
package/dist/testUtils.d.ts
CHANGED
|
@@ -16,12 +16,12 @@ export declare function teamWithTwoAdmins(): {
|
|
|
16
16
|
export declare function newTeamHighLevel(): {
|
|
17
17
|
admin: AnonymousControlledAccount;
|
|
18
18
|
node: LocalNode;
|
|
19
|
-
team: import("./
|
|
19
|
+
team: import("./team.js").Team;
|
|
20
20
|
};
|
|
21
21
|
export declare function teamWithTwoAdminsHighLevel(): {
|
|
22
22
|
admin: AnonymousControlledAccount;
|
|
23
23
|
node: LocalNode;
|
|
24
|
-
team: import("./
|
|
24
|
+
team: import("./team.js").Team;
|
|
25
25
|
otherAdmin: import("./account.js").ControlledAccount;
|
|
26
26
|
};
|
|
27
27
|
export declare function shouldNotResolve<T>(promise: Promise<T>, ops: {
|
package/dist/testUtils.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createdNowUnique, getAgentID, newRandomAgentSecret } from "./crypto.js";
|
|
2
2
|
import { newRandomSessionID } from "./coValue.js";
|
|
3
3
|
import { LocalNode } from "./node.js";
|
|
4
|
-
import { expectTeamContent } from "./
|
|
4
|
+
import { expectTeamContent } from "./team.js";
|
|
5
5
|
import { AnonymousControlledAccount } from "./account.js";
|
|
6
6
|
export function randomAnonymousAccountAndSessionID() {
|
|
7
7
|
const agentSecret = newRandomAgentSecret();
|
package/dist/testUtils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testUtils.js","sourceRoot":"","sources":["../src/testUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,gBAAgB,EAAE,UAAU,EAAE,oBAAoB,EAAG,MAAM,aAAa,CAAC;AAC/F,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"testUtils.js","sourceRoot":"","sources":["../src/testUtils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
8
|
-
"version": "0.0.
|
|
8
|
+
"version": "0.0.22",
|
|
9
9
|
"devDependencies": {
|
|
10
10
|
"@types/jest": "^29.5.3",
|
|
11
11
|
"@typescript-eslint/eslint-plugin": "^6.2.1",
|
|
@@ -52,5 +52,5 @@
|
|
|
52
52
|
"/dist/"
|
|
53
53
|
]
|
|
54
54
|
},
|
|
55
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "6a6fb2eb3c5f2bb4577c2dfb20173b6e9f7a8f4b"
|
|
56
56
|
}
|
package/src/account.ts
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
} from "./crypto.js";
|
|
15
15
|
import { AgentID } from "./ids.js";
|
|
16
16
|
import { CoMap, LocalNode } from "./index.js";
|
|
17
|
-
import { Team, TeamContent } from "./
|
|
17
|
+
import { Team, TeamContent } from "./team.js";
|
|
18
18
|
|
|
19
19
|
export function accountHeaderForInitialAgentSecret(
|
|
20
20
|
agentSecret: AgentSecret
|
package/src/coValue.ts
CHANGED
|
@@ -24,11 +24,10 @@ import { JsonObject, JsonValue } from "./jsonValue.js";
|
|
|
24
24
|
import { base58 } from "@scure/base";
|
|
25
25
|
import {
|
|
26
26
|
PermissionsDef as RulesetDef,
|
|
27
|
-
Team,
|
|
28
27
|
determineValidTransactions,
|
|
29
|
-
expectTeamContent,
|
|
30
28
|
isKeyForKeyField,
|
|
31
29
|
} from "./permissions.js";
|
|
30
|
+
import { Team, expectTeamContent } from "./team.js";
|
|
32
31
|
import { LocalNode } from "./node.js";
|
|
33
32
|
import { CoValueKnownState, NewContentMessage } from "./sync.js";
|
|
34
33
|
import { RawCoID, SessionID, TransactionID } from "./ids.js";
|
|
@@ -98,7 +97,7 @@ export class CoValue {
|
|
|
98
97
|
node: LocalNode;
|
|
99
98
|
header: CoValueHeader;
|
|
100
99
|
sessions: { [key: SessionID]: SessionLog };
|
|
101
|
-
|
|
100
|
+
_cachedContent?: ContentType;
|
|
102
101
|
listeners: Set<(content?: ContentType) => void> = new Set();
|
|
103
102
|
|
|
104
103
|
constructor(header: CoValueHeader, node: LocalNode) {
|
|
@@ -197,7 +196,7 @@ export class CoValue {
|
|
|
197
196
|
lastSignature: newSignature,
|
|
198
197
|
};
|
|
199
198
|
|
|
200
|
-
this.
|
|
199
|
+
this._cachedContent = undefined;
|
|
201
200
|
|
|
202
201
|
const content = this.getCurrentContent();
|
|
203
202
|
|
|
@@ -296,23 +295,23 @@ export class CoValue {
|
|
|
296
295
|
}
|
|
297
296
|
|
|
298
297
|
getCurrentContent(): ContentType {
|
|
299
|
-
if (this.
|
|
300
|
-
return this.
|
|
298
|
+
if (this._cachedContent) {
|
|
299
|
+
return this._cachedContent;
|
|
301
300
|
}
|
|
302
301
|
|
|
303
302
|
if (this.header.type === "comap") {
|
|
304
|
-
this.
|
|
303
|
+
this._cachedContent = new CoMap(this);
|
|
305
304
|
} else if (this.header.type === "colist") {
|
|
306
|
-
this.
|
|
305
|
+
this._cachedContent = new CoList(this);
|
|
307
306
|
} else if (this.header.type === "costream") {
|
|
308
|
-
this.
|
|
307
|
+
this._cachedContent = new CoStream(this);
|
|
309
308
|
} else if (this.header.type === "static") {
|
|
310
|
-
this.
|
|
309
|
+
this._cachedContent = new Static(this);
|
|
311
310
|
} else {
|
|
312
311
|
throw new Error(`Unknown coValue type ${this.header.type}`);
|
|
313
312
|
}
|
|
314
313
|
|
|
315
|
-
return this.
|
|
314
|
+
return this._cachedContent;
|
|
316
315
|
}
|
|
317
316
|
|
|
318
317
|
getValidSortedTransactions(): DecryptedTransaction[] {
|
|
@@ -12,12 +12,12 @@ type MapOp<K extends string, V extends JsonValue> = {
|
|
|
12
12
|
// TODO: add after TransactionID[] for conflicts/ordering
|
|
13
13
|
|
|
14
14
|
export type MapOpPayload<K extends string, V extends JsonValue> = {
|
|
15
|
-
op: "
|
|
15
|
+
op: "set";
|
|
16
16
|
key: K;
|
|
17
17
|
value: V;
|
|
18
18
|
} |
|
|
19
19
|
{
|
|
20
|
-
op: "
|
|
20
|
+
op: "del";
|
|
21
21
|
key: K;
|
|
22
22
|
};
|
|
23
23
|
|
|
@@ -81,7 +81,7 @@ export class CoMap<
|
|
|
81
81
|
|
|
82
82
|
const lastEntry = ops[ops.length - 1]!;
|
|
83
83
|
|
|
84
|
-
if (lastEntry.op === "
|
|
84
|
+
if (lastEntry.op === "del") {
|
|
85
85
|
return undefined;
|
|
86
86
|
} else {
|
|
87
87
|
return lastEntry.value;
|
|
@@ -100,7 +100,7 @@ export class CoMap<
|
|
|
100
100
|
return undefined;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
if (lastOpBeforeOrAtTime.op === "
|
|
103
|
+
if (lastOpBeforeOrAtTime.op === "del") {
|
|
104
104
|
return undefined;
|
|
105
105
|
} else {
|
|
106
106
|
return lastOpBeforeOrAtTime.value;
|
|
@@ -139,7 +139,7 @@ export class CoMap<
|
|
|
139
139
|
|
|
140
140
|
const lastEntry = ops[ops.length - 1]!;
|
|
141
141
|
|
|
142
|
-
if (lastEntry.op === "
|
|
142
|
+
if (lastEntry.op === "del") {
|
|
143
143
|
return undefined;
|
|
144
144
|
} else {
|
|
145
145
|
return { at: lastEntry.madeAt, txID: lastEntry.txID, value: lastEntry.value };
|
|
@@ -155,7 +155,7 @@ export class CoMap<
|
|
|
155
155
|
const history: { at: number; txID: TransactionID; value: M[K] | undefined; }[] = [];
|
|
156
156
|
|
|
157
157
|
for (const op of ops) {
|
|
158
|
-
if (op.op === "
|
|
158
|
+
if (op.op === "del") {
|
|
159
159
|
history.push({ at: op.madeAt, txID: op.txID, value: undefined });
|
|
160
160
|
} else {
|
|
161
161
|
history.push({ at: op.madeAt, txID: op.txID, value: op.value });
|
|
@@ -199,7 +199,7 @@ export class WriteableCoMap<
|
|
|
199
199
|
set<K extends MapK<M>>(key: K, value: M[K], privacy: "private" | "trusting" = "private"): void {
|
|
200
200
|
this.coValue.makeTransaction([
|
|
201
201
|
{
|
|
202
|
-
op: "
|
|
202
|
+
op: "set",
|
|
203
203
|
key,
|
|
204
204
|
value,
|
|
205
205
|
},
|
|
@@ -211,7 +211,7 @@ export class WriteableCoMap<
|
|
|
211
211
|
delete(key: MapK<M>, privacy: "private" | "trusting" = "private"): void {
|
|
212
212
|
this.coValue.makeTransaction([
|
|
213
213
|
{
|
|
214
|
-
op: "
|
|
214
|
+
op: "del",
|
|
215
215
|
key,
|
|
216
216
|
},
|
|
217
217
|
], privacy);
|