creo 0.2.4 → 0.2.6

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/README.md CHANGED
@@ -336,8 +336,10 @@ bun test packages/creo/src/ # Run tests
336
336
  bun run build # Build all packages
337
337
  bun run typecheck # Type-check
338
338
 
339
- # Run examples:
340
- cd examples/todo && bun install && bun run dev
339
+ # Run the docs site (with the live recipe playground — simple-todo, advanced-todo, table, chess, etc.):
340
+ cd docs && bun install && bun run dev
341
+
342
+ # Run a standalone example:
341
343
  cd examples/router && bun install && bun run dev
342
344
 
343
345
  # Version management:
@@ -1,2 +1 @@
1
1
  export type Key = number | string;
2
- export declare function generateNextKey(): string;
package/dist/index.d.ts CHANGED
@@ -7,12 +7,12 @@ export { Store, store, isStore } from "./public/store";
7
7
  export { $primitive } from "./public/primitive";
8
8
  export type { PrimitiveProps, EventHandlerProps } from "./public/primitive";
9
9
  export { html, text, div, span, section, article, aside, nav, header, footer, main, address, hgroup, search, p, h1, h2, h3, h4, h5, h6, pre, code, em, strong, small, br, hr, a, blockquote, label, abbr, b, bdi, bdo, cite, data, dfn, i, kbd, mark, q, rp, rt, ruby, s, samp, sub, sup, time, u, varEl, wbr, del, ins, ul, ol, li, dl, dt, dd, table, thead, tbody, tfoot, tr, th, td, caption, colgroup, col, form, button, input, textarea, select, option, fieldset, legend, datalist, optgroup, output, progress, meter, img, video, audio, canvas, source, track, map, area, picture, iframe, embed, object, portal, svg, details, summary, dialog, menu, figure, figcaption, script, noscript, template, slot, } from "./public/primitives/primitives";
10
- export type { BaseEventData, PointerEventData, KeyEventData, InputEventData, FocusEventData, ContainerEvents, FormEvents, HtmlAttrs, } from "./public/primitives/primitives";
10
+ export type { BaseEventData, PointerEventData, KeyEventData, InputEventData, FocusEventData, MediaEventData, ScrollEventData, LoadEventData, ErrorEventData, ToggleEventData, ContainerEvents, FormEvents, MediaEvents, DisclosureEvents, HtmlAttrs, } from "./public/primitives/primitives";
11
11
  export type { IRender } from "./render/render_interface";
12
12
  export { HtmlRender } from "./render/html_render";
13
13
  export { JsonRender } from "./render/json_render";
14
14
  export type { JsonNode } from "./render/json_render";
15
- export { HtmlStringRender, StringRender } from "./render/string_render";
15
+ export { HtmlStringRender } from "./render/string_render";
16
16
  export { Engine, type Scheduler } from "./internal/engine";
17
17
  export { type Maybe, type None, type Just, just, withDefault, _ } from "./functional/maybe";
18
18
  export type { Key } from "./functional/key";
package/dist/index.js CHANGED
@@ -177,6 +177,7 @@ var area = html("area");
177
177
  class State {
178
178
  #current;
179
179
  #schedule;
180
+ #pending;
180
181
  constructor(initial, schedule) {
181
182
  this.#current = initial;
182
183
  this.#schedule = schedule;
@@ -185,30 +186,49 @@ class State {
185
186
  return this.#current;
186
187
  }
187
188
  set(value) {
189
+ this.#pending = null;
188
190
  this.#current = value;
189
191
  this.#schedule();
190
192
  }
191
193
  update(fn) {
192
- const result = fn(this.#current);
193
- if (result instanceof Promise) {
194
- result.then((value) => {
194
+ if (this.#pending) {
195
+ const next = this.#pending.then((v) => fn(v));
196
+ this.#pending = next;
197
+ next.then((value) => {
198
+ if (this.#pending !== next)
199
+ return;
200
+ this.#pending = null;
195
201
  this.#current = value;
196
202
  this.#schedule();
197
203
  });
198
- } else {
204
+ return;
205
+ }
206
+ const result = fn(this.#current);
207
+ if (!(result instanceof Promise)) {
199
208
  this.#current = result;
200
209
  this.#schedule();
210
+ return;
201
211
  }
212
+ const captured = result;
213
+ this.#pending = captured;
214
+ captured.then((value) => {
215
+ if (this.#pending !== captured)
216
+ return;
217
+ this.#pending = null;
218
+ this.#current = value;
219
+ this.#schedule();
220
+ });
202
221
  }
203
222
  }
204
223
 
205
224
  // src/public/store.ts
206
- var $store = Symbol("store");
225
+ var $store = Symbol.for("creo.store");
207
226
 
208
227
  class Store {
209
228
  [$store] = true;
210
229
  #current;
211
230
  #subscribers = new Set;
231
+ #pending;
212
232
  constructor(initial) {
213
233
  this.#current = initial;
214
234
  }
@@ -216,20 +236,38 @@ class Store {
216
236
  return this.#current;
217
237
  }
218
238
  set(value) {
239
+ this.#pending = null;
219
240
  this.#current = value;
220
241
  this.#notify();
221
242
  }
222
243
  update(fn) {
223
- const result = fn(this.#current);
224
- if (result instanceof Promise) {
225
- result.then((value) => {
244
+ if (this.#pending) {
245
+ const next = this.#pending.then((v) => fn(v));
246
+ this.#pending = next;
247
+ next.then((value) => {
248
+ if (this.#pending !== next)
249
+ return;
250
+ this.#pending = null;
226
251
  this.#current = value;
227
252
  this.#notify();
228
253
  });
229
- } else {
254
+ return;
255
+ }
256
+ const result = fn(this.#current);
257
+ if (!(result instanceof Promise)) {
230
258
  this.#current = result;
231
259
  this.#notify();
260
+ return;
232
261
  }
262
+ const captured = result;
263
+ this.#pending = captured;
264
+ captured.then((value) => {
265
+ if (this.#pending !== captured)
266
+ return;
267
+ this.#pending = null;
268
+ this.#current = value;
269
+ this.#notify();
270
+ });
233
271
  }
234
272
  subscribe(cb) {
235
273
  this.#subscribers.add(cb);
@@ -262,12 +300,15 @@ function shallowEqual(a2, b2) {
262
300
  let countA = 0;
263
301
  for (const key in a2) {
264
302
  countA++;
265
- if (!Object.is(a2[key], b2[key]))
303
+ if (a2[key] !== b2[key])
266
304
  return false;
267
305
  }
268
306
  let countB = 0;
269
- for (const _ in b2)
307
+ for (const _ in b2) {
270
308
  countB++;
309
+ if (countB > countA)
310
+ return false;
311
+ }
271
312
  return countA === countB;
272
313
  }
273
314
 
@@ -307,17 +348,6 @@ function lis(arr) {
307
348
  }
308
349
 
309
350
  // src/internal/engine.ts
310
- var STATEFUL_DOM_KEYS = ["value", "checked", "selected", "indeterminate", "muted"];
311
- function hasStatefulDomKey(props) {
312
- if (props == null || typeof props !== "object")
313
- return false;
314
- for (const k of STATEFUL_DOM_KEYS) {
315
- if (k in props)
316
- return true;
317
- }
318
- return false;
319
- }
320
-
321
351
  class Engine {
322
352
  renderer;
323
353
  #dirtyQueue = new Set;
@@ -345,11 +375,17 @@ class Engine {
345
375
  keyToView: null,
346
376
  unsubscribe: null,
347
377
  parent,
348
- scHost: null
378
+ scHost: null,
379
+ pos: -1
349
380
  };
350
381
  if (slot2) {
351
- const slotFn = typeof slot2 === "string" ? this.#stringSlot(slot2) : slot2;
352
- res.sc = this.#collect(slotFn, [], res);
382
+ if (typeof slot2 === "string") {
383
+ res.sc = [
384
+ this.newView(textViewFn, res, slot2, null, null)
385
+ ];
386
+ } else {
387
+ res.sc = this.#collect(slot2, [], res);
388
+ }
353
389
  }
354
390
  return res;
355
391
  }
@@ -448,11 +484,6 @@ class Engine {
448
484
  this.#collectFor = beforeParent;
449
485
  return collector;
450
486
  }
451
- #stringSlot(content) {
452
- return () => {
453
- this.view(textViewFn, content, null, null);
454
- };
455
- }
456
487
  nextProps(view2, nextProps, nextSlot, preCollectedSc) {
457
488
  const prevSc = view2.sc;
458
489
  view2.slot = nextSlot;
@@ -460,16 +491,19 @@ class Engine {
460
491
  for (const child of preCollectedSc)
461
492
  child.parent = view2;
462
493
  view2.sc = preCollectedSc;
463
- } else {
464
- if (nextSlot) {
465
- const slotFn = typeof nextSlot === "string" ? this.#stringSlot(nextSlot) : nextSlot;
466
- view2.sc = this.#collect(slotFn, [], view2);
494
+ } else if (nextSlot) {
495
+ if (typeof nextSlot === "string") {
496
+ view2.sc = [
497
+ this.newView(textViewFn, view2, nextSlot, null, null)
498
+ ];
467
499
  } else {
468
- view2.sc = null;
500
+ view2.sc = this.#collect(nextSlot, [], view2);
469
501
  }
502
+ } else {
503
+ view2.sc = null;
470
504
  }
471
505
  const structChanged = hasScStructuralChange(prevSc, view2.sc);
472
- const shouldUpdate = view2.body?.shouldUpdate ? view2.body.shouldUpdate(nextProps) : !shallowEqual(view2.props, nextProps) || (view2.flags & F_PRIMITIVE) !== 0 && hasStatefulDomKey(nextProps);
506
+ const shouldUpdate = view2.body?.shouldUpdate ? view2.body.shouldUpdate(nextProps) : !shallowEqual(view2.props, nextProps) || (view2.flags & F_PRIMITIVE) !== 0 && this.renderer.shouldReassert?.(view2, nextProps) === true;
473
507
  if (shouldUpdate || structChanged) {
474
508
  view2.props = nextProps;
475
509
  this.markDirty(view2);
@@ -521,7 +555,9 @@ class Engine {
521
555
  }
522
556
  if (view2.children == null) {
523
557
  view2.children = pendingChildren;
524
- for (const child of pendingChildren) {
558
+ for (let i2 = 0;i2 < pendingChildren.length; i2++) {
559
+ const child = pendingChildren[i2];
560
+ child.pos = i2;
525
561
  this.initViewBody(child);
526
562
  this.markDirty(child);
527
563
  if (child.userKey != null) {
@@ -547,9 +583,11 @@ class Engine {
547
583
  const old = oldChildren[i2];
548
584
  const pend = pending[i2];
549
585
  this.#patchOrReplace(view2, oldChildren, i2, old, pend);
586
+ oldChildren[i2].pos = i2;
550
587
  }
551
588
  for (let i2 = oldLen;i2 < newLen; i2++) {
552
589
  oldChildren[i2] = pending[i2];
590
+ pending[i2].pos = i2;
553
591
  this.initViewBody(pending[i2]);
554
592
  this.markDirty(pending[i2]);
555
593
  }
@@ -589,21 +627,46 @@ class Engine {
589
627
  view2.keyToView.set(pending[j].userKey, pending[j]);
590
628
  }
591
629
  }
592
- view2.children = [
593
- ...oldChildren.slice(0, i2),
594
- ...pending.slice(i2, newEnd + 1),
595
- ...oldChildren.slice(i2, oldEnd + 1)
596
- ];
630
+ const tailStart2 = oldEnd + 1;
631
+ const tailLen2 = oldChildren.length - tailStart2;
632
+ const insertCount = newEnd - i2 + 1;
633
+ const out2 = new Array(i2 + insertCount + tailLen2);
634
+ for (let j = 0;j < i2; j++) {
635
+ const c = oldChildren[j];
636
+ c.pos = j;
637
+ out2[j] = c;
638
+ }
639
+ for (let j = 0;j < insertCount; j++) {
640
+ const c = pending[i2 + j];
641
+ c.pos = i2 + j;
642
+ out2[i2 + j] = c;
643
+ }
644
+ for (let j = 0;j < tailLen2; j++) {
645
+ const c = oldChildren[tailStart2 + j];
646
+ c.pos = i2 + insertCount + j;
647
+ out2[i2 + insertCount + j] = c;
648
+ }
649
+ view2.children = out2;
597
650
  return;
598
651
  }
599
652
  if (i2 > newEnd) {
600
653
  for (let j = i2;j <= oldEnd; j++) {
601
654
  this.dispose(oldChildren[j]);
602
655
  }
603
- view2.children = [
604
- ...oldChildren.slice(0, i2),
605
- ...oldChildren.slice(oldEnd + 1)
606
- ];
656
+ const tailStart2 = oldEnd + 1;
657
+ const tailLen2 = oldChildren.length - tailStart2;
658
+ const out2 = new Array(i2 + tailLen2);
659
+ for (let j = 0;j < i2; j++) {
660
+ const c = oldChildren[j];
661
+ c.pos = j;
662
+ out2[j] = c;
663
+ }
664
+ for (let j = 0;j < tailLen2; j++) {
665
+ const c = oldChildren[tailStart2 + j];
666
+ c.pos = i2 + j;
667
+ out2[i2 + j] = c;
668
+ }
669
+ view2.children = out2;
607
670
  return;
608
671
  }
609
672
  const newKeyToIndex = new Map;
@@ -630,7 +693,14 @@ class Engine {
630
693
  }
631
694
  }
632
695
  const stable = lis(newIdxToOldIdx);
633
- const newChildren = new Array(middleLen);
696
+ const tailStart = oldEnd + 1;
697
+ const tailLen = oldChildren.length - tailStart;
698
+ const out = new Array(i2 + middleLen + tailLen);
699
+ for (let j = 0;j < i2; j++) {
700
+ const c = oldChildren[j];
701
+ c.pos = j;
702
+ out[j] = c;
703
+ }
634
704
  for (let j = middleLen - 1;j >= 0; j--) {
635
705
  const newIdx = i2 + j;
636
706
  const pendView = pending[newIdx];
@@ -642,19 +712,25 @@ class Engine {
642
712
  view2.keyToView = new Map;
643
713
  view2.keyToView.set(pendView.userKey, pendView);
644
714
  }
645
- newChildren[j] = pendView;
715
+ pendView.pos = i2 + j;
716
+ out[i2 + j] = pendView;
646
717
  } else {
647
718
  const oldView = oldChildren[newIdxToOldIdx[j]];
648
719
  this.#patchOrReplace(view2, oldChildren, newIdxToOldIdx[j], oldView, pendView);
649
720
  if (!stable.has(j)) {
650
721
  this.markMoved(oldView);
651
722
  }
652
- newChildren[j] = oldView;
723
+ const placed = oldChildren[newIdxToOldIdx[j]];
724
+ placed.pos = i2 + j;
725
+ out[i2 + j] = placed;
653
726
  }
654
727
  }
655
- const head = oldChildren.slice(0, i2);
656
- const tail = oldChildren.slice(oldEnd + 1);
657
- view2.children = [...head, ...newChildren, ...tail];
728
+ for (let j = 0;j < tailLen; j++) {
729
+ const c = oldChildren[tailStart + j];
730
+ c.pos = i2 + middleLen + j;
731
+ out[i2 + middleLen + j] = c;
732
+ }
733
+ view2.children = out;
658
734
  }
659
735
  #patchOrReplace(parent, oldChildren, idx, oldView, pendView) {
660
736
  if (oldView.viewFn === pendView.viewFn) {
@@ -777,7 +853,30 @@ var DOM_EVENT = {
777
853
  KeyDown: "keydown",
778
854
  KeyUp: "keyup",
779
855
  Focus: "focus",
780
- Blur: "blur"
856
+ Blur: "blur",
857
+ MouseEnter: "mouseenter",
858
+ MouseLeave: "mouseleave",
859
+ PointerEnter: "pointerenter",
860
+ PointerLeave: "pointerleave",
861
+ Scroll: "scroll",
862
+ Load: "load",
863
+ Error: "error",
864
+ Toggle: "toggle",
865
+ VolumeChange: "volumechange",
866
+ Play: "play",
867
+ Pause: "pause",
868
+ Ended: "ended",
869
+ TimeUpdate: "timeupdate",
870
+ LoadedMetadata: "loadedmetadata",
871
+ LoadedData: "loadeddata",
872
+ CanPlay: "canplay",
873
+ CanPlayThrough: "canplaythrough",
874
+ DurationChange: "durationchange",
875
+ RateChange: "ratechange",
876
+ Seeking: "seeking",
877
+ Seeked: "seeked",
878
+ Stalled: "stalled",
879
+ Waiting: "waiting"
781
880
  };
782
881
  var $EV = Symbol.for("creo.ev");
783
882
  var containerState = new WeakMap;
@@ -788,6 +887,7 @@ function getState(container) {
788
887
  counts: new Map,
789
888
  handler(e) {
790
889
  const domEvent = e.type;
890
+ const noWalk = NO_WALK_EVENTS.has(domEvent);
791
891
  let dom = e.target;
792
892
  while (dom && dom !== container) {
793
893
  const evObj = dom[$EV];
@@ -799,6 +899,8 @@ function getState(container) {
799
899
  return;
800
900
  }
801
901
  }
902
+ if (noWalk)
903
+ return;
802
904
  dom = dom.parentElement;
803
905
  }
804
906
  }
@@ -807,12 +909,52 @@ function getState(container) {
807
909
  }
808
910
  return state;
809
911
  }
810
- var CAPTURE_EVENTS = new Set(["focus", "blur"]);
912
+ var CAPTURE_EVENTS = new Set([
913
+ "focus",
914
+ "blur",
915
+ "mouseenter",
916
+ "mouseleave",
917
+ "pointerenter",
918
+ "pointerleave",
919
+ "scroll",
920
+ "load",
921
+ "error",
922
+ "toggle",
923
+ "volumechange",
924
+ "play",
925
+ "pause",
926
+ "ended",
927
+ "timeupdate",
928
+ "loadedmetadata",
929
+ "loadeddata",
930
+ "canplay",
931
+ "canplaythrough",
932
+ "durationchange",
933
+ "ratechange",
934
+ "seeking",
935
+ "seeked",
936
+ "stalled",
937
+ "waiting"
938
+ ]);
939
+ var NO_WALK_EVENTS = new Set([
940
+ "mouseenter",
941
+ "mouseleave",
942
+ "pointerenter",
943
+ "pointerleave"
944
+ ]);
945
+ var PASSIVE_EVENTS = new Set(["scroll"]);
946
+ function listenerOptions(domEvent) {
947
+ const capture = CAPTURE_EVENTS.has(domEvent);
948
+ if (PASSIVE_EVENTS.has(domEvent)) {
949
+ return { capture, passive: true };
950
+ }
951
+ return capture;
952
+ }
811
953
  function ensureDelegated(container, domEvent) {
812
954
  const state = getState(container);
813
955
  const count = state.counts.get(domEvent) ?? 0;
814
956
  if (count === 0) {
815
- container.addEventListener(domEvent, state.handler, CAPTURE_EVENTS.has(domEvent));
957
+ container.addEventListener(domEvent, state.handler, listenerOptions(domEvent));
816
958
  }
817
959
  state.counts.set(domEvent, count + 1);
818
960
  }
@@ -821,19 +963,68 @@ function removeDelegated(container, domEvent) {
821
963
  const count = state.counts.get(domEvent) ?? 0;
822
964
  if (count <= 1) {
823
965
  state.counts.delete(domEvent);
824
- container.removeEventListener(domEvent, state.handler, CAPTURE_EVENTS.has(domEvent));
966
+ container.removeEventListener(domEvent, state.handler, listenerOptions(domEvent));
825
967
  } else {
826
968
  state.counts.set(domEvent, count - 1);
827
969
  }
828
970
  }
971
+ var POINTER_EVENTS = new Set([
972
+ "click",
973
+ "dblclick",
974
+ "pointerdown",
975
+ "pointerup",
976
+ "pointermove",
977
+ "mouseenter",
978
+ "mouseleave",
979
+ "pointerenter",
980
+ "pointerleave"
981
+ ]);
982
+ var MEDIA_EVENTS = new Set([
983
+ "volumechange",
984
+ "play",
985
+ "pause",
986
+ "ended",
987
+ "timeupdate",
988
+ "loadedmetadata",
989
+ "loadeddata",
990
+ "canplay",
991
+ "canplaythrough",
992
+ "durationchange",
993
+ "ratechange",
994
+ "seeking",
995
+ "seeked",
996
+ "stalled",
997
+ "waiting"
998
+ ]);
829
999
  function mapEventData(domEvent, e) {
830
1000
  let data2;
831
- if (domEvent === "click" || domEvent === "dblclick" || domEvent === "pointerdown" || domEvent === "pointerup" || domEvent === "pointermove") {
1001
+ if (POINTER_EVENTS.has(domEvent)) {
832
1002
  const pe = e;
833
1003
  data2 = { x: pe.clientX, y: pe.clientY };
834
1004
  } else if (domEvent === "input" || domEvent === "change") {
835
1005
  const target = e.target;
836
1006
  data2 = { value: target.value, checked: !!target.checked };
1007
+ } else if (MEDIA_EVENTS.has(domEvent)) {
1008
+ const target = e.target;
1009
+ data2 = {
1010
+ muted: !!target.muted,
1011
+ paused: !!target.paused,
1012
+ volume: target.volume,
1013
+ currentTime: target.currentTime,
1014
+ duration: Number.isFinite(target.duration) ? target.duration : 0
1015
+ };
1016
+ } else if (domEvent === "scroll") {
1017
+ const target = e.target;
1018
+ data2 = {
1019
+ scrollTop: target.scrollTop ?? 0,
1020
+ scrollLeft: target.scrollLeft ?? 0
1021
+ };
1022
+ } else if (domEvent === "error") {
1023
+ const ev = e;
1024
+ data2 = { message: ev.message ?? "" };
1025
+ } else if (domEvent === "toggle") {
1026
+ const target = e.target;
1027
+ data2 = { open: !!target.open };
837
1028
  } else if (domEvent === "keydown" || domEvent === "keyup") {
838
1029
  const ke = e;
839
1030
  data2 = { key: ke.key, code: ke.code };
@@ -877,6 +1068,7 @@ class HtmlRender {
877
1068
  const domRef = { element, prevProps: null };
878
1069
  view2.renderRef = domRef;
879
1070
  this.setAttributes(element, props);
1071
+ domRef.prevProps = props;
880
1072
  if (view2.children?.length === 1) {
881
1073
  const child = view2.children[0];
882
1074
  if (child.flags & F_PRIMITIVE && child.viewFn[$primitive] === "text") {
@@ -886,6 +1078,9 @@ class HtmlRender {
886
1078
  }
887
1079
  }
888
1080
  parentNode.insertBefore(element, refNode);
1081
+ if (props != null && props.autofocus === true && typeof element.focus === "function") {
1082
+ element.focus();
1083
+ }
889
1084
  }
890
1085
  } else {
891
1086
  view2.renderRef = true;
@@ -935,6 +1130,28 @@ class HtmlRender {
935
1130
  }
936
1131
  view2.renderRef = undefined;
937
1132
  }
1133
+ shouldReassert(view2, nextProps) {
1134
+ if (nextProps == null || typeof nextProps !== "object")
1135
+ return false;
1136
+ const ref = view2.renderRef;
1137
+ if (!ref || ref.element instanceof Text)
1138
+ return false;
1139
+ const el = ref.element;
1140
+ const props = nextProps;
1141
+ for (const key of DOM_PROPERTIES) {
1142
+ if (!(key in props))
1143
+ continue;
1144
+ const live = el[key];
1145
+ const next = props[key];
1146
+ if (typeof next === "boolean" || typeof live === "boolean") {
1147
+ if (Boolean(live) !== Boolean(next))
1148
+ return true;
1149
+ } else if (String(live) !== String(next)) {
1150
+ return true;
1151
+ }
1152
+ }
1153
+ return false;
1154
+ }
938
1155
  findParentDom(view2) {
939
1156
  let parent = view2.parent;
940
1157
  while (parent) {
@@ -955,7 +1172,9 @@ class HtmlRender {
955
1172
  if (children[children.length - 1] === view2) {
956
1173
  return this.#parentEndAnchor(parent);
957
1174
  }
958
- const idx = children.indexOf(view2);
1175
+ let idx = view2.pos;
1176
+ if (idx < 0 || children[idx] !== view2)
1177
+ idx = children.indexOf(view2);
959
1178
  for (let i2 = idx + 1;i2 < children.length; i2++) {
960
1179
  const dom = this.getFirstDomNode(children[i2]);
961
1180
  if (dom)
@@ -1002,7 +1221,7 @@ class HtmlRender {
1002
1221
  const creoName = key.slice(2);
1003
1222
  const domEvent = DOM_EVENT[creoName] ?? creoName.toLowerCase();
1004
1223
  const evObj = element[$EV];
1005
- if (evObj) {
1224
+ if (evObj && domEvent in evObj) {
1006
1225
  evObj[domEvent] = value;
1007
1226
  } else {
1008
1227
  this.bindEvent(element, key, value);
@@ -1115,7 +1334,7 @@ class JsonRender {
1115
1334
  }
1116
1335
  const parentNode = view2.parent.renderRef;
1117
1336
  if (parentNode) {
1118
- const idx = view2.parent.children ? view2.parent.children.indexOf(view2) : -1;
1337
+ const idx = view2.pos;
1119
1338
  if (idx >= 0 && idx < parentNode.children.length) {
1120
1339
  parentNode.children.splice(idx, 0, node);
1121
1340
  } else {
@@ -1127,11 +1346,13 @@ class JsonRender {
1127
1346
  if (view2.parent) {
1128
1347
  const parentNode = view2.parent.renderRef;
1129
1348
  if (parentNode) {
1130
- const oldIdx = parentNode.children.indexOf(existing);
1131
- const targetIdx = view2.parent.children ? view2.parent.children.indexOf(view2) : -1;
1132
- if (oldIdx !== -1 && targetIdx !== -1 && oldIdx !== targetIdx) {
1133
- parentNode.children.splice(oldIdx, 1);
1134
- parentNode.children.splice(Math.min(targetIdx, parentNode.children.length), 0, existing);
1349
+ const targetIdx = view2.pos;
1350
+ if (targetIdx >= 0 && parentNode.children[targetIdx] !== existing) {
1351
+ const oldIdx = parentNode.children.indexOf(existing);
1352
+ if (oldIdx !== -1) {
1353
+ parentNode.children.splice(oldIdx, 1);
1354
+ parentNode.children.splice(Math.min(targetIdx, parentNode.children.length), 0, existing);
1355
+ }
1135
1356
  }
1136
1357
  }
1137
1358
  }
@@ -1253,7 +1474,6 @@ class HtmlStringRender {
1253
1474
  return result;
1254
1475
  }
1255
1476
  }
1256
- var StringRender = HtmlStringRender;
1257
1477
  // src/functional/maybe.ts
1258
1478
  function just(maybe, errorMessage) {
1259
1479
  if (maybe == null) {
@@ -1389,7 +1609,6 @@ export {
1389
1609
  abbr,
1390
1610
  a,
1391
1611
  _,
1392
- StringRender,
1393
1612
  Store,
1394
1613
  State,
1395
1614
  JsonRender,
@@ -1399,4 +1618,4 @@ export {
1399
1618
  $primitive
1400
1619
  };
1401
1620
 
1402
- //# debugId=E2DD104085BAD69A64756E2164756E21
1621
+ //# debugId=403015234A66157064756E2164756E21