@inditextech/weave-sdk 2.12.1 → 2.13.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
@@ -1,7 +1,7 @@
1
1
  import Konva from "konva";
2
2
  import { randomFillSync, randomUUID } from "crypto";
3
3
  import pino from "pino";
4
- import { WEAVE_AWARENESS_LAYER_ID, WEAVE_EXPORT_BACKGROUND_COLOR, WEAVE_EXPORT_FORMATS, WEAVE_INSTANCE_STATUS, WEAVE_KONVA_BACKEND, WEAVE_NODE_CUSTOM_EVENTS, WEAVE_NODE_LAYER_ID, WEAVE_NODE_POSITION, WEAVE_STORE_CONNECTION_STATUS, WEAVE_UTILITY_LAYER_ID } from "@inditextech/weave-types";
4
+ import { WEAVE_ASYNC_STATUS, WEAVE_AWARENESS_LAYER_ID, WEAVE_EXPORT_BACKGROUND_COLOR, WEAVE_EXPORT_FORMATS, WEAVE_INSTANCE_STATUS, WEAVE_KONVA_BACKEND, 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
7
  import React from "react";
@@ -18562,6 +18562,7 @@ const WEAVE_GRID_LAYER_ID = "gridLayer";
18562
18562
  //#endregion
18563
18563
  //#region src/plugins/stage-panning/constants.ts
18564
18564
  const WEAVE_STAGE_PANNING_KEY = "stagePanning";
18565
+ const WEAVE_STAGE_PANNING_THROTTLE_MS = 20;
18565
18566
  const WEAVE_STAGE_PANNING_DEFAULT_CONFIG = {
18566
18567
  edgePanOffset: 50,
18567
18568
  edgePanSpeed: 10
@@ -18577,6 +18578,16 @@ const WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_DEFAULT_CONFIG = { style: {
18577
18578
  fill: "transparent"
18578
18579
  } };
18579
18580
 
18581
+ //#endregion
18582
+ //#region src/constants.ts
18583
+ const DEFAULT_THROTTLE_MS = 50;
18584
+
18585
+ //#endregion
18586
+ //#region src/plugins/users-presence/constants.ts
18587
+ const WEAVE_USER_PRESENCE_KEY = "userPresence";
18588
+ const WEAVE_USERS_PRESENCE_PLUGIN_KEY = "usersPresence";
18589
+ const WEAVE_USERS_PRESENCE_CONFIG_DEFAULT_PROPS = { awarenessThrottleMs: DEFAULT_THROTTLE_MS };
18590
+
18580
18591
  //#endregion
18581
18592
  //#region src/plugins/nodes-selection/nodes-selection.ts
18582
18593
  var WeaveNodesSelectionPlugin = class extends WeavePlugin {
@@ -18703,6 +18714,15 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18703
18714
  });
18704
18715
  tr.on("transformstart", () => {
18705
18716
  this.triggerSelectedNodesEvent();
18717
+ const selectedNodes = tr.nodes();
18718
+ for (const node of selectedNodes) if (node.getAttrs().strokeScaleEnabled !== false) {
18719
+ node.setAttr("strokeScaleEnabled", false);
18720
+ node.setAttr("_revertStrokeScaleEnabled", true);
18721
+ }
18722
+ if (this.getSelectedNodes().length > 1) this.instance.setMutexLock({
18723
+ nodeIds: selectedNodes.map((node) => node.id()),
18724
+ operation: "nodes-transform"
18725
+ });
18706
18726
  });
18707
18727
  let nodeHovered = void 0;
18708
18728
  tr.on("mousemove", () => {
@@ -18740,9 +18760,26 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18740
18760
  const moved = this.checkMoved(e);
18741
18761
  if (moved) this.getContextMenuPlugin()?.cancelLongPressTimer();
18742
18762
  this.triggerSelectedNodesEvent();
18763
+ if (this.getUsersPresencePlugin()) for (const node of tr.nodes()) this.getUsersPresencePlugin()?.setPresence(node.id(), {
18764
+ x: node.x(),
18765
+ y: node.y(),
18766
+ width: node.width(),
18767
+ height: node.height(),
18768
+ scaleX: node.scaleX(),
18769
+ scaleY: node.scaleY(),
18770
+ rotation: node.rotation(),
18771
+ strokeScaleEnabled: false
18772
+ });
18743
18773
  };
18744
- tr.on("transform", (0, import_throttle.default)(handleTransform, 50));
18774
+ tr.on("transform", (0, import_throttle.default)(handleTransform, DEFAULT_THROTTLE_MS));
18745
18775
  tr.on("transformend", () => {
18776
+ if (this.getSelectedNodes().length > 1) this.instance.releaseMutexLock();
18777
+ const selectedNodes = tr.nodes();
18778
+ for (const node of selectedNodes) {
18779
+ if (node.getAttrs()._revertStrokeScaleEnabled === true) node.setAttr("strokeScaleEnabled", true);
18780
+ node.setAttr("_revertStrokeScaleEnabled", void 0);
18781
+ if (this.getUsersPresencePlugin()) this.getUsersPresencePlugin()?.removePresence(node.id());
18782
+ }
18746
18783
  this.triggerSelectedNodesEvent();
18747
18784
  });
18748
18785
  let initialPos = null;
@@ -18776,6 +18813,10 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18776
18813
  }
18777
18814
  e.cancelBubble = true;
18778
18815
  tr.forceUpdate();
18816
+ if (this.getSelectedNodes().length > 1) this.instance.setMutexLock({
18817
+ nodeIds: selectedNodes.map((node) => node.id()),
18818
+ operation: "nodes-drag"
18819
+ });
18779
18820
  });
18780
18821
  const handleDragMove = (e) => {
18781
18822
  const actualPos = {
@@ -18808,6 +18849,10 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18808
18849
  if (this.isSelecting() && selectedNodes.length > 1) {
18809
18850
  clearContainerTargets(this.instance);
18810
18851
  const layerToMove = containerOverCursor(this.instance, selectedNodes);
18852
+ if (this.getUsersPresencePlugin()) for (const node of selectedNodes) this.getUsersPresencePlugin()?.setPresence(node.id(), {
18853
+ x: node.x(),
18854
+ y: node.y()
18855
+ });
18811
18856
  if (layerToMove && !selectionContainsFrames) layerToMove.fire(WEAVE_NODE_CUSTOM_EVENTS.onTargetEnter, { bubbles: true });
18812
18857
  }
18813
18858
  tr.forceUpdate();
@@ -18815,12 +18860,14 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18815
18860
  tr.on("dragmove", handleDragMove);
18816
18861
  tr.on("dragend", (e) => {
18817
18862
  if (!this.didMove) return;
18863
+ if (this.getSelectedNodes().length > 1) this.instance.releaseMutexLock();
18818
18864
  e.cancelBubble = true;
18819
18865
  if (tr.nodes().length > 1) {
18820
18866
  const nodes$1 = tr.nodes();
18821
18867
  for (const node of nodes$1) {
18822
18868
  this.getNodesSelectionFeedbackPlugin()?.showSelectionHalo(node);
18823
18869
  this.getNodesSelectionFeedbackPlugin()?.updateSelectionHalo(node);
18870
+ this.getUsersPresencePlugin()?.removePresence(node.id());
18824
18871
  }
18825
18872
  }
18826
18873
  this.instance.getCloningManager().cleanupClones();
@@ -19194,6 +19241,8 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19194
19241
  stage.on("pointermove", handleMouseMove);
19195
19242
  this.panLoop();
19196
19243
  stage.on("pointerup", (e) => {
19244
+ const store = this.instance.getStore();
19245
+ const actUser = store.getUser();
19197
19246
  this.tr.setAttrs({ listening: true });
19198
19247
  this.selecting = false;
19199
19248
  this.stopPanLoop();
@@ -19258,6 +19307,8 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19258
19307
  const box = this.selectionRectangle.getClientRect();
19259
19308
  this.selectionRectangle.visible(false);
19260
19309
  const selected = shapes.filter((shape) => {
19310
+ const shapeMutex = this.instance.getNodeMutexLock(shape.id());
19311
+ if (shapeMutex && shapeMutex.user.id !== actUser.id) return false;
19261
19312
  let parent = this.instance.getInstanceRecursive(shape.getParent());
19262
19313
  if (parent.getAttrs().nodeId) parent = this.instance.getStage().findOne(`#${parent.getAttrs().nodeId}`);
19263
19314
  if (shape.getAttrs().nodeType && shape.getAttrs().nodeType === "frame") {
@@ -19360,7 +19411,10 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19360
19411
  return node.getAttrs().id === nodeTargeted.getAttrs().id;
19361
19412
  });
19362
19413
  const isSelected = nodeSelectedIndex !== -1;
19363
- if (nodeTargeted.getAttrs().locked) return;
19414
+ const user = this.instance.getStore().getUser();
19415
+ const isLocked = nodeTargeted.getAttrs().locked ?? false;
19416
+ const isMutexLocked = nodeTargeted.getAttrs().mutexLocked && nodeTargeted.getAttrs().mutexUserId !== user.id;
19417
+ if (isLocked || isMutexLocked) return;
19364
19418
  if (nodeTargeted.getAttrs().nodeId) {
19365
19419
  const realNode = stage.findOne(`#${nodeTargeted.getAttrs().nodeId}`);
19366
19420
  if (realNode) nodeTargeted = realNode;
@@ -19491,6 +19545,10 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19491
19545
  const stagePanning = this.instance.getPlugin(WEAVE_STAGE_PANNING_KEY);
19492
19546
  return stagePanning;
19493
19547
  }
19548
+ getUsersPresencePlugin() {
19549
+ const usersPresencePlugin = this.instance.getPlugin(WEAVE_USERS_PRESENCE_PLUGIN_KEY);
19550
+ return usersPresencePlugin;
19551
+ }
19494
19552
  getSelectorConfig() {
19495
19553
  return this.config.selection;
19496
19554
  }
@@ -20112,6 +20170,25 @@ var WeaveNode = class {
20112
20170
  });
20113
20171
  return anchors;
20114
20172
  };
20173
+ node.lockMutex = function(user) {
20174
+ const actUser = actInstance.getStore().getUser();
20175
+ this.setAttrs({
20176
+ mutexLocked: true,
20177
+ mutexUserId: user.id
20178
+ });
20179
+ const selectionPlugin = actInstance.getPlugin("nodesSelection");
20180
+ if (selectionPlugin && actUser.id !== user.id) {
20181
+ const selectedNodes = selectionPlugin.getSelectedNodes();
20182
+ const filteredNodes = selectedNodes.filter((n) => n.getAttrs().id !== this.getAttrs().id);
20183
+ selectionPlugin.setSelectedNodes(filteredNodes);
20184
+ }
20185
+ };
20186
+ node.releaseMutex = function() {
20187
+ this.setAttrs({
20188
+ mutexLocked: false,
20189
+ mutexUserId: void 0
20190
+ });
20191
+ };
20115
20192
  }
20116
20193
  isNodeSelected(ele) {
20117
20194
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
@@ -20165,8 +20242,16 @@ var WeaveNode = class {
20165
20242
  let transforming = false;
20166
20243
  node.on("transformstart", (e) => {
20167
20244
  transforming = true;
20245
+ if (e.target.getAttrs().strokeScaleEnabled !== false) {
20246
+ e.target.setAttr("strokeScaleEnabled", false);
20247
+ e.target.setAttr("_revertStrokeScaleEnabled", true);
20248
+ }
20168
20249
  this.getNodesSelectionFeedbackPlugin()?.hideSelectionHalo(node);
20169
20250
  this.instance.emitEvent("onTransform", e.target);
20251
+ if (this.getSelectionPlugin()?.getSelectedNodes().length === 1) this.instance.setMutexLock({
20252
+ nodeIds: [e.target.id()],
20253
+ operation: "node-transform"
20254
+ });
20170
20255
  });
20171
20256
  const handleTransform = (e) => {
20172
20257
  const node$1 = e.target;
@@ -20174,11 +20259,24 @@ var WeaveNode = class {
20174
20259
  const nodesEdgeSnappingPlugin = this.getNodesEdgeSnappingPlugin();
20175
20260
  if (nodesSelectionPlugin && this.isSelecting() && this.isNodeSelected(node$1)) nodesSelectionPlugin.getTransformer().forceUpdate();
20176
20261
  if (nodesEdgeSnappingPlugin && transforming && this.isSelecting() && this.isNodeSelected(node$1)) nodesEdgeSnappingPlugin.evaluateGuidelines(e);
20262
+ this.getUsersPresencePlugin()?.setPresence(node$1.id(), {
20263
+ x: node$1.x(),
20264
+ y: node$1.y(),
20265
+ width: node$1.width(),
20266
+ height: node$1.height(),
20267
+ scaleX: node$1.scaleX(),
20268
+ scaleY: node$1.scaleY(),
20269
+ rotation: node$1.rotation(),
20270
+ strokeScaleEnabled: false
20271
+ });
20177
20272
  };
20178
- node.on("transform", (0, import_lodash.throttle)(handleTransform, 100));
20273
+ node.on("transform", (0, import_lodash.throttle)(handleTransform, DEFAULT_THROTTLE_MS));
20179
20274
  node.on("transformend", (e) => {
20180
20275
  const node$1 = e.target;
20181
- e.target.setAttr("strokeScaleEnabled", true);
20276
+ if (this.getSelectionPlugin()?.getSelectedNodes().length === 1) this.instance.releaseMutexLock();
20277
+ this.getUsersPresencePlugin()?.removePresence(node$1.id());
20278
+ if (e.target.getAttrs()._revertStrokeScaleEnabled === true) e.target.setAttr("strokeScaleEnabled", true);
20279
+ e.target.setAttr("_revertStrokeScaleEnabled", void 0);
20182
20280
  this.instance.emitEvent("onTransform", null);
20183
20281
  transforming = false;
20184
20282
  const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
@@ -20258,6 +20356,10 @@ var WeaveNode = class {
20258
20356
  clone?.startDrag(e.evt);
20259
20357
  });
20260
20358
  }
20359
+ if (this.getNodesSelectionPlugin()?.getSelectedNodes().length === 1) this.instance.setMutexLock({
20360
+ nodeIds: [e.target.id()],
20361
+ operation: "node-drag"
20362
+ });
20261
20363
  });
20262
20364
  const handleDragMove = (e) => {
20263
20365
  const nodeTarget = e.target;
@@ -20281,14 +20383,19 @@ var WeaveNode = class {
20281
20383
  const realNodeTarget = this.getRealSelectedNode(nodeTarget);
20282
20384
  if (this.isSelecting() && this.getSelectionPlugin()?.getSelectedNodes().length === 1) {
20283
20385
  clearContainerTargets(this.instance);
20386
+ this.getUsersPresencePlugin()?.setPresence(realNodeTarget.id(), {
20387
+ x: realNodeTarget.x(),
20388
+ y: realNodeTarget.y()
20389
+ });
20284
20390
  const layerToMove = containerOverCursor(this.instance, [realNodeTarget]);
20285
20391
  if (layerToMove && !hasFrames(realNodeTarget) && realNodeTarget.isDragging() && !realNodeTarget.getAttrs().lockToContainer) layerToMove.fire(WEAVE_NODE_CUSTOM_EVENTS.onTargetEnter, { node: realNodeTarget });
20286
20392
  }
20287
20393
  };
20288
- node.on("dragmove", (0, import_lodash.throttle)(handleDragMove, 100));
20394
+ node.on("dragmove", (0, import_lodash.throttle)(handleDragMove, DEFAULT_THROTTLE_MS));
20289
20395
  node.on("dragend", (e) => {
20290
20396
  const nodeTarget = e.target;
20291
20397
  if (this.getSelectionPlugin()?.getSelectedNodes().length === 1) {
20398
+ this.instance.releaseMutexLock();
20292
20399
  this.getNodesSelectionFeedbackPlugin()?.showSelectionHalo(nodeTarget);
20293
20400
  this.getNodesSelectionFeedbackPlugin()?.updateSelectionHalo(nodeTarget);
20294
20401
  }
@@ -20308,6 +20415,7 @@ var WeaveNode = class {
20308
20415
  }
20309
20416
  this.instance.emitEvent("onDrag", null);
20310
20417
  const realNodeTarget = this.getRealSelectedNode(nodeTarget);
20418
+ this.getUsersPresencePlugin()?.removePresence(realNodeTarget.id());
20311
20419
  if (this.getNodesSelectionPlugin()?.getSelectedNodes().length === 1 && realNodeTarget.getAttr("dragStartOpacity") !== void 0) {
20312
20420
  const originalNodeOpacity = realNodeTarget.getAttr("dragStartOpacity") ?? 1;
20313
20421
  realNodeTarget.setAttrs({ opacity: originalNodeOpacity });
@@ -20376,35 +20484,33 @@ var WeaveNode = class {
20376
20484
  }
20377
20485
  handleMouseOver(node) {
20378
20486
  const stage = this.instance.getStage();
20487
+ const user = this.instance.getStore().getUser();
20379
20488
  const activeAction = this.instance.getActiveAction();
20380
20489
  const isNodeSelectionEnabled = this.getSelectionPlugin()?.isEnabled();
20381
20490
  const realNode = this.instance.getInstanceRecursive(node);
20382
20491
  const isTargetable = node.getAttrs().isTargetable !== false;
20383
20492
  const isLocked = node.getAttrs().locked ?? false;
20493
+ const isMutexLocked = realNode.getAttrs().mutexLocked && realNode.getAttrs().mutexUserId !== user.id;
20384
20494
  if ([MOVE_TOOL_ACTION_NAME].includes(activeAction ?? "")) return false;
20385
20495
  let showHover = false;
20386
20496
  let cancelBubble = false;
20387
- if (isNodeSelectionEnabled && this.isSelecting() && !this.isNodeSelected(realNode) && !this.isPasting() && isLocked) {
20388
- const stage$1 = this.instance.getStage();
20389
- stage$1.container().style.cursor = "default";
20497
+ if (isNodeSelectionEnabled && this.isSelecting() && !this.isNodeSelected(realNode) && !this.isPasting() && (isLocked || isMutexLocked)) {
20498
+ stage.container().style.cursor = "default";
20390
20499
  cancelBubble = true;
20391
20500
  }
20392
- if (isNodeSelectionEnabled && this.isSelecting() && !this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !isLocked && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
20393
- const stage$1 = this.instance.getStage();
20501
+ if (isNodeSelectionEnabled && this.isSelecting() && !this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !(isLocked || isMutexLocked) && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
20394
20502
  showHover = true;
20395
- stage$1.container().style.cursor = "pointer";
20503
+ stage.container().style.cursor = "pointer";
20396
20504
  cancelBubble = true;
20397
20505
  }
20398
- if (isNodeSelectionEnabled && this.isSelecting() && this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !isLocked && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
20399
- const stage$1 = this.instance.getStage();
20506
+ if (isNodeSelectionEnabled && this.isSelecting() && this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !(isLocked || isMutexLocked) && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
20400
20507
  showHover = true;
20401
- stage$1.container().style.cursor = "grab";
20508
+ stage.container().style.cursor = "grab";
20402
20509
  cancelBubble = true;
20403
20510
  }
20404
20511
  if (!isTargetable) cancelBubble = true;
20405
20512
  if (this.isPasting()) {
20406
- const stage$1 = this.instance.getStage();
20407
- stage$1.container().style.cursor = "crosshair";
20513
+ stage.container().style.cursor = "crosshair";
20408
20514
  cancelBubble = true;
20409
20515
  }
20410
20516
  if (showHover) this.setHoverState(realNode);
@@ -20435,6 +20541,8 @@ var WeaveNode = class {
20435
20541
  serialize(instance) {
20436
20542
  const attrs = instance.getAttrs();
20437
20543
  const cleanedAttrs = { ...attrs };
20544
+ delete cleanedAttrs.mutexLocked;
20545
+ delete cleanedAttrs.mutexUserId;
20438
20546
  delete cleanedAttrs.draggable;
20439
20547
  return {
20440
20548
  key: attrs.id ?? "",
@@ -20555,6 +20663,10 @@ var WeaveNode = class {
20555
20663
  const selectionFeedbackPlugin = this.instance.getPlugin(WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_KEY);
20556
20664
  return selectionFeedbackPlugin;
20557
20665
  }
20666
+ getUsersPresencePlugin() {
20667
+ const usersPresencePlugin = this.instance.getPlugin(WEAVE_USERS_PRESENCE_PLUGIN_KEY);
20668
+ return usersPresencePlugin;
20669
+ }
20558
20670
  };
20559
20671
 
20560
20672
  //#endregion
@@ -21991,7 +22103,7 @@ var WeaveRegisterManager = class {
21991
22103
 
21992
22104
  //#endregion
21993
22105
  //#region package.json
21994
- var version = "2.12.1";
22106
+ var version = "2.13.0";
21995
22107
 
21996
22108
  //#endregion
21997
22109
  //#region src/managers/setup.ts
@@ -22470,7 +22582,163 @@ var WeavePluginsManager = class {
22470
22582
  };
22471
22583
 
22472
22584
  //#endregion
22473
- //#region src/watch-map.ts
22585
+ //#region src/plugins/connected-users/constants.ts
22586
+ const WEAVE_CONNECTED_USERS_KEY = "connectedUsers";
22587
+ const WEAVE_CONNECTED_USER_INFO_KEY = "userInfo";
22588
+
22589
+ //#endregion
22590
+ //#region src/managers/mutex/mutex.ts
22591
+ var WeaveMutexManager = class {
22592
+ userMutexLocked = new Map();
22593
+ nodeMutexLocked = new Map();
22594
+ WEAVE_USER_MUTEX_LOCK_KEY = "userMutexLock";
22595
+ constructor(instance) {
22596
+ this.instance = instance;
22597
+ this.logger = this.instance.getChildLogger("mutex-manager");
22598
+ this.logger.debug("Mutex manager created");
22599
+ this.init();
22600
+ }
22601
+ init() {
22602
+ this.setupMutexManager();
22603
+ }
22604
+ setupMutexManager() {
22605
+ this.instance.addEventListener("onConnectedUsersChange", (users) => {
22606
+ const actUser = this.instance.getStore().getUser();
22607
+ const userMutexKeys = Array.from(this.userMutexLocked.keys());
22608
+ for (const userMutexKey of userMutexKeys) if (actUser.id !== userMutexKey && !users[userMutexKey]) {
22609
+ const info = this.userMutexLocked.get(userMutexKey);
22610
+ if (info) {
22611
+ const user = info.user;
22612
+ this.releaseMutexLockRemote(user);
22613
+ }
22614
+ }
22615
+ });
22616
+ this.instance.addEventListener(
22617
+ "onAwarenessChange",
22618
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
22619
+ (changes) => {
22620
+ const actUser = this.instance.getStore().getUser();
22621
+ for (const change of changes) {
22622
+ if (!change[this.WEAVE_USER_MUTEX_LOCK_KEY] && change[WEAVE_CONNECTED_USER_INFO_KEY] && actUser.id !== change[WEAVE_CONNECTED_USER_INFO_KEY].id) {
22623
+ const user = change[WEAVE_CONNECTED_USER_INFO_KEY];
22624
+ this.releaseMutexLockRemote(user);
22625
+ continue;
22626
+ }
22627
+ if (change[WEAVE_CONNECTED_USER_INFO_KEY] && actUser.id !== change[WEAVE_CONNECTED_USER_INFO_KEY].id) {
22628
+ const user = change[WEAVE_CONNECTED_USER_INFO_KEY];
22629
+ const mutexInfo = change[this.WEAVE_USER_MUTEX_LOCK_KEY];
22630
+ this.setMutexLockRemote({
22631
+ nodeIds: mutexInfo.nodeIds,
22632
+ operation: mutexInfo.operation,
22633
+ metadata: mutexInfo.metadata
22634
+ }, user);
22635
+ }
22636
+ }
22637
+ }
22638
+ );
22639
+ }
22640
+ async acquireMutexLock({ nodeIds, operation }, action) {
22641
+ const lockAcquired = this.setMutexLock({
22642
+ nodeIds,
22643
+ operation
22644
+ });
22645
+ if (lockAcquired) {
22646
+ await Promise.resolve(action());
22647
+ this.releaseMutexLock();
22648
+ }
22649
+ }
22650
+ getUserMutexLock(userMutexKey) {
22651
+ if (this.userMutexLocked.get(userMutexKey)) return this.userMutexLocked.get(userMutexKey);
22652
+ return void 0;
22653
+ }
22654
+ getNodeMutexLock(nodeMutexKey) {
22655
+ if (this.nodeMutexLocked.get(nodeMutexKey)) return this.nodeMutexLocked.get(nodeMutexKey);
22656
+ return void 0;
22657
+ }
22658
+ getUserMutexKey(user) {
22659
+ const store = this.instance.getStore();
22660
+ let userInfo = store.getUser();
22661
+ if (user !== void 0) userInfo = user;
22662
+ return userInfo.id;
22663
+ }
22664
+ getNodeMutexKey(nodeId) {
22665
+ return nodeId;
22666
+ }
22667
+ setMutexLockRemote({ nodeIds, operation, metadata }, user) {
22668
+ return this.setMutexLock({
22669
+ nodeIds,
22670
+ operation,
22671
+ metadata
22672
+ }, user, false);
22673
+ }
22674
+ setMutexLock({ nodeIds, operation, metadata }, userInfo = void 0, sendAwareness = true) {
22675
+ const store = this.instance.getStore();
22676
+ let user = store.getUser();
22677
+ if (userInfo !== void 0) user = userInfo;
22678
+ const userMutexKey = this.getUserMutexKey(user);
22679
+ if (this.userMutexLocked.has(userMutexKey)) return false;
22680
+ const preLockedNodes = [];
22681
+ for (const nodeId of nodeIds) {
22682
+ const nodeMutexKey = this.getNodeMutexKey(nodeId);
22683
+ if (this.nodeMutexLocked.has(nodeMutexKey)) break;
22684
+ else {
22685
+ this.nodeMutexLocked.set(nodeMutexKey, {
22686
+ user,
22687
+ operation,
22688
+ metadata
22689
+ });
22690
+ const nodeInstance = this.instance.getStage().findOne(`#${nodeId}`);
22691
+ if (nodeInstance) nodeInstance.lockMutex(user);
22692
+ preLockedNodes.push(nodeMutexKey);
22693
+ }
22694
+ }
22695
+ if (preLockedNodes.length === nodeIds.length && !this.userMutexLocked.has(userMutexKey)) {
22696
+ this.userMutexLocked.set(userMutexKey, {
22697
+ user,
22698
+ nodeIds,
22699
+ operation,
22700
+ metadata
22701
+ });
22702
+ if (sendAwareness) store.setAwarenessInfo(this.WEAVE_USER_MUTEX_LOCK_KEY, {
22703
+ user,
22704
+ nodeIds,
22705
+ operation,
22706
+ metadata
22707
+ });
22708
+ this.instance.emitEvent("onMutexLockChange", { locks: [...this.userMutexLocked.keys()] });
22709
+ return true;
22710
+ }
22711
+ if (preLockedNodes.length !== nodeIds.length) {
22712
+ this.userMutexLocked.delete(userMutexKey);
22713
+ for (const nodeMutexKey of preLockedNodes) this.nodeMutexLocked.delete(nodeMutexKey);
22714
+ }
22715
+ return false;
22716
+ }
22717
+ releaseMutexLockRemote(user) {
22718
+ this.releaseMutexLock(user, false);
22719
+ }
22720
+ releaseMutexLock(userInfo = void 0, sendAwareness = true) {
22721
+ const store = this.instance.getStore();
22722
+ let user = store.getUser();
22723
+ if (userInfo !== void 0) user = userInfo;
22724
+ const userMutexKey = this.getUserMutexKey(user);
22725
+ if (this.userMutexLocked.has(userMutexKey)) {
22726
+ const nodeIds = this.userMutexLocked.get(userMutexKey).nodeIds;
22727
+ for (const nodeId of nodeIds) {
22728
+ const nodeMutexKey = this.getNodeMutexKey(nodeId);
22729
+ this.nodeMutexLocked.delete(nodeMutexKey);
22730
+ const nodeInstance = this.instance.getStage().findOne(`#${nodeId}`);
22731
+ if (nodeInstance) nodeInstance.releaseMutex();
22732
+ }
22733
+ this.userMutexLocked.delete(userMutexKey);
22734
+ if (sendAwareness) store.setAwarenessInfo(this.WEAVE_USER_MUTEX_LOCK_KEY, void 0);
22735
+ this.instance.emitEvent("onMutexLockChange", { locks: [...this.userMutexLocked.keys()] });
22736
+ }
22737
+ }
22738
+ };
22739
+
22740
+ //#endregion
22741
+ //#region src/managers/async/watch-map.ts
22474
22742
  function watchMap(onChange, map = new Map()) {
22475
22743
  const handler = { get(target, prop, receiver) {
22476
22744
  if (prop === "set") return (key, value$1) => {
@@ -22514,12 +22782,70 @@ function watchMap(onChange, map = new Map()) {
22514
22782
  return new Proxy(map, handler);
22515
22783
  }
22516
22784
 
22785
+ //#endregion
22786
+ //#region src/managers/async/async.ts
22787
+ var WeaveAsyncManager = class {
22788
+ constructor(instance) {
22789
+ this.instance = instance;
22790
+ this.logger = this.instance.getChildLogger("async-manager");
22791
+ this.logger.debug("Async manager created");
22792
+ this.asyncElements = watchMap(() => {
22793
+ this.instance.emitEvent("onAsyncElementChange");
22794
+ }, new Map());
22795
+ }
22796
+ asyncElementsLoaded() {
22797
+ return [...this.asyncElements.values()].every((el) => el.status === WEAVE_ASYNC_STATUS.LOADED);
22798
+ }
22799
+ loadAsyncElement(nodeId, type) {
22800
+ let element = this.asyncElements.get(nodeId);
22801
+ if (element) element.status = WEAVE_ASYNC_STATUS.LOADING;
22802
+ else element = {
22803
+ type,
22804
+ status: WEAVE_ASYNC_STATUS.LOADING
22805
+ };
22806
+ this.asyncElements.set(nodeId, element);
22807
+ }
22808
+ resolveAsyncElement(nodeId, type) {
22809
+ let element = this.asyncElements.get(nodeId);
22810
+ if (element) element.status = WEAVE_ASYNC_STATUS.LOADED;
22811
+ else element = {
22812
+ type,
22813
+ status: WEAVE_ASYNC_STATUS.LOADED
22814
+ };
22815
+ this.asyncElements.set(nodeId, element);
22816
+ }
22817
+ };
22818
+
22819
+ //#endregion
22820
+ //#region src/managers/hooks.ts
22821
+ var WeaveHooksManager = class {
22822
+ registeredHooks = new Map();
22823
+ constructor(instance) {
22824
+ this.instance = instance;
22825
+ this.logger = this.instance.getChildLogger("hooks-manager");
22826
+ this.logger.debug("Hooks manager created");
22827
+ }
22828
+ registerHook(hookName, hook) {
22829
+ const exists = this.registeredHooks.has(hookName);
22830
+ if (!exists) this.registeredHooks.set(hookName, hook);
22831
+ }
22832
+ runPhaseHooks(phaseName, execution) {
22833
+ const hooks = [...this.registeredHooks.keys()].filter((key) => key.startsWith(`${phaseName}:`)).map((key) => this.registeredHooks.get(key));
22834
+ for (const hook of hooks) execution(hook);
22835
+ }
22836
+ getHook(hookName) {
22837
+ return this.registeredHooks.get(hookName);
22838
+ }
22839
+ unregisterHook(hookName) {
22840
+ this.registeredHooks.delete(hookName);
22841
+ }
22842
+ };
22843
+
22517
22844
  //#endregion
22518
22845
  //#region src/weave.ts
22519
22846
  var Weave = class {
22520
22847
  initialized = false;
22521
22848
  status = WEAVE_INSTANCE_STATUS.IDLE;
22522
- registeredHooks = new Map();
22523
22849
  constructor(weaveConfig, stageConfig) {
22524
22850
  globalThis._weave_isServerSide = false;
22525
22851
  if (typeof window === "undefined") globalThis._weave_isServerSide = true;
@@ -22527,9 +22853,6 @@ var Weave = class {
22527
22853
  Konva.showWarnings = false;
22528
22854
  this.id = v4_default();
22529
22855
  this.initialized = false;
22530
- this.asyncElements = watchMap(() => {
22531
- this.emitEvent("onAsyncElementChange");
22532
- }, new Map());
22533
22856
  this.config = mergeExceptArrays({}, weaveConfig);
22534
22857
  this.logger = new WeaveLogger(this.config?.logger ?? {
22535
22858
  disabled: false,
@@ -22552,6 +22875,9 @@ var Weave = class {
22552
22875
  this.exportManager = new WeaveExportManager(this);
22553
22876
  this.actionsManager = new WeaveActionsManager(this);
22554
22877
  this.pluginsManager = new WeavePluginsManager(this);
22878
+ this.mutexManager = new WeaveMutexManager(this);
22879
+ this.asyncManager = new WeaveAsyncManager(this);
22880
+ this.hooksManager = new WeaveHooksManager(this);
22555
22881
  this.setupManager.welcomeLog();
22556
22882
  }
22557
22883
  getRenderer() {
@@ -23041,42 +23367,50 @@ var Weave = class {
23041
23367
  }
23042
23368
  }
23043
23369
  asyncElementsLoaded() {
23044
- return [...this.asyncElements.values()].every((el) => el.status === "loaded");
23370
+ return this.asyncManager.asyncElementsLoaded();
23045
23371
  }
23046
23372
  loadAsyncElement(nodeId, type) {
23047
- let element = this.asyncElements.get(nodeId);
23048
- if (element) element.status = "loading";
23049
- else element = {
23050
- type,
23051
- status: "loading"
23052
- };
23053
- this.asyncElements.set(nodeId, element);
23373
+ this.asyncManager.loadAsyncElement(nodeId, type);
23054
23374
  }
23055
23375
  resolveAsyncElement(nodeId, type) {
23056
- let element = this.asyncElements.get(nodeId);
23057
- if (element) element.status = "loaded";
23058
- else element = {
23059
- type,
23060
- status: "loaded"
23061
- };
23062
- this.asyncElements.set(nodeId, element);
23376
+ this.asyncManager.resolveAsyncElement(nodeId, type);
23063
23377
  }
23064
23378
  isServerSide() {
23065
23379
  return globalThis._weave_isServerSide === true;
23066
23380
  }
23067
23381
  registerHook(hookName, hook) {
23068
- const exists = this.registeredHooks.has(hookName);
23069
- if (!exists) this.registeredHooks.set(hookName, hook);
23382
+ this.hooksManager.registerHook(hookName, hook);
23070
23383
  }
23071
23384
  runPhaseHooks(phaseName, execution) {
23072
- const hooks = [...this.registeredHooks.keys()].filter((key) => key.startsWith(`${phaseName}:`)).map((key) => this.registeredHooks.get(key));
23073
- for (const hook of hooks) execution(hook);
23385
+ this.hooksManager.runPhaseHooks(phaseName, execution);
23074
23386
  }
23075
23387
  getHook(hookName) {
23076
- return this.registeredHooks.get(hookName);
23388
+ return this.hooksManager.getHook(hookName);
23077
23389
  }
23078
23390
  unregisterHook(hookName) {
23079
- this.registeredHooks.delete(hookName);
23391
+ this.hooksManager.unregisterHook(hookName);
23392
+ }
23393
+ async acquireMutexLock({ nodeIds, operation }, action) {
23394
+ return await this.mutexManager.acquireMutexLock({
23395
+ nodeIds,
23396
+ operation
23397
+ }, action);
23398
+ }
23399
+ setMutexLock({ nodeIds, operation, metadata }) {
23400
+ return this.mutexManager.setMutexLock({
23401
+ nodeIds,
23402
+ operation,
23403
+ metadata
23404
+ });
23405
+ }
23406
+ releaseMutexLock() {
23407
+ this.mutexManager.releaseMutexLock();
23408
+ }
23409
+ getLockDetails(lockId) {
23410
+ return this.mutexManager.getUserMutexLock(lockId);
23411
+ }
23412
+ getNodeMutexLock(nodeId) {
23413
+ return this.mutexManager.getNodeMutexLock(nodeId);
23080
23414
  }
23081
23415
  };
23082
23416
 
@@ -23225,11 +23559,15 @@ var WeaveLayerNode = class extends WeaveNode {
23225
23559
  if (!handler) continue;
23226
23560
  childrenMapped.push(handler.serialize(node));
23227
23561
  }
23562
+ const cleanedAttrs = { ...attrs };
23563
+ delete cleanedAttrs.mutexLocked;
23564
+ delete cleanedAttrs.mutexUserId;
23565
+ delete cleanedAttrs.draggable;
23228
23566
  return {
23229
23567
  key: attrs.id ?? "",
23230
23568
  type: attrs.nodeType,
23231
23569
  props: {
23232
- ...attrs,
23570
+ ...cleanedAttrs,
23233
23571
  id: attrs.id ?? "",
23234
23572
  nodeType: attrs.nodeType,
23235
23573
  children: childrenMapped
@@ -23302,11 +23640,15 @@ var WeaveGroupNode = class extends WeaveNode {
23302
23640
  if (!handler) continue;
23303
23641
  childrenMapped.push(handler.serialize(node));
23304
23642
  }
23643
+ const cleanedAttrs = { ...attrs };
23644
+ delete cleanedAttrs.mutexLocked;
23645
+ delete cleanedAttrs.mutexUserId;
23646
+ delete cleanedAttrs.draggable;
23305
23647
  return {
23306
23648
  key: attrs.id ?? "",
23307
23649
  type: attrs.nodeType,
23308
23650
  props: {
23309
- ...attrs,
23651
+ ...cleanedAttrs,
23310
23652
  id: attrs.id ?? "",
23311
23653
  nodeType: attrs.nodeType,
23312
23654
  sceneFunc: void 0,
@@ -23918,7 +24260,7 @@ var WeaveTextNode = class extends WeaveNode {
23918
24260
  text.on("transformstart", (e) => {
23919
24261
  this.instance.emitEvent("onTransform", e.target);
23920
24262
  });
23921
- text.on("transform", (0, import_lodash.throttle)(handleTextTransform, 50));
24263
+ text.on("transform", (0, import_lodash.throttle)(handleTextTransform, DEFAULT_THROTTLE_MS));
23922
24264
  text.on("transformend", () => {
23923
24265
  this.instance.emitEvent("onTransform", null);
23924
24266
  });
@@ -23987,6 +24329,8 @@ var WeaveTextNode = class extends WeaveNode {
23987
24329
  serialize(instance) {
23988
24330
  const attrs = instance.getAttrs();
23989
24331
  const cleanedAttrs = { ...attrs };
24332
+ delete cleanedAttrs.mutexLocked;
24333
+ delete cleanedAttrs.mutexUserId;
23990
24334
  delete cleanedAttrs.draggable;
23991
24335
  delete cleanedAttrs.triggerEditMode;
23992
24336
  delete cleanedAttrs.cancelEditMode;
@@ -24145,6 +24489,13 @@ var WeaveTextNode = class extends WeaveNode {
24145
24489
  const correctionY = (actualFont === void 0 ? 0 : actualFont.offsetY ?? 0) * stage.scaleX();
24146
24490
  this.textArea.style.left = `${correctionX - 1}px`;
24147
24491
  this.textArea.style.top = `${correctionY}px`;
24492
+ const updateTextNode = () => {
24493
+ if (!this.textArea) return;
24494
+ updateTextNodeSize();
24495
+ textNode.text(this.textArea.value);
24496
+ textNode.visible(true);
24497
+ this.instance.updateNode(this.serialize(textNode));
24498
+ };
24148
24499
  this.textArea.onfocus = () => {
24149
24500
  this.textAreaDomResize(textNode);
24150
24501
  };
@@ -24156,9 +24507,11 @@ var WeaveTextNode = class extends WeaveNode {
24156
24507
  };
24157
24508
  this.textArea.onpaste = () => {
24158
24509
  this.textAreaDomResize(textNode);
24510
+ updateTextNode();
24159
24511
  };
24160
24512
  this.textArea.oninput = () => {
24161
24513
  this.textAreaDomResize(textNode);
24514
+ updateTextNode();
24162
24515
  };
24163
24516
  this.textAreaSuperContainer.addEventListener("scroll", () => {
24164
24517
  if (this.textAreaSuperContainer) {
@@ -24287,6 +24640,7 @@ var WeaveTextNode = class extends WeaveNode {
24287
24640
  else textNode.visible(true);
24288
24641
  }
24289
24642
  removeTextAreaDOM(textNode) {
24643
+ this.instance.releaseMutexLock();
24290
24644
  this.editing = false;
24291
24645
  const stage = this.instance.getStage();
24292
24646
  delete window.weaveTextEditing[textNode.id()];
@@ -24309,6 +24663,11 @@ var WeaveTextNode = class extends WeaveNode {
24309
24663
  this.instance.emitEvent("onExitTextNodeEditMode", { node: textNode });
24310
24664
  }
24311
24665
  triggerEditMode(textNode) {
24666
+ const lockAcquired = this.instance.setMutexLock({
24667
+ nodeIds: [textNode.id()],
24668
+ operation: "text-edit"
24669
+ });
24670
+ if (!lockAcquired) return;
24312
24671
  this.editing = true;
24313
24672
  textNode.visible(false);
24314
24673
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
@@ -24533,6 +24892,7 @@ var WeaveImageCrop = class WeaveImageCrop {
24533
24892
  const nodesSelectionPlugin = this.getNodesSelectionPlugin();
24534
24893
  if (nodesSelectionPlugin) nodesSelectionPlugin.enable();
24535
24894
  stage.mode(WEAVE_STAGE_DEFAULT_MODE);
24895
+ this.instance.releaseMutexLock();
24536
24896
  this.instance.emitEvent("onImageCropEnd", { instance: this.image });
24537
24897
  }
24538
24898
  drawGridLines(x, y, width, height) {
@@ -24714,6 +25074,11 @@ var WeaveImageNode = class extends WeaveNode {
24714
25074
  const stage = this.instance.getStage();
24715
25075
  if (imageNode.getAttrs().cropping ?? false) return;
24716
25076
  if (!(this.isSelecting() && this.isNodeSelected(imageNode))) return;
25077
+ const lockAcquired = this.instance.setMutexLock({
25078
+ nodeIds: [imageNode.id()],
25079
+ operation: "image-crop"
25080
+ });
25081
+ if (!lockAcquired) return;
24717
25082
  stage.mode("cropping");
24718
25083
  const image = stage.findOne(`#${imageNode.getAttrs().id}`);
24719
25084
  const internalImage = image?.findOne(`#${image.getAttrs().id}-image`);
@@ -25688,6 +26053,8 @@ var WeaveFrameNode = class extends WeaveNode {
25688
26053
  }
25689
26054
  const realAttrs = mainNode?.getAttrs();
25690
26055
  const cleanedAttrs = { ...realAttrs };
26056
+ delete cleanedAttrs.mutexLocked;
26057
+ delete cleanedAttrs.mutexUserId;
25691
26058
  delete cleanedAttrs.draggable;
25692
26059
  delete cleanedAttrs.onTargetEnter;
25693
26060
  return {
@@ -25920,6 +26287,8 @@ var WeaveStrokeNode = class extends WeaveNode {
25920
26287
  serialize(instance) {
25921
26288
  const attrs = instance.getAttrs();
25922
26289
  const cleanedAttrs = { ...attrs };
26290
+ delete cleanedAttrs.mutexLocked;
26291
+ delete cleanedAttrs.mutexUserId;
25923
26292
  delete cleanedAttrs.draggable;
25924
26293
  delete cleanedAttrs.sceneFunc;
25925
26294
  delete cleanedAttrs.hitFunc;
@@ -29092,6 +29461,8 @@ var WeaveConnectorNode = class extends WeaveNode {
29092
29461
  serialize(instance) {
29093
29462
  const attrs = instance.getAttrs();
29094
29463
  const cleanedAttrs = { ...attrs };
29464
+ delete cleanedAttrs.mutexLocked;
29465
+ delete cleanedAttrs.mutexUserId;
29095
29466
  delete cleanedAttrs.draggable;
29096
29467
  delete cleanedAttrs.sceneFunc;
29097
29468
  delete cleanedAttrs.hitFunc;
@@ -29272,7 +29643,7 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
29272
29643
  this.config.zoomSteps = [minimumZoom, ...this.config.zoomSteps];
29273
29644
  }
29274
29645
  };
29275
- mainLayer?.on("draw", (0, import_lodash.throttle)(handleDraw, 50));
29646
+ mainLayer?.on("draw", (0, import_lodash.throttle)(handleDraw, DEFAULT_THROTTLE_MS));
29276
29647
  this.setZoom(this.config.zoomSteps[this.actualStep]);
29277
29648
  }
29278
29649
  setZoom(scale, centered = true, pointer) {
@@ -29438,15 +29809,8 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
29438
29809
  });
29439
29810
  this.setZoom(scale, false);
29440
29811
  }
29441
- fitToSelection(smartZoom = false) {
29442
- if (!this.enabled) return;
29812
+ fitToElements(box, smartZoom = false) {
29443
29813
  const stage = this.instance.getStage();
29444
- const selectionPlugin = this.getNodesSelectionPlugin();
29445
- if (!selectionPlugin) return;
29446
- const nodes = selectionPlugin.getTransformer().getNodes();
29447
- if (nodes.length === 0) return;
29448
- const box = getBoundingBox(selectionPlugin.getTransformer().getNodes(), { relativeTo: stage });
29449
- if (box.width === 0 || box.height === 0) return;
29450
29814
  const container = stage.container();
29451
29815
  const scale = stage.scale();
29452
29816
  const containerWidth = container.clientWidth;
@@ -29497,6 +29861,26 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
29497
29861
  });
29498
29862
  this.setZoom(finalScale, false);
29499
29863
  }
29864
+ fitToNodes(nodes, smartZoom = false) {
29865
+ if (!this.enabled) return;
29866
+ const stage = this.instance.getStage();
29867
+ if (nodes.length === 0) return;
29868
+ const nodesInstances = nodes.map((nodeId) => this.instance.getStage().findOne(`#${nodeId}`)).filter((node) => node !== null);
29869
+ const box = getBoundingBox(nodesInstances, { relativeTo: stage });
29870
+ if (box.width === 0 || box.height === 0) return;
29871
+ this.fitToElements(box, smartZoom);
29872
+ }
29873
+ fitToSelection(smartZoom = false) {
29874
+ if (!this.enabled) return;
29875
+ const stage = this.instance.getStage();
29876
+ const selectionPlugin = this.getNodesSelectionPlugin();
29877
+ if (!selectionPlugin) return;
29878
+ const nodes = selectionPlugin.getTransformer().getNodes();
29879
+ if (nodes.length === 0) return;
29880
+ const box = getBoundingBox(selectionPlugin.getTransformer().getNodes(), { relativeTo: stage });
29881
+ if (box.width === 0 || box.height === 0) return;
29882
+ this.fitToElements(box, smartZoom);
29883
+ }
29500
29884
  enable() {
29501
29885
  this.enabled = true;
29502
29886
  }
@@ -29618,7 +30002,7 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
29618
30002
  requestAnimationFrame(this.zoomTick.bind(this));
29619
30003
  }
29620
30004
  };
29621
- const throttledHandleWheel = (0, import_lodash.throttle)(handleWheel, 30);
30005
+ const throttledHandleWheel = (0, import_lodash.throttle)(handleWheel, DEFAULT_THROTTLE_MS);
29622
30006
  window.addEventListener("wheel", throttledHandleWheel, { passive: true });
29623
30007
  }
29624
30008
  getInertiaScale() {
@@ -32075,12 +32459,12 @@ var WeaveArrowToolAction = class extends WeaveAction {
32075
32459
  this.instance.addNode(finalArrow, this.container?.getAttrs().id);
32076
32460
  this.instance.emitEvent("onAddedArrow");
32077
32461
  }
32078
- }
32079
- const selectionPlugin = this.instance.getPlugin("nodesSelection");
32080
- if (selectionPlugin) {
32081
- const node = stage.findOne(`#${this.arrowId}`);
32082
- if (node) selectionPlugin.setSelectedNodes([node]);
32083
- this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
32462
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
32463
+ if (selectionPlugin) {
32464
+ const node = stage.findOne(`#${this.arrowId}`);
32465
+ if (node) selectionPlugin.setSelectedNodes([node]);
32466
+ this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
32467
+ }
32084
32468
  }
32085
32469
  stage.container().style.cursor = "default";
32086
32470
  this.initialCursor = null;
@@ -33953,7 +34337,7 @@ var WeaveStageGridPlugin = class extends WeavePlugin {
33953
34337
  if (!this.enabled || !(this.isSpaceKeyPressed || this.isMouseMiddleButtonPressed || this.moveToolActive)) return;
33954
34338
  this.onRender();
33955
34339
  };
33956
- stage.on("pointermove", (0, import_lodash.throttle)(handleMouseMove, 50));
34340
+ stage.on("pointermove", (0, import_lodash.throttle)(handleMouseMove, DEFAULT_THROTTLE_MS));
33957
34341
  stage.on("pointermove", () => {
33958
34342
  if (this.enabled) this.onRender();
33959
34343
  });
@@ -34260,7 +34644,7 @@ var WeaveStagePanningPlugin = class extends WeavePlugin {
34260
34644
  lastPos = pos;
34261
34645
  this.instance.emitEvent("onStageMove");
34262
34646
  };
34263
- stage.on("pointermove", (0, import_lodash.throttle)(handleMouseMove, 50));
34647
+ stage.on("pointermove", (0, import_lodash.throttle)(handleMouseMove, DEFAULT_THROTTLE_MS));
34264
34648
  stage.on("pointerup", (e) => {
34265
34649
  this.pointers.delete(e.evt.pointerId);
34266
34650
  this.isMouseLeftButtonPressed = false;
@@ -34286,7 +34670,7 @@ var WeaveStagePanningPlugin = class extends WeavePlugin {
34286
34670
  stage.y(stage.y() - e.deltaY);
34287
34671
  this.instance.emitEvent("onStageMove");
34288
34672
  };
34289
- const handleWheelThrottled = (0, import_lodash.throttle)(handleWheel, 20);
34673
+ const handleWheelThrottled = (0, import_lodash.throttle)(handleWheel, WEAVE_STAGE_PANNING_THROTTLE_MS);
34290
34674
  window.addEventListener("wheel", handleWheelThrottled, { passive: true });
34291
34675
  stage.on("dragstart", (e) => {
34292
34676
  const duration = 1e3 / 60;
@@ -34528,7 +34912,7 @@ var WeaveStageMinimapPlugin = class extends WeavePlugin {
34528
34912
  const throttledUpdateMinimap = (0, import_lodash.throttle)(async () => {
34529
34913
  await this.updateMinimapContent();
34530
34914
  this.updateMinimapViewportReference();
34531
- }, 100);
34915
+ }, DEFAULT_THROTTLE_MS);
34532
34916
  this.instance.addEventListener("onStateChange", throttledUpdateMinimap);
34533
34917
  if (this.instance.isServerSide()) return;
34534
34918
  const workerPath = new URL("./stage-minimap.worker.js", import.meta.url);
@@ -34622,7 +35006,7 @@ var WeaveStageResizePlugin = class extends WeavePlugin {
34622
35006
  onInit() {
34623
35007
  const throttledResize = (0, import_lodash.throttle)(() => {
34624
35008
  this.resizeStage();
34625
- }, 100);
35009
+ }, DEFAULT_THROTTLE_MS);
34626
35010
  window.addEventListener("resize", () => {
34627
35011
  throttledResize();
34628
35012
  });
@@ -34809,11 +35193,6 @@ var WeaveNodesMultiSelectionFeedbackPlugin = class extends WeavePlugin {
34809
35193
  }
34810
35194
  };
34811
35195
 
34812
- //#endregion
34813
- //#region src/plugins/connected-users/constants.ts
34814
- const WEAVE_CONNECTED_USERS_KEY = "connectedUsers";
34815
- const WEAVE_CONNECTED_USER_INFO_KEY = "userInfo";
34816
-
34817
35196
  //#endregion
34818
35197
  //#region src/plugins/connected-users/connected-users.ts
34819
35198
  var WeaveConnectedUsersPlugin = class extends WeavePlugin {
@@ -35029,7 +35408,7 @@ const WEAVE_DEFAULT_USER_INFO_FUNCTION = () => ({
35029
35408
  email: "unknown@domain.com"
35030
35409
  });
35031
35410
  const WEAVE_USERS_POINTERS_CONFIG_DEFAULT_PROPS = {
35032
- awarenessThrottleMs: 100,
35411
+ awarenessThrottleMs: DEFAULT_THROTTLE_MS,
35033
35412
  ui: {
35034
35413
  separation: 8,
35035
35414
  pointer: {
@@ -35042,8 +35421,10 @@ const WEAVE_USERS_POINTERS_CONFIG_DEFAULT_PROPS = {
35042
35421
  backgroundCornerRadius: 0,
35043
35422
  backgroundPaddingX: 8,
35044
35423
  backgroundPaddingY: 4
35045
- }
35046
- }
35424
+ },
35425
+ operationSeparation: 4
35426
+ },
35427
+ getOperationName: (operation) => operation
35047
35428
  };
35048
35429
 
35049
35430
  //#endregion
@@ -35057,6 +35438,7 @@ var WeaveUsersPointersPlugin = class extends WeavePlugin {
35057
35438
  this.config.getUserBackgroundColor = memoize(this.config.getUserBackgroundColor);
35058
35439
  this.config.getUserForegroundColor = memoize(this.config.getUserForegroundColor);
35059
35440
  this.usersPointers = {};
35441
+ this.usersOperations = {};
35060
35442
  }
35061
35443
  getName() {
35062
35444
  return WEAVE_USERS_POINTERS_KEY;
@@ -35113,6 +35495,16 @@ var WeaveUsersPointersPlugin = class extends WeavePlugin {
35113
35495
  };
35114
35496
  const throttledHandleOnPointerMove = (0, import_lodash.throttle)(handleOnPointerMove, this.config.awarenessThrottleMs);
35115
35497
  stage.on("pointermove", throttledHandleOnPointerMove);
35498
+ const handleUsersLocksChange = ({ locks }) => {
35499
+ const actUsersLocks = {};
35500
+ for (const lockKey of locks) {
35501
+ const mutexInfo = this.instance?.getLockDetails(lockKey);
35502
+ if (mutexInfo) actUsersLocks[lockKey] = mutexInfo;
35503
+ }
35504
+ this.usersOperations = actUsersLocks;
35505
+ this.renderPointers();
35506
+ };
35507
+ this.instance.addEventListener("onMutexLockChange", handleUsersLocksChange);
35116
35508
  this.renderPointers();
35117
35509
  }
35118
35510
  sendAwarenessUpdate(mousePos) {
@@ -35146,7 +35538,8 @@ var WeaveUsersPointersPlugin = class extends WeavePlugin {
35146
35538
  scaleY: 1 / stage.scaleY()
35147
35539
  });
35148
35540
  userPointerNode.moveToTop();
35149
- const { separation, pointer: { circleRadius, circleStrokeWidth }, name: { fontFamily, fontSize, backgroundCornerRadius, backgroundPaddingX, backgroundPaddingY } } = this.config.ui;
35541
+ const { separation, pointer: { circleRadius, circleStrokeWidth }, name: { fontFamily, fontSize, backgroundCornerRadius, backgroundPaddingX, backgroundPaddingY }, operationSeparation } = this.config.ui;
35542
+ const getOperationName = this.config.getOperationName;
35150
35543
  const userBackgroundColor = this.config.getUserBackgroundColor(userPointer.rawUser);
35151
35544
  const userForegroundColor = this.config.getUserForegroundColor(userPointer.rawUser);
35152
35545
  const userPointNode = new Konva.Circle({
@@ -35196,6 +35589,41 @@ var WeaveUsersPointersPlugin = class extends WeavePlugin {
35196
35589
  userPointerNode.add(userPointNode);
35197
35590
  userPointerNode.add(userNameBackground);
35198
35591
  userPointerNode.add(userNameNode);
35592
+ if (this.usersOperations[userPointer.user]) {
35593
+ const userOperationNode = new Konva.Text({
35594
+ id: `pointer_${userPointer.user}_userPointOperation`,
35595
+ x: separation,
35596
+ y: -circleRadius * 2 + backgroundPaddingY + operationSeparation + textHeight + backgroundPaddingY * 2,
35597
+ text: getOperationName(this.usersOperations[userPointer.user].operation),
35598
+ fontSize,
35599
+ fontFamily,
35600
+ lineHeight: .9,
35601
+ fill: userForegroundColor,
35602
+ align: "center",
35603
+ verticalAlign: "middle",
35604
+ draggable: false,
35605
+ listening: false,
35606
+ strokeScaleEnabled: false,
35607
+ ellipsis: true
35608
+ });
35609
+ const textOperationWidth = userOperationNode.getTextWidth();
35610
+ const textOperationHeight = userOperationNode.getTextHeight();
35611
+ userOperationNode.width(textOperationWidth + backgroundPaddingX * 2);
35612
+ userOperationNode.height(textOperationHeight + backgroundPaddingY * 2);
35613
+ const userOperationBackground = new Konva.Rect({
35614
+ id: `pointer_${userPointer.user}_userPointOperationRect`,
35615
+ x: separation,
35616
+ y: -backgroundPaddingY + 4 + userNameBackground.height(),
35617
+ width: textOperationWidth + backgroundPaddingX * 2,
35618
+ height: textOperationHeight + backgroundPaddingY * 2,
35619
+ cornerRadius: backgroundCornerRadius,
35620
+ fill: userBackgroundColor,
35621
+ draggable: false,
35622
+ listening: false
35623
+ });
35624
+ userPointerNode.add(userOperationBackground);
35625
+ userPointerNode.add(userOperationNode);
35626
+ }
35199
35627
  pointersLayer?.add(userPointerNode);
35200
35628
  }
35201
35629
  const selectors = pointersLayer?.find(".selector") ?? [];
@@ -35211,6 +35639,78 @@ var WeaveUsersPointersPlugin = class extends WeavePlugin {
35211
35639
  }
35212
35640
  };
35213
35641
 
35642
+ //#endregion
35643
+ //#region src/plugins/users-presence/users-presence.ts
35644
+ var WeaveUsersPresencePlugin = class extends WeavePlugin {
35645
+ userPresence = {};
35646
+ onRender = void 0;
35647
+ constructor(params) {
35648
+ super();
35649
+ const { config } = params;
35650
+ this.config = mergeExceptArrays(WEAVE_USERS_PRESENCE_CONFIG_DEFAULT_PROPS, config);
35651
+ this.userPresence = {};
35652
+ }
35653
+ getName() {
35654
+ return WEAVE_USERS_PRESENCE_PLUGIN_KEY;
35655
+ }
35656
+ registerHooks() {
35657
+ this.instance.registerHook("onPresenceUpdate:usersPresencePlugin", ({ node, presenceData }) => {
35658
+ const nodeHandler = this.instance.getNodeHandler(node.getAttrs().nodeType);
35659
+ const newProps = {
35660
+ ...node.getAttrs(),
35661
+ ...presenceData
35662
+ };
35663
+ nodeHandler?.onUpdate(node, newProps);
35664
+ });
35665
+ }
35666
+ onInit() {
35667
+ const stage = this.instance.getStage();
35668
+ this.registerHooks();
35669
+ this.instance.addEventListener("onAwarenessChange", (changes) => {
35670
+ for (const change of changes) {
35671
+ if (!change[WEAVE_USER_PRESENCE_KEY]) continue;
35672
+ const userPresence = change[WEAVE_USER_PRESENCE_KEY];
35673
+ const nodes = Object.keys(userPresence);
35674
+ if (nodes.length === 0) continue;
35675
+ for (const nodeId of nodes) {
35676
+ const presenceInfo = userPresence[nodeId];
35677
+ if (this.config.getUser().id === presenceInfo.userId) continue;
35678
+ const nodeInstance = stage.findOne(`#${presenceInfo.nodeId}`);
35679
+ if (nodeInstance) this.instance.runPhaseHooks("onPresenceUpdate", (hook) => {
35680
+ hook({
35681
+ node: nodeInstance,
35682
+ presenceData: presenceInfo.attrs
35683
+ });
35684
+ });
35685
+ }
35686
+ }
35687
+ });
35688
+ }
35689
+ sendPresence() {
35690
+ const store = this.instance.getStore();
35691
+ store.setAwarenessInfo(WEAVE_USER_PRESENCE_KEY, this.userPresence);
35692
+ }
35693
+ setPresence(nodeId, attrs) {
35694
+ const userInfo = this.config.getUser();
35695
+ this.userPresence[nodeId] = {
35696
+ userId: userInfo.id,
35697
+ nodeId,
35698
+ attrs
35699
+ };
35700
+ this.sendPresence();
35701
+ }
35702
+ removePresence(nodeId) {
35703
+ if (this.userPresence[nodeId]) delete this.userPresence[nodeId];
35704
+ this.sendPresence();
35705
+ }
35706
+ enable() {
35707
+ this.enabled = true;
35708
+ }
35709
+ disable() {
35710
+ this.enabled = false;
35711
+ }
35712
+ };
35713
+
35214
35714
  //#endregion
35215
35715
  //#region src/plugins/stage-drop-area/constants.ts
35216
35716
  const WEAVE_STAGE_DROP_AREA_KEY = "stageDropArea";
@@ -36358,5 +36858,5 @@ const setupCanvasBackend = async () => {
36358
36858
  };
36359
36859
 
36360
36860
  //#endregion
36361
- export { ALIGN_NODES_ALIGN_TO, ALIGN_NODES_TOOL_ACTION_NAME, ALIGN_NODES_TOOL_STATE, ARROW_TOOL_ACTION_NAME, ARROW_TOOL_STATE, BRUSH_TOOL_ACTION_NAME, BRUSH_TOOL_DEFAULT_CONFIG, BRUSH_TOOL_STATE, CONNECTOR_TOOL_ACTION_NAME, CONNECTOR_TOOL_DEFAULT_CONFIG, CONNECTOR_TOOL_STATE, COPY_PASTE_NODES_PLUGIN_STATE, ELLIPSE_TOOL_ACTION_NAME, ELLIPSE_TOOL_STATE, ERASER_TOOL_ACTION_NAME, ERASER_TOOL_STATE, FRAME_TOOL_ACTION_NAME, FRAME_TOOL_STATE, GUIDE_DISTANCE_LINE_DEFAULT_CONFIG, GUIDE_ENTER_SNAPPING_TOLERANCE, GUIDE_EXIT_SNAPPING_TOLERANCE, GUIDE_HORIZONTAL_LINE_NAME, GUIDE_LINE_DEFAULT_CONFIG, GUIDE_LINE_DRAG_SNAPPING_THRESHOLD, GUIDE_LINE_NAME, GUIDE_LINE_TRANSFORM_SNAPPING_THRESHOLD, GUIDE_ORIENTATION, GUIDE_VERTICAL_LINE_NAME, IMAGE_TOOL_ACTION_NAME, IMAGE_TOOL_STATE, LINE_TOOL_ACTION_NAME, LINE_TOOL_DEFAULT_CONFIG, LINE_TOOL_STATE, MEASURE_TOOL_ACTION_NAME, MEASURE_TOOL_STATE, MOVE_TOOL_ACTION_NAME, MOVE_TOOL_STATE, NODE_SNAP, NODE_SNAP_HORIZONTAL, NODE_SNAP_VERTICAL, PEN_TOOL_ACTION_NAME, PEN_TOOL_STATE, RECTANGLE_TOOL_ACTION_NAME, RECTANGLE_TOOL_STATE, REGULAR_POLYGON_TOOL_ACTION_NAME, REGULAR_POLYGON_TOOL_STATE, SELECTION_TOOL_ACTION_NAME, SELECTION_TOOL_STATE, STAGE_MINIMAP_DEFAULT_CONFIG, STAR_TOOL_ACTION_NAME, STAR_TOOL_STATE, TEXT_LAYOUT, TEXT_TOOL_ACTION_NAME, TEXT_TOOL_STATE, VIDEO_TOOL_ACTION_NAME, VIDEO_TOOL_STATE, WEAVE_ARROW_NODE_TYPE, WEAVE_COMMENTS_RENDERER_KEY, WEAVE_COMMENTS_TOOL_LAYER_ID, WEAVE_COMMENT_CREATE_ACTION, WEAVE_COMMENT_NODE_ACTION, WEAVE_COMMENT_NODE_DEFAULTS, WEAVE_COMMENT_NODE_TYPE, WEAVE_COMMENT_STATUS, WEAVE_COMMENT_TOOL_ACTION_NAME, WEAVE_COMMENT_TOOL_DEFAULT_CONFIG, WEAVE_COMMENT_TOOL_STATE, WEAVE_COMMENT_VIEW_ACTION, WEAVE_CONNECTOR_NODE_ANCHOR_ORIGIN, WEAVE_CONNECTOR_NODE_DECORATOR_TYPE, WEAVE_CONNECTOR_NODE_DEFAULT_CONFIG, WEAVE_CONNECTOR_NODE_LINE_ORIGIN, WEAVE_CONNECTOR_NODE_LINE_TYPE, WEAVE_CONNECTOR_NODE_TYPE, WEAVE_COPY_PASTE_CONFIG_DEFAULT, WEAVE_COPY_PASTE_NODES_KEY, WEAVE_COPY_PASTE_PASTE_CATCHER_ID, WEAVE_COPY_PASTE_PASTE_MODES, WEAVE_DEFAULT_USER_INFO_FUNCTION, WEAVE_ELLIPSE_NODE_TYPE, WEAVE_FRAME_DEFAULT_BACKGROUND_COLOR, WEAVE_FRAME_NODE_DEFAULT_CONFIG, WEAVE_FRAME_NODE_DEFAULT_PROPS, WEAVE_FRAME_NODE_TYPE, WEAVE_GRID_DEFAULT_COLOR, WEAVE_GRID_DEFAULT_DOT_MAX_DOTS_PER_AXIS, WEAVE_GRID_DEFAULT_MAJOR_DOT_RATIO, WEAVE_GRID_DEFAULT_MAJOR_EVERY, WEAVE_GRID_DEFAULT_MAJOR_LINE_RATIO, WEAVE_GRID_DEFAULT_ORIGIN_COLOR, WEAVE_GRID_DEFAULT_RADIUS, WEAVE_GRID_DEFAULT_SIZE, WEAVE_GRID_DEFAULT_STROKE, WEAVE_GRID_DEFAULT_TYPE, WEAVE_GRID_LAYER_ID, WEAVE_GRID_TYPES, WEAVE_GROUP_NODE_TYPE, WEAVE_IMAGE_CROP_END_TYPE, WEAVE_IMAGE_DEFAULT_CONFIG, WEAVE_IMAGE_NODE_TYPE, WEAVE_LAYER_NODE_TYPE, WEAVE_LINE_NODE_DEFAULT_CONFIG, WEAVE_LINE_NODE_TYPE, WEAVE_MEASURE_NODE_DEFAULT_CONFIG, WEAVE_MEASURE_NODE_TYPE, WEAVE_MEASURE_TOOL_DEFAULT_CONFIG, WEAVE_NODES_DISTANCE_SNAPPING_PLUGIN_KEY, WEAVE_NODES_EDGE_SNAPPING_PLUGIN_KEY, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_DEFAULT_CONFIG, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_KEY, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_LAYER_ID, WEAVE_NODES_SELECTION_DEFAULT_CONFIG, WEAVE_NODES_SELECTION_KEY, WEAVE_NODES_SELECTION_LAYER_ID, WEAVE_RECTANGLE_NODE_TYPE, WEAVE_REGULAR_POLYGON_NODE_TYPE, WEAVE_STAGE_DEFAULT_MODE, WEAVE_STAGE_GRID_PLUGIN_KEY, WEAVE_STAGE_KEYBOARD_MOVE_DEFAULT_CONFIG, WEAVE_STAGE_KEYBOARD_MOVE_KEY, WEAVE_STAGE_MINIMAP_KEY, WEAVE_STAGE_NODE_TYPE, WEAVE_STAGE_PANNING_DEFAULT_CONFIG, WEAVE_STAGE_PANNING_KEY, WEAVE_STAR_NODE_TYPE, WEAVE_STROKE_NODE_DEFAULT_CONFIG, WEAVE_STROKE_NODE_TYPE, WEAVE_TEXT_NODE_TYPE, WEAVE_USERS_POINTERS_CONFIG_DEFAULT_PROPS, WEAVE_USERS_POINTERS_KEY, WEAVE_USERS_SELECTION_KEY, WEAVE_USER_POINTER_KEY, WEAVE_USER_SELECTION_KEY, WEAVE_VIDEO_DEFAULT_CONFIG, WEAVE_VIDEO_NODE_TYPE, Weave, WeaveAction, WeaveAlignNodesToolAction, WeaveArrowNode, WeaveArrowToolAction, WeaveBrushToolAction, WeaveCommentNode, WeaveCommentToolAction, WeaveCommentsRendererPlugin, WeaveConnectedUsersPlugin, WeaveConnectorNode, WeaveConnectorToolAction, WeaveContextMenuPlugin, WeaveCopyPasteNodesPlugin, WeaveEllipseNode, WeaveEllipseToolAction, WeaveEraserToolAction, WeaveExportNodesToolAction, WeaveExportStageToolAction, WeaveFitToScreenToolAction, WeaveFitToSelectionToolAction, WeaveFrameNode, WeaveFrameToolAction, WeaveGroupNode, WeaveImageNode, WeaveImageToolAction, WeaveLayerNode, WeaveLineNode, WeaveLineToolAction, WeaveMeasureNode, WeaveMeasureToolAction, WeaveMoveToolAction, WeaveNode, WeaveNodesDistanceSnappingPlugin, WeaveNodesEdgeSnappingPlugin, WeaveNodesMultiSelectionFeedbackPlugin, WeaveNodesSelectionPlugin, WeavePenToolAction, WeavePlugin, WeaveRectangleNode, WeaveRectangleToolAction, WeaveRegularPolygonNode, WeaveRegularPolygonToolAction, WeaveSelectionToolAction, WeaveStageDropAreaPlugin, WeaveStageGridPlugin, WeaveStageKeyboardMovePlugin, WeaveStageMinimapPlugin, WeaveStageNode, WeaveStagePanningPlugin, WeaveStageResizePlugin, WeaveStageZoomPlugin, WeaveStarNode, WeaveStarToolAction, WeaveStore, WeaveStrokeNode, WeaveTextNode, WeaveTextToolAction, WeaveUsersPointersPlugin, WeaveUsersSelectionPlugin, WeaveVideoNode, WeaveVideoToolAction, WeaveZoomInToolAction, WeaveZoomOutToolAction, canComposite, clearContainerTargets, containerOverCursor, containsNodeDeep, defaultInitialState, getBoundingBox, getExportBoundingBox, getPositionRelativeToContainerOnPosition, getSelectedNodesMetadata, getStageClickPoint, getTargetAndSkipNodes, getTargetedNode, getTopmostShadowHost, getVisibleNodes, getVisibleNodesInViewport, hasFrames, hasImages, intersectArrays, isIOS, isInShadowDOM, isNodeInSelection, isServer, memoize, mergeExceptArrays, moveNodeToContainer, resetScale, setupCanvasBackend, setupSkiaBackend };
36861
+ export { ALIGN_NODES_ALIGN_TO, ALIGN_NODES_TOOL_ACTION_NAME, ALIGN_NODES_TOOL_STATE, ARROW_TOOL_ACTION_NAME, ARROW_TOOL_STATE, BRUSH_TOOL_ACTION_NAME, BRUSH_TOOL_DEFAULT_CONFIG, BRUSH_TOOL_STATE, CONNECTOR_TOOL_ACTION_NAME, CONNECTOR_TOOL_DEFAULT_CONFIG, CONNECTOR_TOOL_STATE, COPY_PASTE_NODES_PLUGIN_STATE, ELLIPSE_TOOL_ACTION_NAME, ELLIPSE_TOOL_STATE, ERASER_TOOL_ACTION_NAME, ERASER_TOOL_STATE, FRAME_TOOL_ACTION_NAME, FRAME_TOOL_STATE, GUIDE_DISTANCE_LINE_DEFAULT_CONFIG, GUIDE_ENTER_SNAPPING_TOLERANCE, GUIDE_EXIT_SNAPPING_TOLERANCE, GUIDE_HORIZONTAL_LINE_NAME, GUIDE_LINE_DEFAULT_CONFIG, GUIDE_LINE_DRAG_SNAPPING_THRESHOLD, GUIDE_LINE_NAME, GUIDE_LINE_TRANSFORM_SNAPPING_THRESHOLD, GUIDE_ORIENTATION, GUIDE_VERTICAL_LINE_NAME, IMAGE_TOOL_ACTION_NAME, IMAGE_TOOL_STATE, LINE_TOOL_ACTION_NAME, LINE_TOOL_DEFAULT_CONFIG, LINE_TOOL_STATE, MEASURE_TOOL_ACTION_NAME, MEASURE_TOOL_STATE, MOVE_TOOL_ACTION_NAME, MOVE_TOOL_STATE, NODE_SNAP, NODE_SNAP_HORIZONTAL, NODE_SNAP_VERTICAL, PEN_TOOL_ACTION_NAME, PEN_TOOL_STATE, RECTANGLE_TOOL_ACTION_NAME, RECTANGLE_TOOL_STATE, REGULAR_POLYGON_TOOL_ACTION_NAME, REGULAR_POLYGON_TOOL_STATE, SELECTION_TOOL_ACTION_NAME, SELECTION_TOOL_STATE, STAGE_MINIMAP_DEFAULT_CONFIG, STAR_TOOL_ACTION_NAME, STAR_TOOL_STATE, TEXT_LAYOUT, TEXT_TOOL_ACTION_NAME, TEXT_TOOL_STATE, VIDEO_TOOL_ACTION_NAME, VIDEO_TOOL_STATE, WEAVE_ARROW_NODE_TYPE, WEAVE_COMMENTS_RENDERER_KEY, WEAVE_COMMENTS_TOOL_LAYER_ID, WEAVE_COMMENT_CREATE_ACTION, WEAVE_COMMENT_NODE_ACTION, WEAVE_COMMENT_NODE_DEFAULTS, WEAVE_COMMENT_NODE_TYPE, WEAVE_COMMENT_STATUS, WEAVE_COMMENT_TOOL_ACTION_NAME, WEAVE_COMMENT_TOOL_DEFAULT_CONFIG, WEAVE_COMMENT_TOOL_STATE, WEAVE_COMMENT_VIEW_ACTION, WEAVE_CONNECTOR_NODE_ANCHOR_ORIGIN, WEAVE_CONNECTOR_NODE_DECORATOR_TYPE, WEAVE_CONNECTOR_NODE_DEFAULT_CONFIG, WEAVE_CONNECTOR_NODE_LINE_ORIGIN, WEAVE_CONNECTOR_NODE_LINE_TYPE, WEAVE_CONNECTOR_NODE_TYPE, WEAVE_COPY_PASTE_CONFIG_DEFAULT, WEAVE_COPY_PASTE_NODES_KEY, WEAVE_COPY_PASTE_PASTE_CATCHER_ID, WEAVE_COPY_PASTE_PASTE_MODES, WEAVE_DEFAULT_USER_INFO_FUNCTION, WEAVE_ELLIPSE_NODE_TYPE, WEAVE_FRAME_DEFAULT_BACKGROUND_COLOR, WEAVE_FRAME_NODE_DEFAULT_CONFIG, WEAVE_FRAME_NODE_DEFAULT_PROPS, WEAVE_FRAME_NODE_TYPE, WEAVE_GRID_DEFAULT_COLOR, WEAVE_GRID_DEFAULT_DOT_MAX_DOTS_PER_AXIS, WEAVE_GRID_DEFAULT_MAJOR_DOT_RATIO, WEAVE_GRID_DEFAULT_MAJOR_EVERY, WEAVE_GRID_DEFAULT_MAJOR_LINE_RATIO, WEAVE_GRID_DEFAULT_ORIGIN_COLOR, WEAVE_GRID_DEFAULT_RADIUS, WEAVE_GRID_DEFAULT_SIZE, WEAVE_GRID_DEFAULT_STROKE, WEAVE_GRID_DEFAULT_TYPE, WEAVE_GRID_LAYER_ID, WEAVE_GRID_TYPES, WEAVE_GROUP_NODE_TYPE, WEAVE_IMAGE_CROP_END_TYPE, WEAVE_IMAGE_DEFAULT_CONFIG, WEAVE_IMAGE_NODE_TYPE, WEAVE_LAYER_NODE_TYPE, WEAVE_LINE_NODE_DEFAULT_CONFIG, WEAVE_LINE_NODE_TYPE, WEAVE_MEASURE_NODE_DEFAULT_CONFIG, WEAVE_MEASURE_NODE_TYPE, WEAVE_MEASURE_TOOL_DEFAULT_CONFIG, WEAVE_NODES_DISTANCE_SNAPPING_PLUGIN_KEY, WEAVE_NODES_EDGE_SNAPPING_PLUGIN_KEY, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_DEFAULT_CONFIG, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_KEY, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_LAYER_ID, WEAVE_NODES_SELECTION_DEFAULT_CONFIG, WEAVE_NODES_SELECTION_KEY, WEAVE_NODES_SELECTION_LAYER_ID, WEAVE_RECTANGLE_NODE_TYPE, WEAVE_REGULAR_POLYGON_NODE_TYPE, WEAVE_STAGE_DEFAULT_MODE, WEAVE_STAGE_GRID_PLUGIN_KEY, WEAVE_STAGE_KEYBOARD_MOVE_DEFAULT_CONFIG, WEAVE_STAGE_KEYBOARD_MOVE_KEY, WEAVE_STAGE_MINIMAP_KEY, WEAVE_STAGE_NODE_TYPE, WEAVE_STAGE_PANNING_DEFAULT_CONFIG, WEAVE_STAGE_PANNING_KEY, WEAVE_STAGE_PANNING_THROTTLE_MS, WEAVE_STAR_NODE_TYPE, WEAVE_STROKE_NODE_DEFAULT_CONFIG, WEAVE_STROKE_NODE_TYPE, WEAVE_TEXT_NODE_TYPE, WEAVE_USERS_POINTERS_CONFIG_DEFAULT_PROPS, WEAVE_USERS_POINTERS_KEY, WEAVE_USERS_PRESENCE_CONFIG_DEFAULT_PROPS, WEAVE_USERS_PRESENCE_PLUGIN_KEY, WEAVE_USERS_SELECTION_KEY, WEAVE_USER_POINTER_KEY, WEAVE_USER_PRESENCE_KEY, WEAVE_USER_SELECTION_KEY, WEAVE_VIDEO_DEFAULT_CONFIG, WEAVE_VIDEO_NODE_TYPE, Weave, WeaveAction, WeaveAlignNodesToolAction, WeaveArrowNode, WeaveArrowToolAction, WeaveBrushToolAction, WeaveCommentNode, WeaveCommentToolAction, WeaveCommentsRendererPlugin, WeaveConnectedUsersPlugin, WeaveConnectorNode, WeaveConnectorToolAction, WeaveContextMenuPlugin, WeaveCopyPasteNodesPlugin, WeaveEllipseNode, WeaveEllipseToolAction, WeaveEraserToolAction, WeaveExportNodesToolAction, WeaveExportStageToolAction, WeaveFitToScreenToolAction, WeaveFitToSelectionToolAction, WeaveFrameNode, WeaveFrameToolAction, WeaveGroupNode, WeaveImageNode, WeaveImageToolAction, WeaveLayerNode, WeaveLineNode, WeaveLineToolAction, WeaveMeasureNode, WeaveMeasureToolAction, WeaveMoveToolAction, WeaveNode, WeaveNodesDistanceSnappingPlugin, WeaveNodesEdgeSnappingPlugin, WeaveNodesMultiSelectionFeedbackPlugin, WeaveNodesSelectionPlugin, WeavePenToolAction, WeavePlugin, WeaveRectangleNode, WeaveRectangleToolAction, WeaveRegularPolygonNode, WeaveRegularPolygonToolAction, WeaveSelectionToolAction, WeaveStageDropAreaPlugin, WeaveStageGridPlugin, WeaveStageKeyboardMovePlugin, WeaveStageMinimapPlugin, WeaveStageNode, WeaveStagePanningPlugin, WeaveStageResizePlugin, WeaveStageZoomPlugin, WeaveStarNode, WeaveStarToolAction, WeaveStore, WeaveStrokeNode, WeaveTextNode, WeaveTextToolAction, WeaveUsersPointersPlugin, WeaveUsersPresencePlugin, WeaveUsersSelectionPlugin, WeaveVideoNode, WeaveVideoToolAction, WeaveZoomInToolAction, WeaveZoomOutToolAction, canComposite, clearContainerTargets, containerOverCursor, containsNodeDeep, defaultInitialState, getBoundingBox, getExportBoundingBox, getPositionRelativeToContainerOnPosition, getSelectedNodesMetadata, getStageClickPoint, getTargetAndSkipNodes, getTargetedNode, getTopmostShadowHost, getVisibleNodes, getVisibleNodesInViewport, hasFrames, hasImages, intersectArrays, isIOS, isInShadowDOM, isNodeInSelection, isServer, memoize, mergeExceptArrays, moveNodeToContainer, resetScale, setupCanvasBackend, setupSkiaBackend };
36362
36862
  //# sourceMappingURL=sdk.node.js.map