cojson 0.10.0 → 0.10.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 +2 -10
- package/CHANGELOG.md +7 -0
- package/dist/CoValuesStore.js.map +1 -0
- package/dist/PeerKnownStates.js.map +1 -0
- package/dist/PeerState.js.map +1 -0
- package/dist/PriorityBasedMessageQueue.js.map +1 -0
- package/dist/SyncStateManager.js.map +1 -0
- package/dist/base64url.js.map +1 -0
- package/dist/base64url.test.js.map +1 -0
- package/dist/coValue.js.map +1 -0
- package/dist/coValueCore.js.map +1 -0
- package/dist/coValueState.js.map +1 -0
- package/dist/coValues/account.js.map +1 -0
- package/dist/coValues/coList.js.map +1 -0
- package/dist/coValues/coMap.js.map +1 -0
- package/dist/coValues/coPlainText.js.map +1 -0
- package/dist/coValues/coStream.js.map +1 -0
- package/dist/coValues/group.js.map +1 -0
- package/dist/coreToCoValue.js.map +1 -0
- package/dist/crypto/PureJSCrypto.js.map +1 -0
- package/dist/crypto/WasmCrypto.js.map +1 -0
- package/dist/crypto/crypto.js.map +1 -0
- package/dist/exports.js.map +1 -0
- package/dist/ids.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/jsonStringify.js.map +1 -0
- package/dist/{native/jsonValue.js.map → jsonValue.js.map} +1 -1
- package/dist/localNode.js.map +1 -0
- package/dist/logger.js.map +1 -0
- package/dist/media.js.map +1 -0
- package/dist/permissions.js.map +1 -0
- package/dist/priority.js.map +1 -0
- package/dist/storage/FileSystem.js.map +1 -0
- package/dist/storage/chunksAndKnownStates.js.map +1 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/streamUtils.js.map +1 -0
- package/dist/sync.js.map +1 -0
- package/dist/typeUtils/accountOrAgentIDfromSessionID.js.map +1 -0
- package/dist/typeUtils/expectGroup.js.map +1 -0
- package/dist/typeUtils/isAccountID.js.map +1 -0
- package/dist/typeUtils/isCoValue.js.map +1 -0
- package/package.json +19 -21
- package/src/exports.ts +1 -0
- package/src/index.ts +1 -0
- package/tsconfig.json +3 -1
- package/dist/native/CoValuesStore.js.map +0 -1
- package/dist/native/PeerKnownStates.js.map +0 -1
- package/dist/native/PeerState.js.map +0 -1
- package/dist/native/PriorityBasedMessageQueue.js.map +0 -1
- package/dist/native/SyncStateManager.js.map +0 -1
- package/dist/native/base64url.js.map +0 -1
- package/dist/native/base64url.test.js.map +0 -1
- package/dist/native/coValue.js.map +0 -1
- package/dist/native/coValueCore.js.map +0 -1
- package/dist/native/coValueState.js.map +0 -1
- package/dist/native/coValues/account.js.map +0 -1
- package/dist/native/coValues/coList.js.map +0 -1
- package/dist/native/coValues/coMap.js.map +0 -1
- package/dist/native/coValues/coPlainText.js.map +0 -1
- package/dist/native/coValues/coStream.js.map +0 -1
- package/dist/native/coValues/group.js.map +0 -1
- package/dist/native/coreToCoValue.js.map +0 -1
- package/dist/native/crypto/PureJSCrypto.js.map +0 -1
- package/dist/native/crypto/WasmCrypto.js.map +0 -1
- package/dist/native/crypto/crypto.js.map +0 -1
- package/dist/native/crypto/export.js +0 -3
- package/dist/native/crypto/export.js.map +0 -1
- package/dist/native/exports.js.map +0 -1
- package/dist/native/ids.js.map +0 -1
- package/dist/native/index.native.js +0 -3
- package/dist/native/index.native.js.map +0 -1
- package/dist/native/jsonStringify.js.map +0 -1
- package/dist/native/localNode.js.map +0 -1
- package/dist/native/logger.js.map +0 -1
- package/dist/native/media.js.map +0 -1
- package/dist/native/permissions.js.map +0 -1
- package/dist/native/priority.js.map +0 -1
- package/dist/native/storage/FileSystem.js.map +0 -1
- package/dist/native/storage/chunksAndKnownStates.js.map +0 -1
- package/dist/native/storage/index.js.map +0 -1
- package/dist/native/streamUtils.js.map +0 -1
- package/dist/native/sync.js.map +0 -1
- package/dist/native/typeUtils/accountOrAgentIDfromSessionID.js.map +0 -1
- package/dist/native/typeUtils/expectGroup.js.map +0 -1
- package/dist/native/typeUtils/isAccountID.js.map +0 -1
- package/dist/native/typeUtils/isCoValue.js.map +0 -1
- package/dist/web/CoValuesStore.js +0 -31
- package/dist/web/CoValuesStore.js.map +0 -1
- package/dist/web/PeerKnownStates.js +0 -68
- package/dist/web/PeerKnownStates.js.map +0 -1
- package/dist/web/PeerState.js +0 -103
- package/dist/web/PeerState.js.map +0 -1
- package/dist/web/PriorityBasedMessageQueue.js +0 -98
- package/dist/web/PriorityBasedMessageQueue.js.map +0 -1
- package/dist/web/SyncStateManager.js +0 -94
- package/dist/web/SyncStateManager.js.map +0 -1
- package/dist/web/base64url.js +0 -53
- package/dist/web/base64url.js.map +0 -1
- package/dist/web/base64url.test.js +0 -25
- package/dist/web/base64url.test.js.map +0 -1
- package/dist/web/coValue.js +0 -52
- package/dist/web/coValue.js.map +0 -1
- package/dist/web/coValueCore.js +0 -597
- package/dist/web/coValueCore.js.map +0 -1
- package/dist/web/coValueState.js +0 -267
- package/dist/web/coValueState.js.map +0 -1
- package/dist/web/coValues/account.js +0 -100
- package/dist/web/coValues/account.js.map +0 -1
- package/dist/web/coValues/coList.js +0 -381
- package/dist/web/coValues/coList.js.map +0 -1
- package/dist/web/coValues/coMap.js +0 -273
- package/dist/web/coValues/coMap.js.map +0 -1
- package/dist/web/coValues/coPlainText.js +0 -86
- package/dist/web/coValues/coPlainText.js.map +0 -1
- package/dist/web/coValues/coStream.js +0 -224
- package/dist/web/coValues/coStream.js.map +0 -1
- package/dist/web/coValues/group.js +0 -522
- package/dist/web/coValues/group.js.map +0 -1
- package/dist/web/coreToCoValue.js +0 -46
- package/dist/web/coreToCoValue.js.map +0 -1
- package/dist/web/crypto/PureJSCrypto.js +0 -94
- package/dist/web/crypto/PureJSCrypto.js.map +0 -1
- package/dist/web/crypto/WasmCrypto.js +0 -115
- package/dist/web/crypto/WasmCrypto.js.map +0 -1
- package/dist/web/crypto/crypto.js +0 -152
- package/dist/web/crypto/crypto.js.map +0 -1
- package/dist/web/crypto/export.js +0 -3
- package/dist/web/crypto/export.js.map +0 -1
- package/dist/web/exports.js +0 -48
- package/dist/web/exports.js.map +0 -1
- package/dist/web/ids.js +0 -50
- package/dist/web/ids.js.map +0 -1
- package/dist/web/index.web.js +0 -3
- package/dist/web/index.web.js.map +0 -1
- package/dist/web/jsonStringify.js +0 -57
- package/dist/web/jsonStringify.js.map +0 -1
- package/dist/web/jsonValue.js +0 -2
- package/dist/web/jsonValue.js.map +0 -1
- package/dist/web/localNode.js +0 -412
- package/dist/web/localNode.js.map +0 -1
- package/dist/web/logger.js +0 -58
- package/dist/web/logger.js.map +0 -1
- package/dist/web/media.js +0 -2
- package/dist/web/media.js.map +0 -1
- package/dist/web/permissions.js +0 -341
- package/dist/web/permissions.js.map +0 -1
- package/dist/web/priority.js +0 -31
- package/dist/web/priority.js.map +0 -1
- package/dist/web/storage/FileSystem.js +0 -48
- package/dist/web/storage/FileSystem.js.map +0 -1
- package/dist/web/storage/chunksAndKnownStates.js +0 -98
- package/dist/web/storage/chunksAndKnownStates.js.map +0 -1
- package/dist/web/storage/index.js +0 -336
- package/dist/web/storage/index.js.map +0 -1
- package/dist/web/streamUtils.js +0 -41
- package/dist/web/streamUtils.js.map +0 -1
- package/dist/web/sync.js +0 -555
- package/dist/web/sync.js.map +0 -1
- package/dist/web/typeUtils/accountOrAgentIDfromSessionID.js +0 -5
- package/dist/web/typeUtils/accountOrAgentIDfromSessionID.js.map +0 -1
- package/dist/web/typeUtils/expectGroup.js +0 -13
- package/dist/web/typeUtils/expectGroup.js.map +0 -1
- package/dist/web/typeUtils/isAccountID.js +0 -4
- package/dist/web/typeUtils/isAccountID.js.map +0 -1
- package/dist/web/typeUtils/isCoValue.js +0 -11
- package/dist/web/typeUtils/isCoValue.js.map +0 -1
- package/src/crypto/export.ts +0 -2
- package/src/index.native.ts +0 -2
- package/src/index.web.ts +0 -2
- package/tsconfig.native.json +0 -10
- package/tsconfig.web.json +0 -5
- /package/dist/{native/CoValuesStore.js → CoValuesStore.js} +0 -0
- /package/dist/{native/PeerKnownStates.js → PeerKnownStates.js} +0 -0
- /package/dist/{native/PeerState.js → PeerState.js} +0 -0
- /package/dist/{native/PriorityBasedMessageQueue.js → PriorityBasedMessageQueue.js} +0 -0
- /package/dist/{native/SyncStateManager.js → SyncStateManager.js} +0 -0
- /package/dist/{native/base64url.js → base64url.js} +0 -0
- /package/dist/{native/base64url.test.js → base64url.test.js} +0 -0
- /package/dist/{native/coValue.js → coValue.js} +0 -0
- /package/dist/{native/coValueCore.js → coValueCore.js} +0 -0
- /package/dist/{native/coValueState.js → coValueState.js} +0 -0
- /package/dist/{native/coValues → coValues}/account.js +0 -0
- /package/dist/{native/coValues → coValues}/coList.js +0 -0
- /package/dist/{native/coValues → coValues}/coMap.js +0 -0
- /package/dist/{native/coValues → coValues}/coPlainText.js +0 -0
- /package/dist/{native/coValues → coValues}/coStream.js +0 -0
- /package/dist/{native/coValues → coValues}/group.js +0 -0
- /package/dist/{native/coreToCoValue.js → coreToCoValue.js} +0 -0
- /package/dist/{native/crypto → crypto}/PureJSCrypto.js +0 -0
- /package/dist/{native/crypto → crypto}/WasmCrypto.js +0 -0
- /package/dist/{native/crypto → crypto}/crypto.js +0 -0
- /package/dist/{native/exports.js → exports.js} +0 -0
- /package/dist/{native/ids.js → ids.js} +0 -0
- /package/dist/{native/jsonStringify.js → jsonStringify.js} +0 -0
- /package/dist/{native/jsonValue.js → jsonValue.js} +0 -0
- /package/dist/{native/localNode.js → localNode.js} +0 -0
- /package/dist/{native/logger.js → logger.js} +0 -0
- /package/dist/{native/media.js → media.js} +0 -0
- /package/dist/{native/permissions.js → permissions.js} +0 -0
- /package/dist/{native/priority.js → priority.js} +0 -0
- /package/dist/{native/storage → storage}/FileSystem.js +0 -0
- /package/dist/{native/storage → storage}/chunksAndKnownStates.js +0 -0
- /package/dist/{native/storage → storage}/index.js +0 -0
- /package/dist/{native/streamUtils.js → streamUtils.js} +0 -0
- /package/dist/{native/sync.js → sync.js} +0 -0
- /package/dist/{native/typeUtils → typeUtils}/accountOrAgentIDfromSessionID.js +0 -0
- /package/dist/{native/typeUtils → typeUtils}/expectGroup.js +0 -0
- /package/dist/{native/typeUtils → typeUtils}/isAccountID.js +0 -0
- /package/dist/{native/typeUtils → typeUtils}/isCoValue.js +0 -0
package/dist/web/coValue.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
export class RawUnknownCoValue {
|
|
2
|
-
constructor(core) {
|
|
3
|
-
this.id = core.id;
|
|
4
|
-
this.core = core;
|
|
5
|
-
}
|
|
6
|
-
get type() {
|
|
7
|
-
return this.core.header.type;
|
|
8
|
-
}
|
|
9
|
-
get headerMeta() {
|
|
10
|
-
return this.core.header.meta;
|
|
11
|
-
}
|
|
12
|
-
/** @category 6. Meta */
|
|
13
|
-
get group() {
|
|
14
|
-
return this.core.getGroup();
|
|
15
|
-
}
|
|
16
|
-
toJSON() {
|
|
17
|
-
return {};
|
|
18
|
-
}
|
|
19
|
-
atTime() {
|
|
20
|
-
return this;
|
|
21
|
-
}
|
|
22
|
-
subscribe(listener) {
|
|
23
|
-
return this.core.subscribe((content) => {
|
|
24
|
-
listener(content);
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
export function expectMap(content) {
|
|
29
|
-
if (content.type !== "comap") {
|
|
30
|
-
throw new Error("Expected map");
|
|
31
|
-
}
|
|
32
|
-
return content;
|
|
33
|
-
}
|
|
34
|
-
export function expectList(content) {
|
|
35
|
-
if (content.type !== "colist") {
|
|
36
|
-
throw new Error("Expected list");
|
|
37
|
-
}
|
|
38
|
-
return content;
|
|
39
|
-
}
|
|
40
|
-
export function expectStream(content) {
|
|
41
|
-
if (content.type !== "costream") {
|
|
42
|
-
throw new Error("Expected stream");
|
|
43
|
-
}
|
|
44
|
-
return content;
|
|
45
|
-
}
|
|
46
|
-
export function expectPlainText(content) {
|
|
47
|
-
if (content.type !== "coplaintext") {
|
|
48
|
-
throw new Error("Expected plaintext");
|
|
49
|
-
}
|
|
50
|
-
return content;
|
|
51
|
-
}
|
|
52
|
-
//# sourceMappingURL=coValue.js.map
|
package/dist/web/coValue.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"coValue.js","sourceRoot":"","sources":["../../src/coValue.ts"],"names":[],"mappings":"AAqCA,MAAM,OAAO,iBAAiB;IAI5B,YAAY,IAAiB;QAC3B,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAgB,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC/B,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAkB,CAAC;IAC7C,CAAC;IAED,wBAAwB;IACxB,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,MAAM;QACJ,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,CAAC,QAA+B;QACvC,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE;YACrC,QAAQ,CAAC,OAAe,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAYD,MAAM,UAAU,SAAS,CAAC,OAAmB;IAC3C,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,OAAmB,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAmB;IAC5C,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,OAAoB,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAmB;IAC9C,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,OAAsB,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAmB;IACjD,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,OAAyB,CAAC;AACnC,CAAC"}
|
package/dist/web/coValueCore.js
DELETED
|
@@ -1,597 +0,0 @@
|
|
|
1
|
-
import { err, ok } from "neverthrow";
|
|
2
|
-
import { coreToCoValue } from "./coreToCoValue.js";
|
|
3
|
-
import { StreamingHash, } from "./crypto/crypto.js";
|
|
4
|
-
import { getGroupDependentKeyList, getParentGroupId, isParentGroupReference, } from "./ids.js";
|
|
5
|
-
import { parseJSON, stableStringify } from "./jsonStringify.js";
|
|
6
|
-
import { logger } from "./logger.js";
|
|
7
|
-
import { determineValidTransactions, isKeyForKeyField, } from "./permissions.js";
|
|
8
|
-
import { getPriorityFromHeader } from "./priority.js";
|
|
9
|
-
import { accountOrAgentIDfromSessionID } from "./typeUtils/accountOrAgentIDfromSessionID.js";
|
|
10
|
-
import { expectGroup } from "./typeUtils/expectGroup.js";
|
|
11
|
-
import { isAccountID } from "./typeUtils/isAccountID.js";
|
|
12
|
-
/**
|
|
13
|
-
In order to not block other concurrently syncing CoValues we introduce a maximum size of transactions,
|
|
14
|
-
since they are the smallest unit of progress that can be synced within a CoValue.
|
|
15
|
-
This is particularly important for storing binary data in CoValues, since they are likely to be at least on the order of megabytes.
|
|
16
|
-
This also means that we want to keep signatures roughly after each MAX_RECOMMENDED_TX size chunk,
|
|
17
|
-
to be able to verify partially loaded CoValues or CoValues that are still being created (like a video live stream).
|
|
18
|
-
**/
|
|
19
|
-
export const MAX_RECOMMENDED_TX_SIZE = 100 * 1024;
|
|
20
|
-
export function idforHeader(header, crypto) {
|
|
21
|
-
const hash = crypto.shortHash(header);
|
|
22
|
-
return `co_z${hash.slice("shortHash_z".length)}`;
|
|
23
|
-
}
|
|
24
|
-
const readKeyCache = new WeakMap();
|
|
25
|
-
export class CoValueCore {
|
|
26
|
-
constructor(header, node, internalInitSessions = new Map()) {
|
|
27
|
-
this.listeners = new Set();
|
|
28
|
-
this._decryptionCache = {};
|
|
29
|
-
this.deferredUpdates = 0;
|
|
30
|
-
this.crypto = node.crypto;
|
|
31
|
-
this.id = idforHeader(header, node.crypto);
|
|
32
|
-
this.header = header;
|
|
33
|
-
this._sessionLogs = internalInitSessions;
|
|
34
|
-
this.node = node;
|
|
35
|
-
if (header.ruleset.type == "ownedByGroup") {
|
|
36
|
-
this.node
|
|
37
|
-
.expectCoValueLoaded(header.ruleset.group)
|
|
38
|
-
.subscribe((_groupUpdate) => {
|
|
39
|
-
this._cachedContent = undefined;
|
|
40
|
-
this.notifyUpdate("immediate");
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
get sessionLogs() {
|
|
45
|
-
return this._sessionLogs;
|
|
46
|
-
}
|
|
47
|
-
testWithDifferentAccount(account, currentSessionID) {
|
|
48
|
-
const newNode = this.node.testWithDifferentAccount(account, currentSessionID);
|
|
49
|
-
return newNode.expectCoValueLoaded(this.id);
|
|
50
|
-
}
|
|
51
|
-
knownState() {
|
|
52
|
-
if (this._cachedKnownState) {
|
|
53
|
-
return this._cachedKnownState;
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
const knownState = this.knownStateUncached();
|
|
57
|
-
this._cachedKnownState = knownState;
|
|
58
|
-
return knownState;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
/** @internal */
|
|
62
|
-
knownStateUncached() {
|
|
63
|
-
const sessions = {};
|
|
64
|
-
for (const [sessionID, sessionLog] of this.sessionLogs.entries()) {
|
|
65
|
-
sessions[sessionID] = sessionLog.transactions.length;
|
|
66
|
-
}
|
|
67
|
-
return {
|
|
68
|
-
id: this.id,
|
|
69
|
-
header: true,
|
|
70
|
-
sessions,
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
get meta() {
|
|
74
|
-
return this.header?.meta ?? null;
|
|
75
|
-
}
|
|
76
|
-
nextTransactionID() {
|
|
77
|
-
// This is an ugly hack to get a unique but stable session ID for editing the current account
|
|
78
|
-
const sessionID = this.header.meta?.type === "account"
|
|
79
|
-
? this.node.currentSessionID.replace(this.node.account.id, this.node.account
|
|
80
|
-
.currentAgentID()
|
|
81
|
-
._unsafeUnwrap({ withStackTrace: true }))
|
|
82
|
-
: this.node.currentSessionID;
|
|
83
|
-
return {
|
|
84
|
-
sessionID,
|
|
85
|
-
txIndex: this.sessionLogs.get(sessionID)?.transactions.length || 0,
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
tryAddTransactions(sessionID, newTransactions, givenExpectedNewHash, newSignature, skipVerify = false) {
|
|
89
|
-
return this.node
|
|
90
|
-
.resolveAccountAgent(accountOrAgentIDfromSessionID(sessionID), "Expected to know signer of transaction")
|
|
91
|
-
.andThen((agent) => {
|
|
92
|
-
const signerID = this.crypto.getAgentSignerID(agent);
|
|
93
|
-
const { expectedNewHash, newStreamingHash } = this.expectedNewHashAfter(sessionID, newTransactions);
|
|
94
|
-
if (givenExpectedNewHash && givenExpectedNewHash !== expectedNewHash) {
|
|
95
|
-
return err({
|
|
96
|
-
type: "InvalidHash",
|
|
97
|
-
id: this.id,
|
|
98
|
-
expectedNewHash,
|
|
99
|
-
givenExpectedNewHash,
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
if (skipVerify !== true &&
|
|
103
|
-
!this.crypto.verify(newSignature, expectedNewHash, signerID)) {
|
|
104
|
-
return err({
|
|
105
|
-
type: "InvalidSignature",
|
|
106
|
-
id: this.id,
|
|
107
|
-
newSignature,
|
|
108
|
-
sessionID,
|
|
109
|
-
signerID,
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
this.doAddTransactions(sessionID, newTransactions, newSignature, expectedNewHash, newStreamingHash, "immediate");
|
|
113
|
-
return ok(true);
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
doAddTransactions(sessionID, newTransactions, newSignature, expectedNewHash, newStreamingHash, notifyMode) {
|
|
117
|
-
if (this.node.crashed) {
|
|
118
|
-
throw new Error("Trying to add transactions after node is crashed");
|
|
119
|
-
}
|
|
120
|
-
const transactions = this.sessionLogs.get(sessionID)?.transactions ?? [];
|
|
121
|
-
for (const tx of newTransactions) {
|
|
122
|
-
transactions.push(tx);
|
|
123
|
-
}
|
|
124
|
-
const signatureAfter = this.sessionLogs.get(sessionID)?.signatureAfter ?? {};
|
|
125
|
-
const lastInbetweenSignatureIdx = Object.keys(signatureAfter).reduce((max, idx) => (parseInt(idx) > max ? parseInt(idx) : max), -1);
|
|
126
|
-
const sizeOfTxsSinceLastInbetweenSignature = transactions
|
|
127
|
-
.slice(lastInbetweenSignatureIdx + 1)
|
|
128
|
-
.reduce((sum, tx) => sum +
|
|
129
|
-
(tx.privacy === "private"
|
|
130
|
-
? tx.encryptedChanges.length
|
|
131
|
-
: tx.changes.length), 0);
|
|
132
|
-
if (sizeOfTxsSinceLastInbetweenSignature > MAX_RECOMMENDED_TX_SIZE) {
|
|
133
|
-
signatureAfter[transactions.length - 1] = newSignature;
|
|
134
|
-
}
|
|
135
|
-
this._sessionLogs.set(sessionID, {
|
|
136
|
-
transactions,
|
|
137
|
-
lastHash: expectedNewHash,
|
|
138
|
-
streamingHash: newStreamingHash,
|
|
139
|
-
lastSignature: newSignature,
|
|
140
|
-
signatureAfter: signatureAfter,
|
|
141
|
-
});
|
|
142
|
-
if (this._cachedContent &&
|
|
143
|
-
"processNewTransactions" in this._cachedContent &&
|
|
144
|
-
typeof this._cachedContent.processNewTransactions === "function") {
|
|
145
|
-
this._cachedContent.processNewTransactions();
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
this._cachedContent = undefined;
|
|
149
|
-
}
|
|
150
|
-
this._cachedKnownState = undefined;
|
|
151
|
-
this._cachedDependentOn = undefined;
|
|
152
|
-
this._cachedNewContentSinceEmpty = undefined;
|
|
153
|
-
this.notifyUpdate(notifyMode);
|
|
154
|
-
}
|
|
155
|
-
notifyUpdate(notifyMode) {
|
|
156
|
-
if (this.listeners.size === 0) {
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
if (notifyMode === "immediate") {
|
|
160
|
-
const content = this.getCurrentContent();
|
|
161
|
-
for (const listener of this.listeners) {
|
|
162
|
-
listener(content);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
if (!this.nextDeferredNotify) {
|
|
167
|
-
this.nextDeferredNotify = new Promise((resolve) => {
|
|
168
|
-
setTimeout(() => {
|
|
169
|
-
this.nextDeferredNotify = undefined;
|
|
170
|
-
this.deferredUpdates = 0;
|
|
171
|
-
const content = this.getCurrentContent();
|
|
172
|
-
for (const listener of this.listeners) {
|
|
173
|
-
listener(content);
|
|
174
|
-
}
|
|
175
|
-
resolve();
|
|
176
|
-
}, 0);
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
this.deferredUpdates++;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
subscribe(listener) {
|
|
183
|
-
this.listeners.add(listener);
|
|
184
|
-
listener(this.getCurrentContent());
|
|
185
|
-
return () => {
|
|
186
|
-
this.listeners.delete(listener);
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
expectedNewHashAfter(sessionID, newTransactions) {
|
|
190
|
-
const streamingHash = this.sessionLogs.get(sessionID)?.streamingHash.clone() ??
|
|
191
|
-
new StreamingHash(this.crypto);
|
|
192
|
-
for (const transaction of newTransactions) {
|
|
193
|
-
streamingHash.update(transaction);
|
|
194
|
-
}
|
|
195
|
-
const newStreamingHash = streamingHash.clone();
|
|
196
|
-
return {
|
|
197
|
-
expectedNewHash: streamingHash.digest(),
|
|
198
|
-
newStreamingHash,
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
async expectedNewHashAfterAsync(sessionID, newTransactions) {
|
|
202
|
-
const streamingHash = this.sessionLogs.get(sessionID)?.streamingHash.clone() ??
|
|
203
|
-
new StreamingHash(this.crypto);
|
|
204
|
-
let before = performance.now();
|
|
205
|
-
for (const transaction of newTransactions) {
|
|
206
|
-
streamingHash.update(transaction);
|
|
207
|
-
const after = performance.now();
|
|
208
|
-
if (after - before > 1) {
|
|
209
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
210
|
-
before = performance.now();
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
const newStreamingHash = streamingHash.clone();
|
|
214
|
-
return {
|
|
215
|
-
expectedNewHash: streamingHash.digest(),
|
|
216
|
-
newStreamingHash,
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
makeTransaction(changes, privacy) {
|
|
220
|
-
const madeAt = Date.now();
|
|
221
|
-
let transaction;
|
|
222
|
-
if (privacy === "private") {
|
|
223
|
-
const { secret: keySecret, id: keyID } = this.getCurrentReadKey();
|
|
224
|
-
if (!keySecret) {
|
|
225
|
-
throw new Error("Can't make transaction without read key secret");
|
|
226
|
-
}
|
|
227
|
-
const encrypted = this.crypto.encryptForTransaction(changes, keySecret, {
|
|
228
|
-
in: this.id,
|
|
229
|
-
tx: this.nextTransactionID(),
|
|
230
|
-
});
|
|
231
|
-
this._decryptionCache[encrypted] = changes;
|
|
232
|
-
transaction = {
|
|
233
|
-
privacy: "private",
|
|
234
|
-
madeAt,
|
|
235
|
-
keyUsed: keyID,
|
|
236
|
-
encryptedChanges: encrypted,
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
else {
|
|
240
|
-
transaction = {
|
|
241
|
-
privacy: "trusting",
|
|
242
|
-
madeAt,
|
|
243
|
-
changes: stableStringify(changes),
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
// This is an ugly hack to get a unique but stable session ID for editing the current account
|
|
247
|
-
const sessionID = this.header.meta?.type === "account"
|
|
248
|
-
? this.node.currentSessionID.replace(this.node.account.id, this.node.account
|
|
249
|
-
.currentAgentID()
|
|
250
|
-
._unsafeUnwrap({ withStackTrace: true }))
|
|
251
|
-
: this.node.currentSessionID;
|
|
252
|
-
const { expectedNewHash } = this.expectedNewHashAfter(sessionID, [
|
|
253
|
-
transaction,
|
|
254
|
-
]);
|
|
255
|
-
const signature = this.crypto.sign(this.node.account.currentSignerSecret(), expectedNewHash);
|
|
256
|
-
const success = this.tryAddTransactions(sessionID, [transaction], expectedNewHash, signature, true)._unsafeUnwrap({ withStackTrace: true });
|
|
257
|
-
if (success) {
|
|
258
|
-
void this.node.syncManager.syncCoValue(this);
|
|
259
|
-
}
|
|
260
|
-
return success;
|
|
261
|
-
}
|
|
262
|
-
getCurrentContent(options) {
|
|
263
|
-
if (!options?.ignorePrivateTransactions && this._cachedContent) {
|
|
264
|
-
return this._cachedContent;
|
|
265
|
-
}
|
|
266
|
-
const newContent = coreToCoValue(this, options);
|
|
267
|
-
if (!options?.ignorePrivateTransactions) {
|
|
268
|
-
this._cachedContent = newContent;
|
|
269
|
-
}
|
|
270
|
-
return newContent;
|
|
271
|
-
}
|
|
272
|
-
getValidTransactions(options) {
|
|
273
|
-
const validTransactions = determineValidTransactions(this);
|
|
274
|
-
const allTransactions = [];
|
|
275
|
-
for (const { txID, tx } of validTransactions) {
|
|
276
|
-
if (options?.knownTransactions?.[txID.sessionID] >= txID.txIndex) {
|
|
277
|
-
continue;
|
|
278
|
-
}
|
|
279
|
-
if (tx.privacy === "trusting") {
|
|
280
|
-
allTransactions.push({
|
|
281
|
-
txID,
|
|
282
|
-
madeAt: tx.madeAt,
|
|
283
|
-
changes: parseJSON(tx.changes),
|
|
284
|
-
});
|
|
285
|
-
continue;
|
|
286
|
-
}
|
|
287
|
-
if (options?.ignorePrivateTransactions) {
|
|
288
|
-
continue;
|
|
289
|
-
}
|
|
290
|
-
const readKey = this.getReadKey(tx.keyUsed);
|
|
291
|
-
if (!readKey) {
|
|
292
|
-
continue;
|
|
293
|
-
}
|
|
294
|
-
let decryptedChanges = this._decryptionCache[tx.encryptedChanges];
|
|
295
|
-
if (!decryptedChanges) {
|
|
296
|
-
const decryptedString = this.crypto.decryptRawForTransaction(tx.encryptedChanges, readKey, {
|
|
297
|
-
in: this.id,
|
|
298
|
-
tx: txID,
|
|
299
|
-
});
|
|
300
|
-
decryptedChanges = decryptedString && parseJSON(decryptedString);
|
|
301
|
-
this._decryptionCache[tx.encryptedChanges] = decryptedChanges;
|
|
302
|
-
}
|
|
303
|
-
if (!decryptedChanges) {
|
|
304
|
-
logger.error("Failed to decrypt transaction despite having key");
|
|
305
|
-
continue;
|
|
306
|
-
}
|
|
307
|
-
allTransactions.push({
|
|
308
|
-
txID,
|
|
309
|
-
madeAt: tx.madeAt,
|
|
310
|
-
changes: decryptedChanges,
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
return allTransactions;
|
|
314
|
-
}
|
|
315
|
-
getValidSortedTransactions(options) {
|
|
316
|
-
const allTransactions = this.getValidTransactions(options);
|
|
317
|
-
allTransactions.sort(this.compareTransactions);
|
|
318
|
-
return allTransactions;
|
|
319
|
-
}
|
|
320
|
-
compareTransactions(a, b) {
|
|
321
|
-
return (a.madeAt - b.madeAt ||
|
|
322
|
-
(a.txID.sessionID < b.txID.sessionID ? -1 : 1) ||
|
|
323
|
-
a.txID.txIndex - b.txID.txIndex);
|
|
324
|
-
}
|
|
325
|
-
getCurrentReadKey() {
|
|
326
|
-
if (this.header.ruleset.type === "group") {
|
|
327
|
-
const content = expectGroup(this.getCurrentContent());
|
|
328
|
-
const currentKeyId = content.getCurrentReadKeyId();
|
|
329
|
-
if (!currentKeyId) {
|
|
330
|
-
throw new Error("No readKey set");
|
|
331
|
-
}
|
|
332
|
-
const secret = this.getReadKey(currentKeyId);
|
|
333
|
-
return {
|
|
334
|
-
secret: secret,
|
|
335
|
-
id: currentKeyId,
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
else if (this.header.ruleset.type === "ownedByGroup") {
|
|
339
|
-
return this.node
|
|
340
|
-
.expectCoValueLoaded(this.header.ruleset.group)
|
|
341
|
-
.getCurrentReadKey();
|
|
342
|
-
}
|
|
343
|
-
else {
|
|
344
|
-
throw new Error("Only groups or values owned by groups have read secrets");
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
getReadKey(keyID) {
|
|
348
|
-
let key = readKeyCache.get(this)?.[keyID];
|
|
349
|
-
if (!key) {
|
|
350
|
-
key = this.getUncachedReadKey(keyID);
|
|
351
|
-
if (key) {
|
|
352
|
-
let cache = readKeyCache.get(this);
|
|
353
|
-
if (!cache) {
|
|
354
|
-
cache = {};
|
|
355
|
-
readKeyCache.set(this, cache);
|
|
356
|
-
}
|
|
357
|
-
cache[keyID] = key;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
return key;
|
|
361
|
-
}
|
|
362
|
-
getUncachedReadKey(keyID) {
|
|
363
|
-
if (this.header.ruleset.type === "group") {
|
|
364
|
-
const content = expectGroup(this.getCurrentContent({ ignorePrivateTransactions: true }));
|
|
365
|
-
const keyForEveryone = content.get(`${keyID}_for_everyone`);
|
|
366
|
-
if (keyForEveryone)
|
|
367
|
-
return keyForEveryone;
|
|
368
|
-
// Try to find key revelation for us
|
|
369
|
-
const lookupAccountOrAgentID = this.header.meta?.type === "account"
|
|
370
|
-
? this.node.account
|
|
371
|
-
.currentAgentID()
|
|
372
|
-
._unsafeUnwrap({ withStackTrace: true })
|
|
373
|
-
: this.node.account.id;
|
|
374
|
-
const lastReadyKeyEdit = content.lastEditAt(`${keyID}_for_${lookupAccountOrAgentID}`);
|
|
375
|
-
if (lastReadyKeyEdit?.value) {
|
|
376
|
-
const revealer = lastReadyKeyEdit.by;
|
|
377
|
-
const revealerAgent = this.node
|
|
378
|
-
.resolveAccountAgent(revealer, "Expected to know revealer")
|
|
379
|
-
._unsafeUnwrap({ withStackTrace: true });
|
|
380
|
-
const secret = this.crypto.unseal(lastReadyKeyEdit.value, this.node.account.currentSealerSecret(), this.crypto.getAgentSealerID(revealerAgent), {
|
|
381
|
-
in: this.id,
|
|
382
|
-
tx: lastReadyKeyEdit.tx,
|
|
383
|
-
});
|
|
384
|
-
if (secret) {
|
|
385
|
-
return secret;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
// Try to find indirect revelation through previousKeys
|
|
389
|
-
for (const co of content.keys()) {
|
|
390
|
-
if (isKeyForKeyField(co) && co.startsWith(keyID)) {
|
|
391
|
-
const encryptingKeyID = co.split("_for_")[1];
|
|
392
|
-
const encryptingKeySecret = this.getReadKey(encryptingKeyID);
|
|
393
|
-
if (!encryptingKeySecret) {
|
|
394
|
-
continue;
|
|
395
|
-
}
|
|
396
|
-
const encryptedPreviousKey = content.get(co);
|
|
397
|
-
const secret = this.crypto.decryptKeySecret({
|
|
398
|
-
encryptedID: keyID,
|
|
399
|
-
encryptingID: encryptingKeyID,
|
|
400
|
-
encrypted: encryptedPreviousKey,
|
|
401
|
-
}, encryptingKeySecret);
|
|
402
|
-
if (secret) {
|
|
403
|
-
return secret;
|
|
404
|
-
}
|
|
405
|
-
else {
|
|
406
|
-
logger.warn(`Encrypting ${encryptingKeyID} key didn't decrypt ${keyID}`);
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
// try to find revelation to parent group read keys
|
|
411
|
-
for (const co of content.keys()) {
|
|
412
|
-
if (isParentGroupReference(co)) {
|
|
413
|
-
const parentGroupID = getParentGroupId(co);
|
|
414
|
-
const parentGroup = this.node.expectCoValueLoaded(parentGroupID, "Expected parent group to be loaded");
|
|
415
|
-
const parentKeys = this.findValidParentKeys(keyID, content, parentGroup);
|
|
416
|
-
for (const parentKey of parentKeys) {
|
|
417
|
-
const revelationForParentKey = content.get(`${keyID}_for_${parentKey.id}`);
|
|
418
|
-
if (revelationForParentKey) {
|
|
419
|
-
const secret = parentGroup.crypto.decryptKeySecret({
|
|
420
|
-
encryptedID: keyID,
|
|
421
|
-
encryptingID: parentKey.id,
|
|
422
|
-
encrypted: revelationForParentKey,
|
|
423
|
-
}, parentKey.secret);
|
|
424
|
-
if (secret) {
|
|
425
|
-
return secret;
|
|
426
|
-
}
|
|
427
|
-
else {
|
|
428
|
-
logger.warn(`Encrypting parent ${parentKey.id} key didn't decrypt ${keyID}`);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
return undefined;
|
|
435
|
-
}
|
|
436
|
-
else if (this.header.ruleset.type === "ownedByGroup") {
|
|
437
|
-
return this.node
|
|
438
|
-
.expectCoValueLoaded(this.header.ruleset.group)
|
|
439
|
-
.getReadKey(keyID);
|
|
440
|
-
}
|
|
441
|
-
else {
|
|
442
|
-
throw new Error("Only groups or values owned by groups have read secrets");
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
findValidParentKeys(keyID, group, parentGroup) {
|
|
446
|
-
const validParentKeys = [];
|
|
447
|
-
for (const co of group.keys()) {
|
|
448
|
-
if (isKeyForKeyField(co) && co.startsWith(keyID)) {
|
|
449
|
-
const encryptingKeyID = co.split("_for_")[1];
|
|
450
|
-
const encryptingKeySecret = parentGroup.getReadKey(encryptingKeyID);
|
|
451
|
-
if (!encryptingKeySecret) {
|
|
452
|
-
continue;
|
|
453
|
-
}
|
|
454
|
-
validParentKeys.push({
|
|
455
|
-
id: encryptingKeyID,
|
|
456
|
-
secret: encryptingKeySecret,
|
|
457
|
-
});
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
return validParentKeys;
|
|
461
|
-
}
|
|
462
|
-
getGroup() {
|
|
463
|
-
if (this.header.ruleset.type !== "ownedByGroup") {
|
|
464
|
-
throw new Error("Only values owned by groups have groups");
|
|
465
|
-
}
|
|
466
|
-
return expectGroup(this.node
|
|
467
|
-
.expectCoValueLoaded(this.header.ruleset.group)
|
|
468
|
-
.getCurrentContent());
|
|
469
|
-
}
|
|
470
|
-
getTx(txID) {
|
|
471
|
-
return this.sessionLogs.get(txID.sessionID)?.transactions[txID.txIndex];
|
|
472
|
-
}
|
|
473
|
-
newContentSince(knownState) {
|
|
474
|
-
const isKnownStateEmpty = !knownState?.header && !knownState?.sessions;
|
|
475
|
-
if (isKnownStateEmpty && this._cachedNewContentSinceEmpty) {
|
|
476
|
-
return this._cachedNewContentSinceEmpty;
|
|
477
|
-
}
|
|
478
|
-
let currentPiece = {
|
|
479
|
-
action: "content",
|
|
480
|
-
id: this.id,
|
|
481
|
-
header: knownState?.header ? undefined : this.header,
|
|
482
|
-
priority: getPriorityFromHeader(this.header),
|
|
483
|
-
new: {},
|
|
484
|
-
};
|
|
485
|
-
const pieces = [currentPiece];
|
|
486
|
-
const sentState = {};
|
|
487
|
-
let pieceSize = 0;
|
|
488
|
-
let sessionsTodoAgain = "first";
|
|
489
|
-
while (sessionsTodoAgain === "first" || sessionsTodoAgain?.size || 0 > 0) {
|
|
490
|
-
if (sessionsTodoAgain === "first") {
|
|
491
|
-
sessionsTodoAgain = undefined;
|
|
492
|
-
}
|
|
493
|
-
const sessionsTodo = sessionsTodoAgain ?? this.sessionLogs.keys();
|
|
494
|
-
for (const sessionIDKey of sessionsTodo) {
|
|
495
|
-
const sessionID = sessionIDKey;
|
|
496
|
-
const log = this.sessionLogs.get(sessionID);
|
|
497
|
-
const knownStateForSessionID = knownState?.sessions[sessionID];
|
|
498
|
-
const sentStateForSessionID = sentState[sessionID];
|
|
499
|
-
const nextKnownSignatureIdx = getNextKnownSignatureIdx(log, knownStateForSessionID, sentStateForSessionID);
|
|
500
|
-
const firstNewTxIdx = sentStateForSessionID ?? knownStateForSessionID ?? 0;
|
|
501
|
-
const afterLastNewTxIdx = nextKnownSignatureIdx === undefined
|
|
502
|
-
? log.transactions.length
|
|
503
|
-
: nextKnownSignatureIdx + 1;
|
|
504
|
-
const nNewTx = Math.max(0, afterLastNewTxIdx - firstNewTxIdx);
|
|
505
|
-
if (nNewTx === 0) {
|
|
506
|
-
sessionsTodoAgain?.delete(sessionID);
|
|
507
|
-
continue;
|
|
508
|
-
}
|
|
509
|
-
if (afterLastNewTxIdx < log.transactions.length) {
|
|
510
|
-
if (!sessionsTodoAgain) {
|
|
511
|
-
sessionsTodoAgain = new Set();
|
|
512
|
-
}
|
|
513
|
-
sessionsTodoAgain.add(sessionID);
|
|
514
|
-
}
|
|
515
|
-
const oldPieceSize = pieceSize;
|
|
516
|
-
for (let txIdx = firstNewTxIdx; txIdx < afterLastNewTxIdx; txIdx++) {
|
|
517
|
-
const tx = log.transactions[txIdx];
|
|
518
|
-
pieceSize +=
|
|
519
|
-
tx.privacy === "private"
|
|
520
|
-
? tx.encryptedChanges.length
|
|
521
|
-
: tx.changes.length;
|
|
522
|
-
}
|
|
523
|
-
if (pieceSize >= MAX_RECOMMENDED_TX_SIZE) {
|
|
524
|
-
currentPiece = {
|
|
525
|
-
action: "content",
|
|
526
|
-
id: this.id,
|
|
527
|
-
header: undefined,
|
|
528
|
-
new: {},
|
|
529
|
-
priority: getPriorityFromHeader(this.header),
|
|
530
|
-
};
|
|
531
|
-
pieces.push(currentPiece);
|
|
532
|
-
pieceSize = pieceSize - oldPieceSize;
|
|
533
|
-
}
|
|
534
|
-
let sessionEntry = currentPiece.new[sessionID];
|
|
535
|
-
if (!sessionEntry) {
|
|
536
|
-
sessionEntry = {
|
|
537
|
-
after: sentStateForSessionID ?? knownStateForSessionID ?? 0,
|
|
538
|
-
newTransactions: [],
|
|
539
|
-
lastSignature: "WILL_BE_REPLACED",
|
|
540
|
-
};
|
|
541
|
-
currentPiece.new[sessionID] = sessionEntry;
|
|
542
|
-
}
|
|
543
|
-
for (let txIdx = firstNewTxIdx; txIdx < afterLastNewTxIdx; txIdx++) {
|
|
544
|
-
const tx = log.transactions[txIdx];
|
|
545
|
-
sessionEntry.newTransactions.push(tx);
|
|
546
|
-
}
|
|
547
|
-
sessionEntry.lastSignature =
|
|
548
|
-
nextKnownSignatureIdx === undefined
|
|
549
|
-
? log.lastSignature
|
|
550
|
-
: log.signatureAfter[nextKnownSignatureIdx];
|
|
551
|
-
sentState[sessionID] =
|
|
552
|
-
(sentStateForSessionID ?? knownStateForSessionID ?? 0) + nNewTx;
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
const piecesWithContent = pieces.filter((piece) => Object.keys(piece.new).length > 0 || piece.header);
|
|
556
|
-
if (piecesWithContent.length === 0) {
|
|
557
|
-
return undefined;
|
|
558
|
-
}
|
|
559
|
-
if (isKnownStateEmpty) {
|
|
560
|
-
this._cachedNewContentSinceEmpty = piecesWithContent;
|
|
561
|
-
}
|
|
562
|
-
return piecesWithContent;
|
|
563
|
-
}
|
|
564
|
-
getDependedOnCoValues() {
|
|
565
|
-
if (this._cachedDependentOn) {
|
|
566
|
-
return this._cachedDependentOn;
|
|
567
|
-
}
|
|
568
|
-
else {
|
|
569
|
-
const dependentOn = this.getDependedOnCoValuesUncached();
|
|
570
|
-
this._cachedDependentOn = dependentOn;
|
|
571
|
-
return dependentOn;
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
/** @internal */
|
|
575
|
-
getDependedOnCoValuesUncached() {
|
|
576
|
-
return this.header.ruleset.type === "group"
|
|
577
|
-
? getGroupDependentKeyList(expectGroup(this.getCurrentContent()).keys())
|
|
578
|
-
: this.header.ruleset.type === "ownedByGroup"
|
|
579
|
-
? [
|
|
580
|
-
this.header.ruleset.group,
|
|
581
|
-
...new Set([...this.sessionLogs.keys()]
|
|
582
|
-
.map((sessionID) => accountOrAgentIDfromSessionID(sessionID))
|
|
583
|
-
.filter((session) => isAccountID(session) && session !== this.id)),
|
|
584
|
-
]
|
|
585
|
-
: [];
|
|
586
|
-
}
|
|
587
|
-
waitForSync(options) {
|
|
588
|
-
return this.node.syncManager.waitForSync(this.id, options?.timeout);
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
function getNextKnownSignatureIdx(log, knownStateForSessionID, sentStateForSessionID) {
|
|
592
|
-
return Object.keys(log.signatureAfter)
|
|
593
|
-
.map(Number)
|
|
594
|
-
.sort((a, b) => a - b)
|
|
595
|
-
.find((idx) => idx >= (sentStateForSessionID ?? knownStateForSessionID ?? -1));
|
|
596
|
-
}
|
|
597
|
-
//# sourceMappingURL=coValueCore.js.map
|