@signal9/era-ui 12.1.1 → 12.1.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.
@@ -98,6 +98,10 @@
98
98
  let dragging = false;
99
99
  const live = { x: position.x, y: position.y };
100
100
 
101
+ /* Applies any zone mutation that arrived while a gesture was live. Assigned
102
+ * by the zone effect below, called by onDragEnd — see the observer there. */
103
+ let flushZones: (() => void) | null = null;
104
+
101
105
  const track = (data: DragEventData) => {
102
106
  live.x = data.offset.x;
103
107
  live.y = data.offset.y;
@@ -160,6 +164,7 @@
160
164
  dragging = false;
161
165
  track(data);
162
166
  sync(data);
167
+ flushZones?.();
163
168
  onDragEnd?.(data);
164
169
  }
165
170
  });
@@ -211,7 +216,35 @@
211
216
  }
212
217
  };
213
218
  syncZones();
214
- const observer = new MutationObserver(syncZones);
219
+
220
+ /* MID-DRAG MUTATIONS DO NOT RE-WALK THE SUBTREE.
221
+ *
222
+ * The observer watches childList across the whole subtree, so ANY content
223
+ * that ticks — a clock, a streaming response, a terminal, a swarm's forty
224
+ * rows — fires this on every mutation, and each call is a full
225
+ * querySelectorAll over the pane. Measured on a pane whose body updated on
226
+ * an 8ms interval: 419 walks during a single 200-move drag, about two per
227
+ * frame, none of which could change anything.
228
+ *
229
+ * They cannot change anything because the gesture has ALREADY claimed its
230
+ * zone: handle and cancel registrations are read at pointerdown to decide
231
+ * whether a drag starts, and that decision is made. So the walk is deferred
232
+ * to drag end, where it costs one call instead of hundreds. A pane with a
233
+ * static body never notices — it was 0 walks before and is 0 now. */
234
+ let missed = false;
235
+ const onMutate = () => {
236
+ if (dragging) {
237
+ missed = true;
238
+ return;
239
+ }
240
+ syncZones();
241
+ };
242
+ flushZones = () => {
243
+ if (!missed) return;
244
+ missed = false;
245
+ syncZones();
246
+ };
247
+ const observer = new MutationObserver(onMutate);
215
248
  observer.observe(node, {
216
249
  subtree: true,
217
250
  childList: true,
@@ -219,6 +252,7 @@
219
252
  });
220
253
  return () => {
221
254
  observer.disconnect();
255
+ flushZones = null;
222
256
  for (const mark of marks.values()) mark.off();
223
257
  };
224
258
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signal9/era-ui",
3
- "version": "12.1.1",
3
+ "version": "12.1.2",
4
4
  "scripts": {
5
5
  "dev": "vite dev --host",
6
6
  "build": "vite build && npm run prepack",