@itwin/core-backend 5.9.0 → 5.9.2

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 (36) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/lib/cjs/BriefcaseManager.d.ts +17 -59
  3. package/lib/cjs/BriefcaseManager.d.ts.map +1 -1
  4. package/lib/cjs/BriefcaseManager.js +45 -162
  5. package/lib/cjs/BriefcaseManager.js.map +1 -1
  6. package/lib/cjs/IModelJsFs.d.ts +2 -0
  7. package/lib/cjs/IModelJsFs.d.ts.map +1 -1
  8. package/lib/cjs/IModelJsFs.js +14 -0
  9. package/lib/cjs/IModelJsFs.js.map +1 -1
  10. package/lib/cjs/TxnManager.d.ts +3 -0
  11. package/lib/cjs/TxnManager.d.ts.map +1 -1
  12. package/lib/cjs/TxnManager.js +95 -13
  13. package/lib/cjs/TxnManager.js.map +1 -1
  14. package/lib/cjs/internal/cross-package.d.ts +1 -1
  15. package/lib/cjs/internal/cross-package.d.ts.map +1 -1
  16. package/lib/cjs/internal/cross-package.js +2 -1
  17. package/lib/cjs/internal/cross-package.js.map +1 -1
  18. package/lib/esm/BriefcaseManager.d.ts +17 -59
  19. package/lib/esm/BriefcaseManager.d.ts.map +1 -1
  20. package/lib/esm/BriefcaseManager.js +46 -163
  21. package/lib/esm/BriefcaseManager.js.map +1 -1
  22. package/lib/esm/IModelJsFs.d.ts +2 -0
  23. package/lib/esm/IModelJsFs.d.ts.map +1 -1
  24. package/lib/esm/IModelJsFs.js +14 -0
  25. package/lib/esm/IModelJsFs.js.map +1 -1
  26. package/lib/esm/TxnManager.d.ts +3 -0
  27. package/lib/esm/TxnManager.d.ts.map +1 -1
  28. package/lib/esm/TxnManager.js +96 -14
  29. package/lib/esm/TxnManager.js.map +1 -1
  30. package/lib/esm/internal/cross-package.d.ts +1 -1
  31. package/lib/esm/internal/cross-package.d.ts.map +1 -1
  32. package/lib/esm/internal/cross-package.js +1 -1
  33. package/lib/esm/internal/cross-package.js.map +1 -1
  34. package/lib/esm/test/hubaccess/SemanticRebase.test.js +2276 -70
  35. package/lib/esm/test/hubaccess/SemanticRebase.test.js.map +1 -1
  36. package/package.json +14 -14
@@ -5,14 +5,68 @@
5
5
  /** @packageDocumentation
6
6
  * @module iModels
7
7
  */
8
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
9
+ if (value !== null && value !== void 0) {
10
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
11
+ var dispose, inner;
12
+ if (async) {
13
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
14
+ dispose = value[Symbol.asyncDispose];
15
+ }
16
+ if (dispose === void 0) {
17
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
18
+ dispose = value[Symbol.dispose];
19
+ if (async) inner = dispose;
20
+ }
21
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
22
+ if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
23
+ env.stack.push({ value: value, dispose: dispose, async: async });
24
+ }
25
+ else if (async) {
26
+ env.stack.push({ async: true });
27
+ }
28
+ return value;
29
+ };
30
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
31
+ return function (env) {
32
+ function fail(e) {
33
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
34
+ env.hasError = true;
35
+ }
36
+ var r, s = 0;
37
+ function next() {
38
+ while (r = env.stack.pop()) {
39
+ try {
40
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
41
+ if (r.dispose) {
42
+ var result = r.dispose.call(r.value);
43
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
44
+ }
45
+ else s |= 1;
46
+ }
47
+ catch (e) {
48
+ fail(e);
49
+ }
50
+ }
51
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
52
+ if (env.hasError) throw env.error;
53
+ }
54
+ return next();
55
+ };
56
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
57
+ var e = new Error(message);
58
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
59
+ });
8
60
  import * as touch from "touch";
9
- import { assert, BeEvent, BentleyError, compareStrings, CompressedId64Set, DbConflictResolution, DbResult, IModelStatus, IndexMap, Logger, OrderedId64Array } from "@itwin/core-bentley";
61
+ import { assert, BeEvent, BentleyError, compareStrings, CompressedId64Set, DbConflictResolution, DbResult, Id64, IModelStatus, IndexMap, Logger, OrderedId64Array } from "@itwin/core-bentley";
10
62
  import { IModelError } from "@itwin/core-common";
11
63
  import { BackendLoggerCategory } from "./BackendLoggerCategory";
12
64
  import { IpcHost } from "./IpcHost";
13
65
  import { _nativeDb } from "./internal/Symbols";
14
66
  import { RebaseChangesetConflictArgs } from "./internal/ChangesetConflictArgs";
15
67
  import { BriefcaseManager } from "./BriefcaseManager";
68
+ import { ChangesetReader } from "./ChangesetReader";
69
+ import { ChangeUnifierCache, PartialChangeUnifier } from "./PartialChangeUnifier";
16
70
  /** Strictly for tests. @internal */
17
71
  export function setMaxEntitiesPerEvent(max) {
18
72
  const prevMax = ChangedEntitiesProc.maxPerEvent;
@@ -514,16 +568,15 @@ export class RebaseManager {
514
568
  if (!BriefcaseManager.semanticRebaseDataFolderExists(this._iModel, txnProps.id)) {
515
569
  throw new IModelError(IModelStatus.BadRequest, `Local folder does not exist for transaction ${txnProps.id}`);
516
570
  }
517
- const changedInstances = BriefcaseManager.getChangedInstancesDataForTxn(this._iModel, txnProps.id);
518
- changedInstances.forEach((instance) => {
519
- if (instance.isIndirect) {
571
+ for await (const instance of BriefcaseManager.getChangedInstancesDataForTxn(this._iModel, txnProps.id)) {
572
+ if (instance.$meta.isIndirectChange) {
520
573
  this._iModel.txns.withIndirectTxnMode(() => {
521
574
  this.applyInstancePatch(instance);
522
575
  });
523
- return;
576
+ continue;
524
577
  }
525
578
  this.applyInstancePatch(instance);
526
- });
579
+ }
527
580
  BriefcaseManager.deleteTxnDataFolder(this._iModel, txnProps.id); // delete the folder after importing
528
581
  }
529
582
  else {
@@ -537,27 +590,34 @@ export class RebaseManager {
537
590
  */
538
591
  applyInstancePatch(instance) {
539
592
  const nativeDb = this._iModel[_nativeDb];
540
- switch (instance.op) {
593
+ const { $meta, ...props } = instance;
594
+ switch ($meta.op) {
541
595
  case "Inserted": {
542
- if (!instance.props)
596
+ if (!props)
543
597
  throw new IModelError(IModelStatus.BadRequest, "InstancePatch with op 'Inserted' must have props");
544
598
  const options = { forceUseId: true, useJsNames: true };
545
- nativeDb.insertInstance(instance.props, options);
599
+ const id = nativeDb.insertInstance(props, options);
600
+ if (!Id64.isValidId64(id))
601
+ throw new IModelError(IModelStatus.BadRequest, `Failed to insert instance with id ${props.id}`);
546
602
  break;
547
603
  }
548
604
  case "Updated": {
549
- if (!instance.props)
605
+ if (!props)
550
606
  throw new IModelError(IModelStatus.BadRequest, "InstancePatch with op 'Updated' must have props");
551
- nativeDb.updateInstance(instance.props, { useJsNames: true });
607
+ const isSuccess = nativeDb.updateInstance(props, { useJsNames: true });
608
+ if (!isSuccess)
609
+ throw new IModelError(IModelStatus.BadRequest, `Failed to update instance with id ${props.id}`);
552
610
  break;
553
611
  }
554
612
  case "Deleted": {
555
- const key = { id: instance.key.id, classFullName: instance.key.classFullName };
556
- nativeDb.deleteInstance(key, { useJsNames: true });
613
+ const key = { id: props.id, classFullName: props.className };
614
+ const isSuccess = nativeDb.deleteInstance(key, { useJsNames: true });
615
+ if (!isSuccess)
616
+ throw new IModelError(IModelStatus.BadRequest, `Failed to delete instance with id ${props.id}`);
557
617
  break;
558
618
  }
559
619
  default:
560
- throw new IModelError(IModelStatus.BadRequest, `Unknown InstancePatch op '${instance.op}'`);
620
+ throw new IModelError(IModelStatus.BadRequest, `Unknown InstancePatch op '${$meta.op}'`);
561
621
  }
562
622
  }
563
623
  /**
@@ -800,6 +860,28 @@ export class TxnManager {
800
860
  this.onEndValidation.raiseEvent();
801
861
  // TODO: if (this.validationErrors.length !== 0) throw new IModelError(validation ...)
802
862
  }
863
+ /** Called by native code during semantic rebase while reversing local changes to create instance patches to be used for reinstating changes.
864
+ * @internal */
865
+ _captureInstanceChanges(id) {
866
+ const env_1 = { stack: [], error: void 0, hasError: false };
867
+ try {
868
+ if (BriefcaseManager.semanticRebaseDataFolderExists(this._iModel, id))
869
+ return; // if folder already exists that means we have already captured the changes for this txn during this rebase so we can skip capturing again
870
+ const reader = __addDisposableResource(env_1, ChangesetReader.openTxn({ db: this._iModel, txnId: id, rowOptions: { useJsName: true, abbreviateBlobs: false } }), false);
871
+ const pcu = __addDisposableResource(env_1, new PartialChangeUnifier(ChangeUnifierCache.createSqliteBackedCache()), false);
872
+ while (reader.step()) {
873
+ pcu.appendFrom(reader);
874
+ }
875
+ BriefcaseManager.storeChangedInstancesForSemanticRebase(this._iModel, id, pcu.instances);
876
+ }
877
+ catch (e_1) {
878
+ env_1.error = e_1;
879
+ env_1.hasError = true;
880
+ }
881
+ finally {
882
+ __disposeResources(env_1);
883
+ }
884
+ }
803
885
  /** @internal */
804
886
  _onGeometryChanged(modelProps) {
805
887
  this.onGeometryChanged.raiseEvent(modelProps);