@itwin/core-backend 5.13.0-dev.18 → 5.13.0-dev.20

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.
Files changed (112) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/lib/cjs/EditTxn.d.ts.map +1 -1
  3. package/lib/cjs/EditTxn.js +1 -0
  4. package/lib/cjs/EditTxn.js.map +1 -1
  5. package/lib/cjs/Element.d.ts +5 -1
  6. package/lib/cjs/Element.d.ts.map +1 -1
  7. package/lib/cjs/Element.js +4 -0
  8. package/lib/cjs/Element.js.map +1 -1
  9. package/lib/cjs/IModelDb.d.ts +15 -0
  10. package/lib/cjs/IModelDb.d.ts.map +1 -1
  11. package/lib/cjs/IModelDb.js +24 -0
  12. package/lib/cjs/IModelDb.js.map +1 -1
  13. package/lib/cjs/SchemaSync.d.ts +37 -9
  14. package/lib/cjs/SchemaSync.d.ts.map +1 -1
  15. package/lib/cjs/SchemaSync.js +125 -6
  16. package/lib/cjs/SchemaSync.js.map +1 -1
  17. package/lib/cjs/SynchronousChannel.d.ts +62 -0
  18. package/lib/cjs/SynchronousChannel.d.ts.map +1 -0
  19. package/lib/cjs/SynchronousChannel.js +11 -0
  20. package/lib/cjs/SynchronousChannel.js.map +1 -0
  21. package/lib/cjs/TxnManager.d.ts +44 -4
  22. package/lib/cjs/TxnManager.d.ts.map +1 -1
  23. package/lib/cjs/TxnManager.js +63 -14
  24. package/lib/cjs/TxnManager.js.map +1 -1
  25. package/lib/cjs/core-backend.d.ts +1 -0
  26. package/lib/cjs/core-backend.d.ts.map +1 -1
  27. package/lib/cjs/core-backend.js +1 -0
  28. package/lib/cjs/core-backend.js.map +1 -1
  29. package/lib/cjs/internal/IntegrityCheck.d.ts +22 -0
  30. package/lib/cjs/internal/IntegrityCheck.d.ts.map +1 -1
  31. package/lib/cjs/internal/IntegrityCheck.js +13 -0
  32. package/lib/cjs/internal/IntegrityCheck.js.map +1 -1
  33. package/lib/cjs/internal/NoReservations.d.ts +6 -0
  34. package/lib/cjs/internal/NoReservations.d.ts.map +1 -0
  35. package/lib/cjs/internal/NoReservations.js +21 -0
  36. package/lib/cjs/internal/NoReservations.js.map +1 -0
  37. package/lib/cjs/internal/SchemaSyncReservations.d.ts +4 -0
  38. package/lib/cjs/internal/SchemaSyncReservations.d.ts.map +1 -0
  39. package/lib/cjs/internal/SchemaSyncReservations.js +118 -0
  40. package/lib/cjs/internal/SchemaSyncReservations.js.map +1 -0
  41. package/lib/cjs/internal/Symbols.d.ts +1 -0
  42. package/lib/cjs/internal/Symbols.d.ts.map +1 -1
  43. package/lib/cjs/internal/Symbols.js +2 -1
  44. package/lib/cjs/internal/Symbols.js.map +1 -1
  45. package/lib/esm/EditTxn.d.ts.map +1 -1
  46. package/lib/esm/EditTxn.js +1 -0
  47. package/lib/esm/EditTxn.js.map +1 -1
  48. package/lib/esm/Element.d.ts +5 -1
  49. package/lib/esm/Element.d.ts.map +1 -1
  50. package/lib/esm/Element.js +5 -1
  51. package/lib/esm/Element.js.map +1 -1
  52. package/lib/esm/IModelDb.d.ts +15 -0
  53. package/lib/esm/IModelDb.d.ts.map +1 -1
  54. package/lib/esm/IModelDb.js +24 -0
  55. package/lib/esm/IModelDb.js.map +1 -1
  56. package/lib/esm/SchemaSync.d.ts +37 -9
  57. package/lib/esm/SchemaSync.d.ts.map +1 -1
  58. package/lib/esm/SchemaSync.js +127 -8
  59. package/lib/esm/SchemaSync.js.map +1 -1
  60. package/lib/esm/SynchronousChannel.d.ts +62 -0
  61. package/lib/esm/SynchronousChannel.d.ts.map +1 -0
  62. package/lib/esm/SynchronousChannel.js +9 -0
  63. package/lib/esm/SynchronousChannel.js.map +1 -0
  64. package/lib/esm/TxnManager.d.ts +44 -4
  65. package/lib/esm/TxnManager.d.ts.map +1 -1
  66. package/lib/esm/TxnManager.js +63 -14
  67. package/lib/esm/TxnManager.js.map +1 -1
  68. package/lib/esm/core-backend.d.ts +1 -0
  69. package/lib/esm/core-backend.d.ts.map +1 -1
  70. package/lib/esm/core-backend.js +1 -0
  71. package/lib/esm/core-backend.js.map +1 -1
  72. package/lib/esm/internal/IntegrityCheck.d.ts +22 -0
  73. package/lib/esm/internal/IntegrityCheck.d.ts.map +1 -1
  74. package/lib/esm/internal/IntegrityCheck.js +13 -0
  75. package/lib/esm/internal/IntegrityCheck.js.map +1 -1
  76. package/lib/esm/internal/NoReservations.d.ts +6 -0
  77. package/lib/esm/internal/NoReservations.d.ts.map +1 -0
  78. package/lib/esm/internal/NoReservations.js +18 -0
  79. package/lib/esm/internal/NoReservations.js.map +1 -0
  80. package/lib/esm/internal/SchemaSyncReservations.d.ts +4 -0
  81. package/lib/esm/internal/SchemaSyncReservations.d.ts.map +1 -0
  82. package/lib/esm/internal/SchemaSyncReservations.js +115 -0
  83. package/lib/esm/internal/SchemaSyncReservations.js.map +1 -0
  84. package/lib/esm/internal/Symbols.d.ts +1 -0
  85. package/lib/esm/internal/Symbols.d.ts.map +1 -1
  86. package/lib/esm/internal/Symbols.js +1 -0
  87. package/lib/esm/internal/Symbols.js.map +1 -1
  88. package/lib/esm/test/imodel/IModelLifecycle.test.js +1 -0
  89. package/lib/esm/test/imodel/IModelLifecycle.test.js.map +1 -1
  90. package/lib/esm/test/index.d.ts +0 -1
  91. package/lib/esm/test/index.d.ts.map +1 -1
  92. package/lib/esm/test/index.js +0 -1
  93. package/lib/esm/test/index.js.map +1 -1
  94. package/lib/esm/test/standalone/IntegrityCheck.test.js +29 -10
  95. package/lib/esm/test/standalone/IntegrityCheck.test.js.map +1 -1
  96. package/lib/esm/test/standalone/SchemaSyncDb.test.d.ts +2 -0
  97. package/lib/esm/test/standalone/SchemaSyncDb.test.d.ts.map +1 -0
  98. package/lib/esm/test/standalone/SchemaSyncDb.test.js +221 -0
  99. package/lib/esm/test/standalone/SchemaSyncDb.test.js.map +1 -0
  100. package/lib/esm/test/standalone/SchemaSyncElementReservation.test.d.ts +2 -0
  101. package/lib/esm/test/standalone/SchemaSyncElementReservation.test.d.ts.map +1 -0
  102. package/lib/esm/test/standalone/SchemaSyncElementReservation.test.js +459 -0
  103. package/lib/esm/test/standalone/SchemaSyncElementReservation.test.js.map +1 -0
  104. package/lib/esm/test/standalone/SnapshotDb.test.js +1 -0
  105. package/lib/esm/test/standalone/SnapshotDb.test.js.map +1 -1
  106. package/lib/esm/test/standalone/TxnManager.test.js +108 -8
  107. package/lib/esm/test/standalone/TxnManager.test.js.map +1 -1
  108. package/package.json +13 -13
  109. package/lib/esm/test/RevisionUtility.d.ts +0 -33
  110. package/lib/esm/test/RevisionUtility.d.ts.map +0 -1
  111. package/lib/esm/test/RevisionUtility.js +0 -52
  112. package/lib/esm/test/RevisionUtility.js.map +0 -1
@@ -73,6 +73,16 @@ export function setMaxEntitiesPerEvent(max) {
73
73
  ChangedEntitiesProc.maxPerEvent = max;
74
74
  return prevMax;
75
75
  }
76
+ class TxnEntityMetadataImpl {
77
+ classFullName;
78
+ baseClasses = [];
79
+ constructor(classFullName) {
80
+ this.classFullName = classFullName;
81
+ }
82
+ is(baseClassFullName) {
83
+ return this.classFullName === baseClassFullName || this.baseClasses.some((baseClass) => baseClass.is(baseClassFullName));
84
+ }
85
+ }
76
86
  /** Maintains an ordered array of entity Ids and a parallel array containing the index of the corresponding entity's class Id. */
77
87
  class ChangedEntitiesArray {
78
88
  entityIds = new OrderedId64Array();
@@ -105,12 +115,17 @@ class ChangedEntitiesArray {
105
115
  entities[type] = CompressedId64Set.compressIds(this.entityIds);
106
116
  entities[`${type}Meta`] = this._classIndices;
107
117
  }
108
- iterable(classIds) {
118
+ iterable(classIds, metadata) {
109
119
  function* iterator(entityIds, classIndices) {
110
- const entity = { id: "", classId: "" };
120
+ let entity;
111
121
  for (let i = 0; i < entityIds.length; i++) {
122
+ const classIndex = classIndices[i];
123
+ const entityMetadata = metadata[classIndex];
124
+ assert(undefined !== entityMetadata);
125
+ entity ??= { id: "", classId: "", metadata: entityMetadata };
112
126
  entity.id = entityIds[i];
113
- entity.classId = classIds[classIndices[i]];
127
+ entity.classId = classIds[classIndex];
128
+ entity.metadata = entityMetadata;
114
129
  yield entity;
115
130
  }
116
131
  }
@@ -156,10 +171,10 @@ class ChangedEntitiesProc {
156
171
  const meta = db.classMetaDataRegistry.findByClassId(classId);
157
172
  nameToIndex.set(meta?.ecclass ?? "", nameToIndex.size);
158
173
  }
159
- const result = [];
174
+ const metadata = [];
160
175
  function addMetadata(name, index) {
161
176
  const bases = [];
162
- result[index] = { name, bases };
177
+ metadata[index] = { name, bases };
163
178
  // eslint-disable-next-line @typescript-eslint/no-deprecated
164
179
  const meta = db.tryGetMetaData(name);
165
180
  if (!meta) {
@@ -182,25 +197,43 @@ class ChangedEntitiesProc {
182
197
  }
183
198
  addMetadata(name, index);
184
199
  }
185
- return result;
200
+ return metadata;
201
+ }
202
+ populateBackendMetadata(frontendMetadata) {
203
+ const backendMetadata = frontendMetadata.map(({ name }) => new TxnEntityMetadataImpl(name));
204
+ for (let index = 0; index < frontendMetadata.length; index++) {
205
+ const frontend = frontendMetadata[index];
206
+ const backend = backendMetadata[index];
207
+ assert(undefined !== frontend && undefined !== backend);
208
+ for (const baseClassIndex of frontend.bases) {
209
+ const baseClass = backendMetadata[baseClassIndex];
210
+ assert(undefined !== baseClass);
211
+ backend.baseClasses.push(baseClass);
212
+ }
213
+ }
214
+ return backendMetadata;
186
215
  }
187
216
  sendEvent(iModel, evt, evtName) {
188
217
  if (this._currSize === 0)
189
218
  return;
190
219
  const classIds = this._classIds.toArray();
191
- // Notify backend listeners.
192
- const txnEntities = {
193
- inserts: this._inserted.iterable(classIds),
194
- deletes: this._deleted.iterable(classIds),
195
- updates: this._updated.iterable(classIds),
196
- };
197
- evt.raiseEvent(txnEntities);
220
+ const frontendMetadata = this.populateMetadata(iModel, classIds);
221
+ // Notify backend listeners. Avoid constructing the backend metadata graph when there are no listeners.
222
+ if (evt.numberOfListeners > 0) {
223
+ const backendMetadata = this.populateBackendMetadata(frontendMetadata);
224
+ const txnEntities = {
225
+ inserts: this._inserted.iterable(classIds, backendMetadata),
226
+ deletes: this._deleted.iterable(classIds, backendMetadata),
227
+ updates: this._updated.iterable(classIds, backendMetadata),
228
+ };
229
+ evt.raiseEvent(txnEntities);
230
+ }
198
231
  // Notify frontend listeners.
199
232
  const entities = {
200
233
  insertedMeta: [],
201
234
  updatedMeta: [],
202
235
  deletedMeta: [],
203
- meta: this.populateMetadata(iModel, classIds),
236
+ meta: frontendMetadata,
204
237
  };
205
238
  this._inserted.addToChangedEntities(entities, "inserted");
206
239
  this._deleted.addToChangedEntities(entities, "deleted");
@@ -1074,11 +1107,27 @@ export class TxnManager {
1074
1107
  onEndValidation = new BeEvent();
1075
1108
  /** Called after validation completes from [[IModelDb.saveChanges]].
1076
1109
  * The argument to the event holds the list of elements that were inserted, updated, and deleted.
1110
+ * Each changed entity includes its `id`, `classId`, and [[TxnChangedEntity.metadata]]. Use `metadata.classFullName` for an exact class match or `metadata.is` to match a class or one of its subclasses.
1111
+ * @example
1112
+ * ```ts
1113
+ * iModel.txns.onElementsChanged.addListener((changes) => {
1114
+ * for (const change of changes.inserts) {
1115
+ * if (change.metadata.classFullName === "MySchema:MyElement")
1116
+ * invalidateCache();
1117
+ * }
1118
+ *
1119
+ * for (const change of changes.updates) {
1120
+ * if (change.metadata.is("BisCore:GeometricElement"))
1121
+ * invalidateGeometryCache(change.id);
1122
+ * }
1123
+ * });
1124
+ * ```
1077
1125
  * @note If there are many changed elements in a single Txn, the notifications are sent in batches so this event *may be called multiple times* per Txn.
1078
1126
  */
1079
1127
  onElementsChanged = new BeEvent();
1080
1128
  /** Called after validation completes from [[IModelDb.saveChanges]].
1081
1129
  * The argument to the event holds the list of models that were inserted, updated, and deleted.
1130
+ * Each changed model includes its `id`, `classId`, and [[TxnChangedEntity.metadata]]. Use `metadata.classFullName` for an exact class match or `metadata.is` to match a class or one of its subclasses.
1082
1131
  * @note If there are many changed models in a single Txn, the notifications are sent in batches so this event *may be called multiple times* per Txn.
1083
1132
  */
1084
1133
  onModelsChanged = new BeEvent();