@neeloong/form 0.11.0 → 0.12.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.
package/README.md CHANGED
@@ -14,7 +14,7 @@ const template = `
14
14
  <li !value="list" !enum>
15
15
  <input !bind="b" />
16
16
  <ul !value="c" +x="0">
17
- <li !enum +b=alias$length +a=2 +k="++x">
17
+ <li !enum +b=alias$size +a=2 +k="++x">
18
18
  <div !fragment !text="k"></div>
19
19
  <button @click="a+=1">a+1:<span !fragment !text="a"></span></button>
20
20
  <button @click="b+=1">b+1:<span !fragment !text="b"></span></button>
@@ -24,7 +24,7 @@ const template = `
24
24
  <button @click="$upMove" :disabled="!$upMovable">上移</button>
25
25
  <button @click="$downMove()" :disabled="!$downMovable">下移</button>
26
26
  </li>
27
- <li><button @click="$add(0)">添加</button><button @click="$add( - $length - 1)">添加(<span !fragment !text=" - $length - 1"></span>)</button></li>
27
+ <li><button @click="$add(0)">添加</button><button @click="$add( - $size - 1)">添加(<span !fragment !text=" - $size - 1"></span>)</button></li>
28
28
  </ul>
29
29
  </li>
30
30
  </ul>
@@ -127,7 +127,7 @@ render(store, layouts, app);
127
127
  - **别名(`*alias`)**:
128
128
  为复杂表达式或字段设置别名,简化引用。
129
129
  ```html
130
- <div *len="array$length" !text="len"></div> <!-- 别名 len 指向当前数组长度 -->
130
+ <div *len="array$size" !text="len"></div> <!-- 别名 len 指向当前数组长度 -->
131
131
  ```
132
132
 
133
133
  - **计算值(`*computed`)**:
@@ -179,9 +179,9 @@ render(store, layouts, app);
179
179
  #### 嵌套循环
180
180
 
181
181
  ```html
182
- <div !enum="outerArray" *outerLen="$length">
182
+ <div !enum="outerArray" *outerLen="$size">
183
183
  <div !enum="innerArray">
184
- <span !text="outerLen + ' + ' + $length"></span> <!-- 外层长度 + 内层长度 -->
184
+ <span !text="outerLen + ' + ' + $size"></span> <!-- 外层长度 + 内层长度 -->
185
185
  </div>
186
186
  </div>
187
187
  ```
@@ -300,7 +300,7 @@ render(store, layouts, app);
300
300
  - `$null` 只读 是否为空元素
301
301
  - `$index` 只读 当前项的索引
302
302
  - `$no` 只读 数组项目的序号
303
- - `$length` 只读 数组的长度、对象的成员数
303
+ - `$size` 只读 数组的长度、对象的成员数
304
304
  - `$creatable` 只读 值是否可创建(`$new` 为 `true` 时,字段只读)
305
305
  - `$immutable` 只读 值是否不可改变(`$new` 为 `false` 时,字段只读)
306
306
  - `$new` 只读 是否新建项
@@ -343,8 +343,13 @@ render(store, layouts, app);
343
343
  - `$upMove()` 上移当前项
344
344
  - `$downMove()` 下移当前项
345
345
  1. 上下文隐式变量
346
- - '$store' 只读 当前表单存储实例。
347
- - '$root' 只读 根上下文对象。
346
+ - `$store` 只读 当前表单存储实例。
347
+ - `$root` 只读 根上下文对象。
348
+ 1. `enum` 上下文新增的变量
349
+ - `$$count` 枚举上下文的数量
350
+ - `$$key` 枚举上下文的当前项的键
351
+ - `$$index` 枚举上下文当前项的索引
352
+ - `$$item` 枚举上下文当前项
348
353
  1. 当前范围及组件范围的所有字段(数组字段的成员除外,因为数组字段成员索引为数字,不符合标识符命名规则)都存在 `field$value` 及 `field$$value` 形式的变量
349
354
  1. 如果别名为字段的别名(如 `*alias="v"`),则也存在 `alias$value` 形式的变量
350
355
  1. 当存在同名变量时,则会按照变量来源类型决定优先级,从高到低依次为:
@@ -353,7 +358,6 @@ render(store, layouts, app);
353
358
  1. 全局变量,此部分由 `render` 的参数传入
354
359
  1. 字段声明,包括 `field$value` 及 `field$$value` 形式的变量
355
360
  1. 在同一来源类型重复的变量名,再按照作用域处理
356
- 1. 同一作用域下的别名(或计算名)与显式变量重名时,由于会先处理别名,所以,显式变量会覆盖别名。
357
361
 
358
362
  ### 示例代码
359
363
 
package/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @neeloong/form v0.11.0
2
+ * @neeloong/form v0.12.0
3
3
  * (c) 2024-2025 Fierflame
4
4
  * @license Apache-2.0
5
5
  */
@@ -468,12 +468,12 @@ declare namespace Component {
468
468
  */
469
469
  type Getter = (path: string[], next?: ((path: string[]) => Component | null) | undefined) => Component | null;
470
470
  }
471
- type Schema = Record<string, Schema.Field>;
471
+ type Schema<M = any> = Record<string, Schema.Field<M>>;
472
472
  declare namespace Schema {
473
473
  /**
474
474
  * 字段定义
475
475
  */
476
- type Field = (Schema.Object | Schema.Type) & Schema.Attr;
476
+ type Field<M_1 = any> = (Schema.Object<M_1> | Schema.Type) & Schema.Attr<M_1>;
477
477
  /**
478
478
  * 可选值
479
479
  */
@@ -532,11 +532,11 @@ declare namespace Schema {
532
532
  /**
533
533
  * 对象类型定义
534
534
  */
535
- type Object = {
535
+ type Object<M_1 = any> = {
536
536
  /**
537
537
  * 字段定义
538
538
  */
539
- type: Record<string, Schema.Field>;
539
+ type: Record<string, Schema.Field<M_1>>;
540
540
  /**
541
541
  * 是否为数组
542
542
  */
@@ -580,11 +580,11 @@ declare namespace Schema {
580
580
  */
581
581
  blur: Event;
582
582
  };
583
- type Attr = {
583
+ type Attr<M_1 = any> = {
584
584
  /**
585
585
  * 元信息
586
586
  */
587
- meta?: any;
587
+ meta?: M_1 | undefined;
588
588
  /**
589
589
  * 自定义组件
590
590
  */
@@ -656,7 +656,7 @@ declare namespace Schema {
656
656
  /**
657
657
  * 可选值
658
658
  */
659
- values?: (Schema.Value.Define | Schema.Value.Group.Define)[] | undefined;
659
+ values?: (Schema.Value.Define | Schema.Value.Group.Define)[] | ((store: Store) => (Schema.Value.Group.Define | Schema.Value.Define)[]) | undefined;
660
660
  /**
661
661
  * 监听函数
662
662
  */
@@ -780,17 +780,19 @@ type Ref = {
780
780
  /**
781
781
  * 管理单个表单字段的状态和行为
782
782
  * @template [T=any]
783
+ * @template [M=any]
783
784
  */
784
- declare class Store<T = any> {
785
+ declare class Store<T = any, M = any> {
785
786
  /**
786
787
  * 从数据结构模式创建存储
787
- * @param {Schema} schema 数据结构模式
788
+ * @template [M=any]
789
+ * @param {Schema<M>} schema 数据结构模式
788
790
  * @param {object} [options] 选项
789
791
  * @param {boolean} [options.new] 是否为新建环境
790
792
  */
791
- static create(schema: Schema, options?: {
793
+ static create<M_1 = any>(schema: Schema<M_1>, options?: {
792
794
  new?: boolean | undefined;
793
- }): Store<any>;
795
+ }): Store<any, any>;
794
796
  /**
795
797
  * 设置自定义类型的存储类
796
798
  * @param {string} type
@@ -800,12 +802,12 @@ declare class Store<T = any> {
800
802
  new (...p: ConstructorParameters<typeof Store>): Store;
801
803
  }): void;
802
804
  /**
803
- * @param {Schema.Field} schema 字段的 Schema 定义
805
+ * @param {Schema.Field<M>} schema 字段的 Schema 定义
804
806
  * @param {object} [options] 可选配置
805
807
  * @param {*} [options.parent]
806
808
  * @param {*} [options.state]
807
809
  * @param {number | string | null} [options.index]
808
- * @param {number | Signal.State<number> | Signal.Computed<number>} [options.length]
810
+ * @param {number | Signal.State<number> | Signal.Computed<number>} [options.size]
809
811
  * @param {boolean} [options.null]
810
812
  * @param {boolean} [options.new]
811
813
  * @param {boolean} [options.hidden]
@@ -836,11 +838,11 @@ declare class Store<T = any> {
836
838
  * @param {((value: T?, index: any, store: Store) => void)?} [options.onUpdate]
837
839
  * @param {((value: T?, index: any, store: Store) => void)?} [options.onUpdateState]
838
840
  */
839
- constructor(schema: Schema.Field, { null: isNull, state, ref, setValue, setState, convert, onUpdate, onUpdateState, validator, validators, index, length, new: isNew, parent: parentNode, hidden, clearable, required, disabled, readonly, label, description, placeholder, min, max, step, minLength, maxLength, pattern, values }?: {
841
+ constructor(schema: Schema.Field<M>, { null: isNull, state, ref, setValue, setState, convert, onUpdate, onUpdateState, validator, validators, index, size, new: isNew, parent: parentNode, hidden, clearable, required, disabled, readonly, label, description, placeholder, min, max, step, minLength, maxLength, pattern, values }?: {
840
842
  parent?: any;
841
843
  state?: any;
842
844
  index?: string | number | null | undefined;
843
- length?: number | Signal.State<number> | Signal.Computed<number> | undefined;
845
+ size?: number | Signal.State<number> | Signal.Computed<number> | undefined;
844
846
  null?: boolean | undefined;
845
847
  new?: boolean | undefined;
846
848
  hidden?: boolean | undefined;
@@ -908,21 +910,21 @@ declare class Store<T = any> {
908
910
  /** 存储类类别,继承的自定义类需要设置自定义的此只读属性 */
909
911
  get kind(): string;
910
912
  get ref(): Ref;
911
- schema: Schema.Field;
913
+ schema: Schema.Field<M>;
912
914
  /** 存储对象自身 */
913
915
  get store(): this;
914
916
  /** 父级存储对象 */
915
- get parent(): Store<any> | null;
917
+ get parent(): Store<any, any> | null;
916
918
  /** 根节点的存储对象 */
917
- get root(): Store<any>;
919
+ get root(): Store<any, any>;
918
920
  /** 字段类型 */
919
921
  get type(): any;
920
922
  /** 字段元信息 */
921
- get meta(): any;
923
+ get meta(): void | M;
922
924
  /** 自定义渲染组件信息 */
923
925
  get component(): any;
924
926
  /** 长度信息 */
925
- get length(): number;
927
+ get size(): number;
926
928
  set index(v: string | number);
927
929
  /** 索引信息 */
928
930
  get index(): string | number;
@@ -1067,7 +1069,7 @@ declare class Store<T = any> {
1067
1069
  * @returns {() => void}
1068
1070
  */
1069
1071
  declare function render(store: Store, layouts: Child[], parent: Element, { component, global, relate, enhancements }?: {
1070
- global?: Record<string, Store<any> | {
1072
+ global?: Record<string, Store<any, any> | {
1071
1073
  get?(): any;
1072
1074
  set?(v: any): void;
1073
1075
  exec?(...p: any[]): any;
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @neeloong/form v0.11.0
2
+ * @neeloong/form v0.12.0
3
3
  * (c) 2024-2025 Fierflame
4
4
  * @license Apache-2.0
5
5
  */
@@ -726,7 +726,8 @@
726
726
  /** @type {Record<string, {new(...p: ConstructorParameters<typeof Store>): Store}?>} */
727
727
  let TypeStores = Object.create(null);
728
728
  /**
729
- * @param {Schema.Field} schema
729
+ * @template [M=any]
730
+ * @param {Schema.Field<M>} schema
730
731
  * @param {object} [options]
731
732
  * @param {Store?} [options.parent]
732
733
  * @param {string | number | null} [options.index]
@@ -863,6 +864,7 @@
863
864
  /**
864
865
  * 管理单个表单字段的状态和行为
865
866
  * @template [T=any]
867
+ * @template [M=any]
866
868
  */
867
869
  class Store {
868
870
  /** @type {Map<string, Set<(value: any, store: any) => void | boolean | null>>} */
@@ -904,7 +906,8 @@
904
906
  }
905
907
  /**
906
908
  * 从数据结构模式创建存储
907
- * @param {Schema} schema 数据结构模式
909
+ * @template [M=any]
910
+ * @param {Schema<M>} schema 数据结构模式
908
911
  * @param {object} [options] 选项
909
912
  * @param {boolean} [options.new] 是否为新建环境
910
913
  */
@@ -928,12 +931,12 @@
928
931
  #ref = null;
929
932
  get ref() { return this.#ref || createRef(this); }
930
933
  /**
931
- * @param {Schema.Field} schema 字段的 Schema 定义
934
+ * @param {Schema.Field<M>} schema 字段的 Schema 定义
932
935
  * @param {object} [options] 可选配置
933
936
  * @param {*} [options.parent]
934
937
  * @param {*} [options.state]
935
938
  * @param {number | string | null} [options.index]
936
- * @param {number | Signal.State<number> | Signal.Computed<number>} [options.length]
939
+ * @param {number | Signal.State<number> | Signal.Computed<number>} [options.size]
937
940
  * @param {boolean} [options.null]
938
941
  * @param {boolean} [options.new]
939
942
  * @param {boolean} [options.hidden]
@@ -968,7 +971,7 @@
968
971
  null: isNull, state, ref,
969
972
  setValue, setState, convert, onUpdate, onUpdateState,
970
973
  validator, validators,
971
- index, length, new: isNew, parent: parentNode,
974
+ index, size, new: isNew, parent: parentNode,
972
975
  hidden, clearable, required, disabled, readonly,
973
976
  label, description, placeholder, min, max, step, minLength, maxLength, pattern, values: values$1
974
977
  } = {}) {
@@ -1048,10 +1051,10 @@
1048
1051
  this.#cancelChange = cancelChange;
1049
1052
  this.#cancelBlur = cancelBlur;
1050
1053
 
1051
- if (length instanceof exports.Signal.State || length instanceof exports.Signal.Computed) {
1052
- this.#length = length;
1054
+ if (size instanceof exports.Signal.State || size instanceof exports.Signal.Computed) {
1055
+ this.#size = size;
1053
1056
  } else {
1054
- this.#length = new exports.Signal.State(length || 0);
1057
+ this.#size = new exports.Signal.State(size || 0);
1055
1058
  }
1056
1059
 
1057
1060
  if (isNull) {
@@ -1089,7 +1092,7 @@
1089
1092
  #root = this;
1090
1093
  /** @readonly @type {any} */
1091
1094
  #type;
1092
- /** @readonly @type {any} */
1095
+ /** @readonly @type {M | void} */
1093
1096
  #meta;
1094
1097
  /** @readonly @type {any} */
1095
1098
  #component;
@@ -1107,9 +1110,9 @@
1107
1110
  get component() { return this.#component; }
1108
1111
 
1109
1112
  /** @type {Signal.State<number> | Signal.Computed<number>} */
1110
- #length;
1113
+ #size;
1111
1114
  /** 长度信息 */
1112
- get length() { return this.#length.get(); }
1115
+ get size() { return this.#size.get(); }
1113
1116
  #index = new exports.Signal.State(/** @type {string | number} */(''));
1114
1117
  /** 索引信息 */
1115
1118
  get index() { return this.#index.get(); }
@@ -1496,7 +1499,8 @@
1496
1499
 
1497
1500
  /**
1498
1501
  * @template {Record<string, any>} [T=Record<string, any>]
1499
- * @extends {Store<T>}
1502
+ * @template [M=any]
1503
+ * @extends {Store<T, M>}
1500
1504
  */
1501
1505
  class ObjectStore extends Store {
1502
1506
  get kind() { return 'object'; }
@@ -1510,7 +1514,7 @@
1510
1514
  */
1511
1515
  child(key) { return this.#children[key] || null; }
1512
1516
  /**
1513
- * @param {Schema.Object & Schema.Attr} schema
1517
+ * @param {Schema.Object<M> & Schema.Attr<M>} schema
1514
1518
  * @param {object} [options]
1515
1519
  * @param {Store?} [options.parent]
1516
1520
  * @param {number | string | null} [options.index]
@@ -1522,7 +1526,7 @@
1522
1526
  const childrenTypes = Object.entries(schema.type);
1523
1527
  super(schema, {
1524
1528
  parent, index, new: isNew, onUpdate, onUpdateState,
1525
- length: childrenTypes.length,
1529
+ size: childrenTypes.length,
1526
1530
  setValue(v) { return typeof v === 'object' ? v : null; },
1527
1531
  setState(v) { return typeof v === 'object' ? v : null; },
1528
1532
  convert(v, state) {
@@ -1563,7 +1567,8 @@
1563
1567
 
1564
1568
  /**
1565
1569
  * @template [T=any]
1566
- * @extends {Store<(T | null)[]>}
1570
+ * @template [M=any]
1571
+ * @extends {Store<(T | null)[], M>}
1567
1572
  */
1568
1573
  class ArrayStore extends Store {
1569
1574
  /** @type {(index: number, isNew?: boolean) => Store} */
@@ -1586,7 +1591,7 @@
1586
1591
  }
1587
1592
  get kind() { return 'array'; }
1588
1593
  /**
1589
- * @param {Schema.Field} schema
1594
+ * @param {Schema.Field<M>} schema
1590
1595
  * @param {object} [options]
1591
1596
  * @param {Store?} [options.parent]
1592
1597
  * @param {string | number | null} [options.index]
@@ -1604,6 +1609,7 @@
1604
1609
  for (let i = children.length; i < length; i++) {
1605
1610
  children.push(this.#create(i));
1606
1611
  }
1612
+ children.length = length;
1607
1613
  if (oldLength !== length) {
1608
1614
  childrenState.set(children);
1609
1615
  }
@@ -1611,7 +1617,7 @@
1611
1617
  };
1612
1618
  super(schema, {
1613
1619
  index, new: isNew, parent,
1614
- length: new exports.Signal.Computed(() => childrenState.get().length),
1620
+ size: new exports.Signal.Computed(() => childrenState.get().length),
1615
1621
  state: [],
1616
1622
  setValue(v) { return Array.isArray(v) ? v : v == null ? null : [v] },
1617
1623
  setState(v) { return Array.isArray(v) ? v : v == null ? null : [v] },
@@ -2970,7 +2976,7 @@
2970
2976
  null: true,
2971
2977
  index: true,
2972
2978
  no: true,
2973
- length: true,
2979
+ size: true,
2974
2980
 
2975
2981
  error: true,
2976
2982
  errors: true,
@@ -3029,7 +3035,7 @@
3029
3035
  yield [`${key}${sign}downMovable`, {get: () => {
3030
3036
  const s = val.index;
3031
3037
  if (typeof s !== 'number') { return false; }
3032
- if (s >= parent.length - 1) { return false; }
3038
+ if (s >= parent.size - 1) { return false; }
3033
3039
  return true;
3034
3040
  }}];
3035
3041
  yield [`${key}${sign}remove`, {exec: () => parent.remove(Number(val.index))}];
@@ -3042,7 +3048,7 @@
3042
3048
  yield [`${key}${sign}downMove`, {exec: () => {
3043
3049
  const s = val.index;
3044
3050
  if (typeof s !== 'number') { return; }
3045
- if (s >= parent.length - 1) { return; }
3051
+ if (s >= parent.size - 1) { return; }
3046
3052
  parent.move(s, s + 1);
3047
3053
  }}];
3048
3054
  }
@@ -3194,10 +3200,9 @@
3194
3200
  watch(value, cb) { return watch(() => this.exec(value), cb, true); }
3195
3201
 
3196
3202
  /**
3197
- * @param {Layout.Node.Name | Layout.Node.Calc | Layout.Node.Value | null} [en]
3203
+ * @param {Layout.Node.Name | Layout.Node.Calc | Layout.Node.Value} en
3198
3204
  */
3199
3205
  enum(en) {
3200
- if (!en) { return true; }
3201
3206
  const {name, calc} = en;
3202
3207
  if (typeof calc === 'function') { return () => calc(this.getters); }
3203
3208
  if (typeof name === 'string') {
@@ -3383,17 +3388,16 @@
3383
3388
  const store = this.store;
3384
3389
  const parent = this.#parent;
3385
3390
  const object = this.#object;
3391
+ for (const [key, item] of toItem(store)) {
3392
+ ais[key] = item;
3393
+ }
3394
+ for (const [key, item] of toParentItem(parent, store)) {
3395
+ ais[key] = item;
3396
+ }
3386
3397
  if (object) {
3387
3398
  for (const k of Object.keys(object)) {
3388
3399
  ais[`$${k}`] = {get: () => object[k]};
3389
3400
  }
3390
- } else {
3391
- for (const [key, item] of toItem(store)) {
3392
- ais[key] = item;
3393
- }
3394
- for (const [key, item] of toParentItem(parent, store)) {
3395
- ais[key] = item;
3396
- }
3397
3401
  }
3398
3402
  this.#allItems = ais;
3399
3403
  return ais;
@@ -3402,11 +3406,13 @@
3402
3406
  *
3403
3407
  * @param {Store} store
3404
3408
  * @param {Store} parent
3409
+ * @param {Record<string, any>} [object]
3405
3410
  */
3406
- setStore(store, parent) {
3411
+ setStore(store, parent, object) {
3407
3412
  const cloned = new Environment(store, this);
3408
3413
  if (parent) { cloned.#parent = parent; }
3409
3414
  setStore(cloned.#schemaItems, store);
3415
+ if (object) { cloned.#object = object; }
3410
3416
  return cloned;
3411
3417
  }
3412
3418
  /**
@@ -4541,17 +4547,24 @@
4541
4547
  }
4542
4548
 
4543
4549
  }
4550
+ const count = new exports.Signal.State(0);
4544
4551
  const childrenResult = watch(() => store.children, function render(children) {
4545
4552
  if (!start.parentNode) { return; }
4546
4553
  let nextNode = start.nextSibling;
4547
4554
  const oldSeMap = seMap;
4548
4555
  seMap = new Map();
4556
+ count.set(children.length);
4549
4557
  for (let child of children) {
4550
4558
  const old = oldSeMap.get(child);
4551
4559
  if (!old) {
4552
4560
  const ItemStart = parent.insertBefore(document.createComment(''), nextNode);
4553
4561
  const itemEnd = parent.insertBefore(document.createComment(''), nextNode);
4554
- const d = renderItem(itemEnd, env.setStore(child, store));
4562
+ const d = renderItem(itemEnd, env.setStore(child, store, {
4563
+ get count() { return count.get() },
4564
+ get key() { return child.index; },
4565
+ get index() { return child.index; },
4566
+ get item() { return child.value; },
4567
+ }));
4555
4568
  seMap.set(child, [ItemStart, itemEnd, d]);
4556
4569
  continue;
4557
4570
  }
@@ -4637,7 +4650,7 @@
4637
4650
  };
4638
4651
  }
4639
4652
 
4640
- /** @import { ObjectStore } from '../Store/index.mjs' */
4653
+ /** @import { ObjectStore, Store } from '../Store/index.mjs' */
4641
4654
 
4642
4655
  /**
4643
4656
  *
@@ -4650,8 +4663,16 @@
4650
4663
  function renderObject(parent, next, store, env, renderItem) {
4651
4664
  /** @type {(() => void)[]} */
4652
4665
  const children = [];
4653
- for (const [k, child] of [...store]) {
4654
- children.push(renderItem(next, env.setStore(child, store)));
4666
+ /** @type {[string, Store<any, any>, number][]} */
4667
+ const childStores = [...store].map(([k,v], i) => [k,v,i]);
4668
+ const count = childStores.length;
4669
+ for (const [key, child, index] of childStores) {
4670
+ children.push(renderItem(next, env.setStore(child, store, {
4671
+ get count() { return count; },
4672
+ get key() { return key; },
4673
+ get index() { return index; },
4674
+ get item() { return child.value; },
4675
+ })));
4655
4676
  }
4656
4677
 
4657
4678
  return () => {
@@ -4697,11 +4718,13 @@
4697
4718
  e.remove();
4698
4719
  }
4699
4720
  }
4721
+ const count = new exports.Signal.State(0);
4700
4722
  const childrenResult = watch(() => list.get(), function render(children) {
4701
4723
  if (!start.parentNode) { return; }
4702
4724
  let nextNode = start.nextSibling;
4703
4725
  const oldSeMap = seMap;
4704
4726
  seMap = [];
4727
+ count.set(children.length);
4705
4728
  for (const [value, index, key] of children) {
4706
4729
  const index2 = oldSeMap.findIndex((v) => v[3] === key);
4707
4730
  const [old] = index2 >= 0 ? oldSeMap.splice(index2, 1) : [];
@@ -4711,8 +4734,9 @@
4711
4734
  const valueState = new exports.Signal.State(value);
4712
4735
  const indexState = new exports.Signal.State(index);
4713
4736
  const d = renderItem(itemEnd, env.setObject({
4737
+ get count() { return count.get() },
4714
4738
  get key() { return key; },
4715
- get value() { return valueState.get(); },
4739
+ get item() { return valueState.get(); },
4716
4740
  get index() { return indexState.get(); },
4717
4741
  }));
4718
4742
  seMap.push([ItemStart, itemEnd, d, key, valueState, indexState]);
@@ -5065,9 +5089,6 @@
5065
5089
  const list = env.enum(layout.value);
5066
5090
  /** @type {(next: Node | null, env: any) => () => void} */
5067
5091
  const r = (next, env) => renderChildren(layout.children, parent, next, env, templates, componentPath, enhancements, relate, getComponent);
5068
- if (list === true) {
5069
- return r(next, env);
5070
- }
5071
5092
  if (list instanceof ArrayStore) {
5072
5093
  return renderArray(parent, next, list, env, r);
5073
5094
  }