cojson 0.18.19 → 0.18.20
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 +12 -0
- package/dist/GarbageCollector.d.ts +2 -1
- package/dist/GarbageCollector.d.ts.map +1 -1
- package/dist/GarbageCollector.js +3 -2
- package/dist/GarbageCollector.js.map +1 -1
- package/dist/coValueCore/coValueCore.d.ts +28 -25
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +128 -90
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValueCore/utils.d.ts +6 -0
- package/dist/coValueCore/utils.d.ts.map +1 -1
- package/dist/coValueCore/utils.js +53 -25
- package/dist/coValueCore/utils.js.map +1 -1
- package/dist/localNode.d.ts +5 -4
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +31 -37
- package/dist/localNode.js.map +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +56 -69
- package/dist/sync.js.map +1 -1
- package/dist/tests/GarbageCollector.test.js +14 -0
- package/dist/tests/GarbageCollector.test.js.map +1 -1
- package/dist/tests/SyncStateManager.test.js +1 -1
- package/dist/tests/coValueCore.dependencies.test.d.ts +2 -0
- package/dist/tests/coValueCore.dependencies.test.d.ts.map +1 -0
- package/dist/tests/coValueCore.dependencies.test.js +55 -0
- package/dist/tests/coValueCore.dependencies.test.js.map +1 -0
- package/dist/tests/coValueCore.test.js +2 -2
- package/dist/tests/coValueCore.test.js.map +1 -1
- package/dist/tests/coValueCoreLoadingState.test.js +43 -62
- package/dist/tests/coValueCoreLoadingState.test.js.map +1 -1
- package/dist/tests/permissions.test.js +117 -117
- package/dist/tests/permissions.test.js.map +1 -1
- package/dist/tests/sync.load.test.js +238 -9
- package/dist/tests/sync.load.test.js.map +1 -1
- package/dist/tests/sync.peerReconciliation.test.js +7 -6
- package/dist/tests/sync.peerReconciliation.test.js.map +1 -1
- package/dist/tests/testUtils.d.ts.map +1 -1
- package/dist/tests/testUtils.js +2 -1
- package/dist/tests/testUtils.js.map +1 -1
- package/package.json +2 -2
- package/src/GarbageCollector.ts +5 -2
- package/src/coValueCore/coValueCore.ts +172 -118
- package/src/coValueCore/utils.ts +85 -31
- package/src/localNode.ts +43 -48
- package/src/sync.ts +63 -89
- package/src/tests/GarbageCollector.test.ts +20 -0
- package/src/tests/SyncStateManager.test.ts +1 -1
- package/src/tests/coValueCore.dependencies.test.ts +90 -0
- package/src/tests/coValueCore.test.ts +2 -2
- package/src/tests/coValueCoreLoadingState.test.ts +50 -66
- package/src/tests/permissions.test.ts +120 -123
- package/src/tests/sync.load.test.ts +308 -9
- package/src/tests/sync.peerReconciliation.test.ts +7 -6
- package/src/tests/testUtils.ts +5 -3
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# cojson
|
|
2
2
|
|
|
3
|
+
## 0.18.20
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e75b3d6: Stop new content processing until all the dependencies are available, preventing inconsistent statuses on sync.
|
|
8
|
+
|
|
9
|
+
This targets a bug that would show up only after we roll out the sync server sharding features.
|
|
10
|
+
|
|
11
|
+
- ecf4967: Add garbageCollectGroups option to enableGarbageCollector
|
|
12
|
+
- d0e2210: Batch subscribe updates during the applyDiff execution
|
|
13
|
+
- cojson-core-wasm@0.18.20
|
|
14
|
+
|
|
3
15
|
## 0.18.19
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -2,8 +2,9 @@ import { CoValueCore } from "./coValueCore/coValueCore.js";
|
|
|
2
2
|
import { RawCoID } from "./ids.js";
|
|
3
3
|
export declare class GarbageCollector {
|
|
4
4
|
private readonly coValues;
|
|
5
|
+
private readonly garbageCollectGroups;
|
|
5
6
|
private readonly interval;
|
|
6
|
-
constructor(coValues: Map<RawCoID, CoValueCore
|
|
7
|
+
constructor(coValues: Map<RawCoID, CoValueCore>, garbageCollectGroups: boolean);
|
|
7
8
|
getCurrentTime(): number;
|
|
8
9
|
trackCoValueAccess({ verified }: CoValueCore): void;
|
|
9
10
|
collect(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GarbageCollector.d.ts","sourceRoot":"","sources":["../src/GarbageCollector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAE3D,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,qBAAa,gBAAgB;
|
|
1
|
+
{"version":3,"file":"GarbageCollector.d.ts","sourceRoot":"","sources":["../src/GarbageCollector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAE3D,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,qBAAa,gBAAgB;IAIzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,oBAAoB;IAJvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;gBAGvC,QAAQ,EAAE,GAAG,CAAC,OAAO,EAAE,WAAW,CAAC,EACnC,oBAAoB,EAAE,OAAO;IAOhD,cAAc;IAId,kBAAkB,CAAC,EAAE,QAAQ,EAAE,EAAE,WAAW;IAM5C,OAAO;IAiBP,IAAI;CAGL"}
|
package/dist/GarbageCollector.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { GARBAGE_COLLECTOR_CONFIG } from "./config.js";
|
|
2
2
|
export class GarbageCollector {
|
|
3
|
-
constructor(coValues) {
|
|
3
|
+
constructor(coValues, garbageCollectGroups) {
|
|
4
4
|
this.coValues = coValues;
|
|
5
|
+
this.garbageCollectGroups = garbageCollectGroups;
|
|
5
6
|
this.interval = setInterval(() => {
|
|
6
7
|
this.collect();
|
|
7
8
|
}, GARBAGE_COLLECTOR_CONFIG.INTERVAL);
|
|
@@ -23,7 +24,7 @@ export class GarbageCollector {
|
|
|
23
24
|
}
|
|
24
25
|
const timeSinceLastAccessed = currentTime - verified.lastAccessed;
|
|
25
26
|
if (timeSinceLastAccessed > GARBAGE_COLLECTOR_CONFIG.MAX_AGE) {
|
|
26
|
-
coValue.unmount();
|
|
27
|
+
coValue.unmount(this.garbageCollectGroups);
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GarbageCollector.js","sourceRoot":"","sources":["../src/GarbageCollector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAGvD,MAAM,OAAO,gBAAgB;IAG3B,
|
|
1
|
+
{"version":3,"file":"GarbageCollector.js","sourceRoot":"","sources":["../src/GarbageCollector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAGvD,MAAM,OAAO,gBAAgB;IAG3B,YACmB,QAAmC,EACnC,oBAA6B;QAD7B,aAAQ,GAAR,QAAQ,CAA2B;QACnC,yBAAoB,GAApB,oBAAoB,CAAS;QAE9C,IAAI,CAAC,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;YAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC,EAAE,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,cAAc;QACZ,OAAO,WAAW,CAAC,GAAG,EAAE,CAAC;IAC3B,CAAC;IAED,kBAAkB,CAAC,EAAE,QAAQ,EAAe;QAC1C,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,YAAY,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAChD,CAAC;IACH,CAAC;IAED,OAAO;QACL,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAC1C,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAC7C,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;YAE7B,IAAI,CAAC,QAAQ,EAAE,YAAY,EAAE,CAAC;gBAC5B,SAAS;YACX,CAAC;YAED,MAAM,qBAAqB,GAAG,WAAW,GAAG,QAAQ,CAAC,YAAY,CAAC;YAElE,IAAI,qBAAqB,GAAG,wBAAwB,CAAC,OAAO,EAAE,CAAC;gBAC7D,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI;QACF,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;CACF"}
|
|
@@ -7,7 +7,7 @@ import { CryptoProvider, Hash, KeyID, KeySecret, Signature, SignerID } from "../
|
|
|
7
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
|
-
import { CoValueKnownState, PeerID } from "../sync.js";
|
|
10
|
+
import { CoValueKnownState, NewContentMessage, PeerID } from "../sync.js";
|
|
11
11
|
import { CoValueHeader, Transaction, VerifiedState } from "./verifiedState.js";
|
|
12
12
|
import { MergeCommit, BranchPointerCommit, BranchStartCommit } from "./branching.js";
|
|
13
13
|
import { type RawAccountID } from "../coValues/account.js";
|
|
@@ -56,12 +56,12 @@ export declare class CoValueCore {
|
|
|
56
56
|
private readonly peers;
|
|
57
57
|
private _cachedContent?;
|
|
58
58
|
readonly listeners: Set<(core: CoValueCore, unsub: () => void) => void>;
|
|
59
|
-
private _cachedDependentOn?;
|
|
60
59
|
private counter;
|
|
61
60
|
private constructor();
|
|
62
61
|
static fromID(id: RawCoID, node: LocalNode): CoValueCore;
|
|
63
62
|
static fromHeader(header: CoValueHeader, node: LocalNode): AvailableCoValueCore;
|
|
64
63
|
get loadingState(): "unavailable" | "available" | "unknown" | "loading";
|
|
64
|
+
hasMissingDependencies(): boolean;
|
|
65
65
|
isAvailable(): this is AvailableCoValueCore;
|
|
66
66
|
hasVerifiedContent(): this is AvailableCoValueCore;
|
|
67
67
|
isErroredInPeer(peerId: PeerID): boolean;
|
|
@@ -75,34 +75,41 @@ export declare class CoValueCore {
|
|
|
75
75
|
error: TryAddTransactionsError;
|
|
76
76
|
} | undefined;
|
|
77
77
|
private updateCounter;
|
|
78
|
-
unmount(): boolean;
|
|
78
|
+
unmount(garbageCollectGroups?: boolean): boolean;
|
|
79
79
|
markNotFoundInPeer(peerId: PeerID): void;
|
|
80
|
+
markFoundInPeer(peerId: PeerID, previousState: string): void;
|
|
80
81
|
missingDependencies: Set<`co_z${string}`>;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
82
|
+
isCircularMissingDependency(dependency: CoValueCore): boolean;
|
|
83
|
+
markDependencyAvailable(dependency: RawCoID): void;
|
|
84
|
+
newContentQueue: {
|
|
85
|
+
msg: NewContentMessage;
|
|
86
|
+
from: PeerState | "storage" | "import";
|
|
87
|
+
}[];
|
|
88
|
+
/**
|
|
89
|
+
* Add a new content to the queue and handle it when the dependencies are available
|
|
90
|
+
*/
|
|
91
|
+
addNewContentToQueue(msg: NewContentMessage, from: PeerState | "storage" | "import"): void;
|
|
92
|
+
addDependencyFromHeader(header: CoValueHeader): void;
|
|
93
|
+
provideHeader(header: CoValueHeader, streamingKnownState?: CoValueKnownState["sessions"], skipVerify?: boolean): boolean;
|
|
87
94
|
markErrored(peerId: PeerID, error: TryAddTransactionsError): void;
|
|
88
95
|
markPending(peerId: PeerID): void;
|
|
89
|
-
internalShamefullyCloneVerifiedStateFrom(state: VerifiedState, { forceOverwrite }?: {
|
|
90
|
-
forceOverwrite?: boolean;
|
|
91
|
-
}): void;
|
|
92
|
-
internalShamefullyResetCachedContent(): void;
|
|
93
96
|
groupInvalidationSubscription?: () => void;
|
|
94
97
|
subscribeToGroupInvalidation(): void;
|
|
95
|
-
contentInClonedNodeWithDifferentAccount(account: ControlledAccountOrAgent): RawCoValue
|
|
98
|
+
contentInClonedNodeWithDifferentAccount(account: ControlledAccountOrAgent): Promise<RawCoValue>;
|
|
96
99
|
knownStateWithStreaming(): CoValueKnownState;
|
|
97
100
|
knownState(): CoValueKnownState;
|
|
98
101
|
get meta(): JsonValue;
|
|
99
102
|
nextTransactionID(): TransactionID;
|
|
103
|
+
addDependenciesFromContentMessage(newContent: NewContentMessage): void;
|
|
100
104
|
tryAddTransactions(sessionID: SessionID, newTransactions: Transaction[], newSignature: Signature, skipVerify?: boolean): Result<true, TryAddTransactionsError>;
|
|
101
|
-
private
|
|
105
|
+
private processNewTransactions;
|
|
102
106
|
private scheduleNotifyUpdate;
|
|
107
|
+
pauseNotifyUpdate(): void;
|
|
108
|
+
resumeNotifyUpdate(): void;
|
|
103
109
|
private notifyUpdate;
|
|
104
110
|
subscribe(listener: (core: CoValueCore, unsub: () => void) => void, immediateInvoke?: boolean): () => void;
|
|
105
111
|
makeTransaction(changes: JsonValue[], privacy: "private" | "trusting", meta?: JsonObject, madeAt?: number): boolean;
|
|
112
|
+
addDependenciesFromNewTransaction(transaction: Transaction): void;
|
|
106
113
|
getCurrentContent(options?: {
|
|
107
114
|
ignorePrivateTransactions: true;
|
|
108
115
|
}): RawCoValue;
|
|
@@ -115,23 +122,17 @@ export declare class CoValueCore {
|
|
|
115
122
|
verifiedTransactions: VerifiedTransaction[];
|
|
116
123
|
private verifiedTransactionsKnownSessions;
|
|
117
124
|
private lastVerifiedTransactionBySessionID;
|
|
125
|
+
private parsingCache;
|
|
118
126
|
/**
|
|
119
127
|
* Loads the new transaction from the SessionMap into verifiedTransactions as a VerifiedTransaction.
|
|
120
128
|
*
|
|
121
129
|
* If the transaction is already loaded from the SessionMap in the past, it will not be loaded again.
|
|
122
130
|
*
|
|
123
131
|
* Used to have a fast way to iterate over the CoValue transactions, and track their validation/decoding state.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
* If provided, the transaction will be preloaded with the given changes and meta.
|
|
127
|
-
*
|
|
128
|
-
* @internal
|
|
132
|
+
|
|
133
|
+
* @internal
|
|
129
134
|
* */
|
|
130
|
-
loadVerifiedTransactionsFromLogs(
|
|
131
|
-
transaction: Transaction;
|
|
132
|
-
changes: JsonValue[];
|
|
133
|
-
meta: JsonObject | undefined;
|
|
134
|
-
}): void;
|
|
135
|
+
loadVerifiedTransactionsFromLogs(): void;
|
|
135
136
|
/**
|
|
136
137
|
* Iterates over the verifiedTransactions and marks them as valid or invalid, based on the group membership of the authors of the transactions .
|
|
137
138
|
*/
|
|
@@ -157,6 +158,8 @@ export declare class CoValueCore {
|
|
|
157
158
|
knownTransactions?: Set<Transaction>;
|
|
158
159
|
skipBranchSource?: boolean;
|
|
159
160
|
}): DecryptedTransaction[];
|
|
161
|
+
dependencies: Set<RawCoID>;
|
|
162
|
+
private addDependency;
|
|
160
163
|
createBranch(name: string, ownerId?: RawCoID): CoValueCore;
|
|
161
164
|
mergeBranch(): CoValueCore;
|
|
162
165
|
getBranch(name: string, ownerId?: RawCoID): CoValueCore;
|
|
@@ -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;AAIrD,OAAO,EACL,cAAc,EACd,IAAI,EACJ,KAAK,EACL,SAAS,EACT,SAAS,EACT,QAAQ,EACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAGtE,OAAO,
|
|
1
|
+
{"version":3,"file":"coValueCore.d.ts","sourceRoot":"","sources":["../../src/coValueCore/coValueCore.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _CoValueCore_isNotificationScheduled, _CoValueCore_batchedUpdates;
|
|
12
|
+
var _CoValueCore_isNotificationScheduled, _CoValueCore_batchedUpdates, _CoValueCore_isNotifyUpdatePaused;
|
|
13
13
|
import { ValueType, metrics } from "@opentelemetry/api";
|
|
14
14
|
import { err, ok } from "neverthrow";
|
|
15
15
|
import { CO_VALUE_LOADING_CONFIG } from "../config.js";
|
|
@@ -17,10 +17,10 @@ import { validateTxSizeLimitInBytes } from "../coValueContentMessage.js";
|
|
|
17
17
|
import { coreToCoValue } from "../coreToCoValue.js";
|
|
18
18
|
import { logger } from "../logger.js";
|
|
19
19
|
import { determineValidTransactions } from "../permissions.js";
|
|
20
|
-
import { emptyKnownState } from "../sync.js";
|
|
20
|
+
import { emptyKnownState, } from "../sync.js";
|
|
21
21
|
import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfromSessionID.js";
|
|
22
22
|
import { expectGroup } from "../typeUtils/expectGroup.js";
|
|
23
|
-
import {
|
|
23
|
+
import { getDependenciesFromContentMessage, getDependenciesFromGroupRawTransactions, getDependenciesFromHeader, } from "./utils.js";
|
|
24
24
|
import { VerifiedState } from "./verifiedState.js";
|
|
25
25
|
import { SessionMap } from "./SessionMap.js";
|
|
26
26
|
import { createBranch, getBranchId, getBranchOwnerId, getBranchSource, mergeBranch, } from "./branching.js";
|
|
@@ -49,8 +49,10 @@ export class CoValueCore {
|
|
|
49
49
|
this.peers = new Map();
|
|
50
50
|
this.listeners = new Set();
|
|
51
51
|
this.missingDependencies = new Set();
|
|
52
|
+
this.newContentQueue = [];
|
|
52
53
|
_CoValueCore_isNotificationScheduled.set(this, false);
|
|
53
54
|
_CoValueCore_batchedUpdates.set(this, false);
|
|
55
|
+
_CoValueCore_isNotifyUpdatePaused.set(this, false);
|
|
54
56
|
// The list of merge commits that have been made
|
|
55
57
|
this.mergeCommits = [];
|
|
56
58
|
this.branches = [];
|
|
@@ -59,6 +61,8 @@ export class CoValueCore {
|
|
|
59
61
|
this.verifiedTransactions = [];
|
|
60
62
|
this.verifiedTransactionsKnownSessions = {};
|
|
61
63
|
this.lastVerifiedTransactionBySessionID = {};
|
|
64
|
+
this.parsingCache = new Map();
|
|
65
|
+
this.dependencies = new Set();
|
|
62
66
|
this.readKeyCache = new Map();
|
|
63
67
|
this.crypto = node.crypto;
|
|
64
68
|
if ("header" in init) {
|
|
@@ -102,8 +106,11 @@ export class CoValueCore {
|
|
|
102
106
|
}
|
|
103
107
|
return "unavailable";
|
|
104
108
|
}
|
|
109
|
+
hasMissingDependencies() {
|
|
110
|
+
return this.missingDependencies.size > 0;
|
|
111
|
+
}
|
|
105
112
|
isAvailable() {
|
|
106
|
-
return this.hasVerifiedContent()
|
|
113
|
+
return this.hasVerifiedContent();
|
|
107
114
|
}
|
|
108
115
|
hasVerifiedContent() {
|
|
109
116
|
return !!this.verified;
|
|
@@ -159,9 +166,9 @@ export class CoValueCore {
|
|
|
159
166
|
this.counter.add(1, { state: newState });
|
|
160
167
|
}
|
|
161
168
|
}
|
|
162
|
-
unmount() {
|
|
163
|
-
|
|
164
|
-
|
|
169
|
+
unmount(garbageCollectGroups = false) {
|
|
170
|
+
if (!garbageCollectGroups &&
|
|
171
|
+
this.verified?.header.ruleset.type === "group") {
|
|
165
172
|
return false;
|
|
166
173
|
}
|
|
167
174
|
if (this.listeners.size > 0) {
|
|
@@ -181,68 +188,76 @@ export class CoValueCore {
|
|
|
181
188
|
this.updateCounter(previousState);
|
|
182
189
|
this.scheduleNotifyUpdate();
|
|
183
190
|
}
|
|
184
|
-
|
|
185
|
-
|
|
191
|
+
markFoundInPeer(peerId, previousState) {
|
|
192
|
+
this.peers.set(peerId, { type: "available" });
|
|
193
|
+
this.updateCounter(previousState);
|
|
194
|
+
this.scheduleNotifyUpdate();
|
|
195
|
+
}
|
|
196
|
+
isCircularMissingDependency(dependency) {
|
|
186
197
|
const visited = new Set();
|
|
187
198
|
const stack = [dependency];
|
|
188
199
|
while (stack.length > 0) {
|
|
189
200
|
const current = stack.pop();
|
|
190
201
|
if (!current) {
|
|
191
|
-
return
|
|
202
|
+
return false;
|
|
192
203
|
}
|
|
193
204
|
visited.add(current.id);
|
|
194
205
|
for (const dependency of current.missingDependencies) {
|
|
195
206
|
if (dependency === this.id) {
|
|
196
|
-
return
|
|
207
|
+
return true;
|
|
197
208
|
}
|
|
198
209
|
if (!visited.has(dependency)) {
|
|
199
210
|
stack.push(this.node.getCoValue(dependency));
|
|
200
211
|
}
|
|
201
212
|
}
|
|
202
213
|
}
|
|
203
|
-
return
|
|
214
|
+
return false;
|
|
204
215
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
if (
|
|
208
|
-
this.
|
|
216
|
+
markDependencyAvailable(dependency) {
|
|
217
|
+
this.missingDependencies.delete(dependency);
|
|
218
|
+
if (this.missingDependencies.size === 0) {
|
|
219
|
+
this.scheduleNotifyUpdate();
|
|
209
220
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Add a new content to the queue and handle it when the dependencies are available
|
|
224
|
+
*/
|
|
225
|
+
addNewContentToQueue(msg, from) {
|
|
226
|
+
const alreadyEnqueued = this.newContentQueue.length > 0;
|
|
227
|
+
this.newContentQueue.push({ msg, from });
|
|
228
|
+
if (alreadyEnqueued) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
this.subscribe((core, unsubscribe) => {
|
|
232
|
+
if (!core.hasMissingDependencies()) {
|
|
233
|
+
unsubscribe();
|
|
234
|
+
const enqueuedNewContent = this.newContentQueue;
|
|
235
|
+
this.newContentQueue = [];
|
|
236
|
+
for (const { msg, from } of enqueuedNewContent) {
|
|
237
|
+
this.node.syncManager.handleNewContent(msg, from);
|
|
218
238
|
}
|
|
219
|
-
}
|
|
220
|
-
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
addDependencyFromHeader(header) {
|
|
243
|
+
for (const dep of getDependenciesFromHeader(header)) {
|
|
244
|
+
this.addDependency(dep);
|
|
221
245
|
}
|
|
222
246
|
}
|
|
223
|
-
provideHeader(header,
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
247
|
+
provideHeader(header, streamingKnownState, skipVerify) {
|
|
248
|
+
if (!skipVerify) {
|
|
249
|
+
const expectedId = idforHeader(header, this.node.crypto);
|
|
250
|
+
if (this.id !== expectedId) {
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
228
253
|
}
|
|
254
|
+
this.addDependencyFromHeader(header);
|
|
229
255
|
if (this._verified?.sessions.size) {
|
|
230
256
|
throw new Error("CoValueCore: provideHeader called on coValue with verified sessions present!");
|
|
231
257
|
}
|
|
232
258
|
this._verified = new VerifiedState(this.id, this.node.crypto, header, new SessionMap(this.id, this.node.crypto), streamingKnownState);
|
|
233
|
-
this.peers.set(fromPeerId, { type: "available" });
|
|
234
|
-
this.updateCounter(previousState);
|
|
235
|
-
this.scheduleNotifyUpdate();
|
|
236
259
|
return true;
|
|
237
260
|
}
|
|
238
|
-
internalMarkMagicallyAvailable(verified, { forceOverwrite = false } = {}) {
|
|
239
|
-
const previousState = this.loadingState;
|
|
240
|
-
this.internalShamefullyCloneVerifiedStateFrom(verified, {
|
|
241
|
-
forceOverwrite,
|
|
242
|
-
});
|
|
243
|
-
this.updateCounter(previousState);
|
|
244
|
-
this.scheduleNotifyUpdate();
|
|
245
|
-
}
|
|
246
261
|
markErrored(peerId, error) {
|
|
247
262
|
const previousState = this.loadingState;
|
|
248
263
|
this.peers.set(peerId, { type: "errored", error });
|
|
@@ -255,18 +270,6 @@ export class CoValueCore {
|
|
|
255
270
|
this.updateCounter(previousState);
|
|
256
271
|
this.scheduleNotifyUpdate();
|
|
257
272
|
}
|
|
258
|
-
internalShamefullyCloneVerifiedStateFrom(state, { forceOverwrite = false } = {}) {
|
|
259
|
-
if (!forceOverwrite && this._verified?.sessions.size) {
|
|
260
|
-
throw new Error("CoValueCore: internalShamefullyCloneVerifiedStateFrom called on coValue with verified sessions present!");
|
|
261
|
-
}
|
|
262
|
-
this._verified = state.clone();
|
|
263
|
-
this.internalShamefullyResetCachedContent();
|
|
264
|
-
}
|
|
265
|
-
internalShamefullyResetCachedContent() {
|
|
266
|
-
this._cachedContent = undefined;
|
|
267
|
-
this._cachedDependentOn = undefined;
|
|
268
|
-
this.resetParsedTransactions();
|
|
269
|
-
}
|
|
270
273
|
subscribeToGroupInvalidation() {
|
|
271
274
|
if (!this.verified) {
|
|
272
275
|
return;
|
|
@@ -281,7 +284,7 @@ export class CoValueCore {
|
|
|
281
284
|
if (entry.isAvailable()) {
|
|
282
285
|
this.groupInvalidationSubscription = entry.subscribe((_groupUpdate) => {
|
|
283
286
|
// When the group is updated, we need to reset the cached content because the transactions validity might have changed
|
|
284
|
-
this.
|
|
287
|
+
this.resetParsedTransactions();
|
|
285
288
|
this.scheduleNotifyUpdate();
|
|
286
289
|
}, false);
|
|
287
290
|
}
|
|
@@ -296,7 +299,7 @@ export class CoValueCore {
|
|
|
296
299
|
contentInClonedNodeWithDifferentAccount(account) {
|
|
297
300
|
return this.node
|
|
298
301
|
.loadCoValueAsDifferentAgent(this.id, account.agentSecret, account.id)
|
|
299
|
-
.getCurrentContent();
|
|
302
|
+
.then((core) => core.getCurrentContent());
|
|
300
303
|
}
|
|
301
304
|
knownStateWithStreaming() {
|
|
302
305
|
if (this.verified) {
|
|
@@ -330,6 +333,12 @@ export class CoValueCore {
|
|
|
330
333
|
txIndex: this.verified.sessions.get(sessionID)?.transactions.length || 0,
|
|
331
334
|
};
|
|
332
335
|
}
|
|
336
|
+
addDependenciesFromContentMessage(newContent) {
|
|
337
|
+
const dependencies = getDependenciesFromContentMessage(this, newContent);
|
|
338
|
+
for (const dependency of dependencies) {
|
|
339
|
+
this.addDependency(dependency);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
333
342
|
tryAddTransactions(sessionID, newTransactions, newSignature, skipVerify = false) {
|
|
334
343
|
let result;
|
|
335
344
|
if (skipVerify) {
|
|
@@ -351,22 +360,23 @@ export class CoValueCore {
|
|
|
351
360
|
}
|
|
352
361
|
const result = this.verified.tryAddTransactions(sessionID, signerID, newTransactions, newSignature, skipVerify);
|
|
353
362
|
if (result.isOk()) {
|
|
354
|
-
this.
|
|
363
|
+
this.processNewTransactions();
|
|
355
364
|
this.scheduleNotifyUpdate();
|
|
356
365
|
}
|
|
357
366
|
return result;
|
|
358
367
|
});
|
|
359
368
|
}
|
|
360
|
-
|
|
361
|
-
if (this._cachedContent
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
369
|
+
processNewTransactions() {
|
|
370
|
+
if (this._cachedContent) {
|
|
371
|
+
// Does the cached content support incremental processing?
|
|
372
|
+
if ("processNewTransactions" in this._cachedContent &&
|
|
373
|
+
typeof this._cachedContent.processNewTransactions === "function") {
|
|
374
|
+
this._cachedContent.processNewTransactions();
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
this._cachedContent = undefined;
|
|
378
|
+
}
|
|
368
379
|
}
|
|
369
|
-
this._cachedDependentOn = undefined;
|
|
370
380
|
}
|
|
371
381
|
scheduleNotifyUpdate() {
|
|
372
382
|
if (this.listeners.size === 0) {
|
|
@@ -384,8 +394,15 @@ export class CoValueCore {
|
|
|
384
394
|
});
|
|
385
395
|
}
|
|
386
396
|
}
|
|
397
|
+
pauseNotifyUpdate() {
|
|
398
|
+
__classPrivateFieldSet(this, _CoValueCore_isNotifyUpdatePaused, true, "f");
|
|
399
|
+
}
|
|
400
|
+
resumeNotifyUpdate() {
|
|
401
|
+
__classPrivateFieldSet(this, _CoValueCore_isNotifyUpdatePaused, false, "f");
|
|
402
|
+
this.notifyUpdate();
|
|
403
|
+
}
|
|
387
404
|
notifyUpdate() {
|
|
388
|
-
if (this.listeners.size === 0) {
|
|
405
|
+
if (this.listeners.size === 0 || __classPrivateFieldGet(this, _CoValueCore_isNotifyUpdatePaused, "f")) {
|
|
389
406
|
return;
|
|
390
407
|
}
|
|
391
408
|
__classPrivateFieldSet(this, _CoValueCore_batchedUpdates, false, "f");
|
|
@@ -433,18 +450,29 @@ export class CoValueCore {
|
|
|
433
450
|
result = this.verified.makeNewTrustingTransaction(sessionID, signerAgent, changes, meta, madeAt ?? Date.now());
|
|
434
451
|
}
|
|
435
452
|
const { transaction, signature } = result;
|
|
453
|
+
// Assign pre-parsed meta and changes to skip the parse/decrypt operation when loading
|
|
454
|
+
// this transaction in the current content
|
|
455
|
+
this.parsingCache.set(transaction, { changes, meta });
|
|
436
456
|
this.node.syncManager.recordTransactionsSize([transaction], "local");
|
|
437
|
-
// We pre-populate the parsed transactions and meta for the new transaction, to skip the parsing step later
|
|
438
|
-
this.loadVerifiedTransactionsFromLogs({ transaction, changes, meta });
|
|
439
457
|
const session = this.verified.sessions.get(sessionID);
|
|
440
458
|
const txIdx = session ? session.transactions.length - 1 : 0;
|
|
441
|
-
this.
|
|
459
|
+
this.processNewTransactions();
|
|
460
|
+
this.addDependenciesFromNewTransaction(transaction);
|
|
442
461
|
// force immediate notification because local updates may come from the UI
|
|
443
462
|
// where we need synchronous updates
|
|
444
463
|
this.notifyUpdate();
|
|
445
464
|
this.node.syncManager.syncLocalTransaction(this.verified, transaction, sessionID, signature, txIdx);
|
|
446
465
|
return true;
|
|
447
466
|
}
|
|
467
|
+
addDependenciesFromNewTransaction(transaction) {
|
|
468
|
+
if (this.verified?.header.ruleset.type === "group") {
|
|
469
|
+
for (const dependency of getDependenciesFromGroupRawTransactions([
|
|
470
|
+
transaction,
|
|
471
|
+
])) {
|
|
472
|
+
this.addDependency(dependency);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
448
476
|
getCurrentContent(options) {
|
|
449
477
|
if (!this.verified) {
|
|
450
478
|
throw new Error("CoValueCore: getCurrentContent called on coValue without verified state");
|
|
@@ -461,6 +489,7 @@ export class CoValueCore {
|
|
|
461
489
|
}
|
|
462
490
|
// Reset the parsed transactions and branches, to validate them again from scratch when the group is updated
|
|
463
491
|
resetParsedTransactions() {
|
|
492
|
+
this._cachedContent = undefined;
|
|
464
493
|
this.branchStart = undefined;
|
|
465
494
|
this.mergeCommits = [];
|
|
466
495
|
for (const transaction of this.verifiedTransactions) {
|
|
@@ -474,13 +503,10 @@ export class CoValueCore {
|
|
|
474
503
|
* If the transaction is already loaded from the SessionMap in the past, it will not be loaded again.
|
|
475
504
|
*
|
|
476
505
|
* Used to have a fast way to iterate over the CoValue transactions, and track their validation/decoding state.
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
* If provided, the transaction will be preloaded with the given changes and meta.
|
|
480
|
-
*
|
|
481
|
-
* @internal
|
|
506
|
+
|
|
507
|
+
* @internal
|
|
482
508
|
* */
|
|
483
|
-
loadVerifiedTransactionsFromLogs(
|
|
509
|
+
loadVerifiedTransactionsFromLogs() {
|
|
484
510
|
if (!this.verified) {
|
|
485
511
|
return;
|
|
486
512
|
}
|
|
@@ -501,14 +527,18 @@ export class CoValueCore {
|
|
|
501
527
|
sessionID,
|
|
502
528
|
txIndex,
|
|
503
529
|
};
|
|
530
|
+
const cache = this.parsingCache.get(tx);
|
|
531
|
+
if (cache) {
|
|
532
|
+
this.parsingCache.delete(tx);
|
|
533
|
+
}
|
|
504
534
|
const verifiedTransaction = {
|
|
505
535
|
author: accountOrAgentIDfromSessionID(sessionID),
|
|
506
536
|
txID,
|
|
507
537
|
madeAt: tx.madeAt,
|
|
508
538
|
isValidated: false,
|
|
509
539
|
isValid: false,
|
|
510
|
-
changes:
|
|
511
|
-
meta:
|
|
540
|
+
changes: cache?.changes,
|
|
541
|
+
meta: cache?.meta,
|
|
512
542
|
hasInvalidChanges: false,
|
|
513
543
|
hasInvalidMeta: false,
|
|
514
544
|
hasMetaBeenParsed: false,
|
|
@@ -647,6 +677,24 @@ export class CoValueCore {
|
|
|
647
677
|
}
|
|
648
678
|
return matchingTransactions;
|
|
649
679
|
}
|
|
680
|
+
addDependency(dependency) {
|
|
681
|
+
if (this.dependencies.has(dependency)) {
|
|
682
|
+
return true;
|
|
683
|
+
}
|
|
684
|
+
this.dependencies.add(dependency);
|
|
685
|
+
const dependencyCoValue = this.node.getCoValue(dependency);
|
|
686
|
+
if (!dependencyCoValue.isAvailable() &&
|
|
687
|
+
!this.isCircularMissingDependency(dependencyCoValue)) {
|
|
688
|
+
this.missingDependencies.add(dependency);
|
|
689
|
+
dependencyCoValue.subscribe((dependencyCoValue, unsubscribe) => {
|
|
690
|
+
if (dependencyCoValue.isAvailable()) {
|
|
691
|
+
unsubscribe();
|
|
692
|
+
this.markDependencyAvailable(dependency);
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
return false;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
650
698
|
createBranch(name, ownerId) {
|
|
651
699
|
return createBranch(this, name, ownerId);
|
|
652
700
|
}
|
|
@@ -759,17 +807,7 @@ export class CoValueCore {
|
|
|
759
807
|
return this.verified?.sessions.get(txID.sessionID)?.transactions[txID.txIndex];
|
|
760
808
|
}
|
|
761
809
|
getDependedOnCoValues() {
|
|
762
|
-
|
|
763
|
-
return this._cachedDependentOn;
|
|
764
|
-
}
|
|
765
|
-
else {
|
|
766
|
-
if (!this.verified) {
|
|
767
|
-
return new Set();
|
|
768
|
-
}
|
|
769
|
-
const dependentOn = getDependedOnCoValuesFromRawData(this.id, this.verified.header, this.verified.sessions.keys(), Array.from(this.verified.sessions.values(), (session) => session.transactions));
|
|
770
|
-
this._cachedDependentOn = dependentOn;
|
|
771
|
-
return dependentOn;
|
|
772
|
-
}
|
|
810
|
+
return this.dependencies;
|
|
773
811
|
}
|
|
774
812
|
waitForSync(options) {
|
|
775
813
|
return this.node.syncManager.waitForSync(this.id, options?.timeout);
|
|
@@ -862,7 +900,7 @@ export class CoValueCore {
|
|
|
862
900
|
});
|
|
863
901
|
}
|
|
864
902
|
}
|
|
865
|
-
_CoValueCore_isNotificationScheduled = new WeakMap(), _CoValueCore_batchedUpdates = new WeakMap();
|
|
903
|
+
_CoValueCore_isNotificationScheduled = new WeakMap(), _CoValueCore_batchedUpdates = new WeakMap(), _CoValueCore_isNotifyUpdatePaused = new WeakMap();
|
|
866
904
|
function isValidTransactionWithChanges(transaction) {
|
|
867
905
|
return Boolean(transaction.isValid && transaction.changes);
|
|
868
906
|
}
|