@twin.org/synchronised-storage-service 0.0.1-next.7 → 0.0.1-next.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +17 -15
- package/dist/esm/index.mjs +17 -15
- package/dist/types/models/ISynchronisedStorageServiceConfig.d.ts +0 -5
- package/dist/types/models/ISynchronisedStorageServiceConstructorOptions.d.ts +1 -0
- package/docs/changelog.md +14 -0
- package/docs/reference/interfaces/ISynchronisedStorageServiceConfig.md +0 -14
- package/docs/reference/interfaces/ISynchronisedStorageServiceConstructorOptions.md +1 -0
- package/package.json +2 -2
package/dist/cjs/index.cjs
CHANGED
|
@@ -1874,11 +1874,18 @@ class SynchronisedStorageService {
|
|
|
1874
1874
|
this._blobStorageConnector = blobStorageModels.BlobStorageConnectorFactory.get(options.blobStorageConnectorType ?? "blob-storage");
|
|
1875
1875
|
this._identityConnector = identityModels.IdentityConnectorFactory.get(options.identityConnectorType ?? "identity");
|
|
1876
1876
|
this._taskSchedulerComponent = core.ComponentFactory.get(options.taskSchedulerComponentType ?? "task-scheduler");
|
|
1877
|
+
// If this is empty we assume the local node has the rights to write to the verifiable storage.
|
|
1878
|
+
let isTrustedNode = true;
|
|
1879
|
+
if (!core.Is.empty(options.trustedSynchronisedStorageComponentType)) {
|
|
1880
|
+
isTrustedNode = false;
|
|
1881
|
+
// If it is set then we used the trusted component to send changesets to
|
|
1882
|
+
this._trustedSynchronisedStorageComponent =
|
|
1883
|
+
core.ComponentFactory.get(options.trustedSynchronisedStorageComponentType);
|
|
1884
|
+
}
|
|
1877
1885
|
this._config = {
|
|
1878
1886
|
synchronisedStorageMethodId: options.config.synchronisedStorageMethodId ?? "synchronised-storage-assertion",
|
|
1879
1887
|
entityUpdateIntervalMinutes: options.config.entityUpdateIntervalMinutes ??
|
|
1880
1888
|
SynchronisedStorageService._DEFAULT_ENTITY_UPDATE_INTERVAL_MINUTES,
|
|
1881
|
-
isTrustedNode: options.config.isTrustedNode ?? false,
|
|
1882
1889
|
consolidationIntervalMinutes: options.config.consolidationIntervalMinutes ??
|
|
1883
1890
|
SynchronisedStorageService._DEFAULT_CONSOLIDATION_INTERVAL_MINUTES,
|
|
1884
1891
|
consolidationBatchSize: options.config.consolidationBatchSize ??
|
|
@@ -1889,17 +1896,10 @@ class SynchronisedStorageService {
|
|
|
1889
1896
|
};
|
|
1890
1897
|
this._synchronisedStorageKey =
|
|
1891
1898
|
verifiableStorageKeys[options.config.verifiableStorageKeyId] ?? options.config.verifiableStorageKeyId;
|
|
1892
|
-
|
|
1893
|
-
// to synchronise with a trusted node.
|
|
1894
|
-
if (!this._config.isTrustedNode) {
|
|
1895
|
-
core.Guards.stringValue(this.CLASS_NAME, "options.trustedSynchronisedStorageComponentType", options.trustedSynchronisedStorageComponentType);
|
|
1896
|
-
this._trustedSynchronisedStorageComponent =
|
|
1897
|
-
core.ComponentFactory.get(options.trustedSynchronisedStorageComponentType);
|
|
1898
|
-
}
|
|
1899
|
-
this._blobStorageHelper = new BlobStorageHelper(this._loggingComponent, this._vaultConnector, this._blobStorageConnector, this._config.blobStorageEncryptionKeyId, this._config.isTrustedNode);
|
|
1899
|
+
this._blobStorageHelper = new BlobStorageHelper(this._loggingComponent, this._vaultConnector, this._blobStorageConnector, this._config.blobStorageEncryptionKeyId, isTrustedNode);
|
|
1900
1900
|
this._changeSetHelper = new ChangeSetHelper(this._loggingComponent, this._eventBusComponent, this._identityConnector, this._blobStorageHelper, this._config.synchronisedStorageMethodId);
|
|
1901
1901
|
this._localSyncStateHelper = new LocalSyncStateHelper(this._loggingComponent, this._localSyncSnapshotEntryEntityStorage, this._changeSetHelper);
|
|
1902
|
-
this._remoteSyncStateHelper = new RemoteSyncStateHelper(this._loggingComponent, this._eventBusComponent, this._verifiableSyncPointerStorageConnector, this._blobStorageHelper, this._changeSetHelper,
|
|
1902
|
+
this._remoteSyncStateHelper = new RemoteSyncStateHelper(this._loggingComponent, this._eventBusComponent, this._verifiableSyncPointerStorageConnector, this._blobStorageHelper, this._changeSetHelper, isTrustedNode, this._config.maxConsolidations);
|
|
1903
1903
|
this._serviceStarted = false;
|
|
1904
1904
|
this._activeStorageKeys = {};
|
|
1905
1905
|
this._eventBusComponent.subscribe(synchronisedStorageModels.SynchronisedStorageTopics.RegisterStorageKey, async (event) => this.registerStorageKey(event.data));
|
|
@@ -1924,7 +1924,7 @@ class SynchronisedStorageService {
|
|
|
1924
1924
|
this._remoteSyncStateHelper.setSynchronisedStorageKey(this._synchronisedStorageKey);
|
|
1925
1925
|
this._serviceStarted = true;
|
|
1926
1926
|
// If this is not a trusted node we need to request the decryption key from a trusted node
|
|
1927
|
-
if (!
|
|
1927
|
+
if (!core.Is.empty(this._trustedSynchronisedStorageComponent)) {
|
|
1928
1928
|
const proof = await this._identityConnector.createProof(this._nodeIdentity, identityModels.DocumentHelper.joinId(this._nodeIdentity, this._config.synchronisedStorageMethodId), standardsW3cDid.ProofTypes.DataIntegrityProof, { nodeIdentity });
|
|
1929
1929
|
const decryptionKey = await this._trustedSynchronisedStorageComponent.getDecryptionKey(this._nodeIdentity, proof);
|
|
1930
1930
|
// We don't have the private key so instead we store the key as a secret in the vault
|
|
@@ -1957,7 +1957,7 @@ class SynchronisedStorageService {
|
|
|
1957
1957
|
* @returns The decryption key.
|
|
1958
1958
|
*/
|
|
1959
1959
|
async getDecryptionKey(nodeIdentity, proof) {
|
|
1960
|
-
if (!this.
|
|
1960
|
+
if (!core.Is.empty(this._trustedSynchronisedStorageComponent)) {
|
|
1961
1961
|
throw new core.GeneralError(this.CLASS_NAME, "notTrustedNode");
|
|
1962
1962
|
}
|
|
1963
1963
|
core.Guards.stringValue(this.CLASS_NAME, "nodeIdentity", nodeIdentity);
|
|
@@ -1980,7 +1980,7 @@ class SynchronisedStorageService {
|
|
|
1980
1980
|
* @returns Nothing.
|
|
1981
1981
|
*/
|
|
1982
1982
|
async syncChangeSet(syncChangeSet) {
|
|
1983
|
-
if (!this.
|
|
1983
|
+
if (!core.Is.empty(this._trustedSynchronisedStorageComponent)) {
|
|
1984
1984
|
throw new core.GeneralError(this.CLASS_NAME, "notTrustedNode");
|
|
1985
1985
|
}
|
|
1986
1986
|
core.Guards.object(this.CLASS_NAME, "syncChangeSet", syncChangeSet);
|
|
@@ -2102,7 +2102,8 @@ class SynchronisedStorageService {
|
|
|
2102
2102
|
}
|
|
2103
2103
|
});
|
|
2104
2104
|
// Send the local changes to the remote storage if we are a trusted node
|
|
2105
|
-
if (
|
|
2105
|
+
if (core.Is.empty(this._trustedSynchronisedStorageComponent) &&
|
|
2106
|
+
core.Is.stringValue(changeSetStorageId)) {
|
|
2106
2107
|
// If we are a trusted node, we can add the change set to the sync state
|
|
2107
2108
|
// and remove the local change snapshot
|
|
2108
2109
|
await this._remoteSyncStateHelper.addChangeSetToSyncState(storageKey, changeSetStorageId);
|
|
@@ -2210,7 +2211,8 @@ class SynchronisedStorageService {
|
|
|
2210
2211
|
}
|
|
2211
2212
|
], async () => this.startEntitySync(storageKey));
|
|
2212
2213
|
}
|
|
2213
|
-
if (
|
|
2214
|
+
if (!core.Is.empty(this._trustedSynchronisedStorageComponent) &&
|
|
2215
|
+
this._config.consolidationIntervalMinutes > 0) {
|
|
2214
2216
|
await this._taskSchedulerComponent.addTask(`synchronised-storage-consolidation-${storageKey}`, [
|
|
2215
2217
|
{
|
|
2216
2218
|
nextTriggerTime: Date.now(),
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1872,11 +1872,18 @@ class SynchronisedStorageService {
|
|
|
1872
1872
|
this._blobStorageConnector = BlobStorageConnectorFactory.get(options.blobStorageConnectorType ?? "blob-storage");
|
|
1873
1873
|
this._identityConnector = IdentityConnectorFactory.get(options.identityConnectorType ?? "identity");
|
|
1874
1874
|
this._taskSchedulerComponent = ComponentFactory.get(options.taskSchedulerComponentType ?? "task-scheduler");
|
|
1875
|
+
// If this is empty we assume the local node has the rights to write to the verifiable storage.
|
|
1876
|
+
let isTrustedNode = true;
|
|
1877
|
+
if (!Is.empty(options.trustedSynchronisedStorageComponentType)) {
|
|
1878
|
+
isTrustedNode = false;
|
|
1879
|
+
// If it is set then we used the trusted component to send changesets to
|
|
1880
|
+
this._trustedSynchronisedStorageComponent =
|
|
1881
|
+
ComponentFactory.get(options.trustedSynchronisedStorageComponentType);
|
|
1882
|
+
}
|
|
1875
1883
|
this._config = {
|
|
1876
1884
|
synchronisedStorageMethodId: options.config.synchronisedStorageMethodId ?? "synchronised-storage-assertion",
|
|
1877
1885
|
entityUpdateIntervalMinutes: options.config.entityUpdateIntervalMinutes ??
|
|
1878
1886
|
SynchronisedStorageService._DEFAULT_ENTITY_UPDATE_INTERVAL_MINUTES,
|
|
1879
|
-
isTrustedNode: options.config.isTrustedNode ?? false,
|
|
1880
1887
|
consolidationIntervalMinutes: options.config.consolidationIntervalMinutes ??
|
|
1881
1888
|
SynchronisedStorageService._DEFAULT_CONSOLIDATION_INTERVAL_MINUTES,
|
|
1882
1889
|
consolidationBatchSize: options.config.consolidationBatchSize ??
|
|
@@ -1887,17 +1894,10 @@ class SynchronisedStorageService {
|
|
|
1887
1894
|
};
|
|
1888
1895
|
this._synchronisedStorageKey =
|
|
1889
1896
|
verifiableStorageKeys[options.config.verifiableStorageKeyId] ?? options.config.verifiableStorageKeyId;
|
|
1890
|
-
|
|
1891
|
-
// to synchronise with a trusted node.
|
|
1892
|
-
if (!this._config.isTrustedNode) {
|
|
1893
|
-
Guards.stringValue(this.CLASS_NAME, "options.trustedSynchronisedStorageComponentType", options.trustedSynchronisedStorageComponentType);
|
|
1894
|
-
this._trustedSynchronisedStorageComponent =
|
|
1895
|
-
ComponentFactory.get(options.trustedSynchronisedStorageComponentType);
|
|
1896
|
-
}
|
|
1897
|
-
this._blobStorageHelper = new BlobStorageHelper(this._loggingComponent, this._vaultConnector, this._blobStorageConnector, this._config.blobStorageEncryptionKeyId, this._config.isTrustedNode);
|
|
1897
|
+
this._blobStorageHelper = new BlobStorageHelper(this._loggingComponent, this._vaultConnector, this._blobStorageConnector, this._config.blobStorageEncryptionKeyId, isTrustedNode);
|
|
1898
1898
|
this._changeSetHelper = new ChangeSetHelper(this._loggingComponent, this._eventBusComponent, this._identityConnector, this._blobStorageHelper, this._config.synchronisedStorageMethodId);
|
|
1899
1899
|
this._localSyncStateHelper = new LocalSyncStateHelper(this._loggingComponent, this._localSyncSnapshotEntryEntityStorage, this._changeSetHelper);
|
|
1900
|
-
this._remoteSyncStateHelper = new RemoteSyncStateHelper(this._loggingComponent, this._eventBusComponent, this._verifiableSyncPointerStorageConnector, this._blobStorageHelper, this._changeSetHelper,
|
|
1900
|
+
this._remoteSyncStateHelper = new RemoteSyncStateHelper(this._loggingComponent, this._eventBusComponent, this._verifiableSyncPointerStorageConnector, this._blobStorageHelper, this._changeSetHelper, isTrustedNode, this._config.maxConsolidations);
|
|
1901
1901
|
this._serviceStarted = false;
|
|
1902
1902
|
this._activeStorageKeys = {};
|
|
1903
1903
|
this._eventBusComponent.subscribe(SynchronisedStorageTopics.RegisterStorageKey, async (event) => this.registerStorageKey(event.data));
|
|
@@ -1922,7 +1922,7 @@ class SynchronisedStorageService {
|
|
|
1922
1922
|
this._remoteSyncStateHelper.setSynchronisedStorageKey(this._synchronisedStorageKey);
|
|
1923
1923
|
this._serviceStarted = true;
|
|
1924
1924
|
// If this is not a trusted node we need to request the decryption key from a trusted node
|
|
1925
|
-
if (!
|
|
1925
|
+
if (!Is.empty(this._trustedSynchronisedStorageComponent)) {
|
|
1926
1926
|
const proof = await this._identityConnector.createProof(this._nodeIdentity, DocumentHelper.joinId(this._nodeIdentity, this._config.synchronisedStorageMethodId), ProofTypes.DataIntegrityProof, { nodeIdentity });
|
|
1927
1927
|
const decryptionKey = await this._trustedSynchronisedStorageComponent.getDecryptionKey(this._nodeIdentity, proof);
|
|
1928
1928
|
// We don't have the private key so instead we store the key as a secret in the vault
|
|
@@ -1955,7 +1955,7 @@ class SynchronisedStorageService {
|
|
|
1955
1955
|
* @returns The decryption key.
|
|
1956
1956
|
*/
|
|
1957
1957
|
async getDecryptionKey(nodeIdentity, proof) {
|
|
1958
|
-
if (!this.
|
|
1958
|
+
if (!Is.empty(this._trustedSynchronisedStorageComponent)) {
|
|
1959
1959
|
throw new GeneralError(this.CLASS_NAME, "notTrustedNode");
|
|
1960
1960
|
}
|
|
1961
1961
|
Guards.stringValue(this.CLASS_NAME, "nodeIdentity", nodeIdentity);
|
|
@@ -1978,7 +1978,7 @@ class SynchronisedStorageService {
|
|
|
1978
1978
|
* @returns Nothing.
|
|
1979
1979
|
*/
|
|
1980
1980
|
async syncChangeSet(syncChangeSet) {
|
|
1981
|
-
if (!this.
|
|
1981
|
+
if (!Is.empty(this._trustedSynchronisedStorageComponent)) {
|
|
1982
1982
|
throw new GeneralError(this.CLASS_NAME, "notTrustedNode");
|
|
1983
1983
|
}
|
|
1984
1984
|
Guards.object(this.CLASS_NAME, "syncChangeSet", syncChangeSet);
|
|
@@ -2100,7 +2100,8 @@ class SynchronisedStorageService {
|
|
|
2100
2100
|
}
|
|
2101
2101
|
});
|
|
2102
2102
|
// Send the local changes to the remote storage if we are a trusted node
|
|
2103
|
-
if (
|
|
2103
|
+
if (Is.empty(this._trustedSynchronisedStorageComponent) &&
|
|
2104
|
+
Is.stringValue(changeSetStorageId)) {
|
|
2104
2105
|
// If we are a trusted node, we can add the change set to the sync state
|
|
2105
2106
|
// and remove the local change snapshot
|
|
2106
2107
|
await this._remoteSyncStateHelper.addChangeSetToSyncState(storageKey, changeSetStorageId);
|
|
@@ -2208,7 +2209,8 @@ class SynchronisedStorageService {
|
|
|
2208
2209
|
}
|
|
2209
2210
|
], async () => this.startEntitySync(storageKey));
|
|
2210
2211
|
}
|
|
2211
|
-
if (
|
|
2212
|
+
if (!Is.empty(this._trustedSynchronisedStorageComponent) &&
|
|
2213
|
+
this._config.consolidationIntervalMinutes > 0) {
|
|
2212
2214
|
await this._taskSchedulerComponent.addTask(`synchronised-storage-consolidation-${storageKey}`, [
|
|
2213
2215
|
{
|
|
2214
2216
|
nextTriggerTime: Date.now(),
|
|
@@ -12,11 +12,6 @@ export interface ISynchronisedStorageServiceConfig {
|
|
|
12
12
|
* @default 5
|
|
13
13
|
*/
|
|
14
14
|
entityUpdateIntervalMinutes?: number;
|
|
15
|
-
/**
|
|
16
|
-
* Is this a node that has permission to write to the verifiable storage?
|
|
17
|
-
* @default false
|
|
18
|
-
*/
|
|
19
|
-
isTrustedNode?: boolean;
|
|
20
15
|
/**
|
|
21
16
|
* Interval to perform consolidation of changesets, only used if isTrustedNode is set.
|
|
22
17
|
* @default 60
|
|
@@ -42,6 +42,7 @@ export interface ISynchronisedStorageServiceConstructorOptions {
|
|
|
42
42
|
taskSchedulerComponentType?: string;
|
|
43
43
|
/**
|
|
44
44
|
* The synchronised entity storage component type to use if this node is not trusted.
|
|
45
|
+
* If this is set, this node uses it as the trusted node to store changesets.
|
|
45
46
|
*/
|
|
46
47
|
trustedSynchronisedStorageComponentType?: string;
|
|
47
48
|
/**
|
package/docs/changelog.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.1-next.8](https://github.com/twinfoundation/synchronised-storage/compare/synchronised-storage-service-v0.0.1-next.7...synchronised-storage-service-v0.0.1-next.8) (2025-08-13)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* remove isTrustedNode from config and rely on trusted component ([cc2d987](https://github.com/twinfoundation/synchronised-storage/commit/cc2d98795044fc97b33fadf871188f6103f5c987))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* The following workspace dependencies were updated
|
|
14
|
+
* dependencies
|
|
15
|
+
* @twin.org/synchronised-storage-models bumped from 0.0.1-next.7 to 0.0.1-next.8
|
|
16
|
+
|
|
3
17
|
## [0.0.1-next.7](https://github.com/twinfoundation/synchronised-storage/compare/synchronised-storage-service-v0.0.1-next.6...synchronised-storage-service-v0.0.1-next.7) (2025-08-12)
|
|
4
18
|
|
|
5
19
|
|
|
@@ -32,20 +32,6 @@ How often to check for entity updates in minutes.
|
|
|
32
32
|
|
|
33
33
|
***
|
|
34
34
|
|
|
35
|
-
### isTrustedNode?
|
|
36
|
-
|
|
37
|
-
> `optional` **isTrustedNode**: `boolean`
|
|
38
|
-
|
|
39
|
-
Is this a node that has permission to write to the verifiable storage?
|
|
40
|
-
|
|
41
|
-
#### Default
|
|
42
|
-
|
|
43
|
-
```ts
|
|
44
|
-
false
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
***
|
|
48
|
-
|
|
49
35
|
### consolidationIntervalMinutes?
|
|
50
36
|
|
|
51
37
|
> `optional` **consolidationIntervalMinutes**: `number`
|
|
@@ -103,6 +103,7 @@ task-scheduler
|
|
|
103
103
|
> `optional` **trustedSynchronisedStorageComponentType**: `string`
|
|
104
104
|
|
|
105
105
|
The synchronised entity storage component type to use if this node is not trusted.
|
|
106
|
+
If this is set, this node uses it as the trusted node to store changesets.
|
|
106
107
|
|
|
107
108
|
***
|
|
108
109
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twin.org/synchronised-storage-service",
|
|
3
|
-
"version": "0.0.1-next.
|
|
3
|
+
"version": "0.0.1-next.8",
|
|
4
4
|
"description": "Synchronised storage contract implementation and REST endpoint definitions",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@twin.org/logging-models": "next",
|
|
27
27
|
"@twin.org/nameof": "next",
|
|
28
28
|
"@twin.org/standards-w3c-did": "next",
|
|
29
|
-
"@twin.org/synchronised-storage-models": "0.0.1-next.
|
|
29
|
+
"@twin.org/synchronised-storage-models": "0.0.1-next.8",
|
|
30
30
|
"@twin.org/verifiable-storage-models": "next",
|
|
31
31
|
"@twin.org/web": "next"
|
|
32
32
|
},
|