streetui 1.0.0 → 1.2.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.
@@ -1,4 +1,4 @@
1
- import { C as CompiledApplication } from './compile-B0q07Hzq.cjs';
1
+ import { C as CompiledApplication } from './compile-DsNJm9IJ.cjs';
2
2
 
3
3
  /**
4
4
  * DOMAdapter — framework-owned abstraction over DOM operations.
@@ -1,4 +1,4 @@
1
- import { C as CompiledApplication } from './compile-B0q07Hzq.js';
1
+ import { C as CompiledApplication } from './compile-DsNJm9IJ.js';
2
2
 
3
3
  /**
4
4
  * DOMAdapter — framework-owned abstraction over DOM operations.
package/dist/server.cjs CHANGED
@@ -162,6 +162,7 @@ function patchProp(dom, element, name, oldValue, newValue) {
162
162
 
163
163
  // ../renderer/src/events.ts
164
164
  function wireEvents(dom, graph, node, element, instance) {
165
+ if (node.events.length === 0) return;
165
166
  for (const eventDesc of node.events) {
166
167
  const handler = graph.getHandler(eventDesc.handlerKey);
167
168
  if (handler === void 0) continue;
@@ -291,6 +292,109 @@ function reconcileChildren(ctx, parentDom, oldInstances, newNodes, mountFn) {
291
292
  reorderDom(ctx, parentDom, newInstances);
292
293
  return { instances: newInstances, removed };
293
294
  }
295
+ function reconcileChildrenByPlan(ctx, parentDom, oldInstances, plan, mountFn) {
296
+ const oldByKey = /* @__PURE__ */ new Map();
297
+ for (const inst of oldInstances) {
298
+ oldByKey.set(inst.graphNode.key ?? inst.graphNode.id, inst);
299
+ }
300
+ const newInstances = [];
301
+ const usedKeys = /* @__PURE__ */ new Set();
302
+ const built = [];
303
+ for (const entry of plan) {
304
+ const existing = oldByKey.get(entry.key);
305
+ if (existing !== void 0) {
306
+ usedKeys.add(entry.key);
307
+ const oldItem = existing.graphNode.getProp("_item");
308
+ if (!Object.is(oldItem, entry.item)) {
309
+ const newSig = entry.sig();
310
+ const oldSig = existing.graphNode.getProp("_sig");
311
+ if (!Object.is(oldSig, newSig)) {
312
+ const freshNode = entry.build();
313
+ built.push(freshNode);
314
+ patchExistingInstance(ctx, existing, freshNode);
315
+ reconcileItemChildren(ctx, existing, freshNode, mountFn);
316
+ existing.graphNode.setProp("_sig", newSig);
317
+ }
318
+ existing.graphNode.setProp("_item", entry.item);
319
+ }
320
+ newInstances.push(existing);
321
+ } else {
322
+ const freshNode = entry.build();
323
+ built.push(freshNode);
324
+ const inst = mountFn(freshNode, parentDom);
325
+ newInstances.push(inst);
326
+ }
327
+ }
328
+ const removed = [];
329
+ for (const inst of oldInstances) {
330
+ const key = inst.graphNode.key ?? inst.graphNode.id;
331
+ if (!usedKeys.has(key)) removed.push(inst);
332
+ }
333
+ for (const inst of removed) {
334
+ const parent = ctx.dom.parentNode(inst.domNode);
335
+ if (parent !== null) ctx.dom.removeChild(parent, inst.domNode);
336
+ inst.dispose();
337
+ }
338
+ reorderDomMinimal(ctx, parentDom, oldInstances, newInstances);
339
+ return { instances: newInstances, removed, built };
340
+ }
341
+ function reorderDomMinimal(ctx, parentDom, oldInstances, newInstances) {
342
+ const n = newInstances.length;
343
+ if (n === 0) return;
344
+ const oldIndexOf = /* @__PURE__ */ new Map();
345
+ for (let i = 0; i < oldInstances.length; i++) oldIndexOf.set(oldInstances[i], i);
346
+ const source = new Array(n);
347
+ let moved = false;
348
+ let lastSeen = -1;
349
+ for (let i = 0; i < n; i++) {
350
+ const oi = oldIndexOf.get(newInstances[i]);
351
+ if (oi === void 0) {
352
+ source[i] = -1;
353
+ moved = true;
354
+ } else {
355
+ source[i] = oi;
356
+ if (oi < lastSeen) moved = true;
357
+ else lastSeen = oi;
358
+ }
359
+ }
360
+ if (!moved) return;
361
+ const keep = longestIncreasingSubsequence(source);
362
+ let refNode = null;
363
+ for (let i = n - 1; i >= 0; i--) {
364
+ const domNode = newInstances[i].domNode;
365
+ if (source[i] === -1 || !keep.has(i)) {
366
+ if (ctx.dom.nextSibling(domNode) !== refNode) {
367
+ ctx.dom.insertBefore(parentDom, domNode, refNode);
368
+ }
369
+ }
370
+ refNode = domNode;
371
+ }
372
+ }
373
+ function longestIncreasingSubsequence(source) {
374
+ const keep = /* @__PURE__ */ new Set();
375
+ const n = source.length;
376
+ const tails = [];
377
+ const prev = new Array(n).fill(-1);
378
+ for (let i = 0; i < n; i++) {
379
+ const v = source[i];
380
+ if (v < 0) continue;
381
+ let lo = 0;
382
+ let hi = tails.length;
383
+ while (lo < hi) {
384
+ const mid = lo + hi >> 1;
385
+ if (source[tails[mid]] < v) lo = mid + 1;
386
+ else hi = mid;
387
+ }
388
+ if (lo > 0) prev[i] = tails[lo - 1];
389
+ tails[lo] = i;
390
+ }
391
+ let idx = tails.length > 0 ? tails[tails.length - 1] : -1;
392
+ while (idx >= 0) {
393
+ keep.add(idx);
394
+ idx = prev[idx];
395
+ }
396
+ return keep;
397
+ }
294
398
  function reconcileItemChildren(ctx, itemInstance, newItemNode, mountFn) {
295
399
  const el = itemInstance.domNode;
296
400
  if (!ctx.dom.isElement(el)) return;
@@ -392,10 +496,12 @@ function mountNode(ctx, graphNode, parentDom) {
392
496
  const textNode = dom.createTextNode(text);
393
497
  dom.appendChild(el2, textNode);
394
498
  applyNodeProps(ctx, graphNode, el2);
395
- wireEvents(dom, graph, graphNode, el2, new NodeInstance(graphNode, el2));
396
499
  const instance2 = new NodeInstance(graphNode, el2);
397
500
  ctx.instances.set(graphNode.id, instance2);
398
- wireSignalBindings(ctx, graphNode, instance2, textUpdate(dom, el2, textNode));
501
+ wireEvents(dom, graph, graphNode, el2, instance2);
502
+ if (graphNode.stateRefs.length !== 0) {
503
+ wireSignalBindings(ctx, graphNode, instance2, textUpdate(dom, el2, textNode));
504
+ }
399
505
  dom.appendChild(parentDom, el2);
400
506
  return instance2;
401
507
  }
@@ -409,7 +515,9 @@ function mountNode(ctx, graphNode, parentDom) {
409
515
  const instance2 = new NodeInstance(graphNode, el2);
410
516
  ctx.instances.set(graphNode.id, instance2);
411
517
  wireEvents(dom, graph, graphNode, el2, instance2);
412
- wireSignalBindings(ctx, graphNode, instance2, headingUpdate(dom, el2));
518
+ if (graphNode.stateRefs.length !== 0) {
519
+ wireSignalBindings(ctx, graphNode, instance2, headingUpdate(dom, el2));
520
+ }
413
521
  dom.appendChild(parentDom, el2);
414
522
  return instance2;
415
523
  }
@@ -425,7 +533,9 @@ function mountNode(ctx, graphNode, parentDom) {
425
533
  const instance2 = new NodeInstance(graphNode, el2);
426
534
  ctx.instances.set(graphNode.id, instance2);
427
535
  wireEvents(dom, graph, graphNode, el2, instance2);
428
- wireSignalBindings(ctx, graphNode, instance2, inputUpdate(dom, el2));
536
+ if (graphNode.stateRefs.length !== 0) {
537
+ wireSignalBindings(ctx, graphNode, instance2, inputUpdate(dom, el2));
538
+ }
429
539
  dom.appendChild(parentDom, el2);
430
540
  return instance2;
431
541
  }
@@ -473,7 +583,9 @@ function mountNode(ctx, graphNode, parentDom) {
473
583
  const instance2 = new NodeInstance(graphNode, el2);
474
584
  ctx.instances.set(graphNode.id, instance2);
475
585
  wireEvents(dom, graph, graphNode, el2, instance2);
476
- wireSignalBindings(ctx, graphNode, instance2, buttonUpdate(dom, el2));
586
+ if (graphNode.stateRefs.length !== 0) {
587
+ wireSignalBindings(ctx, graphNode, instance2, buttonUpdate(dom, el2));
588
+ }
477
589
  dom.appendChild(parentDom, el2);
478
590
  return instance2;
479
591
  }
@@ -500,11 +612,11 @@ function mountNode(ctx, graphNode, parentDom) {
500
612
  dom.setAttribute(el, "data-streetui-key", String(itemKey));
501
613
  }
502
614
  }
503
- if (graphNode.type === "form") {
504
- wireEvents(dom, graph, graphNode, el, new NodeInstance(graphNode, el));
505
- }
506
615
  const instance = new NodeInstance(graphNode, el);
507
616
  ctx.instances.set(graphNode.id, instance);
617
+ if (graphNode.type === "form") {
618
+ wireEvents(dom, graph, graphNode, el, instance);
619
+ }
508
620
  for (const child of graphNode.children) {
509
621
  const childInstance = mountNode(ctx, child, el);
510
622
  instance.addChild(childInstance);
@@ -555,12 +667,15 @@ function buttonUpdate(dom, el) {
555
667
  };
556
668
  }
557
669
  function applyNodeProps(ctx, graphNode, el) {
558
- for (const [key, value] of Object.entries(graphNode.props)) {
670
+ const props = graphNode.props;
671
+ for (const key in props) {
672
+ if (!Object.hasOwn(props, key)) continue;
559
673
  if (SKIP_PROP_KEYS.has(key)) continue;
560
- applyProp(ctx.dom, el, key, value);
674
+ applyProp(ctx.dom, el, key, props[key]);
561
675
  }
562
676
  }
563
677
  function wireSignalBindings(ctx, graphNode, instance, onUpdate) {
678
+ if (graphNode.stateRefs.length === 0) return;
564
679
  for (const stateRef of graphNode.stateRefs) {
565
680
  const signalKey = `__signal__${stateRef.signalId}`;
566
681
  const maybeSig = ctx.graph.getHandler(signalKey);
@@ -572,18 +687,45 @@ function wireSignalBindings(ctx, graphNode, instance, onUpdate) {
572
687
  }
573
688
  }
574
689
  function wireReactiveList(ctx, graphNode, instance, el) {
690
+ const plan = ctx.graph.getHandler(`__listplan__${graphNode.id}`);
575
691
  const build = ctx.graph.getHandler(`__listbuild__${graphNode.id}`);
576
- if (build === void 0) return;
692
+ if (plan === void 0 && build === void 0) return;
577
693
  for (const stateRef of graphNode.stateRefs) {
578
694
  if (stateRef.propKey !== "items") continue;
579
695
  const sig = ctx.graph.getHandler(`__signal__${stateRef.signalId}`);
580
696
  if (sig === void 0 || typeof sig.subscribe !== "function") continue;
581
697
  const unsub = sig.subscribe((value) => {
582
- reconcileReactiveList(ctx, graphNode, instance, el, build(value));
698
+ if (plan !== void 0) {
699
+ reconcileReactiveListByPlan(ctx, graphNode, instance, el, plan(value));
700
+ } else {
701
+ reconcileReactiveList(ctx, graphNode, instance, el, build(value));
702
+ }
583
703
  });
584
704
  instance.trackCleanup(unsub);
585
705
  }
586
706
  }
707
+ function reconcileReactiveListByPlan(ctx, listNode, listInstance, listEl, plan) {
708
+ const oldInstances = [...listInstance.children];
709
+ const result = reconcileChildrenByPlan(
710
+ ctx,
711
+ listEl,
712
+ oldInstances,
713
+ plan,
714
+ (node, parent) => mountNode(ctx, node, parent)
715
+ );
716
+ listInstance.children.length = 0;
717
+ for (const inst of result.instances) listInstance.children.push(inst);
718
+ for (const removed of result.removed) {
719
+ forgetInstance(ctx, removed);
720
+ ctx.graph.detachNode(removed.graphNode);
721
+ }
722
+ const adopted = new Set(result.instances.map((i) => i.graphNode));
723
+ for (const node of result.built ?? []) {
724
+ if (!adopted.has(node)) ctx.graph.detachNode(node);
725
+ }
726
+ for (const child of [...listNode.children]) listNode.removeChild(child);
727
+ for (const inst of result.instances) listNode.appendChild(inst.graphNode);
728
+ }
587
729
  function reconcileReactiveList(ctx, listNode, listInstance, listEl, newNodes) {
588
730
  const oldInstances = [...listInstance.children];
589
731
  const result = reconcileChildren(
@@ -959,7 +1101,7 @@ function renderToString(compiled, options = {}) {
959
1101
  }
960
1102
 
961
1103
  // src/version.ts
962
- var VERSION = "1.0.0";
1104
+ var VERSION = "1.2.0";
963
1105
  // Annotate the CommonJS export names for ESM import in node:
964
1106
  0 && (module.exports = {
965
1107
  STATE_MARKER_ATTR,