@inditextech/weave-sdk 3.9.1 → 3.10.0

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.
package/dist/sdk.node.js CHANGED
@@ -4,6 +4,7 @@ import pino from "pino";
4
4
  import { WEAVE_ASYNC_STATUS, WEAVE_AWARENESS_LAYER_ID, WEAVE_EXPORT_BACKGROUND_COLOR, WEAVE_EXPORT_FORMATS, WEAVE_EXPORT_RETURN_FORMAT, WEAVE_INSTANCE_STATUS, WEAVE_KONVA_BACKEND, WEAVE_LOG_LEVEL, WEAVE_NODE_CHANGE_TYPE, WEAVE_NODE_CUSTOM_EVENTS, WEAVE_NODE_LAYER_ID, WEAVE_NODE_POSITION, WEAVE_STORE_CONNECTION_STATUS, WEAVE_UTILITY_LAYER_ID } from "@inditextech/weave-types";
5
5
  import { getYjsDoc, getYjsValue, observeDeep, syncedStore } from "@syncedstore/core";
6
6
  import * as Y from "yjs";
7
+ import simplify from "simplify-js";
7
8
  import "konva/lib/types";
8
9
 
9
10
  //#region rolldown:runtime
@@ -18833,7 +18834,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18833
18834
  const nodesSelected = tr.nodes();
18834
18835
  if (nodesSelected.length === 1) {
18835
18836
  const node = nodesSelected[0];
18836
- stage.container().style.cursor = node.defineMousePointer() ?? "grab";
18837
+ stage.container().style.cursor = (typeof node?.defineMousePointer === "function" ? node.defineMousePointer() : null) ?? "grab";
18837
18838
  } else stage.container().style.cursor = "grab";
18838
18839
  });
18839
18840
  tr.on("mouseout", (e) => {
@@ -18890,8 +18891,9 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18890
18891
  let selectedNodes = [];
18891
18892
  tr.on("dragstart", (e) => {
18892
18893
  this.dragInProcess = true;
18894
+ if (!e?.evt) return;
18893
18895
  let isWheelMousePressed = false;
18894
- if (e.evt.button === 1) isWheelMousePressed = true;
18896
+ if (e.evt?.button === 1) isWheelMousePressed = true;
18895
18897
  const mainLayer = this.instance.getMainLayer();
18896
18898
  if (!mainLayer) return;
18897
18899
  initialPos = {
@@ -18928,7 +18930,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18928
18930
  y: e.target.y()
18929
18931
  };
18930
18932
  let isWheelMousePressed = false;
18931
- if (e.evt.button === 1) isWheelMousePressed = true;
18933
+ if (e.evt?.button === 1) isWheelMousePressed = true;
18932
18934
  e.cancelBubble = true;
18933
18935
  if (initialPos) {
18934
18936
  const moved = this.checkMovedDrag(initialPos, actualPos);
@@ -19271,8 +19273,8 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19271
19273
  this.handledClickOrTap = false;
19272
19274
  this.pointers[e.evt.pointerId] = e.evt;
19273
19275
  if (e.evt.pointerType === "touch" && Object.keys(this.pointers).length > 1) return;
19274
- if (e.evt.pointerType === "mouse" && e.evt.button !== 0) return;
19275
- if (e.evt.pointerType === "pen" && e.evt.pressure <= .05) return;
19276
+ if (e.evt.pointerType === "mouse" && e.evt?.button !== 0) return;
19277
+ if (e.evt.pointerType === "pen" && e.evt?.pressure <= .05) return;
19276
19278
  if (!this.initialized) return;
19277
19279
  if (!this.active) return;
19278
19280
  if (stage.mode() !== WEAVE_STAGE_DEFAULT_MODE) return;
@@ -19325,8 +19327,9 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19325
19327
  this.panLoopId = requestAnimationFrame(() => this.panLoop());
19326
19328
  });
19327
19329
  const handleMouseMove = (e) => {
19330
+ if (!e?.evt) return;
19328
19331
  const moved = this.checkMoved(e);
19329
- if (e.evt.buttons === 0) return;
19332
+ if (e.evt?.buttons === 0) return;
19330
19333
  if (e.evt.pointerType === "touch" && Object.keys(this.pointers).length > 1) return;
19331
19334
  if (!this.initialized) return;
19332
19335
  if (!this.active) return;
@@ -19496,7 +19499,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19496
19499
  this.hideHoverState();
19497
19500
  const selectedGroup = getTargetedNode(this.instance);
19498
19501
  if (!this.initialized) return;
19499
- if (e.evt.pointerType === "mouse" && e.evt.button && e.evt.button !== 0) return;
19502
+ if (e.evt.pointerType === "mouse" && e.evt?.button && e.evt?.button !== 0) return;
19500
19503
  let areNodesSelected = false;
19501
19504
  let nodeTargeted = selectedGroup && !(selectedGroup.getAttrs().active ?? false) ? selectedGroup : e.target;
19502
19505
  if (e.target === this.instance.getStage()) {
@@ -19559,7 +19562,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19559
19562
  if (areNodesSelected) {
19560
19563
  stage.container().tabIndex = 1;
19561
19564
  stage.container().focus();
19562
- stage.container().style.cursor = nodeTargeted.defineMousePointer() ?? "grab";
19565
+ stage.container().style.cursor = (typeof nodeTargeted?.defineMousePointer === "function" ? nodeTargeted.defineMousePointer() : null) ?? "grab";
19563
19566
  }
19564
19567
  this.triggerSelectedNodesEvent();
19565
19568
  }
@@ -19727,6 +19730,10 @@ const WEAVE_COPY_PASTE_CONFIG_DEFAULT = {
19727
19730
  }
19728
19731
  };
19729
19732
 
19733
+ //#endregion
19734
+ //#region src/actions/fit-to-selection-tool/constants.ts
19735
+ const FIT_TO_SELECTION_TOOL_ACTION_NAME = "fitToSelectionTool";
19736
+
19730
19737
  //#endregion
19731
19738
  //#region src/plugins/copy-paste-nodes/copy-paste-nodes.ts
19732
19739
  var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
@@ -19938,8 +19945,8 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
19938
19945
  }
19939
19946
  const nodesSelectionPlugin = this.getNodesSelectionPlugin();
19940
19947
  nodesSelectionPlugin?.setSelectedNodes(realNodes);
19941
- this.instance?.triggerAction("fitToSelectionTool", {
19942
- previousAction: "selectionTool",
19948
+ this.instance?.triggerAction(FIT_TO_SELECTION_TOOL_ACTION_NAME, {
19949
+ previousAction: SELECTION_TOOL_ACTION_NAME,
19943
19950
  smartZoom: true
19944
19951
  });
19945
19952
  this.instance.emitEvent("onPaste", {
@@ -20214,6 +20221,33 @@ const augmentKonvaNodeClass = (config) => {
20214
20221
  Konva.Node.prototype.closeCrop = function() {};
20215
20222
  Konva.Node.prototype.resetCrop = function() {};
20216
20223
  Konva.Node.prototype.dblClick = function() {};
20224
+ Konva.Node.prototype.allowedAnchors = function() {
20225
+ return [];
20226
+ };
20227
+ Konva.Node.prototype.isSelectable = function() {
20228
+ return true;
20229
+ };
20230
+ Konva.Node.prototype.handleMouseover = function() {};
20231
+ Konva.Node.prototype.handleMouseout = function() {};
20232
+ Konva.Node.prototype.handleSelectNode = function() {};
20233
+ Konva.Node.prototype.handleDeselectNode = function() {};
20234
+ Konva.Node.prototype.defineMousePointer = function() {
20235
+ return "default";
20236
+ };
20237
+ Konva.Node.prototype.canBeHovered = function() {
20238
+ return false;
20239
+ };
20240
+ Konva.Node.prototype.canDrag = function() {
20241
+ return false;
20242
+ };
20243
+ Konva.Node.prototype.canMoveToContainer = function() {
20244
+ return false;
20245
+ };
20246
+ Konva.Node.prototype.getNodeAnchors = function() {
20247
+ return [];
20248
+ };
20249
+ Konva.Node.prototype.lockMutex = function() {};
20250
+ Konva.Node.prototype.releaseMutex = function() {};
20217
20251
  };
20218
20252
  var WeaveNode = class {
20219
20253
  async register(instance) {
@@ -20505,10 +20539,11 @@ var WeaveNode = class {
20505
20539
  node.off("dragstart");
20506
20540
  node.on("dragstart", (e) => {
20507
20541
  const nodeTarget = e.target;
20542
+ if (!e.evt) return;
20508
20543
  let isWheelMousePressed = false;
20509
- if (e.evt.button === 1) isWheelMousePressed = true;
20544
+ if (e.evt?.button === 1) isWheelMousePressed = true;
20510
20545
  this.getNodesSelectionFeedbackPlugin()?.hideSelectionHalo(nodeTarget);
20511
- const canMove = nodeTarget?.canDrag() ?? false;
20546
+ const canMove = typeof nodeTarget?.canDrag === "function" ? nodeTarget.canDrag() : false;
20512
20547
  if (!canMove) {
20513
20548
  nodeTarget.stopDrag();
20514
20549
  return;
@@ -20560,7 +20595,7 @@ var WeaveNode = class {
20560
20595
  nodesSelectionPlugin?.setSelectedNodes([]);
20561
20596
  requestAnimationFrame(() => {
20562
20597
  nodesSelectionPlugin?.setSelectedNodes(this.instance.getCloningManager().getClones());
20563
- clone?.startDrag(e.evt);
20598
+ if (clone?.getStage()) clone.startDrag(e.evt);
20564
20599
  });
20565
20600
  }
20566
20601
  if (this.getNodesSelectionPlugin()?.getSelectedNodes().length === 1) this.instance.setMutexLock({
@@ -20571,7 +20606,7 @@ var WeaveNode = class {
20571
20606
  const handleDragMove = (e) => {
20572
20607
  const nodeTarget = e.target;
20573
20608
  let isWheelMousePressed = false;
20574
- if (e.evt.button === 1) isWheelMousePressed = true;
20609
+ if (e.evt?.button === 1) isWheelMousePressed = true;
20575
20610
  e.cancelBubble = true;
20576
20611
  if (e.evt?.buttons === 0) {
20577
20612
  nodeTarget.stopDrag();
@@ -20763,12 +20798,12 @@ var WeaveNode = class {
20763
20798
  }
20764
20799
  if (isNodeSelectionEnabled && this.isSelecting() && !this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !(isLocked || isMutexLocked) && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
20765
20800
  showHover = true;
20766
- stage.container().style.cursor = realNode?.defineMousePointer() ?? "pointer";
20801
+ stage.container().style.cursor = (typeof node?.defineMousePointer === "function" ? node.defineMousePointer() : null) ?? "pointer";
20767
20802
  cancelBubble = true;
20768
20803
  }
20769
20804
  if (isNodeSelectionEnabled && this.isSelecting() && this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !(isLocked || isMutexLocked) && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
20770
20805
  showHover = true;
20771
- stage.container().style.cursor = realNode?.defineMousePointer() ?? "grab";
20806
+ stage.container().style.cursor = (typeof node?.defineMousePointer === "function" ? node.defineMousePointer() : null) ?? "grab";
20772
20807
  cancelBubble = true;
20773
20808
  }
20774
20809
  if (!isTargetable) cancelBubble = true;
@@ -22040,7 +22075,7 @@ var WeaveRegisterManager = class {
22040
22075
 
22041
22076
  //#endregion
22042
22077
  //#region package.json
22043
- var version = "3.9.1";
22078
+ var version = "3.10.0";
22044
22079
 
22045
22080
  //#endregion
22046
22081
  //#region src/managers/setup.ts
@@ -24218,6 +24253,7 @@ function loadImageSource(image, options) {
24218
24253
  }
24219
24254
  async function downscaleImageFile(file, ratio) {
24220
24255
  const bitmap = await createImageBitmap(file);
24256
+ if (bitmap.width === 0) throw new Error("Invalid image", { cause: "InvalidImage" });
24221
24257
  const width = Math.round(bitmap.width * ratio);
24222
24258
  const height = Math.round(bitmap.height * ratio);
24223
24259
  const canvas = document.createElement("canvas");
@@ -24234,13 +24270,19 @@ function getImageSizeFromFile(file) {
24234
24270
  const img = new Image();
24235
24271
  const url = URL.createObjectURL(file);
24236
24272
  img.onload = () => {
24273
+ if (img.naturalWidth === 0) {
24274
+ reject(new Error("Invalid image", { cause: "InvalidImage" }));
24275
+ return;
24276
+ }
24237
24277
  resolve({
24238
24278
  width: img.naturalWidth,
24239
24279
  height: img.naturalHeight
24240
24280
  });
24241
24281
  URL.revokeObjectURL(url);
24242
24282
  };
24243
- img.onerror = reject;
24283
+ img.onerror = () => {
24284
+ reject(new Error("Invalid image", { cause: "InvalidImage" }));
24285
+ };
24244
24286
  img.src = url;
24245
24287
  });
24246
24288
  }
@@ -24264,6 +24306,10 @@ const downscaleImageFromURL = (url, options) => {
24264
24306
  const img = new Image();
24265
24307
  img.crossOrigin = crossOrigin;
24266
24308
  img.onload = () => {
24309
+ if (img.naturalWidth === 0) {
24310
+ reject(new Error("Invalid image", { cause: "InvalidImage" }));
24311
+ return;
24312
+ }
24267
24313
  const ratio = Math.min(maxWidth / img.width, maxHeight / img.height, 1);
24268
24314
  const width = Math.round(img.width * ratio);
24269
24315
  const height = Math.round(img.height * ratio);
@@ -24274,7 +24320,9 @@ const downscaleImageFromURL = (url, options) => {
24274
24320
  ctx.drawImage(img, 0, 0, width, height);
24275
24321
  resolve(canvas.toDataURL(type));
24276
24322
  };
24277
- img.onerror = reject;
24323
+ img.onerror = () => {
24324
+ reject(new Error("Invalid image", { cause: "InvalidImage" }));
24325
+ };
24278
24326
  img.src = url;
24279
24327
  });
24280
24328
  };
@@ -27032,15 +27080,24 @@ var WeaveImageNode = class extends WeaveNode {
27032
27080
  const imageURLToLoad = imageURL ?? "http://localhost/false-image";
27033
27081
  this.imageFallback[imageId] = Konva.Util.createImageElement();
27034
27082
  this.imageFallback[imageId].crossOrigin = this.config.crossOrigin;
27035
- this.imageFallback[imageId].onerror = (error) => {
27083
+ this.imageFallback[imageId].onerror = () => {
27036
27084
  this.imageState[imageId] = {
27037
27085
  status: "error-fallback",
27038
27086
  loaded: false,
27039
27087
  error: true
27040
27088
  };
27041
- onError(error);
27089
+ onError(new Error(`Failed to load fallback image from provided URL`, { cause: "ErrorLoadingFallbackImage" }));
27042
27090
  };
27043
27091
  this.imageFallback[imageId].onload = async () => {
27092
+ if (this.imageFallback[imageId].width === 0) {
27093
+ this.imageState[imageId] = {
27094
+ status: "error-fallback",
27095
+ loaded: false,
27096
+ error: true
27097
+ };
27098
+ onError(new Error(`Invalid fallback image provided`, { cause: "InvalidFallbackImage" }));
27099
+ return;
27100
+ }
27044
27101
  this.imageState[imageId] = {
27045
27102
  status: "loading",
27046
27103
  loaded: true,
@@ -27067,15 +27124,19 @@ var WeaveImageNode = class extends WeaveNode {
27067
27124
  }
27068
27125
  this.imageSource[imageId] = Konva.Util.createImageElement();
27069
27126
  this.imageSource[imageId].crossOrigin = this.config.crossOrigin;
27070
- this.imageSource[imageId].onerror = (error) => {
27127
+ this.imageSource[imageId].onerror = () => {
27071
27128
  if (!loadingTryout) {
27072
27129
  const stage = this.instance.getStage();
27073
27130
  const image = stage.findOne(`#${imageId}`);
27074
27131
  if (image) this.setErrorState(imageId, image);
27075
27132
  }
27076
- onError(error);
27133
+ onError(new Error(`Failed to load image from provided URL`, { cause: "ErrorLoadingImage" }));
27077
27134
  };
27078
27135
  this.imageSource[imageId].onload = async () => {
27136
+ if (this.imageSource[imageId].width === 0) {
27137
+ onError(new Error(`Invalid image provided`, { cause: "InvalidImage" }));
27138
+ return;
27139
+ }
27079
27140
  const stage = this.instance.getStage();
27080
27141
  if (!this.instance.isServerSide()) stage.container().style.cursor = "pointer";
27081
27142
  this.imageState[imageId] = {
@@ -27167,14 +27228,16 @@ var WeaveImageNode = class extends WeaveNode {
27167
27228
  }
27168
27229
  },
27169
27230
  onError: (error) => {
27170
- if (!this.config.useFallbackImage) {
27231
+ let isInvalidImage = false;
27232
+ if (error.cause === "InvalidImage") isInvalidImage = true;
27233
+ if (!this.config.useFallbackImage && !isInvalidImage) {
27171
27234
  const tryoutAttempts = this.imageTryoutAttempts[id] ?? 0;
27172
27235
  if (tryoutAttempts - 1 < this.config.imageLoading.maxRetryAttempts) {
27173
27236
  this.loadImageTryout(id);
27174
27237
  return;
27175
27238
  } else this.setErrorState(id, image);
27176
27239
  }
27177
- if (loadTryout) {
27240
+ if (loadTryout && !isInvalidImage) {
27178
27241
  const tryoutAttempts = this.imageTryoutAttempts[id] ?? 0;
27179
27242
  if (tryoutAttempts - 1 < this.config.imageLoading.maxRetryAttempts) {
27180
27243
  this.loadImageTryout(id);
@@ -27187,12 +27250,7 @@ var WeaveImageNode = class extends WeaveNode {
27187
27250
  return;
27188
27251
  }
27189
27252
  this.setErrorState(id, image);
27190
- image.setAttrs({ image: void 0 });
27191
- console.error("Error loading image", error);
27192
27253
  this.resolveAsyncElement(id);
27193
- imagePlaceholder?.setAttrs({ visible: true });
27194
- internalImage?.setAttrs({ visible: false });
27195
- this.cacheNode(image);
27196
27254
  }
27197
27255
  }, loadTryout);
27198
27256
  }
@@ -27993,8 +28051,8 @@ var WeaveStrokeNode = class extends WeaveNode {
27993
28051
  const segLen = Math.hypot(dx, dy) || 1;
27994
28052
  const nx = -dy / segLen;
27995
28053
  const ny = dx / segLen;
27996
- const w0 = baseW * p0.pressure / 2;
27997
- const w1 = baseW * p1.pressure / 2;
28054
+ const w0 = Math.max(baseW * p0.pressure / 2, .5);
28055
+ const w1 = Math.max(baseW * p1.pressure / 2, .5);
27998
28056
  let traveled = 0;
27999
28057
  while (traveled < segLen) {
28000
28058
  const step = Math.min(dashRemaining, segLen - traveled);
@@ -29684,8 +29742,7 @@ var WeaveVideoNode = class extends WeaveNode {
29684
29742
  this.videoPlaceholder[id] = Konva.Util.createImageElement();
29685
29743
  this.videoPlaceholder[id].crossOrigin = this.config.crossOrigin;
29686
29744
  this.videoPlaceholder[id].src = realVideoPlaceholderURL;
29687
- this.videoPlaceholder[id].onerror = (error) => {
29688
- console.error("Error loading video placeholder", realVideoPlaceholderURL, error);
29745
+ this.videoPlaceholder[id].onerror = () => {
29689
29746
  this.resolveAsyncElement(id);
29690
29747
  };
29691
29748
  this.videoPlaceholder[id].onload = () => {
@@ -32723,13 +32780,13 @@ var WeaveZoomOutToolAction = class extends WeaveAction {
32723
32780
  const stageZoomPlugin = this.getStageZoomPlugin();
32724
32781
  if (!stageZoomPlugin.canZoomOut()) return;
32725
32782
  stageZoomPlugin.zoomOut();
32726
- this.previousAction = params.previousAction;
32783
+ this.previousAction = params?.previousAction;
32727
32784
  this.cancelAction = cancelAction;
32728
32785
  this.cancelAction();
32729
32786
  }
32730
32787
  cleanup() {
32731
32788
  const stage = this.instance.getStage();
32732
- if (this.previousAction !== void 0) this.instance.triggerAction(this.previousAction);
32789
+ if (this.previousAction) this.instance.triggerAction(this.previousAction);
32733
32790
  stage.container().style.cursor = "default";
32734
32791
  }
32735
32792
  };
@@ -32761,13 +32818,13 @@ var WeaveZoomInToolAction = class extends WeaveAction {
32761
32818
  const stageZoomPlugin = this.getStageZoomPlugin();
32762
32819
  if (!stageZoomPlugin.canZoomIn()) return;
32763
32820
  stageZoomPlugin.zoomIn();
32764
- this.previousAction = params.previousAction;
32821
+ this.previousAction = params?.previousAction;
32765
32822
  this.cancelAction = cancelAction;
32766
32823
  this.cancelAction();
32767
32824
  }
32768
32825
  cleanup() {
32769
32826
  const stage = this.instance.getStage();
32770
- if (this.previousAction !== void 0) this.instance.triggerAction(this.previousAction);
32827
+ if (this.previousAction) this.instance.triggerAction(this.previousAction);
32771
32828
  stage.container().style.cursor = "default";
32772
32829
  }
32773
32830
  };
@@ -32798,21 +32855,17 @@ var WeaveFitToScreenToolAction = class extends WeaveAction {
32798
32855
  trigger(cancelAction, params) {
32799
32856
  const stageZoomPlugin = this.getStageZoomPlugin();
32800
32857
  if (stageZoomPlugin) stageZoomPlugin.fitToScreen({ overrideZoom: params?.overrideZoom ?? true });
32801
- this.previousAction = params.previousAction;
32858
+ this.previousAction = params?.previousAction;
32802
32859
  this.cancelAction = cancelAction;
32803
32860
  this.cancelAction();
32804
32861
  }
32805
32862
  cleanup() {
32806
32863
  const stage = this.instance.getStage();
32807
- if (this.previousAction !== void 0) this.instance.triggerAction(this.previousAction);
32864
+ if (this.previousAction) this.instance.triggerAction(this.previousAction);
32808
32865
  stage.container().style.cursor = "default";
32809
32866
  }
32810
32867
  };
32811
32868
 
32812
- //#endregion
32813
- //#region src/actions/fit-to-selection-tool/constants.ts
32814
- const FIT_TO_SELECTION_TOOL_ACTION_NAME = "fitToSelectionTool";
32815
-
32816
32869
  //#endregion
32817
32870
  //#region src/actions/fit-to-selection-tool/fit-to-selection-tool.ts
32818
32871
  var WeaveFitToSelectionToolAction = class extends WeaveAction {
@@ -32844,13 +32897,13 @@ var WeaveFitToSelectionToolAction = class extends WeaveAction {
32844
32897
  smartZoom: params?.smartZoom ?? false,
32845
32898
  overrideZoom: params?.overrideZoom ?? true
32846
32899
  });
32847
- this.previousAction = params.previousAction;
32900
+ this.previousAction = params?.previousAction;
32848
32901
  this.cancelAction = cancelAction;
32849
32902
  this.cancelAction();
32850
32903
  }
32851
32904
  cleanup() {
32852
32905
  const stage = this.instance.getStage();
32853
- if (this.previousAction !== void 0) this.instance.triggerAction(this.previousAction);
32906
+ if (this.previousAction) this.instance.triggerAction(this.previousAction);
32854
32907
  stage.container().style.cursor = "default";
32855
32908
  }
32856
32909
  };
@@ -34076,6 +34129,11 @@ const BRUSH_TOOL_DEFAULT_CONFIG = { interpolationSteps: 10 };
34076
34129
  var WeaveBrushToolAction = class extends WeaveAction {
34077
34130
  initialized = false;
34078
34131
  isSpacePressed = false;
34132
+ penActive = false;
34133
+ lastSmoothedPressure = .5;
34134
+ lastPointerPos = null;
34135
+ lastPointerTime = 0;
34136
+ predictedCount = 0;
34079
34137
  onPropsChange = void 0;
34080
34138
  onInit = void 0;
34081
34139
  constructor(params) {
@@ -34105,11 +34163,29 @@ var WeaveBrushToolAction = class extends WeaveAction {
34105
34163
  };
34106
34164
  }
34107
34165
  getEventPressure(e) {
34108
- if (e.evt.pointerType && e.evt.pointerType === "pen") return e.evt.pressure || .5;
34109
- return .5;
34166
+ const now$2 = performance.now();
34167
+ let velocity = 0;
34168
+ if (this.lastPointerPos && now$2 - this.lastPointerTime > 0) {
34169
+ const dx = e.evt.clientX - this.lastPointerPos.x;
34170
+ const dy = e.evt.clientY - this.lastPointerPos.y;
34171
+ velocity = Math.hypot(dx, dy) / (now$2 - this.lastPointerTime) * 1e3;
34172
+ }
34173
+ this.lastPointerPos = {
34174
+ x: e.evt.clientX,
34175
+ y: e.evt.clientY
34176
+ };
34177
+ this.lastPointerTime = now$2;
34178
+ const alpha = Math.min(Math.max(velocity / 1500, .15), .6);
34179
+ let raw;
34180
+ if (e.evt.pointerType === "pen") raw = e.evt.pressure || .5;
34181
+ else raw = .5;
34182
+ this.lastSmoothedPressure = alpha * raw + (1 - alpha) * this.lastSmoothedPressure;
34183
+ return Math.max(this.lastSmoothedPressure, .15);
34110
34184
  }
34111
34185
  setupEvents() {
34112
34186
  const stage = this.instance.getStage();
34187
+ this.prevTouchAction = stage.container().style.touchAction;
34188
+ stage.container().style.touchAction = "none";
34113
34189
  window.addEventListener("keyup", (e) => {
34114
34190
  if (e.code === "Space" && this.instance.getActiveAction() === BRUSH_TOOL_ACTION_NAME) this.isSpacePressed = false;
34115
34191
  }, { signal: this.instance.getEventsController()?.signal });
@@ -34134,7 +34210,9 @@ var WeaveBrushToolAction = class extends WeaveAction {
34134
34210
  if (this.state !== BRUSH_TOOL_STATE.IDLE) return;
34135
34211
  if (this.getZoomPlugin()?.isPinching()) return;
34136
34212
  if (this.isSpacePressed) return;
34137
- if (e.evt.button !== 0) return;
34213
+ if (e?.evt?.button !== 0) return;
34214
+ if (e.evt.pointerType === "touch" && this.penActive) return;
34215
+ if (e.evt.pointerType === "pen") this.penActive = true;
34138
34216
  const pointPressure = this.getEventPressure(e);
34139
34217
  this.handleStartStroke(pointPressure);
34140
34218
  e.evt.stopPropagation();
@@ -34145,12 +34223,27 @@ var WeaveBrushToolAction = class extends WeaveAction {
34145
34223
  this.setCursor();
34146
34224
  if (this.state !== BRUSH_TOOL_STATE.DEFINE_STROKE) return;
34147
34225
  if (this.getZoomPlugin()?.isPinching()) return;
34148
- const pointPressure = this.getEventPressure(e);
34149
- this.handleMovement(pointPressure);
34226
+ const coalescedEvents = e.evt.getCoalescedEvents ? e.evt.getCoalescedEvents() : [];
34227
+ if (coalescedEvents.length > 1) {
34228
+ for (const ce of coalescedEvents) {
34229
+ const pointPressure = ce.pointerType === "pen" && typeof ce.pressure === "number" ? ce.pressure : .5;
34230
+ this.handleMovement(pointPressure, void 0, false);
34231
+ }
34232
+ const predictedEvents = e.evt.getPredictedEvents ? e.evt.getPredictedEvents() : [];
34233
+ if (predictedEvents.length > 0) {
34234
+ const last = predictedEvents[predictedEvents.length - 1];
34235
+ const predPressure = last.pointerType === "pen" && typeof last.pressure === "number" ? last.pressure : .5;
34236
+ this.handleMovement(predPressure, last, true);
34237
+ }
34238
+ } else {
34239
+ const pointPressure = this.getEventPressure(e);
34240
+ this.handleMovement(pointPressure, void 0, false);
34241
+ }
34150
34242
  e.evt.stopPropagation();
34151
34243
  };
34152
34244
  stage.on("pointermove", handlePointerMove);
34153
34245
  const handlePointerUp = (e) => {
34246
+ this.penActive = false;
34154
34247
  if (this.state !== BRUSH_TOOL_STATE.DEFINE_STROKE) return;
34155
34248
  if (this.getZoomPlugin()?.isPinching()) return;
34156
34249
  this.handleEndStroke();
@@ -34187,6 +34280,10 @@ var WeaveBrushToolAction = class extends WeaveAction {
34187
34280
  };
34188
34281
  }
34189
34282
  handleStartStroke(pressure) {
34283
+ this.lastSmoothedPressure = .5;
34284
+ this.lastPointerPos = null;
34285
+ this.lastPointerTime = 0;
34286
+ this.predictedCount = 0;
34190
34287
  const { mousePoint, container, measureContainer } = this.instance.getMousePointer();
34191
34288
  this.clickPoint = mousePoint;
34192
34289
  this.container = container;
@@ -34215,17 +34312,25 @@ var WeaveBrushToolAction = class extends WeaveAction {
34215
34312
  }
34216
34313
  this.setState(BRUSH_TOOL_STATE.DEFINE_STROKE);
34217
34314
  }
34218
- handleMovement(pressure) {
34315
+ handleMovement(pressure, predictedEvent, isPredicted = false) {
34219
34316
  if (this.state !== BRUSH_TOOL_STATE.DEFINE_STROKE) return;
34317
+ const stage = this.instance.getStage();
34220
34318
  const tempStroke = this.instance.getStage().findOne(`#${this.strokeId}`);
34221
34319
  if (this.measureContainer && tempStroke) {
34320
+ if (predictedEvent) stage.setPointersPositions(predictedEvent);
34222
34321
  const { mousePoint } = this.instance.getMousePointerRelativeToContainer(this.measureContainer);
34223
34322
  const currentPoint = {
34224
34323
  x: mousePoint.x - tempStroke.x(),
34225
34324
  y: mousePoint.y - tempStroke.y(),
34226
34325
  pressure
34227
34326
  };
34228
- const newStrokeElements = [...tempStroke.getAttrs().strokeElements, currentPoint];
34327
+ let newStrokeElements = [...tempStroke.getAttrs().strokeElements];
34328
+ if (!isPredicted && this.predictedCount > 0) {
34329
+ newStrokeElements = newStrokeElements.slice(0, -1 * this.predictedCount);
34330
+ this.predictedCount = 0;
34331
+ }
34332
+ newStrokeElements.push(currentPoint);
34333
+ if (isPredicted) this.predictedCount++;
34229
34334
  const box = this.getBoundingBox(newStrokeElements);
34230
34335
  tempStroke.setAttrs({
34231
34336
  width: box.width,
@@ -34245,17 +34350,22 @@ var WeaveBrushToolAction = class extends WeaveAction {
34245
34350
  if (nodeHandler) {
34246
34351
  const box = this.getBoundingBox(tempStroke.getAttrs().strokeElements);
34247
34352
  let newStrokeElements = [...tempStroke.getAttrs().strokeElements];
34353
+ if (this.predictedCount > 0) {
34354
+ newStrokeElements = newStrokeElements.slice(0, -1 * this.predictedCount);
34355
+ this.predictedCount = 0;
34356
+ }
34248
34357
  newStrokeElements = newStrokeElements.map((point) => ({
34249
34358
  ...point,
34250
34359
  x: point.x - box.x,
34251
34360
  y: point.y - box.y
34252
34361
  }));
34362
+ const compressedPoints = simplify(newStrokeElements, 1, true);
34253
34363
  tempStroke.setAttrs({
34254
34364
  width: box.width,
34255
34365
  height: box.height,
34256
34366
  x: box.x,
34257
34367
  y: box.y,
34258
- strokeElements: newStrokeElements
34368
+ strokeElements: compressedPoints
34259
34369
  });
34260
34370
  const realNode = this.instance.getStage().findOne(`#${tempStroke.getAttrs().id}`);
34261
34371
  if (realNode) realNode.destroy();
@@ -34291,6 +34401,7 @@ var WeaveBrushToolAction = class extends WeaveAction {
34291
34401
  }
34292
34402
  cleanup() {
34293
34403
  const stage = this.instance.getStage();
34404
+ stage.container().style.touchAction = this.prevTouchAction;
34294
34405
  stage.container().style.cursor = "default";
34295
34406
  this.instance.emitEvent("onAddedBrush");
34296
34407
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
@@ -37945,13 +38056,13 @@ var WeaveStageGridPlugin = class extends WeavePlugin {
37945
38056
  });
37946
38057
  stage.on("pointerdown", (e) => {
37947
38058
  const activeAction = this.instance.getActiveAction();
37948
- if (e && e.evt.button === 0 && activeAction === MOVE_TOOL_ACTION_NAME) this.moveToolActive = true;
37949
- if (e && (e.evt.button === 2 || e.evt.buttons === 4)) this.isMouseMiddleButtonPressed = true;
38059
+ if (e && e?.evt?.button === 0 && activeAction === MOVE_TOOL_ACTION_NAME) this.moveToolActive = true;
38060
+ if (e && (e?.evt?.button === 2 || e?.evt?.buttons === 4)) this.isMouseMiddleButtonPressed = true;
37950
38061
  });
37951
38062
  stage.on("pointerup", (e) => {
37952
38063
  const activeAction = this.instance.getActiveAction();
37953
- if (e && e.evt.button === 0 && activeAction === MOVE_TOOL_ACTION_NAME) this.moveToolActive = false;
37954
- if (e && (e.evt.button === 1 || e.evt.buttons === 0)) this.isMouseMiddleButtonPressed = false;
38064
+ if (e && e?.evt?.button === 0 && activeAction === MOVE_TOOL_ACTION_NAME) this.moveToolActive = false;
38065
+ if (e && (e?.evt?.button === 1 || e?.evt?.buttons === 0)) this.isMouseMiddleButtonPressed = false;
37955
38066
  });
37956
38067
  const handleMouseMove = () => {
37957
38068
  if (!this.enabled || !(this.isSpaceKeyPressed || this.isMouseMiddleButtonPressed || this.moveToolActive)) return;
@@ -38272,16 +38383,16 @@ var WeaveStagePanningPlugin = class extends WeavePlugin {
38272
38383
  let lastPos = null;
38273
38384
  stage.on("pointerdown", (e) => {
38274
38385
  this.pointers.set(e.evt.pointerId, {
38275
- x: e.evt.clientX,
38276
- y: e.evt.clientY
38386
+ x: e?.evt?.clientX ?? 0,
38387
+ y: e?.evt?.clientY ?? 0
38277
38388
  });
38278
38389
  if (this.pointers.size > 1) return;
38279
38390
  const activeAction = this.instance.getActiveAction();
38280
38391
  this.enableMove = false;
38281
38392
  if (activeAction === MOVE_TOOL_ACTION_NAME) this.moveToolActive = true;
38282
- if (e.evt.pointerType === "mouse" && e.evt.buttons === 1) this.isMouseLeftButtonPressed = true;
38283
- if (e.evt.pointerType === "mouse" && e.evt.buttons === 4) this.isMouseMiddleButtonPressed = true;
38284
- const isTouchOrPen = ["touch", "pen"].includes(e.evt.pointerType);
38393
+ if (e.evt.pointerType === "mouse" && e?.evt?.buttons === 1) this.isMouseLeftButtonPressed = true;
38394
+ if (e.evt.pointerType === "mouse" && e?.evt?.buttons === 4) this.isMouseMiddleButtonPressed = true;
38395
+ const isTouchOrPen = ["touch", "pen"].includes(e?.evt?.pointerType);
38285
38396
  if (this.enabled && (this.isSpaceKeyPressed || this.moveToolActive && (this.isMouseLeftButtonPressed || isTouchOrPen) || this.isMouseMiddleButtonPressed)) this.enableMove = true;
38286
38397
  if (this.enableMove) {
38287
38398
  this.isDragging = true;
@@ -38290,7 +38401,7 @@ var WeaveStagePanningPlugin = class extends WeavePlugin {
38290
38401
  }
38291
38402
  });
38292
38403
  stage.on("pointercancel", (e) => {
38293
- this.pointers.delete(e.evt.pointerId);
38404
+ if (e?.evt?.pointerId) this.pointers.delete(e.evt.pointerId);
38294
38405
  lastPos = null;
38295
38406
  });
38296
38407
  const handleMouseMove = (e) => {