cojson 0.18.29 → 0.18.30
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 +9 -0
- package/dist/PeerState.d.ts +23 -14
- package/dist/PeerState.d.ts.map +1 -1
- package/dist/PeerState.js +74 -23
- package/dist/PeerState.js.map +1 -1
- package/dist/SyncStateManager.d.ts +3 -3
- package/dist/SyncStateManager.d.ts.map +1 -1
- package/dist/SyncStateManager.js +18 -44
- package/dist/SyncStateManager.js.map +1 -1
- package/dist/coValueContentMessage.d.ts.map +1 -1
- package/dist/coValueContentMessage.js +2 -1
- package/dist/coValueContentMessage.js.map +1 -1
- package/dist/coValueCore/PeerKnownState.d.ts +21 -0
- package/dist/coValueCore/PeerKnownState.d.ts.map +1 -0
- package/dist/coValueCore/PeerKnownState.js +52 -0
- package/dist/coValueCore/PeerKnownState.js.map +1 -0
- package/dist/coValueCore/coValueCore.d.ts +39 -8
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +139 -40
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValueCore/decryptTransactionChangesAndMeta.d.ts.map +1 -1
- package/dist/coValueCore/decryptTransactionChangesAndMeta.js +0 -5
- package/dist/coValueCore/decryptTransactionChangesAndMeta.js.map +1 -1
- package/dist/coValueCore/verifiedState.d.ts +0 -14
- package/dist/coValueCore/verifiedState.d.ts.map +1 -1
- package/dist/coValueCore/verifiedState.js +2 -32
- package/dist/coValueCore/verifiedState.js.map +1 -1
- package/dist/coValues/coList.d.ts +3 -4
- package/dist/coValues/coList.d.ts.map +1 -1
- package/dist/coValues/coList.js +4 -4
- package/dist/coValues/coList.js.map +1 -1
- package/dist/coValues/coMap.d.ts +3 -4
- package/dist/coValues/coMap.d.ts.map +1 -1
- package/dist/coValues/coMap.js +5 -4
- 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 +3 -4
- package/dist/coValues/coStream.js.map +1 -1
- package/dist/coValues/group.d.ts +3 -3
- package/dist/coValues/group.d.ts.map +1 -1
- package/dist/coValues/group.js +74 -52
- package/dist/coValues/group.js.map +1 -1
- package/dist/exports.d.ts +2 -2
- package/dist/exports.d.ts.map +1 -1
- package/dist/exports.js +2 -2
- package/dist/exports.js.map +1 -1
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +7 -5
- package/dist/localNode.js.map +1 -1
- package/dist/permissions.d.ts +5 -1
- package/dist/permissions.d.ts.map +1 -1
- package/dist/permissions.js +173 -109
- package/dist/permissions.js.map +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +33 -44
- package/dist/sync.js.map +1 -1
- package/dist/tests/PeerKnownState.test.d.ts +2 -0
- package/dist/tests/PeerKnownState.test.d.ts.map +1 -0
- package/dist/tests/PeerKnownState.test.js +342 -0
- package/dist/tests/PeerKnownState.test.js.map +1 -0
- package/dist/tests/PeerState.test.js +17 -16
- package/dist/tests/PeerState.test.js.map +1 -1
- package/dist/tests/StorageApiAsync.test.js +12 -12
- package/dist/tests/StorageApiAsync.test.js.map +1 -1
- package/dist/tests/StorageApiSync.test.js +11 -11
- package/dist/tests/StorageApiSync.test.js.map +1 -1
- package/dist/tests/SyncStateManager.test.js +16 -21
- package/dist/tests/SyncStateManager.test.js.map +1 -1
- package/dist/tests/coValueCore.dependencies.test.js +59 -0
- package/dist/tests/coValueCore.dependencies.test.js.map +1 -1
- package/dist/tests/coValueCore.test.js +41 -21
- package/dist/tests/coValueCore.test.js.map +1 -1
- package/dist/tests/group.addMember.test.js +266 -219
- package/dist/tests/group.addMember.test.js.map +1 -1
- package/dist/tests/group.inheritance.test.js +12 -0
- package/dist/tests/group.inheritance.test.js.map +1 -1
- package/dist/tests/group.invite.test.js +77 -0
- package/dist/tests/group.invite.test.js.map +1 -1
- package/dist/tests/group.removeMember.test.js +64 -7
- package/dist/tests/group.removeMember.test.js.map +1 -1
- package/dist/tests/group.roleOf.test.js +14 -4
- package/dist/tests/group.roleOf.test.js.map +1 -1
- package/dist/tests/permissions.test.js +51 -202
- package/dist/tests/permissions.test.js.map +1 -1
- package/dist/tests/sync.content.test.js +2 -2
- package/dist/tests/sync.content.test.js.map +1 -1
- package/dist/tests/sync.invite.test.js +6 -6
- package/dist/tests/sync.load.test.js +22 -22
- package/dist/tests/sync.mesh.test.js +9 -9
- package/dist/tests/sync.storage.test.js +13 -7
- package/dist/tests/sync.storage.test.js.map +1 -1
- package/dist/tests/sync.storageAsync.test.js +3 -3
- package/dist/tests/sync.test.js +13 -33
- package/dist/tests/sync.test.js.map +1 -1
- package/dist/tests/sync.upload.test.js +2 -2
- package/package.json +3 -3
- package/src/PeerState.ts +86 -34
- package/src/SyncStateManager.ts +25 -60
- package/src/coValueContentMessage.ts +3 -1
- package/src/coValueCore/PeerKnownState.ts +74 -0
- package/src/coValueCore/coValueCore.ts +180 -49
- package/src/coValueCore/decryptTransactionChangesAndMeta.ts +0 -6
- package/src/coValueCore/verifiedState.ts +2 -37
- package/src/coValues/coList.ts +7 -7
- package/src/coValues/coMap.ts +9 -7
- package/src/coValues/coStream.ts +6 -5
- package/src/coValues/group.ts +99 -60
- package/src/exports.ts +2 -1
- package/src/localNode.ts +7 -5
- package/src/permissions.ts +204 -123
- package/src/sync.ts +37 -53
- package/src/tests/PeerKnownState.test.ts +426 -0
- package/src/tests/PeerState.test.ts +24 -24
- package/src/tests/StorageApiAsync.test.ts +12 -12
- package/src/tests/StorageApiSync.test.ts +11 -11
- package/src/tests/SyncStateManager.test.ts +23 -53
- package/src/tests/coValueCore.dependencies.test.ts +87 -0
- package/src/tests/coValueCore.test.ts +64 -22
- package/src/tests/group.addMember.test.ts +384 -345
- package/src/tests/group.inheritance.test.ts +33 -0
- package/src/tests/group.invite.test.ts +117 -0
- package/src/tests/group.removeMember.test.ts +95 -9
- package/src/tests/group.roleOf.test.ts +16 -4
- package/src/tests/permissions.test.ts +56 -295
- package/src/tests/sync.content.test.ts +2 -2
- package/src/tests/sync.invite.test.ts +6 -6
- package/src/tests/sync.load.test.ts +22 -22
- package/src/tests/sync.mesh.test.ts +9 -9
- package/src/tests/sync.storage.test.ts +13 -8
- package/src/tests/sync.storageAsync.test.ts +3 -3
- package/src/tests/sync.test.ts +21 -50
- package/src/tests/sync.upload.test.ts +2 -2
- package/dist/PeerKnownStates.d.ts +0 -19
- package/dist/PeerKnownStates.d.ts.map +0 -1
- package/dist/PeerKnownStates.js +0 -64
- package/dist/PeerKnownStates.js.map +0 -1
- package/dist/tests/PeerKnownStates.test.d.ts +0 -2
- package/dist/tests/PeerKnownStates.test.d.ts.map +0 -1
- package/dist/tests/PeerKnownStates.test.js +0 -77
- package/dist/tests/PeerKnownStates.test.js.map +0 -1
- package/src/PeerKnownStates.ts +0 -93
- package/src/tests/PeerKnownStates.test.ts +0 -99
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
import { type RawAccountID } from "../coValues/account.js";
|
|
45
45
|
import { decryptTransactionChangesAndMeta } from "./decryptTransactionChangesAndMeta.js";
|
|
46
46
|
import {
|
|
47
|
+
cloneKnownState,
|
|
47
48
|
combineKnownStateSessions,
|
|
48
49
|
CoValueKnownState,
|
|
49
50
|
emptyKnownState,
|
|
@@ -60,6 +61,7 @@ export function idforHeader(
|
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
export class VerifiedTransaction {
|
|
64
|
+
dispatchTransaction: (transaction: VerifiedTransaction) => void;
|
|
63
65
|
// The account or agent that made the transaction
|
|
64
66
|
author: RawAccountID | AgentID;
|
|
65
67
|
// An object containing the session ID and the transaction index
|
|
@@ -75,14 +77,9 @@ export class VerifiedTransaction {
|
|
|
75
77
|
changes: JsonValue[] | undefined;
|
|
76
78
|
// The decoded meta information of the transaction
|
|
77
79
|
meta: JsonObject | undefined;
|
|
80
|
+
isValidated: boolean = false;
|
|
78
81
|
// Whether the transaction is valid, as per membership rules
|
|
79
82
|
isValid: boolean = false;
|
|
80
|
-
// Whether the transaction has been validated, used to track if determinedValidTransactions needs to check this
|
|
81
|
-
isValidated: boolean = false;
|
|
82
|
-
// True if the transaction has been decrypted
|
|
83
|
-
isDecrypted: boolean = false;
|
|
84
|
-
// True if the meta information has been parsed and loaded in the CoValueCore
|
|
85
|
-
hasMetaBeenParsed: boolean = false;
|
|
86
83
|
// The previous verified transaction for the same session
|
|
87
84
|
previous: VerifiedTransaction | undefined;
|
|
88
85
|
|
|
@@ -95,7 +92,9 @@ export class VerifiedTransaction {
|
|
|
95
92
|
| { changes: JsonValue[]; meta: JsonObject | undefined }
|
|
96
93
|
| undefined,
|
|
97
94
|
previous: VerifiedTransaction | undefined,
|
|
95
|
+
dispatchTransaction: (transaction: VerifiedTransaction) => void,
|
|
98
96
|
) {
|
|
97
|
+
this.dispatchTransaction = dispatchTransaction;
|
|
99
98
|
this.author = accountOrAgentIDfromSessionID(sessionID);
|
|
100
99
|
|
|
101
100
|
const txID = branchId
|
|
@@ -114,7 +113,6 @@ export class VerifiedTransaction {
|
|
|
114
113
|
this.tx = tx;
|
|
115
114
|
this.currentMadeAt = tx.madeAt;
|
|
116
115
|
this.sourceTxMadeAt = undefined;
|
|
117
|
-
this.isValidated = false;
|
|
118
116
|
|
|
119
117
|
this.previous = previous;
|
|
120
118
|
|
|
@@ -151,6 +149,20 @@ export class VerifiedTransaction {
|
|
|
151
149
|
} {
|
|
152
150
|
return Boolean(this.isValid && this.changes);
|
|
153
151
|
}
|
|
152
|
+
|
|
153
|
+
markValid() {
|
|
154
|
+
this.isValid = true;
|
|
155
|
+
|
|
156
|
+
if (!this.isValidated) {
|
|
157
|
+
this.isValidated = true;
|
|
158
|
+
this.dispatchTransaction(this);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
markInvalid() {
|
|
163
|
+
this.isValidated = true;
|
|
164
|
+
this.isValid = false;
|
|
165
|
+
}
|
|
154
166
|
}
|
|
155
167
|
|
|
156
168
|
export type DecryptedTransaction = Omit<VerifiedTransaction, "changes"> & {
|
|
@@ -242,6 +254,31 @@ export class CoValueCore {
|
|
|
242
254
|
return this.hasVerifiedContent();
|
|
243
255
|
}
|
|
244
256
|
|
|
257
|
+
/**
|
|
258
|
+
* True if the coValue is completely downloaded:
|
|
259
|
+
* - the current coValue is available and not streaming
|
|
260
|
+
* - the group is available and not streaming
|
|
261
|
+
* - TODO: all the parent groups are available and not streaming
|
|
262
|
+
*/
|
|
263
|
+
isCompletelyDownloaded(): this is AvailableCoValueCore {
|
|
264
|
+
if (!this.hasVerifiedContent()) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (this.verified.isStreaming()) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const group = this.safeGetGroup();
|
|
273
|
+
|
|
274
|
+
// TODO: Group coValues should be completely downloaded when all their parent groups are completely downloaded
|
|
275
|
+
if (!group) {
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
return group.core.isCompletelyDownloaded();
|
|
280
|
+
}
|
|
281
|
+
|
|
245
282
|
hasVerifiedContent(): this is AvailableCoValueCore {
|
|
246
283
|
return !!this.verified;
|
|
247
284
|
}
|
|
@@ -432,6 +469,8 @@ export class CoValueCore {
|
|
|
432
469
|
new SessionMap(this.id, this.node.crypto, streamingKnownState),
|
|
433
470
|
);
|
|
434
471
|
|
|
472
|
+
this.resetKnownStateCache();
|
|
473
|
+
|
|
435
474
|
return true;
|
|
436
475
|
}
|
|
437
476
|
|
|
@@ -487,20 +526,46 @@ export class CoValueCore {
|
|
|
487
526
|
.then((core) => core.getCurrentContent());
|
|
488
527
|
}
|
|
489
528
|
|
|
529
|
+
private _cachedKnownStateWithStreaming?: CoValueKnownState;
|
|
530
|
+
/**
|
|
531
|
+
* Returns the known state considering the known state of the streaming source
|
|
532
|
+
*
|
|
533
|
+
* Used to correctly manage the content & subscriptions during the content streaming process
|
|
534
|
+
*/
|
|
490
535
|
knownStateWithStreaming(): CoValueKnownState {
|
|
491
|
-
if (this.
|
|
492
|
-
return this.
|
|
493
|
-
} else {
|
|
494
|
-
return emptyKnownState(this.id);
|
|
536
|
+
if (this._cachedKnownStateWithStreaming) {
|
|
537
|
+
return this._cachedKnownStateWithStreaming;
|
|
495
538
|
}
|
|
539
|
+
|
|
540
|
+
const knownState = this.verified
|
|
541
|
+
? cloneKnownState(this.verified.knownStateWithStreaming())
|
|
542
|
+
: emptyKnownState(this.id);
|
|
543
|
+
|
|
544
|
+
this._cachedKnownStateWithStreaming = knownState;
|
|
545
|
+
|
|
546
|
+
return knownState;
|
|
496
547
|
}
|
|
497
548
|
|
|
549
|
+
private _cachedKnownState?: CoValueKnownState;
|
|
550
|
+
/**
|
|
551
|
+
* Returns the known state of the CoValue
|
|
552
|
+
*
|
|
553
|
+
* The return value identity is going to be stable as long as the CoValue is not modified.
|
|
554
|
+
*
|
|
555
|
+
* On change the knownState is invalidated and a new object is returned.
|
|
556
|
+
*/
|
|
498
557
|
knownState(): CoValueKnownState {
|
|
499
|
-
if (this.
|
|
500
|
-
return this.
|
|
501
|
-
} else {
|
|
502
|
-
return emptyKnownState(this.id);
|
|
558
|
+
if (this._cachedKnownState) {
|
|
559
|
+
return this._cachedKnownState;
|
|
503
560
|
}
|
|
561
|
+
|
|
562
|
+
const knownState = this.verified
|
|
563
|
+
? cloneKnownState(this.verified.knownState())
|
|
564
|
+
: emptyKnownState(this.id);
|
|
565
|
+
|
|
566
|
+
this._cachedKnownState = knownState;
|
|
567
|
+
|
|
568
|
+
return knownState;
|
|
504
569
|
}
|
|
505
570
|
|
|
506
571
|
get meta(): JsonValue {
|
|
@@ -575,6 +640,7 @@ export class CoValueCore {
|
|
|
575
640
|
);
|
|
576
641
|
|
|
577
642
|
if (result.isOk()) {
|
|
643
|
+
this.resetKnownStateCache();
|
|
578
644
|
this.processNewTransactions();
|
|
579
645
|
this.scheduleNotifyUpdate();
|
|
580
646
|
}
|
|
@@ -583,6 +649,11 @@ export class CoValueCore {
|
|
|
583
649
|
});
|
|
584
650
|
}
|
|
585
651
|
|
|
652
|
+
private resetKnownStateCache() {
|
|
653
|
+
this._cachedKnownState = undefined;
|
|
654
|
+
this._cachedKnownStateWithStreaming = undefined;
|
|
655
|
+
}
|
|
656
|
+
|
|
586
657
|
private processNewTransactions() {
|
|
587
658
|
if (this._cachedContent) {
|
|
588
659
|
// Does the cached content support incremental processing?
|
|
@@ -730,6 +801,7 @@ export class CoValueCore {
|
|
|
730
801
|
const session = this.verified.sessions.get(sessionID);
|
|
731
802
|
const txIdx = session ? session.transactions.length - 1 : 0;
|
|
732
803
|
|
|
804
|
+
this.resetKnownStateCache();
|
|
733
805
|
this.processNewTransactions();
|
|
734
806
|
this.addDependenciesFromNewTransaction(transaction);
|
|
735
807
|
|
|
@@ -768,10 +840,10 @@ export class CoValueCore {
|
|
|
768
840
|
return this._cachedContent;
|
|
769
841
|
}
|
|
770
842
|
|
|
771
|
-
this.subscribeToGroupInvalidation();
|
|
772
|
-
|
|
773
843
|
const newContent = coreToCoValue(this as AvailableCoValueCore, options);
|
|
774
844
|
|
|
845
|
+
this.subscribeToGroupInvalidation();
|
|
846
|
+
|
|
775
847
|
if (!options?.ignorePrivateTransactions) {
|
|
776
848
|
this._cachedContent = newContent;
|
|
777
849
|
}
|
|
@@ -797,11 +869,20 @@ export class CoValueCore {
|
|
|
797
869
|
|
|
798
870
|
for (const transaction of this.verifiedTransactions) {
|
|
799
871
|
transaction.isValidated = false;
|
|
800
|
-
transaction.hasMetaBeenParsed = false;
|
|
801
872
|
}
|
|
873
|
+
|
|
874
|
+
this.toValidateTransactions = this.verifiedTransactions.slice();
|
|
875
|
+
this.toProcessTransactions = [];
|
|
876
|
+
this.toDecryptTransactions = [];
|
|
877
|
+
this.toParseMetaTransactions = [];
|
|
802
878
|
}
|
|
803
879
|
|
|
804
880
|
verifiedTransactions: VerifiedTransaction[] = [];
|
|
881
|
+
toValidateTransactions: VerifiedTransaction[] = [];
|
|
882
|
+
toDecryptTransactions: VerifiedTransaction[] = [];
|
|
883
|
+
toParseMetaTransactions: VerifiedTransaction[] = [];
|
|
884
|
+
toProcessTransactions: VerifiedTransaction[] = [];
|
|
885
|
+
|
|
805
886
|
private verifiedTransactionsKnownSessions: CoValueKnownState["sessions"] = {};
|
|
806
887
|
|
|
807
888
|
private lastVerifiedTransactionBySessionID: Record<
|
|
@@ -855,6 +936,7 @@ export class CoValueCore {
|
|
|
855
936
|
isBranched ? this.id : undefined,
|
|
856
937
|
cache,
|
|
857
938
|
this.lastVerifiedTransactionBySessionID[sessionID],
|
|
939
|
+
this.dispatchTransaction,
|
|
858
940
|
);
|
|
859
941
|
|
|
860
942
|
if (verifiedTransaction.madeAt > this.latestTxMadeAt) {
|
|
@@ -866,6 +948,7 @@ export class CoValueCore {
|
|
|
866
948
|
}
|
|
867
949
|
|
|
868
950
|
this.verifiedTransactions.push(verifiedTransaction);
|
|
951
|
+
this.dispatchTransaction(verifiedTransaction);
|
|
869
952
|
this.lastVerifiedTransactionBySessionID[sessionID] =
|
|
870
953
|
verifiedTransaction;
|
|
871
954
|
}
|
|
@@ -875,27 +958,39 @@ export class CoValueCore {
|
|
|
875
958
|
}
|
|
876
959
|
}
|
|
877
960
|
|
|
961
|
+
dispatchTransaction = (transaction: VerifiedTransaction) => {
|
|
962
|
+
if (!transaction.isValidated) {
|
|
963
|
+
this.toValidateTransactions.push(transaction);
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
if (transaction.changes) {
|
|
968
|
+
this.toProcessTransactions.push(transaction);
|
|
969
|
+
} else {
|
|
970
|
+
this.toDecryptTransactions.push(transaction);
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
if (transaction.meta) {
|
|
974
|
+
this.toParseMetaTransactions.push(transaction);
|
|
975
|
+
}
|
|
976
|
+
};
|
|
977
|
+
|
|
878
978
|
/**
|
|
879
979
|
* Iterates over the verifiedTransactions and marks them as valid or invalid, based on the group membership of the authors of the transactions .
|
|
880
980
|
*/
|
|
881
981
|
private determineValidTransactions() {
|
|
882
982
|
determineValidTransactions(this);
|
|
983
|
+
this.toValidateTransactions = [];
|
|
883
984
|
}
|
|
884
985
|
|
|
885
986
|
/**
|
|
886
987
|
* Parses the meta information of a transaction, and set the branchStart and mergeCommits.
|
|
887
988
|
*/
|
|
888
989
|
private parseMetaInformation(transaction: VerifiedTransaction) {
|
|
889
|
-
if (
|
|
890
|
-
!transaction.meta ||
|
|
891
|
-
!transaction.isValid ||
|
|
892
|
-
transaction.hasMetaBeenParsed
|
|
893
|
-
) {
|
|
990
|
+
if (!transaction.meta) {
|
|
894
991
|
return;
|
|
895
992
|
}
|
|
896
993
|
|
|
897
|
-
transaction.hasMetaBeenParsed = true;
|
|
898
|
-
|
|
899
994
|
// Branch related meta information
|
|
900
995
|
if (this.isBranched()) {
|
|
901
996
|
// Check if the transaction is a branch start
|
|
@@ -945,7 +1040,7 @@ export class CoValueCore {
|
|
|
945
1040
|
transaction.sourceTxMadeAt &&
|
|
946
1041
|
transaction.sourceTxMadeAt > transaction.currentMadeAt
|
|
947
1042
|
) {
|
|
948
|
-
transaction.
|
|
1043
|
+
transaction.markInvalid();
|
|
949
1044
|
}
|
|
950
1045
|
|
|
951
1046
|
if (sessionID) {
|
|
@@ -973,15 +1068,21 @@ export class CoValueCore {
|
|
|
973
1068
|
if (!this.isAvailable()) {
|
|
974
1069
|
return;
|
|
975
1070
|
}
|
|
976
|
-
|
|
977
1071
|
this.loadVerifiedTransactionsFromLogs();
|
|
978
1072
|
this.determineValidTransactions();
|
|
979
1073
|
|
|
980
|
-
|
|
981
|
-
|
|
1074
|
+
if (!ignorePrivateTransactions) {
|
|
1075
|
+
const toDecryptTransactions = this.toDecryptTransactions;
|
|
1076
|
+
this.toDecryptTransactions = [];
|
|
1077
|
+
for (const transaction of toDecryptTransactions) {
|
|
982
1078
|
decryptTransactionChangesAndMeta(this, transaction);
|
|
1079
|
+
this.dispatchTransaction(transaction);
|
|
983
1080
|
}
|
|
1081
|
+
}
|
|
984
1082
|
|
|
1083
|
+
const toParseMetaTransactions = this.toParseMetaTransactions;
|
|
1084
|
+
this.toParseMetaTransactions = [];
|
|
1085
|
+
for (const transaction of toParseMetaTransactions) {
|
|
985
1086
|
this.parseMetaInformation(transaction);
|
|
986
1087
|
}
|
|
987
1088
|
}
|
|
@@ -994,9 +1095,7 @@ export class CoValueCore {
|
|
|
994
1095
|
// The range, described as knownState sessions, to filter the transactions returned
|
|
995
1096
|
from?: CoValueKnownState["sessions"];
|
|
996
1097
|
to?: CoValueKnownState["sessions"];
|
|
997
|
-
|
|
998
|
-
// The transactions that have already been processed, used for the incremental builds of the content views
|
|
999
|
-
knownTransactions?: Set<Transaction>;
|
|
1098
|
+
knownTransactions?: Record<RawCoID, number>;
|
|
1000
1099
|
|
|
1001
1100
|
// If true, the branch source transactions will be skipped. Used to gather the transactions for the merge operation.
|
|
1002
1101
|
skipBranchSource?: boolean;
|
|
@@ -1011,39 +1110,48 @@ export class CoValueCore {
|
|
|
1011
1110
|
|
|
1012
1111
|
const source = getBranchSource(this);
|
|
1013
1112
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
continue;
|
|
1017
|
-
}
|
|
1113
|
+
const from = options?.from;
|
|
1114
|
+
const to = options?.to;
|
|
1018
1115
|
|
|
1019
|
-
|
|
1116
|
+
const knownTransactions = options?.knownTransactions?.[this.id] ?? 0;
|
|
1117
|
+
|
|
1118
|
+
for (
|
|
1119
|
+
let i = knownTransactions;
|
|
1120
|
+
i < this.toProcessTransactions.length;
|
|
1121
|
+
i++
|
|
1122
|
+
) {
|
|
1123
|
+
const transaction = this.toProcessTransactions[i]!;
|
|
1124
|
+
|
|
1125
|
+
if (!transaction.isValidTransactionWithChanges()) {
|
|
1020
1126
|
continue;
|
|
1021
1127
|
}
|
|
1022
1128
|
|
|
1023
|
-
options?.knownTransactions?.add(transaction.tx);
|
|
1024
|
-
|
|
1025
1129
|
// Using the currentTxID to filter the transactions, because the TxID is modified by the merge meta
|
|
1026
1130
|
const txID = transaction.currentTxID;
|
|
1027
1131
|
|
|
1028
|
-
const
|
|
1132
|
+
const fromIdx = from?.[txID.sessionID] ?? -1;
|
|
1029
1133
|
|
|
1030
1134
|
// Load the to filter index. Sessions that are not in the to filter will be skipped
|
|
1031
|
-
const
|
|
1135
|
+
const toIdx = to?.[txID.sessionID] ?? Infinity;
|
|
1032
1136
|
|
|
1033
1137
|
// The txIndex starts at 0 and from/to are referring to the count of transactions
|
|
1034
|
-
if (
|
|
1138
|
+
if (fromIdx > txID.txIndex || toIdx < txID.txIndex) {
|
|
1035
1139
|
continue;
|
|
1036
1140
|
}
|
|
1037
1141
|
|
|
1038
1142
|
matchingTransactions.push(transaction);
|
|
1039
1143
|
}
|
|
1040
1144
|
|
|
1145
|
+
if (options?.knownTransactions !== undefined) {
|
|
1146
|
+
options.knownTransactions[this.id] = this.toProcessTransactions.length;
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1041
1149
|
// If this is a branch, we load the valid transactions from the source
|
|
1042
1150
|
if (source && this.branchStart && !options?.skipBranchSource) {
|
|
1043
1151
|
const sourceTransactions = source.getValidTransactions({
|
|
1152
|
+
knownTransactions: options?.knownTransactions,
|
|
1044
1153
|
to: this.branchStart,
|
|
1045
1154
|
ignorePrivateTransactions: options?.ignorePrivateTransactions ?? false,
|
|
1046
|
-
knownTransactions: options?.knownTransactions,
|
|
1047
1155
|
});
|
|
1048
1156
|
|
|
1049
1157
|
for (const transaction of sourceTransactions) {
|
|
@@ -1064,12 +1172,14 @@ export class CoValueCore {
|
|
|
1064
1172
|
|
|
1065
1173
|
const dependencyCoValue = this.node.getCoValue(dependency);
|
|
1066
1174
|
|
|
1067
|
-
if (
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1175
|
+
if (this.isCircularMissingDependency(dependencyCoValue)) {
|
|
1176
|
+
return true;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
dependencyCoValue.addDependant(this.id);
|
|
1072
1180
|
|
|
1181
|
+
if (!dependencyCoValue.isAvailable()) {
|
|
1182
|
+
this.missingDependencies.add(dependency);
|
|
1073
1183
|
dependencyCoValue.subscribe((dependencyCoValue, unsubscribe) => {
|
|
1074
1184
|
if (dependencyCoValue.isAvailable()) {
|
|
1075
1185
|
unsubscribe();
|
|
@@ -1080,6 +1190,27 @@ export class CoValueCore {
|
|
|
1080
1190
|
}
|
|
1081
1191
|
}
|
|
1082
1192
|
|
|
1193
|
+
dependant: Set<RawCoID> = new Set();
|
|
1194
|
+
private addDependant(dependant: RawCoID) {
|
|
1195
|
+
this.dependant.add(dependant);
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
isGroup() {
|
|
1199
|
+
if (!this.verified) {
|
|
1200
|
+
return false;
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
if (this.verified.header.ruleset.type !== "group") {
|
|
1204
|
+
return false;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
if (this.verified.header.meta?.type === "account") {
|
|
1208
|
+
return false;
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
return true;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1083
1214
|
createBranch(name: string, ownerId?: RawCoID) {
|
|
1084
1215
|
return createBranch(this, name, ownerId);
|
|
1085
1216
|
}
|
|
@@ -1137,7 +1268,7 @@ export class CoValueCore {
|
|
|
1137
1268
|
ignorePrivateTransactions: boolean;
|
|
1138
1269
|
|
|
1139
1270
|
// The transactions that have already been processed, used for the incremental builds of the content views
|
|
1140
|
-
knownTransactions?:
|
|
1271
|
+
knownTransactions?: Record<RawCoID, number>;
|
|
1141
1272
|
}): DecryptedTransaction[] {
|
|
1142
1273
|
const allTransactions = this.getValidTransactions(options);
|
|
1143
1274
|
|
|
@@ -6,7 +6,6 @@ export function decryptTransactionChangesAndMeta(
|
|
|
6
6
|
) {
|
|
7
7
|
if (
|
|
8
8
|
!transaction.isValid ||
|
|
9
|
-
transaction.isDecrypted ||
|
|
10
9
|
transaction.tx.privacy === "trusting" // Trusting transactions are already decrypted
|
|
11
10
|
) {
|
|
12
11
|
return;
|
|
@@ -48,9 +47,4 @@ export function decryptTransactionChangesAndMeta(
|
|
|
48
47
|
transaction.meta = meta;
|
|
49
48
|
}
|
|
50
49
|
}
|
|
51
|
-
|
|
52
|
-
// We mark the transaction as decrypted even if the changes or meta have failed to be decrypted
|
|
53
|
-
// This is because, if we successfully extracted the readKey and the decrypt failed once it will always fail
|
|
54
|
-
// so better to log the error (we already do that) and mark the transaction as decrypted
|
|
55
|
-
transaction.isDecrypted = true;
|
|
56
50
|
}
|
|
@@ -55,8 +55,6 @@ export class VerifiedState {
|
|
|
55
55
|
readonly crypto: CryptoProvider;
|
|
56
56
|
readonly header: CoValueHeader;
|
|
57
57
|
readonly sessions: SessionMap;
|
|
58
|
-
private _cachedKnownState?: CoValueKnownState;
|
|
59
|
-
private _cachedKnownStateWithStreaming?: CoValueKnownState;
|
|
60
58
|
private _cachedNewContentSinceEmpty: NewContentMessage[] | undefined;
|
|
61
59
|
public lastAccessed: number | undefined;
|
|
62
60
|
public branchSourceId?: RawCoID;
|
|
@@ -102,8 +100,6 @@ export class VerifiedState {
|
|
|
102
100
|
|
|
103
101
|
if (result.isOk()) {
|
|
104
102
|
this._cachedNewContentSinceEmpty = undefined;
|
|
105
|
-
this._cachedKnownState = undefined;
|
|
106
|
-
this._cachedKnownStateWithStreaming = undefined;
|
|
107
103
|
}
|
|
108
104
|
|
|
109
105
|
return result;
|
|
@@ -125,8 +121,6 @@ export class VerifiedState {
|
|
|
125
121
|
);
|
|
126
122
|
|
|
127
123
|
this._cachedNewContentSinceEmpty = undefined;
|
|
128
|
-
this._cachedKnownState = undefined;
|
|
129
|
-
this._cachedKnownStateWithStreaming = undefined;
|
|
130
124
|
|
|
131
125
|
return result;
|
|
132
126
|
}
|
|
@@ -151,8 +145,6 @@ export class VerifiedState {
|
|
|
151
145
|
);
|
|
152
146
|
|
|
153
147
|
this._cachedNewContentSinceEmpty = undefined;
|
|
154
|
-
this._cachedKnownState = undefined;
|
|
155
|
-
this._cachedKnownStateWithStreaming = undefined;
|
|
156
148
|
|
|
157
149
|
return result;
|
|
158
150
|
}
|
|
@@ -286,39 +278,12 @@ export class VerifiedState {
|
|
|
286
278
|
return piecesWithContent;
|
|
287
279
|
}
|
|
288
280
|
|
|
289
|
-
/**
|
|
290
|
-
* Returns the known state of the CoValue
|
|
291
|
-
*
|
|
292
|
-
* The return value identity is going to be stable as long as the CoValue is not modified.
|
|
293
|
-
*
|
|
294
|
-
* On change the knownState is invalidated and a new object is returned.
|
|
295
|
-
*/
|
|
296
281
|
knownState() {
|
|
297
|
-
|
|
298
|
-
return this._cachedKnownState;
|
|
299
|
-
}
|
|
300
|
-
this._cachedKnownState = cloneKnownState(this.sessions.knownState);
|
|
301
|
-
return this._cachedKnownState;
|
|
282
|
+
return this.sessions.knownState;
|
|
302
283
|
}
|
|
303
284
|
|
|
304
|
-
/**
|
|
305
|
-
* Returns the known state considering the known state of the streaming source
|
|
306
|
-
*
|
|
307
|
-
* Used to correctly manage the content & subscriptions during the content streaming process
|
|
308
|
-
*/
|
|
309
285
|
knownStateWithStreaming() {
|
|
310
|
-
|
|
311
|
-
return this.knownState();
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
if (this._cachedKnownStateWithStreaming) {
|
|
315
|
-
return this._cachedKnownStateWithStreaming;
|
|
316
|
-
}
|
|
317
|
-
this._cachedKnownStateWithStreaming = cloneKnownState(
|
|
318
|
-
this.sessions.knownStateWithStreaming,
|
|
319
|
-
);
|
|
320
|
-
|
|
321
|
-
return this._cachedKnownStateWithStreaming;
|
|
286
|
+
return this.sessions.knownStateWithStreaming ?? this.knownState();
|
|
322
287
|
}
|
|
323
288
|
|
|
324
289
|
isStreaming(): boolean {
|
package/src/coValues/coList.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CoID, RawCoValue } from "../coValue.js";
|
|
2
2
|
import { AvailableCoValueCore } from "../coValueCore/coValueCore.js";
|
|
3
|
-
import { AgentID, SessionID, TransactionID } from "../ids.js";
|
|
3
|
+
import { AgentID, SessionID, TransactionID, RawCoID } from "../ids.js";
|
|
4
4
|
import { JsonObject, JsonValue } from "../jsonValue.js";
|
|
5
5
|
import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfromSessionID.js";
|
|
6
6
|
import { isCoValue } from "../typeUtils/isCoValue.js";
|
|
@@ -85,11 +85,8 @@ export class RawCoList<
|
|
|
85
85
|
opID: OpID;
|
|
86
86
|
}[];
|
|
87
87
|
/** @internal */
|
|
88
|
-
knownTransactions:
|
|
89
|
-
|
|
90
|
-
get totalValidTransactions() {
|
|
91
|
-
return this.knownTransactions.size;
|
|
92
|
-
}
|
|
88
|
+
knownTransactions: Record<RawCoID, number>;
|
|
89
|
+
totalValidTransactions: number = 0;
|
|
93
90
|
|
|
94
91
|
lastValidTransaction: number | undefined;
|
|
95
92
|
|
|
@@ -102,7 +99,7 @@ export class RawCoList<
|
|
|
102
99
|
this.deletionsByInsertion = {};
|
|
103
100
|
this.afterStart = [];
|
|
104
101
|
this.beforeEnd = [];
|
|
105
|
-
this.knownTransactions =
|
|
102
|
+
this.knownTransactions = { [core.id]: 0 };
|
|
106
103
|
|
|
107
104
|
this.processNewTransactions();
|
|
108
105
|
}
|
|
@@ -282,6 +279,8 @@ export class RawCoList<
|
|
|
282
279
|
} else {
|
|
283
280
|
this.lastValidTransaction = lastValidTransaction;
|
|
284
281
|
}
|
|
282
|
+
|
|
283
|
+
this.totalValidTransactions += transactions.length;
|
|
285
284
|
}
|
|
286
285
|
|
|
287
286
|
/** @category 6. Meta */
|
|
@@ -669,6 +668,7 @@ export class RawCoList<
|
|
|
669
668
|
this.insertions = listAfter.insertions;
|
|
670
669
|
this.lastValidTransaction = listAfter.lastValidTransaction;
|
|
671
670
|
this.knownTransactions = listAfter.knownTransactions;
|
|
671
|
+
this.totalValidTransactions = listAfter.totalValidTransactions;
|
|
672
672
|
this.deletionsByInsertion = listAfter.deletionsByInsertion;
|
|
673
673
|
this._cachedEntries = undefined;
|
|
674
674
|
}
|
package/src/coValues/coMap.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { CoID, RawCoValue } from "../coValue.js";
|
|
2
2
|
import { AvailableCoValueCore } from "../coValueCore/coValueCore.js";
|
|
3
|
-
import { AgentID, TransactionID } from "../ids.js";
|
|
3
|
+
import { AgentID, RawCoID, TransactionID } from "../ids.js";
|
|
4
4
|
import { JsonObject, JsonValue } from "../jsonValue.js";
|
|
5
5
|
import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfromSessionID.js";
|
|
6
6
|
import { isCoValue } from "../typeUtils/isCoValue.js";
|
|
7
7
|
import { RawAccountID } from "./account.js";
|
|
8
8
|
import type { RawGroup } from "./group.js";
|
|
9
|
-
import { Transaction } from "../coValueCore/verifiedState.js";
|
|
10
9
|
|
|
11
10
|
type MapOp<K extends string, V extends JsonValue | undefined> = {
|
|
12
11
|
txID: TransactionID;
|
|
@@ -61,7 +60,7 @@ export class RawCoMapView<
|
|
|
61
60
|
[Key in keyof Shape & string]?: MapOp<Key, Shape[Key]>[];
|
|
62
61
|
};
|
|
63
62
|
/** @internal */
|
|
64
|
-
knownTransactions:
|
|
63
|
+
knownTransactions: Record<RawCoID, number>;
|
|
65
64
|
|
|
66
65
|
/** @internal */
|
|
67
66
|
ignorePrivateTransactions: boolean;
|
|
@@ -70,9 +69,7 @@ export class RawCoMapView<
|
|
|
70
69
|
/** @category 6. Meta */
|
|
71
70
|
readonly _shape!: Shape;
|
|
72
71
|
|
|
73
|
-
|
|
74
|
-
return this.knownTransactions.size;
|
|
75
|
-
}
|
|
72
|
+
totalValidTransactions: number = 0;
|
|
76
73
|
|
|
77
74
|
/** @internal */
|
|
78
75
|
constructor(
|
|
@@ -88,7 +85,10 @@ export class RawCoMapView<
|
|
|
88
85
|
options?.ignorePrivateTransactions ?? false;
|
|
89
86
|
this.ops = {};
|
|
90
87
|
this.latest = {};
|
|
91
|
-
|
|
88
|
+
|
|
89
|
+
// We track the knownTransacions in multiple CoValues because branches
|
|
90
|
+
// need to retrieve the transactions from both the source and the branch
|
|
91
|
+
this.knownTransactions = { [core.id]: 0 };
|
|
92
92
|
|
|
93
93
|
this.processNewTransactions();
|
|
94
94
|
}
|
|
@@ -147,6 +147,8 @@ export class RawCoMapView<
|
|
|
147
147
|
for (const [key, entries] of changedEntries.entries()) {
|
|
148
148
|
this.latest[key] = entries[entries.length - 1];
|
|
149
149
|
}
|
|
150
|
+
|
|
151
|
+
this.totalValidTransactions += newValidTransactions.length;
|
|
150
152
|
}
|
|
151
153
|
|
|
152
154
|
isTimeTravelEntity() {
|
package/src/coValues/coStream.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { isCoValue } from "../typeUtils/isCoValue.js";
|
|
|
10
10
|
import { RawAccountID } from "./account.js";
|
|
11
11
|
import { RawGroup } from "./group.js";
|
|
12
12
|
import { Transaction } from "../coValueCore/verifiedState.js";
|
|
13
|
+
import { RawCoID } from "../ids.js";
|
|
13
14
|
|
|
14
15
|
export type BinaryStreamInfo = {
|
|
15
16
|
mimeType: string;
|
|
@@ -55,18 +56,16 @@ export class RawCoStreamView<
|
|
|
55
56
|
[key: SessionID]: CoStreamItem<Item>[];
|
|
56
57
|
};
|
|
57
58
|
/** @internal */
|
|
58
|
-
knownTransactions:
|
|
59
|
+
knownTransactions: Record<RawCoID, number>;
|
|
59
60
|
readonly _item!: Item;
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
return this.knownTransactions.size;
|
|
63
|
-
}
|
|
62
|
+
totalValidTransactions: number = 0;
|
|
64
63
|
|
|
65
64
|
constructor(core: AvailableCoValueCore) {
|
|
66
65
|
this.id = core.id as CoID<this>;
|
|
67
66
|
this.core = core;
|
|
68
67
|
this.items = {};
|
|
69
|
-
this.knownTransactions =
|
|
68
|
+
this.knownTransactions = { [core.id]: 0 };
|
|
70
69
|
this.processNewTransactions();
|
|
71
70
|
}
|
|
72
71
|
|
|
@@ -128,6 +127,8 @@ export class RawCoStreamView<
|
|
|
128
127
|
for (const entries of changeEntries) {
|
|
129
128
|
entries.sort(this.compareStreamItems);
|
|
130
129
|
}
|
|
130
|
+
|
|
131
|
+
this.totalValidTransactions += newValidTransactions.length;
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
getSingleStream(): Item[] | undefined {
|