@oh-just-another/state 0.57.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.
Files changed (269) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/LICENSE +21 -0
  3. package/README.md +60 -0
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/actions/actionClipboard.d.ts +6 -0
  6. package/dist/actions/actionClipboard.d.ts.map +1 -0
  7. package/dist/actions/actionClipboard.js +26 -0
  8. package/dist/actions/actionClipboard.js.map +1 -0
  9. package/dist/actions/actionGrouping.d.ts +5 -0
  10. package/dist/actions/actionGrouping.d.ts.map +1 -0
  11. package/dist/actions/actionGrouping.js +26 -0
  12. package/dist/actions/actionGrouping.js.map +1 -0
  13. package/dist/actions/actionHistory.d.ts +5 -0
  14. package/dist/actions/actionHistory.d.ts.map +1 -0
  15. package/dist/actions/actionHistory.js +25 -0
  16. package/dist/actions/actionHistory.js.map +1 -0
  17. package/dist/actions/actionKeyboard.d.ts +3 -0
  18. package/dist/actions/actionKeyboard.d.ts.map +1 -0
  19. package/dist/actions/actionKeyboard.js +130 -0
  20. package/dist/actions/actionKeyboard.js.map +1 -0
  21. package/dist/actions/actionLayout.d.ts +3 -0
  22. package/dist/actions/actionLayout.d.ts.map +1 -0
  23. package/dist/actions/actionLayout.js +65 -0
  24. package/dist/actions/actionLayout.js.map +1 -0
  25. package/dist/actions/actionMode.d.ts +13 -0
  26. package/dist/actions/actionMode.d.ts.map +1 -0
  27. package/dist/actions/actionMode.js +116 -0
  28. package/dist/actions/actionMode.js.map +1 -0
  29. package/dist/actions/actionSelection.d.ts +9 -0
  30. package/dist/actions/actionSelection.d.ts.map +1 -0
  31. package/dist/actions/actionSelection.js +57 -0
  32. package/dist/actions/actionSelection.js.map +1 -0
  33. package/dist/actions/actionView.d.ts +7 -0
  34. package/dist/actions/actionView.d.ts.map +1 -0
  35. package/dist/actions/actionView.js +14 -0
  36. package/dist/actions/actionView.js.map +1 -0
  37. package/dist/actions/actionZOrder.d.ts +7 -0
  38. package/dist/actions/actionZOrder.d.ts.map +1 -0
  39. package/dist/actions/actionZOrder.js +42 -0
  40. package/dist/actions/actionZOrder.js.map +1 -0
  41. package/dist/actions/actionZoom.d.ts +8 -0
  42. package/dist/actions/actionZoom.d.ts.map +1 -0
  43. package/dist/actions/actionZoom.js +61 -0
  44. package/dist/actions/actionZoom.js.map +1 -0
  45. package/dist/actions/index.d.ts +12 -0
  46. package/dist/actions/index.d.ts.map +1 -0
  47. package/dist/actions/index.js +11 -0
  48. package/dist/actions/index.js.map +1 -0
  49. package/dist/actions/registry.d.ts +68 -0
  50. package/dist/actions/registry.d.ts.map +1 -0
  51. package/dist/actions/registry.js +300 -0
  52. package/dist/actions/registry.js.map +1 -0
  53. package/dist/actions/types.d.ts +103 -0
  54. package/dist/actions/types.d.ts.map +1 -0
  55. package/dist/actions/types.js +10 -0
  56. package/dist/actions/types.js.map +1 -0
  57. package/dist/animation-tick.d.ts +28 -0
  58. package/dist/animation-tick.d.ts.map +1 -0
  59. package/dist/animation-tick.js +50 -0
  60. package/dist/animation-tick.js.map +1 -0
  61. package/dist/auto-compact.d.ts +27 -0
  62. package/dist/auto-compact.d.ts.map +1 -0
  63. package/dist/auto-compact.js +46 -0
  64. package/dist/auto-compact.js.map +1 -0
  65. package/dist/auto-layout-scheduler.d.ts +50 -0
  66. package/dist/auto-layout-scheduler.d.ts.map +1 -0
  67. package/dist/auto-layout-scheduler.js +94 -0
  68. package/dist/auto-layout-scheduler.js.map +1 -0
  69. package/dist/built-in-handlers.d.ts +24 -0
  70. package/dist/built-in-handlers.d.ts.map +1 -0
  71. package/dist/built-in-handlers.js +210 -0
  72. package/dist/built-in-handlers.js.map +1 -0
  73. package/dist/clipboard.d.ts +51 -0
  74. package/dist/clipboard.d.ts.map +1 -0
  75. package/dist/clipboard.js +105 -0
  76. package/dist/clipboard.js.map +1 -0
  77. package/dist/constants.d.ts +544 -0
  78. package/dist/constants.d.ts.map +1 -0
  79. package/dist/constants.js +537 -0
  80. package/dist/constants.js.map +1 -0
  81. package/dist/dom-events.d.ts +13 -0
  82. package/dist/dom-events.d.ts.map +1 -0
  83. package/dist/dom-events.js +70 -0
  84. package/dist/dom-events.js.map +1 -0
  85. package/dist/editor/anchor-points.d.ts +22 -0
  86. package/dist/editor/anchor-points.d.ts.map +1 -0
  87. package/dist/editor/anchor-points.js +28 -0
  88. package/dist/editor/anchor-points.js.map +1 -0
  89. package/dist/editor/applies/create.d.ts +60 -0
  90. package/dist/editor/applies/create.d.ts.map +1 -0
  91. package/dist/editor/applies/create.js +107 -0
  92. package/dist/editor/applies/create.js.map +1 -0
  93. package/dist/editor/applies/edge.d.ts +32 -0
  94. package/dist/editor/applies/edge.d.ts.map +1 -0
  95. package/dist/editor/applies/edge.js +44 -0
  96. package/dist/editor/applies/edge.js.map +1 -0
  97. package/dist/editor/applies/link-move.d.ts +53 -0
  98. package/dist/editor/applies/link-move.d.ts.map +1 -0
  99. package/dist/editor/applies/link-move.js +160 -0
  100. package/dist/editor/applies/link-move.js.map +1 -0
  101. package/dist/editor/applies/move.d.ts +38 -0
  102. package/dist/editor/applies/move.d.ts.map +1 -0
  103. package/dist/editor/applies/move.js +83 -0
  104. package/dist/editor/applies/move.js.map +1 -0
  105. package/dist/editor/applies/resize.d.ts +68 -0
  106. package/dist/editor/applies/resize.d.ts.map +1 -0
  107. package/dist/editor/applies/resize.js +199 -0
  108. package/dist/editor/applies/resize.js.map +1 -0
  109. package/dist/editor/applies/selection.d.ts +34 -0
  110. package/dist/editor/applies/selection.d.ts.map +1 -0
  111. package/dist/editor/applies/selection.js +65 -0
  112. package/dist/editor/applies/selection.js.map +1 -0
  113. package/dist/editor/applies/snap-grid.d.ts +45 -0
  114. package/dist/editor/applies/snap-grid.d.ts.map +1 -0
  115. package/dist/editor/applies/snap-grid.js +90 -0
  116. package/dist/editor/applies/snap-grid.js.map +1 -0
  117. package/dist/editor/container-ops.d.ts +74 -0
  118. package/dist/editor/container-ops.d.ts.map +1 -0
  119. package/dist/editor/container-ops.js +262 -0
  120. package/dist/editor/container-ops.js.map +1 -0
  121. package/dist/editor/event-fanout.d.ts +48 -0
  122. package/dist/editor/event-fanout.d.ts.map +1 -0
  123. package/dist/editor/event-fanout.js +53 -0
  124. package/dist/editor/event-fanout.js.map +1 -0
  125. package/dist/editor/gesture-tx.d.ts +77 -0
  126. package/dist/editor/gesture-tx.d.ts.map +1 -0
  127. package/dist/editor/gesture-tx.js +93 -0
  128. package/dist/editor/gesture-tx.js.map +1 -0
  129. package/dist/editor/hit-test.d.ts +178 -0
  130. package/dist/editor/hit-test.d.ts.map +1 -0
  131. package/dist/editor/hit-test.js +460 -0
  132. package/dist/editor/hit-test.js.map +1 -0
  133. package/dist/editor/long-press.d.ts +34 -0
  134. package/dist/editor/long-press.d.ts.map +1 -0
  135. package/dist/editor/long-press.js +58 -0
  136. package/dist/editor/long-press.js.map +1 -0
  137. package/dist/editor/pinch.d.ts +37 -0
  138. package/dist/editor/pinch.d.ts.map +1 -0
  139. package/dist/editor/pinch.js +90 -0
  140. package/dist/editor/pinch.js.map +1 -0
  141. package/dist/editor/pointer-binding.d.ts +18 -0
  142. package/dist/editor/pointer-binding.d.ts.map +1 -0
  143. package/dist/editor/pointer-binding.js +1087 -0
  144. package/dist/editor/pointer-binding.js.map +1 -0
  145. package/dist/editor/public/annotations.d.ts +54 -0
  146. package/dist/editor/public/annotations.d.ts.map +1 -0
  147. package/dist/editor/public/annotations.js +106 -0
  148. package/dist/editor/public/annotations.js.map +1 -0
  149. package/dist/editor/public/arrange-group.d.ts +81 -0
  150. package/dist/editor/public/arrange-group.d.ts.map +1 -0
  151. package/dist/editor/public/arrange-group.js +193 -0
  152. package/dist/editor/public/arrange-group.js.map +1 -0
  153. package/dist/editor/public/brush.d.ts +33 -0
  154. package/dist/editor/public/brush.d.ts.map +1 -0
  155. package/dist/editor/public/brush.js +54 -0
  156. package/dist/editor/public/brush.js.map +1 -0
  157. package/dist/editor/public/clipboard.d.ts +31 -0
  158. package/dist/editor/public/clipboard.d.ts.map +1 -0
  159. package/dist/editor/public/clipboard.js +35 -0
  160. package/dist/editor/public/clipboard.js.map +1 -0
  161. package/dist/editor/public/image-insert.d.ts +30 -0
  162. package/dist/editor/public/image-insert.d.ts.map +1 -0
  163. package/dist/editor/public/image-insert.js +57 -0
  164. package/dist/editor/public/image-insert.js.map +1 -0
  165. package/dist/editor/public/layers.d.ts +56 -0
  166. package/dist/editor/public/layers.d.ts.map +1 -0
  167. package/dist/editor/public/layers.js +104 -0
  168. package/dist/editor/public/layers.js.map +1 -0
  169. package/dist/editor/public/link.d.ts +25 -0
  170. package/dist/editor/public/link.d.ts.map +1 -0
  171. package/dist/editor/public/link.js +74 -0
  172. package/dist/editor/public/link.js.map +1 -0
  173. package/dist/editor/public/placement.d.ts +60 -0
  174. package/dist/editor/public/placement.d.ts.map +1 -0
  175. package/dist/editor/public/placement.js +111 -0
  176. package/dist/editor/public/placement.js.map +1 -0
  177. package/dist/editor/public/selection-ops.d.ts +78 -0
  178. package/dist/editor/public/selection-ops.d.ts.map +1 -0
  179. package/dist/editor/public/selection-ops.js +226 -0
  180. package/dist/editor/public/selection-ops.js.map +1 -0
  181. package/dist/editor/public/text-edit.d.ts +17 -0
  182. package/dist/editor/public/text-edit.d.ts.map +1 -0
  183. package/dist/editor/public/text-edit.js +28 -0
  184. package/dist/editor/public/text-edit.js.map +1 -0
  185. package/dist/editor/public/z-order.d.ts +47 -0
  186. package/dist/editor/public/z-order.d.ts.map +1 -0
  187. package/dist/editor/public/z-order.js +151 -0
  188. package/dist/editor/public/z-order.js.map +1 -0
  189. package/dist/editor/public/zoom-pan.d.ts +44 -0
  190. package/dist/editor/public/zoom-pan.d.ts.map +1 -0
  191. package/dist/editor/public/zoom-pan.js +116 -0
  192. package/dist/editor/public/zoom-pan.js.map +1 -0
  193. package/dist/editor/render-orchestrator.d.ts +11 -0
  194. package/dist/editor/render-orchestrator.d.ts.map +1 -0
  195. package/dist/editor/render-orchestrator.js +473 -0
  196. package/dist/editor/render-orchestrator.js.map +1 -0
  197. package/dist/editor/resize-helpers.d.ts +30 -0
  198. package/dist/editor/resize-helpers.d.ts.map +1 -0
  199. package/dist/editor/resize-helpers.js +121 -0
  200. package/dist/editor/resize-helpers.js.map +1 -0
  201. package/dist/editor/shape-filters.d.ts +11 -0
  202. package/dist/editor/shape-filters.d.ts.map +1 -0
  203. package/dist/editor/shape-filters.js +19 -0
  204. package/dist/editor/shape-filters.js.map +1 -0
  205. package/dist/editor/shape-traits.d.ts +16 -0
  206. package/dist/editor/shape-traits.d.ts.map +1 -0
  207. package/dist/editor/shape-traits.js +29 -0
  208. package/dist/editor/shape-traits.js.map +1 -0
  209. package/dist/editor/viewport-helpers.d.ts +24 -0
  210. package/dist/editor/viewport-helpers.d.ts.map +1 -0
  211. package/dist/editor/viewport-helpers.js +63 -0
  212. package/dist/editor/viewport-helpers.js.map +1 -0
  213. package/dist/editor-events.d.ts +33 -0
  214. package/dist/editor-events.d.ts.map +1 -0
  215. package/dist/editor-events.js +2 -0
  216. package/dist/editor-events.js.map +1 -0
  217. package/dist/editor.d.ts +1841 -0
  218. package/dist/editor.d.ts.map +1 -0
  219. package/dist/editor.js +4803 -0
  220. package/dist/editor.js.map +1 -0
  221. package/dist/file-drop.d.ts +99 -0
  222. package/dist/file-drop.d.ts.map +1 -0
  223. package/dist/file-drop.js +198 -0
  224. package/dist/file-drop.js.map +1 -0
  225. package/dist/frame-helpers.d.ts +30 -0
  226. package/dist/frame-helpers.d.ts.map +1 -0
  227. package/dist/frame-helpers.js +105 -0
  228. package/dist/frame-helpers.js.map +1 -0
  229. package/dist/group-helpers.d.ts +39 -0
  230. package/dist/group-helpers.d.ts.map +1 -0
  231. package/dist/group-helpers.js +116 -0
  232. package/dist/group-helpers.js.map +1 -0
  233. package/dist/handle.d.ts +73 -0
  234. package/dist/handle.d.ts.map +1 -0
  235. package/dist/handle.js +184 -0
  236. package/dist/handle.js.map +1 -0
  237. package/dist/index.d.ts +26 -0
  238. package/dist/index.d.ts.map +1 -0
  239. package/dist/index.js +16 -0
  240. package/dist/index.js.map +1 -0
  241. package/dist/interactive.d.ts +21 -0
  242. package/dist/interactive.d.ts.map +1 -0
  243. package/dist/interactive.js +11 -0
  244. package/dist/interactive.js.map +1 -0
  245. package/dist/link-selection.d.ts +21 -0
  246. package/dist/link-selection.d.ts.map +1 -0
  247. package/dist/link-selection.js +37 -0
  248. package/dist/link-selection.js.map +1 -0
  249. package/dist/machine.d.ts +322 -0
  250. package/dist/machine.d.ts.map +1 -0
  251. package/dist/machine.js +568 -0
  252. package/dist/machine.js.map +1 -0
  253. package/dist/modes.d.ts +24 -0
  254. package/dist/modes.d.ts.map +1 -0
  255. package/dist/modes.js +2 -0
  256. package/dist/modes.js.map +1 -0
  257. package/dist/overlay.d.ts +262 -0
  258. package/dist/overlay.d.ts.map +1 -0
  259. package/dist/overlay.js +673 -0
  260. package/dist/overlay.js.map +1 -0
  261. package/dist/platform.d.ts +70 -0
  262. package/dist/platform.d.ts.map +1 -0
  263. package/dist/platform.js +115 -0
  264. package/dist/platform.js.map +1 -0
  265. package/dist/selection.d.ts +18 -0
  266. package/dist/selection.d.ts.map +1 -0
  267. package/dist/selection.js +31 -0
  268. package/dist/selection.js.map +1 -0
  269. package/package.json +59 -0
@@ -0,0 +1,28 @@
1
+ import { getAnchorWorld, geometryDefaultAnchorsLocal, getAnchorOutwardNormal, snapExcludedAnchors, } from "@oh-just-another/scene";
2
+ /**
3
+ * World-space positions of an element's default connection-anchor dots,
4
+ * each pushed `outsetWorld` units out along its outward normal (floating
5
+ * ports). Excluded anchors (per `snapExcludedAnchors`) are dropped.
6
+ *
7
+ * Shared by the render overlay (which draws the dots) and the pointer
8
+ * hit-test (which detects a press on a link-start dot to begin a link
9
+ * drag) so the two stay 1:1 — a drawn dot is always grabbable at exactly
10
+ * the pixel it appears. The free outline-attach point is NOT produced
11
+ * here; callers append it separately because it is the real landing
12
+ * point and is never offset.
13
+ */
14
+ export const anchorOverlayPoints = (shape, outsetWorld) => {
15
+ const excluded = snapExcludedAnchors(shape);
16
+ const allLocal = geometryDefaultAnchorsLocal(shape);
17
+ const names = [...allLocal.keys()].filter((n) => !excluded.has(n));
18
+ const worldPoints = names.map((name) => {
19
+ const ref = { kind: "named", name };
20
+ const p = getAnchorWorld(shape, ref);
21
+ if (outsetWorld === 0)
22
+ return p;
23
+ const n = getAnchorOutwardNormal(shape, ref);
24
+ return { x: p.x + n.x * outsetWorld, y: p.y + n.y * outsetWorld };
25
+ });
26
+ return { names, worldPoints };
27
+ };
28
+ //# sourceMappingURL=anchor-points.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchor-points.js","sourceRoot":"","sources":["../../src/editor/anchor-points.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,2BAA2B,EAC3B,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,wBAAwB,CAAC;AAUhC;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,KAAwD,EACxD,WAAmB,EACE,EAAE;IACvB,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACrC,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAW,CAAC;QAC7C,MAAM,CAAC,GAAG,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACrC,IAAI,WAAW,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAChC,MAAM,CAAC,GAAG,sBAAsB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC7C,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,WAAW,EAAE,CAAC;IACpE,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;AAChC,CAAC,CAAC"}
@@ -0,0 +1,60 @@
1
+ import { type Link, type LinkEndpoint, type Scene, type Element, type Patch } from "@oh-just-another/scene";
2
+ import type { Bounds, LinkId, LayerId, ElementId, Vec2 } from "@oh-just-another/types";
3
+ /**
4
+ * Build the `Element` object for a CREATE_SHAPE emit. Doesn't touch the
5
+ * scene — caller threads it through `addElement`.
6
+ *
7
+ * Frames go to the bottom of their layer so the children inside
8
+ * them still receive clicks; rect / ellipse go to the top of the
9
+ * stack as usual.
10
+ */
11
+ export declare const buildElementForCreate: (scene: Scene, kind: "rect" | "ellipse" | "frame", bounds: Bounds, id: ElementId, layerId: LayerId, nextFrameName: () => string) => Element;
12
+ /**
13
+ * Build the `Link` object for a CREATE_EDGE emit. Endpoints are
14
+ * pre-resolved (snapped) by the caller — we just compose them with the
15
+ * layer / order / style boilerplate.
16
+ */
17
+ export declare const buildLinkForCreate: (scene: Scene, from: LinkEndpoint, to: LinkEndpoint, id: LinkId, layerId: LayerId) => Link;
18
+ /**
19
+ * Build the throwaway `Link` for the live draw-edge connector preview.
20
+ * Same default object as {@link buildLinkForCreate} (so the dragged preview is
21
+ * a WYSIWYG of the committed link — solid, default arrowhead, default style),
22
+ * with point endpoints at the preview's resolved ends. When the caller already
23
+ * routed the polyline (`points` = `[from, ...corners, to]`), its interior
24
+ * corners are reused as `routedPoints` so the elbow geometry matches exactly.
25
+ */
26
+ export declare const buildEdgePreviewLink: (scene: Scene, preview: {
27
+ readonly from: Vec2;
28
+ readonly to: Vec2;
29
+ readonly points?: readonly Vec2[];
30
+ }, id: LinkId, layerId: LayerId) => Link;
31
+ /**
32
+ * Composite helper for `applyCreate` — builds the shape and runs
33
+ * `addElement` against the scene. Returns the scene + patch so the
34
+ * Editor can `_history.push(patch)` and clear/notify.
35
+ *
36
+ * `void bounds` — the bounds is part of the shape via `position` +
37
+ * `width` / `height`; the parameter is kept on the signature only
38
+ * to document intent at the call site.
39
+ */
40
+ export declare const computeCreateElement: (scene: Scene, kind: "rect" | "ellipse" | "frame", bounds: Bounds, id: ElementId, layerId: LayerId, nextFrameName: () => string) => {
41
+ readonly scene: Scene;
42
+ readonly patch: Patch;
43
+ readonly elementId: ElementId;
44
+ };
45
+ /**
46
+ * Composite helper for `applyCreateLink` — combines `buildLink` and
47
+ * `addLink`. Endpoint snapping is caller responsibility (delegated
48
+ * to the snap engine in Editor); pre-resolved `from`/`to` are
49
+ * threaded in as parameters.
50
+ */
51
+ export declare const computeCreateLink: (scene: Scene, from: LinkEndpoint, to: LinkEndpoint, id: LinkId, layerId: LayerId) => {
52
+ readonly scene: Scene;
53
+ readonly patch: Patch;
54
+ readonly linkId: LinkId;
55
+ };
56
+ /** Generate a unique shape id with the per-editor `nextId` counter. */
57
+ export declare const newElementId: (next: number) => ElementId;
58
+ /** Generate a unique edge id with the per-editor `nextId` counter. */
59
+ export declare const newLinkId: (next: number) => LinkId;
60
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/editor/applies/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,IAAI,EACT,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,KAAK,OAAO,EACZ,KAAK,KAAK,EACX,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EACV,MAAM,EACN,MAAM,EACN,OAAO,EACP,SAAS,EACT,IAAI,EACL,MAAM,wBAAwB,CAAC;AAWhC;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,GAChC,OAAO,KAAK,EACZ,MAAM,MAAM,GAAG,SAAS,GAAG,OAAO,EAClC,QAAQ,MAAM,EACd,IAAI,SAAS,EACb,SAAS,OAAO,EAChB,eAAe,MAAM,MAAM,KAC1B,OAwBF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAC7B,OAAO,KAAK,EACZ,MAAM,YAAY,EAClB,IAAI,YAAY,EAChB,IAAI,MAAM,EACV,SAAS,OAAO,KACf,IAgBF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAC/B,OAAO,KAAK,EACZ,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,IAAI,EAAE,CAAA;CAAE,EACtF,IAAI,MAAM,EACV,SAAS,OAAO,KACf,IAWF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,GAC/B,OAAO,KAAK,EACZ,MAAM,MAAM,GAAG,SAAS,GAAG,OAAO,EAClC,QAAQ,MAAM,EACd,IAAI,SAAS,EACb,SAAS,OAAO,EAChB,eAAe,MAAM,MAAM,KAC1B;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;CAI/E,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAC5B,OAAO,KAAK,EACZ,MAAM,YAAY,EAClB,IAAI,YAAY,EAChB,IAAI,MAAM,EACV,SAAS,OAAO,KACf;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAIzE,CAAC;AAEF,uEAAuE;AACvE,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,KAAG,SACa,CAAC;AAE1D,sEAAsE;AACtE,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,KAAG,MACY,CAAC"}
@@ -0,0 +1,107 @@
1
+ import { addLink, addElement, orderForBottom, orderForTop, } from "@oh-just-another/scene";
2
+ import { DEFAULT_EDGE_STYLE, DEFAULT_ELEMENT_STYLES } from "@oh-just-another/tokens";
3
+ import { DEFAULT_LINK_ARROWHEAD, DEFAULT_LINK_ROUTING, FRAME_DEFAULT_FILL } from "../../constants.js";
4
+ /**
5
+ * Defaults used by `buildElementForCreate` — sourced from
6
+ * `@oh-just-another/tokens` so the editor and the templates package
7
+ * agree on a fresh shape's look.
8
+ */
9
+ const DEFAULT_RECT_STYLE = DEFAULT_ELEMENT_STYLES.rectangle;
10
+ const DEFAULT_ELLIPSE_STYLE = DEFAULT_ELEMENT_STYLES.ellipse;
11
+ /**
12
+ * Build the `Element` object for a CREATE_SHAPE emit. Doesn't touch the
13
+ * scene — caller threads it through `addElement`.
14
+ *
15
+ * Frames go to the bottom of their layer so the children inside
16
+ * them still receive clicks; rect / ellipse go to the top of the
17
+ * stack as usual.
18
+ */
19
+ export const buildElementForCreate = (scene, kind, bounds, id, layerId, nextFrameName) => {
20
+ const orders = Array.from(scene.elements.values())
21
+ .filter((s) => s.layerId === layerId)
22
+ .map((s) => s.order);
23
+ const order = kind === "frame" ? orderForBottom(orders) : orderForTop(orders);
24
+ const common = {
25
+ id,
26
+ layerId,
27
+ position: { x: bounds.x, y: bounds.y },
28
+ rotation: 0,
29
+ scale: { x: 1, y: 1 },
30
+ order,
31
+ width: bounds.width,
32
+ height: bounds.height,
33
+ };
34
+ if (kind === "rect") {
35
+ return { ...common, type: "rectangle", style: { ...DEFAULT_RECT_STYLE } };
36
+ }
37
+ if (kind === "ellipse") {
38
+ return { ...common, type: "ellipse", style: { ...DEFAULT_ELLIPSE_STYLE } };
39
+ }
40
+ // Frame: white body fill (configurable from the panel; border is fixed
41
+ // chrome). Auto-numbered name.
42
+ return { ...common, type: "frame", style: { fill: FRAME_DEFAULT_FILL }, name: nextFrameName() };
43
+ };
44
+ /**
45
+ * Build the `Link` object for a CREATE_EDGE emit. Endpoints are
46
+ * pre-resolved (snapped) by the caller — we just compose them with the
47
+ * layer / order / style boilerplate.
48
+ */
49
+ export const buildLinkForCreate = (scene, from, to, id, layerId) => {
50
+ const order = orderForTop(Array.from(scene.links.values())
51
+ .filter((e) => e.layerId === layerId)
52
+ .map((e) => e.order));
53
+ return {
54
+ id,
55
+ layerId,
56
+ from,
57
+ to,
58
+ order,
59
+ routing: DEFAULT_LINK_ROUTING,
60
+ style: { ...DEFAULT_EDGE_STYLE },
61
+ arrowheads: { to: DEFAULT_LINK_ARROWHEAD },
62
+ };
63
+ };
64
+ /**
65
+ * Build the throwaway `Link` for the live draw-edge connector preview.
66
+ * Same default object as {@link buildLinkForCreate} (so the dragged preview is
67
+ * a WYSIWYG of the committed link — solid, default arrowhead, default style),
68
+ * with point endpoints at the preview's resolved ends. When the caller already
69
+ * routed the polyline (`points` = `[from, ...corners, to]`), its interior
70
+ * corners are reused as `routedPoints` so the elbow geometry matches exactly.
71
+ */
72
+ export const buildEdgePreviewLink = (scene, preview, id, layerId) => {
73
+ const base = buildLinkForCreate(scene, { kind: "point", position: preview.from }, { kind: "point", position: preview.to }, id, layerId);
74
+ return preview.points && preview.points.length > 2
75
+ ? { ...base, routedPoints: preview.points.slice(1, -1) }
76
+ : base;
77
+ };
78
+ /**
79
+ * Composite helper for `applyCreate` — builds the shape and runs
80
+ * `addElement` against the scene. Returns the scene + patch so the
81
+ * Editor can `_history.push(patch)` and clear/notify.
82
+ *
83
+ * `void bounds` — the bounds is part of the shape via `position` +
84
+ * `width` / `height`; the parameter is kept on the signature only
85
+ * to document intent at the call site.
86
+ */
87
+ export const computeCreateElement = (scene, kind, bounds, id, layerId, nextFrameName) => {
88
+ const shape = buildElementForCreate(scene, kind, bounds, id, layerId, nextFrameName);
89
+ const result = addElement(scene, shape);
90
+ return { scene: result.scene, patch: result.patch, elementId: id };
91
+ };
92
+ /**
93
+ * Composite helper for `applyCreateLink` — combines `buildLink` and
94
+ * `addLink`. Endpoint snapping is caller responsibility (delegated
95
+ * to the snap engine in Editor); pre-resolved `from`/`to` are
96
+ * threaded in as parameters.
97
+ */
98
+ export const computeCreateLink = (scene, from, to, id, layerId) => {
99
+ const edge = buildLinkForCreate(scene, from, to, id, layerId);
100
+ const result = addLink(scene, edge);
101
+ return { scene: result.scene, patch: result.patch, linkId: id };
102
+ };
103
+ /** Generate a unique shape id with the per-editor `nextId` counter. */
104
+ export const newElementId = (next) => `shape-${next}-${Date.now().toString(36)}`;
105
+ /** Generate a unique edge id with the per-editor `nextId` counter. */
106
+ export const newLinkId = (next) => `edge-${next}-${Date.now().toString(36)}`;
107
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/editor/applies/create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import { type LinkEndpoint, type Scene, type Patch } from "@oh-just-another/scene";
2
+ import type { ElementId, Vec2 } from "@oh-just-another/types";
3
+ import type { LinkId } from "@oh-just-another/types";
4
+ import type { InteractionEmit } from "../../machine.js";
5
+ /**
6
+ * Compute the visible (snapped) endpoints for an in-progress
7
+ * draw-edge preview. Both ends snap to the nearest anchor on
8
+ * the press-target / hovered shape; if no shape is involved the
9
+ * raw world point is used.
10
+ *
11
+ * Pure — caller (Editor) writes the result to `edgePreview` and
12
+ * fires notify.
13
+ */
14
+ export declare const computeLinkPreviewEndpoints: (scene: Scene, fromElement: ElementId | null, fromPoint: Vec2, toPoint: Vec2) => {
15
+ readonly from: Vec2;
16
+ readonly to: Vec2;
17
+ };
18
+ /**
19
+ * Compute the scene + patch resulting from an UPDATE_EDGE_ENDPOINT
20
+ * emit. Returns `null` when the edge no longer exists (cleared in
21
+ * a parallel undo, etc.); caller treats `null` as "no-op, just
22
+ * clear the drag state". Endpoint snapping is delegated to a
23
+ * callback so this module doesn't pull in the snap engine.
24
+ */
25
+ export declare const computeLinkEndpointUpdate: (scene: Scene, emit: Extract<InteractionEmit, {
26
+ type: "UPDATE_EDGE_ENDPOINT";
27
+ }>, snap: (toElement: ElementId | null, toPoint: Vec2) => LinkEndpoint) => {
28
+ readonly scene: Scene;
29
+ readonly patch: Patch;
30
+ readonly linkId: LinkId;
31
+ } | null;
32
+ //# sourceMappingURL=edge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge.d.ts","sourceRoot":"","sources":["../../../src/editor/applies/edge.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,KAAK,KAAK,EACX,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,GACtC,OAAO,KAAK,EACZ,aAAa,SAAS,GAAG,IAAI,EAC7B,WAAW,IAAI,EACf,SAAS,IAAI,KACZ;IAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAA;CAc1C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,GACpC,OAAO,KAAK,EACZ,MAAM,OAAO,CAAC,eAAe,EAAE;IAAE,IAAI,EAAE,sBAAsB,CAAA;CAAE,CAAC,EAChE,MAAM,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,EAAE,OAAO,EAAE,IAAI,KAAK,YAAY,KACjE;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAS9E,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { findNearestAnchor, getLink, getElement, getElementAt, snapExcludedAnchors, updateLink, } from "@oh-just-another/scene";
2
+ /**
3
+ * Compute the visible (snapped) endpoints for an in-progress
4
+ * draw-edge preview. Both ends snap to the nearest anchor on
5
+ * the press-target / hovered shape; if no shape is involved the
6
+ * raw world point is used.
7
+ *
8
+ * Pure — caller (Editor) writes the result to `edgePreview` and
9
+ * fires notify.
10
+ */
11
+ export const computeLinkPreviewEndpoints = (scene, fromElement, fromPoint, toPoint) => {
12
+ let from = fromPoint;
13
+ if (fromElement) {
14
+ const shape = getElement(scene, fromElement);
15
+ if (shape) {
16
+ from = findNearestAnchor(shape, fromPoint, snapExcludedAnchors(shape)).world;
17
+ }
18
+ }
19
+ let to = toPoint;
20
+ const hovered = getElementAt(scene, toPoint);
21
+ if (hovered) {
22
+ to = findNearestAnchor(hovered, toPoint, snapExcludedAnchors(hovered)).world;
23
+ }
24
+ return { from, to };
25
+ };
26
+ /**
27
+ * Compute the scene + patch resulting from an UPDATE_EDGE_ENDPOINT
28
+ * emit. Returns `null` when the edge no longer exists (cleared in
29
+ * a parallel undo, etc.); caller treats `null` as "no-op, just
30
+ * clear the drag state". Endpoint snapping is delegated to a
31
+ * callback so this module doesn't pull in the snap engine.
32
+ */
33
+ export const computeLinkEndpointUpdate = (scene, emit, snap) => {
34
+ const edge = getLink(scene, emit.linkId);
35
+ if (!edge)
36
+ return null;
37
+ const newEndpoint = snap(emit.toElement, emit.toPoint);
38
+ const result = updateLink(scene, edge.id, (e) => ({
39
+ ...e,
40
+ [emit.side]: newEndpoint,
41
+ }));
42
+ return { scene: result.scene, patch: result.patch, linkId: edge.id };
43
+ };
44
+ //# sourceMappingURL=edge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge.js","sourceRoot":"","sources":["../../../src/editor/applies/edge.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,OAAO,EACP,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,UAAU,GAIX,MAAM,wBAAwB,CAAC;AAKhC;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CACzC,KAAY,EACZ,WAA6B,EAC7B,SAAe,EACf,OAAa,EAC+B,EAAE;IAC9C,IAAI,IAAI,GAAG,SAAS,CAAC;IACrB,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAC7C,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,GAAG,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;QAC/E,CAAC;IACH,CAAC;IACD,IAAI,EAAE,GAAG,OAAO,CAAC;IACjB,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC7C,IAAI,OAAO,EAAE,CAAC;QACZ,EAAE,GAAG,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IAC/E,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AACtB,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACvC,KAAY,EACZ,IAAgE,EAChE,IAAkE,EACgB,EAAE;IACpF,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAChD,GAAG,CAAC;QACJ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,WAAW;KACzB,CAAC,CAAC,CAAC;IACJ,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;AACvE,CAAC,CAAC"}
@@ -0,0 +1,53 @@
1
+ import { type Scene, type Link, type Patch } from "@oh-just-another/scene";
2
+ import type { ElementId, LinkId, Vec2 } from "@oh-just-another/types";
3
+ /** Both endpoints bound to elements being moved → the link moves rigidly. */
4
+ export declare const linkMovesRigidly: (link: Link, moved: ReadonlySet<ElementId>) => boolean;
5
+ /**
6
+ * Return only the geometry fields shifted by `delta`, or `null` when the
7
+ * link carries no movable geometry. `fixedSegments` store a segment's
8
+ * perpendicular coordinate (`pos`) and its centre along its own axis
9
+ * (`at`): an `"h"` (horizontal) segment's `pos` is a Y and `at` is an X;
10
+ * a `"v"` segment is the reverse. Both shift so the segment re-identifies
11
+ * after the route re-flows.
12
+ */
13
+ export declare const translateLinkGeometry: (link: Link, delta: Vec2) => Pick<Link, "waypoints" | "fixedSegments" | "routedPoints"> | null;
14
+ /**
15
+ * Translate a link for a DRAG: its geometry (waypoints / fixedSegments /
16
+ * routedPoints) PLUS any free `point` endpoints, by `delta`. Bound
17
+ * endpoints (anchor / outline / floating) are left alone — they re-resolve
18
+ * from their (also-moving) elements. Returns the changed fields, or `null`
19
+ * when there's nothing to move (a pure auto-routed bound link).
20
+ */
21
+ export declare const translateLinkForDrag: (link: Link, delta: Vec2) => Partial<Link> | null;
22
+ /**
23
+ * Scale a link for a GROUP RESIZE: its geometry (waypoints / fixedSegments /
24
+ * routedPoints) and any free `point` endpoints scale about the anchor
25
+ * `(ax, ay)` by `(sx, sy)` — the same transform the resized elements undergo,
26
+ * so the connector stretches with the box in both size and coordinates. Bound
27
+ * endpoints are left alone (they re-resolve from their own scaled elements).
28
+ * `null` when there's nothing to scale.
29
+ */
30
+ export declare const scaleLinkAround: (link: Link, ax: number, ay: number, sx: number, sy: number) => Partial<Link> | null;
31
+ /**
32
+ * Snapshot links that follow a drag: every SELECTED link (translated whole,
33
+ * incl. free point endpoints) plus links bound on both ends to `moved`
34
+ * elements (geometry-only — their endpoints already follow). Captured at
35
+ * press time so each frame translates from the ORIGINAL, never compounding.
36
+ */
37
+ export declare const snapshotMovingLinks: (scene: Scene, moved: ReadonlySet<ElementId>, selected: ReadonlySet<LinkId>) => Map<LinkId, Link>;
38
+ /**
39
+ * Per-frame drag patches: translate each snapshot link to `origin + delta`.
40
+ * `before` is the live link so the patch chain composes frame to frame.
41
+ */
42
+ export declare const computeMovingLinkPatches: (scene: Scene, originLinks: ReadonlyMap<LinkId, Link>, delta: Vec2) => Patch[];
43
+ /**
44
+ * One-shot translation for committed moves (keyboard nudge): translate every
45
+ * moving link's CURRENT geometry + free endpoints by `delta`, threading the
46
+ * scene so patches stack in one transaction. No snapshot needed — each nudge
47
+ * is a discrete committed step.
48
+ */
49
+ export declare const computeMovingLinkForNudge: (scene: Scene, moved: ReadonlySet<ElementId>, selected: ReadonlySet<LinkId>, delta: Vec2) => {
50
+ readonly scene: Scene;
51
+ readonly patches: Patch[];
52
+ };
53
+ //# sourceMappingURL=link-move.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link-move.d.ts","sourceRoot":"","sources":["../../../src/editor/applies/link-move.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,KAAK,EAAE,KAAK,IAAI,EAAE,KAAK,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAChG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAoBtE,6EAA6E;AAC7E,eAAO,MAAM,gBAAgB,GAAI,MAAM,IAAI,EAAE,OAAO,WAAW,CAAC,SAAS,CAAC,KAAG,OACX,CAAC;AAWnE;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,GAChC,MAAM,IAAI,EACV,OAAO,IAAI,KACV,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,eAAe,GAAG,cAAc,CAAC,GAAG,IAiB/D,CAAC;AAMF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAC/B,MAAM,IAAI,EACV,OAAO,IAAI,KACV,OAAO,CAAC,IAAI,CAAC,GAAG,IASlB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAC1B,MAAM,IAAI,EACV,IAAI,MAAM,EACV,IAAI,MAAM,EACV,IAAI,MAAM,EACV,IAAI,MAAM,KACT,OAAO,CAAC,IAAI,CAAC,GAAG,IAoBlB,CAAC;AASF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAC9B,OAAO,KAAK,EACZ,OAAO,WAAW,CAAC,SAAS,CAAC,EAC7B,UAAU,WAAW,CAAC,MAAM,CAAC,KAC5B,GAAG,CAAC,MAAM,EAAE,IAAI,CAQlB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,GACnC,OAAO,KAAK,EACZ,aAAa,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,EACtC,OAAO,IAAI,KACV,KAAK,EAUP,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GACpC,OAAO,KAAK,EACZ,OAAO,WAAW,CAAC,SAAS,CAAC,EAC7B,UAAU,WAAW,CAAC,MAAM,CAAC,EAC7B,OAAO,IAAI,KACV;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,CAAA;CAYpD,CAAC"}
@@ -0,0 +1,160 @@
1
+ import { getLink, updateLink } from "@oh-just-another/scene";
2
+ /**
3
+ * Rigid connector move.
4
+ *
5
+ * A link whose BOTH endpoints are bound to elements inside the moved
6
+ * selection translates as a rigid body — its stored ABSOLUTE geometry
7
+ * (user waypoints / pinned elbow segments / routed corners) shifts by
8
+ * the same delta as the elements, so the fixed middle moves with the
9
+ * endpoints rather than staying put.
10
+ *
11
+ * Pure-routed links (no waypoints / fixedSegments / routedPoints) need
12
+ * nothing here — their endpoints already re-resolve from the moved
13
+ * elements' bounds every frame.
14
+ */
15
+ /** An endpoint follows the move iff it's bound to an element in `moved`. */
16
+ const endpointInSet = (ep, moved) => ep.kind !== "point" && moved.has(ep.elementId);
17
+ /** Both endpoints bound to elements being moved → the link moves rigidly. */
18
+ export const linkMovesRigidly = (link, moved) => endpointInSet(link.from, moved) && endpointInSet(link.to, moved);
19
+ /** Stored absolute geometry that wouldn't otherwise translate on a move. */
20
+ const hasMovableGeometry = (link) => (link.waypoints?.length ?? 0) > 0 ||
21
+ (link.fixedSegments?.length ?? 0) > 0 ||
22
+ (link.routedPoints?.length ?? 0) > 0;
23
+ const shiftPts = (pts, d) => pts.map((p) => ({ x: p.x + d.x, y: p.y + d.y }));
24
+ /**
25
+ * Return only the geometry fields shifted by `delta`, or `null` when the
26
+ * link carries no movable geometry. `fixedSegments` store a segment's
27
+ * perpendicular coordinate (`pos`) and its centre along its own axis
28
+ * (`at`): an `"h"` (horizontal) segment's `pos` is a Y and `at` is an X;
29
+ * a `"v"` segment is the reverse. Both shift so the segment re-identifies
30
+ * after the route re-flows.
31
+ */
32
+ export const translateLinkGeometry = (link, delta) => {
33
+ if (!hasMovableGeometry(link))
34
+ return null;
35
+ const out = {};
36
+ if (link.waypoints?.length)
37
+ out.waypoints = shiftPts(link.waypoints, delta);
38
+ if (link.fixedSegments?.length) {
39
+ out.fixedSegments = link.fixedSegments.map((s) => ({
40
+ axis: s.axis,
41
+ pos: s.pos + (s.axis === "h" ? delta.y : delta.x),
42
+ at: s.at + (s.axis === "h" ? delta.x : delta.y),
43
+ }));
44
+ }
45
+ if (link.routedPoints?.length)
46
+ out.routedPoints = shiftPts(link.routedPoints, delta);
47
+ return out;
48
+ };
49
+ /** A `point` endpoint shifted by `delta`; bound endpoints pass through. */
50
+ const shiftEndpoint = (ep, delta) => ep.kind === "point" ? { kind: "point", position: { x: ep.position.x + delta.x, y: ep.position.y + delta.y } } : ep;
51
+ /**
52
+ * Translate a link for a DRAG: its geometry (waypoints / fixedSegments /
53
+ * routedPoints) PLUS any free `point` endpoints, by `delta`. Bound
54
+ * endpoints (anchor / outline / floating) are left alone — they re-resolve
55
+ * from their (also-moving) elements. Returns the changed fields, or `null`
56
+ * when there's nothing to move (a pure auto-routed bound link).
57
+ */
58
+ export const translateLinkForDrag = (link, delta) => {
59
+ const geom = translateLinkGeometry(link, delta);
60
+ const fromMoves = link.from.kind === "point";
61
+ const toMoves = link.to.kind === "point";
62
+ if (!geom && !fromMoves && !toMoves)
63
+ return null;
64
+ const out = { ...(geom ?? {}) };
65
+ if (fromMoves)
66
+ out.from = shiftEndpoint(link.from, delta);
67
+ if (toMoves)
68
+ out.to = shiftEndpoint(link.to, delta);
69
+ return out;
70
+ };
71
+ /**
72
+ * Scale a link for a GROUP RESIZE: its geometry (waypoints / fixedSegments /
73
+ * routedPoints) and any free `point` endpoints scale about the anchor
74
+ * `(ax, ay)` by `(sx, sy)` — the same transform the resized elements undergo,
75
+ * so the connector stretches with the box in both size and coordinates. Bound
76
+ * endpoints are left alone (they re-resolve from their own scaled elements).
77
+ * `null` when there's nothing to scale.
78
+ */
79
+ export const scaleLinkAround = (link, ax, ay, sx, sy) => {
80
+ const sp = (p) => ({ x: ax + (p.x - ax) * sx, y: ay + (p.y - ay) * sy });
81
+ const fromMoves = link.from.kind === "point";
82
+ const toMoves = link.to.kind === "point";
83
+ if (!hasMovableGeometry(link) && !fromMoves && !toMoves)
84
+ return null;
85
+ const out = {};
86
+ if (link.waypoints?.length)
87
+ out.waypoints = link.waypoints.map(sp);
88
+ if (link.fixedSegments?.length) {
89
+ out.fixedSegments = link.fixedSegments.map((s) => ({
90
+ axis: s.axis,
91
+ // `pos` is the segment's perpendicular coord (h→Y, v→X), `at` its
92
+ // centre along its own axis (h→X, v→Y) — scale each on its own axis.
93
+ pos: s.axis === "h" ? ay + (s.pos - ay) * sy : ax + (s.pos - ax) * sx,
94
+ at: s.axis === "h" ? ax + (s.at - ax) * sx : ay + (s.at - ay) * sy,
95
+ }));
96
+ }
97
+ if (link.routedPoints?.length)
98
+ out.routedPoints = link.routedPoints.map(sp);
99
+ if (link.from.kind === "point")
100
+ out.from = { kind: "point", position: sp(link.from.position) };
101
+ if (link.to.kind === "point")
102
+ out.to = { kind: "point", position: sp(link.to.position) };
103
+ return out;
104
+ };
105
+ /** A link moves with a drag when it's selected OR rigidly bound to moved elements. */
106
+ const linkMovesWithDrag = (link, moved, selected) => selected.has(link.id) || linkMovesRigidly(link, moved);
107
+ /**
108
+ * Snapshot links that follow a drag: every SELECTED link (translated whole,
109
+ * incl. free point endpoints) plus links bound on both ends to `moved`
110
+ * elements (geometry-only — their endpoints already follow). Captured at
111
+ * press time so each frame translates from the ORIGINAL, never compounding.
112
+ */
113
+ export const snapshotMovingLinks = (scene, moved, selected) => {
114
+ const out = new Map();
115
+ for (const link of scene.links.values()) {
116
+ if (linkMovesWithDrag(link, moved, selected) && translateLinkForDrag(link, { x: 0, y: 0 }) !== null) {
117
+ out.set(link.id, link);
118
+ }
119
+ }
120
+ return out;
121
+ };
122
+ /**
123
+ * Per-frame drag patches: translate each snapshot link to `origin + delta`.
124
+ * `before` is the live link so the patch chain composes frame to frame.
125
+ */
126
+ export const computeMovingLinkPatches = (scene, originLinks, delta) => {
127
+ const out = [];
128
+ for (const [id, origin] of originLinks) {
129
+ const current = getLink(scene, id);
130
+ if (!current)
131
+ continue;
132
+ const translated = translateLinkForDrag(origin, delta);
133
+ if (!translated)
134
+ continue;
135
+ out.push({ kind: "link", id, before: current, after: { ...current, ...translated } });
136
+ }
137
+ return out;
138
+ };
139
+ /**
140
+ * One-shot translation for committed moves (keyboard nudge): translate every
141
+ * moving link's CURRENT geometry + free endpoints by `delta`, threading the
142
+ * scene so patches stack in one transaction. No snapshot needed — each nudge
143
+ * is a discrete committed step.
144
+ */
145
+ export const computeMovingLinkForNudge = (scene, moved, selected, delta) => {
146
+ let s = scene;
147
+ const patches = [];
148
+ for (const link of [...scene.links.values()]) {
149
+ if (!linkMovesWithDrag(link, moved, selected))
150
+ continue;
151
+ const translated = translateLinkForDrag(link, delta);
152
+ if (!translated)
153
+ continue;
154
+ const r = updateLink(s, link.id, (l) => ({ ...l, ...translated }));
155
+ s = r.scene;
156
+ patches.push(r.patch);
157
+ }
158
+ return { scene: s, patches };
159
+ };
160
+ //# sourceMappingURL=link-move.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link-move.js","sourceRoot":"","sources":["../../../src/editor/applies/link-move.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { type Scene, type Patch } from "@oh-just-another/scene";
2
+ import type { AnnotationId, Bounds, ElementId, Vec2 } from "@oh-just-another/types";
3
+ /**
4
+ * Pure: compute the patch that moves shape `id` by `delta` from
5
+ * the press-down state captured in `originalBounds`. Returns
6
+ * `null` when the shape no longer exists (deleted mid-drag, etc.).
7
+ *
8
+ * `originalBounds` is in world space at press time; `localBounds`
9
+ * (current) compensates for parent-rooted layouts where the shape's
10
+ * own position has already moved relative to its parent. The
11
+ * offset is added so the cursor stays at the press anchor through
12
+ * the drag.
13
+ *
14
+ * Editor's wrapper applies the patch, runs `recordGesturePatch`,
15
+ * and fires notify.
16
+ */
17
+ export declare const computeElementMovePatch: (scene: Scene, id: ElementId, delta: Vec2, originalBounds: Bounds) => Patch | null;
18
+ /**
19
+ * Pure: compute one patch per shape in the active group-drag
20
+ * snapshot. `delta` is the cumulative cursor displacement since
21
+ * press-down, so each shape lands at `origin + delta` every frame
22
+ * — no accumulator state inside the loop. Skips no-op moves
23
+ * (delta after rounding lands the shape back at its current pos).
24
+ */
25
+ export declare const computeGroupMovePatches: (scene: Scene, groupMoveOrigin: ReadonlyMap<ElementId, Vec2>, delta: Vec2) => Patch[];
26
+ /**
27
+ * Pure: compute the scene + patch resulting from an annotation
28
+ * drag. For shape-anchored annotations the stored position is the
29
+ * offset from the host shape's world position, so we translate
30
+ * the requested world target back into local space. Returns
31
+ * `null` when the annotation no longer exists or the move is a
32
+ * pixel-perfect no-op.
33
+ */
34
+ export declare const computeAnnotationMovePatch: (scene: Scene, id: AnnotationId, delta: Vec2, origin: Vec2) => {
35
+ readonly scene: Scene;
36
+ readonly patch: Patch;
37
+ } | null;
38
+ //# sourceMappingURL=move.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"move.d.ts","sourceRoot":"","sources":["../../../src/editor/applies/move.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,KAAK,EAEV,KAAK,KAAK,EACX,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EACV,YAAY,EACZ,MAAM,EACN,SAAS,EACT,IAAI,EACL,MAAM,wBAAwB,CAAC;AAEhC;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,uBAAuB,GAClC,OAAO,KAAK,EACZ,IAAI,SAAS,EACb,OAAO,IAAI,EACX,gBAAgB,MAAM,KACrB,KAAK,GAAG,IAcV,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,GAClC,OAAO,KAAK,EACZ,iBAAiB,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,EAC7C,OAAO,IAAI,KACV,KAAK,EAaP,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,GACrC,OAAO,KAAK,EACZ,IAAI,YAAY,EAChB,OAAO,IAAI,EACX,QAAQ,IAAI,KACX;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG,IAiBrD,CAAC"}