@neeloong/form 0.6.2 → 0.7.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.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @neeloong/form v0.6.2
2
+ * @neeloong/form v0.7.0
3
3
  * (c) 2024-2025 Fierflame
4
4
  * @license Apache-2.0
5
5
  */
@@ -688,7 +688,85 @@
688
688
 
689
689
  }
690
690
 
691
+ const ref = Symbol();
692
+ /** @import Store from './index.mjs' */
693
+ /** @typedef {{ [ref]: Store; [k: string]: Ref | undefined;}} Ref */
694
+
695
+ /**
696
+ * @param {Store} store
697
+ */
698
+ function createRef(store) {
699
+
700
+ /** @type{Ref} */
701
+ const r = { [ref]: store };
702
+ for (const [k, f] of store) {
703
+ Object.defineProperty(r, k, {
704
+ get() { return f.ref; },
705
+ configurable: false,
706
+ enumerable: true,
707
+ });
708
+ }
709
+ Object.defineProperty(r, ref, {
710
+ get() { return store; },
711
+ configurable: false,
712
+ enumerable: true,
713
+ });
714
+ return r;
715
+ }
716
+
691
717
  /** @import { Schema } from '../types.mjs' */
718
+
719
+
720
+ /** @type {{new(...p: ConstructorParameters<typeof Store>): Store}?} */
721
+ let ObjectStore$1 = null;
722
+ /** @type {{new(...p: ConstructorParameters<typeof Store>): Store}?} */
723
+ let ArrayStore$1 = null;
724
+ /** @type {Record<string, {new(...p: ConstructorParameters<typeof Store>): Store}?>} */
725
+ let TypeStores = Object.create(null);
726
+ /**
727
+ * @param {Schema.Field} schema
728
+ * @param {object} [options]
729
+ * @param {Store?} [options.parent]
730
+ * @param {string | number | null} [options.index]
731
+ * @param {boolean} [options.new]
732
+ * @param {(value: any, index: any, store: Store) => void} [options.onUpdate]
733
+ * @param {(value: any, index: any, store: Store) => void} [options.onUpdateState]
734
+ */
735
+ function create(schema, options) {
736
+ const type = schema.type;
737
+ /** @type {{new(...p: ConstructorParameters<typeof Store>): Store}} */
738
+ let Class = Store;
739
+ if (schema.array && !(ArrayStore$1 && options?.parent instanceof ArrayStore$1)) {
740
+ if (ArrayStore$1) { Class = ArrayStore$1; }
741
+ } else if (typeof type === 'string') {
742
+ const C = TypeStores[type];
743
+ if (C) { Class = C; }
744
+ } else if (type && typeof type === 'object') {
745
+ if (ObjectStore$1) { Class = ObjectStore$1; }
746
+ }
747
+ return new Class(schema, options);
748
+ }
749
+
750
+ /** @param {{new(...p: ConstructorParameters<typeof Store>): Store}} Class */
751
+ function setObjectStore(Class) {
752
+ ObjectStore$1 = Class;
753
+ }
754
+
755
+ /** @param {{new(...p: ConstructorParameters<typeof Store>): Store}} Class */
756
+ function setArrayStore(Class) {
757
+ ArrayStore$1 = Class;
758
+ }
759
+ /**
760
+ * @param {string} type
761
+ * @param {{new(...p: ConstructorParameters<typeof Store>): Store}} Class
762
+ */
763
+ function setStore$1(type, Class) {
764
+ TypeStores[type] = Class;
765
+ }
766
+
767
+ /** @import { Ref } from './ref.mjs' */
768
+ /** @import { Schema } from '../types.mjs' */
769
+
692
770
  /**
693
771
  * @template [T=any]
694
772
  */
@@ -736,14 +814,24 @@
736
814
  * @param {boolean} [options.new]
737
815
  */
738
816
  static create(schema, options = {}) {
739
- return new ObjectStore({type: schema}, { ...options, parent: null });
817
+ return create({type: schema}, { ...options, parent: null });
818
+ }
819
+ /**
820
+ * @param {string} type
821
+ * @param {{new(...p: ConstructorParameters<typeof Store>): Store}} Class
822
+ */
823
+ static setStore(type, Class) {
824
+ return setStore$1(type, Class);
740
825
  }
741
826
  #null = false;
742
827
  get null() { return this.#null; }
743
828
  get kind() { return ''; }
829
+ /** @type {Ref?} */
830
+ #ref = null;
831
+ get ref() { return this.#ref || createRef(this); }
744
832
  /**
745
833
  * @param {Schema.Field} schema
746
- * @param {object} options
834
+ * @param {object} [options]
747
835
  * @param {*} [options.parent]
748
836
  * @param {*} [options.state]
749
837
  * @param {number | string | null} [options.index]
@@ -764,19 +852,22 @@
764
852
  * @param {number} [options.step] 日期、时间、数字的步长
765
853
  * @param {(Schema.Value.Group | Schema.Value | string | number)[]} [options.values] 可选值
766
854
  *
855
+ * @param {Ref?} [options.ref]
856
+ *
767
857
  * @param {((value: any) => any)?} [options.setValue]
768
858
  * @param {((value: any) => any)?} [options.setState]
769
859
  * @param {((value: any, state: any) => [value: any, state: any])?} [options.convert]
770
- * @param {((value: T?, index: any) => void)?} [options.onUpdate]
771
- * @param {((value: T?, index: any) => void)?} [options.onUpdateState]
860
+ *
861
+ * @param {((value: T?, index: any, store: Store) => void)?} [options.onUpdate]
862
+ * @param {((value: T?, index: any, store: Store) => void)?} [options.onUpdateState]
772
863
  */
773
864
  constructor(schema, {
774
- null: isNull, state,
865
+ null: isNull, state, ref,
775
866
  setValue, setState, convert, onUpdate, onUpdateState,
776
867
  index, length, new: isNew, parent: parentNode,
777
868
  hidden, clearable, required, disabled, readonly,
778
869
  label, description, placeholder, min, max, step, values: values$1
779
- }) {
870
+ } = {}) {
780
871
  this.schema = schema;
781
872
  this.#state.set(typeof state === 'object' && state || {});
782
873
  const parent = parentNode instanceof Store ? parentNode : null;
@@ -845,8 +936,10 @@
845
936
 
846
937
  if (isNull) {
847
938
  this.#null = true;
939
+ this.#ref = createRef(this);
848
940
  return;
849
941
  }
942
+ this.#ref = ref || null;
850
943
  this.#onUpdate = onUpdate || null;
851
944
  this.#onUpdateState = onUpdateState || null;
852
945
  this.#setValue = typeof setValue === 'function' ? setValue : null;
@@ -859,19 +952,16 @@
859
952
  // @ts-ignore
860
953
  this.listen(k, f);
861
954
  }
862
-
863
-
864
955
  }
865
- #destroyed = false;
866
956
  /** @type {((value: any) => any)?} */
867
957
  #setValue = null
868
958
  /** @type {((value: any) => any)?} */
869
959
  #setState = null
870
960
  /** @type {((value: any, state: any) => [value: any, state: any])?} */
871
961
  #convert = null
872
- /** @type {((value: any, index: any) => void)?} */
962
+ /** @type {((value: any, index: any, store: Store) => void)?} */
873
963
  #onUpdate = null
874
- /** @type {((value: any, index: any) => void)?} */
964
+ /** @type {((value: any, index: any, store: Store) => void)?} */
875
965
  #onUpdateState = null
876
966
  /** @readonly @type {Store?} */
877
967
  #parent = null;
@@ -1032,10 +1122,6 @@
1032
1122
  get values() { return this.#values.get(); }
1033
1123
  set values(v) { this.#selfValues.set(values(v)); }
1034
1124
 
1035
-
1036
-
1037
-
1038
-
1039
1125
  /** @returns {IterableIterator<[key: string | number, value: Store]>} */
1040
1126
  *[Symbol.iterator]() {}
1041
1127
  /**
@@ -1046,39 +1132,30 @@
1046
1132
  child(key) { return null; }
1047
1133
 
1048
1134
  #set = false;
1049
- /** @type {T?} */
1050
- #initValue = null;
1051
- #lastValue = this.#initValue;
1052
- #value = new exports.Signal.State(this.#initValue);
1135
+ #initValue = new exports.Signal.State(/** @type {T?} */(null));
1136
+ #value = new exports.Signal.State(this.#initValue.get());
1053
1137
 
1054
1138
 
1055
1139
  #state = new exports.Signal.State(/** @type {any} */(null));
1056
- #lastState = this.#state.get();
1057
-
1058
1140
 
1059
- get changed() { return this.#value.get() === this.#lastValue; }
1060
- get saved() { return this.#value.get() === this.#initValue; }
1141
+ get changed() { return this.#value.get() === this.#initValue.get(); }
1061
1142
 
1062
1143
  get value() { return this.#value.get(); }
1063
1144
  set value(v) {
1064
- if (this.#destroyed) { return; }
1065
1145
  const val = this.#setValue?.(v) || v;
1066
1146
  this.#value.set(val);
1067
1147
  if (!this.#set) {
1068
- this.#set = true;
1069
- this.#initValue = v;
1148
+ this.#initValue.set(val);
1070
1149
  }
1071
- this.#onUpdate?.(this.#value.get(), this.#index.get());
1150
+ this.#onUpdate?.(val, this.#index.get(), this);
1072
1151
  this.#requestUpdate();
1073
1152
  }
1074
1153
 
1075
1154
  get state() { return this.#state.get(); }
1076
1155
  set state(v) {
1077
- if (this.#destroyed) { return; }
1078
1156
  const sta = this.#setState?.(v) || v;
1079
1157
  this.#state.set(sta);
1080
- this.#set = true;
1081
- this.#onUpdateState?.(this.#state.get(), this.#index.get());
1158
+ this.#onUpdateState?.(sta, this.#index.get(), this);
1082
1159
  this.#requestUpdate();
1083
1160
  }
1084
1161
  #requestUpdate() {
@@ -1087,9 +1164,30 @@
1087
1164
  queueMicrotask(() => {
1088
1165
  const oldValue = this.#value.get();
1089
1166
  const oldState = this.#state.get();
1090
- return this.#runUpdate(oldValue, oldState);
1167
+ this.#runUpdate(oldValue, oldState);
1091
1168
  });
1092
1169
  }
1170
+ reset(value = this.#initValue.get()) {
1171
+ this.#reset(value);
1172
+ }
1173
+ /**
1174
+ *
1175
+ * @param {*} value
1176
+ * @returns
1177
+ */
1178
+ #reset(value) {
1179
+ this.#value.set(value);
1180
+ this.#initValue.set(value);
1181
+ if (!value || typeof value !== 'object') {
1182
+ for (const [, field] of this) {
1183
+ field.#reset(null);
1184
+ }
1185
+ return;
1186
+ }
1187
+ for (const [key, field] of this) {
1188
+ field.#reset(value[key]);
1189
+ }
1190
+ }
1093
1191
 
1094
1192
 
1095
1193
  #needUpdate = false;
@@ -1100,26 +1198,21 @@
1100
1198
  * @returns
1101
1199
  */
1102
1200
  #toUpdate(value, state) {
1103
- if (this.#destroyed) { return value; }
1104
1201
  const [val,sta] = this.#convert?.(value, state) || [value, state];
1105
1202
  if(this.#value.get() === val && this.#state.get() === sta) { return [val,sta] }
1106
1203
  this.#value.set(val);
1107
1204
  this.#state.set(sta);
1108
- if (!this.#set) {
1109
- this.#set = true;
1110
- this.#initValue = val;
1111
- }
1112
1205
  return this.#runUpdate(val, sta);
1113
1206
  }
1114
1207
  /**
1115
1208
  *
1116
1209
  * @param {*} val
1117
1210
  * @param {*} sta
1118
- * @returns
1211
+ * @returns {[any, any]}
1119
1212
  */
1120
1213
  #runUpdate(val, sta) {
1121
- if (this.#destroyed) { return [val, sta]; }
1122
1214
  this.#needUpdate = false;
1215
+ let initValue = val;
1123
1216
  if (val && typeof val === 'object') {
1124
1217
  /** @type {T} */
1125
1218
  // @ts-ignore
@@ -1144,34 +1237,26 @@
1144
1237
  if (updated) {
1145
1238
  val = newValues;
1146
1239
  sta = newStates;
1240
+ initValue = val;
1147
1241
  this.#value.set(val);
1148
1242
  this.#state.set(newStates);
1149
1243
  }
1150
1244
  }
1151
- if (this.#lastValue === val && this.#lastState === sta) {
1152
- return [val, sta];
1245
+ if (!this.#set) {
1246
+ this.#set = true;
1247
+ this.#initValue.set(initValue);
1153
1248
  }
1154
- this.#lastValue = val;
1155
- this.#lastState = sta;
1156
1249
  return [val, sta];
1157
-
1158
- }
1159
-
1160
-
1161
-
1162
- get destroyed() { return this.#destroyed; }
1163
- destroy() {
1164
- if (this.#destroyed) { return; }
1165
- this.#destroyed = true;
1166
- for (const [, field] of this) {
1167
- field.destroy();
1168
- }
1169
1250
  }
1170
1251
 
1171
1252
  }
1172
1253
 
1254
+ /** @import { Schema } from '../types.mjs' */
1173
1255
 
1174
-
1256
+ /**
1257
+ * @template {Record<string, any>} [T=Record<string, any>]
1258
+ * @extends {Store<T>}
1259
+ */
1175
1260
  class ObjectStore extends Store {
1176
1261
  get kind() { return 'object'; }
1177
1262
  /** @type {Record<string, Store>} */
@@ -1187,24 +1272,18 @@
1187
1272
  * @param {Schema.Object & Schema.Attr} schema
1188
1273
  * @param {object} [options]
1189
1274
  * @param {Store?} [options.parent]
1190
- * @param {string | number} [options.index]
1275
+ * @param {number | string | null} [options.index]
1191
1276
  * @param {boolean} [options.new]
1192
- * @param {(value: any, index: any) => void} [options.onUpdate]
1193
- * @param {(value: any, index: any) => void} [options.onUpdateState]
1277
+ * @param {((value: T?, index: any, store: Store) => void)?} [options.onUpdate]
1278
+ * @param {((value: T?, index: any, store: Store) => void)?} [options.onUpdateState]
1194
1279
  */
1195
1280
  constructor(schema,{ parent, index, new: isNew, onUpdate, onUpdateState } = {}) {
1196
1281
  const childrenTypes = Object.entries(schema.type);
1197
1282
  super(schema, {
1198
1283
  parent, index, new: isNew, onUpdate, onUpdateState,
1199
1284
  length: childrenTypes.length,
1200
- setValue(v) {
1201
- if (typeof v !== 'object') { return {}; }
1202
- return v;
1203
- },
1204
- setState(v) {
1205
- if (typeof v !== 'object') { return {}; }
1206
- return v;
1207
- },
1285
+ setValue(v) { return typeof v === 'object' ? v : null; },
1286
+ setState(v) { return typeof v === 'object' ? v : null; },
1208
1287
  convert(v, state) {
1209
1288
  return [
1210
1289
  typeof v === 'object' ? v : {},
@@ -1215,34 +1294,31 @@
1215
1294
  const children = Object.create(null);
1216
1295
  const childCommonOptions = {
1217
1296
  parent: this,
1218
- /** @param {*} value @param {*} index */
1219
- onUpdate: (value, index) => {
1297
+ /** @param {*} value @param {*} index @param {Store} store */
1298
+ onUpdate: (value, index, store) => {
1299
+ if (store !== this.#children[index]) { return; }
1300
+ // @ts-ignore
1220
1301
  this.value = {...this.value, [index]: value};
1221
1302
  },
1222
- /** @param {*} state @param {*} index */
1223
- onUpdateState: (state, index) => {
1303
+ /** @param {*} state @param {*} index @param {Store} store */
1304
+ onUpdateState: (state, index, store) => {
1305
+ if (store !== this.#children[index]) { return; }
1224
1306
  this.state = {...this.state, [index]: state};
1225
1307
  }
1226
1308
  };
1227
1309
 
1228
1310
  for (const [index, field] of childrenTypes) {
1229
- let child;
1230
- if (typeof field.type === 'string') {
1231
- if (field.array) {
1232
- child = new ArrayStore(field, {...childCommonOptions, index});
1233
- } else {
1234
- child = new Store(field, {...childCommonOptions, index});
1235
- }
1236
- } else if (field.array) {
1237
- child = new ArrayStore(field, {...childCommonOptions, index});
1238
- } else {
1239
- child = new ObjectStore(/**@type {*}*/(field), { ...childCommonOptions, index});
1240
- }
1241
- children[index] = child;
1311
+ children[index] = create(field, {...childCommonOptions, index});
1242
1312
  }
1243
1313
  this.#children = children;
1244
1314
  }
1245
1315
  }
1316
+ // @ts-ignore
1317
+ setObjectStore(ObjectStore);
1318
+
1319
+ /** @import { Schema } from '../types.mjs' */
1320
+
1321
+
1246
1322
 
1247
1323
  /**
1248
1324
  * @template [T=any]
@@ -1274,23 +1350,19 @@
1274
1350
  * @param {Store?} [options.parent]
1275
1351
  * @param {string | number | null} [options.index]
1276
1352
  * @param {boolean} [options.new]
1277
- * @param {(value: any, index: any) => void} [options.onUpdate]
1278
- * @param {(value: any, index: any) => void} [options.onUpdateState]
1353
+ * @param {(value: any, index: any, store: Store) => void} [options.onUpdate]
1354
+ * @param {(value: any, index: any, store: Store) => void} [options.onUpdateState]
1279
1355
  */
1280
- constructor(schema, { parent, onUpdate, onUpdateState, index, new: isNew} = {}) {
1356
+ constructor(schema, { parent, onUpdate, onUpdateState, index, new: isNew} = {}) {
1281
1357
  const childrenState = new exports.Signal.State(/** @type {Store[]} */([]));
1282
1358
  // @ts-ignore
1283
1359
  const updateChildren = (list) => {
1284
- if (this.destroyed) { return; }
1285
1360
  const length = Array.isArray(list) && list.length || 0;
1286
1361
  const children = [...childrenState.get()];
1287
1362
  const oldLength = children.length;
1288
1363
  for (let i = children.length; i < length; i++) {
1289
1364
  children.push(this.#create(i));
1290
1365
  }
1291
- for (const schema of children.splice(length)) {
1292
- schema.destroy();
1293
- }
1294
1366
  if (oldLength !== length) {
1295
1367
  childrenState.set(children);
1296
1368
  }
@@ -1300,27 +1372,28 @@
1300
1372
  index, new: isNew, parent,
1301
1373
  length: new exports.Signal.Computed(() => childrenState.get().length),
1302
1374
  state: [],
1303
- setValue(v) { return Array.isArray(v) ? v : v == null ? [] : [v] },
1304
- setState(v) { return Array.isArray(v) ? v : v == null ? [] : [v] },
1375
+ setValue(v) { return Array.isArray(v) ? v : v == null ? null : [v] },
1376
+ setState(v) { return Array.isArray(v) ? v : v == null ? null : [v] },
1305
1377
  convert(v, state) {
1306
- const val = Array.isArray(v) ? v : v == null ? [] : [v];
1378
+ const val = Array.isArray(v) ? v : v == null ? null : [v];
1307
1379
  updateChildren(val);
1308
1380
  return [
1309
1381
  val,
1310
1382
  (Array.isArray(state) ? state : v == null ? [] : [state]),
1311
1383
  ];
1312
1384
  },
1313
- onUpdate:(value, index) => {
1385
+ onUpdate:(value, index, state) => {
1314
1386
  updateChildren(value);
1315
- onUpdate?.(value, index);
1387
+ onUpdate?.(value, index, state);
1316
1388
  },
1317
1389
  onUpdateState,
1318
1390
  });
1319
1391
  this.#children = childrenState;
1320
1392
  const childCommonOptions = {
1321
1393
  parent: this,
1322
- /** @param {*} value @param {*} index */
1323
- onUpdate: (value, index) => {
1394
+ /** @param {*} value @param {*} index @param {Store} store */
1395
+ onUpdate: (value, index, store) => {
1396
+ if (childrenState.get()[index] !== store) { return;}
1324
1397
  const val = [...this.value || []];
1325
1398
  if (val.length < index) {
1326
1399
  val.length = index;
@@ -1328,8 +1401,9 @@
1328
1401
  val[index] = value;
1329
1402
  this.value = val;
1330
1403
  },
1331
- /** @param {*} state @param {*} index */
1332
- onUpdateState: (state, index) => {
1404
+ /** @param {*} state @param {*} index @param {Store} store */
1405
+ onUpdateState: (state, index, store) => {
1406
+ if (childrenState.get()[index] !== store) { return;}
1333
1407
  const sta = [...this.state || []];
1334
1408
  if (sta.length < index) {
1335
1409
  sta.length = index;
@@ -1338,33 +1412,21 @@
1338
1412
  this.state = sta;
1339
1413
  },
1340
1414
  };
1341
- if (typeof schema.type === 'string') {
1342
- this.#create = (index, isNew) => {
1343
- const child = new Store(schema, {...childCommonOptions, index, new: isNew });
1344
- child.index = index;
1345
- return child
1346
- };
1347
- } else if (schema.type && typeof schema.type === 'object' && !Array.isArray(schema.type)) {
1348
- this.#create = (index, isNew) => {
1349
- const child = new ObjectStore(/** @type {*} */(schema), { ...childCommonOptions, index, new: isNew});
1350
- child.index = index;
1351
- return child
1352
- };
1353
- } else {
1354
- throw new Error();
1355
- }
1356
-
1415
+ this.#create = (index, isNew) => {
1416
+ const child = create(schema, {...childCommonOptions, index, new: isNew });
1417
+ child.index = index;
1418
+ return child
1419
+ };
1357
1420
  }
1358
1421
  /**
1359
1422
  *
1360
1423
  * @param {number} index
1361
- * @param {T} value
1424
+ * @param {T?} [value]
1362
1425
  * @param {boolean} [isNew]
1363
1426
  * @returns
1364
1427
  */
1365
- insert(index, value, isNew) {
1366
- if (this.destroyed) { return false; }
1367
- const data = this.value;
1428
+ insert(index, value = null, isNew) {
1429
+ const data = this.value || [];
1368
1430
  if (!Array.isArray(data)) { return false; }
1369
1431
  const children = [...this.#children.get()];
1370
1432
  const insertIndex = Math.max(0, Math.min(Math.floor(index), children.length));
@@ -1382,16 +1444,16 @@
1382
1444
  sta.splice(insertIndex, 0, {});
1383
1445
  this.state = sta;
1384
1446
  }
1385
- this.value = val;
1386
1447
  this.#children.set(children);
1448
+ this.value = val;
1387
1449
  return true;
1388
1450
  }
1389
1451
  /**
1390
1452
  *
1391
- * @param {T} value
1453
+ * @param {T?} [value]
1392
1454
  * @returns
1393
1455
  */
1394
- add(value) {
1456
+ add(value = null) {
1395
1457
  return this.insert(this.#children.get().length, value);
1396
1458
  }
1397
1459
  /**
@@ -1400,7 +1462,6 @@
1400
1462
  * @returns
1401
1463
  */
1402
1464
  remove(index) {
1403
- if (this.destroyed) { return; }
1404
1465
  const data = this.value;
1405
1466
  if (!Array.isArray(data)) { return; }
1406
1467
  const children = [...this.#children.get()];
@@ -1410,7 +1471,6 @@
1410
1471
  for (let i = index; i < children.length; i++) {
1411
1472
  children[i].index = i;
1412
1473
  }
1413
- item.destroy();
1414
1474
  const val = [...data];
1415
1475
  const [value] = val.splice(removeIndex, 1);
1416
1476
  const state = this.state;
@@ -1419,8 +1479,8 @@
1419
1479
  sta.splice(removeIndex, 1);
1420
1480
  this.state = sta;
1421
1481
  }
1422
- this.value = val;
1423
1482
  this.#children.set(children);
1483
+ this.value = val;
1424
1484
  return value;
1425
1485
 
1426
1486
  }
@@ -1431,7 +1491,6 @@
1431
1491
  * @returns
1432
1492
  */
1433
1493
  move(from, to) {
1434
- if (this.destroyed) { return false; }
1435
1494
  const data = this.value;
1436
1495
  if (!Array.isArray(data)) { return false; }
1437
1496
  const children = [...this.#children.get()];
@@ -1457,8 +1516,8 @@
1457
1516
  }
1458
1517
  this.state = sta;
1459
1518
  }
1460
- this.value = val;
1461
1519
  this.#children.set(children);
1520
+ this.value = val;
1462
1521
  return true;
1463
1522
 
1464
1523
  }
@@ -1469,7 +1528,6 @@
1469
1528
  * @returns
1470
1529
  */
1471
1530
  exchange(a, b) {
1472
- if (this.destroyed) { return false; }
1473
1531
  const data = this.value;
1474
1532
  if (!Array.isArray(data)) { return false; }
1475
1533
  const children = [...this.#children.get()];
@@ -1494,11 +1552,13 @@
1494
1552
  sta[a] = bValue;
1495
1553
  this.state = sta;
1496
1554
  }
1497
- this.value = val;
1498
1555
  this.#children.set(children);
1556
+ this.value = val;
1499
1557
  return true;
1500
1558
  }
1501
1559
  }
1560
+ // @ts-ignore
1561
+ setArrayStore(ArrayStore);
1502
1562
 
1503
1563
  const errors = {
1504
1564
  CALC: 'no `createCalc` option, no expression parsing support',
@@ -2410,6 +2470,7 @@
2410
2470
  store: true,
2411
2471
  parent: true,
2412
2472
  root: true,
2473
+ ref: true,
2413
2474
 
2414
2475
  schema: true,
2415
2476
 
@@ -2417,6 +2478,7 @@
2417
2478
  readonly: true,
2418
2479
  creatable: true,
2419
2480
  immutable: true,
2481
+ changed: true,
2420
2482
 
2421
2483
  required: true,
2422
2484
  clearable: true,
@@ -2455,6 +2517,7 @@
2455
2517
  }
2456
2518
  yield [`${key}${sign}value`, {get: () => val.value, set: v => val.value = v}];
2457
2519
  yield [`${key}${sign}state`, {get: () => val.state, set: v => val.state = v}];
2520
+ yield [`${key}${sign}reset`, {exec: () => val.reset()}];
2458
2521
  if (!(val instanceof ArrayStore)) { return; }
2459
2522
  yield [`${key}${sign}insert`, {exec: (index, value) => val.insert(index, value)}];
2460
2523
  yield [`${key}${sign}add`, {exec: (v) => val.add(v)}];
@@ -2527,6 +2590,17 @@
2527
2590
  /** @import { ValueDefine, ExecDefine, CalcDefine } from './index.mjs' */
2528
2591
 
2529
2592
 
2593
+ /** @type {Record<string, ValueDefine | ExecDefine | CalcDefine>} */
2594
+ const items = {
2595
+ value$: { calc(r) { return r?.[ref].value; } },
2596
+ state$: { calc(r) { return r?.[ref].state; } },
2597
+ };
2598
+
2599
+ var globals = Object.getOwnPropertyDescriptors(items);
2600
+
2601
+ /** @import { ValueDefine, ExecDefine, CalcDefine } from './index.mjs' */
2602
+
2603
+
2530
2604
  /**
2531
2605
  *
2532
2606
  * @param {string} key
@@ -2544,7 +2618,7 @@
2544
2618
  */
2545
2619
  function toGlobal(global) {
2546
2620
  /** @type {Record<string, ValueDefine | ExecDefine | CalcDefine>} */
2547
- const items = Object.create(null);
2621
+ const items = Object.create(null, globals);
2548
2622
  if (!global || typeof global !== 'object') { return items; }
2549
2623
  for (const [key, value] of Object.entries(global)) {
2550
2624
  if (!testKey(key)) { continue; }