@excalidraw/element 0.18.0-1b287a8ba → 0.18.0-3085f4a

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 (43) hide show
  1. package/dist/dev/index.js +337 -152
  2. package/dist/dev/index.js.map +3 -3
  3. package/dist/prod/index.js +11 -11
  4. package/dist/types/common/src/constants.d.ts +3 -0
  5. package/dist/types/element/src/Scene.d.ts +6 -2
  6. package/dist/types/element/src/delta.d.ts +16 -4
  7. package/dist/types/element/src/linearElementEditor.d.ts +2 -1
  8. package/dist/types/element/src/store.d.ts +6 -1
  9. package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +0 -3
  10. package/dist/types/excalidraw/actions/actionBoundText.d.ts +0 -2
  11. package/dist/types/excalidraw/actions/actionCanvas.d.ts +15 -14
  12. package/dist/types/excalidraw/actions/actionClipboard.d.ts +3 -8
  13. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +0 -1
  14. package/dist/types/excalidraw/actions/actionDeleteSelected.d.ts +3 -6
  15. package/dist/types/excalidraw/actions/actionElementLink.d.ts +0 -1
  16. package/dist/types/excalidraw/actions/actionElementLock.d.ts +0 -2
  17. package/dist/types/excalidraw/actions/actionEmbeddable.d.ts +0 -1
  18. package/dist/types/excalidraw/actions/actionExport.d.ts +0 -9
  19. package/dist/types/excalidraw/actions/actionFinalize.d.ts +2 -3
  20. package/dist/types/excalidraw/actions/actionFrame.d.ts +0 -4
  21. package/dist/types/excalidraw/actions/actionGroup.d.ts +0 -2
  22. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +33 -3
  23. package/dist/types/excalidraw/actions/actionLink.d.ts +0 -1
  24. package/dist/types/excalidraw/actions/actionMenu.d.ts +0 -3
  25. package/dist/types/excalidraw/actions/actionNavigate.d.ts +0 -2
  26. package/dist/types/excalidraw/actions/actionProperties.d.ts +0 -15
  27. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +0 -1
  28. package/dist/types/excalidraw/actions/actionStyles.d.ts +0 -1
  29. package/dist/types/excalidraw/actions/actionToggleGridMode.d.ts +0 -1
  30. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +0 -1
  31. package/dist/types/excalidraw/actions/actionToggleSearchMenu.d.ts +0 -1
  32. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +0 -1
  33. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +0 -1
  34. package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +0 -1
  35. package/dist/types/excalidraw/components/Actions.d.ts +0 -4
  36. package/dist/types/excalidraw/components/App.d.ts +7 -2
  37. package/dist/types/excalidraw/components/shapes.d.ts +129 -1
  38. package/dist/types/excalidraw/data/reconcile.d.ts +1 -0
  39. package/dist/types/excalidraw/data/restore.d.ts +6 -1
  40. package/dist/types/excalidraw/index.d.ts +1 -1
  41. package/dist/types/excalidraw/renderer/staticScene.d.ts +4 -1
  42. package/dist/types/excalidraw/types.d.ts +7 -4
  43. package/package.json +3 -3
package/dist/dev/index.js CHANGED
@@ -5338,6 +5338,11 @@ var handleSegmentRelease = (arrow, fixedSegments, elementsMap) => {
5338
5338
  null,
5339
5339
  null
5340
5340
  );
5341
+ if (!restoredPoints || restoredPoints.length < 2) {
5342
+ throw new Error(
5343
+ "Property 'points' is required in the update returned by normalizeArrowElementUpdate()"
5344
+ );
5345
+ }
5341
5346
  const nextPoints = [];
5342
5347
  if (prevSegment) {
5343
5348
  for (let i = 0; i < prevSegment.index; i++) {
@@ -5583,8 +5588,13 @@ var handleEndpointDrag = (arrow, updatedPoints, fixedSegments, startHeading, end
5583
5588
  newPoints.push(globalUpdatedPoints[newPoints.length + offset]);
5584
5589
  }
5585
5590
  {
5586
- const secondPoint = globalUpdatedPoints[startIsSpecial ? 2 : 1];
5587
- const thirdPoint = globalUpdatedPoints[startIsSpecial ? 3 : 2];
5591
+ const secondPoint = globalUpdatedPoints.at(startIsSpecial ? 2 : 1);
5592
+ const thirdPoint = globalUpdatedPoints.at(startIsSpecial ? 3 : 2);
5593
+ if (!secondPoint || !thirdPoint) {
5594
+ throw new Error(
5595
+ `Second and third points must exist when handling endpoint drag (${startIsSpecial})`
5596
+ );
5597
+ }
5588
5598
  const startIsHorizontal = headingIsHorizontal(startHeading);
5589
5599
  const secondIsHorizontal = headingIsHorizontal(
5590
5600
  vectorToHeading(vectorFromPoint5(secondPoint, thirdPoint))
@@ -5630,8 +5640,17 @@ var handleEndpointDrag = (arrow, updatedPoints, fixedSegments, startHeading, end
5630
5640
  newPoints.unshift(startGlobalPoint);
5631
5641
  }
5632
5642
  {
5633
- const secondToLastPoint = globalUpdatedPoints[globalUpdatedPoints.length - (endIsSpecial ? 3 : 2)];
5634
- const thirdToLastPoint = globalUpdatedPoints[globalUpdatedPoints.length - (endIsSpecial ? 4 : 3)];
5643
+ const secondToLastPoint = globalUpdatedPoints.at(
5644
+ globalUpdatedPoints.length - (endIsSpecial ? 3 : 2)
5645
+ );
5646
+ const thirdToLastPoint = globalUpdatedPoints.at(
5647
+ globalUpdatedPoints.length - (endIsSpecial ? 4 : 3)
5648
+ );
5649
+ if (!secondToLastPoint || !thirdToLastPoint) {
5650
+ throw new Error(
5651
+ `Second and third to last points must exist when handling endpoint drag (${endIsSpecial})`
5652
+ );
5653
+ }
5635
5654
  const endIsHorizontal = headingIsHorizontal(endHeading);
5636
5655
  const secondIsHorizontal = headingForPointIsHorizontal(
5637
5656
  thirdToLastPoint,
@@ -8127,7 +8146,8 @@ var LinearElementEditor = class _LinearElementEditor {
8127
8146
  segmentMidPointHoveredCoords;
8128
8147
  elbowed;
8129
8148
  customLineAngle;
8130
- constructor(element, elementsMap) {
8149
+ isEditing;
8150
+ constructor(element, elementsMap, isEditing = false) {
8131
8151
  this.elementId = element.id;
8132
8152
  if (!pointsEqual6(element.points[0], pointFrom8(0, 0))) {
8133
8153
  console.error("Linear element is not normalized", Error().stack);
@@ -8158,6 +8178,7 @@ var LinearElementEditor = class _LinearElementEditor {
8158
8178
  this.segmentMidPointHoveredCoords = null;
8159
8179
  this.elbowed = isElbowArrow(element) && element.elbowed;
8160
8180
  this.customLineAngle = null;
8181
+ this.isEditing = isEditing;
8161
8182
  }
8162
8183
  // ---------------------------------------------------------------------------
8163
8184
  // static methods
@@ -8175,11 +8196,11 @@ var LinearElementEditor = class _LinearElementEditor {
8175
8196
  return null;
8176
8197
  }
8177
8198
  static handleBoxSelection(event, appState, setState, elementsMap) {
8178
- if (!appState.editingLinearElement || !appState.selectionElement) {
8199
+ if (!appState.selectedLinearElement?.isEditing || !appState.selectionElement) {
8179
8200
  return false;
8180
8201
  }
8181
- const { editingLinearElement } = appState;
8182
- const { selectedPointsIndices, elementId } = editingLinearElement;
8202
+ const { selectedLinearElement } = appState;
8203
+ const { selectedPointsIndices, elementId } = selectedLinearElement;
8183
8204
  const element = _LinearElementEditor.getElement(elementId, elementsMap);
8184
8205
  if (!element) {
8185
8206
  return false;
@@ -8201,8 +8222,8 @@ var LinearElementEditor = class _LinearElementEditor {
8201
8222
  return true;
8202
8223
  });
8203
8224
  setState({
8204
- editingLinearElement: {
8205
- ...editingLinearElement,
8225
+ selectedLinearElement: {
8226
+ ...selectedLinearElement,
8206
8227
  selectedPointsIndices: nextSelectedPoints.length ? nextSelectedPoints : null
8207
8228
  }
8208
8229
  });
@@ -8356,7 +8377,6 @@ var LinearElementEditor = class _LinearElementEditor {
8356
8377
  };
8357
8378
  return {
8358
8379
  ...app.state,
8359
- editingLinearElement: app.state.editingLinearElement ? newLinearElementEditor : null,
8360
8380
  selectedLinearElement: newLinearElementEditor,
8361
8381
  suggestedBindings
8362
8382
  };
@@ -8440,7 +8460,7 @@ var LinearElementEditor = class _LinearElementEditor {
8440
8460
  }
8441
8461
  static getEditorMidPoints = (element, elementsMap, appState) => {
8442
8462
  const boundText = getBoundTextElement(element, elementsMap);
8443
- if (!isElbowArrow(element) && !appState.editingLinearElement && element.points.length > 2 && !boundText) {
8463
+ if (!isElbowArrow(element) && !appState.selectedLinearElement?.isEditing && element.points.length > 2 && !boundText) {
8444
8464
  return [];
8445
8465
  }
8446
8466
  const points = _LinearElementEditor.getPointsGlobalCoordinates(
@@ -8490,7 +8510,7 @@ var LinearElementEditor = class _LinearElementEditor {
8490
8510
  element,
8491
8511
  elementsMap
8492
8512
  );
8493
- if (points.length >= 3 && !appState.editingLinearElement && !isElbowArrow(element)) {
8513
+ if (points.length >= 3 && !appState.selectedLinearElement?.isEditing && !isElbowArrow(element)) {
8494
8514
  return null;
8495
8515
  }
8496
8516
  const threshold = (_LinearElementEditor.POINT_HANDLE_SIZE + 1) / appState.zoom.value;
@@ -8630,7 +8650,7 @@ var LinearElementEditor = class _LinearElementEditor {
8630
8650
  segmentMidpoint,
8631
8651
  elementsMap
8632
8652
  );
8633
- } else if (event.altKey && appState.editingLinearElement) {
8653
+ } else if (event.altKey && appState.selectedLinearElement?.isEditing) {
8634
8654
  if (linearElementEditor.lastUncommittedPoint == null) {
8635
8655
  scene.mutateElement(element, {
8636
8656
  points: [
@@ -8740,14 +8760,14 @@ var LinearElementEditor = class _LinearElementEditor {
8740
8760
  }
8741
8761
  static handlePointerMove(event, scenePointerX, scenePointerY, app) {
8742
8762
  const appState = app.state;
8743
- if (!appState.editingLinearElement) {
8763
+ if (!appState.selectedLinearElement?.isEditing) {
8744
8764
  return null;
8745
8765
  }
8746
- const { elementId, lastUncommittedPoint } = appState.editingLinearElement;
8766
+ const { elementId, lastUncommittedPoint } = appState.selectedLinearElement;
8747
8767
  const elementsMap = app.scene.getNonDeletedElementsMap();
8748
8768
  const element = _LinearElementEditor.getElement(elementId, elementsMap);
8749
8769
  if (!element) {
8750
- return appState.editingLinearElement;
8770
+ return appState.selectedLinearElement;
8751
8771
  }
8752
8772
  const { points } = element;
8753
8773
  const lastPoint = points[points.length - 1];
@@ -8755,10 +8775,10 @@ var LinearElementEditor = class _LinearElementEditor {
8755
8775
  if (lastPoint === lastUncommittedPoint) {
8756
8776
  _LinearElementEditor.deletePoints(element, app, [points.length - 1]);
8757
8777
  }
8758
- return {
8759
- ...appState.editingLinearElement,
8778
+ return appState.selectedLinearElement?.lastUncommittedPoint ? {
8779
+ ...appState.selectedLinearElement,
8760
8780
  lastUncommittedPoint: null
8761
- };
8781
+ } : appState.selectedLinearElement;
8762
8782
  }
8763
8783
  let newPoint;
8764
8784
  if (shouldRotateWithDiscreteAngle(event) && points.length >= 2) {
@@ -8778,8 +8798,8 @@ var LinearElementEditor = class _LinearElementEditor {
8778
8798
  newPoint = _LinearElementEditor.createPointAt(
8779
8799
  element,
8780
8800
  elementsMap,
8781
- scenePointerX - appState.editingLinearElement.pointerOffset.x,
8782
- scenePointerY - appState.editingLinearElement.pointerOffset.y,
8801
+ scenePointerX - appState.selectedLinearElement.pointerOffset.x,
8802
+ scenePointerY - appState.selectedLinearElement.pointerOffset.y,
8783
8803
  event[KEYS2.CTRL_OR_CMD] || isElbowArrow(element) ? null : app.getEffectiveGridSize()
8784
8804
  );
8785
8805
  }
@@ -8800,7 +8820,7 @@ var LinearElementEditor = class _LinearElementEditor {
8800
8820
  _LinearElementEditor.addPoints(element, app.scene, [newPoint]);
8801
8821
  }
8802
8822
  return {
8803
- ...appState.editingLinearElement,
8823
+ ...appState.selectedLinearElement,
8804
8824
  lastUncommittedPoint: element.points[element.points.length - 1]
8805
8825
  };
8806
8826
  }
@@ -8906,11 +8926,11 @@ var LinearElementEditor = class _LinearElementEditor {
8906
8926
  // ---------------------------------------------------------------------------
8907
8927
  static duplicateSelectedPoints(appState, scene) {
8908
8928
  invariant6(
8909
- appState.editingLinearElement,
8929
+ appState.selectedLinearElement?.isEditing,
8910
8930
  "Not currently editing a linear element"
8911
8931
  );
8912
8932
  const elementsMap = scene.getNonDeletedElementsMap();
8913
- const { selectedPointsIndices, elementId } = appState.editingLinearElement;
8933
+ const { selectedPointsIndices, elementId } = appState.selectedLinearElement;
8914
8934
  const element = _LinearElementEditor.getElement(elementId, elementsMap);
8915
8935
  invariant6(
8916
8936
  element,
@@ -8957,14 +8977,14 @@ var LinearElementEditor = class _LinearElementEditor {
8957
8977
  }
8958
8978
  return {
8959
8979
  ...appState,
8960
- editingLinearElement: {
8961
- ...appState.editingLinearElement,
8980
+ selectedLinearElement: {
8981
+ ...appState.selectedLinearElement,
8962
8982
  selectedPointsIndices: nextSelectedIndices
8963
8983
  }
8964
8984
  };
8965
8985
  }
8966
8986
  static deletePoints(element, app, pointIndices) {
8967
- const isUncommittedPoint = app.state.editingLinearElement?.lastUncommittedPoint === element.points[element.points.length - 1];
8987
+ const isUncommittedPoint = app.state.selectedLinearElement?.isEditing && app.state.selectedLinearElement?.lastUncommittedPoint === element.points[element.points.length - 1];
8968
8988
  const nextPoints = element.points.filter((_, idx) => {
8969
8989
  return !pointIndices.includes(idx);
8970
8990
  });
@@ -9073,7 +9093,7 @@ var LinearElementEditor = class _LinearElementEditor {
9073
9093
  pointFrom8(origin.x, origin.y),
9074
9094
  pointFrom8(pointerCoords.x, pointerCoords.y)
9075
9095
  );
9076
- if (!appState.editingLinearElement && dist < DRAGGING_THRESHOLD / appState.zoom.value) {
9096
+ if (!appState.selectedLinearElement?.isEditing && dist < DRAGGING_THRESHOLD / appState.zoom.value) {
9077
9097
  return false;
9078
9098
  }
9079
9099
  return true;
@@ -10562,6 +10582,11 @@ var getCanvasPadding = (element) => {
10562
10582
  return element.strokeWidth * 12;
10563
10583
  case "text":
10564
10584
  return element.fontSize / 2;
10585
+ case "arrow":
10586
+ if (element.endArrowhead || element.endArrowhead) {
10587
+ return 40;
10588
+ }
10589
+ return 20;
10565
10590
  default:
10566
10591
  return 20;
10567
10592
  }
@@ -13231,8 +13256,9 @@ var Store = class {
13231
13256
  constructor(app) {
13232
13257
  this.app = app;
13233
13258
  }
13234
- // internally used by history
13259
+ // for internal use by history
13235
13260
  onDurableIncrementEmitter = new Emitter();
13261
+ // for public use as part of onIncrement API
13236
13262
  onStoreIncrementEmitter = new Emitter();
13237
13263
  scheduledMacroActions = /* @__PURE__ */ new Set();
13238
13264
  scheduledMicroActions = [];
@@ -13488,7 +13514,7 @@ var EphemeralIncrement = class extends StoreIncrement {
13488
13514
  this.change = change;
13489
13515
  }
13490
13516
  };
13491
- var StoreDelta = class {
13517
+ var StoreDelta = class _StoreDelta {
13492
13518
  constructor(id, elements, appState) {
13493
13519
  this.id = id;
13494
13520
  this.elements = elements;
@@ -13526,10 +13552,23 @@ var StoreDelta = class {
13526
13552
  */
13527
13553
  static load({
13528
13554
  id,
13529
- elements: { added, removed, updated }
13555
+ elements: { added, removed, updated },
13556
+ appState: { delta: appStateDelta }
13530
13557
  }) {
13531
13558
  const elements = ElementsDelta.create(added, removed, updated);
13532
- return new this(id, elements, AppStateDelta.empty());
13559
+ const appState = AppStateDelta.create(appStateDelta);
13560
+ return new this(id, elements, appState);
13561
+ }
13562
+ /**
13563
+ * Squash the passed deltas into the aggregated delta instance.
13564
+ */
13565
+ static squash(...deltas) {
13566
+ const aggregatedDelta = _StoreDelta.empty();
13567
+ for (const delta of deltas) {
13568
+ aggregatedDelta.elements.squash(delta.elements);
13569
+ aggregatedDelta.appState.squash(delta.appState);
13570
+ }
13571
+ return aggregatedDelta;
13533
13572
  }
13534
13573
  /**
13535
13574
  * Inverse store delta, creates new instance of `StoreDelta`.
@@ -13540,9 +13579,7 @@ var StoreDelta = class {
13540
13579
  /**
13541
13580
  * Apply the delta to the passed elements and appState, does not modify the snapshot.
13542
13581
  */
13543
- static applyTo(delta, elements, appState, options = {
13544
- excludedProperties: /* @__PURE__ */ new Set()
13545
- }) {
13582
+ static applyTo(delta, elements, appState, options) {
13546
13583
  const [nextElements, elementsContainVisibleChange] = delta.elements.applyTo(
13547
13584
  elements,
13548
13585
  StoreSnapshot.empty().elements,
@@ -13568,6 +13605,9 @@ var StoreDelta = class {
13568
13605
  }
13569
13606
  );
13570
13607
  }
13608
+ static empty() {
13609
+ return _StoreDelta.create(ElementsDelta.empty(), AppStateDelta.empty());
13610
+ }
13571
13611
  isEmpty() {
13572
13612
  return this.elements.isEmpty() && this.appState.isEmpty();
13573
13613
  }
@@ -13808,8 +13848,7 @@ var getDefaultObservedAppState = () => {
13808
13848
  viewBackgroundColor: COLOR_PALETTE2.white,
13809
13849
  selectedElementIds: {},
13810
13850
  selectedGroupIds: {},
13811
- editingLinearElementId: null,
13812
- selectedLinearElementId: null,
13851
+ selectedLinearElement: null,
13813
13852
  croppingElementId: null,
13814
13853
  activeLockedId: null,
13815
13854
  lockedMultiSelections: {}
@@ -13825,10 +13864,10 @@ var getObservedAppState = (appState) => {
13825
13864
  croppingElementId: appState.croppingElementId,
13826
13865
  activeLockedId: appState.activeLockedId,
13827
13866
  lockedMultiSelections: appState.lockedMultiSelections,
13828
- editingLinearElementId: appState.editingLinearElement?.elementId ?? // prefer app state, as it's likely newer
13829
- appState.editingLinearElementId ?? // fallback to observed app state, as it's likely older coming from a previous snapshot
13830
- null,
13831
- selectedLinearElementId: appState.selectedLinearElement?.elementId ?? appState.selectedLinearElementId ?? null
13867
+ selectedLinearElement: appState.selectedLinearElement ? {
13868
+ elementId: appState.selectedLinearElement.elementId,
13869
+ isEditing: !!appState.selectedLinearElement.isEditing
13870
+ } : null
13832
13871
  };
13833
13872
  Reflect.defineProperty(observedAppState, hiddenObservedAppStateProp, {
13834
13873
  value: true,
@@ -14392,9 +14431,9 @@ var Scene = class {
14392
14431
  getFramesIncludingDeleted() {
14393
14432
  return this.frames;
14394
14433
  }
14395
- constructor(elements = null) {
14434
+ constructor(elements = null, options) {
14396
14435
  if (elements) {
14397
- this.replaceAllElements(elements);
14436
+ this.replaceAllElements(elements, options);
14398
14437
  }
14399
14438
  }
14400
14439
  getSelectedElements(opts) {
@@ -14459,10 +14498,12 @@ var Scene = class {
14459
14498
  }
14460
14499
  return didChange;
14461
14500
  }
14462
- replaceAllElements(nextElements) {
14501
+ replaceAllElements(nextElements, options) {
14463
14502
  const _nextElements = toArray(nextElements);
14464
14503
  const nextFrameLikes = [];
14465
- validateIndicesThrottled(_nextElements);
14504
+ if (!options?.skipValidation) {
14505
+ validateIndicesThrottled(_nextElements);
14506
+ }
14466
14507
  this.elements = syncInvalidIndices2(_nextElements);
14467
14508
  this.elementsMap.clear();
14468
14509
  this.elements.forEach((element) => {
@@ -14632,10 +14673,19 @@ var Delta = class _Delta {
14632
14673
  static isEmpty(delta) {
14633
14674
  return !Object.keys(delta.deleted).length && !Object.keys(delta.inserted).length;
14634
14675
  }
14676
+ /**
14677
+ * Merges two deltas into a new one.
14678
+ */
14679
+ static merge(delta1, delta2, delta3 = _Delta.empty()) {
14680
+ return _Delta.create(
14681
+ { ...delta1.deleted, ...delta2.deleted, ...delta3.deleted },
14682
+ { ...delta1.inserted, ...delta2.inserted, ...delta3.inserted }
14683
+ );
14684
+ }
14635
14685
  /**
14636
14686
  * Merges deleted and inserted object partials.
14637
14687
  */
14638
- static mergeObjects(prev, added, removed) {
14688
+ static mergeObjects(prev, added, removed = {}) {
14639
14689
  const cloned = { ...prev };
14640
14690
  for (const key of Object.keys(removed)) {
14641
14691
  delete cloned[key];
@@ -14856,6 +14906,9 @@ var AppStateDelta = class _AppStateDelta {
14856
14906
  constructor(delta) {
14857
14907
  this.delta = delta;
14858
14908
  }
14909
+ static create(delta) {
14910
+ return new _AppStateDelta(delta);
14911
+ }
14859
14912
  static calculate(prevAppState, nextAppState) {
14860
14913
  const delta = Delta.calculate(
14861
14914
  prevAppState,
@@ -14877,50 +14930,98 @@ var AppStateDelta = class _AppStateDelta {
14877
14930
  const inversedDelta = Delta.create(this.delta.inserted, this.delta.deleted);
14878
14931
  return new _AppStateDelta(inversedDelta);
14879
14932
  }
14933
+ squash(delta) {
14934
+ if (delta.isEmpty()) {
14935
+ return this;
14936
+ }
14937
+ const mergedDeletedSelectedElementIds = Delta.mergeObjects(
14938
+ this.delta.deleted.selectedElementIds ?? {},
14939
+ delta.delta.deleted.selectedElementIds ?? {}
14940
+ );
14941
+ const mergedInsertedSelectedElementIds = Delta.mergeObjects(
14942
+ this.delta.inserted.selectedElementIds ?? {},
14943
+ delta.delta.inserted.selectedElementIds ?? {}
14944
+ );
14945
+ const mergedDeletedSelectedGroupIds = Delta.mergeObjects(
14946
+ this.delta.deleted.selectedGroupIds ?? {},
14947
+ delta.delta.deleted.selectedGroupIds ?? {}
14948
+ );
14949
+ const mergedInsertedSelectedGroupIds = Delta.mergeObjects(
14950
+ this.delta.inserted.selectedGroupIds ?? {},
14951
+ delta.delta.inserted.selectedGroupIds ?? {}
14952
+ );
14953
+ const mergedDeletedLockedMultiSelections = Delta.mergeObjects(
14954
+ this.delta.deleted.lockedMultiSelections ?? {},
14955
+ delta.delta.deleted.lockedMultiSelections ?? {}
14956
+ );
14957
+ const mergedInsertedLockedMultiSelections = Delta.mergeObjects(
14958
+ this.delta.inserted.lockedMultiSelections ?? {},
14959
+ delta.delta.inserted.lockedMultiSelections ?? {}
14960
+ );
14961
+ const mergedInserted = {};
14962
+ const mergedDeleted = {};
14963
+ if (Object.keys(mergedDeletedSelectedElementIds).length || Object.keys(mergedInsertedSelectedElementIds).length) {
14964
+ mergedDeleted.selectedElementIds = mergedDeletedSelectedElementIds;
14965
+ mergedInserted.selectedElementIds = mergedInsertedSelectedElementIds;
14966
+ }
14967
+ if (Object.keys(mergedDeletedSelectedGroupIds).length || Object.keys(mergedInsertedSelectedGroupIds).length) {
14968
+ mergedDeleted.selectedGroupIds = mergedDeletedSelectedGroupIds;
14969
+ mergedInserted.selectedGroupIds = mergedInsertedSelectedGroupIds;
14970
+ }
14971
+ if (Object.keys(mergedDeletedLockedMultiSelections).length || Object.keys(mergedInsertedLockedMultiSelections).length) {
14972
+ mergedDeleted.lockedMultiSelections = mergedDeletedLockedMultiSelections;
14973
+ mergedInserted.lockedMultiSelections = mergedInsertedLockedMultiSelections;
14974
+ }
14975
+ this.delta = Delta.merge(
14976
+ this.delta,
14977
+ delta.delta,
14978
+ Delta.create(mergedDeleted, mergedInserted)
14979
+ );
14980
+ return this;
14981
+ }
14880
14982
  applyTo(appState, nextElements) {
14881
14983
  try {
14882
14984
  const {
14883
- selectedElementIds: removedSelectedElementIds = {},
14884
- selectedGroupIds: removedSelectedGroupIds = {}
14985
+ selectedElementIds: deletedSelectedElementIds = {},
14986
+ selectedGroupIds: deletedSelectedGroupIds = {},
14987
+ lockedMultiSelections: deletedLockedMultiSelections = {}
14885
14988
  } = this.delta.deleted;
14886
14989
  const {
14887
- selectedElementIds: addedSelectedElementIds = {},
14888
- selectedGroupIds: addedSelectedGroupIds = {},
14889
- selectedLinearElementId,
14890
- editingLinearElementId,
14990
+ selectedElementIds: insertedSelectedElementIds = {},
14991
+ selectedGroupIds: insertedSelectedGroupIds = {},
14992
+ lockedMultiSelections: insertedLockedMultiSelections = {},
14993
+ selectedLinearElement: insertedSelectedLinearElement,
14891
14994
  ...directlyApplicablePartial
14892
14995
  } = this.delta.inserted;
14893
14996
  const mergedSelectedElementIds = Delta.mergeObjects(
14894
14997
  appState.selectedElementIds,
14895
- addedSelectedElementIds,
14896
- removedSelectedElementIds
14998
+ insertedSelectedElementIds,
14999
+ deletedSelectedElementIds
14897
15000
  );
14898
15001
  const mergedSelectedGroupIds = Delta.mergeObjects(
14899
15002
  appState.selectedGroupIds,
14900
- addedSelectedGroupIds,
14901
- removedSelectedGroupIds
15003
+ insertedSelectedGroupIds,
15004
+ deletedSelectedGroupIds
14902
15005
  );
14903
- const selectedLinearElement = selectedLinearElementId && nextElements.has(selectedLinearElementId) ? new LinearElementEditor(
14904
- nextElements.get(
14905
- selectedLinearElementId
14906
- ),
14907
- nextElements
14908
- ) : null;
14909
- const editingLinearElement = editingLinearElementId && nextElements.has(editingLinearElementId) ? new LinearElementEditor(
15006
+ const mergedLockedMultiSelections = Delta.mergeObjects(
15007
+ appState.lockedMultiSelections,
15008
+ insertedLockedMultiSelections,
15009
+ deletedLockedMultiSelections
15010
+ );
15011
+ const selectedLinearElement = insertedSelectedLinearElement && nextElements.has(insertedSelectedLinearElement.elementId) ? new LinearElementEditor(
14910
15012
  nextElements.get(
14911
- editingLinearElementId
15013
+ insertedSelectedLinearElement.elementId
14912
15014
  ),
14913
- nextElements
15015
+ nextElements,
15016
+ insertedSelectedLinearElement.isEditing
14914
15017
  ) : null;
14915
15018
  const nextAppState = {
14916
15019
  ...appState,
14917
15020
  ...directlyApplicablePartial,
14918
15021
  selectedElementIds: mergedSelectedElementIds,
14919
15022
  selectedGroupIds: mergedSelectedGroupIds,
14920
- selectedLinearElement: typeof selectedLinearElementId !== "undefined" ? selectedLinearElement : appState.selectedLinearElement,
14921
- // otherwise assign what we had before
14922
- editingLinearElement: typeof editingLinearElementId !== "undefined" ? editingLinearElement : appState.editingLinearElement
14923
- // otherwise assign what we had before
15023
+ lockedMultiSelections: mergedLockedMultiSelections,
15024
+ selectedLinearElement: typeof insertedSelectedLinearElement !== "undefined" ? selectedLinearElement : appState.selectedLinearElement
14924
15025
  };
14925
15026
  const constainsVisibleChanges = this.filterInvisibleChanges(
14926
15027
  appState,
@@ -15010,57 +15111,44 @@ var AppStateDelta = class _AppStateDelta {
15010
15111
  nextAppState[key] = null;
15011
15112
  }
15012
15113
  break;
15013
- case "selectedLinearElementId":
15014
- case "editingLinearElementId":
15015
- const appStateKey = _AppStateDelta.convertToAppStateKey(key);
15016
- const linearElement = nextAppState[appStateKey];
15017
- if (!linearElement) {
15114
+ case "selectedLinearElement":
15115
+ const nextLinearElement = nextAppState[key];
15116
+ if (!nextLinearElement) {
15018
15117
  visibleDifferenceFlag.value = true;
15019
15118
  } else {
15020
- const element = nextElements.get(linearElement.elementId);
15119
+ const element = nextElements.get(nextLinearElement.elementId);
15021
15120
  if (element && !element.isDeleted) {
15022
15121
  visibleDifferenceFlag.value = true;
15023
15122
  } else {
15024
- nextAppState[appStateKey] = null;
15123
+ nextAppState[key] = null;
15025
15124
  }
15026
15125
  }
15027
15126
  break;
15028
- case "lockedMultiSelections": {
15127
+ case "lockedMultiSelections":
15029
15128
  const prevLockedUnits = prevAppState[key] || {};
15030
15129
  const nextLockedUnits = nextAppState[key] || {};
15031
15130
  if (!isShallowEqual2(prevLockedUnits, nextLockedUnits)) {
15032
15131
  visibleDifferenceFlag.value = true;
15033
15132
  }
15034
15133
  break;
15035
- }
15036
- case "activeLockedId": {
15134
+ case "activeLockedId":
15037
15135
  const prevHitLockedId = prevAppState[key] || null;
15038
15136
  const nextHitLockedId = nextAppState[key] || null;
15039
15137
  if (prevHitLockedId !== nextHitLockedId) {
15040
15138
  visibleDifferenceFlag.value = true;
15041
15139
  }
15042
15140
  break;
15043
- }
15044
- default: {
15141
+ default:
15045
15142
  assertNever4(
15046
15143
  key,
15047
15144
  `Unknown ObservedElementsAppState's key "${key}"`,
15048
15145
  true
15049
15146
  );
15050
- }
15051
15147
  }
15052
15148
  }
15053
15149
  }
15054
15150
  return visibleDifferenceFlag.value;
15055
15151
  }
15056
- static convertToAppStateKey(key) {
15057
- switch (key) {
15058
- case "selectedLinearElementId":
15059
- return "selectedLinearElement";
15060
- case "editingLinearElementId":
15061
- return "editingLinearElement";
15062
- }
15063
- }
15064
15152
  static filterSelectedElements(selectedElementIds, elements, visibleDifferenceFlag) {
15065
15153
  const ids = Object.keys(selectedElementIds);
15066
15154
  if (!ids.length) {
@@ -15099,8 +15187,7 @@ var AppStateDelta = class _AppStateDelta {
15099
15187
  editingGroupId,
15100
15188
  selectedGroupIds,
15101
15189
  selectedElementIds,
15102
- editingLinearElementId,
15103
- selectedLinearElementId,
15190
+ selectedLinearElement,
15104
15191
  croppingElementId,
15105
15192
  lockedMultiSelections,
15106
15193
  activeLockedId,
@@ -15137,12 +15224,6 @@ var AppStateDelta = class _AppStateDelta {
15137
15224
  "lockedMultiSelections",
15138
15225
  (prevValue) => prevValue ?? {}
15139
15226
  );
15140
- Delta.diffObjects(
15141
- deleted,
15142
- inserted,
15143
- "activeLockedId",
15144
- (prevValue) => prevValue ?? null
15145
- );
15146
15227
  } catch (e) {
15147
15228
  console.error(`Couldn't postprocess appstate change deltas.`);
15148
15229
  if (isTestEnv8() || isDevEnv7()) {
@@ -15221,13 +15302,17 @@ var ElementsDelta = class _ElementsDelta {
15221
15302
  static satisfiesCommmonInvariants = ({
15222
15303
  deleted,
15223
15304
  inserted
15224
- }) => !!(deleted.version && inserted.version && // versions are required integers
15225
- Number.isInteger(deleted.version) && Number.isInteger(inserted.version) && // versions should be positive, zero included
15305
+ }) => !!// versions are required integers
15306
+ (Number.isInteger(deleted.version) && Number.isInteger(inserted.version) && // versions should be positive, zero included
15226
15307
  deleted.version >= 0 && inserted.version >= 0 && // versions should never be the same
15227
15308
  deleted.version !== inserted.version);
15309
+ static satisfiesUniqueInvariants = (elementsDelta, id) => {
15310
+ const { added, removed, updated } = elementsDelta;
15311
+ return [added[id], removed[id], updated[id]].filter(Boolean).length === 1;
15312
+ };
15228
15313
  static validate(elementsDelta, type, satifiesSpecialInvariants) {
15229
15314
  for (const [id, delta] of Object.entries(elementsDelta[type])) {
15230
- if (!this.satisfiesCommmonInvariants(delta) || !satifiesSpecialInvariants(delta)) {
15315
+ if (!this.satisfiesCommmonInvariants(delta) || !this.satisfiesUniqueInvariants(elementsDelta, id) || !satifiesSpecialInvariants(delta)) {
15231
15316
  console.error(
15232
15317
  `Broken invariant for "${type}" delta, element "${id}", delta:`,
15233
15318
  delta
@@ -15254,7 +15339,7 @@ var ElementsDelta = class _ElementsDelta {
15254
15339
  for (const prevElement of prevElements.values()) {
15255
15340
  const nextElement = nextElements.get(prevElement.id);
15256
15341
  if (!nextElement) {
15257
- const deleted = { ...prevElement, isDeleted: false };
15342
+ const deleted = { ...prevElement };
15258
15343
  const inserted = {
15259
15344
  isDeleted: true,
15260
15345
  version: prevElement.version + 1,
@@ -15265,7 +15350,11 @@ var ElementsDelta = class _ElementsDelta {
15265
15350
  inserted,
15266
15351
  _ElementsDelta.stripIrrelevantProps
15267
15352
  );
15268
- removed[prevElement.id] = delta;
15353
+ if (!prevElement.isDeleted) {
15354
+ removed[prevElement.id] = delta;
15355
+ } else {
15356
+ updated[prevElement.id] = delta;
15357
+ }
15269
15358
  }
15270
15359
  }
15271
15360
  for (const nextElement of nextElements.values()) {
@@ -15277,15 +15366,18 @@ var ElementsDelta = class _ElementsDelta {
15277
15366
  versionNonce: randomInteger4()
15278
15367
  };
15279
15368
  const inserted = {
15280
- ...nextElement,
15281
- isDeleted: false
15369
+ ...nextElement
15282
15370
  };
15283
15371
  const delta = Delta.create(
15284
15372
  deleted,
15285
15373
  inserted,
15286
15374
  _ElementsDelta.stripIrrelevantProps
15287
15375
  );
15288
- added[nextElement.id] = delta;
15376
+ if (!nextElement.isDeleted) {
15377
+ added[nextElement.id] = delta;
15378
+ } else {
15379
+ updated[nextElement.id] = delta;
15380
+ }
15289
15381
  continue;
15290
15382
  }
15291
15383
  if (prevElement.versionNonce !== nextElement.versionNonce) {
@@ -15306,9 +15398,7 @@ var ElementsDelta = class _ElementsDelta {
15306
15398
  }
15307
15399
  continue;
15308
15400
  }
15309
- if (!Delta.isEmpty(delta)) {
15310
- updated[nextElement.id] = delta;
15311
- }
15401
+ updated[nextElement.id] = delta;
15312
15402
  }
15313
15403
  }
15314
15404
  return _ElementsDelta.create(added, removed, updated);
@@ -15319,8 +15409,8 @@ var ElementsDelta = class _ElementsDelta {
15319
15409
  inverse() {
15320
15410
  const inverseInternal = (deltas) => {
15321
15411
  const inversedDeltas = {};
15322
- for (const [id, delta] of Object.entries(deltas)) {
15323
- inversedDeltas[id] = Delta.create(delta.inserted, delta.deleted);
15412
+ for (const [id, { inserted, deleted }] of Object.entries(deltas)) {
15413
+ inversedDeltas[id] = Delta.create({ ...inserted }, { ...deleted });
15324
15414
  }
15325
15415
  return inversedDeltas;
15326
15416
  };
@@ -15398,26 +15488,30 @@ var ElementsDelta = class _ElementsDelta {
15398
15488
  // redistribute the deltas as `isDeleted` could have been updated
15399
15489
  });
15400
15490
  }
15401
- applyTo(elements, snapshot = StoreSnapshot.empty().elements, options = {
15402
- excludedProperties: /* @__PURE__ */ new Set()
15403
- }) {
15491
+ applyTo(elements, snapshot = StoreSnapshot.empty().elements, options) {
15404
15492
  let nextElements = new Map(elements);
15405
15493
  let changedElements;
15406
15494
  const flags = {
15407
15495
  containsVisibleDifference: false,
15408
- containsZindexDifference: false
15496
+ containsZindexDifference: false,
15497
+ applyDirection: void 0
15409
15498
  };
15410
15499
  try {
15411
15500
  const applyDeltas = _ElementsDelta.createApplier(
15501
+ elements,
15412
15502
  nextElements,
15413
15503
  snapshot,
15414
- options,
15415
- flags
15504
+ flags,
15505
+ options
15416
15506
  );
15417
15507
  const addedElements = applyDeltas(this.added);
15418
15508
  const removedElements = applyDeltas(this.removed);
15419
15509
  const updatedElements = applyDeltas(this.updated);
15420
- const affectedElements = this.resolveConflicts(elements, nextElements);
15510
+ const affectedElements = this.resolveConflicts(
15511
+ elements,
15512
+ nextElements,
15513
+ flags.applyDirection
15514
+ );
15421
15515
  changedElements = new Map([
15422
15516
  ...addedElements,
15423
15517
  ...removedElements,
@@ -15437,9 +15531,7 @@ var ElementsDelta = class _ElementsDelta {
15437
15531
  changedElements,
15438
15532
  flags
15439
15533
  );
15440
- const tempScene = new Scene(nextElements);
15441
- _ElementsDelta.redrawTextBoundingBoxes(tempScene, changedElements);
15442
- _ElementsDelta.redrawBoundArrows(tempScene, changedElements);
15534
+ _ElementsDelta.redrawElements(nextElements, changedElements);
15443
15535
  } catch (e) {
15444
15536
  console.error(
15445
15537
  `Couldn't mutate elements after applying elements change`,
@@ -15452,7 +15544,82 @@ var ElementsDelta = class _ElementsDelta {
15452
15544
  return [nextElements, flags.containsVisibleDifference];
15453
15545
  }
15454
15546
  }
15455
- static createApplier = (nextElements, snapshot, options, flags) => (deltas) => {
15547
+ squash(delta) {
15548
+ if (delta.isEmpty()) {
15549
+ return this;
15550
+ }
15551
+ const { added, removed, updated } = delta;
15552
+ const mergeBoundElements = (prevDelta, nextDelta) => {
15553
+ const mergedDeletedBoundElements = Delta.mergeArrays(
15554
+ prevDelta.deleted.boundElements ?? [],
15555
+ nextDelta.deleted.boundElements ?? [],
15556
+ void 0,
15557
+ (x) => x.id
15558
+ ) ?? [];
15559
+ const mergedInsertedBoundElements = Delta.mergeArrays(
15560
+ prevDelta.inserted.boundElements ?? [],
15561
+ nextDelta.inserted.boundElements ?? [],
15562
+ void 0,
15563
+ (x) => x.id
15564
+ ) ?? [];
15565
+ if (!mergedDeletedBoundElements.length && !mergedInsertedBoundElements.length) {
15566
+ return;
15567
+ }
15568
+ return Delta.create(
15569
+ {
15570
+ boundElements: mergedDeletedBoundElements
15571
+ },
15572
+ {
15573
+ boundElements: mergedInsertedBoundElements
15574
+ }
15575
+ );
15576
+ };
15577
+ for (const [id, nextDelta] of Object.entries(added)) {
15578
+ const prevDelta = this.added[id] ?? this.removed[id] ?? this.updated[id];
15579
+ if (!prevDelta) {
15580
+ this.added[id] = nextDelta;
15581
+ } else {
15582
+ const mergedDelta = mergeBoundElements(prevDelta, nextDelta);
15583
+ delete this.removed[id];
15584
+ delete this.updated[id];
15585
+ this.added[id] = Delta.merge(prevDelta, nextDelta, mergedDelta);
15586
+ }
15587
+ }
15588
+ for (const [id, nextDelta] of Object.entries(removed)) {
15589
+ const prevDelta = this.added[id] ?? this.removed[id] ?? this.updated[id];
15590
+ if (!prevDelta) {
15591
+ this.removed[id] = nextDelta;
15592
+ } else {
15593
+ const mergedDelta = mergeBoundElements(prevDelta, nextDelta);
15594
+ delete this.added[id];
15595
+ delete this.updated[id];
15596
+ this.removed[id] = Delta.merge(prevDelta, nextDelta, mergedDelta);
15597
+ }
15598
+ }
15599
+ for (const [id, nextDelta] of Object.entries(updated)) {
15600
+ const prevDelta = this.added[id] ?? this.removed[id] ?? this.updated[id];
15601
+ if (!prevDelta) {
15602
+ this.updated[id] = nextDelta;
15603
+ } else {
15604
+ const mergedDelta = mergeBoundElements(prevDelta, nextDelta);
15605
+ const updatedDelta = Delta.merge(prevDelta, nextDelta, mergedDelta);
15606
+ if (prevDelta === this.added[id]) {
15607
+ this.added[id] = updatedDelta;
15608
+ } else if (prevDelta === this.removed[id]) {
15609
+ this.removed[id] = updatedDelta;
15610
+ } else {
15611
+ this.updated[id] = updatedDelta;
15612
+ }
15613
+ }
15614
+ }
15615
+ if (isTestEnv8() || isDevEnv7()) {
15616
+ _ElementsDelta.validate(this, "added", _ElementsDelta.satisfiesAddition);
15617
+ _ElementsDelta.validate(this, "removed", _ElementsDelta.satisfiesRemoval);
15618
+ _ElementsDelta.validate(this, "updated", _ElementsDelta.satisfiesUpdate);
15619
+ }
15620
+ return this;
15621
+ }
15622
+ static createApplier = (prevElements, nextElements, snapshot, flags, options) => (deltas) => {
15456
15623
  const getElement = _ElementsDelta.createGetter(
15457
15624
  nextElements,
15458
15625
  snapshot,
@@ -15461,14 +15628,20 @@ var ElementsDelta = class _ElementsDelta {
15461
15628
  return Object.entries(deltas).reduce((acc, [id, delta]) => {
15462
15629
  const element = getElement(id, delta.inserted);
15463
15630
  if (element) {
15464
- const newElement2 = _ElementsDelta.applyDelta(
15631
+ const nextElement = _ElementsDelta.applyDelta(
15465
15632
  element,
15466
15633
  delta,
15467
- options,
15468
- flags
15634
+ flags,
15635
+ options
15469
15636
  );
15470
- nextElements.set(newElement2.id, newElement2);
15471
- acc.set(newElement2.id, newElement2);
15637
+ nextElements.set(nextElement.id, nextElement);
15638
+ acc.set(nextElement.id, nextElement);
15639
+ if (!flags.applyDirection) {
15640
+ const prevElement = prevElements.get(id);
15641
+ if (prevElement) {
15642
+ flags.applyDirection = prevElement.version > nextElement.version ? "backward" : "forward";
15643
+ }
15644
+ }
15472
15645
  }
15473
15646
  return acc;
15474
15647
  }, /* @__PURE__ */ new Map());
@@ -15493,13 +15666,13 @@ var ElementsDelta = class _ElementsDelta {
15493
15666
  }
15494
15667
  return element;
15495
15668
  };
15496
- static applyDelta(element, delta, options, flags) {
15669
+ static applyDelta(element, delta, flags, options) {
15497
15670
  const directlyApplicablePartial = {};
15498
15671
  for (const key of Object.keys(delta.inserted)) {
15499
15672
  if (key === "boundElements") {
15500
15673
  continue;
15501
15674
  }
15502
- if (options.excludedProperties.has(key)) {
15675
+ if (options?.excludedProperties?.has(key)) {
15503
15676
  continue;
15504
15677
  }
15505
15678
  const value = delta.inserted[key];
@@ -15527,7 +15700,7 @@ var ElementsDelta = class _ElementsDelta {
15527
15700
  if (!flags.containsZindexDifference) {
15528
15701
  flags.containsZindexDifference = delta.deleted.index !== delta.inserted.index;
15529
15702
  }
15530
- return newElementWith(element, directlyApplicablePartial);
15703
+ return newElementWith(element, directlyApplicablePartial, true);
15531
15704
  }
15532
15705
  /**
15533
15706
  * Check for visible changes regardless of whether they were removed, added or updated.
@@ -15552,25 +15725,32 @@ var ElementsDelta = class _ElementsDelta {
15552
15725
  *
15553
15726
  * @returns all elements affected by the conflict resolution
15554
15727
  */
15555
- resolveConflicts(prevElements, nextElements) {
15728
+ resolveConflicts(prevElements, nextElements, applyDirection = "forward") {
15556
15729
  const nextAffectedElements = /* @__PURE__ */ new Map();
15557
15730
  const updater = (element, updates) => {
15558
15731
  const nextElement = nextElements.get(element.id);
15559
15732
  if (!nextElement) {
15560
15733
  return;
15561
15734
  }
15735
+ const prevElement = prevElements.get(element.id);
15736
+ const nextVersion = applyDirection === "forward" ? nextElement.version + 1 : nextElement.version - 1;
15737
+ const elementUpdates = updates;
15562
15738
  let affectedElement;
15563
- if (prevElements.get(element.id) === nextElement) {
15739
+ if (prevElement === nextElement) {
15564
15740
  affectedElement = newElementWith(
15565
15741
  nextElement,
15566
- updates
15742
+ {
15743
+ ...elementUpdates,
15744
+ version: nextVersion
15745
+ },
15746
+ true
15567
15747
  );
15568
15748
  } else {
15569
- affectedElement = mutateElement(
15570
- nextElement,
15571
- nextElements,
15572
- updates
15573
- );
15749
+ affectedElement = mutateElement(nextElement, nextElements, {
15750
+ ...elementUpdates,
15751
+ // don't modify the version further, if it's already different
15752
+ version: prevElement?.version !== nextElement.version ? nextElement.version : nextVersion
15753
+ });
15574
15754
  }
15575
15755
  nextAffectedElements.set(affectedElement.id, affectedElement);
15576
15756
  nextElements.set(affectedElement.id, affectedElement);
@@ -15595,19 +15775,10 @@ var ElementsDelta = class _ElementsDelta {
15595
15775
  const prevAffectedElements = new Map(
15596
15776
  Array.from(prevElements).filter(([id]) => nextAffectedElements.has(id))
15597
15777
  );
15598
- const { added, removed, updated } = _ElementsDelta.calculate(
15599
- prevAffectedElements,
15600
- nextAffectedElements
15778
+ this.squash(
15779
+ // technically we could do better here if perf. would become an issue
15780
+ _ElementsDelta.calculate(prevAffectedElements, nextAffectedElements)
15601
15781
  );
15602
- for (const [id, delta] of Object.entries(added)) {
15603
- this.added[id] = delta;
15604
- }
15605
- for (const [id, delta] of Object.entries(removed)) {
15606
- this.removed[id] = delta;
15607
- }
15608
- for (const [id, delta] of Object.entries(updated)) {
15609
- this.updated[id] = delta;
15610
- }
15611
15782
  return nextAffectedElements;
15612
15783
  }
15613
15784
  /**
@@ -15642,6 +15813,20 @@ var ElementsDelta = class _ElementsDelta {
15642
15813
  );
15643
15814
  BindableElement.rebindAffected(nextElements, nextElement(), updater);
15644
15815
  }
15816
+ static redrawElements(nextElements, changedElements) {
15817
+ try {
15818
+ const tempScene = new Scene(nextElements, { skipValidation: true });
15819
+ _ElementsDelta.redrawTextBoundingBoxes(tempScene, changedElements);
15820
+ _ElementsDelta.redrawBoundArrows(tempScene, changedElements);
15821
+ } catch (e) {
15822
+ console.error(`Couldn't redraw elements`, e);
15823
+ if (isTestEnv8() || isDevEnv7()) {
15824
+ throw e;
15825
+ }
15826
+ } finally {
15827
+ return nextElements;
15828
+ }
15829
+ }
15645
15830
  static redrawTextBoundingBoxes(scene, changed) {
15646
15831
  const elements = scene.getNonDeletedElementsMap();
15647
15832
  const boxesToRedraw = /* @__PURE__ */ new Map();
@@ -18453,7 +18638,7 @@ var getTransformHandles = (element, zoom, elementsMap, pointerType = "mouse", om
18453
18638
  );
18454
18639
  };
18455
18640
  var shouldShowBoundingBox = (elements, appState) => {
18456
- if (appState.editingLinearElement) {
18641
+ if (appState.selectedLinearElement?.isEditing) {
18457
18642
  return false;
18458
18643
  }
18459
18644
  if (elements.length > 1) {