@twin.org/entity-storage-connector-synchronised 0.0.2-next.4 → 0.0.2-next.5

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.
@@ -40,6 +40,11 @@ class SynchronisedEntityStorageConnector {
40
40
  * @internal
41
41
  */
42
42
  _eventBusComponent;
43
+ /**
44
+ * The node identity.
45
+ * @internal
46
+ */
47
+ _nodeIdentity;
43
48
  /**
44
49
  * Create a new instance of SynchronisedEntityStorageConnector.
45
50
  * @param options The options for the connector.
@@ -87,6 +92,7 @@ class SynchronisedEntityStorageConnector {
87
92
  * @returns Nothing.
88
93
  */
89
94
  async start(nodeIdentity, nodeLoggingConnectorType, componentState) {
95
+ this._nodeIdentity = nodeIdentity;
90
96
  // Tell the synchronised storage about this storage key
91
97
  await this._eventBusComponent.publish(synchronisedStorageModels.SynchronisedStorageTopics.RegisterStorageKey, {
92
98
  storageKey: this._storageKey
@@ -112,15 +118,19 @@ class SynchronisedEntityStorageConnector {
112
118
  */
113
119
  async set(entity, conditions) {
114
120
  core.Guards.object(this.CLASS_NAME, "entity", entity);
115
- // Make sure the entity has the required properties
116
- entity.dateModified = new Date(Date.now()).toISOString();
117
- await this._entityStorageConnector.set(entity, conditions);
118
- // Tell the synchronised storage about the entity changes
119
- await this._eventBusComponent.publish(synchronisedStorageModels.SynchronisedStorageTopics.LocalItemChange, {
120
- storageKey: this._storageKey,
121
- operation: synchronisedStorageModels.SyncChangeOperation.Set,
122
- id: entity[this._primaryKey.property]
123
- });
121
+ if (core.Is.stringValue(this._nodeIdentity)) {
122
+ // Make sure the entity has the required properties
123
+ entity.dateModified = new Date(Date.now()).toISOString();
124
+ entity.nodeIdentity = this._nodeIdentity;
125
+ await this._entityStorageConnector.set(entity, conditions);
126
+ // Tell the synchronised storage about the entity changes
127
+ await this._eventBusComponent.publish(synchronisedStorageModels.SynchronisedStorageTopics.LocalItemChange, {
128
+ storageKey: this._storageKey,
129
+ operation: synchronisedStorageModels.SyncChangeOperation.Set,
130
+ nodeIdentity: this._nodeIdentity,
131
+ id: entity[this._primaryKey.property]
132
+ });
133
+ }
124
134
  }
125
135
  /**
126
136
  * Remove the entity.
@@ -130,13 +140,16 @@ class SynchronisedEntityStorageConnector {
130
140
  */
131
141
  async remove(id, conditions) {
132
142
  core.Guards.stringValue(this.CLASS_NAME, "id", id);
133
- await this._entityStorageConnector.remove(id, conditions);
134
- // Tell the synchronised storage about the entity removal
135
- await this._eventBusComponent.publish(synchronisedStorageModels.SynchronisedStorageTopics.LocalItemChange, {
136
- storageKey: this._storageKey,
137
- operation: synchronisedStorageModels.SyncChangeOperation.Delete,
138
- id
139
- });
143
+ if (core.Is.stringValue(this._nodeIdentity)) {
144
+ await this._entityStorageConnector.remove(id, conditions);
145
+ // Tell the synchronised storage about the entity removal
146
+ await this._eventBusComponent.publish(synchronisedStorageModels.SynchronisedStorageTopics.LocalItemChange, {
147
+ storageKey: this._storageKey,
148
+ operation: synchronisedStorageModels.SyncChangeOperation.Delete,
149
+ nodeIdentity: this._nodeIdentity,
150
+ id
151
+ });
152
+ }
140
153
  }
141
154
  /**
142
155
  * Find all the entities which match the conditions.
@@ -158,53 +171,144 @@ class SynchronisedEntityStorageConnector {
158
171
  handleEventBusMessages() {
159
172
  // When the synchronised storage requests an item, we need to provide it
160
173
  this._eventBusComponent.subscribe(synchronisedStorageModels.SynchronisedStorageTopics.LocalItemRequest, async (params) => {
161
- // Only handle the request if it matches the storage key
162
- if (params.data.storageKey === this._storageKey) {
163
- let entity;
164
- try {
165
- entity = await this._entityStorageConnector.get(params.data.id);
166
- }
167
- catch { }
168
- // Publish the item response with the entity
169
- this._eventBusComponent.publish(synchronisedStorageModels.SynchronisedStorageTopics.LocalItemResponse, {
170
- storageKey: this._storageKey,
171
- id: params.data.id,
172
- entity
173
- });
174
- }
174
+ await this.handleLocalItemRequest(params);
175
175
  });
176
176
  // When the synchronised storage requests a batch, we need to provide it
177
177
  this._eventBusComponent.subscribe(synchronisedStorageModels.SynchronisedStorageTopics.BatchRequest, async (params) => {
178
- // Only handle the request if it matches the storage key
179
- if (params.data.storageKey === this._storageKey) {
180
- let cursor;
181
- do {
182
- const result = await this._entityStorageConnector.query(undefined, [{ property: "dateModified", sortDirection: entity.SortDirection.Ascending }], undefined, cursor, params.data.batchSize);
183
- cursor = result.cursor;
184
- // Publish the batch response with the entities
185
- this._eventBusComponent.publish(synchronisedStorageModels.SynchronisedStorageTopics.BatchResponse, {
186
- storageKey: this._storageKey,
187
- entities: result.entities,
188
- lastEntry: !core.Is.stringValue(cursor)
189
- });
190
- } while (core.Is.stringValue(cursor));
191
- }
178
+ await this.handleBatchRequest(params);
192
179
  });
193
180
  // Subscribe to remote item set events from the synchronised storage and update the local storage
194
181
  this._eventBusComponent.subscribe(synchronisedStorageModels.SynchronisedStorageTopics.RemoteItemSet, async (params) => {
195
- // Only remove the item if it matches the storage key
196
- if (params.data.storageKey === this._storageKey) {
197
- await this.set(params.data.entity);
198
- }
182
+ await this.handleRemoteItemSet(params);
199
183
  });
200
184
  // Subscribe to remote item remove events from the synchronised storage and update the local storage
201
185
  this._eventBusComponent.subscribe(synchronisedStorageModels.SynchronisedStorageTopics.RemoteItemRemove, async (params) => {
202
- // Only remove the item if it matches the storage key
203
- if (params.data.storageKey === this._storageKey) {
204
- await this.remove(params.data.id);
205
- }
186
+ await this.handleRemoteItemRemove(params);
187
+ });
188
+ // Subscribe to resets from the synchronised storage and update the local storage
189
+ this._eventBusComponent.subscribe(synchronisedStorageModels.SynchronisedStorageTopics.Reset, async (params) => {
190
+ await this.handleReset(params);
206
191
  });
207
192
  }
193
+ /**
194
+ * Handle a local item request.
195
+ * @param event The request parameters
196
+ * @internal
197
+ */
198
+ async handleLocalItemRequest(event) {
199
+ // Only handle the request if it matches the storage key
200
+ if (event.data.storageKey === this._storageKey) {
201
+ let entity;
202
+ try {
203
+ entity = await this._entityStorageConnector.get(event.data.id);
204
+ }
205
+ catch { }
206
+ // Publish the item response with the entity
207
+ this._eventBusComponent.publish(synchronisedStorageModels.SynchronisedStorageTopics.LocalItemResponse, {
208
+ storageKey: this._storageKey,
209
+ id: event.data.id,
210
+ entity
211
+ });
212
+ }
213
+ }
214
+ /**
215
+ * Handle a remote item set event.
216
+ * @param event The event parameters
217
+ * @internal
218
+ */
219
+ async handleRemoteItemSet(event) {
220
+ // Only set the item if it matches the storage key
221
+ // and it is from another node, remote updates can not change data for this node
222
+ // That must be done via the regular entity storage methods
223
+ if (event.data.storageKey === this._storageKey &&
224
+ event.data.entity.nodeIdentity !== this._nodeIdentity) {
225
+ await this._entityStorageConnector.set(event.data.entity);
226
+ }
227
+ }
228
+ /**
229
+ * Handle a remote item remove event.
230
+ * @param params The event parameters
231
+ * @internal
232
+ */
233
+ async handleRemoteItemRemove(params) {
234
+ // Only remove the item if it matches the storage key
235
+ // and it is from another node, remote updates can not change data for this node
236
+ // That must be done via the regular entity storage methods
237
+ if (params.data.storageKey === this._storageKey &&
238
+ params.data.nodeIdentity !== this._nodeIdentity) {
239
+ await this._entityStorageConnector.remove(params.data.id);
240
+ }
241
+ }
242
+ /**
243
+ * Handle a batch request.
244
+ * @param event The request parameters
245
+ * @internal
246
+ */
247
+ async handleBatchRequest(event) {
248
+ // Only handle the request if it matches the storage key
249
+ if (event.data.storageKey === this._storageKey) {
250
+ let cursor;
251
+ do {
252
+ const condition = {
253
+ conditions: []
254
+ };
255
+ if (event.data.requestMode === synchronisedStorageModels.SyncNodeIdentityMode.Local ||
256
+ event.data.requestMode === synchronisedStorageModels.SyncNodeIdentityMode.Remote) {
257
+ condition.conditions.push({
258
+ property: "nodeIdentity",
259
+ value: this._nodeIdentity,
260
+ comparison: event.data.requestMode === synchronisedStorageModels.SyncNodeIdentityMode.Local
261
+ ? entity.ComparisonOperator.Equals
262
+ : entity.ComparisonOperator.NotEquals
263
+ });
264
+ }
265
+ const result = await this._entityStorageConnector.query(condition, [{ property: "dateModified", sortDirection: entity.SortDirection.Ascending }], undefined, cursor, event.data.batchSize);
266
+ cursor = result.cursor;
267
+ // Publish the batch response with the entities
268
+ this._eventBusComponent.publish(synchronisedStorageModels.SynchronisedStorageTopics.BatchResponse, {
269
+ storageKey: this._storageKey,
270
+ entities: result.entities,
271
+ lastEntry: !core.Is.stringValue(cursor)
272
+ });
273
+ } while (core.Is.stringValue(cursor));
274
+ }
275
+ }
276
+ /**
277
+ * Handle a reset event.
278
+ * @param event The event parameters
279
+ * @internal
280
+ */
281
+ async handleReset(event) {
282
+ // Only reset the storage if it matches the storage key
283
+ if (event.data.storageKey === this._storageKey) {
284
+ let cursor;
285
+ let toRemove = [];
286
+ // Build a list of the ids to remove
287
+ do {
288
+ const condition = {
289
+ conditions: []
290
+ };
291
+ // Depending on the reset mode we can filter the entities to remove
292
+ if (event.data.resetMode === synchronisedStorageModels.SyncNodeIdentityMode.Local ||
293
+ event.data.resetMode === synchronisedStorageModels.SyncNodeIdentityMode.Remote) {
294
+ condition.conditions.push({
295
+ property: "nodeIdentity",
296
+ value: this._nodeIdentity,
297
+ comparison: event.data.resetMode === synchronisedStorageModels.SyncNodeIdentityMode.Local
298
+ ? entity.ComparisonOperator.Equals
299
+ : entity.ComparisonOperator.NotEquals
300
+ });
301
+ }
302
+ const result = await this._entityStorageConnector.query(condition, undefined, undefined, cursor);
303
+ cursor = result.cursor;
304
+ toRemove = toRemove.concat(result.entities.map(entity => entity.id));
305
+ } while (core.Is.stringValue(cursor));
306
+ // Remove the entities
307
+ for (let i = 0; i < toRemove.length; i++) {
308
+ await this.remove(toRemove[i]);
309
+ }
310
+ }
311
+ }
208
312
  }
209
313
 
210
314
  exports.SynchronisedEntityStorageConnector = SynchronisedEntityStorageConnector;
@@ -1,7 +1,7 @@
1
1
  import { Guards, StringHelper, Is, GeneralError, ComponentFactory } from '@twin.org/core';
2
- import { EntitySchemaFactory, EntitySchemaHelper, SortDirection } from '@twin.org/entity';
2
+ import { EntitySchemaFactory, EntitySchemaHelper, ComparisonOperator, SortDirection } from '@twin.org/entity';
3
3
  import { EntityStorageConnectorFactory } from '@twin.org/entity-storage-models';
4
- import { SynchronisedStorageTopics, SyncChangeOperation } from '@twin.org/synchronised-storage-models';
4
+ import { SynchronisedStorageTopics, SyncChangeOperation, SyncNodeIdentityMode } from '@twin.org/synchronised-storage-models';
5
5
 
6
6
  // Copyright 2024 IOTA Stiftung.
7
7
  // SPDX-License-Identifier: Apache-2.0.
@@ -38,6 +38,11 @@ class SynchronisedEntityStorageConnector {
38
38
  * @internal
39
39
  */
40
40
  _eventBusComponent;
41
+ /**
42
+ * The node identity.
43
+ * @internal
44
+ */
45
+ _nodeIdentity;
41
46
  /**
42
47
  * Create a new instance of SynchronisedEntityStorageConnector.
43
48
  * @param options The options for the connector.
@@ -85,6 +90,7 @@ class SynchronisedEntityStorageConnector {
85
90
  * @returns Nothing.
86
91
  */
87
92
  async start(nodeIdentity, nodeLoggingConnectorType, componentState) {
93
+ this._nodeIdentity = nodeIdentity;
88
94
  // Tell the synchronised storage about this storage key
89
95
  await this._eventBusComponent.publish(SynchronisedStorageTopics.RegisterStorageKey, {
90
96
  storageKey: this._storageKey
@@ -110,15 +116,19 @@ class SynchronisedEntityStorageConnector {
110
116
  */
111
117
  async set(entity, conditions) {
112
118
  Guards.object(this.CLASS_NAME, "entity", entity);
113
- // Make sure the entity has the required properties
114
- entity.dateModified = new Date(Date.now()).toISOString();
115
- await this._entityStorageConnector.set(entity, conditions);
116
- // Tell the synchronised storage about the entity changes
117
- await this._eventBusComponent.publish(SynchronisedStorageTopics.LocalItemChange, {
118
- storageKey: this._storageKey,
119
- operation: SyncChangeOperation.Set,
120
- id: entity[this._primaryKey.property]
121
- });
119
+ if (Is.stringValue(this._nodeIdentity)) {
120
+ // Make sure the entity has the required properties
121
+ entity.dateModified = new Date(Date.now()).toISOString();
122
+ entity.nodeIdentity = this._nodeIdentity;
123
+ await this._entityStorageConnector.set(entity, conditions);
124
+ // Tell the synchronised storage about the entity changes
125
+ await this._eventBusComponent.publish(SynchronisedStorageTopics.LocalItemChange, {
126
+ storageKey: this._storageKey,
127
+ operation: SyncChangeOperation.Set,
128
+ nodeIdentity: this._nodeIdentity,
129
+ id: entity[this._primaryKey.property]
130
+ });
131
+ }
122
132
  }
123
133
  /**
124
134
  * Remove the entity.
@@ -128,13 +138,16 @@ class SynchronisedEntityStorageConnector {
128
138
  */
129
139
  async remove(id, conditions) {
130
140
  Guards.stringValue(this.CLASS_NAME, "id", id);
131
- await this._entityStorageConnector.remove(id, conditions);
132
- // Tell the synchronised storage about the entity removal
133
- await this._eventBusComponent.publish(SynchronisedStorageTopics.LocalItemChange, {
134
- storageKey: this._storageKey,
135
- operation: SyncChangeOperation.Delete,
136
- id
137
- });
141
+ if (Is.stringValue(this._nodeIdentity)) {
142
+ await this._entityStorageConnector.remove(id, conditions);
143
+ // Tell the synchronised storage about the entity removal
144
+ await this._eventBusComponent.publish(SynchronisedStorageTopics.LocalItemChange, {
145
+ storageKey: this._storageKey,
146
+ operation: SyncChangeOperation.Delete,
147
+ nodeIdentity: this._nodeIdentity,
148
+ id
149
+ });
150
+ }
138
151
  }
139
152
  /**
140
153
  * Find all the entities which match the conditions.
@@ -156,53 +169,144 @@ class SynchronisedEntityStorageConnector {
156
169
  handleEventBusMessages() {
157
170
  // When the synchronised storage requests an item, we need to provide it
158
171
  this._eventBusComponent.subscribe(SynchronisedStorageTopics.LocalItemRequest, async (params) => {
159
- // Only handle the request if it matches the storage key
160
- if (params.data.storageKey === this._storageKey) {
161
- let entity;
162
- try {
163
- entity = await this._entityStorageConnector.get(params.data.id);
164
- }
165
- catch { }
166
- // Publish the item response with the entity
167
- this._eventBusComponent.publish(SynchronisedStorageTopics.LocalItemResponse, {
168
- storageKey: this._storageKey,
169
- id: params.data.id,
170
- entity
171
- });
172
- }
172
+ await this.handleLocalItemRequest(params);
173
173
  });
174
174
  // When the synchronised storage requests a batch, we need to provide it
175
175
  this._eventBusComponent.subscribe(SynchronisedStorageTopics.BatchRequest, async (params) => {
176
- // Only handle the request if it matches the storage key
177
- if (params.data.storageKey === this._storageKey) {
178
- let cursor;
179
- do {
180
- const result = await this._entityStorageConnector.query(undefined, [{ property: "dateModified", sortDirection: SortDirection.Ascending }], undefined, cursor, params.data.batchSize);
181
- cursor = result.cursor;
182
- // Publish the batch response with the entities
183
- this._eventBusComponent.publish(SynchronisedStorageTopics.BatchResponse, {
184
- storageKey: this._storageKey,
185
- entities: result.entities,
186
- lastEntry: !Is.stringValue(cursor)
187
- });
188
- } while (Is.stringValue(cursor));
189
- }
176
+ await this.handleBatchRequest(params);
190
177
  });
191
178
  // Subscribe to remote item set events from the synchronised storage and update the local storage
192
179
  this._eventBusComponent.subscribe(SynchronisedStorageTopics.RemoteItemSet, async (params) => {
193
- // Only remove the item if it matches the storage key
194
- if (params.data.storageKey === this._storageKey) {
195
- await this.set(params.data.entity);
196
- }
180
+ await this.handleRemoteItemSet(params);
197
181
  });
198
182
  // Subscribe to remote item remove events from the synchronised storage and update the local storage
199
183
  this._eventBusComponent.subscribe(SynchronisedStorageTopics.RemoteItemRemove, async (params) => {
200
- // Only remove the item if it matches the storage key
201
- if (params.data.storageKey === this._storageKey) {
202
- await this.remove(params.data.id);
203
- }
184
+ await this.handleRemoteItemRemove(params);
185
+ });
186
+ // Subscribe to resets from the synchronised storage and update the local storage
187
+ this._eventBusComponent.subscribe(SynchronisedStorageTopics.Reset, async (params) => {
188
+ await this.handleReset(params);
204
189
  });
205
190
  }
191
+ /**
192
+ * Handle a local item request.
193
+ * @param event The request parameters
194
+ * @internal
195
+ */
196
+ async handleLocalItemRequest(event) {
197
+ // Only handle the request if it matches the storage key
198
+ if (event.data.storageKey === this._storageKey) {
199
+ let entity;
200
+ try {
201
+ entity = await this._entityStorageConnector.get(event.data.id);
202
+ }
203
+ catch { }
204
+ // Publish the item response with the entity
205
+ this._eventBusComponent.publish(SynchronisedStorageTopics.LocalItemResponse, {
206
+ storageKey: this._storageKey,
207
+ id: event.data.id,
208
+ entity
209
+ });
210
+ }
211
+ }
212
+ /**
213
+ * Handle a remote item set event.
214
+ * @param event The event parameters
215
+ * @internal
216
+ */
217
+ async handleRemoteItemSet(event) {
218
+ // Only set the item if it matches the storage key
219
+ // and it is from another node, remote updates can not change data for this node
220
+ // That must be done via the regular entity storage methods
221
+ if (event.data.storageKey === this._storageKey &&
222
+ event.data.entity.nodeIdentity !== this._nodeIdentity) {
223
+ await this._entityStorageConnector.set(event.data.entity);
224
+ }
225
+ }
226
+ /**
227
+ * Handle a remote item remove event.
228
+ * @param params The event parameters
229
+ * @internal
230
+ */
231
+ async handleRemoteItemRemove(params) {
232
+ // Only remove the item if it matches the storage key
233
+ // and it is from another node, remote updates can not change data for this node
234
+ // That must be done via the regular entity storage methods
235
+ if (params.data.storageKey === this._storageKey &&
236
+ params.data.nodeIdentity !== this._nodeIdentity) {
237
+ await this._entityStorageConnector.remove(params.data.id);
238
+ }
239
+ }
240
+ /**
241
+ * Handle a batch request.
242
+ * @param event The request parameters
243
+ * @internal
244
+ */
245
+ async handleBatchRequest(event) {
246
+ // Only handle the request if it matches the storage key
247
+ if (event.data.storageKey === this._storageKey) {
248
+ let cursor;
249
+ do {
250
+ const condition = {
251
+ conditions: []
252
+ };
253
+ if (event.data.requestMode === SyncNodeIdentityMode.Local ||
254
+ event.data.requestMode === SyncNodeIdentityMode.Remote) {
255
+ condition.conditions.push({
256
+ property: "nodeIdentity",
257
+ value: this._nodeIdentity,
258
+ comparison: event.data.requestMode === SyncNodeIdentityMode.Local
259
+ ? ComparisonOperator.Equals
260
+ : ComparisonOperator.NotEquals
261
+ });
262
+ }
263
+ const result = await this._entityStorageConnector.query(condition, [{ property: "dateModified", sortDirection: SortDirection.Ascending }], undefined, cursor, event.data.batchSize);
264
+ cursor = result.cursor;
265
+ // Publish the batch response with the entities
266
+ this._eventBusComponent.publish(SynchronisedStorageTopics.BatchResponse, {
267
+ storageKey: this._storageKey,
268
+ entities: result.entities,
269
+ lastEntry: !Is.stringValue(cursor)
270
+ });
271
+ } while (Is.stringValue(cursor));
272
+ }
273
+ }
274
+ /**
275
+ * Handle a reset event.
276
+ * @param event The event parameters
277
+ * @internal
278
+ */
279
+ async handleReset(event) {
280
+ // Only reset the storage if it matches the storage key
281
+ if (event.data.storageKey === this._storageKey) {
282
+ let cursor;
283
+ let toRemove = [];
284
+ // Build a list of the ids to remove
285
+ do {
286
+ const condition = {
287
+ conditions: []
288
+ };
289
+ // Depending on the reset mode we can filter the entities to remove
290
+ if (event.data.resetMode === SyncNodeIdentityMode.Local ||
291
+ event.data.resetMode === SyncNodeIdentityMode.Remote) {
292
+ condition.conditions.push({
293
+ property: "nodeIdentity",
294
+ value: this._nodeIdentity,
295
+ comparison: event.data.resetMode === SyncNodeIdentityMode.Local
296
+ ? ComparisonOperator.Equals
297
+ : ComparisonOperator.NotEquals
298
+ });
299
+ }
300
+ const result = await this._entityStorageConnector.query(condition, undefined, undefined, cursor);
301
+ cursor = result.cursor;
302
+ toRemove = toRemove.concat(result.entities.map(entity => entity.id));
303
+ } while (Is.stringValue(cursor));
304
+ // Remove the entities
305
+ for (let i = 0; i < toRemove.length; i++) {
306
+ await this.remove(toRemove[i]);
307
+ }
308
+ }
309
+ }
206
310
  }
207
311
 
208
312
  export { SynchronisedEntityStorageConnector };
package/docs/changelog.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.0.2-next.5](https://github.com/twinfoundation/entity-storage/compare/entity-storage-connector-synchronised-v0.0.2-next.4...entity-storage-connector-synchronised-v0.0.2-next.5) (2025-08-11)
4
+
5
+
6
+ ### Features
7
+
8
+ * support new synchronised storage features ([0d9ebab](https://github.com/twinfoundation/entity-storage/commit/0d9ebab237040892cab8e7db751aa2e40c0c76e0))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @twin.org/entity-storage-models bumped from 0.0.2-next.4 to 0.0.2-next.5
16
+ * devDependencies
17
+ * @twin.org/entity-storage-connector-memory bumped from 0.0.2-next.4 to 0.0.2-next.5
18
+
3
19
  ## [0.0.2-next.4](https://github.com/twinfoundation/entity-storage/compare/entity-storage-connector-synchronised-v0.0.2-next.3...entity-storage-connector-synchronised-v0.0.2-next.4) (2025-08-08)
4
20
 
5
21
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/entity-storage-connector-synchronised",
3
- "version": "0.0.2-next.4",
3
+ "version": "0.0.2-next.5",
4
4
  "description": "Entity Storage connector implementation using synchronised storage",
5
5
  "repository": {
6
6
  "type": "git",
@@ -16,7 +16,7 @@
16
16
  "dependencies": {
17
17
  "@twin.org/core": "next",
18
18
  "@twin.org/entity": "next",
19
- "@twin.org/entity-storage-models": "0.0.2-next.4",
19
+ "@twin.org/entity-storage-models": "0.0.2-next.5",
20
20
  "@twin.org/event-bus-models": "next",
21
21
  "@twin.org/logging-models": "next",
22
22
  "@twin.org/nameof": "next",