@itwin/core-backend 5.15.0-dev.14 → 5.15.0-dev.15

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 (49) hide show
  1. package/lib/cjs/BriefcaseManager.d.ts.map +1 -1
  2. package/lib/cjs/BriefcaseManager.js +4 -0
  3. package/lib/cjs/BriefcaseManager.js.map +1 -1
  4. package/lib/cjs/ECDb.d.ts +1 -0
  5. package/lib/cjs/ECDb.d.ts.map +1 -1
  6. package/lib/cjs/ECDb.js +4 -1
  7. package/lib/cjs/ECDb.js.map +1 -1
  8. package/lib/cjs/IModelDb.d.ts +1 -0
  9. package/lib/cjs/IModelDb.d.ts.map +1 -1
  10. package/lib/cjs/IModelDb.js +9 -3
  11. package/lib/cjs/IModelDb.js.map +1 -1
  12. package/lib/cjs/SchemaSync.d.ts.map +1 -1
  13. package/lib/cjs/SchemaSync.js +1 -0
  14. package/lib/cjs/SchemaSync.js.map +1 -1
  15. package/lib/cjs/TxnManager.d.ts +111 -88
  16. package/lib/cjs/TxnManager.d.ts.map +1 -1
  17. package/lib/cjs/TxnManager.js +95 -75
  18. package/lib/cjs/TxnManager.js.map +1 -1
  19. package/lib/cjs/internal/QueryMetadataCache.d.ts +44 -0
  20. package/lib/cjs/internal/QueryMetadataCache.d.ts.map +1 -0
  21. package/lib/cjs/internal/QueryMetadataCache.js +107 -0
  22. package/lib/cjs/internal/QueryMetadataCache.js.map +1 -0
  23. package/lib/esm/BriefcaseManager.d.ts.map +1 -1
  24. package/lib/esm/BriefcaseManager.js +4 -0
  25. package/lib/esm/BriefcaseManager.js.map +1 -1
  26. package/lib/esm/ECDb.d.ts +1 -0
  27. package/lib/esm/ECDb.d.ts.map +1 -1
  28. package/lib/esm/ECDb.js +4 -1
  29. package/lib/esm/ECDb.js.map +1 -1
  30. package/lib/esm/IModelDb.d.ts +1 -0
  31. package/lib/esm/IModelDb.d.ts.map +1 -1
  32. package/lib/esm/IModelDb.js +9 -3
  33. package/lib/esm/IModelDb.js.map +1 -1
  34. package/lib/esm/SchemaSync.d.ts.map +1 -1
  35. package/lib/esm/SchemaSync.js +1 -0
  36. package/lib/esm/SchemaSync.js.map +1 -1
  37. package/lib/esm/TxnManager.d.ts +111 -88
  38. package/lib/esm/TxnManager.d.ts.map +1 -1
  39. package/lib/esm/TxnManager.js +95 -75
  40. package/lib/esm/TxnManager.js.map +1 -1
  41. package/lib/esm/internal/QueryMetadataCache.d.ts +44 -0
  42. package/lib/esm/internal/QueryMetadataCache.d.ts.map +1 -0
  43. package/lib/esm/internal/QueryMetadataCache.js +103 -0
  44. package/lib/esm/internal/QueryMetadataCache.js.map +1 -0
  45. package/lib/esm/test/ecdb/QueryMetadataCache.test.d.ts +2 -0
  46. package/lib/esm/test/ecdb/QueryMetadataCache.test.d.ts.map +1 -0
  47. package/lib/esm/test/ecdb/QueryMetadataCache.test.js +630 -0
  48. package/lib/esm/test/ecdb/QueryMetadataCache.test.js.map +1 -0
  49. package/package.json +15 -15
@@ -284,18 +284,18 @@ class ChangedEntitiesProc {
284
284
  * Manages the process of merging and rebasing local changes (transactions) in a [[BriefcaseDb]].
285
285
  *
286
286
  * The `RebaseManager` coordinates the rebase of local transactions when pulling and merging changes from other sources,
287
- * such as remote repositories or other users. It provides mechanisms to handle transaction conflicts, register custom conflict
288
- * handlers, and manage the rebase workflow. This includes resuming rebases, invoking user-defined handlers for conflict resolution,
289
- * and tracking the current merge/rebase state.
287
+ * such as remote repositories or other users. It manages the rebase workflow, including resuming or aborting rebases,
288
+ * invoking a custom [[RebaseHandler]] for each rebased transaction, and tracking the current merge/rebase state.
290
289
  *
291
290
  * Key responsibilities:
292
291
  * - Orchestrates the rebase of local transactions after a pull/merge operation.
293
- * - Allows registration and removal of custom conflict handlers to resolve changeset conflicts during rebase.
294
292
  * - Provides methods to check the current merge/rebase state.
295
293
  * - Raises events before and after each transaction is rebased.
296
294
  * - Ensures changes are saved or aborted appropriately based on the outcome of the rebase process.
297
295
  *
298
- * @alpha
296
+ * Obtain the instance for a briefcase via [[TxnManager.rebaser]].
297
+ *
298
+ * @beta
299
299
  */
300
300
  export class RebaseManager {
301
301
  _iModel;
@@ -304,51 +304,51 @@ export class RebaseManager {
304
304
  _aborting = false;
305
305
  _disposed = false;
306
306
  /** Event raised before pull merge process begins.
307
- * @alpha
307
+ * @beta
308
308
  */
309
309
  onPullMergeBegin = new BeEvent();
310
310
  /** Event raised before a rebase operation begins.
311
- * @alpha
311
+ * @beta
312
312
  */
313
313
  onRebaseBegin = new BeEvent();
314
314
  /** Event raised before a transaction is rebased.
315
- * @alpha
315
+ * @beta
316
316
  */
317
317
  onRebaseTxnBegin = new BeEvent();
318
318
  /** Event raised after a transaction is rebased.
319
- * @alpha
319
+ * @beta
320
320
  */
321
321
  onRebaseTxnEnd = new BeEvent();
322
322
  /** Event raised after a rebase operation ends.
323
- * @alpha
323
+ * @beta
324
324
  */
325
325
  onRebaseEnd = new BeEvent();
326
326
  /** Event raised after pull merge process ends.
327
- * @alpha
327
+ * @beta
328
328
  */
329
329
  onPullMergeEnd = new BeEvent();
330
330
  /** Event raised before applying incoming changes.
331
- * @alpha
331
+ * @beta
332
332
  */
333
333
  onApplyIncomingChangesBegin = new BeEvent();
334
334
  /** Event raised after applying incoming changes.
335
- * @alpha
335
+ * @beta
336
336
  */
337
337
  onApplyIncomingChangesEnd = new BeEvent();
338
338
  /** Event raised before reversing local changes.
339
- * @alpha
339
+ * @beta
340
340
  */
341
341
  onReverseLocalChangesBegin = new BeEvent();
342
342
  /** Event raised after reversing local changes.
343
- * @alpha
343
+ * @beta
344
344
  */
345
345
  onReverseLocalChangesEnd = new BeEvent();
346
346
  /** Event raised before downloading changesets.
347
- * @alpha
347
+ * @beta
348
348
  */
349
349
  onDownloadChangesetsBegin = new BeEvent();
350
350
  /** Event raised after downloading changesets.
351
- * @alpha
351
+ * @beta
352
352
  */
353
353
  onDownloadChangesetsEnd = new BeEvent();
354
354
  /** @internal */
@@ -411,13 +411,14 @@ export class RebaseManager {
411
411
  this.onRebaseTxnEnd.raiseEvent(txnProps);
412
412
  IpcHost.notifyTxns(this._iModel, "notifyRebaseTxnEnd", txnProps);
413
413
  }
414
+ /** @alpha */
414
415
  constructor(_iModel) {
415
416
  this._iModel = _iModel;
416
417
  }
417
418
  /** Disposes of this RebaseManager, clearing all event listeners.
418
419
  * Also calls [[RebaseHandler.dispose]] on the registered custom handler, if any.
419
420
  * Subsequent calls are ignored.
420
- * @alpha
421
+ * @beta
421
422
  */
422
423
  dispose() {
423
424
  if (this._disposed)
@@ -442,19 +443,22 @@ export class RebaseManager {
442
443
  * on top of the latest pulled changes from the remote source.
443
444
  *
444
445
  * This method performs the following steps:
445
- * 1. Begins the rebase process using the native database.
446
- * 2. Iterates through each transaction that needs to be rebased:
447
- * - Retrieves transaction properties.
448
- * - Raises events before and after rebasing each transaction.
449
- * - Optionally reinstates local changes based on the rebase handler.
450
- * - Optionally recomputes transaction data using the rebase handler.
451
- * - Updates the transaction in the native database.
452
- * 3. Ends the rebase process and saves changes if the database is not read-only.
453
- * 4. Drops any restore point associated with the pull-merge operation.
446
+ * 1. Begins the rebase and raises [[RebaseManager.onRebaseBegin]].
447
+ * 2. For each local transaction that needs to be rebased:
448
+ * - Raises [[RebaseManager.onRebaseTxnBegin]].
449
+ * - Reinstates the transaction's local changes, unless the custom [[RebaseHandler]]'s `shouldReinstate` returns `false`.
450
+ * - Calls [[RebaseHandler.recompute]] if a custom handler was set via [[RebaseManager.setCustomHandler]].
451
+ * - Updates the transaction with the resulting changes and raises [[RebaseManager.onRebaseTxnEnd]].
452
+ * 3. Ends the rebase, raises [[RebaseManager.onRebaseEnd]], and saves changes if the iModel is not read-only.
453
+ * 4. Drops the pull/merge restore point, if any, and raises [[RebaseManager.onPullMergeEnd]].
454
454
  *
455
- * If an error occurs during the process, the rebase is aborted and the error is rethrown.
455
+ * If an error occurs, only the changes of the transaction currently being rebased are abandoned and the error is rethrown.
456
+ * The rebase remains in progress: call `resume` again to retry, or [[RebaseManager.abort]] to roll back the pull/merge.
457
+ * If the pull/merge used semantic rebase (see [[IModelHostOptions.useSemanticRebase]]), retrying with `resume` is not supported;
458
+ * use [[RebaseManager.abort]] if [[RebaseManager.canAbort]] returns `true`.
456
459
  *
457
- * @throws {Error} If a transaction cannot be found or if any step in the rebase process fails.
460
+ * @throws Error if a transaction cannot be found or if any step in the rebase process fails.
461
+ * @beta
458
462
  */
459
463
  async resume() {
460
464
  const nativeDb = this._iModel[_nativeDb];
@@ -516,6 +520,7 @@ export class RebaseManager {
516
520
  * If an error occurs during the process, the rebase is aborted and the error is rethrown.
517
521
  *
518
522
  * @throws {Error} If a transaction cannot be found or if any step in the rebase process fails.
523
+ * @internal
519
524
  */
520
525
  async resumeSemantic() {
521
526
  const nativeDb = this._iModel[_nativeDb];
@@ -565,7 +570,6 @@ export class RebaseManager {
565
570
  /**
566
571
  * Checks if the transaction is a schema change and if it was a noop change during rebase, purges the local folder for that txn
567
572
  * @param txnProps
568
- * @internal
569
573
  */
570
574
  purgeSchemaFolderForNoopSchemaChange(txnProps) {
571
575
  if (txnProps.type === "ECSchema" || txnProps.type === "Schema") {
@@ -579,7 +583,6 @@ export class RebaseManager {
579
583
  * Reinstantes the semantic changeset data for the given txnProps, both schema as well as data changesets
580
584
  * @param txnProps
581
585
  * @throws IModelError if local folder for transaction does not exist
582
- * @internal
583
586
  */
584
587
  async reinstateSemanticChangeSet(txnProps) {
585
588
  if (txnProps.type === "ECSchema" || txnProps.type === "Schema") {
@@ -619,7 +622,6 @@ export class RebaseManager {
619
622
  /**
620
623
  * Applies instance patch during rebase
621
624
  * @param instance
622
- * @internal
623
625
  */
624
626
  applyInstancePatch(instance) {
625
627
  const nativeDb = this._iModel[_nativeDb];
@@ -654,26 +656,27 @@ export class RebaseManager {
654
656
  }
655
657
  }
656
658
  /**
657
- * Determines whether the current transaction can be aborted.
659
+ * Determines whether the in-progress pull/merge can be rolled back via [[RebaseManager.abort]].
658
660
  *
659
- * This method checks if a transaction is currently in progress and if a specific restore point,
660
- * identified by `BriefcaseManager.PULL_MERGE_RESTORE_POINT_NAME`, exists in the briefcase manager.
661
+ * A pull/merge can be aborted only while it is in progress (see [[RebaseManager.inProgress]]) and a pull/merge restore point exists.
662
+ * The restore point is created at the start of a pull/merge only if the briefcase has pending local transactions, none of which
663
+ * contain schema changes, and [[IModelHostOptions.disableRestorePointOnPullMerge]] is not set.
661
664
  *
662
- * @returns {boolean} Returns `true` if a transaction is in progress and the required restore point exists; otherwise, returns `false`.
665
+ * @returns `true` if a pull/merge is in progress and its restore point exists; otherwise, `false`.
666
+ * @beta
663
667
  */
664
668
  canAbort() {
665
669
  return this.inProgress() && BriefcaseManager.containsRestorePoint(this._iModel, BriefcaseManager.PULL_MERGE_RESTORE_POINT_NAME);
666
670
  }
667
671
  /**
668
- * Aborts the current transaction by restoring the iModel to a predefined restore point. This method will
669
- * automatically discard any unsaved changes before performing the restore.
672
+ * Aborts the in-progress pull/merge, restoring the briefcase to the state it was in before the pull began,
673
+ * including its parent changeset and local transactions. Any unsaved changes are discarded first.
670
674
  *
671
- * If a restore point is available (as determined by `canAbort()`), this method restores the iModel
672
- * to the state saved at the restore point named by `BriefcaseManager.PULL_MERGE_RESTORE_POINT_NAME`.
673
- * If no restore point is available, an error is thrown.
675
+ * [[RebaseManager.isAborting]] is `true` while the restore is running.
674
676
  *
675
677
  * @returns A promise that resolves when the restore operation is complete.
676
- * @throws {Error} If there is no restore point to abort to.
678
+ * @throws Error if the pull/merge cannot be aborted (see [[RebaseManager.canAbort]]).
679
+ * @beta
677
680
  */
678
681
  async abort() {
679
682
  if (this.canAbort()) {
@@ -693,9 +696,13 @@ export class RebaseManager {
693
696
  }
694
697
  }
695
698
  /**
696
- * Sets the handler to be invoked for rebase operations.
699
+ * Sets the [[RebaseHandler]] invoked for each local transaction while it is rebased during a pull/merge.
697
700
  *
698
- * @param handler - The {@link RebaseHandler} to handle rebase events.
701
+ * Only one handler can be set. Setting a new handler replaces the previous one, logs a warning, and does not call
702
+ * [[RebaseHandler.dispose]] on the replaced handler.
703
+ *
704
+ * @param handler - The handler that decides whether to reinstate, and how to recompute, each rebased transaction.
705
+ * @beta
699
706
  */
700
707
  setCustomHandler(handler) {
701
708
  if (this._customHandler) {
@@ -704,47 +711,51 @@ export class RebaseManager {
704
711
  this._customHandler = handler;
705
712
  }
706
713
  /**
707
- * Determines whether rebasing or merging is currently in progress. Same as calling `this.isRebasing || this.isMerging`.
708
- * @returns {boolean} Returns `true` if this rebase manager is currently rebasing or merging changes; otherwise, `false`.
714
+ * Determines whether a pull/merge is currently in progress. Same as `this.isRebasing || this.isMerging`.
715
+ * @returns `true` if the briefcase is currently merging or rebasing changes; otherwise, `false`.
716
+ * @beta
709
717
  */
710
718
  inProgress() {
711
719
  return this._iModel[_nativeDb].pullMergeGetStage() !== "None";
712
720
  }
713
721
  /**
714
- * Indicates whether the current transaction manager is in the process of aborting a transaction.
722
+ * Indicates whether [[RebaseManager.abort]] is currently rolling back a pull/merge.
715
723
  *
716
- * @returns `true` if the transaction manager is currently aborting; otherwise, `false`.
724
+ * @returns `true` while an abort is in progress; otherwise, `false`.
725
+ * @beta
717
726
  */
718
727
  get isAborting() {
719
728
  return this._aborting;
720
729
  }
721
730
  /**
722
- * Indicates whether the current transaction manager is in the "Rebasing" stage.
723
- *
724
- * This property checks the internal native database's merge stage to determine if a rebase operation is in progress.
731
+ * Indicates whether the pull/merge is in the rebasing stage, in which local transactions are being reinstated
732
+ * on top of the incoming changesets.
725
733
  *
726
- * @returns `true` if the transaction manager is currently rebasing; otherwise, `false`.
734
+ * @returns `true` if the briefcase is currently rebasing local changes; otherwise, `false`.
735
+ * @beta
727
736
  */
728
737
  get isRebasing() {
729
738
  return this._iModel[_nativeDb].pullMergeGetStage() === "Rebasing";
730
739
  }
731
740
  /**
732
- * Indicates whether the current iModel is in the process of merging changes from a pull operation.
741
+ * Indicates whether the pull/merge is in the merging stage, in which incoming changesets are being applied.
733
742
  *
734
- * @returns `true` if the iModel is currently merging changes; otherwise, `false`.
743
+ * @returns `true` if the briefcase is currently merging incoming changes; otherwise, `false`.
744
+ * @beta
735
745
  */
736
746
  get isMerging() {
737
747
  return this._iModel[_nativeDb].pullMergeGetStage() === "Merging";
738
748
  }
739
749
  /**
740
- * Attempts to resolve a changeset conflict by invoking registered conflict handlers in sequence.
750
+ * Attempts to resolve a changeset conflict by invoking the handlers registered via [[RebaseManager.addConflictHandler]].
741
751
  *
742
- * Iterates through the linked list of conflict handlers, passing the provided conflict arguments to each handler.
743
- * If a handler returns a defined resolution, logs the resolution and returns it immediately.
744
- * If no handler resolves the conflict, returns `undefined`.
752
+ * Called during rebase for conflicts not already resolved by the built-in rules. Handlers are invoked from most recently
753
+ * to least recently added; the first handler that returns a resolution wins. If no handler resolves the conflict,
754
+ * returns `undefined` and the default resolution is applied.
745
755
  *
746
756
  * @param args - The arguments describing the changeset conflict to resolve.
747
757
  * @returns The conflict resolution provided by a handler, or `undefined` if no handler resolves the conflict.
758
+ * @internal
748
759
  */
749
760
  onConflict(args) {
750
761
  let curr = this._conflictHandlers;
@@ -769,6 +780,9 @@ export class RebaseManager {
769
780
  * @remarks
770
781
  * Conflict handlers are used during changeset rebase operations to resolve conflicts.
771
782
  * Each handler must have a unique `id`. Attempting to register a handler with a duplicate `id` will result in an error.
783
+ * The most recently added handler is invoked first. A handler should return `undefined` to defer to the next handler.
784
+ * A handler must not throw; if it does, the transaction being rebased is aborted.
785
+ * @internal
772
786
  */
773
787
  addConflictHandler(args) {
774
788
  const idExists = (id) => {
@@ -785,12 +799,11 @@ export class RebaseManager {
785
799
  this._conflictHandlers = { ...args, next: this._conflictHandlers };
786
800
  }
787
801
  /**
788
- * Removes a conflict handler from the internal linked list by its identifier.
802
+ * Removes a conflict handler previously registered via [[RebaseManager.addConflictHandler]].
803
+ * If no handler with the given `id` is registered, the method does nothing.
789
804
  *
790
805
  * @param id - The unique identifier of the conflict handler to remove.
791
- *
792
- * If the handler with the specified `id` exists in the list, it will be removed.
793
- * If no handler with the given `id` is found, the method does nothing.
806
+ * @internal
794
807
  */
795
808
  removeConflictHandler(id) {
796
809
  if (!this._conflictHandlers)
@@ -824,7 +837,9 @@ export class TxnManager {
824
837
  get isDisposed() {
825
838
  return this._isDisposed;
826
839
  }
827
- /** @internal */
840
+ /** Manages rebasing local changes onto incoming changesets during pull/merge.
841
+ * @beta
842
+ */
828
843
  rebaser;
829
844
  /** @internal */
830
845
  constructor(_iModel) {
@@ -1070,20 +1085,20 @@ export class TxnManager {
1070
1085
  return DbConflictResolution.Replace;
1071
1086
  }
1072
1087
  /**
1073
- * @alpha
1074
1088
  * Retrieves the txn properties for a given txn ID.
1075
1089
  *
1076
1090
  * @param id - The unique identifier of the transaction.
1077
1091
  * @returns The properties of the transaction if found; otherwise, `undefined`.
1092
+ * @beta
1078
1093
  */
1079
1094
  getTxnProps(id) {
1080
1095
  return this._iModel[_nativeDb].getTxnProps(id);
1081
1096
  }
1082
1097
  /**
1083
- * @alpha
1084
- * Iterates over all transactions in the sequence, yielding each transaction's properties.
1098
+ * Iterates over all transactions, from first to last, yielding each transaction's properties.
1085
1099
  *
1086
- * @yields {TxnProps} The properties of each transaction in the sequence.
1100
+ * @returns A generator yielding the [[TxnProps]] of each transaction.
1101
+ * @beta
1087
1102
  */
1088
1103
  *queryTxns() {
1089
1104
  let txn = this.getTxnProps(this.queryFirstTxnId());
@@ -1093,10 +1108,10 @@ export class TxnManager {
1093
1108
  }
1094
1109
  }
1095
1110
  /**
1096
- * @alpha
1097
- * Retrieves the properties of the last saved txn via `IModelDb.saveChanges()`, if available.
1111
+ * Retrieves the properties of the most recently saved txn (for example via [[EditTxn.saveChanges]]), if any.
1098
1112
  *
1099
1113
  * @returns The properties of the last saved txn, or `undefined` if none exist.
1114
+ * @beta
1100
1115
  */
1101
1116
  getLastSavedTxnProps() {
1102
1117
  return this.getTxnProps(this.queryPreviousTxnId(this.getCurrentTxnId()));
@@ -1487,17 +1502,19 @@ export class TxnManager {
1487
1502
  return this._iModel[_nativeDb].getChangeTrackingMemoryUsed();
1488
1503
  }
1489
1504
  /**
1490
- * @alpha
1491
1505
  * Get the current transaction mode.
1492
- * @returns The current transaction mode, either "direct" or "indirect".
1506
+ * @returns The current [[TxnMode]], either `"direct"` or `"indirect"`.
1507
+ * @beta
1493
1508
  */
1494
1509
  getMode() {
1495
1510
  return this._nativeDb.getTxnMode();
1496
1511
  }
1497
1512
  /**
1498
- * @alpha
1499
- * Execute a series of changes in an indirect transaction.
1513
+ * Synchronously execute a series of changes with the [[TxnMode]] set to `"indirect"`, so they are recorded as indirect changes.
1514
+ * Calls may be nested; the mode reverts to `"direct"` when the outermost call returns or throws.
1515
+ * This method does not save changes.
1500
1516
  * @param callback The function containing the changes to make.
1517
+ * @beta
1501
1518
  */
1502
1519
  withIndirectTxnMode(callback) {
1503
1520
  if (this._withIndirectChangeRefCounter === 0) {
@@ -1515,9 +1532,12 @@ export class TxnManager {
1515
1532
  }
1516
1533
  }
1517
1534
  /**
1518
- * @alpha
1519
- * Execute a series of changes in an indirect transaction.
1535
+ * Asynchronously execute a series of changes with the [[TxnMode]] set to `"indirect"`, so they are recorded as indirect changes.
1536
+ * Calls may be nested with each other and with [[TxnManager.withIndirectTxnMode]]; the mode reverts to `"direct"` when the
1537
+ * outermost call completes or rejects. While the returned promise is pending, all changes to this iModel, including those made by
1538
+ * other concurrent code, are recorded as indirect. This method does not save changes.
1520
1539
  * @param callback The function containing the changes to make.
1540
+ * @beta
1521
1541
  */
1522
1542
  async withIndirectTxnModeAsync(callback) {
1523
1543
  if (this._withIndirectChangeRefCounter === 0) {