@estjs/template 0.0.15-beta.9 → 0.0.15

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.
@@ -39,6 +39,108 @@ var __async = (__this, __arguments, generator) => {
39
39
  step((generator = generator.apply(__this, __arguments)).next());
40
40
  });
41
41
  };
42
+ var LIFECYCLE = {
43
+ mount: "mount",
44
+ destroy: "destroy",
45
+ update: "update"
46
+ };
47
+ function registerScopedHook(scope, listKey, hook) {
48
+ let hookList = scope[listKey];
49
+ if (!hookList) {
50
+ hookList = scope[listKey] = [];
51
+ }
52
+ if (!hookList.includes(hook)) {
53
+ hookList.push(hook);
54
+ }
55
+ }
56
+ function executeHooks(hooks, scopeId2, phase) {
57
+ const len = hooks.length;
58
+ if (len === 0) return;
59
+ let pending;
60
+ for (let i = 0; i < len; i++) {
61
+ try {
62
+ const result = hooks[i]();
63
+ if (shared.isPromise(result)) {
64
+ const safePromise = result.catch((error_) => {
65
+ if (true) {
66
+ shared.error(`Scope(${scopeId2}): Async ${phase} hook rejected:`, error_);
67
+ }
68
+ });
69
+ (pending != null ? pending : pending = []).push(safePromise);
70
+ }
71
+ } catch (error_) {
72
+ {
73
+ shared.error(`Scope(${scopeId2}): Error in ${phase} hook:`, error_);
74
+ }
75
+ }
76
+ }
77
+ if (!pending) return;
78
+ return Promise.all(pending).then(() => void 0);
79
+ }
80
+ function onMount(hook) {
81
+ const scope = getActiveScope();
82
+ if (!scope) {
83
+ shared.error("onMount() must be called within a scope");
84
+ return;
85
+ }
86
+ if (scope.isMounted) {
87
+ try {
88
+ const result = hook();
89
+ if (shared.isPromise(result)) {
90
+ result.catch((error_) => {
91
+ if (true) shared.error(`Scope(${scope.id}): Async ${LIFECYCLE.mount} hook rejected:`, error_);
92
+ });
93
+ }
94
+ } catch (error_) {
95
+ shared.error(`Scope(${scope.id}): Error in ${LIFECYCLE.mount} hook:`, error_);
96
+ }
97
+ return;
98
+ }
99
+ registerScopedHook(scope, "onMount", hook);
100
+ }
101
+ function onUpdate(hook) {
102
+ const scope = getActiveScope();
103
+ if (!scope) {
104
+ shared.error("onUpdate() must be called within a scope");
105
+ return;
106
+ }
107
+ registerScopedHook(scope, "onUpdate", hook);
108
+ }
109
+ function onDestroy(hook) {
110
+ const scope = getActiveScope();
111
+ if (!scope) {
112
+ shared.error("onDestroy() must be called within a scope");
113
+ return;
114
+ }
115
+ registerScopedHook(scope, "onDestroy", hook);
116
+ }
117
+ function triggerMountHooks(scope) {
118
+ var _a2;
119
+ if (scope.isDestroyed || !((_a2 = scope.onMount) == null ? void 0 : _a2.length)) {
120
+ scope.isMounted = true;
121
+ return;
122
+ }
123
+ const mountHooks = scope.onMount;
124
+ const result = runWithScope(scope, () => executeHooks(mountHooks, scope.id, LIFECYCLE.mount));
125
+ mountHooks.length = 0;
126
+ scope.isMounted = true;
127
+ return result;
128
+ }
129
+ function triggerUpdateHooks(scope) {
130
+ var _a2;
131
+ if (scope.isDestroyed || !((_a2 = scope.onUpdate) == null ? void 0 : _a2.length)) return;
132
+ const updateHooks = scope.onUpdate;
133
+ const result = runWithScope(scope, () => executeHooks(updateHooks, scope.id, "update"));
134
+ updateHooks.length = 0;
135
+ return result;
136
+ }
137
+ function triggerDestroyHooks(scope) {
138
+ var _a2;
139
+ if (scope.isDestroyed || !((_a2 = scope.onDestroy) == null ? void 0 : _a2.length)) return;
140
+ return runWithScope(scope, () => executeHooks(scope.onDestroy, scope.id, "destroy"));
141
+ }
142
+
143
+ // src/scope.ts
42
144
  var activeScope = null;
43
145
  var scopeId = 0;
44
146
  function getActiveScope() {
@@ -52,25 +154,19 @@ function createScope(parent = activeScope) {
52
154
  id: ++scopeId,
53
155
  parent,
54
156
  children: null,
55
- // Lazy initialized
56
157
  provides: null,
57
- // Lazy initialized
58
158
  cleanup: null,
59
- // Lazy initialized
60
159
  onMount: null,
61
- // Lazy initialized
62
160
  onUpdate: null,
63
- // Lazy initialized
64
161
  onDestroy: null,
65
- // Lazy initialized
66
162
  isMounted: false,
67
163
  isDestroyed: false
68
164
  };
69
165
  if (parent) {
70
166
  if (!parent.children) {
71
- parent.children = /* @__PURE__ */ new Set();
167
+ parent.children = [];
72
168
  }
73
- parent.children.add(scope);
169
+ parent.children.push(scope);
74
170
  }
75
171
  return scope;
76
172
  }
@@ -84,31 +180,22 @@ function runWithScope(scope, fn) {
84
180
  }
85
181
  }
86
182
  function disposeScope(scope) {
87
- var _a2, _b, _c, _d, _e;
183
+ var _a2, _b, _c;
88
184
  if (!scope || scope.isDestroyed) {
89
185
  return;
90
186
  }
187
+ const parentScope = scope.parent;
91
188
  if (scope.children) {
92
- while (scope.children.size > 0) {
93
- const child = scope.children.values().next().value;
94
- if (child) {
95
- disposeScope(child);
96
- }
189
+ for (const child of scope.children) {
190
+ disposeScope(child);
97
191
  }
192
+ scope.children.length = 0;
98
193
  }
99
- if (scope.onDestroy) {
100
- for (const hook of scope.onDestroy) {
101
- try {
102
- hook();
103
- } catch (error_) {
104
- {
105
- shared.error(`Scope(${scope.id}): Error in destroy hook:`, error_);
106
- }
107
- }
108
- }
109
- scope.onDestroy.clear();
194
+ if ((_a2 = scope.onDestroy) == null ? void 0 : _a2.length) {
195
+ triggerDestroyHooks(scope);
196
+ scope.onDestroy.length = 0;
110
197
  }
111
- if (scope.cleanup) {
198
+ if ((_b = scope.cleanup) == null ? void 0 : _b.length) {
112
199
  for (const fn of scope.cleanup) {
113
200
  try {
114
201
  fn();
@@ -118,18 +205,22 @@ function disposeScope(scope) {
118
205
  }
119
206
  }
120
207
  }
121
- scope.cleanup.clear();
208
+ scope.cleanup.length = 0;
122
209
  }
123
- if ((_a2 = scope.parent) == null ? void 0 : _a2.children) {
124
- scope.parent.children.delete(scope);
210
+ if (parentScope == null ? void 0 : parentScope.children) {
211
+ const idx = parentScope.children.indexOf(scope);
212
+ if (idx !== -1) {
213
+ parentScope.children.splice(idx, 1);
214
+ }
125
215
  }
126
- (_b = scope.children) == null ? void 0 : _b.clear();
127
216
  (_c = scope.provides) == null ? void 0 : _c.clear();
128
- (_d = scope.onMount) == null ? void 0 : _d.clear();
129
- (_e = scope.onUpdate) == null ? void 0 : _e.clear();
130
- setActiveScope(scope.parent);
217
+ if (scope.onMount) scope.onMount.length = 0;
218
+ if (scope.onUpdate) scope.onUpdate.length = 0;
131
219
  scope.parent = null;
132
220
  scope.isDestroyed = true;
221
+ if (activeScope === scope) {
222
+ activeScope = parentScope;
223
+ }
133
224
  }
134
225
  function onCleanup(fn) {
135
226
  const scope = activeScope;
@@ -140,9 +231,9 @@ function onCleanup(fn) {
140
231
  return;
141
232
  }
142
233
  if (!scope.cleanup) {
143
- scope.cleanup = /* @__PURE__ */ new Set();
234
+ scope.cleanup = [];
144
235
  }
145
- scope.cleanup.add(fn);
236
+ scope.cleanup.push(fn);
146
237
  }
147
238
 
148
239
  // src/constants.ts
@@ -153,6 +244,11 @@ var KEY_PROP = "key";
153
244
  var SVG_NAMESPACE = "http://www.w3.org/2000/svg";
154
245
  var XLINK_NAMESPACE = "http://www.w3.org/2000/xlink";
155
246
  var XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/";
247
+ var NORMAL_COMPONENT = /* @__PURE__ */ Symbol("Normal Component" );
248
+ var FRAGMENT_COMPONENT = /* @__PURE__ */ Symbol("Fragment Component" );
249
+ var PORTAL_COMPONENT = /* @__PURE__ */ Symbol("Portal Component" );
250
+ var SUSPENSE_COMPONENT = /* @__PURE__ */ Symbol("Suspense Component" );
251
+ var FOR_COMPONENT = /* @__PURE__ */ Symbol("For Component" );
156
252
  var MAX_KEY_LENGTH = 1e3;
157
253
  var componentKeyPrefixCache = /* @__PURE__ */ new WeakMap();
158
254
  function getComponentKey(type) {
@@ -275,62 +371,51 @@ function isSameNode(a, b) {
275
371
  }
276
372
  function shallowCompare(a, b) {
277
373
  if (a === b) return true;
278
- if (!a || !b) return false;
279
- if (Array.isArray(a) !== Array.isArray(b)) return false;
280
- for (const key in a) {
281
- if (a[key] !== b[key]) return false;
282
- }
283
- for (const key in b) {
284
- if (!(key in a)) return false;
374
+ if (shared.isNull(a) || shared.isNull(b)) return false;
375
+ if (!shared.isObject(a) || !shared.isObject(b)) return false;
376
+ if (shared.isArray(a) !== shared.isArray(b)) return false;
377
+ const aRecord = a;
378
+ const bRecord = b;
379
+ const aKeys = Object.keys(aRecord);
380
+ const bKeys = Object.keys(bRecord);
381
+ if (aKeys.length !== bKeys.length) return false;
382
+ for (const key of aKeys) {
383
+ if (!(key in bRecord) || aRecord[key] !== bRecord[key]) {
384
+ return false;
385
+ }
285
386
  }
286
387
  return true;
287
388
  }
288
389
  function removeNode(node) {
289
390
  if (!node) return;
290
- try {
291
- if (isComponent(node)) {
292
- node.destroy();
293
- } else {
294
- const element = node;
295
- if (element.parentElement) {
296
- element.remove();
297
- }
298
- }
299
- } catch (_error) {
300
- shared.error("Failed to remove node:", _error);
391
+ if (isComponent(node)) {
392
+ node.destroy();
393
+ return;
394
+ }
395
+ const element = node;
396
+ if (element.parentElement) {
397
+ element.remove();
301
398
  }
302
399
  }
303
400
  function insertNode(parent, child, before) {
304
401
  if (!parent || !child) return;
305
- try {
306
- const beforeNode = isComponent(before) ? before.firstChild : before;
307
- if (isComponent(child)) {
308
- child.mount(parent, beforeNode);
309
- return;
310
- }
311
- if (beforeNode) {
312
- parent.insertBefore(child, beforeNode);
313
- } else {
314
- if (true) {
315
- if (!child) {
316
- shared.error("insertNode: child is not a Node", child);
317
- }
318
- }
319
- parent.appendChild(child);
320
- }
321
- } catch (_error) {
322
- shared.error("Failed to insert node:", _error);
402
+ if (isComponent(child)) {
403
+ const beforeNode2 = isComponent(before) ? before.firstChild : before;
404
+ child.mount(parent, beforeNode2);
405
+ return;
406
+ }
407
+ const beforeNode = isComponent(before) ? before.firstChild : before;
408
+ if (beforeNode) {
409
+ parent.insertBefore(child, beforeNode);
410
+ } else {
411
+ parent.appendChild(child);
323
412
  }
324
413
  }
325
414
  function replaceNode(parent, newNode, oldNode) {
326
415
  if (!parent || !newNode || !oldNode || newNode === oldNode) return;
327
- try {
328
- const beforeNode = isComponent(oldNode) ? oldNode.beforeNode : oldNode.nextSibling;
329
- removeNode(oldNode);
330
- insertNode(parent, newNode, beforeNode);
331
- } catch (_error) {
332
- shared.error("Failed to replace node:", _error);
333
- }
416
+ const beforeNode = isComponent(oldNode) ? oldNode.beforeNode : oldNode.nextSibling;
417
+ removeNode(oldNode);
418
+ insertNode(parent, newNode, beforeNode);
334
419
  }
335
420
  function getFirstDOMNode(node) {
336
421
  if (!node) {
@@ -641,18 +726,6 @@ function getSequence(arr) {
641
726
  return result;
642
727
  }
643
728
 
644
- // src/utils/shared.ts
645
- var isHydrationActive = false;
646
- function startHydration() {
647
- isHydrationActive = true;
648
- }
649
- function endHydration() {
650
- isHydrationActive = false;
651
- }
652
- function isHydrating() {
653
- return isHydrationActive;
654
- }
655
-
656
729
  // src/binding.ts
657
730
  function addEventListener(element, event, handler, options) {
658
731
  element.addEventListener(event, handler, options);
@@ -720,28 +793,21 @@ function bindSelectElement(node, setter) {
720
793
  }
721
794
  });
722
795
  }
723
- var isFirstRun = true;
724
- function executeReactiveUpdate(ownerScope, parent, nodeFactory, before, renderedNodes) {
725
- const executeUpdate = () => {
726
- const rawNodes = shared.isFunction(nodeFactory) ? nodeFactory() : nodeFactory;
727
- const nodes = shared.coerceArray(rawNodes).map((item) => shared.isFunction(item) ? item() : item).flatMap((i) => i).map(normalizeNode);
728
- if (isFirstRun && isHydrating()) {
729
- isFirstRun = false;
730
- return renderedNodes;
731
- }
732
- return patchChildren(parent, renderedNodes, nodes, before);
733
- };
734
- if (ownerScope && !ownerScope.isDestroyed) {
735
- return runWithScope(ownerScope, executeUpdate);
736
- }
737
- return executeUpdate();
738
- }
739
796
  function insert(parent, nodeFactory, before) {
740
797
  if (!parent) return;
741
- const ownerScope = getActiveScope();
742
798
  let renderedNodes = [];
799
+ const currentScope = getActiveScope();
743
800
  const cleanup = signals.effect(() => {
744
- renderedNodes = executeReactiveUpdate(ownerScope, parent, nodeFactory, before, renderedNodes);
801
+ const run = () => {
802
+ const rawNodes = shared.isFunction(nodeFactory) ? nodeFactory() : nodeFactory;
803
+ const nodes = shared.coerceArray(rawNodes).map((item) => shared.isFunction(item) ? item() : item).flatMap(normalizeNode);
804
+ renderedNodes = patchChildren(parent, renderedNodes, nodes, before);
805
+ };
806
+ if (currentScope) {
807
+ runWithScope(currentScope, run);
808
+ } else {
809
+ run();
810
+ }
745
811
  });
746
812
  onCleanup(() => {
747
813
  cleanup();
@@ -774,127 +840,40 @@ function mapNodes(template2, indexes) {
774
840
  walk(template2);
775
841
  return tree;
776
842
  }
777
- function registerMountHook(hook) {
778
- const scope = getActiveScope();
779
- if (!scope) {
780
- {
781
- shared.error("onMount() must be called within a scope");
782
- }
783
- return;
784
- }
785
- if (scope.isMounted) {
786
- try {
787
- hook();
788
- } catch (error_) {
789
- {
790
- shared.error(`Scope(${scope.id}): Error in mount hook:`, error_);
791
- }
792
- }
793
- return;
794
- }
795
- if (!scope.onMount) {
796
- scope.onMount = /* @__PURE__ */ new Set();
797
- }
798
- scope.onMount.add(hook);
799
- }
800
- function registerUpdateHook(hook) {
801
- const scope = getActiveScope();
802
- if (!scope) {
803
- {
804
- shared.error("onUpdate() must be called within a scope");
805
- }
806
- return;
807
- }
808
- if (!scope.onUpdate) {
809
- scope.onUpdate = /* @__PURE__ */ new Set();
810
- }
811
- scope.onUpdate.add(hook);
812
- }
813
- function registerDestroyHook(hook) {
814
- const scope = getActiveScope();
815
- if (!scope) {
816
- {
817
- shared.error("onDestroy() must be called within a scope");
818
- }
819
- return;
820
- }
821
- if (!scope.onDestroy) {
822
- scope.onDestroy = /* @__PURE__ */ new Set();
823
- }
824
- scope.onDestroy.add(hook);
825
- }
826
- function triggerMountHooks(scope) {
827
- if (!scope || scope.isDestroyed || scope.isMounted) {
828
- return;
829
- }
830
- scope.isMounted = true;
831
- if (scope.onMount) {
832
- runWithScope(scope, () => {
833
- for (const hook of scope.onMount) {
834
- try {
835
- hook();
836
- } catch (error_) {
837
- if (true) {
838
- shared.error(`Scope(${scope.id}): Error in mount hook:`, error_);
839
- }
840
- }
841
- }
842
- });
843
- }
844
- }
845
- function triggerUpdateHooks(scope) {
846
- if (!scope || scope.isDestroyed) {
847
- return;
848
- }
849
- if (scope.onUpdate) {
850
- for (const hook of scope.onUpdate) {
851
- try {
852
- hook();
853
- } catch (error_) {
854
- {
855
- shared.error(`Scope(${scope.id}): Error in update hook:`, error_);
856
- }
857
- }
858
- }
859
- }
860
- }
861
- function onMount(hook) {
862
- registerMountHook(hook);
863
- }
864
- function onDestroy(hook) {
865
- registerDestroyHook(hook);
866
- }
867
- function onUpdate(hook) {
868
- registerUpdateHook(hook);
869
- }
870
843
 
871
844
  // src/component.ts
872
845
  var _a;
873
- _a = "normal" /* NORMAL */;
846
+ _a = NORMAL_COMPONENT;
874
847
  var Component = class {
875
848
  constructor(component, props = {}) {
876
849
  this.component = component;
877
850
  this.props = props;
878
- // component rendered nodes (supports arrays and fragments)
851
+ // Component rendered nodes (supports arrays and fragments)
879
852
  this.renderedNodes = [];
880
- // component scope (unified context management)
853
+ // Component scope (unified context management)
881
854
  this.scope = null;
882
- // component parent node
855
+ // Component parent node
883
856
  this.parentNode = void 0;
884
- // component before node
857
+ // Component before node
885
858
  this.beforeNode = void 0;
886
- // component reactive props
859
+ // Component props (reactive and snapshot)
887
860
  this.reactiveProps = {};
888
- // component state
861
+ this._propSnapshots = {};
862
+ // Component lifecycle state
889
863
  this.state = 0 /* INITIAL */;
890
- // parent scope captured at construction time
864
+ // Parent scope captured at construction time for correct hierarchy
891
865
  this.parentScope = null;
892
- // component type
893
866
  // @ts-ignore
894
867
  this[_a] = true;
895
868
  this.key = props.key ? normalizeKey(props.key) : getComponentKey(component);
896
- this.reactiveProps = signals.shallowReactive(__spreadValues({}, props || {}));
869
+ this.reactiveProps = signals.shallowReactive(__spreadValues({}, props));
897
870
  this.parentScope = getActiveScope();
871
+ for (const key in props) {
872
+ const val = props[key];
873
+ if (shared.isObject(val)) {
874
+ this._propSnapshots[key] = shared.isArray(val) ? [...val] : __spreadValues({}, val);
875
+ }
876
+ }
898
877
  }
899
878
  get isConnected() {
900
879
  return this.state === 2 /* MOUNTED */;
@@ -902,14 +881,12 @@ var Component = class {
902
881
  get firstChild() {
903
882
  for (const node of this.renderedNodes) {
904
883
  const dom = getFirstDOMNode(node);
905
- if (dom) {
906
- return dom;
907
- }
884
+ if (dom) return dom;
908
885
  }
909
886
  return void 0;
910
887
  }
911
888
  mount(parentNode, beforeNode) {
912
- var _a2;
889
+ var _a2, _b;
913
890
  this.parentNode = parentNode;
914
891
  this.beforeNode = beforeNode;
915
892
  this.state = 1 /* MOUNTING */;
@@ -920,28 +897,21 @@ var Component = class {
920
897
  this.state = 2 /* MOUNTED */;
921
898
  return this.renderedNodes;
922
899
  }
923
- const parent = (_a2 = this.parentScope) != null ? _a2 : getActiveScope();
924
- this.scope = createScope(parent);
925
- const renderedNodes = runWithScope(this.scope, () => {
926
- var _a3;
927
- let result = this.component(this.reactiveProps);
928
- if (shared.isFunction(result)) {
929
- result = result(this.reactiveProps);
930
- }
931
- if (signals.isSignal(result) || signals.isComputed(result)) {
932
- result = result.value;
933
- }
934
- const nodes = (_a3 = insert(parentNode, result, beforeNode)) != null ? _a3 : [];
935
- return nodes;
936
- });
900
+ const parentScope = (_a2 = this.parentScope) != null ? _a2 : getActiveScope();
901
+ this.scope = createScope(parentScope);
902
+ setActiveScope(this.scope);
903
+ let result = this.component(this.reactiveProps);
904
+ if (shared.isFunction(result)) {
905
+ result = result(this.reactiveProps);
906
+ }
907
+ if (signals.isSignal(result) || signals.isComputed(result)) {
908
+ result = result.value;
909
+ }
910
+ const renderedNodes = (_b = insert(parentNode, result, beforeNode)) != null ? _b : [];
937
911
  this.renderedNodes = renderedNodes;
938
- runWithScope(this.scope, () => {
939
- this.applyProps(this.props || {});
940
- });
912
+ this.applyProps(this.props);
941
913
  this.state = 2 /* MOUNTED */;
942
- if (this.scope) {
943
- triggerMountHooks(this.scope);
944
- }
914
+ triggerMountHooks(this.scope);
945
915
  return this.renderedNodes;
946
916
  }
947
917
  update(prevNode) {
@@ -956,91 +926,106 @@ var Component = class {
956
926
  this.renderedNodes = prevNode.renderedNodes;
957
927
  this.state = prevNode.state;
958
928
  this.reactiveProps = prevNode.reactiveProps;
959
- if (!this.props || Object.keys(this.props).length === 0) {
960
- if (!this.isConnected && this.parentNode) {
961
- this.mount(this.parentNode, this.beforeNode);
962
- return this;
963
- }
964
- if (this.scope) {
965
- runWithScope(this.scope, () => {
966
- this.applyProps(this.props || {});
967
- });
968
- triggerUpdateHooks(this.scope);
969
- }
929
+ this._propSnapshots = prevNode._propSnapshots;
930
+ this._updateReactiveProps(this.props);
931
+ if (!this.isConnected && this.parentNode) {
932
+ this.mount(this.parentNode, this.beforeNode);
970
933
  return this;
971
934
  }
972
- let hasChanges = false;
973
- for (const key in this.props) {
935
+ if (this.scope) {
936
+ setActiveScope(this.scope);
937
+ this.applyProps(this.props);
938
+ triggerUpdateHooks(this.scope);
939
+ }
940
+ return this;
941
+ }
942
+ /**
943
+ * Update reactive props by comparing with current values
944
+ */
945
+ _updateReactiveProps(props) {
946
+ for (const key in props) {
974
947
  if (key === "key") continue;
975
- const newValue = this.props[key];
948
+ const newValue = props[key];
976
949
  const oldValue = this.reactiveProps[key];
977
- if (Object.is(oldValue, newValue)) {
978
- continue;
979
- }
980
- if (shared.isObject(oldValue) && shared.isObject(newValue)) {
981
- if (shallowCompare(oldValue, newValue)) {
982
- continue;
950
+ if (newValue === oldValue && !this._propSnapshots[key]) continue;
951
+ const isNewValueObject = shared.isObject(newValue);
952
+ if (isNewValueObject) {
953
+ const snapshot = this._propSnapshots[key];
954
+ if (snapshot && shallowCompare(newValue, snapshot)) continue;
955
+ const newSnapshot = shared.isArray(newValue) ? [...newValue] : __spreadValues({}, newValue);
956
+ this.reactiveProps[key] = newSnapshot;
957
+ this._propSnapshots[key] = newSnapshot;
958
+ } else {
959
+ if (shared.hasChanged(newValue, oldValue)) {
960
+ this.reactiveProps[key] = newValue;
961
+ if (this._propSnapshots[key]) {
962
+ delete this._propSnapshots[key];
963
+ }
983
964
  }
984
965
  }
985
- this.reactiveProps[key] = newValue;
986
- hasChanges = true;
987
966
  }
988
- if (!this.isConnected && this.parentNode) {
989
- this.mount(this.parentNode, this.beforeNode);
967
+ }
968
+ unwrapRenderResult(result) {
969
+ if (shared.isFunction(result)) {
970
+ result = result(this.reactiveProps);
971
+ }
972
+ if (signals.isSignal(result) || signals.isComputed(result)) {
973
+ result = result.value;
974
+ }
975
+ if (isComponent(result)) {
976
+ result = result.mount(this.parentNode, this.beforeNode);
977
+ }
978
+ if (shared.isPromise(result)) {
979
+ result = result.then((r) => this.unwrapRenderResult(r));
990
980
  }
991
- if (this.scope && (hasChanges || !this.isConnected)) {
981
+ return result;
982
+ }
983
+ forceUpdate() {
984
+ if (this.state === 5 /* DESTROYED */ || !this.parentNode || !this.scope) {
985
+ return;
986
+ }
987
+ const originalNodes = [...this.renderedNodes];
988
+ try {
992
989
  runWithScope(this.scope, () => {
993
- this.applyProps(this.props || {});
990
+ let result = this.component(this.reactiveProps);
991
+ if (shared.isFunction(result)) {
992
+ result = result(this.reactiveProps);
993
+ }
994
+ if (signals.isSignal(result) || signals.isComputed(result)) {
995
+ result = result.value;
996
+ }
997
+ const newNodes = shared.coerceArray(result);
998
+ const anchor = this._getAnchorNode();
999
+ if (!this.parentNode) return;
1000
+ for (const node of this.renderedNodes) {
1001
+ removeNode(node);
1002
+ }
1003
+ for (const node of newNodes) {
1004
+ insertNode(this.parentNode, node, anchor);
1005
+ }
1006
+ this.renderedNodes = newNodes;
994
1007
  });
995
- if (hasChanges) {
1008
+ if (this.scope) {
996
1009
  triggerUpdateHooks(this.scope);
997
1010
  }
1011
+ } catch (error8) {
1012
+ this.renderedNodes = originalNodes;
1013
+ throw error8;
998
1014
  }
999
- return this;
1000
1015
  }
1001
- forceUpdate() {
1002
- return __async(this, null, function* () {
1003
- yield Promise.resolve();
1004
- if (this.state === 5 /* DESTROYED */ || !this.parentNode || !this.scope) {
1005
- return;
1006
- }
1007
- const originalNodes = [...this.renderedNodes];
1008
- try {
1009
- runWithScope(this.scope, () => {
1010
- let result = this.component(this.reactiveProps);
1011
- if (shared.isFunction(result)) {
1012
- result = result(this.reactiveProps);
1013
- }
1014
- if (signals.isSignal(result) || signals.isComputed(result)) {
1015
- result = result.value;
1016
- }
1017
- const newNodes = shared.coerceArray(result);
1018
- if (this.parentNode) {
1019
- let anchor = this.beforeNode;
1020
- if (!anchor && this.renderedNodes.length > 0) {
1021
- const lastNode = this.renderedNodes[this.renderedNodes.length - 1];
1022
- const lastDom = getFirstDOMNode(lastNode);
1023
- if (lastDom) {
1024
- anchor = lastDom.nextSibling;
1025
- }
1026
- }
1027
- for (const node of this.renderedNodes) {
1028
- removeNode(node);
1029
- }
1030
- for (const node of newNodes) {
1031
- insertNode(this.parentNode, node, anchor);
1032
- }
1033
- this.renderedNodes = newNodes;
1034
- }
1035
- });
1036
- if (this.scope) {
1037
- triggerUpdateHooks(this.scope);
1038
- }
1039
- } catch (error8) {
1040
- this.renderedNodes = originalNodes;
1041
- throw error8;
1016
+ /**
1017
+ * Get anchor node for insertion
1018
+ */
1019
+ _getAnchorNode() {
1020
+ if (this.beforeNode) return this.beforeNode;
1021
+ if (this.renderedNodes.length > 0) {
1022
+ const lastNode = this.renderedNodes[this.renderedNodes.length - 1];
1023
+ const lastDom = getFirstDOMNode(lastNode);
1024
+ if (lastDom) {
1025
+ return lastDom.nextSibling;
1042
1026
  }
1043
- });
1027
+ }
1028
+ return void 0;
1044
1029
  }
1045
1030
  /**
1046
1031
  * Destroy component
@@ -1050,14 +1035,14 @@ var Component = class {
1050
1035
  return;
1051
1036
  }
1052
1037
  this.state = 4 /* DESTROYING */;
1038
+ for (const node of this.renderedNodes) {
1039
+ removeNode(node);
1040
+ }
1053
1041
  const scope = this.scope;
1054
1042
  if (scope) {
1055
1043
  disposeScope(scope);
1056
1044
  this.scope = null;
1057
1045
  }
1058
- for (const node of this.renderedNodes) {
1059
- removeNode(node);
1060
- }
1061
1046
  this.renderedNodes = [];
1062
1047
  this.parentNode = void 0;
1063
1048
  this.beforeNode = void 0;
@@ -1067,16 +1052,13 @@ var Component = class {
1067
1052
  this.state = 5 /* DESTROYED */;
1068
1053
  }
1069
1054
  applyProps(props) {
1070
- if (!props) {
1071
- return;
1072
- }
1055
+ if (!props) return;
1073
1056
  const firstElement = this.firstChild;
1074
1057
  for (const [propName, propValue] of Object.entries(props)) {
1075
- if (shared.startsWith(propName, EVENT_PREFIX) && firstElement) {
1076
- const eventName = propName.slice(2).toLowerCase();
1077
- if (shared.isHTMLElement(firstElement)) {
1078
- addEventListener(firstElement, eventName, propValue);
1079
- }
1058
+ if (shared.startsWith(propName, EVENT_PREFIX)) {
1059
+ if (!firstElement || !shared.isHTMLElement(firstElement)) return;
1060
+ const eventName = propName.slice(EVENT_PREFIX.length).toLowerCase();
1061
+ addEventListener(firstElement, eventName, propValue);
1080
1062
  } else if (propName === REF_KEY && signals.isSignal(propValue)) {
1081
1063
  propValue.value = firstElement;
1082
1064
  }
@@ -1085,7 +1067,7 @@ var Component = class {
1085
1067
  }
1086
1068
  };
1087
1069
  function isComponent(node) {
1088
- return !!node && !!node["normal" /* NORMAL */];
1070
+ return !!node && !!node[NORMAL_COMPONENT];
1089
1071
  }
1090
1072
  function createComponent(componentFn, props) {
1091
1073
  if (isComponent(componentFn)) {
@@ -1119,7 +1101,7 @@ function createApp(component, target) {
1119
1101
  shared.error(`Target element is not empty, it will be delete: ${target}`);
1120
1102
  container.innerHTML = "";
1121
1103
  }
1122
- const rootComponent = createComponent(component);
1104
+ const rootComponent = isComponent(component) ? component : createComponent(component);
1123
1105
  rootComponent.mount(container);
1124
1106
  return rootComponent;
1125
1107
  }
@@ -1156,53 +1138,59 @@ function inject(key, defaultValue) {
1156
1138
  }
1157
1139
  return defaultValue;
1158
1140
  }
1159
- function eventHandler(e) {
1160
- let node = e.target;
1161
- const key = `${e.type}`;
1162
- const oriTarget = e.target;
1163
- const oriCurrentTarget = e.currentTarget;
1164
- const reTarget = (value) => Object.defineProperty(e, "target", {
1141
+ function reTarget(event, value) {
1142
+ Object.defineProperty(event, "target", {
1165
1143
  configurable: true,
1166
1144
  value
1167
1145
  });
1168
- const handleNode = () => {
1169
- const handler = node[`_$${key}`];
1170
- if (handler && shared.isFunction(handler) && !node.disabled) {
1171
- const data = node[`${key}Data`];
1172
- data ? handler.call(node, data, e) : handler.call(node, e);
1173
- if (e.cancelBubble) return false;
1174
- }
1175
- if (node.host && !shared.isString(node.host) && !node.host._$host && shared.isFunction(node.contains) && node.contains(e.target)) {
1176
- reTarget(node.host);
1177
- }
1178
- return true;
1179
- };
1180
- const walkUpTree = () => {
1181
- while (handleNode() && (node = node._$host || node.parentNode || node.host)) ;
1182
- };
1183
- Object.defineProperty(e, "currentTarget", {
1146
+ }
1147
+ function handleNodeEvent(node, event, key) {
1148
+ const handler = node[`_$${key}`];
1149
+ if (handler && shared.isFunction(handler) && !node.disabled) {
1150
+ const data = node[`${key}Data`];
1151
+ data ? handler.call(node, data, event) : handler.call(node, event);
1152
+ if (event.cancelBubble) return false;
1153
+ }
1154
+ if (node.host && !shared.isString(node.host) && !node.host._$host && shared.isFunction(node.contains) && node.contains(event.target)) {
1155
+ reTarget(event, node.host);
1156
+ }
1157
+ return true;
1158
+ }
1159
+ function walkUpTree(startNode, event, key) {
1160
+ let node = startNode;
1161
+ while (handleNodeEvent(node, event, key) && (node = node._$host || node.parentNode || node.host)) ;
1162
+ return node;
1163
+ }
1164
+ function eventHandler(event) {
1165
+ let node = event.target;
1166
+ const key = `${event.type}`;
1167
+ const oriTarget = event.target;
1168
+ const oriCurrentTarget = event.currentTarget;
1169
+ Object.defineProperty(event, "currentTarget", {
1184
1170
  configurable: true,
1185
1171
  get() {
1186
1172
  return node || document;
1187
1173
  }
1188
1174
  });
1189
- if (e.composedPath) {
1190
- const path = e.composedPath();
1191
- reTarget(path[0]);
1175
+ if (event.composedPath) {
1176
+ const path = event.composedPath();
1177
+ reTarget(event, path[0]);
1192
1178
  for (let i = 0; i < path.length - 2; i++) {
1193
1179
  node = path[i];
1194
- if (!handleNode()) break;
1180
+ if (!handleNodeEvent(node, event, key)) break;
1195
1181
  if (node._$host) {
1196
1182
  node = node._$host;
1197
- walkUpTree();
1183
+ node = walkUpTree(node, event, key);
1198
1184
  break;
1199
1185
  }
1200
1186
  if (node.parentNode === oriCurrentTarget) {
1201
1187
  break;
1202
1188
  }
1203
1189
  }
1204
- } else walkUpTree();
1205
- reTarget(oriTarget);
1190
+ } else {
1191
+ node = walkUpTree(node, event, key);
1192
+ }
1193
+ reTarget(event, oriTarget);
1206
1194
  }
1207
1195
  var $EVENTS = /* @__PURE__ */ Symbol("_$EVENTS");
1208
1196
  function delegateEvents(eventNames, document2 = window.document) {
@@ -1247,6 +1235,110 @@ function omitProps(target, keys) {
1247
1235
  }
1248
1236
  });
1249
1237
  }
1238
+
1239
+ // src/hydration/shared.ts
1240
+ var isHydrationActive = false;
1241
+ function startHydration() {
1242
+ isHydrationActive = true;
1243
+ }
1244
+ function endHydration() {
1245
+ isHydrationActive = false;
1246
+ }
1247
+ function isHydrating() {
1248
+ return isHydrationActive;
1249
+ }
1250
+ var hydrationCounter = 0;
1251
+ function getHydrationKey() {
1252
+ return `${hydrationCounter++}`;
1253
+ }
1254
+ function resetHydrationKey() {
1255
+ hydrationCounter = 0;
1256
+ }
1257
+
1258
+ // src/hydration/hydration.ts
1259
+ var DATA_IDX_REGEX = /^\d+-\d+$/;
1260
+ function getRenderedElement(temp) {
1261
+ return () => {
1262
+ if (!shared.isBrowser()) {
1263
+ return null;
1264
+ }
1265
+ const key = getHydrationKey();
1266
+ const node = document.querySelector(`[data-hk="${key}"]`);
1267
+ if (node) {
1268
+ return node;
1269
+ }
1270
+ return template(temp)();
1271
+ };
1272
+ }
1273
+ function mapSSRNodes(templateEl, idx) {
1274
+ const hk = templateEl.dataset.hk;
1275
+ if (!hk) {
1276
+ return mapNodes(templateEl, idx);
1277
+ }
1278
+ const nodesList = [];
1279
+ const elements = templateEl.querySelectorAll(`[data-idx^="${hk}"]`);
1280
+ if (elements.length > 0) {
1281
+ nodesList.push(
1282
+ ...Array.from(elements).filter((item) => {
1283
+ const idxAttr = item.dataset.idx;
1284
+ return idxAttr !== null && DATA_IDX_REGEX.test(idxAttr);
1285
+ }).map((item) => {
1286
+ const idxAttr = item.dataset.idx || "";
1287
+ const [hkPart, idxPart] = idxAttr.split("-");
1288
+ return {
1289
+ hk: hkPart,
1290
+ idx: idxPart,
1291
+ node: item
1292
+ };
1293
+ })
1294
+ );
1295
+ }
1296
+ const commentNodes = [];
1297
+ const walkNodes = (node) => {
1298
+ if (node.nodeType === Node.COMMENT_NODE && node.textContent && DATA_IDX_REGEX.test(node.textContent)) {
1299
+ const [hkPart, idxPart] = node.textContent.split("-");
1300
+ commentNodes.push({
1301
+ hk: hkPart,
1302
+ idx: idxPart,
1303
+ node
1304
+ });
1305
+ }
1306
+ let child = node.firstChild;
1307
+ while (child) {
1308
+ walkNodes(child);
1309
+ child = child.nextSibling;
1310
+ }
1311
+ };
1312
+ walkNodes(templateEl);
1313
+ nodesList.push(...commentNodes);
1314
+ const nodes = [templateEl];
1315
+ idx.forEach((indexValue) => {
1316
+ const node = nodesList.find((item) => item.idx === String(indexValue));
1317
+ if (node) {
1318
+ nodes.push(node.node);
1319
+ }
1320
+ });
1321
+ return nodes;
1322
+ }
1323
+ function hydrate(component, container) {
1324
+ startHydration();
1325
+ resetHydrationKey();
1326
+ try {
1327
+ const rootElement = shared.isString(container) ? document.querySelector(container) : container;
1328
+ if (!rootElement) {
1329
+ shared.error("Hydration error: Root element not found");
1330
+ return void 0;
1331
+ }
1332
+ const rootComponent = createComponent(component);
1333
+ rootComponent.mount(rootElement);
1334
+ endHydration();
1335
+ return rootComponent;
1336
+ } catch (error_) {
1337
+ shared.error("Hydration error:", error_);
1338
+ endHydration();
1339
+ return void 0;
1340
+ }
1341
+ }
1250
1342
  function patchClass(el, prev, next, isSVG = false) {
1251
1343
  if (prev === next) {
1252
1344
  return;
@@ -1333,7 +1425,7 @@ function setStyle(style, name, val) {
1333
1425
  return;
1334
1426
  }
1335
1427
  const prefixed = autoPrefix(style, name);
1336
- if (typeof val === "string" && importantRE.test(val)) {
1428
+ if (shared.isString(val) && importantRE.test(val)) {
1337
1429
  style.setProperty(shared.camelCase(prefixed), val.replace(importantRE, ""), "important");
1338
1430
  } else {
1339
1431
  style[prefixed] = val;
@@ -1423,7 +1515,7 @@ function patchAttr(el, key, prev, next) {
1423
1515
  }
1424
1516
  const attrValue = shared.isSymbol(next) ? String(next) : next;
1425
1517
  const isUrlAttr = lowerKey === "href" || lowerKey === "src" || lowerKey === "xlink:href";
1426
- if (isUrlAttr && typeof attrValue === "string") {
1518
+ if (isUrlAttr && shared.isString(attrValue)) {
1427
1519
  const v = attrValue.trim().toLowerCase();
1428
1520
  if (v.startsWith("javascript:") || v.startsWith("data:")) {
1429
1521
  return;
@@ -1470,26 +1562,21 @@ function Fragment(props) {
1470
1562
  shared.error("Fragment component requires props");
1471
1563
  return null;
1472
1564
  }
1473
- if (!props.children) {
1474
- shared.error("Fragment component requires children");
1475
- return null;
1476
- }
1477
1565
  }
1478
- return props == null ? void 0 : props.children;
1566
+ if (!(props == null ? void 0 : props.children)) {
1567
+ shared.error("Fragment component requires children");
1568
+ return null;
1569
+ }
1570
+ const { children } = props;
1571
+ return children;
1479
1572
  }
1480
- Fragment["fragment" /* FRAGMENT */] = true;
1573
+ Fragment[FRAGMENT_COMPONENT] = true;
1481
1574
  function isFragment(node) {
1482
- return !!node && !!node["fragment" /* FRAGMENT */];
1575
+ return !!node && !!node[FRAGMENT_COMPONENT];
1483
1576
  }
1484
1577
  function Portal(props) {
1485
- if (typeof document === "undefined") {
1486
- const children2 = props.children;
1487
- if (!children2) return "";
1488
- const childArray = shared.isArray(children2) ? children2 : [children2];
1489
- return childArray.map((child) => String(child || "")).join("");
1490
- }
1491
1578
  const placeholder = document.createComment("portal");
1492
- placeholder["portal" /* PORTAL */] = true;
1579
+ placeholder[PORTAL_COMPONENT] = true;
1493
1580
  const children = props.children;
1494
1581
  if (children) {
1495
1582
  const childArray = shared.isArray(children) ? children : [children];
@@ -1497,7 +1584,7 @@ function Portal(props) {
1497
1584
  onMount(() => {
1498
1585
  const targetElement = shared.isString(props.target) ? document.querySelector(props.target) : props.target;
1499
1586
  if (!targetElement) {
1500
- {
1587
+ if (true) {
1501
1588
  shared.warn(`[Portal] Target element not found: ${props.target}`);
1502
1589
  }
1503
1590
  return;
@@ -1513,7 +1600,7 @@ function Portal(props) {
1513
1600
  });
1514
1601
  onCleanup(() => {
1515
1602
  nodes.forEach((node) => {
1516
- if (typeof node !== "string" && node.parentNode === targetElement) {
1603
+ if (!shared.isString(node) && node.parentNode === targetElement) {
1517
1604
  targetElement.removeChild(node);
1518
1605
  }
1519
1606
  });
@@ -1522,9 +1609,9 @@ function Portal(props) {
1522
1609
  }
1523
1610
  return placeholder;
1524
1611
  }
1525
- Portal["portal" /* PORTAL */] = true;
1612
+ Portal[PORTAL_COMPONENT] = true;
1526
1613
  function isPortal(node) {
1527
- return !!node && !!node["portal" /* PORTAL */];
1614
+ return !!node && !!node[PORTAL_COMPONENT];
1528
1615
  }
1529
1616
  var SuspenseContext = /* @__PURE__ */ Symbol("SuspenseContext");
1530
1617
  function Suspense(props) {
@@ -1653,9 +1740,9 @@ function Suspense(props) {
1653
1740
  });
1654
1741
  return container;
1655
1742
  }
1656
- Suspense["suspense" /* SUSPENSE */] = true;
1743
+ Suspense[SUSPENSE_COMPONENT] = true;
1657
1744
  function isSuspense(node) {
1658
- return !!node && !!node["suspense" /* SUSPENSE */];
1745
+ return !!node && !!node[SUSPENSE_COMPONENT];
1659
1746
  }
1660
1747
  function createResource(fetcher, options) {
1661
1748
  const value = signals.signal(options == null ? void 0 : options.initialValue);
@@ -1714,8 +1801,175 @@ function createResource(fetcher, options) {
1714
1801
  };
1715
1802
  return [resource, actions];
1716
1803
  }
1804
+ function For(props) {
1805
+ const fragment = document.createDocumentFragment();
1806
+ const marker = document.createComment("");
1807
+ fragment.appendChild(marker);
1808
+ let entries = [];
1809
+ let fallbackNode = null;
1810
+ const keyFn = props.keyFn;
1811
+ const renderFn = props.children;
1812
+ const getList = () => {
1813
+ var _a2, _b;
1814
+ const input = props.each;
1815
+ if (signals.isSignal(input)) return (_a2 = input.value) != null ? _a2 : [];
1816
+ if (typeof input === "function") return (_b = input()) != null ? _b : [];
1817
+ return input != null ? input : [];
1818
+ };
1819
+ const getKey = (item) => keyFn ? keyFn(item) : item;
1820
+ const renderItem = (item, index, parent, before) => {
1821
+ var _a2;
1822
+ const prevScope = getActiveScope();
1823
+ const scope = createScope(prevScope);
1824
+ setActiveScope(scope);
1825
+ let node;
1826
+ try {
1827
+ const result = renderFn(item, index);
1828
+ if (isComponent(result)) {
1829
+ result.mount(parent, before);
1830
+ node = (_a2 = result.firstChild) != null ? _a2 : document.createComment("empty");
1831
+ } else {
1832
+ node = result;
1833
+ if (!node.parentNode) {
1834
+ if (before) {
1835
+ parent.insertBefore(node, before);
1836
+ } else {
1837
+ parent.appendChild(node);
1838
+ }
1839
+ }
1840
+ }
1841
+ } finally {
1842
+ setActiveScope(prevScope);
1843
+ }
1844
+ return { key: getKey(item), node, scope };
1845
+ };
1846
+ const disposeItem = (entry) => {
1847
+ disposeScope(entry.scope);
1848
+ if (entry.node.parentNode) {
1849
+ entry.node.parentNode.removeChild(entry.node);
1850
+ }
1851
+ };
1852
+ signals.memoEffect(
1853
+ ({ prev }) => {
1854
+ var _a2;
1855
+ const newItems = getList();
1856
+ if (prev === newItems) return { prev: newItems };
1857
+ const parent = marker.parentNode;
1858
+ if (!parent) {
1859
+ if (newItems.length === 0) {
1860
+ if (props.fallback) {
1861
+ const fb = props.fallback();
1862
+ if (isComponent(fb)) {
1863
+ fb.mount(fragment, marker);
1864
+ fallbackNode = (_a2 = fb.firstChild) != null ? _a2 : document.createComment("empty");
1865
+ } else {
1866
+ fallbackNode = fb;
1867
+ fragment.insertBefore(fallbackNode, marker);
1868
+ }
1869
+ }
1870
+ return { prev: newItems };
1871
+ }
1872
+ entries = new Array(newItems.length);
1873
+ for (const [i, newItem] of newItems.entries()) {
1874
+ entries[i] = renderItem(newItem, i, fragment, marker);
1875
+ }
1876
+ return { prev: newItems };
1877
+ }
1878
+ signals.untrack(() => reconcile(parent, newItems));
1879
+ return { prev: newItems };
1880
+ },
1881
+ {
1882
+ prev: []
1883
+ }
1884
+ );
1885
+ function reconcile(parent, newItems) {
1886
+ var _a2;
1887
+ const oldLen = entries.length;
1888
+ const newLen = newItems.length;
1889
+ if (newLen === 0) {
1890
+ for (let i = 0; i < oldLen; i++) {
1891
+ disposeItem(entries[i]);
1892
+ }
1893
+ entries = [];
1894
+ if (props.fallback && !fallbackNode) {
1895
+ const fb = props.fallback();
1896
+ if (isComponent(fb)) {
1897
+ fb.mount(parent, marker);
1898
+ fallbackNode = (_a2 = fb.firstChild) != null ? _a2 : document.createComment("empty");
1899
+ } else {
1900
+ fallbackNode = fb;
1901
+ parent.insertBefore(fallbackNode, marker);
1902
+ }
1903
+ }
1904
+ return;
1905
+ }
1906
+ if (oldLen === 0 || fallbackNode) {
1907
+ if (fallbackNode) {
1908
+ if (fallbackNode.parentNode) fallbackNode.parentNode.removeChild(fallbackNode);
1909
+ fallbackNode = null;
1910
+ }
1911
+ entries = new Array(newLen);
1912
+ const batchFragment2 = document.createDocumentFragment();
1913
+ for (let i = 0; i < newLen; i++) {
1914
+ entries[i] = renderItem(newItems[i], i, batchFragment2, null);
1915
+ }
1916
+ parent.insertBefore(batchFragment2, marker);
1917
+ return;
1918
+ }
1919
+ const oldKeyMap = /* @__PURE__ */ new Map();
1920
+ for (let i = 0; i < oldLen; i++) {
1921
+ const entry = entries[i];
1922
+ const list = oldKeyMap.get(entry.key);
1923
+ if (list) {
1924
+ list.push(entry);
1925
+ } else {
1926
+ oldKeyMap.set(entry.key, [entry]);
1927
+ }
1928
+ }
1929
+ const newEntries = new Array(newLen);
1930
+ const toRemove = [];
1931
+ const batchFragment = document.createDocumentFragment();
1932
+ for (let i = 0; i < newLen; i++) {
1933
+ const item = newItems[i];
1934
+ const key = getKey(item);
1935
+ const oldList = oldKeyMap.get(key);
1936
+ if (oldList && oldList.length > 0) {
1937
+ newEntries[i] = oldList.shift();
1938
+ } else {
1939
+ newEntries[i] = renderItem(item, i, batchFragment, null);
1940
+ }
1941
+ }
1942
+ for (const list of oldKeyMap.values()) {
1943
+ for (const entry of list) {
1944
+ toRemove.push(entry);
1945
+ }
1946
+ }
1947
+ for (const entry of toRemove) {
1948
+ disposeItem(entry);
1949
+ }
1950
+ for (let i = 0; i < newLen; i++) {
1951
+ const node = newEntries[i].node;
1952
+ parent.insertBefore(node, marker);
1953
+ }
1954
+ entries = newEntries;
1955
+ }
1956
+ onCleanup(() => {
1957
+ for (const entry of entries) {
1958
+ disposeItem(entry);
1959
+ }
1960
+ if (fallbackNode && fallbackNode.parentNode) {
1961
+ fallbackNode.parentNode.removeChild(fallbackNode);
1962
+ }
1963
+ if (marker.parentNode) {
1964
+ marker.parentNode.removeChild(marker);
1965
+ }
1966
+ });
1967
+ return fragment;
1968
+ }
1969
+ For[FOR_COMPONENT] = true;
1717
1970
 
1718
1971
  exports.Component = Component;
1972
+ exports.For = For;
1719
1973
  exports.Fragment = Fragment;
1720
1974
  exports.Portal = Portal;
1721
1975
  exports.Suspense = Suspense;
@@ -1731,6 +1985,9 @@ exports.disposeScope = disposeScope;
1731
1985
  exports.endHydration = endHydration;
1732
1986
  exports.getActiveScope = getActiveScope;
1733
1987
  exports.getFirstDOMNode = getFirstDOMNode;
1988
+ exports.getHydrationKey = getHydrationKey;
1989
+ exports.getRenderedElement = getRenderedElement;
1990
+ exports.hydrate = hydrate;
1734
1991
  exports.inject = inject;
1735
1992
  exports.insert = insert;
1736
1993
  exports.insertNode = insertNode;
@@ -1741,6 +1998,7 @@ exports.isPortal = isPortal;
1741
1998
  exports.isSameNode = isSameNode;
1742
1999
  exports.isSuspense = isSuspense;
1743
2000
  exports.mapNodes = mapNodes;
2001
+ exports.mapSSRNodes = mapSSRNodes;
1744
2002
  exports.normalizeClass = normalizeClass;
1745
2003
  exports.normalizeNode = normalizeNode;
1746
2004
  exports.omitProps = omitProps;
@@ -1754,6 +2012,7 @@ exports.patchStyle = patchStyle;
1754
2012
  exports.provide = provide;
1755
2013
  exports.removeNode = removeNode;
1756
2014
  exports.replaceNode = replaceNode;
2015
+ exports.resetHydrationKey = resetHydrationKey;
1757
2016
  exports.runWithScope = runWithScope;
1758
2017
  exports.setActiveScope = setActiveScope;
1759
2018
  exports.setStyle = setStyle;