@itwin/core-backend 5.10.0-dev.10 → 5.10.0-dev.11

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.
@@ -1 +1 @@
1
- {"version":3,"file":"HubMock.js","sourceRoot":"","sources":["../../../src/internal/HubMock.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;AAE/F,+BAA4B;AAC5B,sDAAuD;AASvD,4DAA+I;AAC/I,8CAA2C;AAC3C,8CAA2C;AAC3C,0CAAuC;AAEvC,uCAA0E;AAC1E,0DAAuD;AACvD,6BAA6B;AAE7B,SAAS,UAAU,CAAC,GAAuB;IACzC,IAAI,SAAS,KAAK,GAAG;QACnB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,UAAU,CAAC,IAA6E;IAC/F,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;AAC/D,CAAC;AACD,MAAM,cAAc,GAAmB;IACrC,UAAU,EAAE,CAAC,UAA2B,EAAE,EAAE;QAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,mCAAgB,CAAC,oBAAoB,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,GAAG,UAAU,CAAC,SAAS,CAAC,KAAK,MAAM,CAAC,CAAC;QAC9H,UAAU,CAAC,EAAE,GAAG,UAAU,EAAE,UAAU,EAAE,CAAC,CAAA;QACzC,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,YAAY,EAAE,CAAC,OAAwB,EAAE,EAAE;QACzC,UAAU,CAAC,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACvE,CAAC;CACF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAa,OAAO;IACV,MAAM,CAAC,QAAQ,CAA2B;IAC1C,MAAM,CAAC,IAAI,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC1C,MAAM,CAAC,cAAc,CAA+B;IACpD,MAAM,CAAC,QAAQ,CAAyB;IAEhD,oEAAoE;IAC7D,MAAM,KAAK,OAAO,KAAK,OAAO,SAAS,KAAK,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC5D,MAAM,KAAK,OAAO;QACvB,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,OAAO,CAAC,QAAsB,EAAE,SAAiB;QAC7D,IAAI,IAAI,CAAC,OAAO;YACd,MAAM,IAAI,KAAK,CAAC,0JAA0J,CAAC,CAAC;QAE9K,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC,QAAQ,GAAG,IAAA,WAAI,EAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QACrD,uBAAU,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7C,uBAAU,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAI,CAAC,cAAc,GAAG,uBAAU,CAAC,uBAAa,CAAC,EAAE,CAAC;QAElD,uBAAU,CAAC,uBAAa,CAAC,CAAC,IAAI,CAAC,CAAC;QAChC,OAAO,CAAC,QAAQ,GAAG,mBAAI,CAAC,WAAW,EAAE,CAAC,CAAC,mDAAmD;QAE1F,uCAAmB,CAAC,yBAAe,CAAC,GAAG,cAAc,CAAC;IACxD,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,QAAQ;QACpB,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;YAC7B,OAAO;QAET,uCAAmB,CAAC,yBAAe,CAAC,GAAG,SAAS,CAAC;QAEjD,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;QAC7B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI;YACzB,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QAEnB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAClB,uBAAU,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvC,uBAAU,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrC,uBAAU,CAAC,uBAAa,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/C,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;IAC5B,CAAC;IAEM,MAAM,CAAC,YAAY,CAAC,QAAoB;QAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG;YACN,MAAM,IAAI,KAAK,CAAC,wBAAwB,QAAQ,cAAc,CAAC,CAAC;QAClE,OAAO,GAAG,CAAC;IACb,CAAC;IAED,4CAA4C;IACrC,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,GAAyB;QAC3D,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1B,MAAM,KAAK,GAAG,EAAE,GAAG,GAAG,EAAE,QAAQ,EAAE,mBAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACvD,MAAM,IAAI,GAAG,IAAI,mBAAQ,CAAC,IAAA,WAAI,EAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC;QACtE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACpC,OAAO,KAAK,CAAC,QAAQ,CAAC;IACxB,CAAC;IAED,4CAA4C;IACrC,MAAM,CAAC,OAAO,CAAC,QAAoB;QACxC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC;QACtC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAED,wEAAwE;IAEjE,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,GAA0C;QACzF,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC3E,CAAC;IAEO,MAAM,CAAC,qBAAqB,CAAC,GAAiB;QACpD,OAAO,CAAC,SAAS,KAAK,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACzI,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,GAA6C;QACvF,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAC5B,IAAI,OAAO,CAAC,OAAO;YACjB,OAAO,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;QAEpC,MAAM,IAAI,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;QACxC,IAAI,IAAI;YACN,OAAO,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAEpC,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;QACtC,IAAI,WAAW;YACb,OAAO,GAAG,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAE3C,OAAO,GAAG,CAAC,kBAAkB,EAAE,CAAC;IAClC,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,GAAgB;QACrD,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,kBAAkB,EAAE,CAAC;IAC9D,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,GAAa;QAC/C,OAAO,GAAG,CAAC,WAAW,IAAI,MAAM,uBAAU,CAAC,cAAc,EAAE,CAAC;IAC9D,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAgB;QACpD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;IACtE,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,GAA6B;QACrE,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,WAAW,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IAChG,CAAC;IAED,gHAAgH;IACzG,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAmB;QACtD,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7E,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAyB;QAC7D,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;QAE/I,IAAI,GAAG,CAAC,gBAAgB,EAAE,CAAC;YACzB,MAAM,SAAS,GAAG,uBAAU,CAAC,SAAS,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC;YACtE,IAAI,SAAS;gBACX,MAAM,OAAO,CAAC,qBAAqB,CAAC,GAAG,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;QACzE,CAAC;QAED,OAAO,cAAc,CAAC;IACxB,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,GAA8B;QACnE,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;QAE1H,IAAI,GAAG,CAAC,gBAAgB,EAAE,CAAC;YACzB,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,uBAAU,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACpH,MAAM,OAAO,CAAC,qBAAqB,CAAC,GAAG,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;QACvE,CAAC;QAED,OAAO,cAAc,CAAC;IACxB,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,GAAiB;QAClD,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9F,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,GAA6C;QAC/E,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpE,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,GAAyD;QACzF,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC1E,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAoB;QACxD,OAAO;YACL,WAAW,EAAE,MAAM;YACnB,QAAQ,EAAE,MAAM;YAChB,WAAW,EAAE,mBAAI,CAAC,WAAW,EAAE;YAC/B,MAAM,EAAE,GAAG,GAAG,CAAC,SAAS,CAAC,KAAK,IAAI,CAAC,MAAM;YACzC,WAAW,EAAE,MAAM;YACnB,MAAM,EAAE,IAAI;YACZ,UAAU,EAAE,GAAG;SACW,CAAC;IAC/B,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,GAAmB;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5C,GAAG,CAAC,eAAe,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,cAAc,EAAE,GAAG,CAAC,qBAAqB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAClH,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,GAAmB;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5C,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,IAAoB;QACpD,OAAO,EAAE,CAAC;IACZ,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,GAAmB,EAAE,KAAc;QAClE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC3D,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,GAAmB,EAAE,KAAc;QAClE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC3D,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAkB;QACtD,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;YACxB,IAAI,QAAQ,CAAC,OAAO,KAAK,GAAG,CAAC,OAAO,IAAI,QAAQ,CAAC,UAAU,KAAK,GAAG,CAAC,UAAU;gBAC5E,OAAO,QAAQ,CAAC,QAAQ,CAAC;QAC7B,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,GAA0C;QACzE,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,gBAAkC,EAAE,SAAiB;QAC9F,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACpC,IAAI,QAAQ,GAAG,KAAK,CAAC;YAErB,MAAM,YAAY,GAAG,CAAC,KAAa,EAAE,EAAE;gBACrC,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC5D,IAAI,CAAC,QAAQ,IAAI,gBAAgB,CAAC,eAAe,EAAE,SAAS,CAAC,KAAK,kCAAc,CAAC,KAAK,EAAE,CAAC;oBACvF,QAAQ,GAAG,IAAI,CAAC;oBAChB,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;gBAClC,CAAC;YACH,CAAC,CAAC;YAEF,YAAY,CAAC,CAAC,CAAC,CAAC;YAChB,UAAU,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACtC,UAAU,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YACvC,UAAU,CAAC,GAAG,EAAE;gBACd,YAAY,CAAC,CAAC,CAAC,CAAC;gBAChB,OAAO,CAAC,SAAS,CAAC,CAAC;YACrB,CAAC,EAAE,GAAG,CAAC,CAAC;QACV,CAAC,CAAC,CAAC;IACL,CAAC;;AApOH,0BAqOC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { join } from \"path\";\r\nimport { Guid, GuidString } from \"@itwin/core-bentley\";\r\nimport {\r\n ChangesetFileProps, ChangesetIndex, ChangesetIndexOrId, ChangesetProps, ChangesetRange, IModelVersion, LocalDirName,\r\n} from \"@itwin/core-common\";\r\nimport {\r\n AcquireNewBriefcaseIdArg,\r\n BackendHubAccess, BriefcaseDbArg, BriefcaseIdArg, ChangesetArg, CreateNewIModelProps, DownloadChangesetArg, DownloadChangesetRangeArg, IModelIdArg, IModelNameArg,\r\n LockMap, LockProps, V2CheckpointAccessProps,\r\n} from \"../BackendHubAccess\";\r\nimport { CheckpointProps, DownloadRequest, MockCheckpoint, ProgressFunction, ProgressStatus, V2CheckpointManager } from \"../CheckpointManager\";\r\nimport { IModelHost } from \"../IModelHost\";\r\nimport { IModelJsFs } from \"../IModelJsFs\";\r\nimport { LocalHub } from \"../LocalHub\";\r\nimport { TokenArg } from \"../IModelDb\";\r\nimport { _getHubAccess, _mockCheckpoint, _setHubAccess } from \"./Symbols\";\r\nimport { BriefcaseManager } from \"../BriefcaseManager\";\r\nimport * as path from \"path\";\r\n\r\nfunction wasStarted(val: string | undefined): asserts val is string {\r\n if (undefined === val)\r\n throw new Error(\"Call HubMock.startup first\");\r\n}\r\n\r\nfunction doDownload(args: { iModelId: string, changeset: ChangesetIndexOrId, targetFile: string }) {\r\n HubMock.findLocalHub(args.iModelId).downloadCheckpoint(args);\r\n}\r\nconst mockCheckpoint: MockCheckpoint = {\r\n mockAttach: (checkpoint: CheckpointProps) => {\r\n const targetFile = path.join(BriefcaseManager.getBriefcaseBasePath(checkpoint.iModelId), `${checkpoint.changeset.index}.bim`);\r\n doDownload({ ...checkpoint, targetFile })\r\n return targetFile;\r\n },\r\n\r\n mockDownload: (request: DownloadRequest) => {\r\n doDownload({ ...request.checkpoint, targetFile: request.localFile });\r\n }\r\n};\r\n\r\n/**\r\n * Mocks iModelHub for testing creating Briefcases, downloading checkpoints, and simulating multiple users pushing and pulling changesets, etc.\r\n *\r\n * Generally, tests for apis that *create or modify* iModels can and should be mocked. Otherwise they:\r\n * - create tremendous load on the test servers when they run on programmer's desktops and in CI jobs\r\n * - waste network and data center resources (i.e. $$$s),\r\n * - interfere with other tests running on the same or other systems, and\r\n * - (far worse) are the source of test flakiness outside of the api being tested.\r\n *\r\n * This class can be used to create tests that do not require authentication, are synchronous,\r\n * are guaranteed to be self-contained (i.e. do not interfere with other tests running at the same time or later), and do not fail for reasons outside\r\n * of the control of the test itself. As a bonus, in addition to making tests more reliable, mocking IModelHub generally makes tests run *much* faster.\r\n *\r\n * On the other hand, tests that expect to find an existing iModels, checkpoints, changesets, etc. in IModelHub cannot be mocked. In that case, those tests\r\n * should be careful to NOT modify the data, since doing so causes interference with other tests running simultaneously. These tests should be limited to\r\n * low level testing of the core apis only.\r\n *\r\n * To initialize HubMock, call [[startup]] at the beginning of your test, usually in `describe.before`. Thereafter, all access to iModelHub for an iModel will be\r\n * directed to a [[LocalHub]] - your test code does not change. After the test(s) complete, call [[shutdown]] (usually in `describe.after`) to stop mocking IModelHub and clean\r\n * up any resources used by the test(s). If you want to mock a single test, call [[startup]] as the first line and [[shutdown]] as the last. If you wish to run the\r\n * test against a \"real\" IModelHub, you can simply comment off the call [[startup]], though in that case you should make sure the name of your\r\n * iModel is unique so your test won't collide with other tests (iModel name uniqueness is not necessary for mocked tests.)\r\n *\r\n * Mocked tests must always start by creating a new iModel via [[IModelHost[_hubAccess].createNewIModel]] with a `version0` iModel.\r\n * They use mock (aka \"bogus\") credentials for `AccessTokens`, which is fine since [[HubMock]] never accesses resources outside the current\r\n * computer.\r\n *\r\n * @note Only one HubMock at a time, *running in a single process*, may be active. The comments above about multiple simultaneous tests refer to tests\r\n * running on different computers, or on a single computer in multiple processes. All of those scenarios are problematic without mocking.\r\n *\r\n * @internal\r\n */\r\nexport class HubMock {\r\n private static mockRoot: LocalDirName | undefined;\r\n private static hubs = new Map<string, LocalHub>();\r\n private static _saveHubAccess: BackendHubAccess | undefined;\r\n private static _iTwinId: GuidString | undefined;\r\n\r\n /** Determine whether a test us currently being run under HubMock */\r\n public static get isValid() { return undefined !== this.mockRoot; }\r\n public static get iTwinId() {\r\n wasStarted(this._iTwinId);\r\n return this._iTwinId;\r\n }\r\n\r\n /**\r\n * Begin mocking IModelHub access. After this call, all access to IModelHub will be directed to a [[LocalHub]].\r\n * @param mockName a unique name (e.g. \"MyTest\") for this HubMock to disambiguate tests when more than one is simultaneously active.\r\n * It is used to create a private directory used by the HubMock for a test. That directory is removed when [[shutdown]] is called.\r\n */\r\n public static startup(mockName: LocalDirName, outputDir: string) {\r\n if (this.isValid)\r\n throw new Error(\"Either a previous test did not call HubMock.shutdown() properly, or more than one test is simultaneously attempting to use HubMock, which is not allowed\");\r\n\r\n this.hubs.clear();\r\n this.mockRoot = join(outputDir, \"HubMock\", mockName);\r\n IModelJsFs.recursiveMkDirSync(this.mockRoot);\r\n IModelJsFs.purgeDirSync(this.mockRoot);\r\n this._saveHubAccess = IModelHost[_getHubAccess]();\r\n\r\n IModelHost[_setHubAccess](this);\r\n HubMock._iTwinId = Guid.createValue(); // all iModels for this test get the same \"iTwinId\"\r\n\r\n V2CheckpointManager[_mockCheckpoint] = mockCheckpoint;\r\n }\r\n\r\n /** Stop a HubMock that was previously started with [[startup]]\r\n * @note this function throws an exception if any of the iModels used during the tests are left open.\r\n */\r\n public static shutdown() {\r\n if (this.mockRoot === undefined)\r\n return;\r\n\r\n V2CheckpointManager[_mockCheckpoint] = undefined;\r\n\r\n HubMock._iTwinId = undefined;\r\n for (const hub of this.hubs)\r\n hub[1].cleanup();\r\n\r\n this.hubs.clear();\r\n IModelJsFs.purgeDirSync(this.mockRoot);\r\n IModelJsFs.removeSync(this.mockRoot);\r\n IModelHost[_setHubAccess](this._saveHubAccess);\r\n this.mockRoot = undefined;\r\n }\r\n\r\n public static findLocalHub(iModelId: GuidString): LocalHub {\r\n const hub = this.hubs.get(iModelId);\r\n if (!hub)\r\n throw new Error(`local hub for iModel ${iModelId} not created`);\r\n return hub;\r\n }\r\n\r\n /** create a [[LocalHub]] for an iModel. */\r\n public static async createNewIModel(arg: CreateNewIModelProps): Promise<GuidString> {\r\n wasStarted(this.mockRoot);\r\n const props = { ...arg, iModelId: Guid.createValue() };\r\n const mock = new LocalHub(join(this.mockRoot, props.iModelId), props);\r\n this.hubs.set(props.iModelId, mock);\r\n return props.iModelId;\r\n }\r\n\r\n /** remove the [[LocalHub]] for an iModel */\r\n public static destroy(iModelId: GuidString) {\r\n this.findLocalHub(iModelId).cleanup();\r\n this.hubs.delete(iModelId);\r\n }\r\n\r\n /** All methods below are mocks of the [[BackendHubAccess]] interface */\r\n\r\n public static async getChangesetFromNamedVersion(arg: IModelIdArg & { versionName: string }): Promise<ChangesetProps> {\r\n return this.findLocalHub(arg.iModelId).findNamedVersion(arg.versionName);\r\n }\r\n\r\n private static changesetIndexFromArg(arg: ChangesetArg) {\r\n return (undefined !== arg.changeset.index) ? arg.changeset.index : this.findLocalHub(arg.iModelId).getChangesetIndex(arg.changeset.id);\r\n }\r\n\r\n public static async getChangesetFromVersion(arg: IModelIdArg & { version: IModelVersion }): Promise<ChangesetProps> {\r\n const hub = this.findLocalHub(arg.iModelId);\r\n const version = arg.version;\r\n if (version.isFirst)\r\n return hub.getChangesetByIndex(0);\r\n\r\n const asOf = version.getAsOfChangeSet();\r\n if (asOf)\r\n return hub.getChangesetById(asOf);\r\n\r\n const versionName = version.getName();\r\n if (versionName)\r\n return hub.findNamedVersion(versionName);\r\n\r\n return hub.getLatestChangeset();\r\n }\r\n\r\n public static async getLatestChangeset(arg: IModelIdArg): Promise<ChangesetProps> {\r\n return this.findLocalHub(arg.iModelId).getLatestChangeset();\r\n }\r\n\r\n private static async getAccessToken(arg: TokenArg) {\r\n return arg.accessToken ?? await IModelHost.getAccessToken();\r\n }\r\n\r\n public static async getMyBriefcaseIds(arg: IModelIdArg): Promise<number[]> {\r\n const accessToken = await this.getAccessToken(arg);\r\n return this.findLocalHub(arg.iModelId).getBriefcaseIds(accessToken);\r\n }\r\n\r\n public static async acquireNewBriefcaseId(arg: AcquireNewBriefcaseIdArg): Promise<number> {\r\n const accessToken = await this.getAccessToken(arg);\r\n return this.findLocalHub(arg.iModelId).acquireNewBriefcaseId(accessToken, arg.briefcaseAlias);\r\n }\r\n\r\n /** Release a briefcaseId. After this call it is illegal to generate changesets for the released briefcaseId. */\r\n public static async releaseBriefcase(arg: BriefcaseIdArg): Promise<void> {\r\n return this.findLocalHub(arg.iModelId).releaseBriefcaseId(arg.briefcaseId);\r\n }\r\n\r\n public static async downloadChangeset(arg: DownloadChangesetArg): Promise<ChangesetFileProps> {\r\n const changesetProps = this.findLocalHub(arg.iModelId).downloadChangeset({ index: this.changesetIndexFromArg(arg), targetDir: arg.targetDir });\r\n\r\n if (arg.progressCallback) {\r\n const totalSize = IModelJsFs.lstatSync(changesetProps.pathname)?.size;\r\n if (totalSize)\r\n await HubMock.mockProgressReporting(arg.progressCallback, totalSize);\r\n }\r\n\r\n return changesetProps;\r\n }\r\n\r\n public static async downloadChangesets(arg: DownloadChangesetRangeArg): Promise<ChangesetFileProps[]> {\r\n const changesetProps = this.findLocalHub(arg.iModelId).downloadChangesets({ range: arg.range, targetDir: arg.targetDir });\r\n\r\n if (arg.progressCallback) {\r\n const totalSize = changesetProps.reduce((sum, props) => sum + (IModelJsFs.lstatSync(props.pathname)?.size ?? 0), 0);\r\n await HubMock.mockProgressReporting(arg.progressCallback, totalSize);\r\n }\r\n\r\n return changesetProps;\r\n }\r\n\r\n public static async queryChangeset(arg: ChangesetArg): Promise<ChangesetProps> {\r\n return this.findLocalHub(arg.iModelId).getChangesetByIndex(this.changesetIndexFromArg(arg));\r\n }\r\n\r\n public static async queryChangesets(arg: IModelIdArg & { range?: ChangesetRange }): Promise<ChangesetProps[]> {\r\n return this.findLocalHub(arg.iModelId).queryChangesets(arg.range);\r\n }\r\n\r\n public static async pushChangeset(arg: IModelIdArg & { changesetProps: ChangesetFileProps }): Promise<ChangesetIndex> {\r\n return this.findLocalHub(arg.iModelId).addChangeset(arg.changesetProps);\r\n }\r\n\r\n public static async queryV2Checkpoint(arg: CheckpointProps): Promise<V2CheckpointAccessProps | undefined> {\r\n return {\r\n accountName: \"none\",\r\n sasToken: \"none\",\r\n containerId: Guid.createValue(),\r\n dbName: `${arg.changeset.index ?? 0}.bim`,\r\n storageType: \"mock\",\r\n isMock: true,\r\n checkpoint: arg,\r\n } as V2CheckpointAccessProps;\r\n }\r\n\r\n public static async releaseAllLocks(arg: BriefcaseDbArg) {\r\n const hub = this.findLocalHub(arg.iModelId);\r\n hub.releaseAllLocks({ briefcaseId: arg.briefcaseId, changesetIndex: hub.getIndexFromChangeset(arg.changeset) });\r\n }\r\n\r\n public static async abandonAllLocks(arg: BriefcaseIdArg): Promise<void> {\r\n const hub = this.findLocalHub(arg.iModelId);\r\n hub.abandonAllLocks(arg);\r\n }\r\n\r\n public static async queryAllLocks(_arg: BriefcaseDbArg): Promise<LockProps[]> {\r\n return [];\r\n }\r\n\r\n public static async acquireLocks(arg: BriefcaseDbArg, locks: LockMap): Promise<void> {\r\n this.findLocalHub(arg.iModelId).acquireLocks(locks, arg);\r\n }\r\n\r\n public static async abandonLocks(arg: BriefcaseIdArg, locks: LockMap): Promise<void> {\r\n this.findLocalHub(arg.iModelId).abandonLocks(locks, arg);\r\n }\r\n\r\n public static async queryIModelByName(arg: IModelNameArg): Promise<GuidString | undefined> {\r\n for (const hub of this.hubs) {\r\n const localHub = hub[1];\r\n if (localHub.iTwinId === arg.iTwinId && localHub.iModelName === arg.iModelName)\r\n return localHub.iModelId;\r\n }\r\n return undefined;\r\n }\r\n\r\n public static async deleteIModel(arg: IModelIdArg & { iTwinId: GuidString }): Promise<void> {\r\n return this.destroy(arg.iModelId);\r\n }\r\n\r\n private static async mockProgressReporting(progressCallback: ProgressFunction, totalSize: number): Promise<void> {\r\n await new Promise((resolve, reject) => {\r\n let rejected = false;\r\n\r\n const mockProgress = (index: number) => {\r\n const bytesDownloaded = Math.floor(totalSize * (index / 4));\r\n if (!rejected && progressCallback(bytesDownloaded, totalSize) === ProgressStatus.Abort) {\r\n rejected = true;\r\n reject(new Error(\"AbortError\"));\r\n }\r\n };\r\n\r\n mockProgress(1);\r\n setTimeout(() => mockProgress(2), 50);\r\n setTimeout(() => mockProgress(3), 100);\r\n setTimeout(() => {\r\n mockProgress(4);\r\n resolve(undefined);\r\n }, 150);\r\n });\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"HubMock.js","sourceRoot":"","sources":["../../../src/internal/HubMock.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { join } from \"path\";\r\nimport { Guid, GuidString } from \"@itwin/core-bentley\";\r\nimport {\r\n ChangesetFileProps, ChangesetIndex, ChangesetIndexOrId, ChangesetProps, ChangesetRange, IModelVersion, LocalDirName,\r\n} from \"@itwin/core-common\";\r\nimport {\r\n AcquireNewBriefcaseIdArg,\r\n BackendHubAccess, BriefcaseDbArg, BriefcaseIdArg, ChangesetArg, CreateNewIModelProps, DownloadChangesetArg, DownloadChangesetRangeArg, IModelIdArg, IModelNameArg,\r\n LockMap, LockProps, V2CheckpointAccessProps,\r\n} from \"../BackendHubAccess\";\r\nimport { CheckpointProps, DownloadRequest, MockCheckpoint, ProgressFunction, ProgressStatus, V2CheckpointManager } from \"../CheckpointManager\";\r\nimport { IModelHost } from \"../IModelHost\";\r\nimport { IModelJsFs } from \"../IModelJsFs\";\r\nimport { LocalHub } from \"../LocalHub\";\r\nimport { SnapshotDb, TokenArg } from \"../IModelDb\";\r\nimport { _getHubAccess, _mockCheckpoint, _nativeDb, _setHubAccess } from \"./Symbols\";\r\nimport { BriefcaseManager } from \"../BriefcaseManager\";\r\n\r\nfunction wasStarted(val: string | undefined): asserts val is string {\r\n if (undefined === val)\r\n throw new Error(\"Call HubMock.startup first\");\r\n}\r\n\r\n// Used by mockAttach: copies the nearest *prior* checkpoint (never newer) so the\r\n// returned file is already at or before the requested version.\r\nfunction doDownloadPrior(args: { iModelId: string, changeset: ChangesetIndexOrId, targetFile: string }) {\r\n HubMock.findLocalHub(args.iModelId).downloadCheckpoint(args);\r\n}\r\n\r\n// Used by mockDownload: copies the *nearest* checkpoint (forward or backward).\r\n// When the nearest is newer than the requested version, CheckpointManager.updateToRequestedVersion\r\n// will reverse it to the requested version via BriefcaseManager.pullAndApplyChangesets.\r\nfunction doDownloadNearest(args: { iModelId: string, changeset: ChangesetIndexOrId, targetFile: string }) {\r\n const hub = HubMock.findLocalHub(args.iModelId);\r\n const requestedIndex = hub.getIndexFromChangeset(args.changeset);\r\n const nearest = hub.queryNearestCheckpoint(requestedIndex);\r\n IModelJsFs.copySync(join(hub.checkpointDir, hub.checkpointNameFromIndex(nearest)), args.targetFile);\r\n}\r\n\r\nconst mockCheckpoint: MockCheckpoint = {\r\n mockAttach: (checkpoint: CheckpointProps) => {\r\n const targetFile = join(BriefcaseManager.getBriefcaseBasePath(checkpoint.iModelId), `${checkpoint.changeset.index}.bim`);\r\n doDownloadPrior({ ...checkpoint, targetFile });\r\n return targetFile;\r\n },\r\n\r\n mockDownload: (request: DownloadRequest) => {\r\n doDownloadNearest({ ...request.checkpoint, targetFile: request.localFile });\r\n }\r\n};\r\n\r\n/**\r\n * Mocks iModelHub for testing creating Briefcases, downloading checkpoints, and simulating multiple users pushing and pulling changesets, etc.\r\n *\r\n * Generally, tests for apis that *create or modify* iModels can and should be mocked. Otherwise they:\r\n * - create tremendous load on the test servers when they run on programmer's desktops and in CI jobs\r\n * - waste network and data center resources (i.e. $$$s),\r\n * - interfere with other tests running on the same or other systems, and\r\n * - (far worse) are the source of test flakiness outside of the api being tested.\r\n *\r\n * This class can be used to create tests that do not require authentication, are synchronous,\r\n * are guaranteed to be self-contained (i.e. do not interfere with other tests running at the same time or later), and do not fail for reasons outside\r\n * of the control of the test itself. As a bonus, in addition to making tests more reliable, mocking IModelHub generally makes tests run *much* faster.\r\n *\r\n * On the other hand, tests that expect to find an existing iModels, checkpoints, changesets, etc. in IModelHub cannot be mocked. In that case, those tests\r\n * should be careful to NOT modify the data, since doing so causes interference with other tests running simultaneously. These tests should be limited to\r\n * low level testing of the core apis only.\r\n *\r\n * To initialize HubMock, call [[startup]] at the beginning of your test, usually in `describe.before`. Thereafter, all access to iModelHub for an iModel will be\r\n * directed to a [[LocalHub]] - your test code does not change. After the test(s) complete, call [[shutdown]] (usually in `describe.after`) to stop mocking IModelHub and clean\r\n * up any resources used by the test(s). If you want to mock a single test, call [[startup]] as the first line and [[shutdown]] as the last. If you wish to run the\r\n * test against a \"real\" IModelHub, you can simply comment off the call [[startup]], though in that case you should make sure the name of your\r\n * iModel is unique so your test won't collide with other tests (iModel name uniqueness is not necessary for mocked tests.)\r\n *\r\n * Mocked tests must always start by creating a new iModel via [[IModelHost[_hubAccess].createNewIModel]] with a `version0` iModel.\r\n * They use mock (aka \"bogus\") credentials for `AccessTokens`, which is fine since [[HubMock]] never accesses resources outside the current\r\n * computer.\r\n *\r\n * @note Only one HubMock at a time, *running in a single process*, may be active. The comments above about multiple simultaneous tests refer to tests\r\n * running on different computers, or on a single computer in multiple processes. All of those scenarios are problematic without mocking.\r\n *\r\n * @internal\r\n */\r\n/** Options for [[HubMock.startup]]. @internal */\r\nexport interface HubMockStartupOptions {\r\n /**\r\n * When `true`, every successful [[HubMock.pushChangeset]] call automatically uploads a V1 checkpoint\r\n * (the current briefcase `.bim` file) for the tip changeset index into [[LocalHub]].\r\n * This lets tests download a tip checkpoint and reverse changesets from it.\r\n */\r\n createTipCheckpointOnPush?: boolean;\r\n}\r\n\r\nexport class HubMock {\r\n private static mockRoot: LocalDirName | undefined;\r\n private static hubs = new Map<string, LocalHub>();\r\n private static _saveHubAccess: BackendHubAccess | undefined;\r\n private static _iTwinId: GuidString | undefined;\r\n private static _createTipCheckpointOnPush = false;\r\n\r\n /** Determine whether a test us currently being run under HubMock */\r\n public static get isValid() { return undefined !== this.mockRoot; }\r\n public static get iTwinId() {\r\n wasStarted(this._iTwinId);\r\n return this._iTwinId;\r\n }\r\n\r\n /**\r\n * Begin mocking IModelHub access. After this call, all access to IModelHub will be directed to a [[LocalHub]].\r\n * @param mockName a unique name (e.g. \"MyTest\") for this HubMock to disambiguate tests when more than one is simultaneously active.\r\n * It is used to create a private directory used by the HubMock for a test. That directory is removed when [[shutdown]] is called.\r\n */\r\n public static startup(mockName: LocalDirName, outputDir: string, options?: HubMockStartupOptions) {\r\n if (this.isValid)\r\n throw new Error(\"Either a previous test did not call HubMock.shutdown() properly, or more than one test is simultaneously attempting to use HubMock, which is not allowed\");\r\n\r\n this.hubs.clear();\r\n this.mockRoot = join(outputDir, \"HubMock\", mockName);\r\n IModelJsFs.recursiveMkDirSync(this.mockRoot);\r\n IModelJsFs.purgeDirSync(this.mockRoot);\r\n this._saveHubAccess = IModelHost[_getHubAccess]();\r\n\r\n IModelHost[_setHubAccess](this);\r\n HubMock._iTwinId = Guid.createValue(); // all iModels for this test get the same \"iTwinId\"\r\n this._createTipCheckpointOnPush = options?.createTipCheckpointOnPush ?? false;\r\n\r\n V2CheckpointManager[_mockCheckpoint] = mockCheckpoint;\r\n }\r\n\r\n /** Stop a HubMock that was previously started with [[startup]]\r\n * @note this function throws an exception if any of the iModels used during the tests are left open.\r\n */\r\n public static shutdown() {\r\n if (this.mockRoot === undefined)\r\n return;\r\n\r\n V2CheckpointManager[_mockCheckpoint] = undefined;\r\n this._createTipCheckpointOnPush = false;\r\n\r\n HubMock._iTwinId = undefined;\r\n for (const hub of this.hubs)\r\n hub[1].cleanup();\r\n\r\n this.hubs.clear();\r\n IModelJsFs.purgeDirSync(this.mockRoot);\r\n IModelJsFs.removeSync(this.mockRoot);\r\n IModelHost[_setHubAccess](this._saveHubAccess);\r\n this.mockRoot = undefined;\r\n }\r\n\r\n public static findLocalHub(iModelId: GuidString): LocalHub {\r\n const hub = this.hubs.get(iModelId);\r\n if (!hub)\r\n throw new Error(`local hub for iModel ${iModelId} not created`);\r\n return hub;\r\n }\r\n\r\n /** create a [[LocalHub]] for an iModel. */\r\n public static async createNewIModel(arg: CreateNewIModelProps): Promise<GuidString> {\r\n wasStarted(this.mockRoot);\r\n const props = { ...arg, iModelId: Guid.createValue() };\r\n const mock = new LocalHub(join(this.mockRoot, props.iModelId), props);\r\n this.hubs.set(props.iModelId, mock);\r\n return props.iModelId;\r\n }\r\n\r\n /** remove the [[LocalHub]] for an iModel */\r\n public static destroy(iModelId: GuidString) {\r\n this.findLocalHub(iModelId).cleanup();\r\n this.hubs.delete(iModelId);\r\n }\r\n\r\n /** All methods below are mocks of the [[BackendHubAccess]] interface */\r\n\r\n public static async getChangesetFromNamedVersion(arg: IModelIdArg & { versionName: string }): Promise<ChangesetProps> {\r\n return this.findLocalHub(arg.iModelId).findNamedVersion(arg.versionName);\r\n }\r\n\r\n private static changesetIndexFromArg(arg: ChangesetArg) {\r\n return (undefined !== arg.changeset.index) ? arg.changeset.index : this.findLocalHub(arg.iModelId).getChangesetIndex(arg.changeset.id);\r\n }\r\n\r\n public static async getChangesetFromVersion(arg: IModelIdArg & { version: IModelVersion }): Promise<ChangesetProps> {\r\n const hub = this.findLocalHub(arg.iModelId);\r\n const version = arg.version;\r\n if (version.isFirst)\r\n return hub.getChangesetByIndex(0);\r\n\r\n const asOf = version.getAsOfChangeSet();\r\n if (asOf)\r\n return hub.getChangesetById(asOf);\r\n\r\n const versionName = version.getName();\r\n if (versionName)\r\n return hub.findNamedVersion(versionName);\r\n\r\n return hub.getLatestChangeset();\r\n }\r\n\r\n public static async getLatestChangeset(arg: IModelIdArg): Promise<ChangesetProps> {\r\n return this.findLocalHub(arg.iModelId).getLatestChangeset();\r\n }\r\n\r\n private static async getAccessToken(arg: TokenArg) {\r\n return arg.accessToken ?? await IModelHost.getAccessToken();\r\n }\r\n\r\n public static async getMyBriefcaseIds(arg: IModelIdArg): Promise<number[]> {\r\n const accessToken = await this.getAccessToken(arg);\r\n return this.findLocalHub(arg.iModelId).getBriefcaseIds(accessToken);\r\n }\r\n\r\n public static async acquireNewBriefcaseId(arg: AcquireNewBriefcaseIdArg): Promise<number> {\r\n const accessToken = await this.getAccessToken(arg);\r\n return this.findLocalHub(arg.iModelId).acquireNewBriefcaseId(accessToken, arg.briefcaseAlias);\r\n }\r\n\r\n /** Release a briefcaseId. After this call it is illegal to generate changesets for the released briefcaseId. */\r\n public static async releaseBriefcase(arg: BriefcaseIdArg): Promise<void> {\r\n return this.findLocalHub(arg.iModelId).releaseBriefcaseId(arg.briefcaseId);\r\n }\r\n\r\n public static async downloadChangeset(arg: DownloadChangesetArg): Promise<ChangesetFileProps> {\r\n const changesetProps = this.findLocalHub(arg.iModelId).downloadChangeset({ index: this.changesetIndexFromArg(arg), targetDir: arg.targetDir });\r\n\r\n if (arg.progressCallback) {\r\n const totalSize = IModelJsFs.lstatSync(changesetProps.pathname)?.size;\r\n if (totalSize)\r\n await HubMock.mockProgressReporting(arg.progressCallback, totalSize);\r\n }\r\n\r\n return changesetProps;\r\n }\r\n\r\n public static async downloadChangesets(arg: DownloadChangesetRangeArg): Promise<ChangesetFileProps[]> {\r\n const changesetProps = this.findLocalHub(arg.iModelId).downloadChangesets({ range: arg.range, targetDir: arg.targetDir });\r\n\r\n if (arg.progressCallback) {\r\n const totalSize = changesetProps.reduce((sum, props) => sum + (IModelJsFs.lstatSync(props.pathname)?.size ?? 0), 0);\r\n await HubMock.mockProgressReporting(arg.progressCallback, totalSize);\r\n }\r\n\r\n return changesetProps;\r\n }\r\n\r\n public static async queryChangeset(arg: ChangesetArg): Promise<ChangesetProps> {\r\n return this.findLocalHub(arg.iModelId).getChangesetByIndex(this.changesetIndexFromArg(arg));\r\n }\r\n\r\n public static async queryChangesets(arg: IModelIdArg & { range?: ChangesetRange }): Promise<ChangesetProps[]> {\r\n return this.findLocalHub(arg.iModelId).queryChangesets(arg.range);\r\n }\r\n\r\n public static async pushChangeset(arg: IModelIdArg & { changesetProps: ChangesetFileProps }): Promise<ChangesetIndex> {\r\n const csIndex = this.findLocalHub(arg.iModelId).addChangeset(arg.changesetProps);\r\n if (this._createTipCheckpointOnPush)\r\n await this.createTipCheckpoint(arg.iModelId);\r\n return csIndex;\r\n }\r\n\r\n /**\r\n * Build and upload a V1 checkpoint at the current tip changeset of the given iModel.\r\n *\r\n * The checkpoint is constructed by copying the nearest prior checkpoint from [[LocalHub]] as a\r\n * starting base, then applying all subsequent changesets forward to the latest index via\r\n * [[BriefcaseManager.pullAndApplyChangesets]]. The result is registered in [[LocalHub]] so that\r\n * [[V2CheckpointManager]] (mock path) can serve it to consumers.\r\n *\r\n * When [[HubMockStartupOptions.createTipCheckpointOnPush]] is `true` this is called automatically\r\n * after every successful [[pushChangeset]]. Tests can also call it explicitly to create a single\r\n * checkpoint at the tip after all changesets have been pushed.\r\n */\r\n public static async createTipCheckpoint(iModelId: GuidString): Promise<void> {\r\n const hub = this.findLocalHub(iModelId);\r\n const csIndex = hub.latestChangesetIndex;\r\n // Find the nearest checkpoint that precedes the new tip and use it as the base.\r\n const prevIndex = hub.queryPreviousCheckpoint(csIndex);\r\n const prevCheckpointFile = join(hub.checkpointDir, hub.checkpointNameFromIndex(prevIndex));\r\n const tempFile = join(hub.rootDir, `checkpoint-building-${csIndex}.bim`);\r\n IModelJsFs.copySync(prevCheckpointFile, tempFile);\r\n try {\r\n const db = SnapshotDb.openForApplyChangesets(tempFile);\r\n try {\r\n await BriefcaseManager.pullAndApplyChangesets(db, { accessToken: \"\", toIndex: csIndex });\r\n db[_nativeDb].saveChanges();\r\n } finally {\r\n db.close();\r\n }\r\n\r\n hub.uploadCheckpoint({ changesetIndex: csIndex, localFile: tempFile });\r\n } finally {\r\n if (IModelJsFs.existsSync(tempFile))\r\n IModelJsFs.removeSync(tempFile);\r\n }\r\n }\r\n\r\n public static async queryV2Checkpoint(arg: CheckpointProps): Promise<V2CheckpointAccessProps | undefined> {\r\n return {\r\n accountName: \"none\",\r\n sasToken: \"none\",\r\n containerId: Guid.createValue(),\r\n dbName: `${arg.changeset.index ?? 0}.bim`,\r\n storageType: \"mock\",\r\n isMock: true,\r\n checkpoint: arg,\r\n } as V2CheckpointAccessProps;\r\n }\r\n\r\n public static async releaseAllLocks(arg: BriefcaseDbArg) {\r\n const hub = this.findLocalHub(arg.iModelId);\r\n hub.releaseAllLocks({ briefcaseId: arg.briefcaseId, changesetIndex: hub.getIndexFromChangeset(arg.changeset) });\r\n }\r\n\r\n public static async abandonAllLocks(arg: BriefcaseIdArg): Promise<void> {\r\n const hub = this.findLocalHub(arg.iModelId);\r\n hub.abandonAllLocks(arg);\r\n }\r\n\r\n public static async queryAllLocks(_arg: BriefcaseDbArg): Promise<LockProps[]> {\r\n return [];\r\n }\r\n\r\n public static async acquireLocks(arg: BriefcaseDbArg, locks: LockMap): Promise<void> {\r\n this.findLocalHub(arg.iModelId).acquireLocks(locks, arg);\r\n }\r\n\r\n public static async abandonLocks(arg: BriefcaseIdArg, locks: LockMap): Promise<void> {\r\n this.findLocalHub(arg.iModelId).abandonLocks(locks, arg);\r\n }\r\n\r\n public static async queryIModelByName(arg: IModelNameArg): Promise<GuidString | undefined> {\r\n for (const hub of this.hubs) {\r\n const localHub = hub[1];\r\n if (localHub.iTwinId === arg.iTwinId && localHub.iModelName === arg.iModelName)\r\n return localHub.iModelId;\r\n }\r\n return undefined;\r\n }\r\n\r\n public static async deleteIModel(arg: IModelIdArg & { iTwinId: GuidString }): Promise<void> {\r\n return this.destroy(arg.iModelId);\r\n }\r\n\r\n private static async mockProgressReporting(progressCallback: ProgressFunction, totalSize: number): Promise<void> {\r\n await new Promise((resolve, reject) => {\r\n let rejected = false;\r\n\r\n const mockProgress = (index: number) => {\r\n const bytesDownloaded = Math.floor(totalSize * (index / 4));\r\n if (!rejected && progressCallback(bytesDownloaded, totalSize) === ProgressStatus.Abort) {\r\n rejected = true;\r\n reject(new Error(\"AbortError\"));\r\n }\r\n };\r\n\r\n mockProgress(1);\r\n setTimeout(() => mockProgress(2), 50);\r\n setTimeout(() => mockProgress(3), 100);\r\n setTimeout(() => {\r\n mockProgress(4);\r\n resolve(undefined);\r\n }, 150);\r\n });\r\n }\r\n}\r\n"]}
@@ -109,6 +109,12 @@ export declare class LocalHub {
109
109
  getCheckpoints(range?: ChangesetRange): ChangesetIndex[];
110
110
  /** Find the checkpoint that is no newer than a changesetIndex */
111
111
  queryPreviousCheckpoint(changesetIndex: ChangesetIndex): ChangesetIndex;
112
+ /**
113
+ * Find the checkpoint nearest to `changesetIndex` (searching both backward and forward).
114
+ * When the previous and next checkpoints are equidistant, the newer (next) checkpoint is preferred,
115
+ * which enables the tip-then-reverse download path in [[V2CheckpointManager]].
116
+ */
117
+ queryNearestCheckpoint(changesetIndex: ChangesetIndex): ChangesetIndex;
112
118
  /** "download" a checkpoint */
113
119
  downloadCheckpoint(arg: {
114
120
  changeset: ChangesetIndexOrId;
@@ -1 +1 @@
1
- {"version":3,"file":"LocalHub.d.ts","sourceRoot":"","sources":["../../src/LocalHub.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LocalHub.d.ts","sourceRoot":"","sources":["../../src/LocalHub.ts"],"names":[],"mappings":"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"}
@@ -328,6 +328,29 @@ export class LocalHub {
328
328
  return stmt.getValueInteger(0);
329
329
  });
330
330
  }
331
+ /**
332
+ * Find the checkpoint nearest to `changesetIndex` (searching both backward and forward).
333
+ * When the previous and next checkpoints are equidistant, the newer (next) checkpoint is preferred,
334
+ * which enables the tip-then-reverse download path in [[V2CheckpointManager]].
335
+ */
336
+ queryNearestCheckpoint(changesetIndex) {
337
+ const prev = this.queryPreviousCheckpoint(changesetIndex); // always ≥ 0; returns 0 when none found
338
+ const next = this.db.withSqliteStatement("SELECT min(csIndex) FROM checkpoints WHERE csIndex >= ?", (stmt) => {
339
+ stmt.bindInteger(1, changesetIndex);
340
+ stmt.step();
341
+ const val = stmt.getValue(0);
342
+ return val.isNull ? undefined : val.getInteger();
343
+ });
344
+ if (next === undefined)
345
+ return prev; // no checkpoint at or after requested index
346
+ if (next === prev)
347
+ return prev; // exact match
348
+ // Prefer the newer (next) checkpoint when equidistant so that CheckpointManager
349
+ // will reverse from a tip checkpoint rather than apply from an old seed.
350
+ const distPrev = changesetIndex - prev;
351
+ const distNext = next - changesetIndex;
352
+ return distNext <= distPrev ? next : prev;
353
+ }
331
354
  /** "download" a checkpoint */
332
355
  downloadCheckpoint(arg) {
333
356
  const index = this.getIndexFromChangeset(arg.changeset);
@@ -1 +1 @@
1
- {"version":3,"file":"LocalHub.js","sourceRoot":"","sources":["../../src/LocalHub.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { join } from \"path\";\r\nimport { assert, DbResult, GuidString, Id64String, IModelHubStatus, IModelStatus, OpenMode } from \"@itwin/core-bentley\";\r\nimport {\r\n BriefcaseId, BriefcaseIdValue, ChangesetFileProps, ChangesetId, ChangesetIdWithIndex, ChangesetIndex, ChangesetIndexOrId, ChangesetProps,\r\n ChangesetRange, IModelError, LocalDirName, LocalFileName, LockState,\r\n} from \"@itwin/core-common\";\r\nimport { BriefcaseIdArg, LockConflict, LockMap, LockProps } from \"./BackendHubAccess\";\r\nimport { BriefcaseManager } from \"./BriefcaseManager\";\r\nimport { BriefcaseLocalValue, IModelDb, SnapshotDb } from \"./IModelDb\";\r\nimport { IModelJsFs } from \"./IModelJsFs\";\r\nimport { SQLiteDb } from \"./SQLiteDb\";\r\n\r\n// cspell:ignore rowid\r\n\r\n/** @internal */\r\ninterface MockBriefcaseIdProps {\r\n id: BriefcaseId;\r\n user: string; // Just an AccessToken that simulates a user\r\n alias: string;\r\n assigned: boolean;\r\n}\r\n\r\n/** @internal */\r\ninterface LocalHubProps {\r\n readonly iTwinId: GuidString;\r\n readonly iModelId: GuidString;\r\n readonly iModelName: string;\r\n readonly description?: string;\r\n readonly version0?: string;\r\n readonly noLocks?: true;\r\n}\r\n\r\ninterface LockLastReleaseChangesetIndices {\r\n lastExclusiveReleaseChangesetIndex?: ChangesetIndex;\r\n lastSharedReleaseChangesetIndex?: ChangesetIndex;\r\n}\r\n\r\ninterface LocksEntry extends LockLastReleaseChangesetIndices {\r\n id: Id64String;\r\n level: LockState;\r\n briefcaseId?: BriefcaseId;\r\n}\r\n\r\ninterface LockStatusNone extends LockLastReleaseChangesetIndices {\r\n state: LockState.None;\r\n}\r\n\r\n/** @internal exported for tests. */\r\nexport interface LockStatusExclusive extends LockLastReleaseChangesetIndices {\r\n state: LockState.Exclusive;\r\n briefcaseId: BriefcaseId;\r\n}\r\n\r\n/** @internal exported for tests. */\r\nexport interface LockStatusShared extends LockLastReleaseChangesetIndices {\r\n state: LockState.Shared;\r\n sharedBy: Set<BriefcaseId>;\r\n}\r\n\r\ninterface BriefcaseIdAndChangeset {\r\n changeset: ChangesetIdWithIndex;\r\n briefcaseId: BriefcaseId;\r\n}\r\n\r\ntype LockStatus = LockStatusNone | LockStatusExclusive | LockStatusShared;\r\n\r\n/**\r\n * A \"local\" mock for IModelHub to provide access to a single iModel. Used by HubMock.\r\n * @internal\r\n */\r\nexport class LocalHub {\r\n public readonly iTwinId: GuidString;\r\n public readonly iModelId: GuidString;\r\n public readonly iModelName: string;\r\n public readonly description?: string;\r\n private _hubDb?: SQLiteDb;\r\n private _nextBriefcaseId = BriefcaseIdValue.FirstValid;\r\n private _latestChangesetIndex = 0;\r\n public get latestChangesetIndex() { return this._latestChangesetIndex; }\r\n\r\n public constructor(public readonly rootDir: LocalDirName, arg: LocalHubProps) {\r\n this.iTwinId = arg.iTwinId;\r\n this.iModelId = arg.iModelId;\r\n this.iModelName = arg.iModelName;\r\n this.description = arg.description;\r\n\r\n this.cleanup();\r\n\r\n IModelJsFs.recursiveMkDirSync(this.rootDir);\r\n IModelJsFs.mkdirSync(this.changesetDir);\r\n IModelJsFs.mkdirSync(this.checkpointDir);\r\n\r\n const db = this._hubDb = new SQLiteDb();\r\n db.createDb(this.mockDbName);\r\n db.executeSQL(\"CREATE TABLE briefcases(id INTEGER PRIMARY KEY NOT NULL,user TEXT NOT NULL,alias TEXT NOT NULL,assigned INTEGER DEFAULT 1)\");\r\n db.executeSQL(\"CREATE TABLE timeline(csIndex INTEGER PRIMARY KEY NOT NULL,csId TEXT NOT NULL UNIQUE,description TEXT,user TEXT,size BIGINT,type INTEGER,pushDate TEXT,briefcaseId INTEGER,uncompressedSize BIGINT,\\\r\n FOREIGN KEY(briefcaseId) REFERENCES briefcases(id))\");\r\n db.executeSQL(\"CREATE TABLE checkpoints(csIndex INTEGER PRIMARY KEY NOT NULL)\");\r\n db.executeSQL(\"CREATE TABLE versions(name TEXT PRIMARY KEY NOT NULL,csIndex TEXT,FOREIGN KEY(csIndex) REFERENCES timeline(csIndex))\");\r\n db.executeSQL(\"CREATE TABLE locks(id INTEGER PRIMARY KEY NOT NULL,level INTEGER NOT NULL,lastExclusiveReleaseChangesetIndex INTEGER,lastSharedReleaseChangesetIndex INTEGER,briefcaseId INTEGER)\");\r\n db.executeSQL(\"CREATE TABLE sharedLocks(lockId INTEGER NOT NULL,briefcaseId INTEGER NOT NULL,PRIMARY KEY(lockId,briefcaseId))\");\r\n db.executeSQL(\"CREATE INDEX LockIdx ON locks(briefcaseId)\");\r\n db.executeSQL(\"CREATE INDEX SharedLockIdx ON sharedLocks(briefcaseId)\");\r\n db.saveChanges();\r\n\r\n const version0Root = `${rootDir}_version0`;\r\n const version0 = arg.version0 ?? join(version0Root, \"version0.bim\");\r\n\r\n if (!arg.version0) { // if they didn't supply a version0 file, create a blank one.\r\n IModelJsFs.recursiveMkDirSync(version0Root);\r\n IModelJsFs.removeSync(version0);\r\n SnapshotDb.createEmpty(version0, { rootSubject: { name: arg.description ?? arg.iModelName } }).close();\r\n }\r\n\r\n const path = this.uploadCheckpoint({ changesetIndex: 0, localFile: version0 });\r\n if (!arg.version0)\r\n IModelJsFs.removeSync(version0);\r\n\r\n const nativeDb = IModelDb.openDgnDb({ path }, OpenMode.ReadWrite);\r\n try {\r\n nativeDb.setITwinId(this.iTwinId);\r\n nativeDb.setIModelId(this.iModelId);\r\n nativeDb.saveChanges();\r\n nativeDb.deleteAllTxns(); // necessary before resetting briefcaseId\r\n nativeDb.resetBriefcaseId(BriefcaseIdValue.Unassigned);\r\n nativeDb.saveLocalValue(BriefcaseLocalValue.NoLocking, arg.noLocks ? \"true\" : undefined);\r\n nativeDb.saveChanges();\r\n } finally {\r\n nativeDb.closeFile();\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\r\n private get db(): SQLiteDb { return this._hubDb!; } // eslint-disable-line @typescript-eslint/naming-convention\r\n public get changesetDir() { return join(this.rootDir, \"changesets\"); }\r\n public get checkpointDir() { return join(this.rootDir, \"checkpoints\"); }\r\n public get mockDbName() { return join(this.rootDir, \"localHub.db\"); }\r\n\r\n /** Acquire the next available briefcaseId and assign it to the supplied user */\r\n public acquireNewBriefcaseId(user: string, alias?: string): BriefcaseId {\r\n const db = this.db;\r\n const newId = this._nextBriefcaseId++;\r\n db.withSqliteStatement(\"INSERT INTO briefcases(id,user,alias) VALUES (?,?,?)\", (stmt) => {\r\n stmt.bindInteger(1, newId);\r\n stmt.bindString(2, user);\r\n stmt.bindString(3, alias ?? `${user} (${newId})`);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_DONE !== rc)\r\n throw new IModelError(rc, \"can't insert briefcaseId in mock database\");\r\n });\r\n db.saveChanges();\r\n return newId;\r\n }\r\n\r\n /** Release a briefcaseId */\r\n public releaseBriefcaseId(id: BriefcaseId) {\r\n const db = this.db;\r\n this.releaseAllLocks({ briefcaseId: id, changesetIndex: 0 });\r\n db.withSqliteStatement(\"UPDATE briefcases SET assigned=0 WHERE id=?\", (stmt) => {\r\n stmt.bindInteger(1, id);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_DONE !== rc)\r\n throw new IModelError(rc, `briefcaseId ${id} was not reserved`);\r\n });\r\n db.saveChanges();\r\n }\r\n\r\n /** Get an array of all of the currently assigned Briefcases */\r\n public getBriefcases(onlyAssigned = true): MockBriefcaseIdProps[] {\r\n const briefcases: MockBriefcaseIdProps[] = [];\r\n let sql = \"SELECT id,user,alias,assigned FROM briefcases\";\r\n if (onlyAssigned)\r\n sql += \" WHERE assigned=1\";\r\n\r\n this.db.withSqliteStatement(sql, (stmt) => {\r\n while (DbResult.BE_SQLITE_ROW === stmt.step()) {\r\n briefcases.push({\r\n id: stmt.getValueInteger(0),\r\n user: stmt.getValueString(1),\r\n alias: stmt.getValueString(2),\r\n assigned: stmt.getValueInteger(3) !== 0,\r\n });\r\n }\r\n });\r\n return briefcases;\r\n }\r\n\r\n /** Get an array of all of the currently assigned BriefcaseIds for a user */\r\n public getBriefcaseIds(user: string): BriefcaseId[] {\r\n const briefcases: BriefcaseId[] = [];\r\n this.db.withSqliteStatement(\"SELECT id FROM briefcases WHERE user=? AND assigned=1\", (stmt) => {\r\n stmt.bindString(1, user);\r\n while (DbResult.BE_SQLITE_ROW === stmt.step())\r\n briefcases.push(stmt.getValueInteger(0));\r\n });\r\n return briefcases;\r\n }\r\n\r\n public getBriefcase(id: BriefcaseId): MockBriefcaseIdProps {\r\n return this.db.withSqliteStatement(\"SELECT user,alias,assigned FROM briefcases WHERE id=?\", (stmt) => {\r\n stmt.bindInteger(1, id);\r\n if (DbResult.BE_SQLITE_ROW !== stmt.step())\r\n throw new IModelError(IModelStatus.NotFound, \"no briefcase with that id\");\r\n return { id, user: stmt.getValueString(0), alias: stmt.getValueString(1), assigned: stmt.getValueInteger(2) !== 0 };\r\n });\r\n }\r\n\r\n private getChangesetFileName(index: ChangesetIndex) {\r\n return join(this.changesetDir, `changeset-${index}`);\r\n }\r\n\r\n /** Add a changeset to the timeline\r\n * @return the changesetIndex of the added changeset\r\n */\r\n public addChangeset(changeset: ChangesetFileProps): ChangesetIndex {\r\n const stats = IModelJsFs.lstatSync(changeset.pathname);\r\n if (!stats)\r\n throw new Error(`cannot read changeset file ${changeset.pathname}`);\r\n\r\n const parentIndex = this.getChangesetById(changeset.parentId).index;\r\n if (parentIndex !== this.latestChangesetIndex)\r\n throw new IModelError(IModelStatus.InvalidParent, \"changeset parent is not latest changeset\");\r\n\r\n this.getBriefcase(changeset.briefcaseId); // throws if invalid id\r\n const db = this.db;\r\n changeset.index = this._latestChangesetIndex + 1;\r\n db.withSqliteStatement(\"INSERT INTO timeline(csIndex,csId,description,size,type,pushDate,user,briefcaseId,uncompressedSize) VALUES (?,?,?,?,?,?,?,?,?)\", (stmt) => {\r\n stmt.bindInteger(1, changeset.index);\r\n stmt.bindString(2, changeset.id);\r\n stmt.bindString(3, changeset.description);\r\n stmt.bindInteger(4, stats.size);\r\n stmt.bindInteger(5, changeset.changesType ?? 0);\r\n stmt.bindString(6, changeset.pushDate ?? new Date().toISOString());\r\n stmt.bindString(7, changeset.userCreated ?? \"\");\r\n stmt.bindInteger(8, changeset.briefcaseId);\r\n stmt.bindInteger(9, changeset.uncompressedSize ?? 0);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_DONE !== rc)\r\n throw new IModelError(rc, \"can't insert changeset into mock db\");\r\n });\r\n this._latestChangesetIndex = changeset.index; // only change this after insert succeeds\r\n db.saveChanges();\r\n IModelJsFs.copySync(changeset.pathname, this.getChangesetFileName(changeset.index));\r\n return changeset.index;\r\n }\r\n\r\n public getIndexFromChangeset(changeset: ChangesetIndexOrId): ChangesetIndex {\r\n return changeset.index ?? this.getChangesetIndex(changeset.id);\r\n }\r\n\r\n /** Get the index of a changeset by its Id */\r\n public getChangesetIndex(id: ChangesetId): ChangesetIndex {\r\n if (id === \"\")\r\n return 0;\r\n\r\n return this.db.withPreparedSqliteStatement(\"SELECT csIndex FROM timeline WHERE csId=?\", (stmt) => {\r\n stmt.bindString(1, id);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_ROW !== rc)\r\n throw new IModelError(rc, `changeset ${id} not found`);\r\n\r\n return stmt.getValueInteger(0);\r\n });\r\n }\r\n\r\n /** Get the properties of a changeset by its Id */\r\n public getChangesetById(id: ChangesetId): ChangesetProps {\r\n return this.getChangesetByIndex(this.getChangesetIndex(id));\r\n }\r\n\r\n public getPreviousIndex(index: ChangesetIndex) {\r\n return this.db.withPreparedSqliteStatement(\"SELECT max(csIndex) FROM timeline WHERE csIndex<?\", (stmt) => {\r\n stmt.bindInteger(1, index);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_ROW !== rc)\r\n throw new IModelError(rc, `cannot get previous index`);\r\n\r\n return stmt.getValueInteger(0);\r\n });\r\n }\r\n\r\n public getParentId(index: ChangesetIndex): ChangesetId {\r\n if (index === 0)\r\n return \"\";\r\n\r\n return this.db.withPreparedSqliteStatement(\"SELECT csId FROM timeline WHERE csIndex=?\", (stmt) => {\r\n stmt.bindInteger(1, this.getPreviousIndex(index));\r\n stmt.step();\r\n return stmt.getValueString(0);\r\n });\r\n }\r\n\r\n /** Get the properties of a changeset by its index */\r\n public getChangesetByIndex(index: ChangesetIndex): ChangesetProps {\r\n if (index <= 0)\r\n return { id: \"\", changesType: 0, description: \"version0\", parentId: \"\", briefcaseId: 0, pushDate: \"\", userCreated: \"\", index: 0, size: 0, uncompressedSize: 0 };\r\n\r\n return this.db.withPreparedSqliteStatement(\"SELECT description,size,type,pushDate,user,csId,briefcaseId,uncompressedSize FROM timeline WHERE csIndex=?\", (stmt) => {\r\n stmt.bindInteger(1, index);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_ROW !== rc)\r\n throw new IModelError(rc, `changeset at index ${index} not found`);\r\n\r\n return {\r\n description: stmt.getValueString(0),\r\n size: stmt.getValueDouble(1),\r\n changesType: stmt.getValueInteger(2),\r\n pushDate: stmt.getValueString(3),\r\n userCreated: stmt.getValueString(4),\r\n id: stmt.getValueString(5),\r\n briefcaseId: stmt.getValueInteger(6),\r\n index,\r\n parentId: this.getParentId(index),\r\n uncompressedSize: stmt.getValueInteger(7),\r\n };\r\n });\r\n }\r\n\r\n public getLatestChangeset(): ChangesetProps {\r\n return this.getChangesetByIndex(this.latestChangesetIndex);\r\n }\r\n\r\n public getChangesetId(index: ChangesetIndex): ChangesetId {\r\n return this.getChangesetByIndex(index).id;\r\n }\r\n\r\n /** Get an array of changesets starting with first to last, by index */\r\n public queryChangesets(range?: ChangesetRange): ChangesetProps[] {\r\n const changesets: ChangesetProps[] = [];\r\n const first = range?.first ?? 0;\r\n const last = range?.end ?? this.latestChangesetIndex;\r\n\r\n this.db.withPreparedSqliteStatement(\"SELECT csIndex FROM timeline WHERE csIndex>=? AND csIndex<=? ORDER BY csIndex\", (stmt) => {\r\n stmt.bindInteger(1, first);\r\n stmt.bindInteger(2, last);\r\n while (DbResult.BE_SQLITE_ROW === stmt.step())\r\n changesets.push(this.getChangesetByIndex(stmt.getValueInteger(0)));\r\n });\r\n return changesets;\r\n }\r\n\r\n /** Name a version */\r\n public addNamedVersion(arg: { versionName: string, csIndex: ChangesetIndex }) {\r\n const db = this.db;\r\n db.withSqliteStatement(\"INSERT INTO versions(name,csIndex) VALUES (?,?)\", (stmt) => {\r\n stmt.bindString(1, arg.versionName);\r\n stmt.bindInteger(2, arg.csIndex);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_DONE !== rc)\r\n throw new IModelError(rc, \"can't insert named version\");\r\n });\r\n db.saveChanges();\r\n }\r\n\r\n /** Delete a named version */\r\n public deleteNamedVersion(versionName: string) {\r\n const db = this.db;\r\n db.withSqliteStatement(\"DELETE FROM versions WHERE name=?\", (stmt) => {\r\n stmt.bindString(1, versionName);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_DONE !== rc)\r\n throw new IModelError(rc, \"can't delete named version\");\r\n });\r\n db.saveChanges();\r\n }\r\n\r\n /** find the changeset for a named version */\r\n public findNamedVersion(versionName: string): ChangesetProps {\r\n const index = this.db.withSqliteStatement(\"SELECT csIndex FROM versions WHERE name=?\", (stmt) => {\r\n stmt.bindString(1, versionName);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_ROW !== rc)\r\n throw new IModelError(IModelStatus.NotFound, `Named version ${versionName} not found`);\r\n return stmt.getValueInteger(0);\r\n });\r\n return this.getChangesetByIndex(index);\r\n }\r\n\r\n public checkpointNameFromIndex(csIndex: ChangesetIndex) {\r\n return `checkpoint-${csIndex}`;\r\n }\r\n\r\n /** \"upload\" a checkpoint */\r\n public uploadCheckpoint(arg: { changesetIndex: ChangesetIndex, localFile: LocalFileName }) {\r\n const db = this.db;\r\n db.withSqliteStatement(\"INSERT INTO checkpoints(csIndex) VALUES (?)\", (stmt) => {\r\n stmt.bindInteger(1, arg.changesetIndex);\r\n const res = stmt.step();\r\n if (DbResult.BE_SQLITE_DONE !== res)\r\n throw new IModelError(res, \"can't insert checkpoint into mock db\");\r\n });\r\n db.saveChanges();\r\n const outName = join(this.checkpointDir, this.checkpointNameFromIndex(arg.changesetIndex));\r\n IModelJsFs.copySync(arg.localFile, outName);\r\n return outName;\r\n }\r\n\r\n /** Get an array of the indexes for a range of checkpoints */\r\n public getCheckpoints(range?: ChangesetRange): ChangesetIndex[] {\r\n const first = range?.first ?? 0;\r\n const last = range?.end ?? this.latestChangesetIndex;\r\n\r\n const checkpoints: ChangesetIndex[] = [];\r\n this.db.withSqliteStatement(\"SELECT csIndex FROM checkpoints WHERE csIndex>=? AND csIndex<=? ORDER BY csIndex\", (stmt) => {\r\n stmt.bindInteger(1, first);\r\n stmt.bindInteger(2, last);\r\n while (DbResult.BE_SQLITE_ROW === stmt.step())\r\n checkpoints.push(stmt.getValueInteger(0));\r\n\r\n });\r\n return checkpoints;\r\n }\r\n\r\n /** Find the checkpoint that is no newer than a changesetIndex */\r\n public queryPreviousCheckpoint(changesetIndex: ChangesetIndex): ChangesetIndex {\r\n if (changesetIndex <= 0)\r\n return 0;\r\n\r\n return this.db.withSqliteStatement(\"SELECT max(csIndex) FROM checkpoints WHERE csIndex <= ? \", (stmt) => {\r\n stmt.bindInteger(1, changesetIndex);\r\n const res = stmt.step();\r\n if (DbResult.BE_SQLITE_ROW !== res)\r\n throw new IModelError(res, \"can't get previous checkpoint\");\r\n return stmt.getValueInteger(0);\r\n });\r\n }\r\n\r\n /** \"download\" a checkpoint */\r\n public downloadCheckpoint(arg: { changeset: ChangesetIndexOrId, targetFile: LocalFileName }) {\r\n const index = this.getIndexFromChangeset(arg.changeset);\r\n const prev = this.queryPreviousCheckpoint(index);\r\n IModelJsFs.copySync(join(this.checkpointDir, this.checkpointNameFromIndex(prev)), arg.targetFile);\r\n const changeset = this.getChangesetByIndex(index);\r\n return { index, id: changeset.id };\r\n }\r\n\r\n private copyChangeset(arg: ChangesetFileProps): ChangesetFileProps {\r\n IModelJsFs.copySync(this.getChangesetFileName(arg.index), arg.pathname);\r\n return arg;\r\n }\r\n\r\n /** \"download\" a changeset */\r\n public downloadChangeset(arg: { index: ChangesetIndex, targetDir: LocalDirName }) {\r\n const cs = this.getChangesetByIndex(arg.index);\r\n const csProps = { ...cs, pathname: join(arg.targetDir, cs.id), index: arg.index };\r\n return this.copyChangeset(csProps);\r\n }\r\n\r\n /** \"download\" all the changesets in a given range */\r\n public downloadChangesets(arg: { range?: ChangesetRange, targetDir: LocalDirName }): ChangesetFileProps[] {\r\n const cSets = this.queryChangesets(arg.range) as ChangesetFileProps[];\r\n for (const cs of cSets) {\r\n cs.pathname = join(arg.targetDir, cs.id);\r\n this.copyChangeset(cs);\r\n }\r\n return cSets;\r\n }\r\n\r\n private querySharedLockHolders(elementId: Id64String) {\r\n return this.db.withPreparedSqliteStatement(\"SELECT briefcaseId FROM sharedLocks WHERE lockId=?\", (stmt) => {\r\n stmt.bindId(1, elementId);\r\n const briefcases = new Set<BriefcaseId>();\r\n while (DbResult.BE_SQLITE_ROW === stmt.step())\r\n briefcases.add(stmt.getValueInteger(0));\r\n return briefcases;\r\n });\r\n }\r\n\r\n public queryAllLocks(briefcaseId: BriefcaseId) {\r\n this.getBriefcase(briefcaseId); // throws if briefcaseId invalid.\r\n const locks: LockProps[] = [];\r\n this.db.withPreparedSqliteStatement(\"SELECT id FROM locks WHERE briefcaseId=?\", (stmt) => {\r\n stmt.bindInteger(1, briefcaseId);\r\n while (DbResult.BE_SQLITE_ROW === stmt.step())\r\n locks.push({ id: stmt.getValueId(0), state: LockState.Exclusive });\r\n });\r\n this.db.withPreparedSqliteStatement(\"SELECT lockId FROM sharedLocks WHERE briefcaseId=?\", (stmt) => {\r\n stmt.bindInteger(1, briefcaseId);\r\n while (DbResult.BE_SQLITE_ROW === stmt.step())\r\n locks.push({ id: stmt.getValueId(0), state: LockState.Shared });\r\n });\r\n return locks;\r\n }\r\n\r\n public queryLockStatus(elementId: Id64String): LockStatus {\r\n return this.db.withPreparedSqliteStatement(\"SELECT lastSharedReleaseChangesetIndex,lastExclusiveReleaseChangesetIndex,level,briefcaseId FROM locks WHERE id=?\", (stmt) => {\r\n stmt.bindId(1, elementId);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_ROW !== rc)\r\n return { state: LockState.None };\r\n const lastSharedCsVal = stmt.getValue(0);\r\n const lastExclusiveCsVal = stmt.getValue(1);\r\n const lock = {\r\n lastSharedReleaseChangesetIndex: lastSharedCsVal.isNull ? undefined : lastSharedCsVal.getInteger(),\r\n lastExclusiveReleaseChangesetIndex: lastExclusiveCsVal.isNull ? undefined : lastExclusiveCsVal.getInteger(),\r\n state: stmt.getValueInteger(2),\r\n };\r\n switch (lock.state) {\r\n case LockState.None:\r\n return lock;\r\n case LockState.Exclusive:\r\n return { ...lock, briefcaseId: stmt.getValueInteger(3) };\r\n case LockState.Shared:\r\n return { ...lock, sharedBy: this.querySharedLockHolders(elementId) };\r\n default:\r\n throw new Error(\"illegal lock state\");\r\n }\r\n });\r\n }\r\n\r\n private doesBriefcaseRequirePullBeforeLock(currStatus: LockStatus, props: LockProps, briefcase: BriefcaseIdAndChangeset): boolean {\r\n if (props.state === LockState.None)\r\n return false;\r\n\r\n const briefcaseChangesetIndex = this.getIndexFromChangeset(briefcase.changeset);\r\n const exclusiveIndexIsNewer = currStatus.lastExclusiveReleaseChangesetIndex !== undefined &&\r\n currStatus.lastExclusiveReleaseChangesetIndex > briefcaseChangesetIndex;\r\n\r\n if (props.state === LockState.Shared) {\r\n // To acquire a shared lock, the briefcase must at least at the latest exclusive changeset index\r\n return exclusiveIndexIsNewer;\r\n } else {\r\n assert(props.state === LockState.Exclusive);\r\n\r\n const sharedIndexIsNewer = currStatus.lastSharedReleaseChangesetIndex !== undefined &&\r\n currStatus.lastSharedReleaseChangesetIndex > briefcaseChangesetIndex;\r\n\r\n // To acquire the exclusive lock the briefcase must be at least at the greater of the two last-indexes\r\n return exclusiveIndexIsNewer || sharedIndexIsNewer;\r\n }\r\n }\r\n\r\n private addSharedLockRecord(lockId: Id64String, briefcaseId: BriefcaseId) {\r\n this.db.withPreparedSqliteStatement(\"INSERT INTO sharedLocks(lockId,briefcaseId) VALUES(?,?) ON CONFLICT(lockId,briefcaseId) DO NOTHING\", (stmt) => {\r\n stmt.bindId(1, lockId);\r\n stmt.bindInteger(2, briefcaseId);\r\n const rc = stmt.step();\r\n if (rc !== DbResult.BE_SQLITE_DONE)\r\n throw new IModelError(rc, \"cannot insert shared lock\");\r\n });\r\n }\r\n\r\n private reserveLock(currStatus: LockStatus, props: LockProps, briefcase: BriefcaseIdAndChangeset) {\r\n if (this.doesBriefcaseRequirePullBeforeLock(currStatus, props, briefcase)) {\r\n throw new IModelError(IModelHubStatus.PullIsRequired, \"pull is required to obtain lock\");\r\n }\r\n\r\n const wantShared = props.state === LockState.Shared;\r\n if (wantShared && (currStatus.state === LockState.Exclusive))\r\n throw new Error(\"cannot acquire shared lock because an exclusive lock is already held\");\r\n\r\n this.db.withPreparedSqliteStatement(\"INSERT INTO locks(id,level,briefcaseId) VALUES(?,?,?) ON CONFLICT(id) DO UPDATE SET briefcaseId=excluded.briefcaseId,level=excluded.level\", (stmt) => {\r\n stmt.bindId(1, props.id);\r\n stmt.bindInteger(2, props.state);\r\n stmt.bindValue(3, wantShared ? undefined : briefcase.briefcaseId);\r\n const rc = stmt.step();\r\n if (rc !== DbResult.BE_SQLITE_DONE)\r\n throw new IModelError(rc, \"cannot insert lock\");\r\n });\r\n\r\n if (wantShared) {\r\n this.addSharedLockRecord(props.id, briefcase.briefcaseId);\r\n }\r\n }\r\n\r\n private downgradeExclusiveLockToShared(lockId: Id64String, briefcaseId: BriefcaseId) {\r\n this.db.withPreparedSqliteStatement(\"UPDATE locks SET level=1,briefcaseId=NULL WHERE id=? AND briefcaseId=? AND level=2\", (stmt) => {\r\n stmt.bindId(1, lockId);\r\n stmt.bindInteger(2, briefcaseId);\r\n const rc = stmt.step();\r\n if (rc !== DbResult.BE_SQLITE_DONE)\r\n throw new IModelError(rc, \"can't downgrade lock\");\r\n });\r\n\r\n // Verify that the above actually updated a row. If it didn't, something has gone wrong with the downgrade.\r\n // This shouldn't happen.\r\n this.db.withPreparedSqliteStatement(\"SELECT CHANGES()\", (stmt) => {\r\n stmt.step();\r\n if (stmt.getValueInteger(0) !== 1)\r\n throw new IModelError(IModelHubStatus.LockOwnedByAnotherBriefcase, \"lock not held by this briefcase or lock is not exclusive\");\r\n });\r\n\r\n this.addSharedLockRecord(lockId, briefcaseId);\r\n }\r\n\r\n private clearLock(id: Id64String) {\r\n this.db.withPreparedSqliteStatement(\"UPDATE locks SET level=0,briefcaseId=NULL WHERE id=?\", (stmt) => {\r\n stmt.bindId(1, id);\r\n const rc = stmt.step();\r\n if (rc !== DbResult.BE_SQLITE_DONE)\r\n throw new IModelError(rc, \"can't release lock\");\r\n });\r\n }\r\n\r\n private updateLockExclusiveChangeset(id: Id64String, index: ChangesetIndex) {\r\n if (index <= 0)\r\n return;\r\n\r\n this.db.withPreparedSqliteStatement(\"UPDATE locks SET lastExclusiveReleaseChangesetIndex=? WHERE id=?\", (stmt) => {\r\n stmt.bindInteger(1, index);\r\n stmt.bindId(2, id);\r\n const rc = stmt.step();\r\n if (rc !== DbResult.BE_SQLITE_DONE)\r\n throw new IModelError(rc, \"can't update lock exclusive changeSetId\");\r\n });\r\n }\r\n\r\n private updateLockSharedChangeset(id: Id64String, index: ChangesetIndex) {\r\n if (index <= 0)\r\n return;\r\n\r\n this.db.withPreparedSqliteStatement(\"UPDATE locks SET lastSharedReleaseChangesetIndex=? WHERE id=?\", (stmt) => {\r\n stmt.bindInteger(1, index);\r\n stmt.bindId(2, id);\r\n const rc = stmt.step();\r\n if (rc !== DbResult.BE_SQLITE_DONE)\r\n throw new IModelError(rc, \"can't update lock shared changeSetId\");\r\n });\r\n }\r\n\r\n private requestLock(props: LockProps, briefcase: BriefcaseIdAndChangeset) {\r\n if (props.state === LockState.None)\r\n throw new Error(\"cannot request lock for LockState.None\");\r\n\r\n this.getBriefcase(briefcase.briefcaseId); // throws if briefcaseId invalid.\r\n\r\n const lockStatus = this.queryLockStatus(props.id);\r\n switch (lockStatus.state) {\r\n case LockState.None:\r\n return this.reserveLock(lockStatus, props, briefcase);\r\n\r\n case LockState.Shared:\r\n if (props.state === LockState.Shared) {\r\n if (!lockStatus.sharedBy.has(briefcase.briefcaseId))\r\n this.reserveLock(lockStatus, props, briefcase);\r\n } else {\r\n // if requester is the only one holding a shared lock, \"upgrade\" the lock from shared to exclusive\r\n if (lockStatus.sharedBy.size > 1 || !lockStatus.sharedBy.has(briefcase.briefcaseId)) {\r\n const id = lockStatus.sharedBy.values().next().value!; // eslint-disable-line @typescript-eslint/no-non-null-assertion\r\n throw new LockConflict(id, this.getBriefcase(id).alias, \"shared lock is held\");\r\n }\r\n this.removeSharedLock(props.id, briefcase.briefcaseId);\r\n this.reserveLock(this.queryLockStatus(props.id), props, briefcase);\r\n }\r\n return;\r\n\r\n case LockState.Exclusive:\r\n if (lockStatus.briefcaseId !== briefcase.briefcaseId)\r\n throw new LockConflict(lockStatus.briefcaseId, this.getBriefcase(lockStatus.briefcaseId).alias, \"exclusive lock is already held\");\r\n }\r\n }\r\n\r\n private removeSharedLock(lockId: Id64String, briefcaseId: BriefcaseId) {\r\n this.db.withPreparedSqliteStatement(\"DELETE FROM sharedLocks WHERE lockId=? AND briefcaseId=?\", (stmt) => {\r\n stmt.bindId(1, lockId);\r\n stmt.bindInteger(2, briefcaseId);\r\n const rc = stmt.step();\r\n if (rc !== DbResult.BE_SQLITE_DONE)\r\n throw new IModelError(rc, \"can't remove shared lock\");\r\n });\r\n }\r\n\r\n private abandonLock(props: LockProps, briefcase: BriefcaseIdArg) {\r\n // When abandoning (but not when releasing), props.state indicates which\r\n // state we're abandoning _to_. Specifically, an Exclusive lock can be\r\n // abandoned to either Shared or None.\r\n\r\n // It makes no sense to abandon a lock _to_ the Exclusive state.\r\n if (props.state === LockState.Exclusive)\r\n throw new IModelError(IModelHubStatus.InvalidArgumentError, \"must specify Shared or None when abandoning a lock\");\r\n\r\n const lockId = props.id;\r\n const previousLockStatus = this.queryLockStatus(lockId);\r\n switch (previousLockStatus.state) {\r\n case LockState.None:\r\n throw new IModelError(IModelHubStatus.LockDoesNotExist, \"lock not held\");\r\n\r\n case LockState.Exclusive:\r\n if (previousLockStatus.briefcaseId !== briefcase.briefcaseId)\r\n throw new IModelError(IModelHubStatus.LockOwnedByAnotherBriefcase, \"lock not held by this briefcase\");\r\n if (props.state === LockState.Shared) {\r\n // Exclusive -> Shared\r\n this.downgradeExclusiveLockToShared(lockId, briefcase.briefcaseId);\r\n } else {\r\n // Exclusive -> None\r\n this.clearLock(lockId);\r\n }\r\n break;\r\n\r\n case LockState.Shared:\r\n if (!previousLockStatus.sharedBy.has(briefcase.briefcaseId))\r\n throw new IModelError(IModelHubStatus.LockDoesNotExist, \"shared lock not held by this briefcase\");\r\n this.removeSharedLock(lockId, briefcase.briefcaseId);\r\n if (previousLockStatus.sharedBy.size === 1)\r\n this.clearLock(lockId);\r\n }\r\n }\r\n\r\n private releaseLock(props: LockProps, briefcase: { briefcaseId: BriefcaseId, changesetIndex: ChangesetIndex }) {\r\n // Unlike abandonLock above, release always releases the lock all the way back to the None state.\r\n // So we ignore props.state. There's no such thing as a \"downgrade\" here.\r\n\r\n const lockId = props.id;\r\n const previousLockStatus = this.queryLockStatus(lockId);\r\n switch (previousLockStatus.state) {\r\n case LockState.None:\r\n throw new IModelError(IModelHubStatus.LockDoesNotExist, \"lock not held\");\r\n\r\n case LockState.Exclusive:\r\n if (previousLockStatus.briefcaseId !== briefcase.briefcaseId)\r\n throw new IModelError(IModelHubStatus.LockOwnedByAnotherBriefcase, \"lock not held by this briefcase\");\r\n this.updateLockExclusiveChangeset(lockId, briefcase.changesetIndex);\r\n this.clearLock(lockId);\r\n break;\r\n\r\n case LockState.Shared:\r\n if (!previousLockStatus.sharedBy.has(briefcase.briefcaseId))\r\n throw new IModelError(IModelHubStatus.LockDoesNotExist, \"shared lock not held by this briefcase\");\r\n this.updateLockSharedChangeset(lockId, briefcase.changesetIndex);\r\n this.removeSharedLock(lockId, briefcase.briefcaseId);\r\n if (previousLockStatus.sharedBy.size === 1)\r\n this.clearLock(lockId);\r\n }\r\n }\r\n\r\n /** Acquire a set of locks. If any lock cannot be acquired, no locks are acquired */\r\n public acquireLocks(locks: LockMap, briefcase: BriefcaseIdAndChangeset) {\r\n try {\r\n for (const lock of locks)\r\n this.requestLock({ id: lock[0], state: lock[1] }, briefcase);\r\n this.db.saveChanges(); // only after all locks have been acquired\r\n } catch (err) {\r\n this.db.abandonChanges(); // abandon all locks that may have been acquired\r\n throw err;\r\n }\r\n }\r\n\r\n public acquireLock(props: LockProps, briefcase: BriefcaseIdAndChangeset) {\r\n const locks = new Map<Id64String, LockState>();\r\n locks.set(props.id, props.state);\r\n this.acquireLocks(locks, briefcase);\r\n }\r\n\r\n public releaseLocks(locks: LockProps[], arg: { briefcaseId: BriefcaseId, changesetIndex: ChangesetIndex }) {\r\n for (const props of locks)\r\n this.releaseLock(props, arg);\r\n this.db.saveChanges();\r\n }\r\n\r\n public abandonLocks(locks: LockMap, arg: BriefcaseIdArg) {\r\n for (const props of locks)\r\n this.abandonLock({ id: props[0], state: props[1] }, arg);\r\n this.db.saveChanges();\r\n }\r\n\r\n public releaseAllLocks(arg: { briefcaseId: BriefcaseId, changesetIndex: ChangesetIndex }) {\r\n const locks = this.queryAllLocks(arg.briefcaseId);\r\n this.releaseLocks(locks, arg);\r\n }\r\n\r\n public abandonAllLocks(arg: BriefcaseIdArg) {\r\n const locks = new Map<Id64String, LockState>();\r\n this.queryAllLocks(arg.briefcaseId).forEach(lock => locks.set(lock.id, LockState.None));\r\n this.abandonLocks(locks, arg);\r\n }\r\n\r\n private countTable(tableName: string): number {\r\n return this.db.withSqliteStatement(`SELECT count(*) from ${tableName}`, (stmt) => {\r\n stmt.step();\r\n return stmt.getValueInteger(0);\r\n });\r\n }\r\n\r\n // for debugging\r\n public countSharedLocks(): number { return this.countTable(\"sharedLocks\"); }\r\n // for debugging\r\n public countLocks(): number { return this.countTable(\"locks\"); }\r\n\r\n // for debugging\r\n public queryAllSharedLocks(): { id: Id64String, briefcaseId: BriefcaseId }[] {\r\n const locks: { id: Id64String, briefcaseId: BriefcaseId }[] = [];\r\n this.db.withPreparedSqliteStatement(\"SELECT lockId,briefcaseId FROM sharedLocks\", (stmt) => {\r\n while (DbResult.BE_SQLITE_ROW === stmt.step())\r\n locks.push({ id: stmt.getValueId(0), briefcaseId: stmt.getValueInteger(1) });\r\n });\r\n return locks;\r\n }\r\n\r\n // for debugging\r\n public queryLocks(): LocksEntry[] {\r\n const locks: LocksEntry[] = [];\r\n this.db.withPreparedSqliteStatement(\"SELECT id,level,lastExclusiveReleaseChangesetIndex,lastSharedReleaseChangesetIndex,briefcaseId FROM locks\", (stmt) => {\r\n while (DbResult.BE_SQLITE_ROW === stmt.step())\r\n locks.push({\r\n id: stmt.getValueId(0),\r\n level: stmt.getValueInteger(1),\r\n lastExclusiveReleaseChangesetIndex: stmt.getValue(2).isNull ? undefined : stmt.getValueInteger(2),\r\n lastSharedReleaseChangesetIndex: stmt.getValue(3).isNull ? undefined : stmt.getValueInteger(3),\r\n briefcaseId: stmt.getValue(4).isNull ? undefined : stmt.getValueInteger(4),\r\n });\r\n });\r\n return locks;\r\n }\r\n\r\n public removeDir(dirName: string) {\r\n if (IModelJsFs.existsSync(dirName)) {\r\n IModelJsFs.purgeDirSync(dirName);\r\n IModelJsFs.rmdirSync(dirName);\r\n }\r\n\r\n }\r\n public cleanup() {\r\n if (this._hubDb) {\r\n this._hubDb.closeDb();\r\n this._hubDb = undefined;\r\n }\r\n try {\r\n this.removeDir(BriefcaseManager.getIModelPath(this.iModelId));\r\n this.removeDir(this.rootDir);\r\n } catch {\r\n // eslint-disable-next-line no-console\r\n console.log(`ERROR: test left an iModel open for [${this.iModelName}]. LocalMock cannot clean up - make sure you call imodel.close() in your test`);\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"LocalHub.js","sourceRoot":"","sources":["../../src/LocalHub.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { join } from \"path\";\r\nimport { assert, DbResult, GuidString, Id64String, IModelHubStatus, IModelStatus, OpenMode } from \"@itwin/core-bentley\";\r\nimport {\r\n BriefcaseId, BriefcaseIdValue, ChangesetFileProps, ChangesetId, ChangesetIdWithIndex, ChangesetIndex, ChangesetIndexOrId, ChangesetProps,\r\n ChangesetRange, IModelError, LocalDirName, LocalFileName, LockState,\r\n} from \"@itwin/core-common\";\r\nimport { BriefcaseIdArg, LockConflict, LockMap, LockProps } from \"./BackendHubAccess\";\r\nimport { BriefcaseManager } from \"./BriefcaseManager\";\r\nimport { BriefcaseLocalValue, IModelDb, SnapshotDb } from \"./IModelDb\";\r\nimport { IModelJsFs } from \"./IModelJsFs\";\r\nimport { SQLiteDb } from \"./SQLiteDb\";\r\n\r\n// cspell:ignore rowid\r\n\r\n/** @internal */\r\ninterface MockBriefcaseIdProps {\r\n id: BriefcaseId;\r\n user: string; // Just an AccessToken that simulates a user\r\n alias: string;\r\n assigned: boolean;\r\n}\r\n\r\n/** @internal */\r\ninterface LocalHubProps {\r\n readonly iTwinId: GuidString;\r\n readonly iModelId: GuidString;\r\n readonly iModelName: string;\r\n readonly description?: string;\r\n readonly version0?: string;\r\n readonly noLocks?: true;\r\n}\r\n\r\ninterface LockLastReleaseChangesetIndices {\r\n lastExclusiveReleaseChangesetIndex?: ChangesetIndex;\r\n lastSharedReleaseChangesetIndex?: ChangesetIndex;\r\n}\r\n\r\ninterface LocksEntry extends LockLastReleaseChangesetIndices {\r\n id: Id64String;\r\n level: LockState;\r\n briefcaseId?: BriefcaseId;\r\n}\r\n\r\ninterface LockStatusNone extends LockLastReleaseChangesetIndices {\r\n state: LockState.None;\r\n}\r\n\r\n/** @internal exported for tests. */\r\nexport interface LockStatusExclusive extends LockLastReleaseChangesetIndices {\r\n state: LockState.Exclusive;\r\n briefcaseId: BriefcaseId;\r\n}\r\n\r\n/** @internal exported for tests. */\r\nexport interface LockStatusShared extends LockLastReleaseChangesetIndices {\r\n state: LockState.Shared;\r\n sharedBy: Set<BriefcaseId>;\r\n}\r\n\r\ninterface BriefcaseIdAndChangeset {\r\n changeset: ChangesetIdWithIndex;\r\n briefcaseId: BriefcaseId;\r\n}\r\n\r\ntype LockStatus = LockStatusNone | LockStatusExclusive | LockStatusShared;\r\n\r\n/**\r\n * A \"local\" mock for IModelHub to provide access to a single iModel. Used by HubMock.\r\n * @internal\r\n */\r\nexport class LocalHub {\r\n public readonly iTwinId: GuidString;\r\n public readonly iModelId: GuidString;\r\n public readonly iModelName: string;\r\n public readonly description?: string;\r\n private _hubDb?: SQLiteDb;\r\n private _nextBriefcaseId = BriefcaseIdValue.FirstValid;\r\n private _latestChangesetIndex = 0;\r\n public get latestChangesetIndex() { return this._latestChangesetIndex; }\r\n\r\n public constructor(public readonly rootDir: LocalDirName, arg: LocalHubProps) {\r\n this.iTwinId = arg.iTwinId;\r\n this.iModelId = arg.iModelId;\r\n this.iModelName = arg.iModelName;\r\n this.description = arg.description;\r\n\r\n this.cleanup();\r\n\r\n IModelJsFs.recursiveMkDirSync(this.rootDir);\r\n IModelJsFs.mkdirSync(this.changesetDir);\r\n IModelJsFs.mkdirSync(this.checkpointDir);\r\n\r\n const db = this._hubDb = new SQLiteDb();\r\n db.createDb(this.mockDbName);\r\n db.executeSQL(\"CREATE TABLE briefcases(id INTEGER PRIMARY KEY NOT NULL,user TEXT NOT NULL,alias TEXT NOT NULL,assigned INTEGER DEFAULT 1)\");\r\n db.executeSQL(\"CREATE TABLE timeline(csIndex INTEGER PRIMARY KEY NOT NULL,csId TEXT NOT NULL UNIQUE,description TEXT,user TEXT,size BIGINT,type INTEGER,pushDate TEXT,briefcaseId INTEGER,uncompressedSize BIGINT,\\\r\n FOREIGN KEY(briefcaseId) REFERENCES briefcases(id))\");\r\n db.executeSQL(\"CREATE TABLE checkpoints(csIndex INTEGER PRIMARY KEY NOT NULL)\");\r\n db.executeSQL(\"CREATE TABLE versions(name TEXT PRIMARY KEY NOT NULL,csIndex TEXT,FOREIGN KEY(csIndex) REFERENCES timeline(csIndex))\");\r\n db.executeSQL(\"CREATE TABLE locks(id INTEGER PRIMARY KEY NOT NULL,level INTEGER NOT NULL,lastExclusiveReleaseChangesetIndex INTEGER,lastSharedReleaseChangesetIndex INTEGER,briefcaseId INTEGER)\");\r\n db.executeSQL(\"CREATE TABLE sharedLocks(lockId INTEGER NOT NULL,briefcaseId INTEGER NOT NULL,PRIMARY KEY(lockId,briefcaseId))\");\r\n db.executeSQL(\"CREATE INDEX LockIdx ON locks(briefcaseId)\");\r\n db.executeSQL(\"CREATE INDEX SharedLockIdx ON sharedLocks(briefcaseId)\");\r\n db.saveChanges();\r\n\r\n const version0Root = `${rootDir}_version0`;\r\n const version0 = arg.version0 ?? join(version0Root, \"version0.bim\");\r\n\r\n if (!arg.version0) { // if they didn't supply a version0 file, create a blank one.\r\n IModelJsFs.recursiveMkDirSync(version0Root);\r\n IModelJsFs.removeSync(version0);\r\n SnapshotDb.createEmpty(version0, { rootSubject: { name: arg.description ?? arg.iModelName } }).close();\r\n }\r\n\r\n const path = this.uploadCheckpoint({ changesetIndex: 0, localFile: version0 });\r\n if (!arg.version0)\r\n IModelJsFs.removeSync(version0);\r\n\r\n const nativeDb = IModelDb.openDgnDb({ path }, OpenMode.ReadWrite);\r\n try {\r\n nativeDb.setITwinId(this.iTwinId);\r\n nativeDb.setIModelId(this.iModelId);\r\n nativeDb.saveChanges();\r\n nativeDb.deleteAllTxns(); // necessary before resetting briefcaseId\r\n nativeDb.resetBriefcaseId(BriefcaseIdValue.Unassigned);\r\n nativeDb.saveLocalValue(BriefcaseLocalValue.NoLocking, arg.noLocks ? \"true\" : undefined);\r\n nativeDb.saveChanges();\r\n } finally {\r\n nativeDb.closeFile();\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\r\n private get db(): SQLiteDb { return this._hubDb!; } // eslint-disable-line @typescript-eslint/naming-convention\r\n public get changesetDir() { return join(this.rootDir, \"changesets\"); }\r\n public get checkpointDir() { return join(this.rootDir, \"checkpoints\"); }\r\n public get mockDbName() { return join(this.rootDir, \"localHub.db\"); }\r\n\r\n /** Acquire the next available briefcaseId and assign it to the supplied user */\r\n public acquireNewBriefcaseId(user: string, alias?: string): BriefcaseId {\r\n const db = this.db;\r\n const newId = this._nextBriefcaseId++;\r\n db.withSqliteStatement(\"INSERT INTO briefcases(id,user,alias) VALUES (?,?,?)\", (stmt) => {\r\n stmt.bindInteger(1, newId);\r\n stmt.bindString(2, user);\r\n stmt.bindString(3, alias ?? `${user} (${newId})`);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_DONE !== rc)\r\n throw new IModelError(rc, \"can't insert briefcaseId in mock database\");\r\n });\r\n db.saveChanges();\r\n return newId;\r\n }\r\n\r\n /** Release a briefcaseId */\r\n public releaseBriefcaseId(id: BriefcaseId) {\r\n const db = this.db;\r\n this.releaseAllLocks({ briefcaseId: id, changesetIndex: 0 });\r\n db.withSqliteStatement(\"UPDATE briefcases SET assigned=0 WHERE id=?\", (stmt) => {\r\n stmt.bindInteger(1, id);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_DONE !== rc)\r\n throw new IModelError(rc, `briefcaseId ${id} was not reserved`);\r\n });\r\n db.saveChanges();\r\n }\r\n\r\n /** Get an array of all of the currently assigned Briefcases */\r\n public getBriefcases(onlyAssigned = true): MockBriefcaseIdProps[] {\r\n const briefcases: MockBriefcaseIdProps[] = [];\r\n let sql = \"SELECT id,user,alias,assigned FROM briefcases\";\r\n if (onlyAssigned)\r\n sql += \" WHERE assigned=1\";\r\n\r\n this.db.withSqliteStatement(sql, (stmt) => {\r\n while (DbResult.BE_SQLITE_ROW === stmt.step()) {\r\n briefcases.push({\r\n id: stmt.getValueInteger(0),\r\n user: stmt.getValueString(1),\r\n alias: stmt.getValueString(2),\r\n assigned: stmt.getValueInteger(3) !== 0,\r\n });\r\n }\r\n });\r\n return briefcases;\r\n }\r\n\r\n /** Get an array of all of the currently assigned BriefcaseIds for a user */\r\n public getBriefcaseIds(user: string): BriefcaseId[] {\r\n const briefcases: BriefcaseId[] = [];\r\n this.db.withSqliteStatement(\"SELECT id FROM briefcases WHERE user=? AND assigned=1\", (stmt) => {\r\n stmt.bindString(1, user);\r\n while (DbResult.BE_SQLITE_ROW === stmt.step())\r\n briefcases.push(stmt.getValueInteger(0));\r\n });\r\n return briefcases;\r\n }\r\n\r\n public getBriefcase(id: BriefcaseId): MockBriefcaseIdProps {\r\n return this.db.withSqliteStatement(\"SELECT user,alias,assigned FROM briefcases WHERE id=?\", (stmt) => {\r\n stmt.bindInteger(1, id);\r\n if (DbResult.BE_SQLITE_ROW !== stmt.step())\r\n throw new IModelError(IModelStatus.NotFound, \"no briefcase with that id\");\r\n return { id, user: stmt.getValueString(0), alias: stmt.getValueString(1), assigned: stmt.getValueInteger(2) !== 0 };\r\n });\r\n }\r\n\r\n private getChangesetFileName(index: ChangesetIndex) {\r\n return join(this.changesetDir, `changeset-${index}`);\r\n }\r\n\r\n /** Add a changeset to the timeline\r\n * @return the changesetIndex of the added changeset\r\n */\r\n public addChangeset(changeset: ChangesetFileProps): ChangesetIndex {\r\n const stats = IModelJsFs.lstatSync(changeset.pathname);\r\n if (!stats)\r\n throw new Error(`cannot read changeset file ${changeset.pathname}`);\r\n\r\n const parentIndex = this.getChangesetById(changeset.parentId).index;\r\n if (parentIndex !== this.latestChangesetIndex)\r\n throw new IModelError(IModelStatus.InvalidParent, \"changeset parent is not latest changeset\");\r\n\r\n this.getBriefcase(changeset.briefcaseId); // throws if invalid id\r\n const db = this.db;\r\n changeset.index = this._latestChangesetIndex + 1;\r\n db.withSqliteStatement(\"INSERT INTO timeline(csIndex,csId,description,size,type,pushDate,user,briefcaseId,uncompressedSize) VALUES (?,?,?,?,?,?,?,?,?)\", (stmt) => {\r\n stmt.bindInteger(1, changeset.index);\r\n stmt.bindString(2, changeset.id);\r\n stmt.bindString(3, changeset.description);\r\n stmt.bindInteger(4, stats.size);\r\n stmt.bindInteger(5, changeset.changesType ?? 0);\r\n stmt.bindString(6, changeset.pushDate ?? new Date().toISOString());\r\n stmt.bindString(7, changeset.userCreated ?? \"\");\r\n stmt.bindInteger(8, changeset.briefcaseId);\r\n stmt.bindInteger(9, changeset.uncompressedSize ?? 0);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_DONE !== rc)\r\n throw new IModelError(rc, \"can't insert changeset into mock db\");\r\n });\r\n this._latestChangesetIndex = changeset.index; // only change this after insert succeeds\r\n db.saveChanges();\r\n IModelJsFs.copySync(changeset.pathname, this.getChangesetFileName(changeset.index));\r\n return changeset.index;\r\n }\r\n\r\n public getIndexFromChangeset(changeset: ChangesetIndexOrId): ChangesetIndex {\r\n return changeset.index ?? this.getChangesetIndex(changeset.id);\r\n }\r\n\r\n /** Get the index of a changeset by its Id */\r\n public getChangesetIndex(id: ChangesetId): ChangesetIndex {\r\n if (id === \"\")\r\n return 0;\r\n\r\n return this.db.withPreparedSqliteStatement(\"SELECT csIndex FROM timeline WHERE csId=?\", (stmt) => {\r\n stmt.bindString(1, id);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_ROW !== rc)\r\n throw new IModelError(rc, `changeset ${id} not found`);\r\n\r\n return stmt.getValueInteger(0);\r\n });\r\n }\r\n\r\n /** Get the properties of a changeset by its Id */\r\n public getChangesetById(id: ChangesetId): ChangesetProps {\r\n return this.getChangesetByIndex(this.getChangesetIndex(id));\r\n }\r\n\r\n public getPreviousIndex(index: ChangesetIndex) {\r\n return this.db.withPreparedSqliteStatement(\"SELECT max(csIndex) FROM timeline WHERE csIndex<?\", (stmt) => {\r\n stmt.bindInteger(1, index);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_ROW !== rc)\r\n throw new IModelError(rc, `cannot get previous index`);\r\n\r\n return stmt.getValueInteger(0);\r\n });\r\n }\r\n\r\n public getParentId(index: ChangesetIndex): ChangesetId {\r\n if (index === 0)\r\n return \"\";\r\n\r\n return this.db.withPreparedSqliteStatement(\"SELECT csId FROM timeline WHERE csIndex=?\", (stmt) => {\r\n stmt.bindInteger(1, this.getPreviousIndex(index));\r\n stmt.step();\r\n return stmt.getValueString(0);\r\n });\r\n }\r\n\r\n /** Get the properties of a changeset by its index */\r\n public getChangesetByIndex(index: ChangesetIndex): ChangesetProps {\r\n if (index <= 0)\r\n return { id: \"\", changesType: 0, description: \"version0\", parentId: \"\", briefcaseId: 0, pushDate: \"\", userCreated: \"\", index: 0, size: 0, uncompressedSize: 0 };\r\n\r\n return this.db.withPreparedSqliteStatement(\"SELECT description,size,type,pushDate,user,csId,briefcaseId,uncompressedSize FROM timeline WHERE csIndex=?\", (stmt) => {\r\n stmt.bindInteger(1, index);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_ROW !== rc)\r\n throw new IModelError(rc, `changeset at index ${index} not found`);\r\n\r\n return {\r\n description: stmt.getValueString(0),\r\n size: stmt.getValueDouble(1),\r\n changesType: stmt.getValueInteger(2),\r\n pushDate: stmt.getValueString(3),\r\n userCreated: stmt.getValueString(4),\r\n id: stmt.getValueString(5),\r\n briefcaseId: stmt.getValueInteger(6),\r\n index,\r\n parentId: this.getParentId(index),\r\n uncompressedSize: stmt.getValueInteger(7),\r\n };\r\n });\r\n }\r\n\r\n public getLatestChangeset(): ChangesetProps {\r\n return this.getChangesetByIndex(this.latestChangesetIndex);\r\n }\r\n\r\n public getChangesetId(index: ChangesetIndex): ChangesetId {\r\n return this.getChangesetByIndex(index).id;\r\n }\r\n\r\n /** Get an array of changesets starting with first to last, by index */\r\n public queryChangesets(range?: ChangesetRange): ChangesetProps[] {\r\n const changesets: ChangesetProps[] = [];\r\n const first = range?.first ?? 0;\r\n const last = range?.end ?? this.latestChangesetIndex;\r\n\r\n this.db.withPreparedSqliteStatement(\"SELECT csIndex FROM timeline WHERE csIndex>=? AND csIndex<=? ORDER BY csIndex\", (stmt) => {\r\n stmt.bindInteger(1, first);\r\n stmt.bindInteger(2, last);\r\n while (DbResult.BE_SQLITE_ROW === stmt.step())\r\n changesets.push(this.getChangesetByIndex(stmt.getValueInteger(0)));\r\n });\r\n return changesets;\r\n }\r\n\r\n /** Name a version */\r\n public addNamedVersion(arg: { versionName: string, csIndex: ChangesetIndex }) {\r\n const db = this.db;\r\n db.withSqliteStatement(\"INSERT INTO versions(name,csIndex) VALUES (?,?)\", (stmt) => {\r\n stmt.bindString(1, arg.versionName);\r\n stmt.bindInteger(2, arg.csIndex);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_DONE !== rc)\r\n throw new IModelError(rc, \"can't insert named version\");\r\n });\r\n db.saveChanges();\r\n }\r\n\r\n /** Delete a named version */\r\n public deleteNamedVersion(versionName: string) {\r\n const db = this.db;\r\n db.withSqliteStatement(\"DELETE FROM versions WHERE name=?\", (stmt) => {\r\n stmt.bindString(1, versionName);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_DONE !== rc)\r\n throw new IModelError(rc, \"can't delete named version\");\r\n });\r\n db.saveChanges();\r\n }\r\n\r\n /** find the changeset for a named version */\r\n public findNamedVersion(versionName: string): ChangesetProps {\r\n const index = this.db.withSqliteStatement(\"SELECT csIndex FROM versions WHERE name=?\", (stmt) => {\r\n stmt.bindString(1, versionName);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_ROW !== rc)\r\n throw new IModelError(IModelStatus.NotFound, `Named version ${versionName} not found`);\r\n return stmt.getValueInteger(0);\r\n });\r\n return this.getChangesetByIndex(index);\r\n }\r\n\r\n public checkpointNameFromIndex(csIndex: ChangesetIndex) {\r\n return `checkpoint-${csIndex}`;\r\n }\r\n\r\n /** \"upload\" a checkpoint */\r\n public uploadCheckpoint(arg: { changesetIndex: ChangesetIndex, localFile: LocalFileName }) {\r\n const db = this.db;\r\n db.withSqliteStatement(\"INSERT INTO checkpoints(csIndex) VALUES (?)\", (stmt) => {\r\n stmt.bindInteger(1, arg.changesetIndex);\r\n const res = stmt.step();\r\n if (DbResult.BE_SQLITE_DONE !== res)\r\n throw new IModelError(res, \"can't insert checkpoint into mock db\");\r\n });\r\n db.saveChanges();\r\n const outName = join(this.checkpointDir, this.checkpointNameFromIndex(arg.changesetIndex));\r\n IModelJsFs.copySync(arg.localFile, outName);\r\n return outName;\r\n }\r\n\r\n /** Get an array of the indexes for a range of checkpoints */\r\n public getCheckpoints(range?: ChangesetRange): ChangesetIndex[] {\r\n const first = range?.first ?? 0;\r\n const last = range?.end ?? this.latestChangesetIndex;\r\n\r\n const checkpoints: ChangesetIndex[] = [];\r\n this.db.withSqliteStatement(\"SELECT csIndex FROM checkpoints WHERE csIndex>=? AND csIndex<=? ORDER BY csIndex\", (stmt) => {\r\n stmt.bindInteger(1, first);\r\n stmt.bindInteger(2, last);\r\n while (DbResult.BE_SQLITE_ROW === stmt.step())\r\n checkpoints.push(stmt.getValueInteger(0));\r\n\r\n });\r\n return checkpoints;\r\n }\r\n\r\n /** Find the checkpoint that is no newer than a changesetIndex */\r\n public queryPreviousCheckpoint(changesetIndex: ChangesetIndex): ChangesetIndex {\r\n if (changesetIndex <= 0)\r\n return 0;\r\n\r\n return this.db.withSqliteStatement(\"SELECT max(csIndex) FROM checkpoints WHERE csIndex <= ? \", (stmt) => {\r\n stmt.bindInteger(1, changesetIndex);\r\n const res = stmt.step();\r\n if (DbResult.BE_SQLITE_ROW !== res)\r\n throw new IModelError(res, \"can't get previous checkpoint\");\r\n return stmt.getValueInteger(0);\r\n });\r\n }\r\n\r\n /**\r\n * Find the checkpoint nearest to `changesetIndex` (searching both backward and forward).\r\n * When the previous and next checkpoints are equidistant, the newer (next) checkpoint is preferred,\r\n * which enables the tip-then-reverse download path in [[V2CheckpointManager]].\r\n */\r\n public queryNearestCheckpoint(changesetIndex: ChangesetIndex): ChangesetIndex {\r\n const prev = this.queryPreviousCheckpoint(changesetIndex); // always ≥ 0; returns 0 when none found\r\n\r\n const next: ChangesetIndex | undefined = this.db.withSqliteStatement(\r\n \"SELECT min(csIndex) FROM checkpoints WHERE csIndex >= ?\",\r\n (stmt) => {\r\n stmt.bindInteger(1, changesetIndex);\r\n stmt.step();\r\n const val = stmt.getValue(0);\r\n return val.isNull ? undefined : val.getInteger();\r\n }\r\n );\r\n\r\n if (next === undefined) return prev; // no checkpoint at or after requested index\r\n if (next === prev) return prev; // exact match\r\n\r\n // Prefer the newer (next) checkpoint when equidistant so that CheckpointManager\r\n // will reverse from a tip checkpoint rather than apply from an old seed.\r\n const distPrev = changesetIndex - prev;\r\n const distNext = next - changesetIndex;\r\n return distNext <= distPrev ? next : prev;\r\n }\r\n\r\n /** \"download\" a checkpoint */\r\n public downloadCheckpoint(arg: { changeset: ChangesetIndexOrId, targetFile: LocalFileName }) {\r\n const index = this.getIndexFromChangeset(arg.changeset);\r\n const prev = this.queryPreviousCheckpoint(index);\r\n IModelJsFs.copySync(join(this.checkpointDir, this.checkpointNameFromIndex(prev)), arg.targetFile);\r\n const changeset = this.getChangesetByIndex(index);\r\n return { index, id: changeset.id };\r\n }\r\n\r\n private copyChangeset(arg: ChangesetFileProps): ChangesetFileProps {\r\n IModelJsFs.copySync(this.getChangesetFileName(arg.index), arg.pathname);\r\n return arg;\r\n }\r\n\r\n /** \"download\" a changeset */\r\n public downloadChangeset(arg: { index: ChangesetIndex, targetDir: LocalDirName }) {\r\n const cs = this.getChangesetByIndex(arg.index);\r\n const csProps = { ...cs, pathname: join(arg.targetDir, cs.id), index: arg.index };\r\n return this.copyChangeset(csProps);\r\n }\r\n\r\n /** \"download\" all the changesets in a given range */\r\n public downloadChangesets(arg: { range?: ChangesetRange, targetDir: LocalDirName }): ChangesetFileProps[] {\r\n const cSets = this.queryChangesets(arg.range) as ChangesetFileProps[];\r\n for (const cs of cSets) {\r\n cs.pathname = join(arg.targetDir, cs.id);\r\n this.copyChangeset(cs);\r\n }\r\n return cSets;\r\n }\r\n\r\n private querySharedLockHolders(elementId: Id64String) {\r\n return this.db.withPreparedSqliteStatement(\"SELECT briefcaseId FROM sharedLocks WHERE lockId=?\", (stmt) => {\r\n stmt.bindId(1, elementId);\r\n const briefcases = new Set<BriefcaseId>();\r\n while (DbResult.BE_SQLITE_ROW === stmt.step())\r\n briefcases.add(stmt.getValueInteger(0));\r\n return briefcases;\r\n });\r\n }\r\n\r\n public queryAllLocks(briefcaseId: BriefcaseId) {\r\n this.getBriefcase(briefcaseId); // throws if briefcaseId invalid.\r\n const locks: LockProps[] = [];\r\n this.db.withPreparedSqliteStatement(\"SELECT id FROM locks WHERE briefcaseId=?\", (stmt) => {\r\n stmt.bindInteger(1, briefcaseId);\r\n while (DbResult.BE_SQLITE_ROW === stmt.step())\r\n locks.push({ id: stmt.getValueId(0), state: LockState.Exclusive });\r\n });\r\n this.db.withPreparedSqliteStatement(\"SELECT lockId FROM sharedLocks WHERE briefcaseId=?\", (stmt) => {\r\n stmt.bindInteger(1, briefcaseId);\r\n while (DbResult.BE_SQLITE_ROW === stmt.step())\r\n locks.push({ id: stmt.getValueId(0), state: LockState.Shared });\r\n });\r\n return locks;\r\n }\r\n\r\n public queryLockStatus(elementId: Id64String): LockStatus {\r\n return this.db.withPreparedSqliteStatement(\"SELECT lastSharedReleaseChangesetIndex,lastExclusiveReleaseChangesetIndex,level,briefcaseId FROM locks WHERE id=?\", (stmt) => {\r\n stmt.bindId(1, elementId);\r\n const rc = stmt.step();\r\n if (DbResult.BE_SQLITE_ROW !== rc)\r\n return { state: LockState.None };\r\n const lastSharedCsVal = stmt.getValue(0);\r\n const lastExclusiveCsVal = stmt.getValue(1);\r\n const lock = {\r\n lastSharedReleaseChangesetIndex: lastSharedCsVal.isNull ? undefined : lastSharedCsVal.getInteger(),\r\n lastExclusiveReleaseChangesetIndex: lastExclusiveCsVal.isNull ? undefined : lastExclusiveCsVal.getInteger(),\r\n state: stmt.getValueInteger(2),\r\n };\r\n switch (lock.state) {\r\n case LockState.None:\r\n return lock;\r\n case LockState.Exclusive:\r\n return { ...lock, briefcaseId: stmt.getValueInteger(3) };\r\n case LockState.Shared:\r\n return { ...lock, sharedBy: this.querySharedLockHolders(elementId) };\r\n default:\r\n throw new Error(\"illegal lock state\");\r\n }\r\n });\r\n }\r\n\r\n private doesBriefcaseRequirePullBeforeLock(currStatus: LockStatus, props: LockProps, briefcase: BriefcaseIdAndChangeset): boolean {\r\n if (props.state === LockState.None)\r\n return false;\r\n\r\n const briefcaseChangesetIndex = this.getIndexFromChangeset(briefcase.changeset);\r\n const exclusiveIndexIsNewer = currStatus.lastExclusiveReleaseChangesetIndex !== undefined &&\r\n currStatus.lastExclusiveReleaseChangesetIndex > briefcaseChangesetIndex;\r\n\r\n if (props.state === LockState.Shared) {\r\n // To acquire a shared lock, the briefcase must at least at the latest exclusive changeset index\r\n return exclusiveIndexIsNewer;\r\n } else {\r\n assert(props.state === LockState.Exclusive);\r\n\r\n const sharedIndexIsNewer = currStatus.lastSharedReleaseChangesetIndex !== undefined &&\r\n currStatus.lastSharedReleaseChangesetIndex > briefcaseChangesetIndex;\r\n\r\n // To acquire the exclusive lock the briefcase must be at least at the greater of the two last-indexes\r\n return exclusiveIndexIsNewer || sharedIndexIsNewer;\r\n }\r\n }\r\n\r\n private addSharedLockRecord(lockId: Id64String, briefcaseId: BriefcaseId) {\r\n this.db.withPreparedSqliteStatement(\"INSERT INTO sharedLocks(lockId,briefcaseId) VALUES(?,?) ON CONFLICT(lockId,briefcaseId) DO NOTHING\", (stmt) => {\r\n stmt.bindId(1, lockId);\r\n stmt.bindInteger(2, briefcaseId);\r\n const rc = stmt.step();\r\n if (rc !== DbResult.BE_SQLITE_DONE)\r\n throw new IModelError(rc, \"cannot insert shared lock\");\r\n });\r\n }\r\n\r\n private reserveLock(currStatus: LockStatus, props: LockProps, briefcase: BriefcaseIdAndChangeset) {\r\n if (this.doesBriefcaseRequirePullBeforeLock(currStatus, props, briefcase)) {\r\n throw new IModelError(IModelHubStatus.PullIsRequired, \"pull is required to obtain lock\");\r\n }\r\n\r\n const wantShared = props.state === LockState.Shared;\r\n if (wantShared && (currStatus.state === LockState.Exclusive))\r\n throw new Error(\"cannot acquire shared lock because an exclusive lock is already held\");\r\n\r\n this.db.withPreparedSqliteStatement(\"INSERT INTO locks(id,level,briefcaseId) VALUES(?,?,?) ON CONFLICT(id) DO UPDATE SET briefcaseId=excluded.briefcaseId,level=excluded.level\", (stmt) => {\r\n stmt.bindId(1, props.id);\r\n stmt.bindInteger(2, props.state);\r\n stmt.bindValue(3, wantShared ? undefined : briefcase.briefcaseId);\r\n const rc = stmt.step();\r\n if (rc !== DbResult.BE_SQLITE_DONE)\r\n throw new IModelError(rc, \"cannot insert lock\");\r\n });\r\n\r\n if (wantShared) {\r\n this.addSharedLockRecord(props.id, briefcase.briefcaseId);\r\n }\r\n }\r\n\r\n private downgradeExclusiveLockToShared(lockId: Id64String, briefcaseId: BriefcaseId) {\r\n this.db.withPreparedSqliteStatement(\"UPDATE locks SET level=1,briefcaseId=NULL WHERE id=? AND briefcaseId=? AND level=2\", (stmt) => {\r\n stmt.bindId(1, lockId);\r\n stmt.bindInteger(2, briefcaseId);\r\n const rc = stmt.step();\r\n if (rc !== DbResult.BE_SQLITE_DONE)\r\n throw new IModelError(rc, \"can't downgrade lock\");\r\n });\r\n\r\n // Verify that the above actually updated a row. If it didn't, something has gone wrong with the downgrade.\r\n // This shouldn't happen.\r\n this.db.withPreparedSqliteStatement(\"SELECT CHANGES()\", (stmt) => {\r\n stmt.step();\r\n if (stmt.getValueInteger(0) !== 1)\r\n throw new IModelError(IModelHubStatus.LockOwnedByAnotherBriefcase, \"lock not held by this briefcase or lock is not exclusive\");\r\n });\r\n\r\n this.addSharedLockRecord(lockId, briefcaseId);\r\n }\r\n\r\n private clearLock(id: Id64String) {\r\n this.db.withPreparedSqliteStatement(\"UPDATE locks SET level=0,briefcaseId=NULL WHERE id=?\", (stmt) => {\r\n stmt.bindId(1, id);\r\n const rc = stmt.step();\r\n if (rc !== DbResult.BE_SQLITE_DONE)\r\n throw new IModelError(rc, \"can't release lock\");\r\n });\r\n }\r\n\r\n private updateLockExclusiveChangeset(id: Id64String, index: ChangesetIndex) {\r\n if (index <= 0)\r\n return;\r\n\r\n this.db.withPreparedSqliteStatement(\"UPDATE locks SET lastExclusiveReleaseChangesetIndex=? WHERE id=?\", (stmt) => {\r\n stmt.bindInteger(1, index);\r\n stmt.bindId(2, id);\r\n const rc = stmt.step();\r\n if (rc !== DbResult.BE_SQLITE_DONE)\r\n throw new IModelError(rc, \"can't update lock exclusive changeSetId\");\r\n });\r\n }\r\n\r\n private updateLockSharedChangeset(id: Id64String, index: ChangesetIndex) {\r\n if (index <= 0)\r\n return;\r\n\r\n this.db.withPreparedSqliteStatement(\"UPDATE locks SET lastSharedReleaseChangesetIndex=? WHERE id=?\", (stmt) => {\r\n stmt.bindInteger(1, index);\r\n stmt.bindId(2, id);\r\n const rc = stmt.step();\r\n if (rc !== DbResult.BE_SQLITE_DONE)\r\n throw new IModelError(rc, \"can't update lock shared changeSetId\");\r\n });\r\n }\r\n\r\n private requestLock(props: LockProps, briefcase: BriefcaseIdAndChangeset) {\r\n if (props.state === LockState.None)\r\n throw new Error(\"cannot request lock for LockState.None\");\r\n\r\n this.getBriefcase(briefcase.briefcaseId); // throws if briefcaseId invalid.\r\n\r\n const lockStatus = this.queryLockStatus(props.id);\r\n switch (lockStatus.state) {\r\n case LockState.None:\r\n return this.reserveLock(lockStatus, props, briefcase);\r\n\r\n case LockState.Shared:\r\n if (props.state === LockState.Shared) {\r\n if (!lockStatus.sharedBy.has(briefcase.briefcaseId))\r\n this.reserveLock(lockStatus, props, briefcase);\r\n } else {\r\n // if requester is the only one holding a shared lock, \"upgrade\" the lock from shared to exclusive\r\n if (lockStatus.sharedBy.size > 1 || !lockStatus.sharedBy.has(briefcase.briefcaseId)) {\r\n const id = lockStatus.sharedBy.values().next().value!; // eslint-disable-line @typescript-eslint/no-non-null-assertion\r\n throw new LockConflict(id, this.getBriefcase(id).alias, \"shared lock is held\");\r\n }\r\n this.removeSharedLock(props.id, briefcase.briefcaseId);\r\n this.reserveLock(this.queryLockStatus(props.id), props, briefcase);\r\n }\r\n return;\r\n\r\n case LockState.Exclusive:\r\n if (lockStatus.briefcaseId !== briefcase.briefcaseId)\r\n throw new LockConflict(lockStatus.briefcaseId, this.getBriefcase(lockStatus.briefcaseId).alias, \"exclusive lock is already held\");\r\n }\r\n }\r\n\r\n private removeSharedLock(lockId: Id64String, briefcaseId: BriefcaseId) {\r\n this.db.withPreparedSqliteStatement(\"DELETE FROM sharedLocks WHERE lockId=? AND briefcaseId=?\", (stmt) => {\r\n stmt.bindId(1, lockId);\r\n stmt.bindInteger(2, briefcaseId);\r\n const rc = stmt.step();\r\n if (rc !== DbResult.BE_SQLITE_DONE)\r\n throw new IModelError(rc, \"can't remove shared lock\");\r\n });\r\n }\r\n\r\n private abandonLock(props: LockProps, briefcase: BriefcaseIdArg) {\r\n // When abandoning (but not when releasing), props.state indicates which\r\n // state we're abandoning _to_. Specifically, an Exclusive lock can be\r\n // abandoned to either Shared or None.\r\n\r\n // It makes no sense to abandon a lock _to_ the Exclusive state.\r\n if (props.state === LockState.Exclusive)\r\n throw new IModelError(IModelHubStatus.InvalidArgumentError, \"must specify Shared or None when abandoning a lock\");\r\n\r\n const lockId = props.id;\r\n const previousLockStatus = this.queryLockStatus(lockId);\r\n switch (previousLockStatus.state) {\r\n case LockState.None:\r\n throw new IModelError(IModelHubStatus.LockDoesNotExist, \"lock not held\");\r\n\r\n case LockState.Exclusive:\r\n if (previousLockStatus.briefcaseId !== briefcase.briefcaseId)\r\n throw new IModelError(IModelHubStatus.LockOwnedByAnotherBriefcase, \"lock not held by this briefcase\");\r\n if (props.state === LockState.Shared) {\r\n // Exclusive -> Shared\r\n this.downgradeExclusiveLockToShared(lockId, briefcase.briefcaseId);\r\n } else {\r\n // Exclusive -> None\r\n this.clearLock(lockId);\r\n }\r\n break;\r\n\r\n case LockState.Shared:\r\n if (!previousLockStatus.sharedBy.has(briefcase.briefcaseId))\r\n throw new IModelError(IModelHubStatus.LockDoesNotExist, \"shared lock not held by this briefcase\");\r\n this.removeSharedLock(lockId, briefcase.briefcaseId);\r\n if (previousLockStatus.sharedBy.size === 1)\r\n this.clearLock(lockId);\r\n }\r\n }\r\n\r\n private releaseLock(props: LockProps, briefcase: { briefcaseId: BriefcaseId, changesetIndex: ChangesetIndex }) {\r\n // Unlike abandonLock above, release always releases the lock all the way back to the None state.\r\n // So we ignore props.state. There's no such thing as a \"downgrade\" here.\r\n\r\n const lockId = props.id;\r\n const previousLockStatus = this.queryLockStatus(lockId);\r\n switch (previousLockStatus.state) {\r\n case LockState.None:\r\n throw new IModelError(IModelHubStatus.LockDoesNotExist, \"lock not held\");\r\n\r\n case LockState.Exclusive:\r\n if (previousLockStatus.briefcaseId !== briefcase.briefcaseId)\r\n throw new IModelError(IModelHubStatus.LockOwnedByAnotherBriefcase, \"lock not held by this briefcase\");\r\n this.updateLockExclusiveChangeset(lockId, briefcase.changesetIndex);\r\n this.clearLock(lockId);\r\n break;\r\n\r\n case LockState.Shared:\r\n if (!previousLockStatus.sharedBy.has(briefcase.briefcaseId))\r\n throw new IModelError(IModelHubStatus.LockDoesNotExist, \"shared lock not held by this briefcase\");\r\n this.updateLockSharedChangeset(lockId, briefcase.changesetIndex);\r\n this.removeSharedLock(lockId, briefcase.briefcaseId);\r\n if (previousLockStatus.sharedBy.size === 1)\r\n this.clearLock(lockId);\r\n }\r\n }\r\n\r\n /** Acquire a set of locks. If any lock cannot be acquired, no locks are acquired */\r\n public acquireLocks(locks: LockMap, briefcase: BriefcaseIdAndChangeset) {\r\n try {\r\n for (const lock of locks)\r\n this.requestLock({ id: lock[0], state: lock[1] }, briefcase);\r\n this.db.saveChanges(); // only after all locks have been acquired\r\n } catch (err) {\r\n this.db.abandonChanges(); // abandon all locks that may have been acquired\r\n throw err;\r\n }\r\n }\r\n\r\n public acquireLock(props: LockProps, briefcase: BriefcaseIdAndChangeset) {\r\n const locks = new Map<Id64String, LockState>();\r\n locks.set(props.id, props.state);\r\n this.acquireLocks(locks, briefcase);\r\n }\r\n\r\n public releaseLocks(locks: LockProps[], arg: { briefcaseId: BriefcaseId, changesetIndex: ChangesetIndex }) {\r\n for (const props of locks)\r\n this.releaseLock(props, arg);\r\n this.db.saveChanges();\r\n }\r\n\r\n public abandonLocks(locks: LockMap, arg: BriefcaseIdArg) {\r\n for (const props of locks)\r\n this.abandonLock({ id: props[0], state: props[1] }, arg);\r\n this.db.saveChanges();\r\n }\r\n\r\n public releaseAllLocks(arg: { briefcaseId: BriefcaseId, changesetIndex: ChangesetIndex }) {\r\n const locks = this.queryAllLocks(arg.briefcaseId);\r\n this.releaseLocks(locks, arg);\r\n }\r\n\r\n public abandonAllLocks(arg: BriefcaseIdArg) {\r\n const locks = new Map<Id64String, LockState>();\r\n this.queryAllLocks(arg.briefcaseId).forEach(lock => locks.set(lock.id, LockState.None));\r\n this.abandonLocks(locks, arg);\r\n }\r\n\r\n private countTable(tableName: string): number {\r\n return this.db.withSqliteStatement(`SELECT count(*) from ${tableName}`, (stmt) => {\r\n stmt.step();\r\n return stmt.getValueInteger(0);\r\n });\r\n }\r\n\r\n // for debugging\r\n public countSharedLocks(): number { return this.countTable(\"sharedLocks\"); }\r\n // for debugging\r\n public countLocks(): number { return this.countTable(\"locks\"); }\r\n\r\n // for debugging\r\n public queryAllSharedLocks(): { id: Id64String, briefcaseId: BriefcaseId }[] {\r\n const locks: { id: Id64String, briefcaseId: BriefcaseId }[] = [];\r\n this.db.withPreparedSqliteStatement(\"SELECT lockId,briefcaseId FROM sharedLocks\", (stmt) => {\r\n while (DbResult.BE_SQLITE_ROW === stmt.step())\r\n locks.push({ id: stmt.getValueId(0), briefcaseId: stmt.getValueInteger(1) });\r\n });\r\n return locks;\r\n }\r\n\r\n // for debugging\r\n public queryLocks(): LocksEntry[] {\r\n const locks: LocksEntry[] = [];\r\n this.db.withPreparedSqliteStatement(\"SELECT id,level,lastExclusiveReleaseChangesetIndex,lastSharedReleaseChangesetIndex,briefcaseId FROM locks\", (stmt) => {\r\n while (DbResult.BE_SQLITE_ROW === stmt.step())\r\n locks.push({\r\n id: stmt.getValueId(0),\r\n level: stmt.getValueInteger(1),\r\n lastExclusiveReleaseChangesetIndex: stmt.getValue(2).isNull ? undefined : stmt.getValueInteger(2),\r\n lastSharedReleaseChangesetIndex: stmt.getValue(3).isNull ? undefined : stmt.getValueInteger(3),\r\n briefcaseId: stmt.getValue(4).isNull ? undefined : stmt.getValueInteger(4),\r\n });\r\n });\r\n return locks;\r\n }\r\n\r\n public removeDir(dirName: string) {\r\n if (IModelJsFs.existsSync(dirName)) {\r\n IModelJsFs.purgeDirSync(dirName);\r\n IModelJsFs.rmdirSync(dirName);\r\n }\r\n\r\n }\r\n public cleanup() {\r\n if (this._hubDb) {\r\n this._hubDb.closeDb();\r\n this._hubDb = undefined;\r\n }\r\n try {\r\n this.removeDir(BriefcaseManager.getIModelPath(this.iModelId));\r\n this.removeDir(this.rootDir);\r\n } catch {\r\n // eslint-disable-next-line no-console\r\n console.log(`ERROR: test left an iModel open for [${this.iModelName}]. LocalMock cannot clean up - make sure you call imodel.close() in your test`);\r\n }\r\n }\r\n}\r\n"]}
@@ -35,11 +35,21 @@ import { LocalHub } from "../LocalHub";
35
35
  *
36
36
  * @internal
37
37
  */
38
+ /** Options for [[HubMock.startup]]. @internal */
39
+ export interface HubMockStartupOptions {
40
+ /**
41
+ * When `true`, every successful [[HubMock.pushChangeset]] call automatically uploads a V1 checkpoint
42
+ * (the current briefcase `.bim` file) for the tip changeset index into [[LocalHub]].
43
+ * This lets tests download a tip checkpoint and reverse changesets from it.
44
+ */
45
+ createTipCheckpointOnPush?: boolean;
46
+ }
38
47
  export declare class HubMock {
39
48
  private static mockRoot;
40
49
  private static hubs;
41
50
  private static _saveHubAccess;
42
51
  private static _iTwinId;
52
+ private static _createTipCheckpointOnPush;
43
53
  /** Determine whether a test us currently being run under HubMock */
44
54
  static get isValid(): boolean;
45
55
  static get iTwinId(): string;
@@ -48,7 +58,7 @@ export declare class HubMock {
48
58
  * @param mockName a unique name (e.g. "MyTest") for this HubMock to disambiguate tests when more than one is simultaneously active.
49
59
  * It is used to create a private directory used by the HubMock for a test. That directory is removed when [[shutdown]] is called.
50
60
  */
51
- static startup(mockName: LocalDirName, outputDir: string): void;
61
+ static startup(mockName: LocalDirName, outputDir: string, options?: HubMockStartupOptions): void;
52
62
  /** Stop a HubMock that was previously started with [[startup]]
53
63
  * @note this function throws an exception if any of the iModels used during the tests are left open.
54
64
  */
@@ -81,6 +91,19 @@ export declare class HubMock {
81
91
  static pushChangeset(arg: IModelIdArg & {
82
92
  changesetProps: ChangesetFileProps;
83
93
  }): Promise<ChangesetIndex>;
94
+ /**
95
+ * Build and upload a V1 checkpoint at the current tip changeset of the given iModel.
96
+ *
97
+ * The checkpoint is constructed by copying the nearest prior checkpoint from [[LocalHub]] as a
98
+ * starting base, then applying all subsequent changesets forward to the latest index via
99
+ * [[BriefcaseManager.pullAndApplyChangesets]]. The result is registered in [[LocalHub]] so that
100
+ * [[V2CheckpointManager]] (mock path) can serve it to consumers.
101
+ *
102
+ * When [[HubMockStartupOptions.createTipCheckpointOnPush]] is `true` this is called automatically
103
+ * after every successful [[pushChangeset]]. Tests can also call it explicitly to create a single
104
+ * checkpoint at the tip after all changesets have been pushed.
105
+ */
106
+ static createTipCheckpoint(iModelId: GuidString): Promise<void>;
84
107
  static queryV2Checkpoint(arg: CheckpointProps): Promise<V2CheckpointAccessProps | undefined>;
85
108
  static releaseAllLocks(arg: BriefcaseDbArg): Promise<void>;
86
109
  static abandonAllLocks(arg: BriefcaseIdArg): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"HubMock.d.ts","sourceRoot":"","sources":["../../../src/internal/HubMock.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"HubMock.d.ts","sourceRoot":"","sources":["../../../src/internal/HubMock.ts"],"names":[],"mappings":"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"}