@mlightcad/data-model 1.10.1 → 1.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +17 -0
  2. package/dist/data-model.cjs +8 -7
  3. package/lib/converter/index.d.ts +1 -1
  4. package/lib/converter/index.d.ts.map +1 -1
  5. package/lib/converter/worker/AcDbBaseWorker.d.ts +22 -0
  6. package/lib/converter/worker/AcDbBaseWorker.d.ts.map +1 -1
  7. package/lib/converter/worker/AcDbBaseWorker.js +26 -3
  8. package/lib/converter/worker/AcDbBaseWorker.js.map +1 -1
  9. package/lib/converter/worker/AcDbWorkerManager.d.ts +3 -0
  10. package/lib/converter/worker/AcDbWorkerManager.d.ts.map +1 -1
  11. package/lib/converter/worker/AcDbWorkerManager.js +8 -3
  12. package/lib/converter/worker/AcDbWorkerManager.js.map +1 -1
  13. package/lib/converter/worker/index.d.ts +1 -1
  14. package/lib/converter/worker/index.d.ts.map +1 -1
  15. package/lib/database/AcDbBlockTable.d.ts +2 -1
  16. package/lib/database/AcDbBlockTable.d.ts.map +1 -1
  17. package/lib/database/AcDbBlockTable.js +7 -18
  18. package/lib/database/AcDbBlockTable.js.map +1 -1
  19. package/lib/database/AcDbBlockTableRecord.d.ts +7 -1
  20. package/lib/database/AcDbBlockTableRecord.d.ts.map +1 -1
  21. package/lib/database/AcDbBlockTableRecord.js +48 -13
  22. package/lib/database/AcDbBlockTableRecord.js.map +1 -1
  23. package/lib/database/AcDbDatabase.d.ts +92 -12
  24. package/lib/database/AcDbDatabase.d.ts.map +1 -1
  25. package/lib/database/AcDbDatabase.js +322 -198
  26. package/lib/database/AcDbDatabase.js.map +1 -1
  27. package/lib/database/AcDbOpenDatabaseError.d.ts +113 -0
  28. package/lib/database/AcDbOpenDatabaseError.d.ts.map +1 -0
  29. package/lib/database/AcDbOpenDatabaseError.js +156 -0
  30. package/lib/database/AcDbOpenDatabaseError.js.map +1 -0
  31. package/lib/database/AcDbSymbolTable.d.ts +20 -3
  32. package/lib/database/AcDbSymbolTable.d.ts.map +1 -1
  33. package/lib/database/AcDbSymbolTable.js +120 -11
  34. package/lib/database/AcDbSymbolTable.js.map +1 -1
  35. package/lib/database/AcDbTextStyleTable.js +1 -1
  36. package/lib/database/AcDbTextStyleTable.js.map +1 -1
  37. package/lib/database/index.d.ts +3 -1
  38. package/lib/database/index.d.ts.map +1 -1
  39. package/lib/database/index.js +1 -0
  40. package/lib/database/index.js.map +1 -1
  41. package/lib/entity/AcDbLeader.d.ts +44 -0
  42. package/lib/entity/AcDbLeader.d.ts.map +1 -1
  43. package/lib/entity/AcDbLeader.js +238 -10
  44. package/lib/entity/AcDbLeader.js.map +1 -1
  45. package/lib/entity/AcDbMText.d.ts +10 -0
  46. package/lib/entity/AcDbMText.d.ts.map +1 -1
  47. package/lib/entity/AcDbMText.js +28 -3
  48. package/lib/entity/AcDbMText.js.map +1 -1
  49. package/lib/entity/AcDbTextExtentsHelpers.d.ts +104 -1
  50. package/lib/entity/AcDbTextExtentsHelpers.d.ts.map +1 -1
  51. package/lib/entity/AcDbTextExtentsHelpers.js +126 -0
  52. package/lib/entity/AcDbTextExtentsHelpers.js.map +1 -1
  53. package/lib/index.d.ts +3 -3
  54. package/lib/index.d.ts.map +1 -1
  55. package/lib/index.js +1 -1
  56. package/lib/index.js.map +1 -1
  57. package/lib/misc/AcDbObjectIterator.d.ts +5 -4
  58. package/lib/misc/AcDbObjectIterator.d.ts.map +1 -1
  59. package/lib/misc/AcDbObjectIterator.js +50 -5
  60. package/lib/misc/AcDbObjectIterator.js.map +1 -1
  61. package/lib/object/AcDbDictionary.d.ts +0 -2
  62. package/lib/object/AcDbDictionary.d.ts.map +1 -1
  63. package/lib/object/AcDbDictionary.js +21 -12
  64. package/lib/object/AcDbDictionary.js.map +1 -1
  65. package/package.json +4 -4
@@ -49,17 +49,6 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
49
49
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
50
50
  }
51
51
  };
52
- var __values = (this && this.__values) || function(o) {
53
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
54
- if (m) return m.call(o);
55
- if (o && typeof o.length === "number") return {
56
- next: function () {
57
- if (o && i >= o.length) o = void 0;
58
- return { value: o && o[i++], done: !o };
59
- }
60
- };
61
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
62
- };
63
52
  var __read = (this && this.__read) || function (o, n) {
64
53
  var m = typeof Symbol === "function" && o[Symbol.iterator];
65
54
  if (!m) return o;
@@ -85,10 +74,21 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
85
74
  }
86
75
  return to.concat(ar || Array.prototype.slice.call(from));
87
76
  };
77
+ var __values = (this && this.__values) || function(o) {
78
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
79
+ if (m) return m.call(o);
80
+ if (o && typeof o.length === "number") return {
81
+ next: function () {
82
+ if (o && i >= o.length) o = void 0;
83
+ return { value: o && o[i++], done: !o };
84
+ }
85
+ };
86
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
87
+ };
88
88
  /* eslint-disable simple-import-sort/imports */
89
89
  import { AcCmColor, AcCmColorMethod, AcCmEventManager, AcCmTransparency } from '@mlightcad/common';
90
90
  import { AcDbDxfFiler } from '../base/AcDbDxfFiler';
91
- import { AcDbObject } from '../base/AcDbObject';
91
+ import { AcDbObject, TEMP_OBJECT_ID_PREFIX } from '../base/AcDbObject';
92
92
  import { AcDbOpenMode } from '../base/AcDbOpenMode';
93
93
  import { AcDbRegenerator } from '../converter/AcDbRegenerator';
94
94
  import { AcDbDatabaseConverterManager, AcDbFileType } from './AcDbDatabaseConverterManager';
@@ -103,6 +103,7 @@ import { AcDbMLeaderStyle } from '../object/AcDbMLeaderStyle';
103
103
  import { AcDbMlineStyle } from '../object/AcDbMlineStyle';
104
104
  import { AcDbBlockTable } from './AcDbBlockTable';
105
105
  import { AcDbBlockTableRecord } from './AcDbBlockTableRecord';
106
+ import { AcDbOpenDatabaseError } from './AcDbOpenDatabaseError';
106
107
  import { AcDbDimStyleTable } from './AcDbDimStyleTable';
107
108
  import { AcDbDimStyleTableRecord } from './AcDbDimStyleTableRecord';
108
109
  import { AcDbLayerTable } from './AcDbLayerTable';
@@ -147,6 +148,8 @@ var AcDbDatabase = /** @class */ (function (_super) {
147
148
  */
148
149
  function AcDbDatabase() {
149
150
  var _this = _super.call(this, { objectId: '0' }) || this;
151
+ /** Global registry of committed object handles across all database-resident objects */
152
+ _this._handleRegistry = new Map();
150
153
  /**
151
154
  * When false, entities on non-plottable layers are not drawn (viewer semantics).
152
155
  * Set from {@link AcDbOpenDatabaseOptions.drawNoPlotLayers} when opening a database.
@@ -157,6 +160,7 @@ var AcDbDatabase = /** @class */ (function (_super) {
157
160
  _this._pendingEntityErased = [];
158
161
  _this._pendingDictObjectSet = [];
159
162
  _this._pendingDictObjectErased = [];
163
+ _this._lastOpenError = null;
160
164
  /**
161
165
  * Events that can be triggered by the database.
162
166
  *
@@ -181,7 +185,9 @@ var AcDbDatabase = /** @class */ (function (_super) {
181
185
  /** Fired when a layer is erased from the database */
182
186
  layerErased: new AcCmEventManager(),
183
187
  /** Fired during database opening operations to report progress */
184
- openProgress: new AcCmEventManager()
188
+ openProgress: new AcCmEventManager(),
189
+ /** Fired when {@link AcDbDatabase.read} or {@link AcDbDatabase.openUri} fails */
190
+ openFailed: new AcCmEventManager()
185
191
  };
186
192
  AcDbDatabase._unsavedDrawingSequence += 1;
187
193
  _this._dwgname = "Drawing".concat(AcDbDatabase._unsavedDrawingSequence, ".dwg");
@@ -237,6 +243,7 @@ var AcDbDatabase = /** @class */ (function (_super) {
237
243
  xrecord: new AcDbDictionary(_this)
238
244
  };
239
245
  _this.transactionManager = new AcDbDatabaseTransactionManager(_this);
246
+ _this.registerBootstrapHandles();
240
247
  return _this;
241
248
  }
242
249
  Object.defineProperty(AcDbDatabase.prototype, "tables", {
@@ -279,69 +286,18 @@ var AcDbDatabase = /** @class */ (function (_super) {
279
286
  /**
280
287
  * Looks up a database-resident object by its object ID.
281
288
  *
282
- * Search order: entities, symbol table records, dictionary objects
283
- * (including nested dictionaries), then the database object itself.
289
+ * Uses the global handle registry maintained by {@link registerObjectHandle}.
284
290
  *
285
291
  * @param id - Object identifier to resolve
286
292
  * @param _openErased - Reserved for erased-object support
287
293
  * @returns The matching object, or undefined if not found
288
294
  */
289
295
  AcDbDatabase.prototype.getObjectById = function (id, _openErased) {
290
- var e_1, _a, e_2, _b;
291
296
  if (_openErased === void 0) { _openErased = false; }
292
297
  if (id === this.objectId) {
293
298
  return this;
294
299
  }
295
- var entity = this.tables.blockTable.getEntityById(id);
296
- if (entity) {
297
- return entity;
298
- }
299
- var symbolTables = [
300
- this.tables.appIdTable,
301
- this.tables.blockTable,
302
- this.tables.dimStyleTable,
303
- this.tables.linetypeTable,
304
- this.tables.textStyleTable,
305
- this.tables.viewTable,
306
- this.tables.layerTable,
307
- this.tables.viewportTable
308
- ];
309
- try {
310
- for (var symbolTables_1 = __values(symbolTables), symbolTables_1_1 = symbolTables_1.next(); !symbolTables_1_1.done; symbolTables_1_1 = symbolTables_1.next()) {
311
- var table = symbolTables_1_1.value;
312
- var record = table.getIdAt(id);
313
- if (record) {
314
- return record;
315
- }
316
- }
317
- }
318
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
319
- finally {
320
- try {
321
- if (symbolTables_1_1 && !symbolTables_1_1.done && (_a = symbolTables_1.return)) _a.call(symbolTables_1);
322
- }
323
- finally { if (e_1) throw e_1.error; }
324
- }
325
- try {
326
- for (var _c = __values(this.getRootDictionaries()), _d = _c.next(); !_d.done; _d = _c.next()) {
327
- var dictionary = _d.value;
328
- if (dictionary.objectId === id) {
329
- return dictionary;
330
- }
331
- var object = this.findObjectInDictionary(dictionary, id);
332
- if (object) {
333
- return object;
334
- }
335
- }
336
- }
337
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
338
- finally {
339
- try {
340
- if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
341
- }
342
- finally { if (e_2) throw e_2.error; }
343
- }
344
- return undefined;
300
+ return this._handleRegistry.get(id);
345
301
  };
346
302
  /**
347
303
  * Returns true when the transaction manager is actively recording changes.
@@ -428,45 +384,6 @@ var AcDbDatabase = /** @class */ (function (_super) {
428
384
  this.objects.xrecord
429
385
  ];
430
386
  };
431
- /**
432
- * Recursively searches a dictionary tree for an object with the given ID.
433
- *
434
- * @param dictionary - Root dictionary to search (including nested dictionaries)
435
- * @param id - Object identifier to resolve
436
- * @returns Matching object, or undefined when not found under `dictionary`
437
- */
438
- AcDbDatabase.prototype.findObjectInDictionary = function (dictionary, id) {
439
- var e_3, _a;
440
- if (dictionary.objectId === id) {
441
- return dictionary;
442
- }
443
- var direct = dictionary.getIdAt(id);
444
- if (direct) {
445
- return direct;
446
- }
447
- try {
448
- for (var _b = __values(dictionary.entries()), _c = _b.next(); !_c.done; _c = _b.next()) {
449
- var _d = __read(_c.value, 2), entry = _d[1];
450
- if (entry.objectId === id) {
451
- return entry;
452
- }
453
- if (entry instanceof AcDbDictionary) {
454
- var nested = this.findObjectInDictionary(entry, id);
455
- if (nested) {
456
- return nested;
457
- }
458
- }
459
- }
460
- }
461
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
462
- finally {
463
- try {
464
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
465
- }
466
- finally { if (e_3) throw e_3.error; }
467
- }
468
- return undefined;
469
- };
470
387
  /**
471
388
  * Begins suppressing database events until {@link endEventBatch} is called.
472
389
  */
@@ -567,7 +484,7 @@ var AcDbDatabase = /** @class */ (function (_super) {
567
484
  * Appended and erased entities are dispatched in batch arrays where applicable.
568
485
  */
569
486
  AcDbDatabase.prototype.flushEventBatch = function () {
570
- var e_4, _a, e_5, _b;
487
+ var e_1, _a, e_2, _b;
571
488
  if (this._pendingEntityAppended.length > 0) {
572
489
  var appended = this._pendingEntityAppended;
573
490
  this._pendingEntityAppended = [];
@@ -597,12 +514,12 @@ var AcDbDatabase = /** @class */ (function (_super) {
597
514
  });
598
515
  }
599
516
  }
600
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
517
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
601
518
  finally {
602
519
  try {
603
520
  if (dictSet_1_1 && !dictSet_1_1.done && (_a = dictSet_1.return)) _a.call(dictSet_1);
604
521
  }
605
- finally { if (e_4) throw e_4.error; }
522
+ finally { if (e_1) throw e_1.error; }
606
523
  }
607
524
  }
608
525
  if (this._pendingDictObjectErased.length > 0) {
@@ -618,12 +535,12 @@ var AcDbDatabase = /** @class */ (function (_super) {
618
535
  });
619
536
  }
620
537
  }
621
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
538
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
622
539
  finally {
623
540
  try {
624
541
  if (dictErased_1_1 && !dictErased_1_1.done && (_b = dictErased_1.return)) _b.call(dictErased_1);
625
542
  }
626
- finally { if (e_5) throw e_5.error; }
543
+ finally { if (e_2) throw e_2.error; }
627
544
  }
628
545
  }
629
546
  };
@@ -662,6 +579,143 @@ var AcDbDatabase = /** @class */ (function (_super) {
662
579
  this._maxHandle++;
663
580
  return this._maxHandle.toString(16).toUpperCase();
664
581
  };
582
+ /**
583
+ * Generates a handle that is not already registered in this database.
584
+ *
585
+ * @internal
586
+ */
587
+ AcDbDatabase.prototype.generateUniqueHandle = function () {
588
+ var handle = this.generateHandle();
589
+ while (this.isHandleTaken(handle)) {
590
+ handle = this.generateHandle();
591
+ }
592
+ return handle;
593
+ };
594
+ /**
595
+ * Initializes {@link generateHandle} from a DXF/DWG `$HANDSEED` value.
596
+ *
597
+ * `$HANDSEED` is the next handle AutoCAD would assign; internal `_maxHandle`
598
+ * is kept one below that value.
599
+ *
600
+ * @param seed - Hexadecimal handle seed from the drawing header
601
+ */
602
+ AcDbDatabase.prototype.initializeHandleSeed = function (seed) {
603
+ var next = parseInt(seed, 16);
604
+ if (!isNaN(next) && next > 0) {
605
+ var baseline = next - 1;
606
+ if (baseline > this._maxHandle) {
607
+ this._maxHandle = baseline;
608
+ }
609
+ }
610
+ };
611
+ /**
612
+ * Adopts a handle from an external drawing when it is still available.
613
+ *
614
+ * When the preferred handle is already registered to another object, a new
615
+ * unique handle is generated instead.
616
+ *
617
+ * @internal
618
+ */
619
+ AcDbDatabase.prototype.adoptExternalHandle = function (object, preferredId) {
620
+ this.releaseObjectHandle(object);
621
+ if (preferredId &&
622
+ !preferredId.startsWith(TEMP_OBJECT_ID_PREFIX) &&
623
+ !this.isHandleTaken(preferredId)) {
624
+ object.objectId = preferredId;
625
+ this.registerObjectHandle(object);
626
+ this.updateMaxHandle(preferredId);
627
+ return preferredId;
628
+ }
629
+ return this.assignGeneratedHandle(object);
630
+ };
631
+ /**
632
+ * Registers an object's current {@link AcDbObject.objectId} in the global handle map.
633
+ *
634
+ * @internal
635
+ */
636
+ AcDbDatabase.prototype.registerObjectHandle = function (object) {
637
+ var objectId = object.objectId;
638
+ if (!objectId || objectId.startsWith(TEMP_OBJECT_ID_PREFIX)) {
639
+ return;
640
+ }
641
+ this._handleRegistry.set(objectId, object);
642
+ };
643
+ /**
644
+ * Removes an object's handle from the global handle map.
645
+ *
646
+ * @internal
647
+ */
648
+ AcDbDatabase.prototype.releaseObjectHandle = function (object) {
649
+ var objectId = object.objectId;
650
+ if (!objectId || objectId.startsWith(TEMP_OBJECT_ID_PREFIX)) {
651
+ return;
652
+ }
653
+ if (this._handleRegistry.get(objectId) === object) {
654
+ this._handleRegistry.delete(objectId);
655
+ }
656
+ };
657
+ /**
658
+ * Returns true when a handle is already registered to another object.
659
+ *
660
+ * @internal
661
+ */
662
+ AcDbDatabase.prototype.isHandleTaken = function (objectId, except) {
663
+ if (!objectId || objectId.startsWith(TEMP_OBJECT_ID_PREFIX)) {
664
+ return false;
665
+ }
666
+ var owner = this._handleRegistry.get(objectId);
667
+ return owner !== undefined && owner !== except;
668
+ };
669
+ /**
670
+ * Registers bootstrap tables, dictionaries, and the database object itself.
671
+ */
672
+ AcDbDatabase.prototype.registerBootstrapHandles = function () {
673
+ var e_3, _a, e_4, _b;
674
+ this._handleRegistry.clear();
675
+ this.registerObjectHandle(this);
676
+ try {
677
+ for (var _c = __values(Object.values(this._tables)), _d = _c.next(); !_d.done; _d = _c.next()) {
678
+ var table = _d.value;
679
+ this.registerObjectHandle(table);
680
+ }
681
+ }
682
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
683
+ finally {
684
+ try {
685
+ if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
686
+ }
687
+ finally { if (e_3) throw e_3.error; }
688
+ }
689
+ try {
690
+ for (var _e = __values(Object.values(this._objects)), _f = _e.next(); !_f.done; _f = _e.next()) {
691
+ var dictionary = _f.value;
692
+ this.registerObjectHandle(dictionary);
693
+ }
694
+ }
695
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
696
+ finally {
697
+ try {
698
+ if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
699
+ }
700
+ finally { if (e_4) throw e_4.error; }
701
+ }
702
+ };
703
+ /**
704
+ * Assigns a freshly generated unique handle to an object.
705
+ *
706
+ * @internal
707
+ */
708
+ AcDbDatabase.prototype.assignGeneratedHandle = function (object) {
709
+ var oldId = object.objectId;
710
+ this.releaseObjectHandle(object);
711
+ var handle = this.generateUniqueHandle();
712
+ object.objectId = handle;
713
+ this.registerObjectHandle(object);
714
+ if (oldId && oldId !== handle) {
715
+ this.updateMaxHandle(handle);
716
+ }
717
+ return handle;
718
+ };
665
719
  /**
666
720
  * Updates the maximum handle value if the provided handle is greater.
667
721
  * This is called when setting an object's objectId from external sources (e.g., reading DXF/DWG).
@@ -689,12 +743,33 @@ var AcDbDatabase = /** @class */ (function (_super) {
689
743
  */
690
744
  AcDbDatabase.prototype.commitObjectHandle = function (object, hasId) {
691
745
  var objectId = object.getAttrWithoutException('objectId');
692
- if (!objectId || object.isTemp || (hasId && hasId(objectId))) {
693
- object.objectId = this.generateHandle();
746
+ var tableDuplicate = hasId != null && objectId != null && hasId(objectId);
747
+ var needsGenerated = !objectId ||
748
+ object.isTemp ||
749
+ tableDuplicate;
750
+ if (needsGenerated) {
751
+ this.assignGeneratedHandle(object);
752
+ return;
694
753
  }
695
- else {
696
- this.updateMaxHandle(objectId);
754
+ var incumbent = this._handleRegistry.get(objectId);
755
+ if (incumbent && incumbent !== object) {
756
+ if (this.shouldPreserveIncomingHandle(object)) {
757
+ this.assignGeneratedHandle(incumbent);
758
+ }
759
+ else {
760
+ this.assignGeneratedHandle(object);
761
+ return;
762
+ }
697
763
  }
764
+ this.registerObjectHandle(object);
765
+ this.updateMaxHandle(objectId);
766
+ };
767
+ /**
768
+ * Returns true when an object already carries an explicit handle that should
769
+ * be preserved over auto-generated registry occupants (typically DXF/DWG imports).
770
+ */
771
+ AcDbDatabase.prototype.shouldPreserveIncomingHandle = function (object) {
772
+ return !object.isTemp;
698
773
  };
699
774
  Object.defineProperty(AcDbDatabase.prototype, "currentSpaceId", {
700
775
  /**
@@ -1498,6 +1573,19 @@ var AcDbDatabase = /** @class */ (function (_super) {
1498
1573
  enumerable: false,
1499
1574
  configurable: true
1500
1575
  });
1576
+ Object.defineProperty(AcDbDatabase.prototype, "lastOpenError", {
1577
+ /**
1578
+ * The most recent failure from {@link read} or {@link openUri}, or `null` after a successful open.
1579
+ *
1580
+ * Useful when a caller catches no exception (for example a viewer that returns `false`)
1581
+ * but still needs to distinguish worker out-of-memory from other parse failures.
1582
+ */
1583
+ get: function () {
1584
+ return this._lastOpenError;
1585
+ },
1586
+ enumerable: false,
1587
+ configurable: true
1588
+ });
1501
1589
  /**
1502
1590
  * Reads drawing data from a string or ArrayBuffer.
1503
1591
  *
@@ -1524,8 +1612,7 @@ var AcDbDatabase = /** @class */ (function (_super) {
1524
1612
  */
1525
1613
  AcDbDatabase.prototype.read = function (data_1, options_1) {
1526
1614
  return __awaiter(this, arguments, void 0, function (data, options, fileType) {
1527
- var converter;
1528
- var _this = this;
1615
+ var converter, error_1, openError;
1529
1616
  var _a;
1530
1617
  if (fileType === void 0) { fileType = AcDbFileType.DXF; }
1531
1618
  return __generator(this, function (_b) {
@@ -1535,46 +1622,95 @@ var AcDbDatabase = /** @class */ (function (_super) {
1535
1622
  if (converter == null)
1536
1623
  throw new Error("Database converter for file type '".concat(fileType, "' isn't registered and can can't read this file!"));
1537
1624
  this.clear();
1625
+ this._lastOpenError = null;
1538
1626
  this._drawNoPlotLayers = (_a = options === null || options === void 0 ? void 0 : options.drawNoPlotLayers) !== null && _a !== void 0 ? _a : true;
1539
1627
  if (options === null || options === void 0 ? void 0 : options.fileName) {
1540
1628
  this.setDwgName(options.fileName);
1541
1629
  }
1542
- return [4 /*yield*/, converter.read(data, this, (options && options.minimumChunkSize) || 10, function (percentage, stage, stageStatus, data) { return __awaiter(_this, void 0, void 0, function () {
1543
- var fonts_1;
1544
- return __generator(this, function (_a) {
1545
- switch (_a.label) {
1546
- case 0:
1547
- this.events.openProgress.dispatch({
1548
- database: this,
1549
- percentage: percentage,
1550
- stage: 'CONVERSION',
1551
- subStage: stage,
1552
- subStageStatus: stageStatus,
1553
- data: data
1554
- });
1555
- if (!(options &&
1556
- options.fontLoader &&
1557
- stage == 'FONT' &&
1558
- stageStatus == 'END')) return [3 /*break*/, 2];
1559
- fonts_1 = data
1560
- ? data
1561
- : this.tables.textStyleTable.fonts;
1562
- return [4 /*yield*/, options.fontLoader.load(fonts_1)];
1563
- case 1:
1564
- _a.sent();
1565
- _a.label = 2;
1566
- case 2: return [2 /*return*/];
1567
- }
1568
- });
1569
- }); }, options === null || options === void 0 ? void 0 : options.timeout, options === null || options === void 0 ? void 0 : options.sysVars)];
1630
+ _b.label = 1;
1570
1631
  case 1:
1632
+ _b.trys.push([1, 3, , 4]);
1633
+ return [4 /*yield*/, converter.read(data, this, (options && options.minimumChunkSize) || 10, this.createConversionProgressHandler(options), options === null || options === void 0 ? void 0 : options.timeout, options === null || options === void 0 ? void 0 : options.sysVars)];
1634
+ case 2:
1571
1635
  _b.sent();
1636
+ return [3 /*break*/, 4];
1637
+ case 3:
1638
+ error_1 = _b.sent();
1639
+ openError = AcDbOpenDatabaseError.from(error_1);
1640
+ this._lastOpenError = openError;
1641
+ this.events.openFailed.dispatch({ database: this, error: openError });
1642
+ throw openError;
1643
+ case 4:
1644
+ this._lastOpenError = null;
1572
1645
  this.ensureDatabaseDefaults();
1573
1646
  return [2 /*return*/];
1574
1647
  }
1575
1648
  });
1576
1649
  });
1577
1650
  };
1651
+ AcDbDatabase.prototype.createConversionProgressHandler = function (options) {
1652
+ var _this = this;
1653
+ return function (percentage, stage, stageStatus, data, taskError) { return __awaiter(_this, void 0, void 0, function () {
1654
+ var progressData, openError, fonts_1, error_2, message;
1655
+ var _a;
1656
+ return __generator(this, function (_b) {
1657
+ switch (_b.label) {
1658
+ case 0:
1659
+ progressData = data;
1660
+ if (stageStatus === 'ERROR' && taskError) {
1661
+ openError = AcDbOpenDatabaseError.fromTask(taskError);
1662
+ this._lastOpenError = openError;
1663
+ progressData = {
1664
+ code: openError.code,
1665
+ message: openError.message,
1666
+ stage: (_a = openError.stage) !== null && _a !== void 0 ? _a : stage
1667
+ };
1668
+ }
1669
+ this.events.openProgress.dispatch({
1670
+ database: this,
1671
+ percentage: percentage,
1672
+ stage: 'CONVERSION',
1673
+ subStage: stage,
1674
+ subStageStatus: stageStatus,
1675
+ data: progressData
1676
+ });
1677
+ if (!(options &&
1678
+ options.fontLoader &&
1679
+ stage == 'FONT' &&
1680
+ stageStatus == 'END')) return [3 /*break*/, 4];
1681
+ fonts_1 = data
1682
+ ? data
1683
+ : this.tables.textStyleTable.fonts;
1684
+ _b.label = 1;
1685
+ case 1:
1686
+ _b.trys.push([1, 3, , 4]);
1687
+ return [4 /*yield*/, options.fontLoader.load(fonts_1)];
1688
+ case 2:
1689
+ _b.sent();
1690
+ return [3 /*break*/, 4];
1691
+ case 3:
1692
+ error_2 = _b.sent();
1693
+ if (options.failOnFontLoadError) {
1694
+ throw error_2;
1695
+ }
1696
+ message = error_2 instanceof Error ? error_2.message : String(error_2);
1697
+ console.warn('Failed to load fonts; continuing without them. ' +
1698
+ 'Check your network or configure a local baseUrl. See ' +
1699
+ 'https://github.com/mlightcad/cad-viewer/wiki/Self-Hosted-Fonts-and-Templates', error_2);
1700
+ this.events.openProgress.dispatch({
1701
+ database: this,
1702
+ percentage: percentage,
1703
+ stage: 'CONVERSION',
1704
+ subStage: stage,
1705
+ subStageStatus: 'ERROR',
1706
+ data: { fonts: fonts_1, error: message, code: 'font_load_failed' }
1707
+ });
1708
+ return [3 /*break*/, 4];
1709
+ case 4: return [2 /*return*/];
1710
+ }
1711
+ });
1712
+ }); };
1713
+ };
1578
1714
  /**
1579
1715
  * Read AutoCAD DXF or DWG drawing specified by the URL into the database object.
1580
1716
  * The method automatically detects the file type based on the URL extension:
@@ -1586,7 +1722,7 @@ var AcDbDatabase = /** @class */ (function (_super) {
1586
1722
  AcDbDatabase.prototype.openUri = function (url, options) {
1587
1723
  return __awaiter(this, void 0, void 0, function () {
1588
1724
  var response, contentLength, totalBytes, loadedBytes, reader, chunks, _a, done, value, percentage, content, position, chunks_1, chunks_1_1, chunk, fileName, fileExtension;
1589
- var e_6, _b;
1725
+ var e_5, _b;
1590
1726
  var _c;
1591
1727
  return __generator(this, function (_d) {
1592
1728
  switch (_d.label) {
@@ -1649,12 +1785,12 @@ var AcDbDatabase = /** @class */ (function (_super) {
1649
1785
  position += chunk.length;
1650
1786
  }
1651
1787
  }
1652
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
1788
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
1653
1789
  finally {
1654
1790
  try {
1655
1791
  if (chunks_1_1 && !chunks_1_1.done && (_b = chunks_1.return)) _b.call(chunks_1);
1656
1792
  }
1657
- finally { if (e_6) throw e_6.error; }
1793
+ finally { if (e_5) throw e_5.error; }
1658
1794
  }
1659
1795
  fileName = this.getFileNameFromUri(url);
1660
1796
  if (fileName) {
@@ -1732,24 +1868,11 @@ var AcDbDatabase = /** @class */ (function (_super) {
1732
1868
  AcDbDatabase.prototype.regen = function () {
1733
1869
  return __awaiter(this, void 0, void 0, function () {
1734
1870
  var converter;
1735
- var _this = this;
1736
1871
  return __generator(this, function (_a) {
1737
1872
  switch (_a.label) {
1738
1873
  case 0:
1739
1874
  converter = new AcDbRegenerator(this);
1740
- return [4 /*yield*/, converter.read(null, this, 500, function (percentage, stage, stageStatus, data) { return __awaiter(_this, void 0, void 0, function () {
1741
- return __generator(this, function (_a) {
1742
- this.events.openProgress.dispatch({
1743
- database: this,
1744
- percentage: percentage,
1745
- stage: 'CONVERSION',
1746
- subStage: stage,
1747
- subStageStatus: stageStatus,
1748
- data: data
1749
- });
1750
- return [2 /*return*/];
1751
- });
1752
- }); })];
1875
+ return [4 /*yield*/, converter.read(null, this, 500, this.createConversionProgressHandler())];
1753
1876
  case 1:
1754
1877
  _a.sent();
1755
1878
  return [2 /*return*/];
@@ -1839,7 +1962,7 @@ var AcDbDatabase = /** @class */ (function (_super) {
1839
1962
  }));
1840
1963
  };
1841
1964
  AcDbDatabase.prototype.hasDefaultTextStyle = function () {
1842
- var e_7, _a, e_8, _b;
1965
+ var e_6, _a, e_7, _b;
1843
1966
  var defaultNames = [DEFAULT_TEXT_STYLE, 'STANDARD'];
1844
1967
  try {
1845
1968
  for (var defaultNames_1 = __values(defaultNames), defaultNames_1_1 = defaultNames_1.next(); !defaultNames_1_1.done; defaultNames_1_1 = defaultNames_1.next()) {
@@ -1849,12 +1972,12 @@ var AcDbDatabase = /** @class */ (function (_super) {
1849
1972
  }
1850
1973
  }
1851
1974
  }
1852
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
1975
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
1853
1976
  finally {
1854
1977
  try {
1855
1978
  if (defaultNames_1_1 && !defaultNames_1_1.done && (_a = defaultNames_1.return)) _a.call(defaultNames_1);
1856
1979
  }
1857
- finally { if (e_7) throw e_7.error; }
1980
+ finally { if (e_6) throw e_6.error; }
1858
1981
  }
1859
1982
  try {
1860
1983
  for (var _c = __values(this.tables.textStyleTable.newIterator()), _d = _c.next(); !_d.done; _d = _c.next()) {
@@ -1864,12 +1987,12 @@ var AcDbDatabase = /** @class */ (function (_super) {
1864
1987
  }
1865
1988
  }
1866
1989
  }
1867
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
1990
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
1868
1991
  finally {
1869
1992
  try {
1870
1993
  if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
1871
1994
  }
1872
- finally { if (e_8) throw e_8.error; }
1995
+ finally { if (e_7) throw e_7.error; }
1873
1996
  }
1874
1997
  return false;
1875
1998
  };
@@ -1956,7 +2079,7 @@ var AcDbDatabase = /** @class */ (function (_super) {
1956
2079
  * Ensures one MLINE style exists for the provided style name.
1957
2080
  */
1958
2081
  AcDbDatabase.prototype.ensureMLineStyle = function (styleName) {
1959
- var e_9, _a;
2082
+ var e_8, _a;
1960
2083
  var dictionary = this.objects.mlineStyle;
1961
2084
  var normalizedName = styleName.trim();
1962
2085
  if (!normalizedName)
@@ -1973,12 +2096,12 @@ var AcDbDatabase = /** @class */ (function (_super) {
1973
2096
  }
1974
2097
  }
1975
2098
  }
1976
- catch (e_9_1) { e_9 = { error: e_9_1 }; }
2099
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
1977
2100
  finally {
1978
2101
  try {
1979
2102
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1980
2103
  }
1981
- finally { if (e_9) throw e_9.error; }
2104
+ finally { if (e_8) throw e_8.error; }
1982
2105
  }
1983
2106
  var style = new AcDbMlineStyle();
1984
2107
  style.styleName = normalizedName;
@@ -2000,7 +2123,7 @@ var AcDbDatabase = /** @class */ (function (_super) {
2000
2123
  * Ensures one MLEADER style exists for the provided style name.
2001
2124
  */
2002
2125
  AcDbDatabase.prototype.ensureMLeaderStyle = function (styleName) {
2003
- var e_10, _a;
2126
+ var e_9, _a;
2004
2127
  var dictionary = this.objects.mleaderStyle;
2005
2128
  var normalizedName = styleName.trim();
2006
2129
  if (!normalizedName)
@@ -2016,12 +2139,12 @@ var AcDbDatabase = /** @class */ (function (_super) {
2016
2139
  }
2017
2140
  }
2018
2141
  }
2019
- catch (e_10_1) { e_10 = { error: e_10_1 }; }
2142
+ catch (e_9_1) { e_9 = { error: e_9_1 }; }
2020
2143
  finally {
2021
2144
  try {
2022
2145
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2023
2146
  }
2024
- finally { if (e_10) throw e_10.error; }
2147
+ finally { if (e_9) throw e_9.error; }
2025
2148
  }
2026
2149
  var style = new AcDbMLeaderStyle();
2027
2150
  // Match AutoCAD "Standard" defaults observed in exported DXF.
@@ -2148,7 +2271,7 @@ var AcDbDatabase = /** @class */ (function (_super) {
2148
2271
  * @param filer - DXF output writer.
2149
2272
  */
2150
2273
  AcDbDatabase.prototype.writeDxfBlocksSection = function (filer) {
2151
- var e_11, _a, e_12, _b;
2274
+ var e_10, _a, e_11, _b;
2152
2275
  filer.startSection('BLOCKS');
2153
2276
  try {
2154
2277
  for (var _c = __values(this.tables.blockTable.newIterator()), _d = _c.next(); !_d.done; _d = _c.next()) {
@@ -2156,28 +2279,28 @@ var AcDbDatabase = /** @class */ (function (_super) {
2156
2279
  btr.dxfOutBlockBegin(filer);
2157
2280
  if (!btr.isModelSapce && !btr.isPaperSapce) {
2158
2281
  try {
2159
- for (var _e = (e_12 = void 0, __values(btr.newIterator())), _f = _e.next(); !_f.done; _f = _e.next()) {
2282
+ for (var _e = (e_11 = void 0, __values(btr.newIterator())), _f = _e.next(); !_f.done; _f = _e.next()) {
2160
2283
  var entity = _f.value;
2161
2284
  this.writeDxfEntity(filer, entity);
2162
2285
  }
2163
2286
  }
2164
- catch (e_12_1) { e_12 = { error: e_12_1 }; }
2287
+ catch (e_11_1) { e_11 = { error: e_11_1 }; }
2165
2288
  finally {
2166
2289
  try {
2167
2290
  if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
2168
2291
  }
2169
- finally { if (e_12) throw e_12.error; }
2292
+ finally { if (e_11) throw e_11.error; }
2170
2293
  }
2171
2294
  }
2172
2295
  btr.dxfOutBlockEnd(filer);
2173
2296
  }
2174
2297
  }
2175
- catch (e_11_1) { e_11 = { error: e_11_1 }; }
2298
+ catch (e_10_1) { e_10 = { error: e_10_1 }; }
2176
2299
  finally {
2177
2300
  try {
2178
2301
  if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
2179
2302
  }
2180
- finally { if (e_11) throw e_11.error; }
2303
+ finally { if (e_10) throw e_10.error; }
2181
2304
  }
2182
2305
  filer.endSection();
2183
2306
  };
@@ -2187,7 +2310,7 @@ var AcDbDatabase = /** @class */ (function (_super) {
2187
2310
  * @param filer - DXF output writer.
2188
2311
  */
2189
2312
  AcDbDatabase.prototype.writeDxfEntitiesSection = function (filer) {
2190
- var e_13, _a, e_14, _b;
2313
+ var e_12, _a, e_13, _b;
2191
2314
  filer.startSection('ENTITIES');
2192
2315
  try {
2193
2316
  for (var _c = __values(this.tables.blockTable.newIterator()), _d = _c.next(); !_d.done; _d = _c.next()) {
@@ -2195,26 +2318,26 @@ var AcDbDatabase = /** @class */ (function (_super) {
2195
2318
  if (!btr.isModelSapce && !btr.isPaperSapce)
2196
2319
  continue;
2197
2320
  try {
2198
- for (var _e = (e_14 = void 0, __values(btr.newIterator())), _f = _e.next(); !_f.done; _f = _e.next()) {
2321
+ for (var _e = (e_13 = void 0, __values(btr.newIterator())), _f = _e.next(); !_f.done; _f = _e.next()) {
2199
2322
  var entity = _f.value;
2200
2323
  this.writeDxfEntity(filer, entity);
2201
2324
  }
2202
2325
  }
2203
- catch (e_14_1) { e_14 = { error: e_14_1 }; }
2326
+ catch (e_13_1) { e_13 = { error: e_13_1 }; }
2204
2327
  finally {
2205
2328
  try {
2206
2329
  if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
2207
2330
  }
2208
- finally { if (e_14) throw e_14.error; }
2331
+ finally { if (e_13) throw e_13.error; }
2209
2332
  }
2210
2333
  }
2211
2334
  }
2212
- catch (e_13_1) { e_13 = { error: e_13_1 }; }
2335
+ catch (e_12_1) { e_12 = { error: e_12_1 }; }
2213
2336
  finally {
2214
2337
  try {
2215
2338
  if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
2216
2339
  }
2217
- finally { if (e_13) throw e_13.error; }
2340
+ finally { if (e_12) throw e_12.error; }
2218
2341
  }
2219
2342
  filer.endSection();
2220
2343
  };
@@ -2224,7 +2347,7 @@ var AcDbDatabase = /** @class */ (function (_super) {
2224
2347
  * @param filer - DXF output writer.
2225
2348
  */
2226
2349
  AcDbDatabase.prototype.writeDxfObjectsSection = function (filer) {
2227
- var e_15, _a, e_16, _b, e_17, _c, e_18, _d, e_19, _e;
2350
+ var e_14, _a, e_15, _b, e_16, _c, e_17, _d, e_18, _e;
2228
2351
  filer.startSection('OBJECTS');
2229
2352
  var rootDict = this.objects.dictionary;
2230
2353
  rootDict.ownerId = '0';
@@ -2289,12 +2412,12 @@ var AcDbDatabase = /** @class */ (function (_super) {
2289
2412
  layout.dxfOut(filer);
2290
2413
  }
2291
2414
  }
2292
- catch (e_15_1) { e_15 = { error: e_15_1 }; }
2415
+ catch (e_14_1) { e_14 = { error: e_14_1 }; }
2293
2416
  finally {
2294
2417
  try {
2295
2418
  if (_g && !_g.done && (_a = _f.return)) _a.call(_f);
2296
2419
  }
2297
- finally { if (e_15) throw e_15.error; }
2420
+ finally { if (e_14) throw e_14.error; }
2298
2421
  }
2299
2422
  try {
2300
2423
  for (var _j = __values(this.objects.imageDefinition.entries()), _k = _j.next(); !_k.done; _k = _j.next()) {
@@ -2303,12 +2426,12 @@ var AcDbDatabase = /** @class */ (function (_super) {
2303
2426
  imageDef.dxfOut(filer);
2304
2427
  }
2305
2428
  }
2306
- catch (e_16_1) { e_16 = { error: e_16_1 }; }
2429
+ catch (e_15_1) { e_15 = { error: e_15_1 }; }
2307
2430
  finally {
2308
2431
  try {
2309
2432
  if (_k && !_k.done && (_b = _j.return)) _b.call(_j);
2310
2433
  }
2311
- finally { if (e_16) throw e_16.error; }
2434
+ finally { if (e_15) throw e_15.error; }
2312
2435
  }
2313
2436
  try {
2314
2437
  for (var _m = __values(this.objects.mleaderStyle.entries()), _o = _m.next(); !_o.done; _o = _m.next()) {
@@ -2317,12 +2440,12 @@ var AcDbDatabase = /** @class */ (function (_super) {
2317
2440
  mleaderStyle.dxfOut(filer);
2318
2441
  }
2319
2442
  }
2320
- catch (e_17_1) { e_17 = { error: e_17_1 }; }
2443
+ catch (e_16_1) { e_16 = { error: e_16_1 }; }
2321
2444
  finally {
2322
2445
  try {
2323
2446
  if (_o && !_o.done && (_c = _m.return)) _c.call(_m);
2324
2447
  }
2325
- finally { if (e_17) throw e_17.error; }
2448
+ finally { if (e_16) throw e_16.error; }
2326
2449
  }
2327
2450
  try {
2328
2451
  for (var _q = __values(this.objects.mlineStyle.entries()), _r = _q.next(); !_r.done; _r = _q.next()) {
@@ -2331,12 +2454,12 @@ var AcDbDatabase = /** @class */ (function (_super) {
2331
2454
  mlineStyle.dxfOut(filer);
2332
2455
  }
2333
2456
  }
2334
- catch (e_18_1) { e_18 = { error: e_18_1 }; }
2457
+ catch (e_17_1) { e_17 = { error: e_17_1 }; }
2335
2458
  finally {
2336
2459
  try {
2337
2460
  if (_r && !_r.done && (_d = _q.return)) _d.call(_q);
2338
2461
  }
2339
- finally { if (e_18) throw e_18.error; }
2462
+ finally { if (e_17) throw e_17.error; }
2340
2463
  }
2341
2464
  try {
2342
2465
  for (var _t = __values(this.objects.xrecord.entries()), _u = _t.next(); !_u.done; _u = _t.next()) {
@@ -2345,12 +2468,12 @@ var AcDbDatabase = /** @class */ (function (_super) {
2345
2468
  xrecord.dxfOut(filer);
2346
2469
  }
2347
2470
  }
2348
- catch (e_19_1) { e_19 = { error: e_19_1 }; }
2471
+ catch (e_18_1) { e_18 = { error: e_18_1 }; }
2349
2472
  finally {
2350
2473
  try {
2351
2474
  if (_u && !_u.done && (_e = _t.return)) _e.call(_t);
2352
2475
  }
2353
- finally { if (e_19) throw e_19.error; }
2476
+ finally { if (e_18) throw e_18.error; }
2354
2477
  }
2355
2478
  filer.endSection();
2356
2479
  };
@@ -2364,7 +2487,7 @@ var AcDbDatabase = /** @class */ (function (_super) {
2364
2487
  * @param recordType - DXF record type name for each table record.
2365
2488
  */
2366
2489
  AcDbDatabase.prototype.writeDxfTable = function (filer, tableName, table, records, recordType) {
2367
- var e_20, _a;
2490
+ var e_19, _a;
2368
2491
  var items = __spreadArray([], __read(records), false);
2369
2492
  filer.startTable(tableName);
2370
2493
  table.dxfOut(filer);
@@ -2380,12 +2503,12 @@ var AcDbDatabase = /** @class */ (function (_super) {
2380
2503
  record.dxfOut(filer);
2381
2504
  }
2382
2505
  }
2383
- catch (e_20_1) { e_20 = { error: e_20_1 }; }
2506
+ catch (e_19_1) { e_19 = { error: e_19_1 }; }
2384
2507
  finally {
2385
2508
  try {
2386
2509
  if (items_1_1 && !items_1_1.done && (_a = items_1.return)) _a.call(items_1);
2387
2510
  }
2388
- finally { if (e_20) throw e_20.error; }
2511
+ finally { if (e_19) throw e_19.error; }
2389
2512
  }
2390
2513
  filer.endTable();
2391
2514
  };
@@ -2431,6 +2554,7 @@ var AcDbDatabase = /** @class */ (function (_super) {
2431
2554
  this._objects.xrecord.removeAll();
2432
2555
  this._currentSpace = undefined;
2433
2556
  this._extents.makeEmpty();
2557
+ this.registerBootstrapHandles();
2434
2558
  };
2435
2559
  /**
2436
2560
  * Updates a sysvar value and dispatches the change event only when the value changed.