@twin.org/entity-storage-connector-synchronised 0.0.2-next.9 → 0.0.3-next.10
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/README.md +2 -2
- package/dist/es/index.js +6 -0
- package/dist/es/index.js.map +1 -0
- package/dist/es/models/ISynchronisedEntityStorageConnectorConfig.js +4 -0
- package/dist/es/models/ISynchronisedEntityStorageConnectorConfig.js.map +1 -0
- package/dist/es/models/ISynchronisedEntityStorageConnectorConstructorOptions.js +2 -0
- package/dist/es/models/ISynchronisedEntityStorageConnectorConstructorOptions.js.map +1 -0
- package/dist/{esm/index.mjs → es/synchronisedEntityStorageConnector.js} +83 -56
- package/dist/es/synchronisedEntityStorageConnector.js.map +1 -0
- package/dist/types/index.d.ts +3 -3
- package/dist/types/models/ISynchronisedEntityStorageConnectorConstructorOptions.d.ts +1 -1
- package/dist/types/synchronisedEntityStorageConnector.d.ts +11 -7
- package/docs/changelog.md +157 -1
- package/docs/examples.md +98 -1
- package/docs/reference/classes/SynchronisedEntityStorageConnector.md +31 -23
- package/docs/reference/interfaces/ISynchronisedEntityStorageConnectorConfig.md +2 -2
- package/docs/reference/interfaces/ISynchronisedEntityStorageConnectorConstructorOptions.md +6 -6
- package/locales/en.json +8 -1
- package/package.json +15 -12
- package/dist/cjs/index.cjs +0 -313
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Entity Storage Connector Synchronised
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This package integrates synchronised storage with an entity storage connector so local writes can be published as sync events and remote updates can be applied to local persistence.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
package/dist/es/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Copyright 2024 IOTA Stiftung.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
3
|
+
export * from "./synchronisedEntityStorageConnector.js";
|
|
4
|
+
export * from "./models/ISynchronisedEntityStorageConnectorConfig.js";
|
|
5
|
+
export * from "./models/ISynchronisedEntityStorageConnectorConstructorOptions.js";
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,cAAc,yCAAyC,CAAC;AACxD,cAAc,uDAAuD,CAAC;AACtE,cAAc,mEAAmE,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nexport * from \"./synchronisedEntityStorageConnector.js\";\nexport * from \"./models/ISynchronisedEntityStorageConnectorConfig.js\";\nexport * from \"./models/ISynchronisedEntityStorageConnectorConstructorOptions.js\";\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ISynchronisedEntityStorageConnectorConfig.js","sourceRoot":"","sources":["../../../src/models/ISynchronisedEntityStorageConnectorConfig.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\n\n/**\n * Configuration for the Synchronised Entity Storage Connector.\n */\nexport interface ISynchronisedEntityStorageConnectorConfig {\n\t/**\n\t * The storage key for the synchronised entity storage connector.\n\t * Will default to kebab cased entity schema name.\n\t */\n\tstorageKey?: string;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ISynchronisedEntityStorageConnectorConstructorOptions.js","sourceRoot":"","sources":["../../../src/models/ISynchronisedEntityStorageConnectorConstructorOptions.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { ISynchronisedEntityStorageConnectorConfig } from \"./ISynchronisedEntityStorageConnectorConfig.js\";\n\n/**\n * Options for the Synchronised Entity Storage Connector constructor.\n */\nexport interface ISynchronisedEntityStorageConnectorConstructorOptions {\n\t/**\n\t * The name of the entity schema.\n\t */\n\tentitySchema: string;\n\n\t/**\n\t * The entity storage connector type to use for actual data.\n\t */\n\tentityStorageConnectorType: string;\n\n\t/**\n\t * The event bus component type.\n\t * @default event-bus\n\t */\n\teventBusComponentType?: string;\n\n\t/**\n\t * The configuration for the connector.\n\t */\n\tconfig?: ISynchronisedEntityStorageConnectorConfig;\n}\n"]}
|
|
@@ -1,18 +1,33 @@
|
|
|
1
|
-
import { Guards, StringHelper, Is, GeneralError, ComponentFactory } from '@twin.org/core';
|
|
2
|
-
import { EntitySchemaFactory, EntitySchemaHelper, ComparisonOperator, SortDirection } from '@twin.org/entity';
|
|
3
|
-
import { EntityStorageConnectorFactory } from '@twin.org/entity-storage-models';
|
|
4
|
-
import { SynchronisedStorageTopics, SyncChangeOperation, SyncNodeIdentityMode } from '@twin.org/synchronised-storage-models';
|
|
5
|
-
|
|
6
1
|
// Copyright 2024 IOTA Stiftung.
|
|
7
2
|
// SPDX-License-Identifier: Apache-2.0.
|
|
3
|
+
import { ContextIdHelper, ContextIdKeys, ContextIdStore } from "@twin.org/context";
|
|
4
|
+
import { ComponentFactory, GeneralError, Guards, Is, StringHelper } from "@twin.org/core";
|
|
5
|
+
import { ComparisonOperator, EntitySchemaFactory, EntitySchemaHelper, SortDirection } from "@twin.org/entity";
|
|
6
|
+
import { EntityStorageConnectorFactory } from "@twin.org/entity-storage-models";
|
|
7
|
+
import { SyncChangeOperation, SynchronisedStorageTopics, SyncNodeIdMode } from "@twin.org/synchronised-storage-models";
|
|
8
8
|
/**
|
|
9
9
|
* Class for performing entity storage operations in synchronised storage.
|
|
10
10
|
*/
|
|
11
|
-
class SynchronisedEntityStorageConnector {
|
|
11
|
+
export class SynchronisedEntityStorageConnector {
|
|
12
12
|
/**
|
|
13
13
|
* Runtime name for the class.
|
|
14
14
|
*/
|
|
15
|
-
CLASS_NAME = "SynchronisedEntityStorageConnector";
|
|
15
|
+
static CLASS_NAME = "SynchronisedEntityStorageConnector";
|
|
16
|
+
/**
|
|
17
|
+
* Fixed name for node id properties.
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
static _PROP_NAME_NODE_IDENTITY = "nodeIdentity";
|
|
21
|
+
/**
|
|
22
|
+
* Fixed name for date modified properties.
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
static _PROP_NAME_DATE_MODIFIED = "dateModified";
|
|
26
|
+
/**
|
|
27
|
+
* Fixed name for id properties.
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
static _PROP_NAME_ID = "id";
|
|
16
31
|
/**
|
|
17
32
|
* The schema for the entity.
|
|
18
33
|
* @internal
|
|
@@ -42,32 +57,32 @@ class SynchronisedEntityStorageConnector {
|
|
|
42
57
|
* The node identity.
|
|
43
58
|
* @internal
|
|
44
59
|
*/
|
|
45
|
-
|
|
60
|
+
_nodeId;
|
|
46
61
|
/**
|
|
47
62
|
* Create a new instance of SynchronisedEntityStorageConnector.
|
|
48
63
|
* @param options The options for the connector.
|
|
49
64
|
*/
|
|
50
65
|
constructor(options) {
|
|
51
|
-
Guards.object(
|
|
52
|
-
Guards.stringValue(
|
|
53
|
-
Guards.stringValue(
|
|
66
|
+
Guards.object(SynchronisedEntityStorageConnector.CLASS_NAME, "options", options);
|
|
67
|
+
Guards.stringValue(SynchronisedEntityStorageConnector.CLASS_NAME, "options.entitySchema", options.entitySchema);
|
|
68
|
+
Guards.stringValue(SynchronisedEntityStorageConnector.CLASS_NAME, "options.entityStorageConnectorType", options.entityStorageConnectorType);
|
|
54
69
|
this._entitySchema = EntitySchemaFactory.get(options.entitySchema);
|
|
55
70
|
this._storageKey = options?.config?.storageKey ?? StringHelper.kebabCase(options.entitySchema);
|
|
56
71
|
this._primaryKey = EntitySchemaHelper.getPrimaryKey(this._entitySchema);
|
|
57
72
|
const requiredProperties = [
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
73
|
+
SynchronisedEntityStorageConnector._PROP_NAME_ID,
|
|
74
|
+
SynchronisedEntityStorageConnector._PROP_NAME_NODE_IDENTITY,
|
|
75
|
+
SynchronisedEntityStorageConnector._PROP_NAME_DATE_MODIFIED
|
|
61
76
|
];
|
|
62
77
|
for (const requiredProperty of requiredProperties) {
|
|
63
78
|
const foundProperty = this._entitySchema.properties?.find(prop => prop.property === requiredProperty);
|
|
64
79
|
if (Is.empty(foundProperty)) {
|
|
65
|
-
throw new GeneralError(
|
|
80
|
+
throw new GeneralError(SynchronisedEntityStorageConnector.CLASS_NAME, "missingRequiredProperty", { requiredProperty });
|
|
66
81
|
}
|
|
67
82
|
else if (Is.empty(foundProperty.isPrimary) &&
|
|
68
83
|
Is.empty(foundProperty.isSecondary) &&
|
|
69
84
|
Is.empty(foundProperty.sortDirection)) {
|
|
70
|
-
throw new GeneralError(
|
|
85
|
+
throw new GeneralError(SynchronisedEntityStorageConnector.CLASS_NAME, "missingRequiredPropertySort", {
|
|
71
86
|
requiredProperty
|
|
72
87
|
});
|
|
73
88
|
}
|
|
@@ -75,6 +90,13 @@ class SynchronisedEntityStorageConnector {
|
|
|
75
90
|
this._entityStorageConnector = EntityStorageConnectorFactory.get(options.entityStorageConnectorType);
|
|
76
91
|
this._eventBusComponent = ComponentFactory.get(options.eventBusComponentType ?? "event-bus");
|
|
77
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Returns the class name of the component.
|
|
95
|
+
* @returns The class name of the component.
|
|
96
|
+
*/
|
|
97
|
+
className() {
|
|
98
|
+
return SynchronisedEntityStorageConnector.CLASS_NAME;
|
|
99
|
+
}
|
|
78
100
|
/**
|
|
79
101
|
* Get the schema for the entities.
|
|
80
102
|
* @returns The schema for the entities.
|
|
@@ -84,17 +106,18 @@ class SynchronisedEntityStorageConnector {
|
|
|
84
106
|
}
|
|
85
107
|
/**
|
|
86
108
|
* The component needs to be started when the node is initialized.
|
|
87
|
-
* @param nodeIdentity The identity of the node starting the component.
|
|
88
109
|
* @param nodeLoggingComponentType The node logging component type.
|
|
89
110
|
* @returns Nothing.
|
|
90
111
|
*/
|
|
91
|
-
async start(
|
|
92
|
-
|
|
112
|
+
async start(nodeLoggingComponentType) {
|
|
113
|
+
const contextIds = await ContextIdStore.getContextIds();
|
|
114
|
+
ContextIdHelper.guard(contextIds, ContextIdKeys.Node);
|
|
115
|
+
this._nodeId = contextIds[ContextIdKeys.Node];
|
|
93
116
|
// Tell the synchronised storage about this storage key
|
|
94
117
|
await this._eventBusComponent.publish(SynchronisedStorageTopics.RegisterStorageKey, {
|
|
95
118
|
storageKey: this._storageKey
|
|
96
119
|
});
|
|
97
|
-
this.handleEventBusMessages();
|
|
120
|
+
await this.handleEventBusMessages();
|
|
98
121
|
}
|
|
99
122
|
/**
|
|
100
123
|
* Get an entity.
|
|
@@ -104,7 +127,7 @@ class SynchronisedEntityStorageConnector {
|
|
|
104
127
|
* @returns The object if it can be found or undefined.
|
|
105
128
|
*/
|
|
106
129
|
async get(id, secondaryIndex, conditions) {
|
|
107
|
-
Guards.stringValue(
|
|
130
|
+
Guards.stringValue(SynchronisedEntityStorageConnector.CLASS_NAME, "id", id);
|
|
108
131
|
return this._entityStorageConnector.get(id, secondaryIndex, conditions);
|
|
109
132
|
}
|
|
110
133
|
/**
|
|
@@ -114,17 +137,17 @@ class SynchronisedEntityStorageConnector {
|
|
|
114
137
|
* @returns The id of the entity.
|
|
115
138
|
*/
|
|
116
139
|
async set(entity, conditions) {
|
|
117
|
-
Guards.object(
|
|
118
|
-
if (Is.stringValue(this.
|
|
119
|
-
// Make sure the entity has the required properties
|
|
140
|
+
Guards.object(SynchronisedEntityStorageConnector.CLASS_NAME, "entity", entity);
|
|
141
|
+
if (Is.stringValue(this._nodeId)) {
|
|
142
|
+
// Make sure the entity has the required properties populated
|
|
120
143
|
entity.dateModified = new Date(Date.now()).toISOString();
|
|
121
|
-
entity.nodeIdentity = this.
|
|
144
|
+
entity.nodeIdentity = this._nodeId;
|
|
122
145
|
await this._entityStorageConnector.set(entity, conditions);
|
|
123
146
|
// Tell the synchronised storage about the entity changes
|
|
124
147
|
await this._eventBusComponent.publish(SynchronisedStorageTopics.LocalItemChange, {
|
|
125
148
|
storageKey: this._storageKey,
|
|
126
149
|
operation: SyncChangeOperation.Set,
|
|
127
|
-
|
|
150
|
+
nodeId: this._nodeId,
|
|
128
151
|
id: entity[this._primaryKey.property]
|
|
129
152
|
});
|
|
130
153
|
}
|
|
@@ -136,14 +159,14 @@ class SynchronisedEntityStorageConnector {
|
|
|
136
159
|
* @returns Nothing.
|
|
137
160
|
*/
|
|
138
161
|
async remove(id, conditions) {
|
|
139
|
-
Guards.stringValue(
|
|
140
|
-
if (Is.stringValue(this.
|
|
162
|
+
Guards.stringValue(SynchronisedEntityStorageConnector.CLASS_NAME, "id", id);
|
|
163
|
+
if (Is.stringValue(this._nodeId)) {
|
|
141
164
|
await this._entityStorageConnector.remove(id, conditions);
|
|
142
165
|
// Tell the synchronised storage about the entity removal
|
|
143
166
|
await this._eventBusComponent.publish(SynchronisedStorageTopics.LocalItemChange, {
|
|
144
167
|
storageKey: this._storageKey,
|
|
145
168
|
operation: SyncChangeOperation.Delete,
|
|
146
|
-
|
|
169
|
+
nodeId: this._nodeId,
|
|
147
170
|
id
|
|
148
171
|
});
|
|
149
172
|
}
|
|
@@ -153,37 +176,38 @@ class SynchronisedEntityStorageConnector {
|
|
|
153
176
|
* @param conditions The conditions to match for the entities.
|
|
154
177
|
* @param sortProperties The optional sort order.
|
|
155
178
|
* @param properties The optional properties to return, defaults to all.
|
|
156
|
-
* @param cursor The cursor to request the next
|
|
157
|
-
* @param
|
|
179
|
+
* @param cursor The cursor to request the next chunk of entities.
|
|
180
|
+
* @param limit The suggested number of entities to return in each chunk, in some scenarios can return a different amount.
|
|
158
181
|
* @returns All the entities for the storage matching the conditions,
|
|
159
182
|
* and a cursor which can be used to request more entities.
|
|
160
183
|
*/
|
|
161
|
-
async query(conditions, sortProperties, properties, cursor,
|
|
162
|
-
|
|
184
|
+
async query(conditions, sortProperties, properties, cursor, limit) {
|
|
185
|
+
// We deliberately skip the partition key as we want to query all partitions in synchronised storage
|
|
186
|
+
return this._entityStorageConnector.query(conditions, sortProperties, properties, cursor, limit);
|
|
163
187
|
}
|
|
164
188
|
/**
|
|
165
189
|
* Handle the event bus messages.
|
|
166
190
|
* @internal
|
|
167
191
|
*/
|
|
168
|
-
handleEventBusMessages() {
|
|
192
|
+
async handleEventBusMessages() {
|
|
169
193
|
// When the synchronised storage requests an item, we need to provide it
|
|
170
|
-
this._eventBusComponent.subscribe(SynchronisedStorageTopics.LocalItemRequest, async (params) => {
|
|
194
|
+
await this._eventBusComponent.subscribe(SynchronisedStorageTopics.LocalItemRequest, async (params) => {
|
|
171
195
|
await this.handleLocalItemRequest(params);
|
|
172
196
|
});
|
|
173
197
|
// When the synchronised storage requests a batch, we need to provide it
|
|
174
|
-
this._eventBusComponent.subscribe(SynchronisedStorageTopics.BatchRequest, async (params) => {
|
|
198
|
+
await this._eventBusComponent.subscribe(SynchronisedStorageTopics.BatchRequest, async (params) => {
|
|
175
199
|
await this.handleBatchRequest(params);
|
|
176
200
|
});
|
|
177
201
|
// Subscribe to remote item set events from the synchronised storage and update the local storage
|
|
178
|
-
this._eventBusComponent.subscribe(SynchronisedStorageTopics.RemoteItemSet, async (params) => {
|
|
202
|
+
await this._eventBusComponent.subscribe(SynchronisedStorageTopics.RemoteItemSet, async (params) => {
|
|
179
203
|
await this.handleRemoteItemSet(params);
|
|
180
204
|
});
|
|
181
205
|
// Subscribe to remote item remove events from the synchronised storage and update the local storage
|
|
182
|
-
this._eventBusComponent.subscribe(SynchronisedStorageTopics.RemoteItemRemove, async (params) => {
|
|
206
|
+
await this._eventBusComponent.subscribe(SynchronisedStorageTopics.RemoteItemRemove, async (params) => {
|
|
183
207
|
await this.handleRemoteItemRemove(params);
|
|
184
208
|
});
|
|
185
209
|
// Subscribe to resets from the synchronised storage and update the local storage
|
|
186
|
-
this._eventBusComponent.subscribe(SynchronisedStorageTopics.Reset, async (params) => {
|
|
210
|
+
await this._eventBusComponent.subscribe(SynchronisedStorageTopics.Reset, async (params) => {
|
|
187
211
|
await this.handleReset(params);
|
|
188
212
|
});
|
|
189
213
|
}
|
|
@@ -201,7 +225,7 @@ class SynchronisedEntityStorageConnector {
|
|
|
201
225
|
}
|
|
202
226
|
catch { }
|
|
203
227
|
// Publish the item response with the entity
|
|
204
|
-
this._eventBusComponent.publish(SynchronisedStorageTopics.LocalItemResponse, {
|
|
228
|
+
await this._eventBusComponent.publish(SynchronisedStorageTopics.LocalItemResponse, {
|
|
205
229
|
storageKey: this._storageKey,
|
|
206
230
|
id: event.data.id,
|
|
207
231
|
entity
|
|
@@ -218,7 +242,7 @@ class SynchronisedEntityStorageConnector {
|
|
|
218
242
|
// and it is from another node, remote updates can not change data for this node
|
|
219
243
|
// That must be done via the regular entity storage methods
|
|
220
244
|
if (event.data.storageKey === this._storageKey &&
|
|
221
|
-
event.data.entity.nodeIdentity !== this.
|
|
245
|
+
event.data.entity.nodeIdentity !== this._nodeId) {
|
|
222
246
|
await this._entityStorageConnector.set(event.data.entity);
|
|
223
247
|
}
|
|
224
248
|
}
|
|
@@ -231,8 +255,7 @@ class SynchronisedEntityStorageConnector {
|
|
|
231
255
|
// Only remove the item if it matches the storage key
|
|
232
256
|
// and it is from another node, remote updates can not change data for this node
|
|
233
257
|
// That must be done via the regular entity storage methods
|
|
234
|
-
if (params.data.storageKey === this._storageKey &&
|
|
235
|
-
params.data.nodeIdentity !== this._nodeIdentity) {
|
|
258
|
+
if (params.data.storageKey === this._storageKey && params.data.nodeId !== this._nodeId) {
|
|
236
259
|
await this._entityStorageConnector.remove(params.data.id);
|
|
237
260
|
}
|
|
238
261
|
}
|
|
@@ -249,20 +272,25 @@ class SynchronisedEntityStorageConnector {
|
|
|
249
272
|
const condition = {
|
|
250
273
|
conditions: []
|
|
251
274
|
};
|
|
252
|
-
if (event.data.requestMode ===
|
|
253
|
-
event.data.requestMode ===
|
|
275
|
+
if (event.data.requestMode === SyncNodeIdMode.Local ||
|
|
276
|
+
event.data.requestMode === SyncNodeIdMode.Remote) {
|
|
254
277
|
condition.conditions.push({
|
|
255
|
-
property:
|
|
256
|
-
value: this.
|
|
257
|
-
comparison: event.data.requestMode ===
|
|
278
|
+
property: SynchronisedEntityStorageConnector._PROP_NAME_NODE_IDENTITY,
|
|
279
|
+
value: this._nodeId,
|
|
280
|
+
comparison: event.data.requestMode === SyncNodeIdMode.Local
|
|
258
281
|
? ComparisonOperator.Equals
|
|
259
282
|
: ComparisonOperator.NotEquals
|
|
260
283
|
});
|
|
261
284
|
}
|
|
262
|
-
const result = await this._entityStorageConnector.query(condition, [
|
|
285
|
+
const result = await this._entityStorageConnector.query(condition, [
|
|
286
|
+
{
|
|
287
|
+
property: SynchronisedEntityStorageConnector._PROP_NAME_DATE_MODIFIED,
|
|
288
|
+
sortDirection: SortDirection.Ascending
|
|
289
|
+
}
|
|
290
|
+
], undefined, cursor, event.data.batchSize);
|
|
263
291
|
cursor = result.cursor;
|
|
264
292
|
// Publish the batch response with the entities
|
|
265
|
-
this._eventBusComponent.publish(SynchronisedStorageTopics.BatchResponse, {
|
|
293
|
+
await this._eventBusComponent.publish(SynchronisedStorageTopics.BatchResponse, {
|
|
266
294
|
storageKey: this._storageKey,
|
|
267
295
|
entities: result.entities,
|
|
268
296
|
lastEntry: !Is.stringValue(cursor)
|
|
@@ -286,12 +314,12 @@ class SynchronisedEntityStorageConnector {
|
|
|
286
314
|
conditions: []
|
|
287
315
|
};
|
|
288
316
|
// Depending on the reset mode we can filter the entities to remove
|
|
289
|
-
if (event.data.resetMode ===
|
|
290
|
-
event.data.resetMode ===
|
|
317
|
+
if (event.data.resetMode === SyncNodeIdMode.Local ||
|
|
318
|
+
event.data.resetMode === SyncNodeIdMode.Remote) {
|
|
291
319
|
condition.conditions.push({
|
|
292
320
|
property: "nodeIdentity",
|
|
293
|
-
value: this.
|
|
294
|
-
comparison: event.data.resetMode ===
|
|
321
|
+
value: this._nodeId,
|
|
322
|
+
comparison: event.data.resetMode === SyncNodeIdMode.Local
|
|
295
323
|
? ComparisonOperator.Equals
|
|
296
324
|
: ComparisonOperator.NotEquals
|
|
297
325
|
});
|
|
@@ -307,5 +335,4 @@ class SynchronisedEntityStorageConnector {
|
|
|
307
335
|
}
|
|
308
336
|
}
|
|
309
337
|
}
|
|
310
|
-
|
|
311
|
-
export { SynchronisedEntityStorageConnector };
|
|
338
|
+
//# sourceMappingURL=synchronisedEntityStorageConnector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synchronisedEntityStorageConnector.js","sourceRoot":"","sources":["../../src/synchronisedEntityStorageConnector.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { ContextIdHelper, ContextIdKeys, ContextIdStore } from \"@twin.org/context\";\nimport { ComponentFactory, GeneralError, Guards, Is, StringHelper } from \"@twin.org/core\";\nimport {\n\tComparisonOperator,\n\ttype EntityCondition,\n\tEntitySchemaFactory,\n\tEntitySchemaHelper,\n\ttype IEntitySchema,\n\ttype IEntitySchemaProperty,\n\tSortDirection\n} from \"@twin.org/entity\";\nimport {\n\tEntityStorageConnectorFactory,\n\ttype IEntityStorageConnector\n} from \"@twin.org/entity-storage-models\";\nimport type { IEvent, IEventBusComponent } from \"@twin.org/event-bus-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport {\n\ttype ISyncBatchRequest,\n\ttype ISyncBatchResponse,\n\ttype ISynchronisedEntity,\n\ttype ISyncItemChange,\n\ttype ISyncItemRemove,\n\ttype ISyncItemRequest,\n\ttype ISyncItemResponse,\n\ttype ISyncItemSet,\n\ttype ISyncRegisterStorageKey,\n\ttype ISyncReset,\n\tSyncChangeOperation,\n\tSynchronisedStorageTopics,\n\tSyncNodeIdMode\n} from \"@twin.org/synchronised-storage-models\";\nimport type { ISynchronisedEntityStorageConnectorConstructorOptions } from \"./models/ISynchronisedEntityStorageConnectorConstructorOptions.js\";\n\n/**\n * Class for performing entity storage operations in synchronised storage.\n */\nexport class SynchronisedEntityStorageConnector<\n\tT extends ISynchronisedEntity = ISynchronisedEntity\n> implements IEntityStorageConnector<T> {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<SynchronisedEntityStorageConnector>();\n\n\t/**\n\t * Fixed name for node id properties.\n\t * @internal\n\t */\n\tprivate static readonly _PROP_NAME_NODE_IDENTITY = \"nodeIdentity\";\n\n\t/**\n\t * Fixed name for date modified properties.\n\t * @internal\n\t */\n\tprivate static readonly _PROP_NAME_DATE_MODIFIED = \"dateModified\";\n\n\t/**\n\t * Fixed name for id properties.\n\t * @internal\n\t */\n\tprivate static readonly _PROP_NAME_ID = \"id\";\n\n\t/**\n\t * The schema for the entity.\n\t * @internal\n\t */\n\tprivate readonly _entitySchema: IEntitySchema<T>;\n\n\t/**\n\t * The primary key for the entity schema.\n\t * @internal\n\t */\n\tprivate readonly _primaryKey: IEntitySchemaProperty<T>;\n\n\t/**\n\t * The storage key for the entity.\n\t * @internal\n\t */\n\tprivate readonly _storageKey: string;\n\n\t/**\n\t * The entity storage connector to use for actual data.\n\t * @internal\n\t */\n\tprivate readonly _entityStorageConnector: IEntityStorageConnector<T>;\n\n\t/**\n\t * The event bus component.\n\t * @internal\n\t */\n\tprivate readonly _eventBusComponent: IEventBusComponent;\n\n\t/**\n\t * The node identity.\n\t * @internal\n\t */\n\tprivate _nodeId?: string;\n\n\t/**\n\t * Create a new instance of SynchronisedEntityStorageConnector.\n\t * @param options The options for the connector.\n\t */\n\tconstructor(options: ISynchronisedEntityStorageConnectorConstructorOptions) {\n\t\tGuards.object<ISynchronisedEntityStorageConnectorConstructorOptions>(\n\t\t\tSynchronisedEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options),\n\t\t\toptions\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tSynchronisedEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.entitySchema),\n\t\t\toptions.entitySchema\n\t\t);\n\t\tGuards.stringValue(\n\t\t\tSynchronisedEntityStorageConnector.CLASS_NAME,\n\t\t\tnameof(options.entityStorageConnectorType),\n\t\t\toptions.entityStorageConnectorType\n\t\t);\n\n\t\tthis._entitySchema = EntitySchemaFactory.get(options.entitySchema);\n\t\tthis._storageKey = options?.config?.storageKey ?? StringHelper.kebabCase(options.entitySchema);\n\n\t\tthis._primaryKey = EntitySchemaHelper.getPrimaryKey(this._entitySchema);\n\n\t\tconst requiredProperties: (keyof ISynchronisedEntity)[] = [\n\t\t\tSynchronisedEntityStorageConnector._PROP_NAME_ID,\n\t\t\tSynchronisedEntityStorageConnector._PROP_NAME_NODE_IDENTITY,\n\t\t\tSynchronisedEntityStorageConnector._PROP_NAME_DATE_MODIFIED\n\t\t];\n\n\t\tfor (const requiredProperty of requiredProperties) {\n\t\t\tconst foundProperty = this._entitySchema.properties?.find(\n\t\t\t\tprop => prop.property === requiredProperty\n\t\t\t);\n\t\t\tif (Is.empty(foundProperty)) {\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tSynchronisedEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"missingRequiredProperty\",\n\t\t\t\t\t{ requiredProperty }\n\t\t\t\t);\n\t\t\t} else if (\n\t\t\t\tIs.empty(foundProperty.isPrimary) &&\n\t\t\t\tIs.empty(foundProperty.isSecondary) &&\n\t\t\t\tIs.empty(foundProperty.sortDirection)\n\t\t\t) {\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tSynchronisedEntityStorageConnector.CLASS_NAME,\n\t\t\t\t\t\"missingRequiredPropertySort\",\n\t\t\t\t\t{\n\t\t\t\t\t\trequiredProperty\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tthis._entityStorageConnector = EntityStorageConnectorFactory.get(\n\t\t\toptions.entityStorageConnectorType\n\t\t);\n\n\t\tthis._eventBusComponent = ComponentFactory.get(options.eventBusComponentType ?? \"event-bus\");\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn SynchronisedEntityStorageConnector.CLASS_NAME;\n\t}\n\n\t/**\n\t * Get the schema for the entities.\n\t * @returns The schema for the entities.\n\t */\n\tpublic getSchema(): IEntitySchema {\n\t\treturn this._entitySchema as IEntitySchema;\n\t}\n\n\t/**\n\t * The component needs to be started when the node is initialized.\n\t * @param nodeLoggingComponentType The node logging component type.\n\t * @returns Nothing.\n\t */\n\tpublic async start(nodeLoggingComponentType?: string): Promise<void> {\n\t\tconst contextIds = await ContextIdStore.getContextIds();\n\t\tContextIdHelper.guard(contextIds, ContextIdKeys.Node);\n\t\tthis._nodeId = contextIds[ContextIdKeys.Node];\n\n\t\t// Tell the synchronised storage about this storage key\n\t\tawait this._eventBusComponent.publish<ISyncRegisterStorageKey>(\n\t\t\tSynchronisedStorageTopics.RegisterStorageKey,\n\t\t\t{\n\t\t\t\tstorageKey: this._storageKey\n\t\t\t}\n\t\t);\n\n\t\tawait this.handleEventBusMessages();\n\t}\n\n\t/**\n\t * Get an entity.\n\t * @param id The id of the entity to get, or the index value if secondaryIndex is set.\n\t * @param secondaryIndex Get the item using a secondary index.\n\t * @param conditions The optional conditions to match for the entities.\n\t * @returns The object if it can be found or undefined.\n\t */\n\tpublic async get(\n\t\tid: string,\n\t\tsecondaryIndex?: keyof T,\n\t\tconditions?: { property: keyof T; value: unknown }[]\n\t): Promise<T | undefined> {\n\t\tGuards.stringValue(SynchronisedEntityStorageConnector.CLASS_NAME, nameof(id), id);\n\n\t\treturn this._entityStorageConnector.get(id, secondaryIndex, conditions);\n\t}\n\n\t/**\n\t * Set an entity.\n\t * @param entity The entity to set.\n\t * @param conditions The optional conditions to match for the entities.\n\t * @returns The id of the entity.\n\t */\n\tpublic async set(entity: T, conditions?: { property: keyof T; value: unknown }[]): Promise<void> {\n\t\tGuards.object<T>(SynchronisedEntityStorageConnector.CLASS_NAME, nameof(entity), entity);\n\n\t\tif (Is.stringValue(this._nodeId)) {\n\t\t\t// Make sure the entity has the required properties populated\n\t\t\tentity.dateModified = new Date(Date.now()).toISOString();\n\t\t\tentity.nodeIdentity = this._nodeId;\n\n\t\t\tawait this._entityStorageConnector.set(entity, conditions);\n\n\t\t\t// Tell the synchronised storage about the entity changes\n\t\t\tawait this._eventBusComponent.publish<ISyncItemChange>(\n\t\t\t\tSynchronisedStorageTopics.LocalItemChange,\n\t\t\t\t{\n\t\t\t\t\tstorageKey: this._storageKey,\n\t\t\t\t\toperation: SyncChangeOperation.Set,\n\t\t\t\t\tnodeId: this._nodeId,\n\t\t\t\t\tid: entity[this._primaryKey.property] as string\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Remove the entity.\n\t * @param id The id of the entity to remove.\n\t * @param conditions The optional conditions to match for the entities.\n\t * @returns Nothing.\n\t */\n\tpublic async remove(\n\t\tid: string,\n\t\tconditions?: { property: keyof T; value: unknown }[]\n\t): Promise<void> {\n\t\tGuards.stringValue(SynchronisedEntityStorageConnector.CLASS_NAME, nameof(id), id);\n\n\t\tif (Is.stringValue(this._nodeId)) {\n\t\t\tawait this._entityStorageConnector.remove(id, conditions);\n\n\t\t\t// Tell the synchronised storage about the entity removal\n\t\t\tawait this._eventBusComponent.publish<ISyncItemChange>(\n\t\t\t\tSynchronisedStorageTopics.LocalItemChange,\n\t\t\t\t{\n\t\t\t\t\tstorageKey: this._storageKey,\n\t\t\t\t\toperation: SyncChangeOperation.Delete,\n\t\t\t\t\tnodeId: this._nodeId,\n\t\t\t\t\tid\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Find all the entities which match the conditions.\n\t * @param conditions The conditions to match for the entities.\n\t * @param sortProperties The optional sort order.\n\t * @param properties The optional properties to return, defaults to all.\n\t * @param cursor The cursor to request the next chunk of entities.\n\t * @param limit The suggested number of entities to return in each chunk, in some scenarios can return a different amount.\n\t * @returns All the entities for the storage matching the conditions,\n\t * and a cursor which can be used to request more entities.\n\t */\n\tpublic async query(\n\t\tconditions?: EntityCondition<T>,\n\t\tsortProperties?: {\n\t\t\tproperty: keyof T;\n\t\t\tsortDirection: SortDirection;\n\t\t}[],\n\t\tproperties?: (keyof T)[],\n\t\tcursor?: string,\n\t\tlimit?: number\n\t): Promise<{\n\t\t/**\n\t\t * The entities, which can be partial if a limited keys list was provided.\n\t\t */\n\t\tentities: Partial<T>[];\n\t\t/**\n\t\t * An optional cursor, when defined can be used to call find to get more entities.\n\t\t */\n\t\tcursor?: string;\n\t}> {\n\t\t// We deliberately skip the partition key as we want to query all partitions in synchronised storage\n\t\treturn this._entityStorageConnector.query(\n\t\t\tconditions,\n\t\t\tsortProperties,\n\t\t\tproperties,\n\t\t\tcursor,\n\t\t\tlimit\n\t\t);\n\t}\n\n\t/**\n\t * Handle the event bus messages.\n\t * @internal\n\t */\n\tprivate async handleEventBusMessages(): Promise<void> {\n\t\t// When the synchronised storage requests an item, we need to provide it\n\t\tawait this._eventBusComponent.subscribe<ISyncItemRequest>(\n\t\t\tSynchronisedStorageTopics.LocalItemRequest,\n\t\t\tasync params => {\n\t\t\t\tawait this.handleLocalItemRequest(params);\n\t\t\t}\n\t\t);\n\n\t\t// When the synchronised storage requests a batch, we need to provide it\n\t\tawait this._eventBusComponent.subscribe<ISyncBatchRequest>(\n\t\t\tSynchronisedStorageTopics.BatchRequest,\n\t\t\tasync params => {\n\t\t\t\tawait this.handleBatchRequest(params);\n\t\t\t}\n\t\t);\n\n\t\t// Subscribe to remote item set events from the synchronised storage and update the local storage\n\t\tawait this._eventBusComponent.subscribe<ISyncItemSet>(\n\t\t\tSynchronisedStorageTopics.RemoteItemSet,\n\t\t\tasync params => {\n\t\t\t\tawait this.handleRemoteItemSet(params);\n\t\t\t}\n\t\t);\n\n\t\t// Subscribe to remote item remove events from the synchronised storage and update the local storage\n\t\tawait this._eventBusComponent.subscribe<ISyncItemRemove>(\n\t\t\tSynchronisedStorageTopics.RemoteItemRemove,\n\t\t\tasync params => {\n\t\t\t\tawait this.handleRemoteItemRemove(params);\n\t\t\t}\n\t\t);\n\n\t\t// Subscribe to resets from the synchronised storage and update the local storage\n\t\tawait this._eventBusComponent.subscribe<ISyncReset>(\n\t\t\tSynchronisedStorageTopics.Reset,\n\t\t\tasync params => {\n\t\t\t\tawait this.handleReset(params);\n\t\t\t}\n\t\t);\n\t}\n\n\t/**\n\t * Handle a local item request.\n\t * @param event The request parameters\n\t * @internal\n\t */\n\tprivate async handleLocalItemRequest(event: IEvent<ISyncItemRequest>): Promise<void> {\n\t\t// Only handle the request if it matches the storage key\n\t\tif (event.data.storageKey === this._storageKey) {\n\t\t\tlet entity: T | undefined;\n\t\t\ttry {\n\t\t\t\tentity = await this._entityStorageConnector.get(event.data.id);\n\t\t\t} catch {}\n\n\t\t\t// Publish the item response with the entity\n\t\t\tawait this._eventBusComponent.publish<ISyncItemResponse>(\n\t\t\t\tSynchronisedStorageTopics.LocalItemResponse,\n\t\t\t\t{\n\t\t\t\t\tstorageKey: this._storageKey,\n\t\t\t\t\tid: event.data.id,\n\t\t\t\t\tentity\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Handle a remote item set event.\n\t * @param event The event parameters\n\t * @internal\n\t */\n\tprivate async handleRemoteItemSet(event: IEvent<ISyncItemSet>): Promise<void> {\n\t\t// Only set the item if it matches the storage key\n\t\t// and it is from another node, remote updates can not change data for this node\n\t\t// That must be done via the regular entity storage methods\n\t\tif (\n\t\t\tevent.data.storageKey === this._storageKey &&\n\t\t\tevent.data.entity.nodeIdentity !== this._nodeId\n\t\t) {\n\t\t\tawait this._entityStorageConnector.set(event.data.entity as T);\n\t\t}\n\t}\n\n\t/**\n\t * Handle a remote item remove event.\n\t * @param params The event parameters\n\t * @internal\n\t */\n\tprivate async handleRemoteItemRemove(params: IEvent<ISyncItemRemove>): Promise<void> {\n\t\t// Only remove the item if it matches the storage key\n\t\t// and it is from another node, remote updates can not change data for this node\n\t\t// That must be done via the regular entity storage methods\n\t\tif (params.data.storageKey === this._storageKey && params.data.nodeId !== this._nodeId) {\n\t\t\tawait this._entityStorageConnector.remove(params.data.id);\n\t\t}\n\t}\n\n\t/**\n\t * Handle a batch request.\n\t * @param event The request parameters\n\t * @internal\n\t */\n\tprivate async handleBatchRequest(event: IEvent<ISyncBatchRequest>): Promise<void> {\n\t\t// Only handle the request if it matches the storage key\n\t\tif (event.data.storageKey === this._storageKey) {\n\t\t\tlet cursor;\n\t\t\tdo {\n\t\t\t\tconst condition: EntityCondition<T> = {\n\t\t\t\t\tconditions: []\n\t\t\t\t};\n\t\t\t\tif (\n\t\t\t\t\tevent.data.requestMode === SyncNodeIdMode.Local ||\n\t\t\t\t\tevent.data.requestMode === SyncNodeIdMode.Remote\n\t\t\t\t) {\n\t\t\t\t\tcondition.conditions.push({\n\t\t\t\t\t\tproperty: SynchronisedEntityStorageConnector._PROP_NAME_NODE_IDENTITY,\n\t\t\t\t\t\tvalue: this._nodeId,\n\t\t\t\t\t\tcomparison:\n\t\t\t\t\t\t\tevent.data.requestMode === SyncNodeIdMode.Local\n\t\t\t\t\t\t\t\t? ComparisonOperator.Equals\n\t\t\t\t\t\t\t\t: ComparisonOperator.NotEquals\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst result = await this._entityStorageConnector.query(\n\t\t\t\t\tcondition,\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tproperty: SynchronisedEntityStorageConnector._PROP_NAME_DATE_MODIFIED,\n\t\t\t\t\t\t\tsortDirection: SortDirection.Ascending\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tundefined,\n\t\t\t\t\tcursor,\n\t\t\t\t\tevent.data.batchSize\n\t\t\t\t);\n\n\t\t\t\tcursor = result.cursor;\n\n\t\t\t\t// Publish the batch response with the entities\n\t\t\t\tawait this._eventBusComponent.publish<ISyncBatchResponse>(\n\t\t\t\t\tSynchronisedStorageTopics.BatchResponse,\n\t\t\t\t\t{\n\t\t\t\t\t\tstorageKey: this._storageKey,\n\t\t\t\t\t\tentities: result.entities as T[],\n\t\t\t\t\t\tlastEntry: !Is.stringValue(cursor)\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t} while (Is.stringValue(cursor));\n\t\t}\n\t}\n\n\t/**\n\t * Handle a reset event.\n\t * @param event The event parameters\n\t * @internal\n\t */\n\tprivate async handleReset(event: IEvent<ISyncReset>): Promise<void> {\n\t\t// Only reset the storage if it matches the storage key\n\t\tif (event.data.storageKey === this._storageKey) {\n\t\t\tlet cursor;\n\t\t\tlet toRemove: string[] = [];\n\n\t\t\t// Build a list of the ids to remove\n\t\t\tdo {\n\t\t\t\tconst condition: EntityCondition<T> = {\n\t\t\t\t\tconditions: []\n\t\t\t\t};\n\n\t\t\t\t// Depending on the reset mode we can filter the entities to remove\n\t\t\t\tif (\n\t\t\t\t\tevent.data.resetMode === SyncNodeIdMode.Local ||\n\t\t\t\t\tevent.data.resetMode === SyncNodeIdMode.Remote\n\t\t\t\t) {\n\t\t\t\t\tcondition.conditions.push({\n\t\t\t\t\t\tproperty: \"nodeIdentity\",\n\t\t\t\t\t\tvalue: this._nodeId,\n\t\t\t\t\t\tcomparison:\n\t\t\t\t\t\t\tevent.data.resetMode === SyncNodeIdMode.Local\n\t\t\t\t\t\t\t\t? ComparisonOperator.Equals\n\t\t\t\t\t\t\t\t: ComparisonOperator.NotEquals\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst result = await this._entityStorageConnector.query(\n\t\t\t\t\tcondition,\n\t\t\t\t\tundefined,\n\t\t\t\t\tundefined,\n\t\t\t\t\tcursor\n\t\t\t\t);\n\n\t\t\t\tcursor = result.cursor;\n\t\t\t\ttoRemove = toRemove.concat(result.entities.map(entity => (entity as T).id));\n\t\t\t} while (Is.stringValue(cursor));\n\n\t\t\t// Remove the entities\n\t\t\tfor (let i = 0; i < toRemove.length; i++) {\n\t\t\t\tawait this.remove(toRemove[i]);\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from "./synchronisedEntityStorageConnector";
|
|
2
|
-
export * from "./models/ISynchronisedEntityStorageConnectorConfig";
|
|
3
|
-
export * from "./models/ISynchronisedEntityStorageConnectorConstructorOptions";
|
|
1
|
+
export * from "./synchronisedEntityStorageConnector.js";
|
|
2
|
+
export * from "./models/ISynchronisedEntityStorageConnectorConfig.js";
|
|
3
|
+
export * from "./models/ISynchronisedEntityStorageConnectorConstructorOptions.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ISynchronisedEntityStorageConnectorConfig } from "./ISynchronisedEntityStorageConnectorConfig";
|
|
1
|
+
import type { ISynchronisedEntityStorageConnectorConfig } from "./ISynchronisedEntityStorageConnectorConfig.js";
|
|
2
2
|
/**
|
|
3
3
|
* Options for the Synchronised Entity Storage Connector constructor.
|
|
4
4
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type EntityCondition, type IEntitySchema, SortDirection } from "@twin.org/entity";
|
|
2
2
|
import { type IEntityStorageConnector } from "@twin.org/entity-storage-models";
|
|
3
3
|
import { type ISynchronisedEntity } from "@twin.org/synchronised-storage-models";
|
|
4
|
-
import type { ISynchronisedEntityStorageConnectorConstructorOptions } from "./models/ISynchronisedEntityStorageConnectorConstructorOptions";
|
|
4
|
+
import type { ISynchronisedEntityStorageConnectorConstructorOptions } from "./models/ISynchronisedEntityStorageConnectorConstructorOptions.js";
|
|
5
5
|
/**
|
|
6
6
|
* Class for performing entity storage operations in synchronised storage.
|
|
7
7
|
*/
|
|
@@ -9,12 +9,17 @@ export declare class SynchronisedEntityStorageConnector<T extends ISynchronisedE
|
|
|
9
9
|
/**
|
|
10
10
|
* Runtime name for the class.
|
|
11
11
|
*/
|
|
12
|
-
readonly CLASS_NAME: string;
|
|
12
|
+
static readonly CLASS_NAME: string;
|
|
13
13
|
/**
|
|
14
14
|
* Create a new instance of SynchronisedEntityStorageConnector.
|
|
15
15
|
* @param options The options for the connector.
|
|
16
16
|
*/
|
|
17
17
|
constructor(options: ISynchronisedEntityStorageConnectorConstructorOptions);
|
|
18
|
+
/**
|
|
19
|
+
* Returns the class name of the component.
|
|
20
|
+
* @returns The class name of the component.
|
|
21
|
+
*/
|
|
22
|
+
className(): string;
|
|
18
23
|
/**
|
|
19
24
|
* Get the schema for the entities.
|
|
20
25
|
* @returns The schema for the entities.
|
|
@@ -22,11 +27,10 @@ export declare class SynchronisedEntityStorageConnector<T extends ISynchronisedE
|
|
|
22
27
|
getSchema(): IEntitySchema;
|
|
23
28
|
/**
|
|
24
29
|
* The component needs to be started when the node is initialized.
|
|
25
|
-
* @param nodeIdentity The identity of the node starting the component.
|
|
26
30
|
* @param nodeLoggingComponentType The node logging component type.
|
|
27
31
|
* @returns Nothing.
|
|
28
32
|
*/
|
|
29
|
-
start(
|
|
33
|
+
start(nodeLoggingComponentType?: string): Promise<void>;
|
|
30
34
|
/**
|
|
31
35
|
* Get an entity.
|
|
32
36
|
* @param id The id of the entity to get, or the index value if secondaryIndex is set.
|
|
@@ -63,15 +67,15 @@ export declare class SynchronisedEntityStorageConnector<T extends ISynchronisedE
|
|
|
63
67
|
* @param conditions The conditions to match for the entities.
|
|
64
68
|
* @param sortProperties The optional sort order.
|
|
65
69
|
* @param properties The optional properties to return, defaults to all.
|
|
66
|
-
* @param cursor The cursor to request the next
|
|
67
|
-
* @param
|
|
70
|
+
* @param cursor The cursor to request the next chunk of entities.
|
|
71
|
+
* @param limit The suggested number of entities to return in each chunk, in some scenarios can return a different amount.
|
|
68
72
|
* @returns All the entities for the storage matching the conditions,
|
|
69
73
|
* and a cursor which can be used to request more entities.
|
|
70
74
|
*/
|
|
71
75
|
query(conditions?: EntityCondition<T>, sortProperties?: {
|
|
72
76
|
property: keyof T;
|
|
73
77
|
sortDirection: SortDirection;
|
|
74
|
-
}[], properties?: (keyof T)[], cursor?: string,
|
|
78
|
+
}[], properties?: (keyof T)[], cursor?: string, limit?: number): Promise<{
|
|
75
79
|
/**
|
|
76
80
|
* The entities, which can be partial if a limited keys list was provided.
|
|
77
81
|
*/
|
package/docs/changelog.md
CHANGED
|
@@ -1,5 +1,161 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.3-next.10](https://github.com/twinfoundation/synchronised-storage/compare/entity-storage-connector-synchronised-v0.0.3-next.9...entity-storage-connector-synchronised-v0.0.3-next.10) (2026-03-20)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Miscellaneous Chores
|
|
7
|
+
|
|
8
|
+
* **entity-storage-connector-synchronised:** Synchronize repo versions
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* The following workspace dependencies were updated
|
|
14
|
+
* dependencies
|
|
15
|
+
* @twin.org/synchronised-storage-models bumped from 0.0.3-next.9 to 0.0.3-next.10
|
|
16
|
+
|
|
17
|
+
## [0.0.3-next.9](https://github.com/twinfoundation/synchronised-storage/compare/entity-storage-connector-synchronised-v0.0.3-next.8...entity-storage-connector-synchronised-v0.0.3-next.9) (2026-03-04)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Miscellaneous Chores
|
|
21
|
+
|
|
22
|
+
* **entity-storage-connector-synchronised:** Synchronize repo versions
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Dependencies
|
|
26
|
+
|
|
27
|
+
* The following workspace dependencies were updated
|
|
28
|
+
* dependencies
|
|
29
|
+
* @twin.org/synchronised-storage-models bumped from 0.0.3-next.8 to 0.0.3-next.9
|
|
30
|
+
|
|
31
|
+
## [0.0.3-next.8](https://github.com/twinfoundation/synchronised-storage/compare/entity-storage-connector-synchronised-v0.0.3-next.7...entity-storage-connector-synchronised-v0.0.3-next.8) (2026-02-25)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
### Miscellaneous Chores
|
|
35
|
+
|
|
36
|
+
* **entity-storage-connector-synchronised:** Synchronize repo versions
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
### Dependencies
|
|
40
|
+
|
|
41
|
+
* The following workspace dependencies were updated
|
|
42
|
+
* dependencies
|
|
43
|
+
* @twin.org/synchronised-storage-models bumped from 0.0.3-next.7 to 0.0.3-next.8
|
|
44
|
+
|
|
45
|
+
## [0.0.3-next.7](https://github.com/twinfoundation/synchronised-storage/compare/entity-storage-connector-synchronised-v0.0.3-next.6...entity-storage-connector-synchronised-v0.0.3-next.7) (2026-01-28)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
### Features
|
|
49
|
+
|
|
50
|
+
* json ld contexts ([#36](https://github.com/twinfoundation/synchronised-storage/issues/36)) ([3a87a9f](https://github.com/twinfoundation/synchronised-storage/commit/3a87a9fb16d21baf672e44b4e8914cf1937b1d6a))
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
### Dependencies
|
|
54
|
+
|
|
55
|
+
* The following workspace dependencies were updated
|
|
56
|
+
* dependencies
|
|
57
|
+
* @twin.org/synchronised-storage-models bumped from 0.0.3-next.6 to 0.0.3-next.7
|
|
58
|
+
|
|
59
|
+
## [0.0.3-next.6](https://github.com/twinfoundation/synchronised-storage/compare/entity-storage-connector-synchronised-v0.0.3-next.5...entity-storage-connector-synchronised-v0.0.3-next.6) (2026-01-22)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
### Miscellaneous Chores
|
|
63
|
+
|
|
64
|
+
* **entity-storage-connector-synchronised:** Synchronize repo versions
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
### Dependencies
|
|
68
|
+
|
|
69
|
+
* The following workspace dependencies were updated
|
|
70
|
+
* dependencies
|
|
71
|
+
* @twin.org/synchronised-storage-models bumped from 0.0.3-next.5 to 0.0.3-next.6
|
|
72
|
+
|
|
73
|
+
## [0.0.3-next.5](https://github.com/twinfoundation/synchronised-storage/compare/entity-storage-connector-synchronised-v0.0.3-next.4...entity-storage-connector-synchronised-v0.0.3-next.5) (2026-01-19)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
### Miscellaneous Chores
|
|
77
|
+
|
|
78
|
+
* **entity-storage-connector-synchronised:** Synchronize repo versions
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
### Dependencies
|
|
82
|
+
|
|
83
|
+
* The following workspace dependencies were updated
|
|
84
|
+
* dependencies
|
|
85
|
+
* @twin.org/synchronised-storage-models bumped from 0.0.3-next.4 to 0.0.3-next.5
|
|
86
|
+
|
|
87
|
+
## [0.0.3-next.4](https://github.com/twinfoundation/synchronised-storage/compare/entity-storage-connector-synchronised-v0.0.3-next.3...entity-storage-connector-synchronised-v0.0.3-next.4) (2026-01-15)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
### Miscellaneous Chores
|
|
91
|
+
|
|
92
|
+
* **entity-storage-connector-synchronised:** Synchronize repo versions
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
### Dependencies
|
|
96
|
+
|
|
97
|
+
* The following workspace dependencies were updated
|
|
98
|
+
* dependencies
|
|
99
|
+
* @twin.org/synchronised-storage-models bumped from 0.0.3-next.3 to 0.0.3-next.4
|
|
100
|
+
|
|
101
|
+
## [0.0.3-next.3](https://github.com/twinfoundation/synchronised-storage/compare/entity-storage-connector-synchronised-v0.0.3-next.2...entity-storage-connector-synchronised-v0.0.3-next.3) (2026-01-12)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
### Miscellaneous Chores
|
|
105
|
+
|
|
106
|
+
* **entity-storage-connector-synchronised:** Synchronize repo versions
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
### Dependencies
|
|
110
|
+
|
|
111
|
+
* The following workspace dependencies were updated
|
|
112
|
+
* dependencies
|
|
113
|
+
* @twin.org/synchronised-storage-models bumped from 0.0.3-next.2 to 0.0.3-next.3
|
|
114
|
+
|
|
115
|
+
## [0.0.3-next.2](https://github.com/twinfoundation/synchronised-storage/compare/entity-storage-connector-synchronised-v0.0.3-next.1...entity-storage-connector-synchronised-v0.0.3-next.2) (2025-12-04)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
### Bug Fixes
|
|
119
|
+
|
|
120
|
+
* package.json ([9d3c7d6](https://github.com/twinfoundation/synchronised-storage/commit/9d3c7d65d01b4100f7831b5f057b96fba8211815))
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
### Dependencies
|
|
124
|
+
|
|
125
|
+
* The following workspace dependencies were updated
|
|
126
|
+
* dependencies
|
|
127
|
+
* @twin.org/synchronised-storage-models bumped from 0.0.3-next.1 to 0.0.3-next.2
|
|
128
|
+
|
|
129
|
+
## [0.0.3-next.1](https://github.com/twinfoundation/synchronised-storage/compare/entity-storage-connector-synchronised-v0.0.3-next.0...entity-storage-connector-synchronised-v0.0.3-next.1) (2025-11-12)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
### Features
|
|
133
|
+
|
|
134
|
+
* add context id features ([#24](https://github.com/twinfoundation/synchronised-storage/issues/24)) ([5266b18](https://github.com/twinfoundation/synchronised-storage/commit/5266b18088317c7dc274a209a79102a6fc88a8e4))
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
### Dependencies
|
|
138
|
+
|
|
139
|
+
* The following workspace dependencies were updated
|
|
140
|
+
* dependencies
|
|
141
|
+
* @twin.org/synchronised-storage-models bumped from 0.0.3-next.0 to 0.0.3-next.1
|
|
142
|
+
|
|
143
|
+
## [0.0.2-next.10](https://github.com/twinfoundation/entity-storage/compare/entity-storage-connector-synchronised-v0.0.2-next.9...entity-storage-connector-synchronised-v0.0.2-next.10) (2025-10-09)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
### Features
|
|
147
|
+
|
|
148
|
+
* add validate-locales ([e66ef0d](https://github.com/twinfoundation/entity-storage/commit/e66ef0de26ca2f82b3fe89bb5c7a15a0978a9644))
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
### Dependencies
|
|
152
|
+
|
|
153
|
+
* The following workspace dependencies were updated
|
|
154
|
+
* dependencies
|
|
155
|
+
* @twin.org/entity-storage-models bumped from 0.0.2-next.9 to 0.0.2-next.10
|
|
156
|
+
* devDependencies
|
|
157
|
+
* @twin.org/entity-storage-connector-memory bumped from 0.0.2-next.9 to 0.0.2-next.10
|
|
158
|
+
|
|
3
159
|
## [0.0.2-next.9](https://github.com/twinfoundation/entity-storage/compare/entity-storage-connector-synchronised-v0.0.2-next.8...entity-storage-connector-synchronised-v0.0.2-next.9) (2025-10-02)
|
|
4
160
|
|
|
5
161
|
|
|
@@ -122,4 +278,4 @@
|
|
|
122
278
|
* devDependencies
|
|
123
279
|
* @twin.org/entity-storage-connector-memory bumped from 0.0.1-next.29 to 0.0.2-next.3
|
|
124
280
|
|
|
125
|
-
##
|
|
281
|
+
## Changelog
|