@itwin/core-frontend 5.12.0-dev.8 → 5.13.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/lib/cjs/AccuDraw.d.ts.map +1 -1
  3. package/lib/cjs/AccuDraw.js +10 -9
  4. package/lib/cjs/AccuDraw.js.map +1 -1
  5. package/lib/cjs/AuxCoordSys.d.ts +11 -4
  6. package/lib/cjs/AuxCoordSys.d.ts.map +1 -1
  7. package/lib/cjs/AuxCoordSys.js +12 -6
  8. package/lib/cjs/AuxCoordSys.js.map +1 -1
  9. package/lib/cjs/DrawingViewState.d.ts.map +1 -1
  10. package/lib/cjs/DrawingViewState.js +3 -4
  11. package/lib/cjs/DrawingViewState.js.map +1 -1
  12. package/lib/cjs/EntityState.js +1 -1
  13. package/lib/cjs/EntityState.js.map +1 -1
  14. package/lib/cjs/IModelConnection.d.ts +20 -7
  15. package/lib/cjs/IModelConnection.d.ts.map +1 -1
  16. package/lib/cjs/IModelConnection.js +66 -77
  17. package/lib/cjs/IModelConnection.js.map +1 -1
  18. package/lib/cjs/IpcApp.d.ts +37 -0
  19. package/lib/cjs/IpcApp.d.ts.map +1 -1
  20. package/lib/cjs/IpcApp.js +56 -26
  21. package/lib/cjs/IpcApp.js.map +1 -1
  22. package/lib/cjs/ViewCreator2d.d.ts.map +1 -1
  23. package/lib/cjs/ViewCreator2d.js +7 -9
  24. package/lib/cjs/ViewCreator2d.js.map +1 -1
  25. package/lib/cjs/common/gltf/GltfSchema.d.ts +7 -0
  26. package/lib/cjs/common/gltf/GltfSchema.d.ts.map +1 -1
  27. package/lib/cjs/common/gltf/GltfSchema.js.map +1 -1
  28. package/lib/cjs/tile/GltfReader.d.ts.map +1 -1
  29. package/lib/cjs/tile/GltfReader.js +3 -0
  30. package/lib/cjs/tile/GltfReader.js.map +1 -1
  31. package/lib/cjs/tile/TileRequestChannel.js.map +1 -1
  32. package/lib/cjs/tools/AccuDrawTool.d.ts +20 -3
  33. package/lib/cjs/tools/AccuDrawTool.d.ts.map +1 -1
  34. package/lib/cjs/tools/AccuDrawTool.js +108 -58
  35. package/lib/cjs/tools/AccuDrawTool.js.map +1 -1
  36. package/lib/cjs/tools/ElementSetTool.d.ts.map +1 -1
  37. package/lib/cjs/tools/ElementSetTool.js +1 -2
  38. package/lib/cjs/tools/ElementSetTool.js.map +1 -1
  39. package/lib/esm/AccuDraw.d.ts.map +1 -1
  40. package/lib/esm/AccuDraw.js +11 -10
  41. package/lib/esm/AccuDraw.js.map +1 -1
  42. package/lib/esm/AuxCoordSys.d.ts +11 -4
  43. package/lib/esm/AuxCoordSys.d.ts.map +1 -1
  44. package/lib/esm/AuxCoordSys.js +13 -7
  45. package/lib/esm/AuxCoordSys.js.map +1 -1
  46. package/lib/esm/DrawingViewState.d.ts.map +1 -1
  47. package/lib/esm/DrawingViewState.js +3 -4
  48. package/lib/esm/DrawingViewState.js.map +1 -1
  49. package/lib/esm/EntityState.js +1 -1
  50. package/lib/esm/EntityState.js.map +1 -1
  51. package/lib/esm/IModelConnection.d.ts +20 -7
  52. package/lib/esm/IModelConnection.d.ts.map +1 -1
  53. package/lib/esm/IModelConnection.js +67 -78
  54. package/lib/esm/IModelConnection.js.map +1 -1
  55. package/lib/esm/IpcApp.d.ts +37 -0
  56. package/lib/esm/IpcApp.d.ts.map +1 -1
  57. package/lib/esm/IpcApp.js +56 -27
  58. package/lib/esm/IpcApp.js.map +1 -1
  59. package/lib/esm/ViewCreator2d.d.ts.map +1 -1
  60. package/lib/esm/ViewCreator2d.js +7 -9
  61. package/lib/esm/ViewCreator2d.js.map +1 -1
  62. package/lib/esm/common/gltf/GltfSchema.d.ts +7 -0
  63. package/lib/esm/common/gltf/GltfSchema.d.ts.map +1 -1
  64. package/lib/esm/common/gltf/GltfSchema.js.map +1 -1
  65. package/lib/esm/tile/GltfReader.d.ts.map +1 -1
  66. package/lib/esm/tile/GltfReader.js +3 -0
  67. package/lib/esm/tile/GltfReader.js.map +1 -1
  68. package/lib/esm/tile/TileRequestChannel.js.map +1 -1
  69. package/lib/esm/tools/AccuDrawTool.d.ts +20 -3
  70. package/lib/esm/tools/AccuDrawTool.d.ts.map +1 -1
  71. package/lib/esm/tools/AccuDrawTool.js +109 -59
  72. package/lib/esm/tools/AccuDrawTool.js.map +1 -1
  73. package/lib/esm/tools/ElementSetTool.d.ts.map +1 -1
  74. package/lib/esm/tools/ElementSetTool.js +1 -2
  75. package/lib/esm/tools/ElementSetTool.js.map +1 -1
  76. package/lib/public/scripts/parse-imdl-worker.js +1 -1
  77. package/lib/workers/webpack/parse-imdl-worker.js +1 -1
  78. package/package.json +23 -23
@@ -107,7 +107,9 @@ class IModelConnection extends core_common_1.IModel {
107
107
  */
108
108
  fontMap; // eslint-disable-line @typescript-eslint/no-deprecated
109
109
  _schemaContext;
110
- _schemasPromise;
110
+ // Created lazily on the first getSchemaView call. Owns the SchemaView's lifetime and does all its
111
+ // data access through the SchemaViewDataProvider implemented below.
112
+ _schemaViewManager;
111
113
  /** Load the FontMap for this IModelConnection.
112
114
  * @returns Returns a Promise<FontMap> that is fulfilled when the FontMap member of this IModelConnection is valid.
113
115
  * @deprecated in 5.0.0 - might be removed in next major version. If you need font Ids on the front-end for some reason, write an Ipc method that queries [IModelDb.fonts]($backend).
@@ -535,33 +537,23 @@ class IModelConnection extends core_common_1.IModel {
535
537
  }
536
538
  /** Get the schema view for this iModel. The view is built lazily on
537
539
  * first call by fetching compact binary schema data via `PRAGMA schema_view` through
538
- * the existing queryRows RPC (ConcurrentQuery). Subsequent calls return the cached view.
539
- * Multiple concurrent callers share a single in-flight fetch.
540
+ * the existing queryRows RPC (ConcurrentQuery).
540
541
  *
541
542
  * The returned `SchemaView` is a lightweight, read-only, synchronous API for
542
543
  * navigating schema metadata - classes, properties, relationships, enumerations, etc.
543
544
  * It is the recommended default for runtime read-only metadata access and is significantly
544
545
  * faster and lower-memory than [[schemaContext]]. Use [[schemaContext]] for custom-attribute
545
546
  * deserialization or anywhere you need the full ecschema-metadata object graph.
547
+ *
548
+ * Every call shares one accumulating view instance and concurrent calls are serialized, so a
549
+ * caller never observes a partially loaded view. The instance is discarded once the connection
550
+ * detects that schemas changed, for example after [[BriefcaseConnection.pullChanges]]; the next
551
+ * call builds a new one. See [GetSchemaViewArgs]($ecschema-metadata) for the arguments.
546
552
  * @beta
547
553
  */
548
- async getSchemaView() {
549
- if (this._schemasPromise) {
550
- const ctx = await this._schemasPromise;
551
- if (!ctx.isOutdated)
552
- return ctx;
553
- }
554
- // Capture the in-flight promise locally so the rejection handler only clears
555
- // `_schemasPromise` if it still points at this build. A concurrent invalidation +
556
- // re-fetch could otherwise replace the field before our fetch fails, and a naive
557
- // `_schemasPromise = undefined` would clobber that newer reference.
558
- const inflight = this._fetchSchemas();
559
- this._schemasPromise = inflight;
560
- inflight.catch(() => {
561
- if (this._schemasPromise === inflight)
562
- this._schemasPromise = undefined;
563
- });
564
- return inflight;
554
+ async getSchemaView(args) {
555
+ this._schemaViewManager ??= new ecschema_metadata_1.SchemaViewManager(this._createSchemaViewDataProvider());
556
+ return this._schemaViewManager.getSchemaView(args);
565
557
  }
566
558
  /**
567
559
  * Checks whether the iModel's schemas have changed since the current cached [[SchemaView]] was
@@ -573,7 +565,7 @@ class IModelConnection extends core_common_1.IModel {
573
565
  * returns only the new changeset id, not the list of applied changesets with their types.
574
566
  * Unconditionally discarding the cached [[SchemaView]] after every such operation would cause
575
567
  * unnecessary reloads in the common case where schemas are unchanged. This method avoids that
576
- * cost by fetching a lightweight schema checksum via `PRAGMA checksum(ecdb_schema)` and
568
+ * cost by fetching a lightweight schema token via `PRAGMA checksum(schema_token)` and
577
569
  * comparing it against the token stored in the cached view. Only when the token differs is the
578
570
  * cache discarded.
579
571
  *
@@ -582,61 +574,59 @@ class IModelConnection extends core_common_1.IModel {
582
574
  * @internal
583
575
  */
584
576
  async invalidateSchemaViewIfChanged() {
585
- if (!this._schemasPromise)
586
- return;
587
- const existingPromise = this._schemasPromise;
588
- let existing;
589
- try {
590
- existing = await existingPromise;
591
- }
592
- catch {
593
- // The cached promise itself failed; drop it so the next getSchemaView() retries.
594
- if (this._schemasPromise === existingPromise)
595
- this._schemasPromise = undefined;
596
- return;
597
- }
598
- if (!existing.schemaToken)
599
- return;
600
- try {
601
- const reader = this.createQueryReader("PRAGMA checksum(ecdb_schema)");
602
- const result = await reader.next();
603
- if (result.done)
604
- throw new Error("PRAGMA checksum(ecdb_schema) returned no rows");
605
- const liveToken = result.value.sha3_256;
606
- if (liveToken !== existing.schemaToken) {
607
- if (this._schemasPromise === existingPromise)
608
- this._schemasPromise = undefined;
609
- existing.markOutdated();
610
- }
611
- }
612
- catch {
613
- // The checksum check is called right after operations that may have changed schemas
614
- // (e.g., pullChanges). If we cannot verify the cached view is still current, drop it
615
- // rather than risk returning stale metadata indefinitely. The next getSchemaView() call
616
- // will reload. We also mark the existing view outdated so any retained references can
617
- // observe the invalidation.
618
- if (this._schemasPromise === existingPromise) {
619
- this._schemasPromise = undefined;
620
- existing.markOutdated();
621
- }
622
- }
577
+ await this._schemaViewManager?.invalidateIfChanged();
578
+ }
579
+ /** The [SchemaViewDataProvider]($ecschema-metadata) backing this iModel's [[getSchemaView]]: the
580
+ * transport-specific half of schema-view loading, issued through the queryRows RPC
581
+ * (ConcurrentQuery). The frontend *pins* the blob format version in both pragmas, because the
582
+ * backend it talks to can be older or newer; the pin makes it return a blob this code can parse,
583
+ * or fail cleanly.
584
+ */
585
+ _createSchemaViewDataProvider() {
586
+ return {
587
+ fetchFullBlob: async () => this._fetchSchemaBlob(`PRAGMA schema_view(${ecschema_metadata_1.schemaViewFormatVersion})`),
588
+ // Names are ECNames, so a comma can never occur in one. Native re-validates each token as an
589
+ // ECName and fails the pragma on an unknown name. The `v<N>;` prefix pins the format version.
590
+ fetchFragmentBlob: async (schemaNames) => this._fetchSchemaBlob(`PRAGMA schema_view_fragment('v${ecschema_metadata_1.schemaViewFormatVersion};${schemaNames.join(",")}')`),
591
+ fetchManifest: async () => {
592
+ const schemaRows = [];
593
+ const schemaSql = "SELECT ECInstanceId, Name, VersionMajor, VersionWrite, VersionMinor FROM meta.ECSchemaDef";
594
+ for await (const row of this.createQueryReader(schemaSql)) {
595
+ // ECInstanceId arrives as a hex Id64String. `ec_` metadata rowids carry no briefcase
596
+ // prefix, so the local id is the full value.
597
+ schemaRows.push({ ecInstanceId: core_bentley_1.Id64.getLocalId(row[0]), name: row[1], versionMajor: row[2], versionWrite: row[3], versionMinor: row[4] });
598
+ }
599
+ const referenceRows = [];
600
+ const referenceSql = "SELECT SourceECInstanceId, TargetECInstanceId FROM meta.SchemaHasSchemaReferences";
601
+ for await (const row of this.createQueryReader(referenceSql))
602
+ referenceRows.push({ sourceECInstanceId: core_bentley_1.Id64.getLocalId(row[0]), targetECInstanceId: core_bentley_1.Id64.getLocalId(row[1]) });
603
+ return ecschema_metadata_1.SchemaManifest.fromRows(schemaRows, referenceRows);
604
+ },
605
+ fetchSchemaToken: async () => {
606
+ const reader = this.createQueryReader("PRAGMA checksum(schema_token)");
607
+ const result = await reader.next();
608
+ if (result.done)
609
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "PRAGMA checksum(schema_token) returned no rows");
610
+ return result.value.sha3_256;
611
+ },
612
+ };
623
613
  }
624
- async _fetchSchemas() {
625
- // PRAGMA returns exactly one row with format, formatVersion, data (binary), schemaToken.
626
- // Important: only call reader.next() once - do NOT use `for await` on PRAGMA results.
627
- // ConcurrentQuery wraps regular ECSQL in LIMIT/OFFSET for pagination but skips this for
628
- // PRAGMAs. If the serialized result exceeds the memory threshold, the response is marked
629
- // "Partial", and a `for await` loop would re-issue the same PRAGMA forever since PRAGMAs
630
- // don't support OFFSET-based pagination.
631
- const reader = this.createQueryReader(`PRAGMA schema_view(${ecschema_metadata_1.schemaViewFormatVersion})`);
614
+ /** Fetch one schema-view blob (full or fragment). Both `PRAGMA schema_view` and
615
+ * `PRAGMA schema_view_fragment` return a single row with the same columns. */
616
+ async _fetchSchemaBlob(pragma) {
617
+ // Only call reader.next() once - do NOT use `for await` on PRAGMA results. ConcurrentQuery wraps
618
+ // regular ECSQL in LIMIT/OFFSET for pagination but skips this for PRAGMAs; if the serialized
619
+ // result exceeds the memory threshold, the response is marked "Partial", and a `for await` loop
620
+ // would re-issue the same PRAGMA forever since PRAGMAs don't support OFFSET-based pagination.
621
+ const reader = this.createQueryReader(pragma);
632
622
  const result = await reader.next();
633
623
  if (result.done)
634
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "PRAGMA schema_view returned no rows");
624
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, `${pragma} returned no rows`);
635
625
  const data = result.value.data;
636
626
  const token = result.value.schemaToken;
637
627
  if (data === undefined || data === null)
638
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "PRAGMA schema_view returned null data column");
639
- return ecschema_metadata_1.SchemaView.fromBinary(data, token ?? "");
628
+ throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, `${pragma} returned null data column`);
629
+ return { data, schemaToken: token ?? "" };
640
630
  }
641
631
  }
642
632
  exports.IModelConnection = IModelConnection;
@@ -1100,24 +1090,24 @@ exports.SnapshotConnection = SnapshotConnection;
1100
1090
  return [];
1101
1091
  const select3d = `
1102
1092
  SELECT
1103
- ECInstanceId,
1093
+ ECInstanceId as id,
1104
1094
  Origin.x as x, Origin.y as y, Origin.z as z,
1105
1095
  BBoxLow.x as lx, BBoxLow.y as ly, BBoxLow.z as lz,
1106
1096
  BBoxHigh.x as hx, BBoxHigh.y as hy, BBoxHigh.z as hz,
1107
- Yaw, Pitch, Roll,
1108
- NULL as Rotation
1097
+ Yaw as yaw, Pitch as pitch, Roll as roll,
1098
+ NULL as rotation
1109
1099
  FROM bis.GeometricElement3d
1110
1100
  WHERE Origin IS NOT NULL AND BBoxLow IS NOT NULL AND BBoxHigh IS NOT NULL`;
1111
1101
  // Note: For the UNION ALL statement, the column aliases in select2d are ignored - so they
1112
1102
  // must match those in select3d.
1113
1103
  const select2d = `
1114
1104
  SELECT
1115
- ECInstanceId,
1105
+ ECInstanceId as id,
1116
1106
  Origin.x as x, Origin.y as y, NULL as z,
1117
1107
  BBoxLow.x as lx, BBoxLow.y as ly, NULL as lz,
1118
1108
  BBoxHigh.x as hx, BBoxHigh.y as hy, NULL as hz,
1119
1109
  NULL as yaw, NULL as pitch, NULL as roll,
1120
- Rotation
1110
+ Rotation as rotation
1121
1111
  FROM bis.GeometricElement2d
1122
1112
  WHERE Origin IS NOT NULL AND BBoxLow IS NOT NULL AND BBoxHigh IS NOT NULL`;
1123
1113
  const idCriterion = `ECInstanceId IN (${ids.join(",")})`;
@@ -1139,8 +1129,7 @@ exports.SnapshotConnection = SnapshotConnection;
1139
1129
  break;
1140
1130
  }
1141
1131
  const placements = new Array();
1142
- // eslint-disable-next-line @typescript-eslint/no-deprecated
1143
- for await (const queryRow of this._iModel.createQueryReader(ecsql, undefined, { rowFormat: core_common_1.QueryRowFormat.UseJsPropertyNames })) {
1132
+ for await (const queryRow of this._iModel.createQueryReader(ecsql, undefined, { rowFormat: core_common_1.QueryRowFormat.UseECSqlPropertyNames })) {
1144
1133
  const row = queryRow.toRow();
1145
1134
  const origin = [row.x, row.y, row.z];
1146
1135
  const bbox = {