@axi-engine/fields 0.3.8 → 0.3.10
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.d.mts +266 -26
- package/dist/index.d.ts +266 -26
- package/dist/index.js +225 -59
- package/dist/index.mjs +216 -51
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -318,6 +318,9 @@ var Fields = class _Fields {
|
|
|
318
318
|
onRemove = new Emitter2();
|
|
319
319
|
/**
|
|
320
320
|
* Gets the read-only map of all `Field` instances in this container.
|
|
321
|
+
*
|
|
322
|
+
* @internal
|
|
323
|
+
*
|
|
321
324
|
* @returns {Map<string, Field<any>>} The collection of fields.
|
|
322
325
|
*/
|
|
323
326
|
get fields() {
|
|
@@ -464,11 +467,28 @@ var FieldTree = class _FieldTree {
|
|
|
464
467
|
*/
|
|
465
468
|
onRemove = new Emitter3();
|
|
466
469
|
/**
|
|
467
|
-
*
|
|
470
|
+
* Provides direct access to the internal node storage.
|
|
471
|
+
*
|
|
472
|
+
* @remarks
|
|
473
|
+
* This is primarily intended for **serialization**, debugging, or low-level iteration.
|
|
474
|
+
* Avoid modifying this map directly to maintain internal consistency; use {@link addNode} or {@link removeNode} instead.
|
|
475
|
+
* @internal
|
|
468
476
|
*/
|
|
469
477
|
get nodes() {
|
|
470
478
|
return this._nodes;
|
|
471
479
|
}
|
|
480
|
+
/**
|
|
481
|
+
* Exposes the internal factory instance used by this tree.
|
|
482
|
+
*
|
|
483
|
+
* @remarks
|
|
484
|
+
* Direct usage of this getter is generally unnecessary.
|
|
485
|
+
* Prefer using {@link createDetachedTree} or {@link createDetachedFields} to create isolated instances.
|
|
486
|
+
*
|
|
487
|
+
* @returns {FieldTreeFactory} The factory instance.
|
|
488
|
+
*/
|
|
489
|
+
get factory() {
|
|
490
|
+
return this._factory;
|
|
491
|
+
}
|
|
472
492
|
/**
|
|
473
493
|
* Creates an instance of FieldTree.
|
|
474
494
|
* @param {FieldTreeFactory} factory - A factory responsible for creating new nodes within the tree.
|
|
@@ -640,6 +660,23 @@ var FieldTree = class _FieldTree {
|
|
|
640
660
|
this.onAdd.clear();
|
|
641
661
|
this.onRemove.clear();
|
|
642
662
|
}
|
|
663
|
+
/**
|
|
664
|
+
* Creates a new, detached FieldTree instance using the same factory as this tree.
|
|
665
|
+
* This new tree has no parent and is completely isolated.
|
|
666
|
+
*
|
|
667
|
+
* @returns A new instance of the same tree type.
|
|
668
|
+
*/
|
|
669
|
+
createDetachedTree() {
|
|
670
|
+
return this._factory.tree();
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* Creates a new, detached Fields container using the same factory.
|
|
674
|
+
*
|
|
675
|
+
* @returns
|
|
676
|
+
*/
|
|
677
|
+
createDetachedFields() {
|
|
678
|
+
return this._factory.fields();
|
|
679
|
+
}
|
|
643
680
|
/**
|
|
644
681
|
* @private
|
|
645
682
|
* Navigates the tree to the parent of a target node.
|
|
@@ -837,13 +874,35 @@ var FieldSerializer = class {
|
|
|
837
874
|
const fieldType = snapshot.__type;
|
|
838
875
|
throwIfEmpty3(fieldType, 'Invalid field snapshot: missing "__type" identifier.');
|
|
839
876
|
const Ctor = this.fieldRegistry.getOrThrow(fieldType);
|
|
840
|
-
let policies;
|
|
841
|
-
if (!isNullOrUndefined2(snapshot.policies)) {
|
|
842
|
-
policies = [];
|
|
843
|
-
snapshot.policies.forEach((p) => policies.push(this.policySerializer.hydrate(p)));
|
|
844
|
-
}
|
|
877
|
+
let policies = this.hydratePolicies(snapshot);
|
|
845
878
|
return new Ctor(snapshot.name, snapshot.value, { policies });
|
|
846
879
|
}
|
|
880
|
+
/**
|
|
881
|
+
* Updates an existing Field instance with data from a snapshot.
|
|
882
|
+
*
|
|
883
|
+
* This method modifies the field in-place, preserving the object reference.
|
|
884
|
+
* It updates the field's value and completely replaces its current policies
|
|
885
|
+
* with the ones defined in the snapshot.
|
|
886
|
+
*
|
|
887
|
+
* @param {Field<any>} field - The existing Field instance to update.
|
|
888
|
+
* @param {FieldSnapshot} snapshot - The snapshot containing the new state.
|
|
889
|
+
*/
|
|
890
|
+
patch(field, snapshot) {
|
|
891
|
+
let policies = this.hydratePolicies(snapshot);
|
|
892
|
+
field.policies.clear();
|
|
893
|
+
if (policies) {
|
|
894
|
+
policies.forEach((p) => field.policies.add(p));
|
|
895
|
+
}
|
|
896
|
+
field.value = snapshot.value;
|
|
897
|
+
}
|
|
898
|
+
hydratePolicies(snapshot) {
|
|
899
|
+
if (isNullOrUndefined2(snapshot.policies)) {
|
|
900
|
+
return void 0;
|
|
901
|
+
}
|
|
902
|
+
const policies = [];
|
|
903
|
+
snapshot.policies.forEach((p) => policies.push(this.policySerializer.hydrate(p)));
|
|
904
|
+
return policies;
|
|
905
|
+
}
|
|
847
906
|
};
|
|
848
907
|
|
|
849
908
|
// src/serializer/fields-serializer.ts
|
|
@@ -894,9 +953,17 @@ var FieldsSerializer = class {
|
|
|
894
953
|
// src/serializer/field-tree-serializer.ts
|
|
895
954
|
import { isString } from "@axi-engine/utils";
|
|
896
955
|
var FieldTreeSerializer = class {
|
|
956
|
+
_factory;
|
|
957
|
+
_fieldsSerializer;
|
|
958
|
+
get factory() {
|
|
959
|
+
return this._factory;
|
|
960
|
+
}
|
|
961
|
+
get fieldsSerializer() {
|
|
962
|
+
return this._fieldsSerializer;
|
|
963
|
+
}
|
|
897
964
|
constructor(fieldTreeNodeFactory, fieldsSerializer) {
|
|
898
|
-
this.
|
|
899
|
-
this.
|
|
965
|
+
this._factory = fieldTreeNodeFactory;
|
|
966
|
+
this._fieldsSerializer = fieldsSerializer;
|
|
900
967
|
}
|
|
901
968
|
/**
|
|
902
969
|
* Creates a serializable snapshot of the entire tree and its contained fields.
|
|
@@ -922,7 +989,7 @@ var FieldTreeSerializer = class {
|
|
|
922
989
|
*/
|
|
923
990
|
hydrate(snapshot) {
|
|
924
991
|
const { __type, ...nodes } = snapshot;
|
|
925
|
-
const tree = this.
|
|
992
|
+
const tree = this._factory.tree();
|
|
926
993
|
for (const key in nodes) {
|
|
927
994
|
const nodeData = nodes[key];
|
|
928
995
|
if (isString(nodeData)) {
|
|
@@ -962,23 +1029,52 @@ var StringFieldResolver = class {
|
|
|
962
1029
|
}
|
|
963
1030
|
};
|
|
964
1031
|
|
|
1032
|
+
// src/guards.ts
|
|
1033
|
+
import { isNullOrUndefined as isNullOrUndefined3 } from "@axi-engine/utils";
|
|
1034
|
+
function isFields(value) {
|
|
1035
|
+
return !isNullOrUndefined3(value) && value.typeName === Fields.typeName;
|
|
1036
|
+
}
|
|
1037
|
+
function isFieldTree(value) {
|
|
1038
|
+
return !isNullOrUndefined3(value) && value.typeName === FieldTree.typeName;
|
|
1039
|
+
}
|
|
1040
|
+
function isDataStore(value) {
|
|
1041
|
+
return !isNullOrUndefined3(value) && value.typeName === DataStore.typeName;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
965
1044
|
// src/data-store.ts
|
|
966
|
-
var DataStore = class {
|
|
967
|
-
|
|
968
|
-
|
|
1045
|
+
var DataStore = class _DataStore {
|
|
1046
|
+
static typeName = "dataStore";
|
|
1047
|
+
typeName = _DataStore.typeName;
|
|
1048
|
+
resolvers = [];
|
|
1049
|
+
_variables;
|
|
1050
|
+
_tree;
|
|
1051
|
+
_factory;
|
|
1052
|
+
get variables() {
|
|
1053
|
+
if (!this._variables) {
|
|
1054
|
+
this._variables = this._factory.fields();
|
|
1055
|
+
}
|
|
1056
|
+
return this._variables;
|
|
1057
|
+
}
|
|
1058
|
+
get tree() {
|
|
1059
|
+
if (!this._tree) {
|
|
1060
|
+
this._tree = this._factory.tree();
|
|
1061
|
+
}
|
|
1062
|
+
return this._tree;
|
|
1063
|
+
}
|
|
1064
|
+
constructor(treeOrFactory, variables) {
|
|
1065
|
+
if (!isFieldTree(treeOrFactory)) {
|
|
1066
|
+
this._factory = treeOrFactory;
|
|
1067
|
+
} else {
|
|
1068
|
+
this._tree = treeOrFactory;
|
|
1069
|
+
this._factory = this._tree.factory;
|
|
1070
|
+
}
|
|
1071
|
+
if (variables) {
|
|
1072
|
+
this._variables = variables;
|
|
1073
|
+
}
|
|
969
1074
|
this.registerResolver(new NumericFieldResolver());
|
|
970
1075
|
this.registerResolver(new BooleanFieldResolver());
|
|
971
1076
|
this.registerResolver(new StringFieldResolver());
|
|
972
1077
|
}
|
|
973
|
-
resolvers = [];
|
|
974
|
-
rootFieldsName = "__root_fields";
|
|
975
|
-
_rootFields;
|
|
976
|
-
get rootFields() {
|
|
977
|
-
if (!this._rootFields) {
|
|
978
|
-
this._rootFields = this.tree.getOrCreateFields(this.rootFieldsName);
|
|
979
|
-
}
|
|
980
|
-
return this._rootFields;
|
|
981
|
-
}
|
|
982
1078
|
registerResolver(resolver) {
|
|
983
1079
|
this.resolvers.unshift(resolver);
|
|
984
1080
|
}
|
|
@@ -1048,8 +1144,8 @@ var DataStore = class {
|
|
|
1048
1144
|
getField(path) {
|
|
1049
1145
|
const pathArr = ensurePathArray2(path);
|
|
1050
1146
|
throwIfEmpty4(pathArr, `Wrong path or path is empty: ${ensurePathString2(path)}, should contain at least one path segment`);
|
|
1051
|
-
if (this.
|
|
1052
|
-
return this.
|
|
1147
|
+
if (this.isPathToVariables(pathArr)) {
|
|
1148
|
+
return this.variables.get(pathArr[0]);
|
|
1053
1149
|
}
|
|
1054
1150
|
const fieldName = pathArr.pop();
|
|
1055
1151
|
const fields = this.tree.getFields(pathArr);
|
|
@@ -1070,8 +1166,8 @@ var DataStore = class {
|
|
|
1070
1166
|
remove(path) {
|
|
1071
1167
|
const pathArr = ensurePathArray2(path);
|
|
1072
1168
|
throwIfEmpty4(pathArr, `Wrong path or path is empty: ${ensurePathString2(path)}, should contain at least one path segment`);
|
|
1073
|
-
if (this.
|
|
1074
|
-
this.
|
|
1169
|
+
if (this.isPathToVariables(pathArr)) {
|
|
1170
|
+
this.variables.remove(pathArr);
|
|
1075
1171
|
return;
|
|
1076
1172
|
}
|
|
1077
1173
|
const node = this.tree.findParentNode(pathArr);
|
|
@@ -1082,25 +1178,26 @@ var DataStore = class {
|
|
|
1082
1178
|
node.removeNode(leafName);
|
|
1083
1179
|
}
|
|
1084
1180
|
}
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1181
|
+
/**
|
|
1182
|
+
* Creates a new, independent instance of the Store with a fresh, empty data state (FieldsTree).
|
|
1183
|
+
*
|
|
1184
|
+
* The new instance retains the same capabilities (e.g., factory configuration)
|
|
1185
|
+
* as the current one but is completely detached from the existing data hierarchy.
|
|
1186
|
+
* This is useful for creating local scopes, stack frames, or temporary data contexts.
|
|
1187
|
+
*
|
|
1188
|
+
* @returns {DataStore} A new, isolated DataStore instance.
|
|
1189
|
+
*/
|
|
1190
|
+
createIsolated() {
|
|
1191
|
+
return new _DataStore(this._factory);
|
|
1095
1192
|
}
|
|
1193
|
+
/** code below -> implementation of the DataStore from utils */
|
|
1096
1194
|
has(path) {
|
|
1097
1195
|
const pathArr = ensurePathArray2(path);
|
|
1098
|
-
if (this.
|
|
1099
|
-
return this.
|
|
1196
|
+
if (this.isPathToVariables(pathArr)) {
|
|
1197
|
+
return this.variables.has(pathArr[0]);
|
|
1100
1198
|
}
|
|
1101
1199
|
return this.tree.hasPath(pathArr);
|
|
1102
1200
|
}
|
|
1103
|
-
/** implementation of the DataStore from utils */
|
|
1104
1201
|
get(path) {
|
|
1105
1202
|
return this.getField(path).value;
|
|
1106
1203
|
}
|
|
@@ -1116,19 +1213,86 @@ var DataStore = class {
|
|
|
1116
1213
|
delete(path) {
|
|
1117
1214
|
this.remove(path);
|
|
1118
1215
|
}
|
|
1216
|
+
/**
|
|
1217
|
+
* @internal Used for serialization
|
|
1218
|
+
*/
|
|
1219
|
+
getInternalVariables() {
|
|
1220
|
+
return this._variables;
|
|
1221
|
+
}
|
|
1222
|
+
/**
|
|
1223
|
+
* @internal Used for serialization
|
|
1224
|
+
*/
|
|
1225
|
+
getInternalTree() {
|
|
1226
|
+
return this._tree;
|
|
1227
|
+
}
|
|
1228
|
+
/**
|
|
1229
|
+
* @private
|
|
1230
|
+
*/
|
|
1231
|
+
isPathToVariables(path) {
|
|
1232
|
+
return ensurePathArray2(path).length === 1;
|
|
1233
|
+
}
|
|
1234
|
+
/**
|
|
1235
|
+
* @private
|
|
1236
|
+
*/
|
|
1237
|
+
getDestinationFields(path) {
|
|
1238
|
+
const pathArr = ensurePathArray2(path);
|
|
1239
|
+
if (this.isPathToVariables(pathArr)) {
|
|
1240
|
+
return { fields: this.variables, leafName: pathArr[0] };
|
|
1241
|
+
}
|
|
1242
|
+
const leafName = pathArr.pop();
|
|
1243
|
+
return { fields: this.tree.getOrCreateFields(path), leafName };
|
|
1244
|
+
}
|
|
1119
1245
|
};
|
|
1120
1246
|
|
|
1121
|
-
// src/
|
|
1122
|
-
import { isNullOrUndefined as
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1247
|
+
// src/serializer/data-store-serializer.ts
|
|
1248
|
+
import { isNullOrUndefined as isNullOrUndefined4 } from "@axi-engine/utils";
|
|
1249
|
+
var DataStoreSerializer = class {
|
|
1250
|
+
/**
|
|
1251
|
+
* Creates an instance of DataStoreSerializer.
|
|
1252
|
+
* @param {FieldTreeSerializer} fieldTreeSerializer - The serializer used for the underlying tree and fields.
|
|
1253
|
+
*/
|
|
1254
|
+
constructor(fieldTreeSerializer) {
|
|
1255
|
+
this.fieldTreeSerializer = fieldTreeSerializer;
|
|
1256
|
+
}
|
|
1257
|
+
/**
|
|
1258
|
+
* Captures the current state of a DataStore into a serializable snapshot.
|
|
1259
|
+
*
|
|
1260
|
+
* It checks for the existence of internal variables and the internal tree,
|
|
1261
|
+
* serializing them only if they have been initialized (lazy serialization).
|
|
1262
|
+
*
|
|
1263
|
+
* @param {DataStore} store - The store instance to serialize.
|
|
1264
|
+
* @returns {DataStoreSnapshot} The snapshot object.
|
|
1265
|
+
*/
|
|
1266
|
+
snapshot(store) {
|
|
1267
|
+
let snapshot = {
|
|
1268
|
+
__type: store.typeName
|
|
1269
|
+
};
|
|
1270
|
+
const variables = store.getInternalVariables();
|
|
1271
|
+
if (variables) {
|
|
1272
|
+
snapshot.variables = this.fieldTreeSerializer.fieldsSerializer.snapshot(variables);
|
|
1273
|
+
}
|
|
1274
|
+
const tree = store.getInternalTree();
|
|
1275
|
+
if (tree) {
|
|
1276
|
+
snapshot.tree = this.fieldTreeSerializer.snapshot(tree);
|
|
1277
|
+
}
|
|
1278
|
+
return snapshot;
|
|
1279
|
+
}
|
|
1280
|
+
/**
|
|
1281
|
+
* Reconstructs a DataStore instance from a snapshot.
|
|
1282
|
+
*
|
|
1283
|
+
* If the snapshot contains a tree, the store is initialized with it.
|
|
1284
|
+
* If not, the store is initialized with the factory (lazy mode), and the
|
|
1285
|
+
* detached variables are injected if present.
|
|
1286
|
+
*
|
|
1287
|
+
* @param {DataStoreSnapshot} snapshot - The snapshot to hydrate.
|
|
1288
|
+
* @returns {DataStore} A new, fully restored DataStore instance.
|
|
1289
|
+
*/
|
|
1290
|
+
hydrate(snapshot) {
|
|
1291
|
+
const tree = isNullOrUndefined4(snapshot.tree) ? void 0 : this.fieldTreeSerializer.hydrate(snapshot.tree);
|
|
1292
|
+
const variables = isNullOrUndefined4(snapshot.variables) ? void 0 : this.fieldTreeSerializer.fieldsSerializer.hydrate(snapshot.variables);
|
|
1293
|
+
return new DataStore(tree ? tree : this.fieldTreeSerializer.factory, variables);
|
|
1294
|
+
}
|
|
1295
|
+
};
|
|
1132
1296
|
|
|
1133
1297
|
// src/setup.ts
|
|
1134
1298
|
function createCoreFieldRegistry() {
|
|
@@ -1180,6 +1344,7 @@ export {
|
|
|
1180
1344
|
CoreStringField,
|
|
1181
1345
|
CoreTreeNodeFactory,
|
|
1182
1346
|
DataStore,
|
|
1347
|
+
DataStoreSerializer,
|
|
1183
1348
|
FieldRegistry,
|
|
1184
1349
|
FieldSerializer,
|
|
1185
1350
|
FieldTree,
|
|
@@ -1197,7 +1362,7 @@ export {
|
|
|
1197
1362
|
createCoreTreeNodeFactory,
|
|
1198
1363
|
createCoreTreeSerializer,
|
|
1199
1364
|
createTypedMethodsMixin,
|
|
1365
|
+
isDataStore,
|
|
1200
1366
|
isFieldTree,
|
|
1201
|
-
isFields
|
|
1202
|
-
isStore
|
|
1367
|
+
isFields
|
|
1203
1368
|
};
|