@axi-engine/fields 0.2.2 → 0.3.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/dist/index.js CHANGED
@@ -26,13 +26,15 @@ __export(index_exports, {
26
26
  ClampMinPolicySerializerHandler: () => ClampMinPolicySerializerHandler,
27
27
  ClampPolicy: () => ClampPolicy,
28
28
  ClampPolicySerializerHandler: () => ClampPolicySerializerHandler,
29
- DefaultBooleanField: () => DefaultBooleanField,
30
- DefaultField: () => DefaultField,
31
- DefaultFields: () => DefaultFields,
32
- DefaultFieldsFactory: () => DefaultFieldsFactory,
33
- DefaultNumericField: () => DefaultNumericField,
34
- DefaultStringField: () => DefaultStringField,
35
- DefaultTreeNodeFactory: () => DefaultTreeNodeFactory,
29
+ CoreBooleanField: () => CoreBooleanField,
30
+ CoreField: () => CoreField,
31
+ CoreFieldTree: () => CoreFieldTree,
32
+ CoreFields: () => CoreFields,
33
+ CoreFieldsFactory: () => CoreFieldsFactory,
34
+ CoreNumericField: () => CoreNumericField,
35
+ CoreStringField: () => CoreStringField,
36
+ CoreTreeNodeFactory: () => CoreTreeNodeFactory,
37
+ DataStore: () => DataStore,
36
38
  FieldRegistry: () => FieldRegistry,
37
39
  FieldSerializer: () => FieldSerializer,
38
40
  FieldTree: () => FieldTree,
@@ -43,7 +45,13 @@ __export(index_exports, {
43
45
  PolicySerializer: () => PolicySerializer,
44
46
  clampMaxPolicy: () => clampMaxPolicy,
45
47
  clampMinPolicy: () => clampMinPolicy,
46
- clampPolicy: () => clampPolicy
48
+ clampPolicy: () => clampPolicy,
49
+ createCoreFieldRegistry: () => createCoreFieldRegistry,
50
+ createCoreFieldSystem: () => createCoreFieldSystem,
51
+ createCorePolicySerializer: () => createCorePolicySerializer,
52
+ createCoreTreeNodeFactory: () => createCoreTreeNodeFactory,
53
+ createCoreTreeSerializer: () => createCoreTreeSerializer,
54
+ createTypedMethodsMixin: () => createTypedMethodsMixin
47
55
  });
48
56
  module.exports = __toCommonJS(index_exports);
49
57
 
@@ -166,13 +174,38 @@ var Policies = class {
166
174
  }
167
175
  };
168
176
 
169
- // src/field-definitions/default-field.ts
177
+ // src/mixins/mixin-factory.ts
178
+ function createTypedMethodsMixin(typeName, baseMethodName) {
179
+ const methodNames = {
180
+ create: `create${baseMethodName}`,
181
+ upset: `upset${baseMethodName}`,
182
+ get: `get${baseMethodName}`
183
+ };
184
+ return function(Base) {
185
+ return class FieldsWith extends Base {
186
+ // createBoolean, createMySignal, etc.
187
+ [methodNames.create](name, initialValue, options) {
188
+ return this.create(typeName, name, initialValue, options);
189
+ }
190
+ // upsetBoolean, upsetMySignal, etc.
191
+ [methodNames.upset](name, value, options) {
192
+ return this.upset(typeName, name, value, options);
193
+ }
194
+ // getBoolean, getMySignal, etc.
195
+ [methodNames.get](name) {
196
+ return this.get(name);
197
+ }
198
+ };
199
+ };
200
+ }
201
+
202
+ // src/field-definitions/core-field.ts
170
203
  var import_utils = require("@axi-engine/utils");
171
204
  var import_dequal = require("dequal");
172
- var DefaultField = class _DefaultField {
205
+ var CoreField = class _CoreField {
173
206
  /** A type keyword of the field */
174
207
  static typeName = "default";
175
- typeName = _DefaultField.typeName;
208
+ typeName = _CoreField.typeName;
176
209
  /** A unique identifier for the field. */
177
210
  _name;
178
211
  _value;
@@ -233,10 +266,10 @@ var DefaultField = class _DefaultField {
233
266
  }
234
267
  };
235
268
 
236
- // src/field-definitions/default-boolean-field.ts
237
- var DefaultBooleanField = class _DefaultBooleanField extends DefaultField {
269
+ // src/field-definitions/core-boolean-field.ts
270
+ var CoreBooleanField = class _CoreBooleanField extends CoreField {
238
271
  static typeName = "boolean";
239
- typeName = _DefaultBooleanField.typeName;
272
+ typeName = _CoreBooleanField.typeName;
240
273
  constructor(name, initialVal, options) {
241
274
  super(name, initialVal, options);
242
275
  }
@@ -246,10 +279,10 @@ var DefaultBooleanField = class _DefaultBooleanField extends DefaultField {
246
279
  }
247
280
  };
248
281
 
249
- // src/field-definitions/default-string-field.ts
250
- var DefaultStringField = class _DefaultStringField extends DefaultField {
282
+ // src/field-definitions/core-string-field.ts
283
+ var CoreStringField = class _CoreStringField extends CoreField {
251
284
  static typeName = "string";
252
- typeName = _DefaultStringField.typeName;
285
+ typeName = _CoreStringField.typeName;
253
286
  constructor(name, initialVal, options) {
254
287
  super(name, initialVal, options);
255
288
  }
@@ -273,11 +306,11 @@ var DefaultStringField = class _DefaultStringField extends DefaultField {
273
306
  }
274
307
  };
275
308
 
276
- // src/field-definitions/default-numeric-field.ts
309
+ // src/field-definitions/core-numeric-field.ts
277
310
  var import_utils2 = require("@axi-engine/utils");
278
- var DefaultNumericField = class _DefaultNumericField extends DefaultField {
311
+ var CoreNumericField = class _CoreNumericField extends CoreField {
279
312
  static typeName = "numeric";
280
- typeName = _DefaultNumericField.typeName;
313
+ typeName = _CoreNumericField.typeName;
281
314
  get min() {
282
315
  const policy = this.policies.get(ClampPolicy.id) ?? this.policies.get(ClampMinPolicy.id);
283
316
  return policy?.min;
@@ -457,9 +490,9 @@ var Fields = class _Fields {
457
490
  }
458
491
  /**
459
492
  * Retrieves a field by its name.
460
- * @template T - The expected `Field` type to be returned.
493
+ * @template TField - The expected `Field` type to be returned.
461
494
  * @param {string} name - The name of the field to retrieve.
462
- * @returns {T} The `Field` instance.
495
+ * @returns {TField} The `Field` instance.
463
496
  * @throws If the field does not exist.
464
497
  */
465
498
  get(name) {
@@ -499,70 +532,6 @@ var Fields = class _Fields {
499
532
  }
500
533
  };
501
534
 
502
- // src/mixins/with-boolean-fields.mixin.ts
503
- function WithBooleanFields(Base) {
504
- return class FieldsWithBoolean extends Base {
505
- createBoolean(name, initialValue, options) {
506
- return this.create(DefaultBooleanField.typeName, name, initialValue, options);
507
- }
508
- upsetBoolean(name, value, options) {
509
- return this.upset(DefaultBooleanField.typeName, name, value, options);
510
- }
511
- getBoolean(name) {
512
- return this.get(name);
513
- }
514
- };
515
- }
516
-
517
- // src/mixins/with-string-fields.mixin.ts
518
- function WithStringFields(Base) {
519
- return class FieldsWithString extends Base {
520
- createString(name, initialValue, options) {
521
- return this.create(DefaultStringField.typeName, name, initialValue, options);
522
- }
523
- upsetString(name, value, options) {
524
- return this.upset(DefaultStringField.typeName, name, value, options);
525
- }
526
- getString(name) {
527
- return this.get(name);
528
- }
529
- };
530
- }
531
-
532
- // src/mixins/with-numeric-fields.mixin.ts
533
- function WithNumericFields(Base) {
534
- return class FieldsWithNumeric extends Base {
535
- createNumeric(name, initialValue, options) {
536
- return this.create(DefaultNumericField.typeName, name, initialValue, options);
537
- }
538
- upsetNumeric(name, value, options) {
539
- return this.upset(DefaultNumericField.typeName, name, value, options);
540
- }
541
- getNumeric(name) {
542
- return this.get(name);
543
- }
544
- };
545
- }
546
-
547
- // src/mixins/with-default-generic-fields.mixin.ts
548
- function WithDefaultGenericFields(Base) {
549
- return class FieldsWithDefaultGeneric extends Base {
550
- createGeneric(name, initialValue, options) {
551
- return this.create(DefaultField.typeName, name, initialValue, options);
552
- }
553
- upsetGeneric(name, value, options) {
554
- return this.upset(DefaultField.typeName, name, value, options);
555
- }
556
- getGeneric(name) {
557
- return this.get(name);
558
- }
559
- };
560
- }
561
-
562
- // src/default-fields.ts
563
- var DefaultFields = class extends WithBooleanFields(WithStringFields(WithNumericFields(WithDefaultGenericFields(Fields)))) {
564
- };
565
-
566
535
  // src/field-tree.ts
567
536
  var import_utils5 = require("@axi-engine/utils");
568
537
  var FieldTree = class _FieldTree {
@@ -603,7 +572,7 @@ var FieldTree = class _FieldTree {
603
572
  }
604
573
  /**
605
574
  * Creates an instance of FieldTree.
606
- * @param {TreeNodeFactory} factory - A factory responsible for creating new nodes within the tree.
575
+ * @param {FieldTreeFactory} factory - A factory responsible for creating new nodes within the tree.
607
576
  */
608
577
  constructor(factory) {
609
578
  this._factory = factory;
@@ -742,6 +711,16 @@ var FieldTree = class _FieldTree {
742
711
  const traversedPath = this.traversePath(path, true);
743
712
  return traversedPath.branch.has(traversedPath.leafName) ? traversedPath.branch.getFields(traversedPath.leafName) : traversedPath.branch.createFields(traversedPath.leafName);
744
713
  }
714
+ /**
715
+ * Finds the parent node for a given path.
716
+ * @param path The path to the target node.
717
+ * @returns The parent node (either a FieldTree or Fields).
718
+ * @throws An error if the path is invalid or any intermediate node is not a FieldTree.
719
+ */
720
+ findParentNode(path) {
721
+ const info = this.traversePath(path);
722
+ return info.branch;
723
+ }
745
724
  /**
746
725
  * Removes all child nodes from this tree branch.
747
726
  * This method ensures that `destroy()` is called on each child node, allowing for
@@ -793,21 +772,59 @@ var FieldTree = class _FieldTree {
793
772
  }
794
773
  };
795
774
 
796
- // src/field-tree-node-factory.ts
797
- var DefaultFieldsFactory = class {
775
+ // src/mixins/with-boolean-fields.mixin.ts
776
+ var WithBooleanFields = createTypedMethodsMixin(CoreBooleanField.typeName, "Boolean");
777
+
778
+ // src/mixins/with-string-fields.mixin.ts
779
+ var WithStringFields = createTypedMethodsMixin(CoreBooleanField.typeName, "String");
780
+
781
+ // src/mixins/with-numeric-fields.mixin.ts
782
+ var WithNumericFields = createTypedMethodsMixin(CoreBooleanField.typeName, "Numeric");
783
+
784
+ // src/mixins/with-default-generic-fields.mixin.ts
785
+ function WithDefaultGenericFields(Base) {
786
+ return class FieldsWithDefaultGeneric extends Base {
787
+ createGeneric(name, initialValue, options) {
788
+ return this.create(CoreField.typeName, name, initialValue, options);
789
+ }
790
+ upsetGeneric(name, value, options) {
791
+ return this.upset(CoreField.typeName, name, value, options);
792
+ }
793
+ getGeneric(name) {
794
+ return this.get(name);
795
+ }
796
+ };
797
+ }
798
+
799
+ // src/core-fields.ts
800
+ var CoreFields = class extends WithBooleanFields(WithStringFields(WithNumericFields(WithDefaultGenericFields(Fields)))) {
801
+ };
802
+
803
+ // src/core-fields-factory.ts
804
+ var CoreFieldsFactory = class {
805
+ _fieldRegistry;
806
+ get fieldRegistry() {
807
+ return this._fieldRegistry;
808
+ }
798
809
  constructor(fieldRegistry) {
799
- this.fieldRegistry = fieldRegistry;
810
+ this._fieldRegistry = fieldRegistry;
800
811
  }
801
812
  fields() {
802
- return new DefaultFields(this.fieldRegistry);
813
+ return new CoreFields(this._fieldRegistry);
803
814
  }
804
815
  };
805
- var DefaultTreeNodeFactory = class extends DefaultFieldsFactory {
816
+
817
+ // src/core-field-tree.ts
818
+ var CoreFieldTree = class extends FieldTree {
819
+ };
820
+
821
+ // src/core-field-tree-factory.ts
822
+ var CoreTreeNodeFactory = class extends CoreFieldsFactory {
806
823
  constructor(fieldRegistry) {
807
824
  super(fieldRegistry);
808
825
  }
809
826
  tree() {
810
- return new FieldTree(this);
827
+ return new CoreFieldTree(this);
811
828
  }
812
829
  };
813
830
 
@@ -1028,6 +1045,196 @@ var FieldTreeSerializer = class {
1028
1045
  return tree;
1029
1046
  }
1030
1047
  };
1048
+
1049
+ // src/data-store-field-resolver.ts
1050
+ var import_utils9 = require("@axi-engine/utils");
1051
+ var NumericFieldResolver = class {
1052
+ typeName = CoreNumericField.typeName;
1053
+ supports(value) {
1054
+ return (0, import_utils9.isNumber)(value);
1055
+ }
1056
+ };
1057
+ var BooleanFieldResolver = class {
1058
+ typeName = CoreBooleanField.typeName;
1059
+ supports(value) {
1060
+ return (0, import_utils9.isBoolean)(value);
1061
+ }
1062
+ };
1063
+ var StringFieldResolver = class {
1064
+ typeName = CoreStringField.typeName;
1065
+ supports(value) {
1066
+ return (0, import_utils9.isString)(value);
1067
+ }
1068
+ };
1069
+
1070
+ // src/data-store.ts
1071
+ var import_utils10 = require("@axi-engine/utils");
1072
+ var DataStore = class {
1073
+ constructor(tree) {
1074
+ this.tree = tree;
1075
+ this.registerResolver(new NumericFieldResolver());
1076
+ this.registerResolver(new BooleanFieldResolver());
1077
+ this.registerResolver(new StringFieldResolver());
1078
+ }
1079
+ resolvers = [];
1080
+ rootFieldsName = "__root_fields";
1081
+ _rootFields;
1082
+ get rootFields() {
1083
+ if (!this._rootFields) {
1084
+ this._rootFields = this.tree.getOrCreateFields(this.rootFieldsName);
1085
+ }
1086
+ return this._rootFields;
1087
+ }
1088
+ registerResolver(resolver) {
1089
+ this.resolvers.unshift(resolver);
1090
+ }
1091
+ clearResolvers() {
1092
+ this.resolvers.length = 0;
1093
+ }
1094
+ getValue(path) {
1095
+ return this.getField(path).value;
1096
+ }
1097
+ setValue(path, val) {
1098
+ const field = this.getField(path);
1099
+ field.value = val;
1100
+ return field.value;
1101
+ }
1102
+ createValue(path, val, options) {
1103
+ const dest = this.getDestinationFields(path);
1104
+ if (options?.fieldType) {
1105
+ return dest.fields.create(options.fieldType, dest.leafName, val, options).value;
1106
+ }
1107
+ for (let resolver of this.resolvers) {
1108
+ if (resolver.supports(val)) {
1109
+ return dest.fields.create(resolver.typeName, dest.leafName, val, options).value;
1110
+ }
1111
+ }
1112
+ return dest.fields.createGeneric(dest.leafName, val, options).value;
1113
+ }
1114
+ upsetValue(path, val, options) {
1115
+ const dest = this.getDestinationFields(path);
1116
+ if (options?.fieldType) {
1117
+ return dest.fields.upset(options.fieldType, dest.leafName, val, options).value;
1118
+ }
1119
+ for (let resolver of this.resolvers) {
1120
+ if (resolver.supports(val)) {
1121
+ return dest.fields.upset(resolver.typeName, dest.leafName, val, options).value;
1122
+ }
1123
+ }
1124
+ return dest.fields.upsetGeneric(dest.leafName, val, options).value;
1125
+ }
1126
+ createBoolean(path, initialValue, options) {
1127
+ const dest = this.getDestinationFields(path);
1128
+ return dest.fields.createBoolean(dest.leafName, initialValue, options);
1129
+ }
1130
+ createNumeric(path, initialValue, options) {
1131
+ const dest = this.getDestinationFields(path);
1132
+ return dest.fields.createNumeric(dest.leafName, initialValue, options);
1133
+ }
1134
+ createString(path, initialValue, options) {
1135
+ const dest = this.getDestinationFields(path);
1136
+ return dest.fields.createString(dest.leafName, initialValue, options);
1137
+ }
1138
+ createGeneric(path, initialValue, options) {
1139
+ const dest = this.getDestinationFields(path);
1140
+ return dest.fields.createGeneric(dest.leafName, initialValue, options);
1141
+ }
1142
+ getBoolean(path) {
1143
+ return this.getField(path);
1144
+ }
1145
+ getNumeric(path) {
1146
+ return this.getField(path);
1147
+ }
1148
+ getString(path) {
1149
+ return this.getField(path);
1150
+ }
1151
+ getGeneric(path) {
1152
+ return this.getField(path);
1153
+ }
1154
+ getField(path) {
1155
+ const pathArr = (0, import_utils10.ensurePathArray)(path);
1156
+ (0, import_utils10.throwIfEmpty)(pathArr, `Wrong path or path is empty: ${(0, import_utils10.ensurePathString)(path)}, should contain at least one path segment`);
1157
+ if (this.isPathToRootFields(pathArr)) {
1158
+ return this.rootFields.get(pathArr[0]);
1159
+ }
1160
+ const fieldName = pathArr.pop();
1161
+ const fields = this.tree.getFields(pathArr);
1162
+ return fields.get(fieldName);
1163
+ }
1164
+ createFields(path) {
1165
+ return this.tree.createFields(path, true);
1166
+ }
1167
+ createTree(path) {
1168
+ return this.tree.createFieldTree(path, true);
1169
+ }
1170
+ getFields(path) {
1171
+ return this.tree.getFields(path);
1172
+ }
1173
+ getTree(path) {
1174
+ return this.tree.getFieldTree(path);
1175
+ }
1176
+ remove(path) {
1177
+ const pathArr = (0, import_utils10.ensurePathArray)(path);
1178
+ (0, import_utils10.throwIfEmpty)(pathArr, `Wrong path or path is empty: ${(0, import_utils10.ensurePathString)(path)}, should contain at least one path segment`);
1179
+ if (this.isPathToRootFields(pathArr)) {
1180
+ this.rootFields.remove(pathArr);
1181
+ return;
1182
+ }
1183
+ const node = this.tree.findParentNode(pathArr);
1184
+ const leafName = pathArr[pathArr.length - 1];
1185
+ if (node instanceof CoreFields) {
1186
+ node.remove(leafName);
1187
+ } else if (node instanceof CoreFieldTree) {
1188
+ node.removeNode(leafName);
1189
+ }
1190
+ }
1191
+ isPathToRootFields(path) {
1192
+ return (0, import_utils10.ensurePathArray)(path).length === 1;
1193
+ }
1194
+ getDestinationFields(path) {
1195
+ const pathArr = (0, import_utils10.ensurePathArray)(path);
1196
+ if (this.isPathToRootFields(pathArr)) {
1197
+ return { fields: this.rootFields, leafName: pathArr[0] };
1198
+ }
1199
+ const leafName = pathArr.pop();
1200
+ return { fields: this.tree.getOrCreateFields(path), leafName };
1201
+ }
1202
+ };
1203
+
1204
+ // src/setup.ts
1205
+ function createCoreFieldRegistry() {
1206
+ const fieldRegistry = new FieldRegistry();
1207
+ fieldRegistry.register(CoreField.typeName, CoreField);
1208
+ fieldRegistry.register(CoreNumericField.typeName, CoreNumericField);
1209
+ fieldRegistry.register(CoreStringField.typeName, CoreStringField);
1210
+ fieldRegistry.register(CoreBooleanField.typeName, CoreBooleanField);
1211
+ return fieldRegistry;
1212
+ }
1213
+ function createCorePolicySerializer() {
1214
+ const policySerializer = new PolicySerializer();
1215
+ policySerializer.register(ClampPolicy.id, new ClampPolicySerializerHandler());
1216
+ policySerializer.register(ClampMinPolicy.id, new ClampMinPolicySerializerHandler());
1217
+ policySerializer.register(ClampMaxPolicy.id, new ClampMaxPolicySerializerHandler());
1218
+ return policySerializer;
1219
+ }
1220
+ function createCoreTreeNodeFactory(fieldRegistry) {
1221
+ return new CoreTreeNodeFactory(fieldRegistry);
1222
+ }
1223
+ function createCoreTreeSerializer(fieldTreeNodeFactory, policySerializer) {
1224
+ return new FieldTreeSerializer(
1225
+ fieldTreeNodeFactory,
1226
+ new FieldsSerializer(
1227
+ fieldTreeNodeFactory,
1228
+ new FieldSerializer(fieldTreeNodeFactory.fieldRegistry, policySerializer ?? createCorePolicySerializer())
1229
+ )
1230
+ );
1231
+ }
1232
+ function createCoreFieldSystem(config) {
1233
+ const registry = config?.registry ?? createCoreFieldRegistry();
1234
+ const factory = createCoreTreeNodeFactory(registry);
1235
+ const serializer = createCoreTreeSerializer(factory, config?.policySerializer);
1236
+ return { factory, serializer };
1237
+ }
1031
1238
  // Annotate the CommonJS export names for ESM import in node:
1032
1239
  0 && (module.exports = {
1033
1240
  ClampMaxPolicy,
@@ -1036,13 +1243,15 @@ var FieldTreeSerializer = class {
1036
1243
  ClampMinPolicySerializerHandler,
1037
1244
  ClampPolicy,
1038
1245
  ClampPolicySerializerHandler,
1039
- DefaultBooleanField,
1040
- DefaultField,
1041
- DefaultFields,
1042
- DefaultFieldsFactory,
1043
- DefaultNumericField,
1044
- DefaultStringField,
1045
- DefaultTreeNodeFactory,
1246
+ CoreBooleanField,
1247
+ CoreField,
1248
+ CoreFieldTree,
1249
+ CoreFields,
1250
+ CoreFieldsFactory,
1251
+ CoreNumericField,
1252
+ CoreStringField,
1253
+ CoreTreeNodeFactory,
1254
+ DataStore,
1046
1255
  FieldRegistry,
1047
1256
  FieldSerializer,
1048
1257
  FieldTree,
@@ -1053,5 +1262,11 @@ var FieldTreeSerializer = class {
1053
1262
  PolicySerializer,
1054
1263
  clampMaxPolicy,
1055
1264
  clampMinPolicy,
1056
- clampPolicy
1265
+ clampPolicy,
1266
+ createCoreFieldRegistry,
1267
+ createCoreFieldSystem,
1268
+ createCorePolicySerializer,
1269
+ createCoreTreeNodeFactory,
1270
+ createCoreTreeSerializer,
1271
+ createTypedMethodsMixin
1057
1272
  });