@neeloong/form 0.4.2 → 0.5.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/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @neeloong/form v0.4.2
2
+ * @neeloong/form v0.5.0
3
3
  * (c) 2024-2025 Fierflame
4
4
  * @license Apache-2.0
5
5
  */
@@ -79,7 +79,7 @@ declare namespace index_d {
79
79
 
80
80
  type VerifyError = any;
81
81
  type Component = {
82
- tag: string | ((ctx: any) => Element | [Element, (Element | null)?]);
82
+ tag: string | ((ctx: Component.Context) => Element | [Element, (Element | null)?]);
83
83
  is?: string | undefined;
84
84
  attrs?: Record<string, Component.Attr> | undefined;
85
85
  events?: Record<string, Component.Event> | undefined;
@@ -100,7 +100,7 @@ declare namespace Component {
100
100
  addEvent: (event: string, listener: EventListener) => void;
101
101
  destroy: () => void;
102
102
  tag: any;
103
- init: () => void;
103
+ mount: () => void;
104
104
  };
105
105
  type Context = {
106
106
  props?: Set<string> | null | undefined;
@@ -128,8 +128,8 @@ declare namespace Component {
128
128
  namespace Event {
129
129
  type Filter = ($event: any, param: string[], env: any) => boolean | null | void;
130
130
  }
131
+ type Getter = (path: string[], next?: ((path: string[]) => Component | null) | undefined) => Component | null;
131
132
  }
132
- type ComponentGetter = (path: string[], next?: ((path: string[]) => Component | null) | undefined) => Component | null;
133
133
  type Schema = Record<string, Schema.Field>;
134
134
  declare namespace Schema {
135
135
  type Field = (Schema.Object | Schema.Type) & Schema.Attr;
@@ -153,16 +153,14 @@ declare namespace Schema {
153
153
  }
154
154
  }
155
155
  type Object = {
156
- type?: null | undefined;
157
- props?: Record<string, Schema.Field> | undefined;
156
+ type: Record<string, Schema.Field>;
158
157
  array?: boolean | undefined;
159
158
  };
160
159
  type Type = {
161
160
  type: string;
162
- props?: null | undefined;
163
161
  array?: boolean | undefined;
164
162
  };
165
- type Event = {
163
+ type Events = {
166
164
  input: InputEvent;
167
165
  change: InputEvent;
168
166
  click: Event;
@@ -286,19 +284,19 @@ declare class Store<T = any> {
286
284
  });
287
285
  /**
288
286
  *
289
- * @template {keyof Schema.Event} K
287
+ * @template {keyof Schema.Events} K
290
288
  * @param {K} event
291
- * @param {Schema.Event[K]} value
289
+ * @param {Schema.Events[K]} value
292
290
  */
293
- emit<K extends keyof Schema.Event>(event: K, value: Schema.Event[K]): boolean;
291
+ emit<K extends keyof Schema.Events>(event: K, value: Schema.Events[K]): boolean;
294
292
  /**
295
293
  *
296
- * @template {keyof Schema.Event} K
294
+ * @template {keyof Schema.Events} K
297
295
  * @param {K} event
298
- * @param {(this: this, p: Schema.Event[K], store: this) => void | boolean | null} listener
296
+ * @param {(this: this, p: Schema.Events[K], store: this) => void | boolean | null} listener
299
297
  * @returns {() => void}
300
298
  */
301
- listen<K extends keyof Schema.Event>(event: K, listener: (this: this, p: Schema.Event[K], store: this) => void | boolean | null): () => void;
299
+ listen<K extends keyof Schema.Events>(event: K, listener: (this: this, p: Schema.Events[K], store: this) => void | boolean | null): () => void;
302
300
  get null(): boolean;
303
301
  get kind(): string;
304
302
  schema: Schema.Field;
@@ -387,7 +385,7 @@ declare class Store<T = any> {
387
385
  }
388
386
  declare class ObjectStore extends Store<any> {
389
387
  /**
390
- * @param {Schema.Field} schema
388
+ * @param {Schema.Object & Schema.Attr} schema
391
389
  * @param {object} [options]
392
390
  * @param {Store?} [options.parent]
393
391
  * @param {string | number} [options.index]
@@ -395,7 +393,7 @@ declare class ObjectStore extends Store<any> {
395
393
  * @param {(value: any, index: any) => void} [options.onUpdate]
396
394
  * @param {(value: any, index: any) => void} [options.onUpdateState]
397
395
  */
398
- constructor(schema: Schema.Field, { parent, index, new: isNew, onUpdate, onUpdateState }?: {
396
+ constructor(schema: Schema.Object & Schema.Attr, { parent, index, new: isNew, onUpdate, onUpdateState }?: {
399
397
  parent?: Store<any> | null | undefined;
400
398
  index?: string | number | undefined;
401
399
  new?: boolean | undefined;
@@ -426,9 +424,9 @@ declare function _default(store: Store, layouts: (Node | string)[], parent: Elem
426
424
  * @param {Store} store
427
425
  * @param {(Layout.Node | string)[]} layouts
428
426
  * @param {Element} parent
429
- * @param {((path: string[]) => Component?)?} [components]
427
+ * @param {Component.Getter?} [components]
430
428
  * @returns {() => void}
431
429
  */
432
- declare function _default(store: Store, layouts: (Node | string)[], parent: Element, components?: ((path: string[]) => Component | null) | null | undefined): () => void;
430
+ declare function _default(store: Store, layouts: (Node | string)[], parent: Element, components?: Component.Getter | null | undefined): () => void;
433
431
 
434
- export { Component, type ComponentGetter, index_d as Layout, Schema, Store, type VerifyError, _default as render };
432
+ export { Component, index_d as Layout, Schema, Store, type VerifyError, _default as render };
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @neeloong/form v0.4.2
2
+ * @neeloong/form v0.5.0
3
3
  * (c) 2024-2025 Fierflame
4
4
  * @license Apache-2.0
5
5
  */
@@ -697,9 +697,9 @@
697
697
  #events = new Map()
698
698
  /**
699
699
  *
700
- * @template {keyof Schema.Event} K
700
+ * @template {keyof Schema.Events} K
701
701
  * @param {K} event
702
- * @param {Schema.Event[K]} value
702
+ * @param {Schema.Events[K]} value
703
703
  */
704
704
  emit(event, value) {
705
705
  const key = typeof event === 'number' ? String(event) : event;
@@ -712,9 +712,9 @@
712
712
  }
713
713
  /**
714
714
  *
715
- * @template {keyof Schema.Event} K
715
+ * @template {keyof Schema.Events} K
716
716
  * @param {K} event
717
- * @param {(this: this, p: Schema.Event[K], store: this) => void | boolean | null} listener
717
+ * @param {(this: this, p: Schema.Events[K], store: this) => void | boolean | null} listener
718
718
  * @returns {() => void}
719
719
  */
720
720
  listen(event, listener) {
@@ -736,7 +736,7 @@
736
736
  * @param {boolean} [options.new]
737
737
  */
738
738
  static create(schema, options = {}) {
739
- return new ObjectStore({type: null, props: schema}, { ...options, parent: null });
739
+ return new ObjectStore({type: schema}, { ...options, parent: null });
740
740
  }
741
741
  #null = false;
742
742
  get null() { return this.#null; }
@@ -1179,7 +1179,7 @@
1179
1179
  */
1180
1180
  child(key) { return this.#children[key] || null; }
1181
1181
  /**
1182
- * @param {Schema.Field} schema
1182
+ * @param {Schema.Object & Schema.Attr} schema
1183
1183
  * @param {object} [options]
1184
1184
  * @param {Store?} [options.parent]
1185
1185
  * @param {string | number} [options.index]
@@ -1218,7 +1218,7 @@
1218
1218
  }
1219
1219
  };
1220
1220
 
1221
- for (const [index, field] of Object.entries(schema.props || {})) {
1221
+ for (const [index, field] of Object.entries(schema.type)) {
1222
1222
  let child;
1223
1223
  if (typeof field.type === 'string') {
1224
1224
  if (field.array) {
@@ -1229,7 +1229,7 @@
1229
1229
  } else if (field.array) {
1230
1230
  child = new ArrayStore(field, {...childCommonOptions, index});
1231
1231
  } else {
1232
- child = new ObjectStore(field, { ...childCommonOptions, index});
1232
+ child = new ObjectStore(/**@type {*}*/(field), { ...childCommonOptions, index});
1233
1233
  }
1234
1234
  children[index] = child;
1235
1235
  }
@@ -1334,9 +1334,9 @@
1334
1334
  child.index = index;
1335
1335
  return child
1336
1336
  };
1337
- } else if (!Array.isArray(schema.props)) {
1337
+ } else if (schema.type && typeof schema.type === 'object' && !Array.isArray(schema.type)) {
1338
1338
  this.#create = (index, isNew) => {
1339
- const child = new ObjectStore(schema, { ...childCommonOptions, index, new: isNew});
1339
+ const child = new ObjectStore(/** @type {*} */(schema), { ...childCommonOptions, index, new: isNew});
1340
1340
  child.index = index;
1341
1341
  return child
1342
1342
  };
@@ -2517,6 +2517,14 @@
2517
2517
  function toGlobal(global) {
2518
2518
  /** @type {Record<string, ValueDefine | ExecDefine | CalcDefine>} */
2519
2519
  const items = Object.create(null);
2520
+ items.$$size = { calc(v) {
2521
+ if (!v) { return 0; }
2522
+ if (Array.isArray(v)) { return v.length; }
2523
+ if (v instanceof Map) { return v.size; }
2524
+ if (v instanceof Set) { return v.size; }
2525
+ return Object.keys(v).length;
2526
+ } };
2527
+
2520
2528
  if (!global || typeof global !== 'object') { return items; }
2521
2529
  for (const [key, value] of Object.entries(global)) {
2522
2530
  if (!key || key.includes('$')) { continue; }
@@ -2611,12 +2619,12 @@
2611
2619
  }
2612
2620
 
2613
2621
  /**
2614
- * @param {string} name
2622
+ * @param {string | true} name
2615
2623
  * @param {string} type
2616
2624
  * @param {(value: any) => void} cb
2617
2625
  */
2618
2626
  bind(name, type, cb) {
2619
- const item = this.#items[name];
2627
+ const item = this.#items[name === true ? '' : name];
2620
2628
  if (!item?.get) { return; }
2621
2629
  const { store } = item;
2622
2630
  if (!store) {
@@ -2632,11 +2640,11 @@
2632
2640
  }
2633
2641
  }
2634
2642
  /**
2635
- * @param {string} name
2643
+ * @param {string | true} name
2636
2644
  * @returns {Record<string, ((cb: (value: any) => void) => () => void) | void> | void}
2637
2645
  */
2638
2646
  bindAll(name) {
2639
- const item = this.#items[name];
2647
+ const item = this.#items[name === true ? '' : name];
2640
2648
  if (!item?.get) { return; }
2641
2649
  const { store } = item;
2642
2650
  if (!store) {
@@ -2651,12 +2659,12 @@
2651
2659
  return res;
2652
2660
  }
2653
2661
  /**
2654
- * @param {string} name
2662
+ * @param {string | true} name
2655
2663
  * @param {string} type
2656
2664
  * @returns {((value: any) => void) | void}
2657
2665
  */
2658
2666
  bindSet(name, type) {
2659
- const item = this.#items[name];
2667
+ const item = this.#items[name === true ? '' : name];
2660
2668
  if (!item?.get) { return; }
2661
2669
  const { store } = item;
2662
2670
  if (!store) { return; }
@@ -2666,11 +2674,11 @@
2666
2674
  }
2667
2675
  }
2668
2676
  /**
2669
- * @param {string} name
2677
+ * @param {string | true} name
2670
2678
  * @returns {Record<string, (value: any) => void> | void}
2671
2679
  */
2672
2680
  bindEvents(name) {
2673
- const item = this.#items[name];
2681
+ const item = this.#items[name === true ? '' : name];
2674
2682
  if (!item?.get) { return; }
2675
2683
  const { store } = item;
2676
2684
  if (!store) {
@@ -3036,7 +3044,7 @@
3036
3044
  continue;
3037
3045
  }
3038
3046
  const bind = attr.bind;
3039
- if (!bindValue || !bind || typeof bindValue === 'boolean') {
3047
+ if (!bindValue || !bind) {
3040
3048
  handler.set(name, attr.default);
3041
3049
  continue;
3042
3050
  }
@@ -3058,8 +3066,9 @@
3058
3066
  continue;
3059
3067
  }
3060
3068
  if (!isState) {
3061
- bk.add(envs.watch(bindValue, v => handler.set(name, v)));
3062
- handler.addEvent(event, (...args) => { envs.all[bindValue] = set(...args);});
3069
+ const bindKey = bindValue === true ? '' : bindValue;
3070
+ bk.add(envs.watch(bindKey, v => handler.set(name, v)));
3071
+ handler.addEvent(event, (...args) => { envs.all[bindKey] = set(...args);});
3063
3072
  continue;
3064
3073
  }
3065
3074
  const r = envs.bind(bindValue, 'state', v => handler.set(name, v));
@@ -3296,7 +3305,6 @@
3296
3305
 
3297
3306
  /** @import { Component } from '../types.mjs' */
3298
3307
  /** @import Environment from './Environment/index.mjs' */
3299
- /** @import Store from '../Store/index.mjs' */
3300
3308
 
3301
3309
 
3302
3310
  /** @type {Record<string, Component.Event.Filter>} */
@@ -3345,7 +3353,7 @@
3345
3353
  if (evt instanceof KeyboardEvent) {
3346
3354
  const key = evt.code.toLowerCase().replace(/-/g, '');
3347
3355
  for (const k of param) {
3348
- if (key === k.toLowerCase().replace(/-/g, '')) { return true }
3356
+ if (key === k.toLowerCase().replace(/-/g, '')) { return true; }
3349
3357
  }
3350
3358
  return false;
3351
3359
  }
@@ -3384,34 +3392,34 @@
3384
3392
  if (evt instanceof PointerEvent) {
3385
3393
  const pointerType = evt.pointerType.toLowerCase().replace(/-/g, '');
3386
3394
  for (const k of param) {
3387
- if (pointerType === k.toLowerCase().replace(/-/g, '')) { return true }
3395
+ if (pointerType === k.toLowerCase().replace(/-/g, '')) { return true; }
3388
3396
  }
3389
3397
  return false;
3390
3398
  }
3391
3399
  },
3392
3400
 
3393
3401
  ctrl(evt) {
3394
- if (evt instanceof MouseEvent|| evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3402
+ if (evt instanceof MouseEvent || evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3395
3403
  return evt.ctrlKey;
3396
3404
  }
3397
3405
  },
3398
3406
  alt(evt) {
3399
- if (evt instanceof MouseEvent|| evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3407
+ if (evt instanceof MouseEvent || evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3400
3408
  return evt.altKey;
3401
3409
  }
3402
3410
  },
3403
3411
  shift(evt) {
3404
- if (evt instanceof MouseEvent|| evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3412
+ if (evt instanceof MouseEvent || evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3405
3413
  return evt.shiftKey;
3406
3414
  }
3407
3415
  },
3408
3416
  meta(evt) {
3409
- if (evt instanceof MouseEvent|| evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3417
+ if (evt instanceof MouseEvent || evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3410
3418
  return evt.metaKey;
3411
3419
  }
3412
3420
  },
3413
3421
  cmd(evt) {
3414
- if (evt instanceof MouseEvent|| evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3422
+ if (evt instanceof MouseEvent || evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3415
3423
  return evt.ctrlKey || evt.metaKey;
3416
3424
  }
3417
3425
  },
@@ -3424,25 +3432,45 @@
3424
3432
  */
3425
3433
  function createContext(component, env) {
3426
3434
  const tag = typeof component === 'string' ? component : component.tag;
3427
- const { attrs, events } = typeof component !== 'string' && component || {attrs: null, events: null };
3435
+ const { attrs, events } = typeof component !== 'string' && component || { attrs: null, events: null };
3428
3436
 
3429
3437
  let destroyed = false;
3430
- let init = false;
3438
+ const destroyedState = new exports.Signal.State(false);
3439
+ let mounted = false;
3440
+ const mountedState = new exports.Signal.State(false);
3441
+ /** @type {Record<string, Signal.State<any> | void>} */
3442
+ const attrStates = Object.create(null);
3431
3443
  const tagAttrs = Object.create(null);
3432
3444
 
3445
+ const attrWatchers = new Set();
3446
+
3433
3447
  /** @type {[string, ($event: any) => void, AddEventListenerOptions][]} */
3434
3448
  const allEvents = [];
3435
3449
  const stateEmitter = new EventEmitter();
3436
- /** @type {EventEmitter<Record<string, [any, any, string]>>} */
3437
- const attrEmitter = new EventEmitter();
3438
3450
  /** @type {Component.Context} */
3439
3451
  const context = {
3440
3452
  events: allEvents,
3441
- props: attrs ? new Set(Object.entries(attrs).filter(([,a]) => a.isProp).map(([e]) => e)) : null,
3453
+ props: attrs ? new Set(Object.entries(attrs).filter(([, a]) => a.isProp).map(([e]) => e)) : null,
3442
3454
  tagAttrs,
3443
- watchAttr(name, fn) { return attrEmitter.listen(name, fn); },
3444
- get destroyed() { return destroyed},
3445
- get init() { return init},
3455
+ watchAttr(name, fn) {
3456
+ if (destroyed) { return () => { }; }
3457
+ const state = attrStates[name];
3458
+ if (!state) { return () => { }; }
3459
+ let old = state.get();
3460
+ const w = watch(() => state.get(), v => {
3461
+ const o = old;
3462
+ old = v;
3463
+ fn(v, o, name);
3464
+ });
3465
+ attrWatchers.add(w);
3466
+
3467
+ return () => {
3468
+ attrWatchers.delete(w);
3469
+ w();
3470
+ };
3471
+ },
3472
+ get destroyed() { return destroyedState.get(); },
3473
+ get init() { return mountedState.get(); },
3446
3474
  listen(name, listener) { return stateEmitter.listen(name, listener); },
3447
3475
  };
3448
3476
  /** @type {Component.Handler} */
@@ -3450,11 +3478,18 @@
3450
3478
  tag,
3451
3479
  set(name, value) {
3452
3480
  if (attrs && !(name in attrs)) { return; }
3453
- if (!(name in tagAttrs)) { tagAttrs[name] = void 0; }
3454
- const old = tagAttrs[name];
3455
- if (old === value) { return; }
3456
- tagAttrs[name] = value;
3457
- attrEmitter.emit(name, value, old, name);
3481
+ let state = attrStates[name];
3482
+ if (state) {
3483
+ state.set(value);
3484
+ return;
3485
+ }
3486
+ const s = new exports.Signal.State(value);
3487
+ attrStates[name] = s;
3488
+ Object.defineProperty(tagAttrs, name, {
3489
+ configurable: true,
3490
+ enumerable: true,
3491
+ get: s.get.bind(s),
3492
+ });
3458
3493
  },
3459
3494
  addEvent(name, fn) {
3460
3495
  if (typeof fn !== 'function') { return; }
@@ -3465,14 +3500,14 @@
3465
3500
  const options = {};
3466
3501
  /** @type {[Component.Event.Filter, string[], boolean][]} */
3467
3502
  const filterFns = [];
3468
- if (filters) for (let f = fs.shift();f;f = fs.shift()) {
3503
+ if (filters) for (let f = fs.shift(); f; f = fs.shift()) {
3469
3504
  const paramIndex = f.indexOf(':');
3470
3505
  const noParamName = paramIndex >= 0 ? f.slice(0, paramIndex) : f;
3471
3506
  const param = paramIndex >= 0 ? f.slice(paramIndex + 1).split(':') : [];
3472
3507
  const filterName = noParamName.replace(/^-+/, '');
3473
3508
  const sub = (noParamName.length - filterName.length) % 2 === 1;
3474
3509
  let filter = filters[filterName] || filterName;
3475
- switch(filter) {
3510
+ switch (filter) {
3476
3511
  case 'once':
3477
3512
  options.once = !sub;
3478
3513
  break;
@@ -3493,20 +3528,25 @@
3493
3528
  allEvents.push([e, $event => {
3494
3529
  const global = env.all;
3495
3530
  for (const [filter, param, sub] of filterFns) {
3496
- if (filter($event, param, global) === sub) { return}
3531
+ if (filter($event, param, global) === sub) { return; }
3497
3532
  }
3498
3533
  fn($event, global);
3499
3534
  }, options]);
3500
3535
  },
3501
3536
  destroy() {
3502
- if (destroyed) { return }
3537
+ if (destroyed) { return; }
3503
3538
  destroyed = true;
3539
+ destroyedState.set(true);
3540
+ for (const w of attrWatchers) {
3541
+ w();
3542
+ }
3504
3543
  stateEmitter.emit('destroy');
3505
3544
  },
3506
- init() {
3507
- if (init) { return }
3508
- init = true;
3509
- stateEmitter.emit('init', {events: allEvents});
3545
+ mount() {
3546
+ if (mounted) { return; }
3547
+ mounted = true;
3548
+ mountedState.set(true);
3549
+ stateEmitter.emit('init', { events: allEvents });
3510
3550
  },
3511
3551
 
3512
3552
  };
@@ -4119,7 +4159,7 @@
4119
4159
  * @param {string | boolean | null} [bind]
4120
4160
  */
4121
4161
  function bindBase(handler, env, bind) {
4122
- if (!bind || typeof bind === 'boolean') { return () => {}; }
4162
+ if (!bind) { return () => {}; }
4123
4163
  let bk = new Set();
4124
4164
  for (const [key, effect] of Object.entries(env.bindAll(bind) || {})) {
4125
4165
  if (typeof effect !== 'function') { continue; }
@@ -4147,7 +4187,7 @@
4147
4187
  * @param {Environment} env
4148
4188
  * @param {Record<string, [Layout.Node, Environment]>} templates
4149
4189
  * @param {string[]} componentPath
4150
- * @param {((path: string[]) => Component?)?} [getComponent]
4190
+ * @param {Component.Getter?} [getComponent]
4151
4191
  */
4152
4192
  function renderItem(layout, parent, next, env, templates, componentPath, getComponent) {
4153
4193
  env = env.set(layout.aliases, layout.vars);
@@ -4203,7 +4243,7 @@
4203
4243
  bindClasses(root, layout.classes, env);
4204
4244
  bindStyles(root, layout.styles, env);
4205
4245
 
4206
- handler.init();
4246
+ handler.mount();
4207
4247
 
4208
4248
  return () => {
4209
4249
  root.remove();
@@ -4221,7 +4261,7 @@
4221
4261
  * @param {Environment} env
4222
4262
  * @param {Record<string, [Layout.Node, Environment]>} templates
4223
4263
  * @param {string[]} componentPath
4224
- * @param {((path: string[]) => Component?)?} [getComponent]
4264
+ * @param {Component.Getter?} [getComponent]
4225
4265
  * @returns {() => void}
4226
4266
  */
4227
4267
  function render(layout, parent, next, env, templates, componentPath, getComponent) {
@@ -4260,15 +4300,15 @@
4260
4300
  * @param {Store} store
4261
4301
  * @param {(Layout.Node | string)[]} layouts
4262
4302
  * @param {Element} parent
4263
- * @param {((path: string[]) => Component?)?} [components]
4303
+ * @param {Component.Getter?} [components]
4264
4304
  * @returns {() => void}
4265
4305
  */
4266
4306
  /**
4267
4307
  * @param {Store} store
4268
4308
  * @param {(Layout.Node | string)[]} layouts
4269
4309
  * @param {Element} parent
4270
- * @param {((path: string[]) => Component?) | Record<string, Store | {get?(): any; set?(v: any): void; exec?(...p: any[]): any; calc?(...p: any[]): any }> | null} [opt1]
4271
- * @param {((path: string[]) => Component?) | Record<string, Store | {get?(): any; set?(v: any): void; exec?(...p: any[]): any; calc?(...p: any[]): any }> | null} [opt2]
4310
+ * @param {Component.Getter | Record<string, Store | {get?(): any; set?(v: any): void; exec?(...p: any[]): any; calc?(...p: any[]): any }> | null} [opt1]
4311
+ * @param {Component.Getter | Record<string, Store | {get?(): any; set?(v: any): void; exec?(...p: any[]): any; calc?(...p: any[]): any }> | null} [opt2]
4272
4312
  */
4273
4313
  function index (store, layouts, parent, opt1, opt2) {
4274
4314
  const options = [opt1, opt2];