@heyramzi/ui 2.11.1 → 2.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) hide show
  1. package/dist/agents/helpers.js +38 -38
  2. package/dist/agents/page-state.js +49 -50
  3. package/dist/agents/vendor/color.js +146 -127
  4. package/dist/agents/vendor/draw.js +617 -508
  5. package/dist/agents/vendor/engine.js +698 -599
  6. package/dist/agents/vendor/mesh.js +653 -683
  7. package/dist/agents/vendor/plastic.js +3913 -3112
  8. package/dist/agents/vendor/presets.js +163 -164
  9. package/dist/agents/vendor/shapes.js +21 -20
  10. package/dist/agents/vendor/ticker.js +41 -42
  11. package/dist/agents/vendor/types.js +1 -0
  12. package/dist/agents/vendor/wear.js +1421 -1448
  13. package/dist/ai/confirmation/confirmation-context.svelte.js +6 -6
  14. package/dist/ai/confirmation/index.js +3 -1
  15. package/dist/ai/index.js +33 -0
  16. package/dist/ai/prompt-input/index.js +3 -1
  17. package/dist/ai/reasoning/index.js +3 -1
  18. package/dist/ai/reasoning/reasoning-context.svelte.js +6 -6
  19. package/dist/ai/suggestion/index.js +3 -1
  20. package/dist/ai/typing-dots/index.js +3 -1
  21. package/dist/animations/text-swap.js +24 -24
  22. package/dist/brand/index.js +54 -48
  23. package/dist/canvas/card/resize.js +5 -3
  24. package/dist/canvas/edges/edge-path.js +255 -242
  25. package/dist/canvas/editor/context-menu.js +39 -36
  26. package/dist/canvas/editor/dispatch.svelte.js +154 -151
  27. package/dist/canvas/editor/editor-context.js +7 -2
  28. package/dist/canvas/editor/editor-mode.js +1 -0
  29. package/dist/canvas/editor/frame.js +73 -76
  30. package/dist/canvas/editor/hand-context.js +5 -2
  31. package/dist/canvas/editor/history-core.js +163 -191
  32. package/dist/canvas/editor/keymap.js +95 -169
  33. package/dist/canvas/editor/layout-actions.js +143 -144
  34. package/dist/canvas/editor/lock.js +52 -51
  35. package/dist/canvas/editor/rebase.js +217 -240
  36. package/dist/canvas/editor/style.js +132 -137
  37. package/dist/canvas/editor/text-field-context.js +7 -2
  38. package/dist/canvas/editor/z-order.js +65 -70
  39. package/dist/canvas/headless/alignment.js +22 -16
  40. package/dist/canvas/headless/break-apart-find.js +286 -279
  41. package/dist/canvas/headless/break-apart-pieces.js +62 -58
  42. package/dist/canvas/headless/break-apart-plan.js +299 -325
  43. package/dist/canvas/headless/break-apart-style.js +75 -70
  44. package/dist/canvas/headless/break-apart.js +188 -181
  45. package/dist/canvas/headless/canvas-cleanup.js +78 -58
  46. package/dist/canvas/headless/edge-anchors.js +115 -116
  47. package/dist/canvas/headless/edge-memo.js +24 -22
  48. package/dist/canvas/headless/edge-serialization.js +17 -27
  49. package/dist/canvas/headless/figure-geometry.js +232 -264
  50. package/dist/canvas/headless/fit-viewport.js +84 -67
  51. package/dist/canvas/headless/grid.js +88 -86
  52. package/dist/canvas/headless/icon-node.js +44 -36
  53. package/dist/canvas/headless/index.js +1 -0
  54. package/dist/canvas/headless/linkify.js +17 -19
  55. package/dist/canvas/headless/pen-marks.js +101 -95
  56. package/dist/canvas/headless/sketch.js +231 -209
  57. package/dist/canvas/headless/snap-guides.js +99 -83
  58. package/dist/canvas/headless/svg-figure.js +133 -117
  59. package/dist/canvas/headless/table-layout.js +146 -107
  60. package/dist/canvas/index.js +2 -0
  61. package/dist/canvas/lod/lod-mode.svelte.js +20 -18
  62. package/dist/canvas/lod/render-all.svelte.js +36 -39
  63. package/dist/canvas/ops/arrange.js +78 -71
  64. package/dist/canvas/ops/ops.js +260 -255
  65. package/dist/canvas/pen/colors.js +37 -35
  66. package/dist/canvas/pen/eraser.js +28 -27
  67. package/dist/canvas/pen/geometry.js +120 -130
  68. package/dist/canvas/pen/index.js +1 -0
  69. package/dist/canvas/pen/ops.js +11 -11
  70. package/dist/canvas/pen/pen-session.js +150 -159
  71. package/dist/canvas/pen/plugin.js +107 -104
  72. package/dist/canvas/pen/shapes.js +73 -68
  73. package/dist/canvas/pen/stroke-path.js +32 -30
  74. package/dist/canvas/pen/types.js +21 -21
  75. package/dist/canvas/pen/ui.js +10 -8
  76. package/dist/canvas/plugin.js +46 -46
  77. package/dist/canvas/screen/glyphs.js +12 -11
  78. package/dist/canvas/screen/labels.js +22 -22
  79. package/dist/canvas/screen/parts.js +98 -111
  80. package/dist/canvas/screen/plugin.js +47 -56
  81. package/dist/canvas/screen/types.js +30 -35
  82. package/dist/canvas/screen/ui.js +7 -7
  83. package/dist/canvas/test-utils.js +14 -14
  84. package/dist/canvas/types.js +1 -0
  85. package/dist/canvas/ui/forward-wheel.js +24 -25
  86. package/dist/canvas/ui/icons.js +64 -131
  87. package/dist/canvas/ui/place-panel.js +58 -49
  88. package/dist/canvas/ui/shortcut-tip.js +14 -12
  89. package/dist/canvas/ui/tools.js +300 -385
  90. package/dist/charts/dashboard/chart.js +4 -0
  91. package/dist/charts/dashboard/data-table.js +11 -0
  92. package/dist/charts/dashboard/windows.js +8 -3
  93. package/dist/charts/edge-fade.js +10 -5
  94. package/dist/charts/hover-band.js +16 -11
  95. package/dist/charts/index.js +0 -1
  96. package/dist/charts/motion.js +11 -7
  97. package/dist/charts/primitives/chart-utils.js +12 -12
  98. package/dist/components/copy/clipboard.js +32 -32
  99. package/dist/components/copy/copied.svelte.js +31 -23
  100. package/dist/components/data-table/data-table.js +39 -39
  101. package/dist/components/docs/index.js +4 -0
  102. package/dist/components/docs/scroll-spy.svelte.js +73 -68
  103. package/dist/components/list-page/filter-section.js +4 -1
  104. package/dist/components/list-page/index.js +2 -0
  105. package/dist/components/list-page/list-table.js +7 -2
  106. package/dist/components/list-page/queue-rail.js +14 -0
  107. package/dist/components/list-page/section-host.js +4 -2
  108. package/dist/components/list-page/step.js +4 -3
  109. package/dist/components/list-page/types.js +1 -0
  110. package/dist/components/picker/trigger.js +48 -30
  111. package/dist/components/picker/types.js +1 -0
  112. package/dist/components/segmented/collapse.js +38 -27
  113. package/dist/components/segmented/index.js +8 -0
  114. package/dist/components/segmented/segmented.js +67 -42
  115. package/dist/components/star-rating-input/index.js +3 -1
  116. package/dist/components/table-view/types.js +1 -0
  117. package/dist/components/tags-input/tags.js +81 -69
  118. package/dist/components/theme/index.js +4 -0
  119. package/dist/components/toolbar/index.js +4 -0
  120. package/dist/components/toolbar/toolbar-trigger.js +14 -1
  121. package/dist/editor/anchors.js +17 -13
  122. package/dist/editor/block-id.js +52 -51
  123. package/dist/editor/block-ops.js +108 -80
  124. package/dist/editor/doc-blocks.js +155 -166
  125. package/dist/editor/extensions.js +139 -180
  126. package/dist/editor/index.js +4 -0
  127. package/dist/editor/markdown-test-helpers.js +4 -2
  128. package/dist/editor/markdown.js +420 -408
  129. package/dist/editor/serializer.js +204 -200
  130. package/dist/editor/slash-items.js +89 -101
  131. package/dist/editor/youtube-url.js +25 -20
  132. package/dist/effects/animated-beam/path-calculator.svelte.js +43 -38
  133. package/dist/effects/animated-beam/types.js +1 -0
  134. package/dist/effects/border-beam/css.js +92 -78
  135. package/dist/effects/border-beam/presets.js +1705 -1720
  136. package/dist/effects/border-beam/register-properties.js +43 -33
  137. package/dist/effects/border-beam/types.js +1 -0
  138. package/dist/effects/image-comparison/compare.js +3 -2
  139. package/dist/effects/image-reveal/types.js +1 -0
  140. package/dist/effects/magnetic/magnetic.js +58 -52
  141. package/dist/effects/reveal/observe.js +50 -40
  142. package/dist/effects/reveal/types.js +1 -0
  143. package/dist/effects/shader-gradient/color.js +36 -29
  144. package/dist/effects/shader-gradient/renderer.js +384 -295
  145. package/dist/effects/shader-gradient/shaders.js +31 -0
  146. package/dist/effects/shader-gradient/types.js +1 -0
  147. package/dist/icons/apple-symbol-exports.js +99 -124
  148. package/dist/icons/sf-symbols.js +357 -461
  149. package/dist/icons/trades.js +43 -28
  150. package/dist/inbox/index.js +1 -0
  151. package/dist/inbox/logic.js +126 -122
  152. package/dist/inbox/types.js +43 -43
  153. package/dist/lib/arrive.js +19 -12
  154. package/dist/lib/icon-types.js +1 -0
  155. package/dist/lib/initials.js +16 -10
  156. package/dist/lib/layout.js +5 -0
  157. package/dist/lib/panel.js +13 -0
  158. package/dist/lib/result.js +22 -22
  159. package/dist/lib/sliding-pill.js +59 -44
  160. package/dist/lib/theme-transition.js +43 -43
  161. package/dist/lib/tone.js +31 -24
  162. package/dist/lib/utils.js +3 -1
  163. package/dist/onboarding/define-tours.js +24 -23
  164. package/dist/onboarding/onboarding.svelte.js +16 -12
  165. package/dist/onboarding/pick.js +10 -6
  166. package/dist/onboarding/stores.js +40 -41
  167. package/dist/onboarding/wait.js +24 -23
  168. package/dist/panel/side-panel-types.js +1 -0
  169. package/dist/record/demo-data.js +459 -486
  170. package/dist/record/fields.js +129 -131
  171. package/dist/record/format.js +70 -82
  172. package/dist/record/gutter.js +1 -0
  173. package/dist/record/kinds.js +95 -105
  174. package/dist/record/logic.js +238 -219
  175. package/dist/record/types.js +49 -48
  176. package/dist/shadcn/accordion/index.js +3 -1
  177. package/dist/shadcn/alert/index.js +3 -1
  178. package/dist/shadcn/alert-dialog/index.js +3 -1
  179. package/dist/shadcn/attachment/index.js +3 -1
  180. package/dist/shadcn/avatar/index.js +3 -1
  181. package/dist/shadcn/breadcrumb/index.js +3 -1
  182. package/dist/shadcn/bubble/index.js +3 -1
  183. package/dist/shadcn/button/index.js +3 -1
  184. package/dist/shadcn/calendar/index.js +3 -1
  185. package/dist/shadcn/card/index.js +3 -1
  186. package/dist/shadcn/checkbox/index.js +3 -1
  187. package/dist/shadcn/code-block/index.js +3 -1
  188. package/dist/shadcn/collapsible/index.js +3 -1
  189. package/dist/shadcn/command/index.js +4 -1
  190. package/dist/shadcn/context-menu/index.js +3 -1
  191. package/dist/shadcn/dialog/index.js +3 -1
  192. package/dist/shadcn/dropdown-menu/menu-item.js +40 -20
  193. package/dist/shadcn/empty/index.js +3 -1
  194. package/dist/shadcn/field/index.js +3 -1
  195. package/dist/shadcn/hooks/highlighter.js +77 -75
  196. package/dist/shadcn/hooks/is-mobile.svelte.js +3 -3
  197. package/dist/shadcn/hooks/use-highlighted-code.svelte.js +62 -62
  198. package/dist/shadcn/input/index.js +3 -1
  199. package/dist/shadcn/kbd/index.js +3 -1
  200. package/dist/shadcn/label/index.js +3 -1
  201. package/dist/shadcn/marker/index.js +3 -1
  202. package/dist/shadcn/message/index.js +3 -1
  203. package/dist/shadcn/message-scroller/index.js +3 -1
  204. package/dist/shadcn/popover/index.js +3 -1
  205. package/dist/shadcn/progress/index.js +3 -1
  206. package/dist/shadcn/progress/tone.js +8 -7
  207. package/dist/shadcn/radio-group/index.js +3 -1
  208. package/dist/shadcn/scroll-area/index.js +3 -1
  209. package/dist/shadcn/select/index.js +3 -1
  210. package/dist/shadcn/separator/index.js +3 -1
  211. package/dist/shadcn/sheet/index.js +3 -1
  212. package/dist/shadcn/sidebar/context.svelte.js +42 -28
  213. package/dist/shadcn/sidebar/index.js +3 -1
  214. package/dist/shadcn/skeleton/index.js +3 -1
  215. package/dist/shadcn/slider/index.js +3 -1
  216. package/dist/shadcn/switch/index.js +3 -1
  217. package/dist/shadcn/table/index.js +3 -1
  218. package/dist/shadcn/tabs/index.js +3 -1
  219. package/dist/shadcn/textarea/index.js +3 -1
  220. package/dist/shadcn/toggle/index.js +3 -1
  221. package/dist/shadcn/toggle-group/index.js +3 -1
  222. package/dist/shadcn/tooltip/context.js +7 -2
  223. package/dist/shadcn/tooltip/index.js +3 -1
  224. package/dist/shadcn/trace/index.js +3 -1
  225. package/dist/slides/bridges.js +65 -59
  226. package/dist/slides/deck-controller.svelte.js +210 -207
  227. package/dist/slides/export/capture.js +66 -71
  228. package/dist/slides/export/ffmpeg.js +76 -72
  229. package/dist/slides/export/index.js +3 -0
  230. package/dist/slides/export/launch.js +9 -6
  231. package/dist/slides/export/pdf.js +60 -54
  232. package/dist/slides/export/types.js +1 -0
  233. package/dist/slides/labels.js +24 -24
  234. package/dist/slides/layout.js +39 -41
  235. package/dist/slides/model.js +9 -7
  236. package/dist/slides/navigation.js +78 -73
  237. package/dist/slides/types.js +2 -2
  238. package/dist/status/define-statuses.js +18 -14
  239. package/dist/status/status-types.js +1 -0
  240. package/dist/test-setup.js +24 -20
  241. package/dist/thread/logic.js +73 -77
  242. package/dist/thread/types.js +21 -21
  243. package/dist/work/board-order.js +94 -90
  244. package/dist/work/dates.js +16 -9
  245. package/dist/work/detail/detail-types.js +18 -18
  246. package/dist/work/docs/edited.js +32 -29
  247. package/dist/work/docs/index.js +4 -0
  248. package/dist/work/docs/labels.js +34 -34
  249. package/dist/work/docs/menu.js +113 -106
  250. package/dist/work/docs/outline.js +39 -29
  251. package/dist/work/gantt/logic.js +211 -235
  252. package/dist/work/inbox/inbox-logic.js +71 -75
  253. package/dist/work/inbox/inbox-statuses.js +75 -72
  254. package/dist/work/inbox/inbox-types.js +1 -0
  255. package/dist/work/kanban-drag.js +27 -22
  256. package/dist/work/kanban-types.js +1 -0
  257. package/dist/work/presets/sales.js +36 -32
  258. package/dist/work/reorder.js +9 -8
  259. package/dist/work/task-types.js +1 -0
  260. package/dist/work/time/duration.js +51 -46
  261. package/dist/work/time/time-types.js +23 -23
  262. package/dist/work/use-kanban-dnd.svelte.js +126 -125
  263. package/package.json +3 -1
  264. package/src/components/list-page/master-detail.svelte +3 -1
  265. package/src/components/list-page/rail-row.svelte +4 -4
  266. package/src/editor/markdown.ts +30 -35
@@ -1,221 +1,193 @@
1
1
  import { sortParentsFirst } from "../headless/canvas-cleanup.js";
2
+ // Fields that churn without changing the document. Stripped, so selecting isn't
3
+ // an undo step and undo doesn't restore a stale selection.
2
4
  const VOLATILE_NODE_FIELDS = new Set([
3
- "selected",
4
- "dragging",
5
- "measured",
6
- "resizing"
7
- ]);
8
- const VOLATILE_EDGE_FIELDS = new Set([
9
- "selected"
5
+ "selected",
6
+ "dragging",
7
+ "measured",
8
+ "resizing"
10
9
  ]);
10
+ const VOLATILE_EDGE_FIELDS = new Set(["selected"]);
11
11
  function stripVolatile(record, volatile) {
12
- const out = {};
13
- for (const [key, value] of Object.entries(record)){
14
- if (volatile.has(key) || value === undefined) continue;
15
- out[key] = value;
16
- }
17
- return out;
12
+ const out = {};
13
+ for (const [key, value] of Object.entries(record)) {
14
+ if (volatile.has(key) || value === undefined) continue;
15
+ out[key] = value;
16
+ }
17
+ return out;
18
18
  }
19
19
  function clone(value) {
20
- return JSON.parse(JSON.stringify(value));
20
+ return JSON.parse(JSON.stringify(value));
21
21
  }
22
22
  function signature(record, volatile) {
23
- return JSON.stringify(stripVolatile(record, volatile));
23
+ return JSON.stringify(stripVolatile(record, volatile));
24
24
  }
25
+ /** True when two versions of a card differ only in fields that churn without changing the document. */
25
26
  export function isSameNode(a, b) {
26
- return a === b || signature(a, VOLATILE_NODE_FIELDS) === signature(b, VOLATILE_NODE_FIELDS);
27
+ return a === b || signature(a, VOLATILE_NODE_FIELDS) === signature(b, VOLATILE_NODE_FIELDS);
27
28
  }
28
29
  export function isSameEdge(a, b) {
29
- return a === b || signature(a, VOLATILE_EDGE_FIELDS) === signature(b, VOLATILE_EDGE_FIELDS);
30
+ return a === b || signature(a, VOLATILE_EDGE_FIELDS) === signature(b, VOLATILE_EDGE_FIELDS);
30
31
  }
31
32
  function diffOrder(base, current) {
32
- const before = base.map((item)=>item.id);
33
- const after = current.map((item)=>item.id);
34
- const same = before.length === after.length && before.every((id, i)=>id === after[i]);
35
- return same ? undefined : {
36
- before,
37
- after
38
- };
33
+ const before = base.map((item) => item.id);
34
+ const after = current.map((item) => item.id);
35
+ const same = before.length === after.length && before.every((id, i) => id === after[i]);
36
+ return same ? undefined : {
37
+ before,
38
+ after
39
+ };
39
40
  }
40
41
  function diffCollection(base, current, volatile) {
41
- const baseById = new Map(base.map((item)=>[
42
- item.id,
43
- item
44
- ]));
45
- const currentById = new Map(current.map((item)=>[
46
- item.id,
47
- item
48
- ]));
49
- const before = [];
50
- const after = [];
51
- for (const item of base){
52
- const counterpart = currentById.get(item.id);
53
- if (!counterpart) {
54
- before.push(clone(stripVolatile(item, volatile)));
55
- continue;
56
- }
57
- if (item !== counterpart && signature(item, volatile) !== signature(counterpart, volatile)) {
58
- before.push(clone(stripVolatile(item, volatile)));
59
- after.push(clone(stripVolatile(counterpart, volatile)));
60
- }
61
- }
62
- for (const item of current){
63
- if (!baseById.has(item.id)) {
64
- after.push(clone(stripVolatile(item, volatile)));
65
- }
66
- }
67
- return {
68
- before,
69
- after
70
- };
71
- }
42
+ const baseById = new Map(base.map((item) => [item.id, item]));
43
+ const currentById = new Map(current.map((item) => [item.id, item]));
44
+ const before = [];
45
+ const after = [];
46
+ for (const item of base) {
47
+ const counterpart = currentById.get(item.id);
48
+ if (!counterpart) {
49
+ before.push(clone(stripVolatile(item, volatile)));
50
+ continue;
51
+ }
52
+ // The same object is the same card: an untouched card costs nothing, however big the board.
53
+ if (item !== counterpart && signature(item, volatile) !== signature(counterpart, volatile)) {
54
+ before.push(clone(stripVolatile(item, volatile)));
55
+ after.push(clone(stripVolatile(counterpart, volatile)));
56
+ }
57
+ }
58
+ for (const item of current) {
59
+ if (!baseById.has(item.id)) {
60
+ after.push(clone(stripVolatile(item, volatile)));
61
+ }
62
+ }
63
+ return {
64
+ before,
65
+ after
66
+ };
67
+ }
68
+ /**
69
+ * Diff two flow states into a history entry, or null when nothing changed. An order change
70
+ * alone is no step, so a bare reshuffle adds no undo entry.
71
+ */
72
72
  export function diffFlowState(base, current) {
73
- const nodes = diffCollection(base.nodes, current.nodes, VOLATILE_NODE_FIELDS);
74
- const edges = diffCollection(base.edges, current.edges, VOLATILE_EDGE_FIELDS);
75
- if (nodes.before.length === 0 && nodes.after.length === 0 && edges.before.length === 0 && edges.after.length === 0) {
76
- return null;
77
- }
78
- const nodeOrder = diffOrder(base.nodes, current.nodes);
79
- const edgeOrder = diffOrder(base.edges, current.edges);
80
- return {
81
- nodesBefore: nodes.before,
82
- nodesAfter: nodes.after,
83
- edgesBefore: edges.before,
84
- edgesAfter: edges.after,
85
- ...nodeOrder && {
86
- nodeOrder
87
- },
88
- ...edgeOrder && {
89
- edgeOrder
90
- }
91
- };
92
- }
73
+ const nodes = diffCollection(base.nodes, current.nodes, VOLATILE_NODE_FIELDS);
74
+ const edges = diffCollection(base.edges, current.edges, VOLATILE_EDGE_FIELDS);
75
+ if (nodes.before.length === 0 && nodes.after.length === 0 && edges.before.length === 0 && edges.after.length === 0) {
76
+ return null;
77
+ }
78
+ const nodeOrder = diffOrder(base.nodes, current.nodes);
79
+ const edgeOrder = diffOrder(base.edges, current.edges);
80
+ return {
81
+ nodesBefore: nodes.before,
82
+ nodesAfter: nodes.after,
83
+ edgesBefore: edges.before,
84
+ edgesAfter: edges.after,
85
+ ...nodeOrder && { nodeOrder },
86
+ ...edgeOrder && { edgeOrder }
87
+ };
88
+ }
89
+ /** Stable sort into `order`. An id the entry never saw keeps its place after the known ones. */
93
90
  function sortByOrder(items, order) {
94
- if (!order) return items;
95
- const rank = new Map(order.map((id, index)=>[
96
- id,
97
- index
98
- ]));
99
- const at = (item)=>rank.get(item.id) ?? order.length;
100
- return items.toSorted((a, b)=>at(a) - at(b));
91
+ if (!order) return items;
92
+ const rank = new Map(order.map((id, index) => [id, index]));
93
+ const at = (item) => rank.get(item.id) ?? order.length;
94
+ return items.toSorted((a, b) => at(a) - at(b));
101
95
  }
96
+ /** Only a child ahead of its parent breaks SvelteFlow, so a valid order is never regrouped. */
102
97
  function parentsFirst(nodes) {
103
- const seen = new Set();
104
- const ids = new Set(nodes.map((node)=>node.id));
105
- for (const node of nodes){
106
- if (node.parentId && ids.has(node.parentId) && !seen.has(node.parentId)) {
107
- return sortParentsFirst(nodes);
108
- }
109
- seen.add(node.id);
110
- }
111
- return nodes;
98
+ const seen = new Set();
99
+ const ids = new Set(nodes.map((node) => node.id));
100
+ for (const node of nodes) {
101
+ if (node.parentId && ids.has(node.parentId) && !seen.has(node.parentId)) {
102
+ return sortParentsFirst(nodes);
103
+ }
104
+ seen.add(node.id);
105
+ }
106
+ return nodes;
112
107
  }
113
108
  function applyCollection(items, restore, discard) {
114
- const restoreById = new Map(restore.map((item)=>[
115
- item.id,
116
- item
117
- ]));
118
- const discardIds = new Set(discard.map((item)=>item.id));
119
- let next = items.filter((item)=>!(discardIds.has(item.id) && !restoreById.has(item.id)));
120
- const present = new Set(next.map((item)=>item.id));
121
- next = next.map((item)=>{
122
- const restored = restoreById.get(item.id);
123
- if (!restored) return item;
124
- const selected = item.selected;
125
- return {
126
- ...clone(restored),
127
- ...selected !== undefined && {
128
- selected
129
- }
130
- };
131
- });
132
- for (const item of restore){
133
- if (!present.has(item.id)) next.push(clone(item));
134
- }
135
- return next;
136
- }
109
+ const restoreById = new Map(restore.map((item) => [item.id, item]));
110
+ const discardIds = new Set(discard.map((item) => item.id));
111
+ // Drop pure additions of the direction being reverted.
112
+ let next = items.filter((item) => !(discardIds.has(item.id) && !restoreById.has(item.id)));
113
+ // Restore changed items in place.
114
+ const present = new Set(next.map((item) => item.id));
115
+ next = next.map((item) => {
116
+ const restored = restoreById.get(item.id);
117
+ if (!restored) return item;
118
+ // Selection is where you are, not what the document held, so an undo leaves it be.
119
+ const selected = item.selected;
120
+ return {
121
+ ...clone(restored),
122
+ ...selected !== undefined && { selected }
123
+ };
124
+ });
125
+ // Re-add items that were removed in the direction being reverted.
126
+ for (const item of restore) {
127
+ if (!present.has(item.id)) next.push(clone(item));
128
+ }
129
+ return next;
130
+ }
131
+ /** Apply a history entry to a state: "undo" restores the before side, "redo" the after side. */
137
132
  export function applyHistoryEntry(state, entry, direction) {
138
- const [restoreNodes, discardNodes] = direction === "undo" ? [
139
- entry.nodesBefore,
140
- entry.nodesAfter
141
- ] : [
142
- entry.nodesAfter,
143
- entry.nodesBefore
144
- ];
145
- const [restoreEdges, discardEdges] = direction === "undo" ? [
146
- entry.edgesBefore,
147
- entry.edgesAfter
148
- ] : [
149
- entry.edgesAfter,
150
- entry.edgesBefore
151
- ];
152
- const side = direction === "undo" ? "before" : "after";
153
- return {
154
- nodes: parentsFirst(sortByOrder(applyCollection(state.nodes, restoreNodes, discardNodes), entry.nodeOrder?.[side])),
155
- edges: sortByOrder(applyCollection(state.edges, restoreEdges, discardEdges), entry.edgeOrder?.[side])
156
- };
157
- }
133
+ const [restoreNodes, discardNodes] = direction === "undo" ? [entry.nodesBefore, entry.nodesAfter] : [entry.nodesAfter, entry.nodesBefore];
134
+ const [restoreEdges, discardEdges] = direction === "undo" ? [entry.edgesBefore, entry.edgesAfter] : [entry.edgesAfter, entry.edgesBefore];
135
+ const side = direction === "undo" ? "before" : "after";
136
+ return {
137
+ // WHY parentsFirst: SvelteFlow requires parents before children; a
138
+ // re-added container must land ahead of the children it re-adopts.
139
+ nodes: parentsFirst(sortByOrder(applyCollection(state.nodes, restoreNodes, discardNodes), entry.nodeOrder?.[side])),
140
+ edges: sortByOrder(applyCollection(state.edges, restoreEdges, discardEdges), entry.edgeOrder?.[side])
141
+ };
142
+ }
143
+ /** An id's earliest before and latest after, so a node touched by both steps keeps its outer states. */
158
144
  function mergeSides(first, second) {
159
- const firstTouched = new Set([
160
- ...first.before,
161
- ...first.after
162
- ].map((item)=>item.id));
163
- const secondTouched = new Set([
164
- ...second.before,
165
- ...second.after
166
- ].map((item)=>item.id));
167
- const before = [
168
- ...first.before,
169
- ...second.before.filter((item)=>!firstTouched.has(item.id))
170
- ];
171
- const after = [
172
- ...first.after.filter((item)=>!secondTouched.has(item.id)),
173
- ...second.after
174
- ];
175
- return {
176
- before,
177
- after
178
- };
145
+ const firstTouched = new Set([...first.before, ...first.after].map((item) => item.id));
146
+ const secondTouched = new Set([...second.before, ...second.after].map((item) => item.id));
147
+ const before = [...first.before, ...second.before.filter((item) => !firstTouched.has(item.id))];
148
+ const after = [...first.after.filter((item) => !secondTouched.has(item.id)), ...second.after];
149
+ return {
150
+ before,
151
+ after
152
+ };
179
153
  }
180
154
  function sameIds(a, b) {
181
- return a.length === b.length && a.every((id, i)=>id === b[i]);
155
+ return a.length === b.length && a.every((id, i) => id === b[i]);
182
156
  }
157
+ /** No order change on one side means that step left the order alone, so the other side's end stands in. */
183
158
  function mergeOrder(first, second) {
184
- const before = first?.before ?? second?.before;
185
- const after = second?.after ?? first?.after;
186
- if (!before || !after) return undefined;
187
- return sameIds(before, after) ? undefined : {
188
- before,
189
- after
190
- };
191
- }
159
+ const before = first?.before ?? second?.before;
160
+ const after = second?.after ?? first?.after;
161
+ if (!before || !after) return undefined;
162
+ return sameIds(before, after) ? undefined : {
163
+ before,
164
+ after
165
+ };
166
+ }
167
+ /** Fold two consecutive steps into one: undoing it restores the state before `first`. */
192
168
  export function mergeHistoryEntries(first, second) {
193
- const nodes = mergeSides({
194
- before: first.nodesBefore,
195
- after: first.nodesAfter
196
- }, {
197
- before: second.nodesBefore,
198
- after: second.nodesAfter
199
- });
200
- const edges = mergeSides({
201
- before: first.edgesBefore,
202
- after: first.edgesAfter
203
- }, {
204
- before: second.edgesBefore,
205
- after: second.edgesAfter
206
- });
207
- const nodeOrder = mergeOrder(first.nodeOrder, second.nodeOrder);
208
- const edgeOrder = mergeOrder(first.edgeOrder, second.edgeOrder);
209
- return {
210
- nodesBefore: nodes.before,
211
- nodesAfter: nodes.after,
212
- edgesBefore: edges.before,
213
- edgesAfter: edges.after,
214
- ...nodeOrder && {
215
- nodeOrder
216
- },
217
- ...edgeOrder && {
218
- edgeOrder
219
- }
220
- };
169
+ const nodes = mergeSides({
170
+ before: first.nodesBefore,
171
+ after: first.nodesAfter
172
+ }, {
173
+ before: second.nodesBefore,
174
+ after: second.nodesAfter
175
+ });
176
+ const edges = mergeSides({
177
+ before: first.edgesBefore,
178
+ after: first.edgesAfter
179
+ }, {
180
+ before: second.edgesBefore,
181
+ after: second.edgesAfter
182
+ });
183
+ const nodeOrder = mergeOrder(first.nodeOrder, second.nodeOrder);
184
+ const edgeOrder = mergeOrder(first.edgeOrder, second.edgeOrder);
185
+ return {
186
+ nodesBefore: nodes.before,
187
+ nodesAfter: nodes.after,
188
+ edgesBefore: edges.before,
189
+ edgesAfter: edges.after,
190
+ ...nodeOrder && { nodeOrder },
191
+ ...edgeOrder && { edgeOrder }
192
+ };
221
193
  }