@neeloong/form 0.4.1 → 0.4.3

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.1
2
+ * @neeloong/form v0.4.3
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;
@@ -162,7 +162,7 @@ declare namespace Schema {
162
162
  props?: null | undefined;
163
163
  array?: boolean | undefined;
164
164
  };
165
- type Event = {
165
+ type Events = {
166
166
  input: InputEvent;
167
167
  change: InputEvent;
168
168
  click: Event;
@@ -286,19 +286,19 @@ declare class Store<T = any> {
286
286
  });
287
287
  /**
288
288
  *
289
- * @template {keyof Schema.Event} K
289
+ * @template {keyof Schema.Events} K
290
290
  * @param {K} event
291
- * @param {Schema.Event[K]} value
291
+ * @param {Schema.Events[K]} value
292
292
  */
293
- emit<K extends keyof Schema.Event>(event: K, value: Schema.Event[K]): boolean;
293
+ emit<K extends keyof Schema.Events>(event: K, value: Schema.Events[K]): boolean;
294
294
  /**
295
295
  *
296
- * @template {keyof Schema.Event} K
296
+ * @template {keyof Schema.Events} K
297
297
  * @param {K} event
298
- * @param {(this: this, p: Schema.Event[K], store: this) => void | boolean | null} listener
298
+ * @param {(this: this, p: Schema.Events[K], store: this) => void | boolean | null} listener
299
299
  * @returns {() => void}
300
300
  */
301
- listen<K extends keyof Schema.Event>(event: K, listener: (this: this, p: Schema.Event[K], store: this) => void | boolean | null): () => void;
301
+ listen<K extends keyof Schema.Events>(event: K, listener: (this: this, p: Schema.Events[K], store: this) => void | boolean | null): () => void;
302
302
  get null(): boolean;
303
303
  get kind(): string;
304
304
  schema: Schema.Field;
@@ -426,9 +426,9 @@ declare function _default(store: Store, layouts: (Node | string)[], parent: Elem
426
426
  * @param {Store} store
427
427
  * @param {(Layout.Node | string)[]} layouts
428
428
  * @param {Element} parent
429
- * @param {((path: string[]) => Component?)?} [components]
429
+ * @param {Component.Getter?} [components]
430
430
  * @returns {() => void}
431
431
  */
432
- declare function _default(store: Store, layouts: (Node | string)[], parent: Element, components?: ((path: string[]) => Component | null) | null | undefined): () => void;
432
+ declare function _default(store: Store, layouts: (Node | string)[], parent: Element, components?: Component.Getter | null | undefined): () => void;
433
433
 
434
- export { Component, type ComponentGetter, index_d as Layout, Schema, Store, type VerifyError, _default as render };
434
+ 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.1
2
+ * @neeloong/form v0.4.3
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) {
@@ -2611,12 +2611,12 @@
2611
2611
  }
2612
2612
 
2613
2613
  /**
2614
- * @param {string} name
2614
+ * @param {string | true} name
2615
2615
  * @param {string} type
2616
2616
  * @param {(value: any) => void} cb
2617
2617
  */
2618
2618
  bind(name, type, cb) {
2619
- const item = this.#items[name];
2619
+ const item = this.#items[name === true ? '' : name];
2620
2620
  if (!item?.get) { return; }
2621
2621
  const { store } = item;
2622
2622
  if (!store) {
@@ -2632,11 +2632,11 @@
2632
2632
  }
2633
2633
  }
2634
2634
  /**
2635
- * @param {string} name
2635
+ * @param {string | true} name
2636
2636
  * @returns {Record<string, ((cb: (value: any) => void) => () => void) | void> | void}
2637
2637
  */
2638
2638
  bindAll(name) {
2639
- const item = this.#items[name];
2639
+ const item = this.#items[name === true ? '' : name];
2640
2640
  if (!item?.get) { return; }
2641
2641
  const { store } = item;
2642
2642
  if (!store) {
@@ -2651,12 +2651,12 @@
2651
2651
  return res;
2652
2652
  }
2653
2653
  /**
2654
- * @param {string} name
2654
+ * @param {string | true} name
2655
2655
  * @param {string} type
2656
2656
  * @returns {((value: any) => void) | void}
2657
2657
  */
2658
2658
  bindSet(name, type) {
2659
- const item = this.#items[name];
2659
+ const item = this.#items[name === true ? '' : name];
2660
2660
  if (!item?.get) { return; }
2661
2661
  const { store } = item;
2662
2662
  if (!store) { return; }
@@ -2666,37 +2666,21 @@
2666
2666
  }
2667
2667
  }
2668
2668
  /**
2669
- * @param {string} name
2669
+ * @param {string | true} name
2670
2670
  * @returns {Record<string, (value: any) => void> | void}
2671
2671
  */
2672
- bindStateAllSet(name) {
2673
- const item = this.#items[name];
2672
+ bindEvents(name) {
2673
+ const item = this.#items[name === true ? '' : name];
2674
2674
  if (!item?.get) { return; }
2675
2675
  const { store } = item;
2676
2676
  if (!store) {
2677
2677
  const set = item.set;
2678
2678
  if (typeof set !== 'function') { return; }
2679
2679
  return { '$value': set }
2680
- }
2680
+ }
2681
2681
  return {
2682
2682
  '$value': v => {store.value = v; },
2683
2683
  '$state': v => {store.state = v; },
2684
- }
2685
- }
2686
- /**
2687
- * @param {string} name
2688
- * @returns {Record<string, (value: any) => void> | void}
2689
- */
2690
- bindEvents(name) {
2691
- const item = this.#items[name];
2692
- if (!item?.get) { return; }
2693
- const { store } = item;
2694
- if (!store) {
2695
- const set = item.set;
2696
- if (typeof set !== 'function') { return; }
2697
- return { '$value': set }
2698
- }
2699
- return {
2700
2684
  '$input': v => {store.emit('input', v); },
2701
2685
  '$change': v => {store.emit('change', v); },
2702
2686
  '$click': v => {store.emit('click', v); },
@@ -3052,7 +3036,7 @@
3052
3036
  continue;
3053
3037
  }
3054
3038
  const bind = attr.bind;
3055
- if (!bindValue || !bind || typeof bindValue === 'boolean') {
3039
+ if (!bindValue || !bind) {
3056
3040
  handler.set(name, attr.default);
3057
3041
  continue;
3058
3042
  }
@@ -3074,8 +3058,9 @@
3074
3058
  continue;
3075
3059
  }
3076
3060
  if (!isState) {
3077
- bk.add(envs.watch(bindValue, v => handler.set(name, v)));
3078
- handler.addEvent(event, (...args) => { envs.all[bindValue] = set(...args);});
3061
+ const bindKey = bindValue === true ? '' : bindValue;
3062
+ bk.add(envs.watch(bindKey, v => handler.set(name, v)));
3063
+ handler.addEvent(event, (...args) => { envs.all[bindKey] = set(...args);});
3079
3064
  continue;
3080
3065
  }
3081
3066
  const r = envs.bind(bindValue, 'state', v => handler.set(name, v));
@@ -3103,9 +3088,8 @@
3103
3088
  * @param {Component.Handler} handler
3104
3089
  * @param {Environment} envs
3105
3090
  * @param {Record<string, string | {name: string} | Layout.Calc>} attrs
3106
- * @param {string | boolean | null} [bindValue]
3107
3091
  */
3108
- function bindBaseAttrs(handler, envs, attrs, bindValue) {
3092
+ function bindBaseAttrs(handler, envs, attrs) {
3109
3093
  const tag = handler.tag;
3110
3094
  let bk = new Set();
3111
3095
  for (const [name, attr] of Object.entries(attrs)) {
@@ -3121,16 +3105,6 @@
3121
3105
  }
3122
3106
  bk.add(envs.watch(attrSchema, val => handler.set(name, val)));
3123
3107
  }
3124
- if (bindValue && typeof bindValue !== 'boolean') {
3125
- for (const [key, effect] of Object.entries(envs.bindAll(bindValue) || {})) {
3126
- if (typeof effect !== 'function') { continue; }
3127
- bk.add(effect(val => handler.set(key, val)));
3128
- }
3129
- for (const [key, setter] of Object.entries(envs.bindStateAllSet(bindValue) || {})) {
3130
- if (typeof setter !== 'function') { continue; }
3131
- handler.addEvent(key, $event => setter($event));
3132
- }
3133
- }
3134
3108
 
3135
3109
  return ()=> {
3136
3110
  const list = bk;
@@ -3323,7 +3297,6 @@
3323
3297
 
3324
3298
  /** @import { Component } from '../types.mjs' */
3325
3299
  /** @import Environment from './Environment/index.mjs' */
3326
- /** @import Store from '../Store/index.mjs' */
3327
3300
 
3328
3301
 
3329
3302
  /** @type {Record<string, Component.Event.Filter>} */
@@ -3372,7 +3345,7 @@
3372
3345
  if (evt instanceof KeyboardEvent) {
3373
3346
  const key = evt.code.toLowerCase().replace(/-/g, '');
3374
3347
  for (const k of param) {
3375
- if (key === k.toLowerCase().replace(/-/g, '')) { return true }
3348
+ if (key === k.toLowerCase().replace(/-/g, '')) { return true; }
3376
3349
  }
3377
3350
  return false;
3378
3351
  }
@@ -3411,34 +3384,34 @@
3411
3384
  if (evt instanceof PointerEvent) {
3412
3385
  const pointerType = evt.pointerType.toLowerCase().replace(/-/g, '');
3413
3386
  for (const k of param) {
3414
- if (pointerType === k.toLowerCase().replace(/-/g, '')) { return true }
3387
+ if (pointerType === k.toLowerCase().replace(/-/g, '')) { return true; }
3415
3388
  }
3416
3389
  return false;
3417
3390
  }
3418
3391
  },
3419
3392
 
3420
3393
  ctrl(evt) {
3421
- if (evt instanceof MouseEvent|| evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3394
+ if (evt instanceof MouseEvent || evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3422
3395
  return evt.ctrlKey;
3423
3396
  }
3424
3397
  },
3425
3398
  alt(evt) {
3426
- if (evt instanceof MouseEvent|| evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3399
+ if (evt instanceof MouseEvent || evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3427
3400
  return evt.altKey;
3428
3401
  }
3429
3402
  },
3430
3403
  shift(evt) {
3431
- if (evt instanceof MouseEvent|| evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3404
+ if (evt instanceof MouseEvent || evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3432
3405
  return evt.shiftKey;
3433
3406
  }
3434
3407
  },
3435
3408
  meta(evt) {
3436
- if (evt instanceof MouseEvent|| evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3409
+ if (evt instanceof MouseEvent || evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3437
3410
  return evt.metaKey;
3438
3411
  }
3439
3412
  },
3440
3413
  cmd(evt) {
3441
- if (evt instanceof MouseEvent|| evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3414
+ if (evt instanceof MouseEvent || evt instanceof KeyboardEvent || evt instanceof TouchEvent) {
3442
3415
  return evt.ctrlKey || evt.metaKey;
3443
3416
  }
3444
3417
  },
@@ -3451,25 +3424,45 @@
3451
3424
  */
3452
3425
  function createContext(component, env) {
3453
3426
  const tag = typeof component === 'string' ? component : component.tag;
3454
- const { attrs, events } = typeof component !== 'string' && component || {attrs: null, events: null };
3427
+ const { attrs, events } = typeof component !== 'string' && component || { attrs: null, events: null };
3455
3428
 
3456
3429
  let destroyed = false;
3457
- let init = false;
3430
+ const destroyedState = new exports.Signal.State(false);
3431
+ let mounted = false;
3432
+ const mountedState = new exports.Signal.State(false);
3433
+ /** @type {Record<string, Signal.State<any> | void>} */
3434
+ const attrStates = Object.create(null);
3458
3435
  const tagAttrs = Object.create(null);
3459
3436
 
3437
+ const attrWatchers = new Set();
3438
+
3460
3439
  /** @type {[string, ($event: any) => void, AddEventListenerOptions][]} */
3461
3440
  const allEvents = [];
3462
3441
  const stateEmitter = new EventEmitter();
3463
- /** @type {EventEmitter<Record<string, [any, any, string]>>} */
3464
- const attrEmitter = new EventEmitter();
3465
3442
  /** @type {Component.Context} */
3466
3443
  const context = {
3467
3444
  events: allEvents,
3468
- props: attrs ? new Set(Object.entries(attrs).filter(([,a]) => a.isProp).map(([e]) => e)) : null,
3445
+ props: attrs ? new Set(Object.entries(attrs).filter(([, a]) => a.isProp).map(([e]) => e)) : null,
3469
3446
  tagAttrs,
3470
- watchAttr(name, fn) { return attrEmitter.listen(name, fn); },
3471
- get destroyed() { return destroyed},
3472
- get init() { return init},
3447
+ watchAttr(name, fn) {
3448
+ if (destroyed) { return () => { }; }
3449
+ const state = attrStates[name];
3450
+ if (!state) { return () => { }; }
3451
+ let old = state.get();
3452
+ const w = watch(() => state.get(), v => {
3453
+ const o = old;
3454
+ old = v;
3455
+ fn(v, o, name);
3456
+ });
3457
+ attrWatchers.add(w);
3458
+
3459
+ return () => {
3460
+ attrWatchers.delete(w);
3461
+ w();
3462
+ };
3463
+ },
3464
+ get destroyed() { return destroyedState.get(); },
3465
+ get init() { return mountedState.get(); },
3473
3466
  listen(name, listener) { return stateEmitter.listen(name, listener); },
3474
3467
  };
3475
3468
  /** @type {Component.Handler} */
@@ -3477,11 +3470,18 @@
3477
3470
  tag,
3478
3471
  set(name, value) {
3479
3472
  if (attrs && !(name in attrs)) { return; }
3480
- if (!(name in tagAttrs)) { tagAttrs[name] = void 0; }
3481
- const old = tagAttrs[name];
3482
- if (old === value) { return; }
3483
- tagAttrs[name] = value;
3484
- attrEmitter.emit(name, value, old, name);
3473
+ let state = attrStates[name];
3474
+ if (state) {
3475
+ state.set(value);
3476
+ return;
3477
+ }
3478
+ const s = new exports.Signal.State(value);
3479
+ attrStates[name] = s;
3480
+ Object.defineProperty(tagAttrs, name, {
3481
+ configurable: true,
3482
+ enumerable: true,
3483
+ get: s.get.bind(s),
3484
+ });
3485
3485
  },
3486
3486
  addEvent(name, fn) {
3487
3487
  if (typeof fn !== 'function') { return; }
@@ -3492,14 +3492,14 @@
3492
3492
  const options = {};
3493
3493
  /** @type {[Component.Event.Filter, string[], boolean][]} */
3494
3494
  const filterFns = [];
3495
- if (filters) for (let f = fs.shift();f;f = fs.shift()) {
3495
+ if (filters) for (let f = fs.shift(); f; f = fs.shift()) {
3496
3496
  const paramIndex = f.indexOf(':');
3497
3497
  const noParamName = paramIndex >= 0 ? f.slice(0, paramIndex) : f;
3498
3498
  const param = paramIndex >= 0 ? f.slice(paramIndex + 1).split(':') : [];
3499
3499
  const filterName = noParamName.replace(/^-+/, '');
3500
3500
  const sub = (noParamName.length - filterName.length) % 2 === 1;
3501
3501
  let filter = filters[filterName] || filterName;
3502
- switch(filter) {
3502
+ switch (filter) {
3503
3503
  case 'once':
3504
3504
  options.once = !sub;
3505
3505
  break;
@@ -3520,20 +3520,25 @@
3520
3520
  allEvents.push([e, $event => {
3521
3521
  const global = env.all;
3522
3522
  for (const [filter, param, sub] of filterFns) {
3523
- if (filter($event, param, global) === sub) { return}
3523
+ if (filter($event, param, global) === sub) { return; }
3524
3524
  }
3525
3525
  fn($event, global);
3526
3526
  }, options]);
3527
3527
  },
3528
3528
  destroy() {
3529
- if (destroyed) { return }
3529
+ if (destroyed) { return; }
3530
3530
  destroyed = true;
3531
+ destroyedState.set(true);
3532
+ for (const w of attrWatchers) {
3533
+ w();
3534
+ }
3531
3535
  stateEmitter.emit('destroy');
3532
3536
  },
3533
- init() {
3534
- if (init) { return }
3535
- init = true;
3536
- stateEmitter.emit('init', {events: allEvents});
3537
+ mount() {
3538
+ if (mounted) { return; }
3539
+ mounted = true;
3540
+ mountedState.set(true);
3541
+ stateEmitter.emit('init', { events: allEvents });
3537
3542
  },
3538
3543
 
3539
3544
  };
@@ -4137,6 +4142,34 @@
4137
4142
  };
4138
4143
  }
4139
4144
 
4145
+ /** @import { Component } from '../types.mjs' */
4146
+
4147
+
4148
+ /**
4149
+ * @param {Component.Handler} handler
4150
+ * @param {Environment} env
4151
+ * @param {string | boolean | null} [bind]
4152
+ */
4153
+ function bindBase(handler, env, bind) {
4154
+ if (!bind) { return () => {}; }
4155
+ let bk = new Set();
4156
+ for (const [key, effect] of Object.entries(env.bindAll(bind) || {})) {
4157
+ if (typeof effect !== 'function') { continue; }
4158
+ bk.add(effect(val => handler.set(key, val)));
4159
+ }
4160
+ for (const [key, setter] of Object.entries(env.bindEvents(bind) || {})) {
4161
+ handler.addEvent(key, $event => setter($event));
4162
+ }
4163
+
4164
+ return ()=> {
4165
+ const list = bk;
4166
+ bk = new Set();
4167
+ for (const s of list) {
4168
+ s();
4169
+ }
4170
+ }
4171
+ }
4172
+
4140
4173
  /** @import Store from '../Store/index.mjs' */
4141
4174
 
4142
4175
  /**
@@ -4146,7 +4179,7 @@
4146
4179
  * @param {Environment} env
4147
4180
  * @param {Record<string, [Layout.Node, Environment]>} templates
4148
4181
  * @param {string[]} componentPath
4149
- * @param {((path: string[]) => Component?)?} [getComponent]
4182
+ * @param {Component.Getter?} [getComponent]
4150
4183
  */
4151
4184
  function renderItem(layout, parent, next, env, templates, componentPath, getComponent) {
4152
4185
  env = env.set(layout.aliases, layout.vars);
@@ -4174,18 +4207,15 @@
4174
4207
  const componentAttrs = component?.attrs;
4175
4208
  const attrs = componentAttrs
4176
4209
  ? bindAttrs(handler, env, layout.attrs, componentAttrs, bind)
4177
- : bindBaseAttrs(handler, env, layout.attrs, bind);
4210
+ : bindBaseAttrs(handler, env, layout.attrs);
4178
4211
 
4179
4212
  for (const [name, event] of Object.entries(layout.events)) {
4180
4213
  const fn = env.getEvent(event);
4181
4214
  if (fn) { handler.addEvent(name, fn); }
4182
4215
  }
4183
4216
 
4184
- if (bind && typeof bind !== 'boolean') {
4185
- for (const [key, event] of Object.entries(env.bindEvents(bind) || {})) {
4186
- handler.addEvent(key, event);
4187
- }
4188
- }
4217
+ const base = bindBase(handler, env, bind);
4218
+
4189
4219
 
4190
4220
  const r = component ?
4191
4221
  typeof component.tag === 'function'
@@ -4205,13 +4235,14 @@
4205
4235
  bindClasses(root, layout.classes, env);
4206
4236
  bindStyles(root, layout.styles, env);
4207
4237
 
4208
- handler.init();
4238
+ handler.mount();
4209
4239
 
4210
4240
  return () => {
4211
4241
  root.remove();
4212
4242
  handler.destroy();
4213
4243
  attrs();
4214
4244
  children();
4245
+ base();
4215
4246
  };
4216
4247
  }
4217
4248
  /**
@@ -4222,7 +4253,7 @@
4222
4253
  * @param {Environment} env
4223
4254
  * @param {Record<string, [Layout.Node, Environment]>} templates
4224
4255
  * @param {string[]} componentPath
4225
- * @param {((path: string[]) => Component?)?} [getComponent]
4256
+ * @param {Component.Getter?} [getComponent]
4226
4257
  * @returns {() => void}
4227
4258
  */
4228
4259
  function render(layout, parent, next, env, templates, componentPath, getComponent) {
@@ -4261,15 +4292,15 @@
4261
4292
  * @param {Store} store
4262
4293
  * @param {(Layout.Node | string)[]} layouts
4263
4294
  * @param {Element} parent
4264
- * @param {((path: string[]) => Component?)?} [components]
4295
+ * @param {Component.Getter?} [components]
4265
4296
  * @returns {() => void}
4266
4297
  */
4267
4298
  /**
4268
4299
  * @param {Store} store
4269
4300
  * @param {(Layout.Node | string)[]} layouts
4270
4301
  * @param {Element} parent
4271
- * @param {((path: string[]) => Component?) | Record<string, Store | {get?(): any; set?(v: any): void; exec?(...p: any[]): any; calc?(...p: any[]): any }> | null} [opt1]
4272
- * @param {((path: string[]) => Component?) | Record<string, Store | {get?(): any; set?(v: any): void; exec?(...p: any[]): any; calc?(...p: any[]): any }> | null} [opt2]
4302
+ * @param {Component.Getter | Record<string, Store | {get?(): any; set?(v: any): void; exec?(...p: any[]): any; calc?(...p: any[]): any }> | null} [opt1]
4303
+ * @param {Component.Getter | Record<string, Store | {get?(): any; set?(v: any): void; exec?(...p: any[]): any; calc?(...p: any[]): any }> | null} [opt2]
4273
4304
  */
4274
4305
  function index (store, layouts, parent, opt1, opt2) {
4275
4306
  const options = [opt1, opt2];