@neeloong/form 0.28.0 → 0.29.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.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @neeloong/form v0.28.0
2
+ * @neeloong/form v0.29.0
3
3
  * (c) 2024-2026 Fierflame
4
4
  * @license Apache-2.0
5
5
  */
@@ -138,7 +138,7 @@ function createRef(store) {
138
138
 
139
139
 
140
140
  /** @type {{new(...p: ConstructorParameters<typeof Store>): Store}?} */
141
- let ObjectStore$2 = null;
141
+ let ObjectStore$1 = null;
142
142
  /** @type {{new(...p: ConstructorParameters<typeof Store>): ArrayStore}?} */
143
143
  let ArrayStoreClass = null;
144
144
  /** @type {Record<string, {new(...p: ConstructorParameters<typeof Store>): Store}?>} */
@@ -163,14 +163,14 @@ function create(schema, options) {
163
163
  const C = TypeStores[type];
164
164
  if (C) { Class = C; }
165
165
  } else if (type && typeof type === 'object') {
166
- if (ObjectStore$2) { Class = ObjectStore$2; }
166
+ if (ObjectStore$1) { Class = ObjectStore$1; }
167
167
  }
168
168
  return new Class(schema, options);
169
169
  }
170
170
 
171
171
  /** @param {{new(...p: ConstructorParameters<typeof Store>): Store}} Class */
172
172
  function setObjectStore(Class) {
173
- ObjectStore$2 = Class;
173
+ ObjectStore$1 = Class;
174
174
  }
175
175
 
176
176
  /** @param {{new(...p: ConstructorParameters<typeof Store>): ArrayStore}} Class */
@@ -292,52 +292,6 @@ function makeDefault(store, def) {
292
292
  return (value) => structuredClone(def(store, value));
293
293
  }
294
294
 
295
- /** @import { Schema } from '../Schema.types.mjs' */
296
-
297
- /**
298
- * @template [T=any]
299
- * @template [M=any]
300
- * @template {Object.<string, Schema.State>} [S=Object.<string, Schema.State>]
301
- * @extends {Store<T, M, S>}
302
- */
303
- class BindObjectStore extends Store {
304
-
305
- get kind() { return 'object'; }
306
- /** @type {Record<string, Store>} */
307
- #children = Object.create(null);
308
- *[Symbol.iterator]() { yield* Object.entries(this.#children); }
309
- /**
310
- *
311
- * @param {string | number} key
312
- * @returns {Store?}
313
- */
314
- child(key) { return this.#children[key] || null; }
315
- /**
316
- * @param {Schema<any, Object.<string, Schema.State>>} schema 数据结构模式
317
- * @param {Store<T, M, S>} store
318
- */
319
- constructor(schema, store) {
320
- super(store);
321
- const children = this.#children;
322
- for (const [index, field] of Object.entries(schema)) {
323
- const bindStore = create(field, {
324
- index, parent: this,
325
- /** @param {*} value @param {*} index @param {Store} store */
326
- onUpdate: (value, index, store) => {
327
- if (store !== children[index]) { return; }
328
- const val = this.value ?? null;
329
- if (typeof val !== 'object' || Array.isArray(val)) { return; }
330
- // @ts-ignore
331
- this.value = { ...val, [index]: value };
332
- },
333
- });
334
- children[index] = bindStore;
335
- }
336
- }
337
- }
338
- // @ts-ignore
339
- setObjectStore(ObjectStore);
340
-
341
295
  /** @import { Ref } from './ref.mjs' */
342
296
  /** @import { Schema } from '../Schema.types.mjs' */
343
297
  /** @import { StoreLayout } from '../StoreLayout.types.mjs' */
@@ -426,116 +380,91 @@ class Store {
426
380
  get ref() { return this.#ref || createRef(this); }
427
381
  /**
428
382
  * @param {Schema.Field<M, S> | Store<T,M,S>} schema 字段的 Schema 定义
429
- * @param {object} [options] 可选配置
430
- * @param {Store?} [options.parent]
431
- * @param {Partial<S>?} [options.states]
432
- * @param {((store: Store, value?: any) => any) | object | number | string | boolean | null | undefined} [options.default]
433
- * @param {number | string | null} [options.index]
434
- * @param {number | Signal.State<number> | Signal.Computed<number>} [options.size]
435
- * @param {boolean} [options.null]
436
- * @param {boolean} [options.new]
437
- * @param {boolean} [options.hidden]
438
- * @param {boolean} [options.clearable]
439
- * @param {boolean} [options.required]
440
- * @param {boolean} [options.disabled]
441
- * @param {boolean} [options.readonly]
442
- * @param {boolean} [options.removable]
443
- *
444
- * @param {string} [options.label] 字段标签
445
- * @param {string} [options.description] 字段描述
446
- * @param {string} [options.placeholder] 占位符
447
- * @param {number} [options.min] 日期、时间、数字的最小值
448
- * @param {number} [options.max] 日期、时间、数字的最大值
449
- * @param {number} [options.step] 日期、时间、数字的步长
450
- * @param {number} [options.minLength]
451
- * @param {number} [options.maxLength]
452
- * @param {RegExp} [options.pattern]
453
- * @param {(Schema.Value.Group | Schema.Value | string | number)[]} [options.values] 可选值
454
- * @param {Schema.Validator | Schema.Validator[] | null} [options.validator]
455
- * @param {{[k in keyof Schema.Events]?: Schema.AsyncValidator | Schema.AsyncValidator[] | null}} [options.validators]
456
- *
457
- * @param {Ref?} [options.ref]
458
- *
459
- * @param {((value: any) => any)?} [options.setValue]
460
- * @param {((value: any) => any)?} [options.convert]
461
- *
462
- * @param {((value: T?, index: any, store: Store) => void)?} [options.onUpdate]
383
+ * @param {StoreOptions | AbortSignal | null} [options] 可选配置
463
384
  */
464
- constructor(schema, {
465
- null: isNull, ref, default: defaultValue,
466
- setValue, convert, onUpdate, states,
467
- validator, validators,
468
- index, size, new: isNew, parent: parentNode,
469
- hidden, clearable, required, disabled, readonly, removable,
470
- label, description, placeholder, min, max, step, minLength, maxLength, pattern, values: values$1
471
- } = {}) {
385
+ constructor(schema, options) {
472
386
  if (schema instanceof Store) {
473
- this.#originStore = schema;
474
- this.#schema = schema.#schema;
475
- this.#null = schema.#null;
476
- this.#ref = schema.#ref;
477
- this.#states = schema.#states;
478
- this.#layout = schema.#layout;
479
- this.#createDefault = schema.#createDefault;
480
- this.#setValue = schema.#setValue;
481
- this.#convert = schema.#convert;
482
- this.#onUpdate = schema.#onUpdate;
483
- this.#parent = schema.#parent;
484
- this.#root = schema.#root;
485
- this.#type = schema.#type;
486
- this.#meta = schema.#meta;
487
- this.#component = schema.#component;
488
- this.#selfLoading = schema.#selfLoading;
489
- this.#loading = schema.#loading;
490
- this.#size = schema.#size;
491
- this.#index = schema.#index;
492
- this.#creatable = schema.#creatable;
493
- this.#immutable = schema.#immutable;
494
- this.#new = schema.#new;
495
- this.#selfNew = schema.#selfNew;
496
- this.#selfHidden = schema.#selfHidden;
497
- this.#hidden = schema.#hidden;
498
- this.#selfClearable = schema.#selfClearable;
499
- this.#clearable = schema.#clearable;
500
- this.#selfRequired = schema.#selfRequired;
501
- this.#required = schema.#required;
502
- this.#selfDisabled = schema.#selfDisabled;
503
- this.#disabled = schema.#disabled;
504
- this.#selfReadonly = schema.#selfReadonly;
505
- this.#readonly = schema.#readonly;
506
- this.#selfRemovable = schema.#selfRemovable;
507
- this.#removable = schema.#removable;
508
- this.#selfLabel = schema.#selfLabel;
509
- this.#label = schema.#label;
510
- this.#selfDescription = schema.#selfDescription;
511
- this.#description = schema.#description;
512
- this.#selfPlaceholder = schema.#selfPlaceholder;
513
- this.#placeholder = schema.#placeholder;
514
- this.#selfMin = schema.#selfMin;
515
- this.#min = schema.#min;
516
- this.#selfMax = schema.#selfMax;
517
- this.#max = schema.#max;
518
- this.#selfStep = schema.#selfStep;
519
- this.#step = schema.#step;
520
- this.#selfMinLength = schema.#selfMinLength;
521
- this.#minLength = schema.#minLength;
522
- this.#selfMaxLength = schema.#selfMaxLength;
523
- this.#maxLength = schema.#maxLength;
524
- this.#selfPattern = schema.#selfPattern;
525
- this.#pattern = schema.#pattern;
526
- this.#selfValues = schema.#selfValues;
527
- this.#values = schema.#values;
528
- this.#errors = schema.#errors;
529
- this.#validatorResult = schema.#validatorResult;
530
- this.#changed = schema.#changed;
531
- this.#blurred = schema.#blurred;
532
- this.#cancelChange = schema.#cancelChange;
533
- this.#cancelBlur = schema.#cancelBlur;
534
- this.#set = schema.#set;
535
- this.#initValue = schema.#initValue;
536
- this.#value = schema.#value;
387
+ const store = schema.#originStore || schema;
388
+ this.#originStore= store;
389
+ this.#schema= store.#schema;
390
+ this.#null= store.#null;
391
+ this.#ref= store.#ref;
392
+ this.#states= store.#states;
393
+ this.#layout= store.#layout;
394
+ this.#createDefault= store.#createDefault;
395
+ this.#setValue= store.#setValue;
396
+ this.#convert= store.#convert;
397
+ this.#onUpdate= store.#onUpdate;
398
+ this.#parent= store.#parent;
399
+ this.#root= store.#root;
400
+ this.#type= store.#type;
401
+ this.#meta= store.#meta;
402
+ this.#component= store.#component;
403
+ this.#selfLoading= store.#selfLoading;
404
+ this.#loading= store.#loading;
405
+ this.#size= store.#size;
406
+ this.#index= store.#index;
407
+ this.#creatable= store.#creatable;
408
+ this.#immutable= store.#immutable;
409
+ this.#new= store.#new;
410
+ this.#selfNew= store.#selfNew;
411
+ this.#selfHidden= store.#selfHidden;
412
+ this.#hidden= store.#hidden;
413
+ this.#selfClearable= store.#selfClearable;
414
+ this.#clearable= store.#clearable;
415
+ this.#selfRequired= store.#selfRequired;
416
+ this.#required= store.#required;
417
+ this.#selfDisabled= store.#selfDisabled;
418
+ this.#disabled= store.#disabled;
419
+ this.#selfReadonly= store.#selfReadonly;
420
+ this.#readonly= store.#readonly;
421
+ this.#selfRemovable= store.#selfRemovable;
422
+ this.#removable= store.#removable;
423
+ this.#selfLabel= store.#selfLabel;
424
+ this.#label= store.#label;
425
+ this.#selfDescription= store.#selfDescription;
426
+ this.#description= store.#description;
427
+ this.#selfPlaceholder= store.#selfPlaceholder;
428
+ this.#placeholder= store.#placeholder;
429
+ this.#selfMin= store.#selfMin;
430
+ this.#min= store.#min;
431
+ this.#selfMax= store.#selfMax;
432
+ this.#max= store.#max;
433
+ this.#selfStep= store.#selfStep;
434
+ this.#step= store.#step;
435
+ this.#selfMinLength= store.#selfMinLength;
436
+ this.#minLength= store.#minLength;
437
+ this.#selfMaxLength= store.#selfMaxLength;
438
+ this.#maxLength= store.#maxLength;
439
+ this.#selfPattern= store.#selfPattern;
440
+ this.#pattern= store.#pattern;
441
+ this.#selfValues= store.#selfValues;
442
+ this.#values= store.#values;
443
+ this.#errors= store.#errors;
444
+ this.#validatorResult= store.#validatorResult;
445
+ this.#changed= store.#changed;
446
+ this.#blurred= store.#blurred;
447
+ this.#cancelChange= store.#cancelChange;
448
+ this.#cancelBlur= store.#cancelBlur;
449
+ this.#set= store.#set;
450
+ this.#initValue= store.#initValue;
451
+ this.#value= store.#value;
452
+ const signal = options instanceof AbortSignal ? options : null;
453
+ if (signal?.aborted) { return; }
454
+ const subBindStores= store.#subBindStores;
455
+ subBindStores.add(this);
456
+ signal?.addEventListener('abort', () => subBindStores.delete(this));
457
+ store.#requestUpdate();
537
458
  return;
538
459
  }
460
+ const {
461
+ null: isNull, ref, default: defaultValue,
462
+ setValue, convert, onUpdate, states,
463
+ validator, validators,
464
+ index, size, new: isNew, parent: parentNode,
465
+ hidden, clearable, required, disabled, readonly, removable,
466
+ label, description, placeholder, min, max, step, minLength, maxLength, pattern, values: values$1
467
+ } = !(options instanceof AbortSignal) && options || {};
539
468
  this.#schema = schema;
540
469
  const parent = parentNode instanceof Store ? parentNode : null;
541
470
  if (parent) {
@@ -948,24 +877,6 @@ class Store {
948
877
 
949
878
  /** @type {Set<Store>} */
950
879
  #subBindStores = new Set();
951
- /**
952
- * @template [M=any]
953
- * @template {Object.<string, Schema.State>} [S=Object.<string, Schema.State>]
954
- * @param {Schema<M, S>} schema 数据结构模式
955
- * @param {AbortSignal} [signal]
956
- * @returns {BindObjectStore}
957
- */
958
- bindObject(schema, signal) {
959
- const originStore = this.#originStore;
960
- if (originStore) { return originStore.bindObject(schema, signal); }
961
- const store = new BindObjectStore(schema, this);
962
- if (signal?.aborted) { return store; }
963
- const subBindStores = this.#subBindStores;
964
- subBindStores.add(store);
965
- signal?.addEventListener('abort', () => subBindStores.delete(store));
966
- this.#requestUpdate();
967
- return store;
968
- }
969
880
 
970
881
  /** 内容是否已改变 */
971
882
  get changed() { return !Object.is(this.#value.get(), this.#initValue.get()); }
@@ -1062,7 +973,7 @@ class Store {
1062
973
  // @ts-ignore
1063
974
  let newValues = Array.isArray(val) ? [...val] : { ...val };
1064
975
  let updated = false;
1065
- for (const bind of [this,...this.#subBindStores]) {
976
+ for (const bind of [this, ...this.#subBindStores]) {
1066
977
  for (const [key, field] of bind) {
1067
978
  // @ts-ignore
1068
979
  const data = Object.hasOwn(val, key) ? val[key] : undefined;
@@ -1128,6 +1039,46 @@ class Store {
1128
1039
  }
1129
1040
  }
1130
1041
 
1042
+ /**
1043
+ * @template [T=any]
1044
+ * @template [M=any]
1045
+ * @template {Object.<string, Schema.State>} [S=Object.<string, Schema.State>]
1046
+ * @typedef {object} StoreOptions
1047
+ * @property {Store?} [parent]
1048
+ * @property {Partial<S>?} [states]
1049
+ * @property {((store: Store, value?: any) => any) | object | number | string | boolean | null | undefined} [default]
1050
+ * @property {number | string | null} [index]
1051
+ * @property {number | Signal.State<number> | Signal.Computed<number>} [size]
1052
+ * @property {boolean} [null]
1053
+ * @property {boolean} [new]
1054
+ * @property {boolean} [hidden]
1055
+ * @property {boolean} [clearable]
1056
+ * @property {boolean} [required]
1057
+ * @property {boolean} [disabled]
1058
+ * @property {boolean} [readonly]
1059
+ * @property {boolean} [removable]
1060
+ *
1061
+ * @property {string} [label] 字段标签
1062
+ * @property {string} [description] 字段描述
1063
+ * @property {string} [placeholder] 占位符
1064
+ * @property {number} [min] 日期、时间、数字的最小值
1065
+ * @property {number} [max] 日期、时间、数字的最大值
1066
+ * @property {number} [step] 日期、时间、数字的步长
1067
+ * @property {number} [minLength]
1068
+ * @property {number} [maxLength]
1069
+ * @property {RegExp} [pattern]
1070
+ * @property {(Schema.Value.Group | Schema.Value | string | number)[]} [values] 可选值
1071
+ * @property {Schema.Validator | Schema.Validator[] | null} [validator]
1072
+ * @property {{[k in keyof Schema.Events]?: Schema.AsyncValidator | Schema.AsyncValidator[] | null}} [validators]
1073
+ *
1074
+ * @property {Ref?} [ref]
1075
+ *
1076
+ * @property {((value: any) => any)?} [setValue]
1077
+ * @property {((value: any) => any)?} [convert]
1078
+ *
1079
+ * @property {((value: T?, index: any, store: Store) => void)?} [onUpdate]
1080
+ */
1081
+
1131
1082
  /** @import { Schema } from '../Schema.types.mjs' */
1132
1083
 
1133
1084
  /**
@@ -1136,7 +1087,7 @@ class Store {
1136
1087
  * @template {Object.<string, Schema.State>} [S=Object.<string, Schema.State>]
1137
1088
  * @extends {Store<T, M, S>}
1138
1089
  */
1139
- let ObjectStore$1 = class ObjectStore extends Store {
1090
+ class ObjectStore extends Store {
1140
1091
  get kind() { return 'object'; }
1141
1092
  /** @type {Record<string, Store>} */
1142
1093
  #children;
@@ -1189,9 +1140,9 @@ let ObjectStore$1 = class ObjectStore extends Store {
1189
1140
  }
1190
1141
  this.#children = children;
1191
1142
  }
1192
- };
1143
+ }
1193
1144
  // @ts-ignore
1194
- setObjectStore(ObjectStore$1);
1145
+ setObjectStore(ObjectStore);
1195
1146
 
1196
1147
  /** @import { Schema } from '../Schema.types.mjs' */
1197
1148
 
@@ -1433,6 +1384,51 @@ class ArrayStore extends Store {
1433
1384
  // @ts-ignore
1434
1385
  setArrayStore(ArrayStore);
1435
1386
 
1387
+ /** @import { Schema } from '../Schema.types.mjs' */
1388
+
1389
+ /**
1390
+ * @template [T=any]
1391
+ * @template [M=any]
1392
+ * @template {Object.<string, Schema.State>} [S=Object.<string, Schema.State>]
1393
+ * @extends {Store<T, M, S>}
1394
+ */
1395
+ class BindObjectStore extends Store {
1396
+
1397
+ get kind() { return 'object'; }
1398
+ /** @type {Record<string, Store>} */
1399
+ #children = Object.create(null);
1400
+ *[Symbol.iterator]() { yield* Object.entries(this.#children); }
1401
+ /**
1402
+ *
1403
+ * @param {string | number} key
1404
+ * @returns {Store?}
1405
+ */
1406
+ child(key) { return this.#children[key] || null; }
1407
+ /**
1408
+ * @param {Schema<any, Object.<string, Schema.State>>} schema 数据结构模式
1409
+ * @param {Store<T, M, S>} store
1410
+ * @param {AbortSignal} [signal]
1411
+ */
1412
+ constructor(schema, store, signal) {
1413
+ super(store, signal);
1414
+ const children = this.#children;
1415
+ for (const [index, field] of Object.entries(schema)) {
1416
+ const bindStore = create(field, {
1417
+ index, parent: this,
1418
+ /** @param {*} value @param {*} index @param {Store} store */
1419
+ onUpdate: (value, index, store) => {
1420
+ if (store !== children[index]) { return; }
1421
+ const val = this.value ?? null;
1422
+ if (typeof val !== 'object' || Array.isArray(val)) { return; }
1423
+ // @ts-ignore
1424
+ this.value = { ...val, [index]: value };
1425
+ },
1426
+ });
1427
+ children[index] = bindStore;
1428
+ }
1429
+ }
1430
+ }
1431
+
1436
1432
  /** @import * as Layout from './index.mjs' */
1437
1433
 
1438
1434
  /** @import { OldNode } from './createElement.mjs' */
@@ -4861,7 +4857,7 @@ function renderChild(layout, parent, next, parentEnv, parentTemplates, component
4861
4857
  if (list instanceof ArrayStore) {
4862
4858
  return renderArray(parent, next, list, env, r, layout.sort);
4863
4859
  }
4864
- if (list instanceof ObjectStore$1) {
4860
+ if (list instanceof ObjectStore) {
4865
4861
  return renderObject(parent, next, list, env, r, layout.sort);
4866
4862
  }
4867
4863
  if (typeof list === 'function') {
@@ -6593,4 +6589,4 @@ function renderStore(store, fieldRenderer, root, layout, options) {
6593
6589
  }, { once: true });
6594
6590
  }
6595
6591
 
6596
- export { ArrayStore, index as Layout, ObjectStore$1 as ObjectStore, Store, effect, render, renderStore, watch };
6592
+ export { ArrayStore, BindObjectStore, index as Layout, ObjectStore, Store, effect, render, renderStore, watch };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neeloong/form",
3
- "version": "0.28.0",
3
+ "version": "0.29.0",
4
4
  "description": "一个基于响应式数据绑定的表单渲染库",
5
5
  "keywords": [
6
6
  "from",