cojson 0.17.14 → 0.18.1
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 +34 -0
- package/dist/coValueCore/branching.d.ts +36 -0
- package/dist/coValueCore/branching.d.ts.map +1 -0
- package/dist/coValueCore/branching.js +122 -0
- package/dist/coValueCore/branching.js.map +1 -0
- package/dist/coValueCore/coValueCore.d.ts +71 -5
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +162 -53
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValueCore/decodeTransactionChangesAndMeta.d.ts +3 -0
- package/dist/coValueCore/decodeTransactionChangesAndMeta.d.ts.map +1 -0
- package/dist/coValueCore/decodeTransactionChangesAndMeta.js +59 -0
- package/dist/coValueCore/decodeTransactionChangesAndMeta.js.map +1 -0
- package/dist/coValueCore/verifiedState.d.ts.map +1 -1
- package/dist/coValues/account.d.ts +2 -1
- package/dist/coValues/account.d.ts.map +1 -1
- package/dist/coValues/account.js +6 -0
- package/dist/coValues/account.js.map +1 -1
- package/dist/coValues/coList.d.ts +3 -3
- package/dist/coValues/coList.d.ts.map +1 -1
- package/dist/coValues/coList.js +4 -7
- package/dist/coValues/coList.js.map +1 -1
- package/dist/coValues/coMap.d.ts +3 -3
- package/dist/coValues/coMap.d.ts.map +1 -1
- package/dist/coValues/coMap.js +6 -6
- package/dist/coValues/coMap.js.map +1 -1
- package/dist/coValues/coStream.d.ts +3 -3
- package/dist/coValues/coStream.d.ts.map +1 -1
- package/dist/coValues/coStream.js +4 -4
- package/dist/coValues/coStream.js.map +1 -1
- package/dist/ids.d.ts.map +1 -1
- package/dist/ids.js.map +1 -1
- package/dist/jsonStringify.d.ts +1 -0
- package/dist/jsonStringify.d.ts.map +1 -1
- package/dist/jsonStringify.js +8 -0
- package/dist/jsonStringify.js.map +1 -1
- package/dist/permissions.d.ts +2 -7
- package/dist/permissions.d.ts.map +1 -1
- package/dist/permissions.js +72 -70
- package/dist/permissions.js.map +1 -1
- package/dist/sync.d.ts +2 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +16 -5
- package/dist/sync.js.map +1 -1
- package/dist/tests/account.test.js +20 -0
- package/dist/tests/account.test.js.map +1 -1
- package/dist/tests/branching.test.d.ts +2 -0
- package/dist/tests/branching.test.d.ts.map +1 -0
- package/dist/tests/branching.test.js +99 -0
- package/dist/tests/branching.test.js.map +1 -0
- package/dist/tests/coValueCore.test.js +2 -3
- package/dist/tests/coValueCore.test.js.map +1 -1
- package/dist/tests/sync.sharding.test.js +63 -0
- package/dist/tests/sync.sharding.test.js.map +1 -1
- package/dist/tests/sync.storage.test.js +1 -3
- package/dist/tests/sync.storage.test.js.map +1 -1
- package/dist/tests/sync.upload.test.js +1 -3
- package/dist/tests/sync.upload.test.js.map +1 -1
- package/dist/tests/testUtils.d.ts +1 -0
- package/dist/tests/testUtils.d.ts.map +1 -1
- package/dist/tests/testUtils.js +1 -1
- package/dist/tests/testUtils.js.map +1 -1
- package/package.json +2 -2
- package/src/coValueCore/branching.ts +198 -0
- package/src/coValueCore/coValueCore.ts +255 -72
- package/src/coValueCore/decodeTransactionChangesAndMeta.ts +81 -0
- package/src/coValueCore/verifiedState.ts +1 -1
- package/src/coValues/account.ts +11 -9
- package/src/coValues/coList.ts +8 -10
- package/src/coValues/coMap.ts +8 -11
- package/src/coValues/coStream.ts +7 -8
- package/src/ids.ts +4 -1
- package/src/jsonStringify.ts +8 -0
- package/src/permissions.ts +80 -89
- package/src/sync.ts +21 -6
- package/src/tests/account.test.ts +24 -0
- package/src/tests/branching.test.ts +141 -0
- package/src/tests/coValueCore.test.ts +2 -3
- package/src/tests/sync.sharding.test.ts +72 -0
- package/src/tests/sync.storage.test.ts +3 -3
- package/src/tests/sync.upload.test.ts +3 -3
- package/src/tests/testUtils.ts +2 -1
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# cojson
|
|
2
2
|
|
|
3
|
+
## 0.18.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- cojson-core-wasm@0.18.1
|
|
8
|
+
|
|
9
|
+
## 0.18.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- f263856: Add `$jazz` field to CoValues:
|
|
14
|
+
- This field contains Jazz methods that cluttered CoValues' API, as well as Jazz internal properties. This field is not enumerable, to allow CoValues to behave similarly to JSON objects.
|
|
15
|
+
- Added a `$jazz.set` method to update a CoValue's fields. When updating collaborative fields, you can pass in JSON objects instead of CoValues and Jazz will create
|
|
16
|
+
the CoValues automatically (similarly to CoValue `create` methods).
|
|
17
|
+
- All CoMap methods have been moved into `$jazz`, to allow defining any arbitrary key in the CoMap (except for `$jazz`) without conflicts.
|
|
18
|
+
- For CoMaps created with `co.map`, fields are now `readonly` to prevent setting properties directly. Use the `$jazz.set` method instead.
|
|
19
|
+
- CoMaps created with class schemas don't get type errors on direct property assignments, but they get a runtime errors prompting indicating to use `$jazz.set`.
|
|
20
|
+
- the `delete` operator can no longer be used to delete CoRecord properties. Use `$jazz.delete` instead.
|
|
21
|
+
- CoList's array-mutation methods have been moved into `$jazz`, in order to prevent using methods
|
|
22
|
+
- CoLists are now readonly arrays. Trying to use any mutation method yields a type error.
|
|
23
|
+
- `$jazz.set` can be used in place of direct element assignments.
|
|
24
|
+
- Added two new utility methods: `$jazz.remove` and `$jazz.retain`. They allow editing a CoList in-place with a simpler API than `$jazz.splice`.
|
|
25
|
+
- `sort`, `reverse`, `fill` and `copyWithin` have been deprecated, given that they could behave inconsistently with CoLists. `$jazz` replacements may be introduced
|
|
26
|
+
in future releases.
|
|
27
|
+
- `.$jazz.owner` now always returns a Group (instead of a Group or an Account). We'll be migrating away of having Accounts as CoValue owners in future releases.
|
|
28
|
+
- Removed `castAs`, since it's an inherently unsafe operation that bypassed typechecking and enabled using CoValues in unsupported ways.
|
|
29
|
+
- Removed the `id` and `_type` fields from `toJSON()`'s output in Account, CoMap, CoFeed & FileStream, to make CoValues behave more similarly to JSON objects.
|
|
30
|
+
- Removed the `root` and `profile` fields from Group.
|
|
31
|
+
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- b709494: Allow adding server peers without reconciliation
|
|
35
|
+
- cojson-core-wasm@0.18.0
|
|
36
|
+
|
|
3
37
|
## 0.17.14
|
|
4
38
|
|
|
5
39
|
### Patch Changes
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { CoValueCore } from "../exports.js";
|
|
2
|
+
import { RawCoID } from "../ids.js";
|
|
3
|
+
import { AvailableCoValueCore } from "./coValueCore.js";
|
|
4
|
+
import { CoValueHeader } from "./verifiedState.js";
|
|
5
|
+
import { CoValueKnownState } from "../sync.js";
|
|
6
|
+
export declare function getBranchHeader({ type, branchName, ownerId, sourceId, }: {
|
|
7
|
+
type: CoValueHeader["type"];
|
|
8
|
+
branchName: string;
|
|
9
|
+
ownerId: RawCoID;
|
|
10
|
+
sourceId: RawCoID;
|
|
11
|
+
}): CoValueHeader;
|
|
12
|
+
/**
|
|
13
|
+
* Given a coValue, a branch name and an owner id, returns the id for the branch
|
|
14
|
+
*/
|
|
15
|
+
export declare function getBranchId(coValue: CoValueCore, name: string, ownerId: RawCoID): RawCoID;
|
|
16
|
+
export type BranchCommit = {
|
|
17
|
+
branch: CoValueKnownState["sessions"];
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Given a coValue, a branch name and an owner id, creates a new branch CoValue
|
|
21
|
+
*/
|
|
22
|
+
export declare function createBranch(coValue: CoValueCore, name: string, ownerId: RawCoID): CoValueCore;
|
|
23
|
+
/**
|
|
24
|
+
* Given a branch coValue, returns the source coValue if available
|
|
25
|
+
*/
|
|
26
|
+
export declare function getBranchSource(coValue: CoValueCore): AvailableCoValueCore | undefined;
|
|
27
|
+
export type MergeCommit = {
|
|
28
|
+
merge: CoValueKnownState["sessions"];
|
|
29
|
+
id: RawCoID;
|
|
30
|
+
count: number;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Given a branch coValue, merges the branch into the source coValue
|
|
34
|
+
*/
|
|
35
|
+
export declare function mergeBranch(branch: CoValueCore): CoValueCore;
|
|
36
|
+
//# sourceMappingURL=branching.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branching.d.ts","sourceRoot":"","sources":["../../src/coValueCore/branching.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAa,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAe,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,UAAU,EACV,OAAO,EACP,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB,GAAG,aAAa,CAkBhB;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,GACf,OAAO,CAeT;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,iBAAiB,CAAC,UAAU,CAAC,CAAC;CACvC,CAAC;AAEF;;GAEG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,GACf,WAAW,CAsBb;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,WAAW,GACnB,oBAAoB,GAAG,SAAS,CAkBlC;AAED,MAAM,MAAM,WAAW,GAAG;IAExB,KAAK,EAAE,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAErC,EAAE,EAAE,OAAO,CAAC;IAEZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAiE5D"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { idforHeader } from "./coValueCore.js";
|
|
2
|
+
export function getBranchHeader({ type, branchName, ownerId, sourceId, }) {
|
|
3
|
+
return {
|
|
4
|
+
type,
|
|
5
|
+
// Branch name and source id are stored in the meta field
|
|
6
|
+
// and used to generate the unique id for the branch
|
|
7
|
+
meta: {
|
|
8
|
+
branch: branchName,
|
|
9
|
+
source: sourceId,
|
|
10
|
+
},
|
|
11
|
+
ruleset: {
|
|
12
|
+
type: "ownedByGroup",
|
|
13
|
+
// The owner is part of the id generation, making it possible to have multiple branches with the same name
|
|
14
|
+
// but different owners
|
|
15
|
+
group: ownerId,
|
|
16
|
+
},
|
|
17
|
+
// The meta is enough to have reproducible unique id for the branch
|
|
18
|
+
uniqueness: "",
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Given a coValue, a branch name and an owner id, returns the id for the branch
|
|
23
|
+
*/
|
|
24
|
+
export function getBranchId(coValue, name, ownerId) {
|
|
25
|
+
if (!coValue.verified) {
|
|
26
|
+
throw new Error("CoValueCore: getBranchId called on coValue without verified state");
|
|
27
|
+
}
|
|
28
|
+
const header = getBranchHeader({
|
|
29
|
+
type: coValue.verified.header.type,
|
|
30
|
+
branchName: name,
|
|
31
|
+
ownerId,
|
|
32
|
+
sourceId: coValue.id,
|
|
33
|
+
});
|
|
34
|
+
return idforHeader(header, coValue.node.crypto);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Given a coValue, a branch name and an owner id, creates a new branch CoValue
|
|
38
|
+
*/
|
|
39
|
+
export function createBranch(coValue, name, ownerId) {
|
|
40
|
+
if (!coValue.verified) {
|
|
41
|
+
throw new Error("CoValueCore: createBranch called on coValue without verified state");
|
|
42
|
+
}
|
|
43
|
+
const header = getBranchHeader({
|
|
44
|
+
type: coValue.verified.header.type,
|
|
45
|
+
branchName: name,
|
|
46
|
+
ownerId,
|
|
47
|
+
sourceId: coValue.id,
|
|
48
|
+
});
|
|
49
|
+
const value = coValue.node.createCoValue(header);
|
|
50
|
+
// Create a branch commit to identify the starting point of the branch
|
|
51
|
+
value.makeTransaction([], "private", {
|
|
52
|
+
branch: coValue.knownState().sessions,
|
|
53
|
+
});
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Given a branch coValue, returns the source coValue if available
|
|
58
|
+
*/
|
|
59
|
+
export function getBranchSource(coValue) {
|
|
60
|
+
if (!coValue.verified) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
const sourceId = coValue.verified.header.meta?.source;
|
|
64
|
+
if (!sourceId) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
const source = coValue.node.getCoValue(sourceId);
|
|
68
|
+
if (!source.isAvailable()) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
return source;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Given a branch coValue, merges the branch into the source coValue
|
|
75
|
+
*/
|
|
76
|
+
export function mergeBranch(branch) {
|
|
77
|
+
if (!branch.verified) {
|
|
78
|
+
throw new Error("CoValueCore: mergeBranch called on coValue without verified state");
|
|
79
|
+
}
|
|
80
|
+
const sourceId = branch.verified.header.meta?.source;
|
|
81
|
+
if (!sourceId) {
|
|
82
|
+
throw new Error("CoValueCore: mergeBranch called on a non-branch coValue");
|
|
83
|
+
}
|
|
84
|
+
const target = getBranchSource(branch);
|
|
85
|
+
if (!target) {
|
|
86
|
+
throw new Error("CoValueCore: unable to find source branch");
|
|
87
|
+
}
|
|
88
|
+
// Look for previous merge commits, to see which transactions needs to be merged
|
|
89
|
+
// Done mostly for performance reasons, as we could merge all the transactions every time and nothing would change
|
|
90
|
+
const mergedTransactions = target.mergeCommits.reduce((acc, { commit }) => {
|
|
91
|
+
if (commit.id !== branch.id) {
|
|
92
|
+
return acc;
|
|
93
|
+
}
|
|
94
|
+
for (const [sessionID, count] of Object.entries(commit.merge)) {
|
|
95
|
+
acc[sessionID] = Math.max(acc[sessionID] ?? 0, count);
|
|
96
|
+
}
|
|
97
|
+
return acc;
|
|
98
|
+
}, {});
|
|
99
|
+
// Get the valid transactions from the branch, skipping the branch source and the previously merged transactions
|
|
100
|
+
const branchValidTransactions = branch
|
|
101
|
+
.getValidTransactions({
|
|
102
|
+
from: mergedTransactions,
|
|
103
|
+
ignorePrivateTransactions: false,
|
|
104
|
+
skipBranchSource: true,
|
|
105
|
+
})
|
|
106
|
+
.filter((tx) => tx.changes.length > 0);
|
|
107
|
+
// If there are no valid transactions to merge, we don't want to create a merge commit
|
|
108
|
+
if (branchValidTransactions.length === 0) {
|
|
109
|
+
return target;
|
|
110
|
+
}
|
|
111
|
+
// Create a merge commit to identify the merge point
|
|
112
|
+
target.makeTransaction([], "private", {
|
|
113
|
+
merge: { ...branch.knownState().sessions },
|
|
114
|
+
id: branch.id,
|
|
115
|
+
count: branchValidTransactions.length,
|
|
116
|
+
});
|
|
117
|
+
for (const { tx, changes } of branchValidTransactions) {
|
|
118
|
+
target.makeTransaction(changes, tx.privacy);
|
|
119
|
+
}
|
|
120
|
+
return target;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=branching.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branching.js","sourceRoot":"","sources":["../../src/coValueCore/branching.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,17 +4,32 @@ import type { RawCoValue } from "../coValue.js";
|
|
|
4
4
|
import type { ControlledAccountOrAgent } from "../coValues/account.js";
|
|
5
5
|
import type { RawGroup } from "../coValues/group.js";
|
|
6
6
|
import { CryptoProvider, Hash, KeyID, KeySecret, Signature, SignerID } from "../crypto/crypto.js";
|
|
7
|
-
import { RawCoID, SessionID, TransactionID } from "../ids.js";
|
|
7
|
+
import { AgentID, RawCoID, SessionID, TransactionID } from "../ids.js";
|
|
8
8
|
import { JsonObject, JsonValue } from "../jsonValue.js";
|
|
9
9
|
import { LocalNode, ResolveAccountAgentError } from "../localNode.js";
|
|
10
10
|
import { CoValueKnownState, PeerID } from "../sync.js";
|
|
11
11
|
import { CoValueHeader, Transaction, VerifiedState } from "./verifiedState.js";
|
|
12
|
+
import { MergeCommit } from "./branching.js";
|
|
13
|
+
import { type RawAccountID } from "../coValues/account.js";
|
|
12
14
|
export declare function idforHeader(header: CoValueHeader, crypto: CryptoProvider): RawCoID;
|
|
15
|
+
export type VerifiedTransaction = {
|
|
16
|
+
author: RawAccountID | AgentID;
|
|
17
|
+
txID: TransactionID;
|
|
18
|
+
tx: Transaction;
|
|
19
|
+
madeAt: number;
|
|
20
|
+
isValidated: boolean;
|
|
21
|
+
changes: JsonValue[] | undefined;
|
|
22
|
+
meta: JsonObject | undefined;
|
|
23
|
+
isValid: boolean;
|
|
24
|
+
hasInvalidChanges: boolean;
|
|
25
|
+
hasInvalidMeta: boolean;
|
|
26
|
+
hasMetaBeenParsed: boolean;
|
|
27
|
+
};
|
|
13
28
|
export type DecryptedTransaction = {
|
|
14
29
|
txID: TransactionID;
|
|
15
30
|
changes: JsonValue[];
|
|
16
31
|
madeAt: number;
|
|
17
|
-
|
|
32
|
+
tx: Transaction;
|
|
18
33
|
};
|
|
19
34
|
export type AvailableCoValueCore = CoValueCore & {
|
|
20
35
|
verified: VerifiedState;
|
|
@@ -39,7 +54,6 @@ export declare class CoValueCore {
|
|
|
39
54
|
private readonly peers;
|
|
40
55
|
private _cachedContent?;
|
|
41
56
|
readonly listeners: Set<(core: CoValueCore, unsub: () => void) => void>;
|
|
42
|
-
private readonly _decryptionCache;
|
|
43
57
|
private _cachedDependentOn?;
|
|
44
58
|
private counter;
|
|
45
59
|
private constructor();
|
|
@@ -90,13 +104,65 @@ export declare class CoValueCore {
|
|
|
90
104
|
getCurrentContent(options?: {
|
|
91
105
|
ignorePrivateTransactions: true;
|
|
92
106
|
}): RawCoValue;
|
|
107
|
+
branchStart: {
|
|
108
|
+
branch: CoValueKnownState["sessions"];
|
|
109
|
+
madeAt: number;
|
|
110
|
+
} | undefined;
|
|
111
|
+
mergeCommits: {
|
|
112
|
+
commit: MergeCommit;
|
|
113
|
+
madeAt: number;
|
|
114
|
+
}[];
|
|
115
|
+
resetParsedTransactions(): void;
|
|
116
|
+
verifiedTransactions: VerifiedTransaction[];
|
|
117
|
+
private verifiedTransactionsKnownSessions;
|
|
118
|
+
/**
|
|
119
|
+
* Loads the new transaction from the SessionMap into verifiedTransactions as a VerifiedTransaction.
|
|
120
|
+
*
|
|
121
|
+
* If the transaction is already loaded from the SessionMap in the past, it will not be loaded again.
|
|
122
|
+
*
|
|
123
|
+
* Used to have a fast way to iterate over the CoValue transactions, and track their validation/decoding state.
|
|
124
|
+
*
|
|
125
|
+
* @param preload - Optional preload object containing the transaction, changes, and meta.
|
|
126
|
+
* If provided, the transaction will be preloaded with the given changes and meta.
|
|
127
|
+
*
|
|
128
|
+
* @internal
|
|
129
|
+
* */
|
|
130
|
+
loadVerifiedTransactionsFromLogs(preload?: {
|
|
131
|
+
transaction: Transaction;
|
|
132
|
+
changes: JsonValue[];
|
|
133
|
+
meta: JsonObject | undefined;
|
|
134
|
+
}): void;
|
|
135
|
+
/**
|
|
136
|
+
* Iterates over the verifiedTransactions and marks them as valid or invalid, based on the group membership of the authors of the transactions .
|
|
137
|
+
*/
|
|
138
|
+
private determineValidTransactions;
|
|
139
|
+
/**
|
|
140
|
+
* Parses the meta information of a transaction, and set the branchStart and mergeCommits.
|
|
141
|
+
*/
|
|
142
|
+
private parseMetaInformation;
|
|
143
|
+
/**
|
|
144
|
+
* Loads the new transactions from SessionMap and:
|
|
145
|
+
* - Validates each transaction based on the group membership of the authors
|
|
146
|
+
* - Decodes the changes & meta for each transaction
|
|
147
|
+
* - Parses the meta information of the transaction
|
|
148
|
+
*/
|
|
149
|
+
private parseNewTransactions;
|
|
150
|
+
/**
|
|
151
|
+
* Returns the valid transactions matching the criteria specified in the options
|
|
152
|
+
*/
|
|
93
153
|
getValidTransactions(options?: {
|
|
94
154
|
ignorePrivateTransactions: boolean;
|
|
95
|
-
|
|
155
|
+
from?: CoValueKnownState["sessions"];
|
|
156
|
+
to?: CoValueKnownState["sessions"];
|
|
157
|
+
knownTransactions?: Set<Transaction>;
|
|
158
|
+
skipBranchSource?: boolean;
|
|
96
159
|
}): DecryptedTransaction[];
|
|
160
|
+
createBranch(name: string, ownerId: RawCoID): CoValueCore;
|
|
161
|
+
mergeBranch(): CoValueCore;
|
|
162
|
+
getBranchId(name: string, ownerId: RawCoID): `co_z${string}`;
|
|
97
163
|
getValidSortedTransactions(options?: {
|
|
98
164
|
ignorePrivateTransactions: boolean;
|
|
99
|
-
knownTransactions
|
|
165
|
+
knownTransactions?: Set<Transaction>;
|
|
100
166
|
}): DecryptedTransaction[];
|
|
101
167
|
compareTransactions(a: Pick<DecryptedTransaction, "madeAt" | "txID">, b: Pick<DecryptedTransaction, "madeAt" | "txID">): number;
|
|
102
168
|
getCurrentReadKey(): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coValueCore.d.ts","sourceRoot":"","sources":["../../src/coValueCore/coValueCore.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAW,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAGrD,OAAO,EACL,cAAc,EAEd,IAAI,EACJ,KAAK,EACL,SAAS,EACT,SAAS,EACT,QAAQ,EACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"coValueCore.d.ts","sourceRoot":"","sources":["../../src/coValueCore/coValueCore.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,6 @@ import { ValueType, metrics } from "@opentelemetry/api";
|
|
|
2
2
|
import { err, ok } from "neverthrow";
|
|
3
3
|
import { CO_VALUE_LOADING_CONFIG } from "../config.js";
|
|
4
4
|
import { coreToCoValue } from "../coreToCoValue.js";
|
|
5
|
-
import { parseJSON } from "../jsonStringify.js";
|
|
6
5
|
import { logger } from "../logger.js";
|
|
7
6
|
import { determineValidTransactions } from "../permissions.js";
|
|
8
7
|
import { emptyKnownState } from "../sync.js";
|
|
@@ -11,6 +10,8 @@ import { expectGroup } from "../typeUtils/expectGroup.js";
|
|
|
11
10
|
import { getDependedOnCoValuesFromRawData } from "./utils.js";
|
|
12
11
|
import { VerifiedState } from "./verifiedState.js";
|
|
13
12
|
import { SessionMap } from "./SessionMap.js";
|
|
13
|
+
import { createBranch, getBranchId, getBranchSource, mergeBranch, } from "./branching.js";
|
|
14
|
+
import { decodeTransactionChangesAndMeta } from "./decodeTransactionChangesAndMeta.js";
|
|
14
15
|
export function idforHeader(header, crypto) {
|
|
15
16
|
const hash = crypto.shortHash(header);
|
|
16
17
|
return `co_z${hash.slice("shortHash_z".length)}`;
|
|
@@ -33,9 +34,12 @@ export class CoValueCore {
|
|
|
33
34
|
constructor(init, node) {
|
|
34
35
|
this.peers = new Map();
|
|
35
36
|
this.listeners = new Set();
|
|
36
|
-
this._decryptionCache = {};
|
|
37
37
|
this.missingDependencies = new Set();
|
|
38
38
|
this.deferredUpdates = 0;
|
|
39
|
+
// The list of merge commits that have been made
|
|
40
|
+
this.mergeCommits = [];
|
|
41
|
+
this.verifiedTransactions = [];
|
|
42
|
+
this.verifiedTransactionsKnownSessions = {};
|
|
39
43
|
this.readKeyCache = new Map();
|
|
40
44
|
this.crypto = node.crypto;
|
|
41
45
|
if ("header" in init) {
|
|
@@ -220,12 +224,12 @@ export class CoValueCore {
|
|
|
220
224
|
throw new Error("CoValueCore: internalShamefullyCloneVerifiedStateFrom called on coValue with verified sessions present!");
|
|
221
225
|
}
|
|
222
226
|
this._verified = state.clone();
|
|
223
|
-
this.
|
|
224
|
-
this._cachedDependentOn = undefined;
|
|
227
|
+
this.internalShamefullyResetCachedContent();
|
|
225
228
|
}
|
|
226
229
|
internalShamefullyResetCachedContent() {
|
|
227
230
|
this._cachedContent = undefined;
|
|
228
231
|
this._cachedDependentOn = undefined;
|
|
232
|
+
this.resetParsedTransactions();
|
|
229
233
|
}
|
|
230
234
|
subscribeToGroupInvalidation() {
|
|
231
235
|
if (!this.verified) {
|
|
@@ -240,7 +244,8 @@ export class CoValueCore {
|
|
|
240
244
|
const entry = this.node.getCoValue(groupId);
|
|
241
245
|
if (entry.isAvailable()) {
|
|
242
246
|
this.groupInvalidationSubscription = entry.subscribe((_groupUpdate) => {
|
|
243
|
-
|
|
247
|
+
// When the group is updated, we need to reset the cached content because the transactions validity might have changed
|
|
248
|
+
this.internalShamefullyResetCachedContent();
|
|
244
249
|
this.notifyUpdate("immediate");
|
|
245
250
|
}, false);
|
|
246
251
|
}
|
|
@@ -395,18 +400,14 @@ export class CoValueCore {
|
|
|
395
400
|
throw new Error("Can't make transaction without read key secret");
|
|
396
401
|
}
|
|
397
402
|
result = this.verified.makeNewPrivateTransaction(sessionID, signerAgent, changes, keyID, keySecret, meta);
|
|
398
|
-
if (result.transaction.privacy === "private") {
|
|
399
|
-
this._decryptionCache[result.transaction.encryptedChanges] = changes;
|
|
400
|
-
if (result.transaction.meta) {
|
|
401
|
-
this._decryptionCache[result.transaction.meta] = meta;
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
403
|
}
|
|
405
404
|
else {
|
|
406
405
|
result = this.verified.makeNewTrustingTransaction(sessionID, signerAgent, changes, meta);
|
|
407
406
|
}
|
|
408
407
|
const { transaction, signature } = result;
|
|
409
408
|
this.node.syncManager.recordTransactionsSize([transaction], "local");
|
|
409
|
+
// We pre-populate the parsed transactions and meta for the new transaction, to skip the parsing step later
|
|
410
|
+
this.loadVerifiedTransactionsFromLogs({ transaction, changes, meta });
|
|
410
411
|
const session = this.verified.sessions.get(sessionID);
|
|
411
412
|
const txIdx = session ? session.transactions.length - 1 : 0;
|
|
412
413
|
this.updateContentAndNotifyUpdate("immediate");
|
|
@@ -427,57 +428,162 @@ export class CoValueCore {
|
|
|
427
428
|
}
|
|
428
429
|
return newContent;
|
|
429
430
|
}
|
|
431
|
+
// Reset the parsed transactions and branches, to validate them again from scratch when the group is updated
|
|
432
|
+
resetParsedTransactions() {
|
|
433
|
+
this.branchStart = undefined;
|
|
434
|
+
this.mergeCommits = [];
|
|
435
|
+
for (const transaction of this.verifiedTransactions) {
|
|
436
|
+
transaction.isValidated = false;
|
|
437
|
+
transaction.hasMetaBeenParsed = false;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Loads the new transaction from the SessionMap into verifiedTransactions as a VerifiedTransaction.
|
|
442
|
+
*
|
|
443
|
+
* If the transaction is already loaded from the SessionMap in the past, it will not be loaded again.
|
|
444
|
+
*
|
|
445
|
+
* Used to have a fast way to iterate over the CoValue transactions, and track their validation/decoding state.
|
|
446
|
+
*
|
|
447
|
+
* @param preload - Optional preload object containing the transaction, changes, and meta.
|
|
448
|
+
* If provided, the transaction will be preloaded with the given changes and meta.
|
|
449
|
+
*
|
|
450
|
+
* @internal
|
|
451
|
+
* */
|
|
452
|
+
loadVerifiedTransactionsFromLogs(preload) {
|
|
453
|
+
if (!this.verified) {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
for (const [sessionID, sessionLog] of this.verified.sessions.entries()) {
|
|
457
|
+
const count = this.verifiedTransactionsKnownSessions[sessionID] ?? 0;
|
|
458
|
+
sessionLog.transactions.forEach((tx, txIndex) => {
|
|
459
|
+
if (txIndex < count) {
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
this.verifiedTransactions.push({
|
|
463
|
+
author: accountOrAgentIDfromSessionID(sessionID),
|
|
464
|
+
txID: {
|
|
465
|
+
sessionID,
|
|
466
|
+
txIndex,
|
|
467
|
+
},
|
|
468
|
+
madeAt: tx.madeAt,
|
|
469
|
+
isValidated: false,
|
|
470
|
+
isValid: false,
|
|
471
|
+
changes: tx === preload?.transaction ? preload.changes : undefined,
|
|
472
|
+
meta: tx === preload?.transaction ? preload.meta : undefined,
|
|
473
|
+
hasInvalidChanges: false,
|
|
474
|
+
hasInvalidMeta: false,
|
|
475
|
+
hasMetaBeenParsed: false,
|
|
476
|
+
tx,
|
|
477
|
+
});
|
|
478
|
+
});
|
|
479
|
+
this.verifiedTransactionsKnownSessions[sessionID] =
|
|
480
|
+
sessionLog.transactions.length;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Iterates over the verifiedTransactions and marks them as valid or invalid, based on the group membership of the authors of the transactions .
|
|
485
|
+
*/
|
|
486
|
+
determineValidTransactions() {
|
|
487
|
+
determineValidTransactions(this);
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Parses the meta information of a transaction, and set the branchStart and mergeCommits.
|
|
491
|
+
*/
|
|
492
|
+
parseMetaInformation(transaction) {
|
|
493
|
+
if (!transaction.meta ||
|
|
494
|
+
!transaction.isValid ||
|
|
495
|
+
transaction.hasMetaBeenParsed) {
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
transaction.hasMetaBeenParsed = true;
|
|
499
|
+
if (transaction.meta?.["branch"] &&
|
|
500
|
+
(!this.branchStart || transaction.madeAt < this.branchStart.madeAt)) {
|
|
501
|
+
this.branchStart = {
|
|
502
|
+
branch: transaction.meta.branch,
|
|
503
|
+
madeAt: transaction.madeAt,
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
if (transaction.meta?.["merge"]) {
|
|
507
|
+
const mergeCommit = transaction.meta;
|
|
508
|
+
this.mergeCommits.push({
|
|
509
|
+
commit: mergeCommit,
|
|
510
|
+
madeAt: transaction.madeAt,
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Loads the new transactions from SessionMap and:
|
|
516
|
+
* - Validates each transaction based on the group membership of the authors
|
|
517
|
+
* - Decodes the changes & meta for each transaction
|
|
518
|
+
* - Parses the meta information of the transaction
|
|
519
|
+
*/
|
|
520
|
+
parseNewTransactions(ignorePrivateTransactions) {
|
|
521
|
+
if (!this.isAvailable()) {
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
this.loadVerifiedTransactionsFromLogs();
|
|
525
|
+
this.determineValidTransactions();
|
|
526
|
+
for (const transaction of this.verifiedTransactions) {
|
|
527
|
+
decodeTransactionChangesAndMeta(this, transaction, ignorePrivateTransactions);
|
|
528
|
+
this.parseMetaInformation(transaction);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Returns the valid transactions matching the criteria specified in the options
|
|
533
|
+
*/
|
|
430
534
|
getValidTransactions(options) {
|
|
431
535
|
if (!this.verified) {
|
|
432
|
-
|
|
536
|
+
return [];
|
|
433
537
|
}
|
|
434
|
-
|
|
435
|
-
const
|
|
436
|
-
for (const
|
|
437
|
-
if (
|
|
538
|
+
this.parseNewTransactions(options?.ignorePrivateTransactions ?? false);
|
|
539
|
+
const matchingTransactions = [];
|
|
540
|
+
for (const transaction of this.verifiedTransactions) {
|
|
541
|
+
if (!isValidTransactionWithChanges(transaction)) {
|
|
438
542
|
continue;
|
|
439
543
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
if (options?.ignorePrivateTransactions) {
|
|
443
|
-
continue;
|
|
444
|
-
}
|
|
445
|
-
const readKey = this.getReadKey(tx.keyUsed);
|
|
446
|
-
if (!readKey) {
|
|
447
|
-
continue;
|
|
448
|
-
}
|
|
449
|
-
let decryptedChanges = this._decryptionCache[tx.encryptedChanges];
|
|
450
|
-
if (!decryptedChanges) {
|
|
451
|
-
decryptedChanges = this.verified.decryptTransaction(txID.sessionID, txID.txIndex, readKey);
|
|
452
|
-
this._decryptionCache[tx.encryptedChanges] = decryptedChanges;
|
|
453
|
-
}
|
|
454
|
-
if (!decryptedChanges) {
|
|
455
|
-
logger.error("Failed to decrypt transaction despite having key", {
|
|
456
|
-
err: new Error("Failed to decrypt transaction despite having key"),
|
|
457
|
-
});
|
|
458
|
-
continue;
|
|
459
|
-
}
|
|
460
|
-
changes = decryptedChanges;
|
|
544
|
+
if (options?.knownTransactions?.has(transaction.tx)) {
|
|
545
|
+
continue;
|
|
461
546
|
}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
});
|
|
470
|
-
continue;
|
|
471
|
-
}
|
|
547
|
+
options?.knownTransactions?.add(transaction.tx);
|
|
548
|
+
const { txID, madeAt } = transaction;
|
|
549
|
+
const from = options?.from?.[txID.sessionID] ?? -1;
|
|
550
|
+
const to = options?.to?.[txID.sessionID] ?? Infinity;
|
|
551
|
+
// The txIndex starts at 0 and from/to are referring to the count of transactions
|
|
552
|
+
if (from > txID.txIndex || to < txID.txIndex) {
|
|
553
|
+
continue;
|
|
472
554
|
}
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
555
|
+
matchingTransactions.push(transaction);
|
|
556
|
+
}
|
|
557
|
+
const source = getBranchSource(this);
|
|
558
|
+
// If this is a branch, we load the valid transactions from the source
|
|
559
|
+
if (source && this.branchStart && !options?.skipBranchSource) {
|
|
560
|
+
const sourceTransactions = source.getValidTransactions({
|
|
561
|
+
to: this.branchStart.branch,
|
|
562
|
+
ignorePrivateTransactions: options?.ignorePrivateTransactions ?? false,
|
|
563
|
+
knownTransactions: options?.knownTransactions,
|
|
478
564
|
});
|
|
565
|
+
for (const { changes, tx, madeAt, txID } of sourceTransactions) {
|
|
566
|
+
matchingTransactions.push({
|
|
567
|
+
txID: {
|
|
568
|
+
sessionID: `${txID.sessionID}_branch_${source.id}`,
|
|
569
|
+
txIndex: txID.txIndex,
|
|
570
|
+
},
|
|
571
|
+
madeAt,
|
|
572
|
+
changes,
|
|
573
|
+
tx,
|
|
574
|
+
});
|
|
575
|
+
}
|
|
479
576
|
}
|
|
480
|
-
return
|
|
577
|
+
return matchingTransactions;
|
|
578
|
+
}
|
|
579
|
+
createBranch(name, ownerId) {
|
|
580
|
+
return createBranch(this, name, ownerId);
|
|
581
|
+
}
|
|
582
|
+
mergeBranch() {
|
|
583
|
+
return mergeBranch(this);
|
|
584
|
+
}
|
|
585
|
+
getBranchId(name, ownerId) {
|
|
586
|
+
return getBranchId(this, name, ownerId);
|
|
481
587
|
}
|
|
482
588
|
getValidSortedTransactions(options) {
|
|
483
589
|
const allTransactions = this.getValidTransactions(options);
|
|
@@ -653,4 +759,7 @@ export class CoValueCore {
|
|
|
653
759
|
});
|
|
654
760
|
}
|
|
655
761
|
}
|
|
762
|
+
function isValidTransactionWithChanges(transaction) {
|
|
763
|
+
return Boolean(transaction.isValid && transaction.changes);
|
|
764
|
+
}
|
|
656
765
|
//# sourceMappingURL=coValueCore.js.map
|