@axi-engine/fields 0.3.10 → 0.3.12
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 +149 -67
- package/dist/index.d.ts +149 -67
- package/dist/index.js +274 -117
- package/dist/index.mjs +267 -114
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -408,6 +408,9 @@ var Fields = class _Fields {
|
|
|
408
408
|
*/
|
|
409
409
|
remove(names) {
|
|
410
410
|
const namesToRemove = Array.isArray(names) ? names : [names];
|
|
411
|
+
if (!namesToRemove.length) {
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
411
414
|
const reallyRemoved = namesToRemove.filter((name) => {
|
|
412
415
|
const field = this._fields.get(name);
|
|
413
416
|
if (!field) {
|
|
@@ -764,7 +767,7 @@ var CoreTreeNodeFactory = class extends CoreFieldsFactory {
|
|
|
764
767
|
}
|
|
765
768
|
};
|
|
766
769
|
|
|
767
|
-
// src/
|
|
770
|
+
// src/serializers/policies/clamp-policy-serializer-handler.ts
|
|
768
771
|
var ClampPolicySerializerHandler = class {
|
|
769
772
|
snapshot(policy) {
|
|
770
773
|
return { min: policy.min, max: policy.max };
|
|
@@ -774,7 +777,7 @@ var ClampPolicySerializerHandler = class {
|
|
|
774
777
|
}
|
|
775
778
|
};
|
|
776
779
|
|
|
777
|
-
// src/
|
|
780
|
+
// src/serializers/policies/clamp-max-policy-serializer-handler.ts
|
|
778
781
|
var ClampMaxPolicySerializerHandler = class {
|
|
779
782
|
snapshot(policy) {
|
|
780
783
|
return { max: policy.max };
|
|
@@ -784,7 +787,7 @@ var ClampMaxPolicySerializerHandler = class {
|
|
|
784
787
|
}
|
|
785
788
|
};
|
|
786
789
|
|
|
787
|
-
// src/
|
|
790
|
+
// src/serializers/policies/clamp-min-policy-serializer-handler.ts
|
|
788
791
|
var ClampMinPolicySerializerHandler = class {
|
|
789
792
|
snapshot(policy) {
|
|
790
793
|
return { min: policy.min };
|
|
@@ -794,7 +797,7 @@ var ClampMinPolicySerializerHandler = class {
|
|
|
794
797
|
}
|
|
795
798
|
};
|
|
796
799
|
|
|
797
|
-
// src/
|
|
800
|
+
// src/serializers/policy-serializer.ts
|
|
798
801
|
import { Registry as Registry2, throwIfEmpty as throwIfEmpty2 } from "@axi-engine/utils";
|
|
799
802
|
var PolicySerializer = class {
|
|
800
803
|
handlers = new Registry2();
|
|
@@ -831,9 +834,9 @@ var PolicySerializer = class {
|
|
|
831
834
|
}
|
|
832
835
|
};
|
|
833
836
|
|
|
834
|
-
// src/
|
|
837
|
+
// src/serializers/field-hydrator.ts
|
|
835
838
|
import { isNullOrUndefined as isNullOrUndefined2, throwIfEmpty as throwIfEmpty3 } from "@axi-engine/utils";
|
|
836
|
-
var
|
|
839
|
+
var FieldHydrator = class {
|
|
837
840
|
/**
|
|
838
841
|
* Creates an instance of FieldSerializer.
|
|
839
842
|
* @param {FieldRegistry} fieldRegistry - A registry that maps string type names to Field constructors.
|
|
@@ -843,25 +846,6 @@ var FieldSerializer = class {
|
|
|
843
846
|
this.fieldRegistry = fieldRegistry;
|
|
844
847
|
this.policySerializer = policySerializer;
|
|
845
848
|
}
|
|
846
|
-
/**
|
|
847
|
-
* Creates a serializable snapshot of a Field instance.
|
|
848
|
-
* The snapshot includes the field's type, name, current value, and the state of all its policies.
|
|
849
|
-
* @param {Field<any>} field - The Field instance to serialize.
|
|
850
|
-
* @returns {FieldSnapshot} A plain object ready for JSON serialization.
|
|
851
|
-
*/
|
|
852
|
-
snapshot(field) {
|
|
853
|
-
let snapshot = {
|
|
854
|
-
__type: field.typeName,
|
|
855
|
-
name: field.name,
|
|
856
|
-
value: field.value
|
|
857
|
-
};
|
|
858
|
-
if (!field.policies.isEmpty()) {
|
|
859
|
-
const serializedPolicies = [];
|
|
860
|
-
field.policies.items.forEach((policy) => serializedPolicies.push(this.policySerializer.snapshot(policy)));
|
|
861
|
-
snapshot.policies = serializedPolicies;
|
|
862
|
-
}
|
|
863
|
-
return snapshot;
|
|
864
|
-
}
|
|
865
849
|
/**
|
|
866
850
|
* Restores a Field instance from its snapshot representation.
|
|
867
851
|
* It uses the `__type` property to find the correct constructor and hydrates
|
|
@@ -888,48 +872,50 @@ var FieldSerializer = class {
|
|
|
888
872
|
* @param {FieldSnapshot} snapshot - The snapshot containing the new state.
|
|
889
873
|
*/
|
|
890
874
|
patch(field, snapshot) {
|
|
891
|
-
let policies = this.hydratePolicies(snapshot);
|
|
892
875
|
field.policies.clear();
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
}
|
|
876
|
+
const policies = this.hydratePolicies(snapshot);
|
|
877
|
+
policies?.forEach((p) => field.policies.add(p));
|
|
896
878
|
field.value = snapshot.value;
|
|
897
879
|
}
|
|
898
880
|
hydratePolicies(snapshot) {
|
|
899
|
-
|
|
900
|
-
|
|
881
|
+
return isNullOrUndefined2(snapshot.policies) ? void 0 : snapshot.policies.map((p) => this.policySerializer.hydrate(p));
|
|
882
|
+
}
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
// src/serializers/field-snapshotter.ts
|
|
886
|
+
var FieldSnapshotter = class {
|
|
887
|
+
constructor(policySerializer) {
|
|
888
|
+
this.policySerializer = policySerializer;
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* Creates a serializable snapshot of a Field instance.
|
|
892
|
+
* The snapshot includes the field's type, name, current value, and the state of all its policies.
|
|
893
|
+
* @param {Field<any>} field - The Field instance to serialize.
|
|
894
|
+
* @returns {FieldSnapshot} A plain object ready for JSON serialization.
|
|
895
|
+
*/
|
|
896
|
+
snapshot(field) {
|
|
897
|
+
let snapshot = {
|
|
898
|
+
__type: field.typeName,
|
|
899
|
+
name: field.name,
|
|
900
|
+
value: field.value
|
|
901
|
+
};
|
|
902
|
+
if (!field.policies.isEmpty()) {
|
|
903
|
+
snapshot.policies = Array.from(field.policies.items.values()).map((policy) => this.policySerializer.snapshot(policy));
|
|
901
904
|
}
|
|
902
|
-
|
|
903
|
-
snapshot.policies.forEach((p) => policies.push(this.policySerializer.hydrate(p)));
|
|
904
|
-
return policies;
|
|
905
|
+
return snapshot;
|
|
905
906
|
}
|
|
906
907
|
};
|
|
907
908
|
|
|
908
|
-
// src/
|
|
909
|
-
var
|
|
909
|
+
// src/serializers/fields-hydrator.ts
|
|
910
|
+
var FieldsHydrator = class {
|
|
910
911
|
/**
|
|
911
912
|
* Creates an instance of FieldsSerializer.
|
|
912
913
|
* @param {FieldsFactory} fieldsFactory - A registry that maps string type names to Field constructors.
|
|
913
|
-
* @param {
|
|
914
|
+
* @param {FieldHydrator} fieldHydrator - A hydrator of field instances.
|
|
914
915
|
*/
|
|
915
|
-
constructor(fieldsFactory,
|
|
916
|
+
constructor(fieldsFactory, fieldHydrator) {
|
|
916
917
|
this.fieldsFactory = fieldsFactory;
|
|
917
|
-
this.
|
|
918
|
-
}
|
|
919
|
-
/**
|
|
920
|
-
* Creates a serializable snapshot of a `Fields` container.
|
|
921
|
-
*
|
|
922
|
-
* The snapshot includes a `__type` identifier (currently hardcoded) and an array of snapshots
|
|
923
|
-
* for each `Field` within the container.
|
|
924
|
-
* @param {Fields} fields - The `Fields` instance to serialize.
|
|
925
|
-
* @returns {FieldsSnapshot} A plain object ready for JSON serialization.
|
|
926
|
-
*/
|
|
927
|
-
snapshot(fields) {
|
|
928
|
-
const res = {
|
|
929
|
-
__type: fields.typeName
|
|
930
|
-
};
|
|
931
|
-
fields.fields.forEach((field) => res[field.name] = this.fieldSerializer.snapshot(field));
|
|
932
|
-
return res;
|
|
918
|
+
this.fieldHydrator = fieldHydrator;
|
|
933
919
|
}
|
|
934
920
|
/**
|
|
935
921
|
* Restores a `Fields` container instance from its snapshot representation.
|
|
@@ -943,45 +929,81 @@ var FieldsSerializer = class {
|
|
|
943
929
|
const fields = this.fieldsFactory.fields();
|
|
944
930
|
for (const fieldName in fieldsData) {
|
|
945
931
|
const fieldSnapshot = fieldsData[fieldName];
|
|
946
|
-
const restoredField = this.
|
|
932
|
+
const restoredField = this.fieldHydrator.hydrate(fieldSnapshot);
|
|
947
933
|
fields.add(restoredField);
|
|
948
934
|
}
|
|
949
935
|
return fields;
|
|
950
936
|
}
|
|
937
|
+
/**
|
|
938
|
+
* Synchronizes an existing `Fields` container with a snapshot.
|
|
939
|
+
*
|
|
940
|
+
* This method performs a "smart update":
|
|
941
|
+
* 1. **Removes** fields from the container that are missing in the snapshot.
|
|
942
|
+
* 2. **Patches** existing fields in-place using {@link FieldHydrator.patch}, preserving object references.
|
|
943
|
+
* 3. **Creates** (hydrates) and adds new fields that exist in the snapshot but not in the container.
|
|
944
|
+
*
|
|
945
|
+
* @param {Fields} fields - The target `Fields` container to update.
|
|
946
|
+
* @param {FieldsSnapshot} snapshot - The source snapshot containing the desired state.
|
|
947
|
+
*/
|
|
948
|
+
patch(fields, snapshot) {
|
|
949
|
+
const { __type, ...fieldsData } = snapshot;
|
|
950
|
+
const snapshotKeys = new Set(Object.keys(fieldsData));
|
|
951
|
+
const fieldsToRemove = Array.from(fields.fields.values()).filter((f) => !snapshotKeys.has(f.name)).map((f) => f.name);
|
|
952
|
+
fields.remove(fieldsToRemove);
|
|
953
|
+
for (const fieldName in fieldsData) {
|
|
954
|
+
const fieldSnapshot = fieldsData[fieldName];
|
|
955
|
+
if (fields.has(fieldName)) {
|
|
956
|
+
const existingField = fields.get(fieldName);
|
|
957
|
+
this.fieldHydrator.patch(existingField, fieldSnapshot);
|
|
958
|
+
} else {
|
|
959
|
+
const newField = this.fieldHydrator.hydrate(fieldSnapshot);
|
|
960
|
+
fields.add(newField);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
}
|
|
951
964
|
};
|
|
952
965
|
|
|
953
|
-
// src/
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
get fieldsSerializer() {
|
|
962
|
-
return this._fieldsSerializer;
|
|
963
|
-
}
|
|
964
|
-
constructor(fieldTreeNodeFactory, fieldsSerializer) {
|
|
965
|
-
this._factory = fieldTreeNodeFactory;
|
|
966
|
-
this._fieldsSerializer = fieldsSerializer;
|
|
966
|
+
// src/serializers/fields-snapshotter.ts
|
|
967
|
+
var FieldsSnapshotter = class {
|
|
968
|
+
/**
|
|
969
|
+
* Creates an instance of FieldsSnapshotter.
|
|
970
|
+
* @param {FieldSnapshotter} fieldSnapshotter - A serializer of field instances.
|
|
971
|
+
*/
|
|
972
|
+
constructor(fieldSnapshotter) {
|
|
973
|
+
this.fieldSnapshotter = fieldSnapshotter;
|
|
967
974
|
}
|
|
968
975
|
/**
|
|
969
|
-
* Creates a serializable snapshot of
|
|
970
|
-
*
|
|
976
|
+
* Creates a serializable snapshot of a `Fields` container.
|
|
977
|
+
*
|
|
978
|
+
* The snapshot includes a `__type` identifier (currently hardcoded) and an array of snapshots
|
|
979
|
+
* for each `Field` within the container.
|
|
980
|
+
* @param {Fields} fields - The `Fields` instance to serialize.
|
|
981
|
+
* @returns {FieldsSnapshot} A plain object ready for JSON serialization.
|
|
971
982
|
*/
|
|
972
|
-
snapshot(
|
|
983
|
+
snapshot(fields) {
|
|
973
984
|
const res = {
|
|
974
|
-
__type:
|
|
985
|
+
__type: fields.typeName
|
|
975
986
|
};
|
|
976
|
-
|
|
977
|
-
if (node.typeName === tree.typeName) {
|
|
978
|
-
res[key] = this.snapshot(node);
|
|
979
|
-
} else if (node.typeName === Fields.typeName) {
|
|
980
|
-
res[key] = this.fieldsSerializer.snapshot(node);
|
|
981
|
-
}
|
|
982
|
-
});
|
|
987
|
+
fields.fields.forEach((field) => res[field.name] = this.fieldSnapshotter.snapshot(field));
|
|
983
988
|
return res;
|
|
984
989
|
}
|
|
990
|
+
};
|
|
991
|
+
|
|
992
|
+
// src/serializers/field-tree-hydrator.ts
|
|
993
|
+
import { isString, throwError } from "@axi-engine/utils";
|
|
994
|
+
var FieldTreeHydrator = class {
|
|
995
|
+
_factory;
|
|
996
|
+
_fieldsHydrator;
|
|
997
|
+
get factory() {
|
|
998
|
+
return this._factory;
|
|
999
|
+
}
|
|
1000
|
+
get fieldsHydrator() {
|
|
1001
|
+
return this._fieldsHydrator;
|
|
1002
|
+
}
|
|
1003
|
+
constructor(fieldTreeNodeFactory, fieldsHydrator) {
|
|
1004
|
+
this._factory = fieldTreeNodeFactory;
|
|
1005
|
+
this._fieldsHydrator = fieldsHydrator;
|
|
1006
|
+
}
|
|
985
1007
|
/**
|
|
986
1008
|
* Restores the state of the tree from a snapshot.
|
|
987
1009
|
* It intelligently creates missing nodes based on `__type` metadata and delegates hydration to child nodes.
|
|
@@ -995,14 +1017,93 @@ var FieldTreeSerializer = class {
|
|
|
995
1017
|
if (isString(nodeData)) {
|
|
996
1018
|
continue;
|
|
997
1019
|
}
|
|
998
|
-
|
|
999
|
-
tree.addNode(key, this.hydrate(nodeData));
|
|
1000
|
-
} else if (nodeData.__type === Fields.typeName) {
|
|
1001
|
-
tree.addNode(key, this.fieldsSerializer.hydrate(nodeData));
|
|
1002
|
-
}
|
|
1020
|
+
this.addNodeFromSnapshot(tree, key, nodeData);
|
|
1003
1021
|
}
|
|
1004
1022
|
return tree;
|
|
1005
1023
|
}
|
|
1024
|
+
/**
|
|
1025
|
+
* Synchronizes an existing `FieldTree` branch with a snapshot.
|
|
1026
|
+
*
|
|
1027
|
+
* This method performs a recursive update to match the tree state with the provided snapshot:
|
|
1028
|
+
* 1. **Removes** child nodes that are present in the tree but missing in the snapshot.
|
|
1029
|
+
* 2. **Creates** new nodes that are present in the snapshot but missing in the tree.
|
|
1030
|
+
* 3. **Replaces** nodes if their type has changed (e.g., replacing a `Fields` leaf with a `FieldTree` branch).
|
|
1031
|
+
* 4. **Patches** existing matching nodes in-place (recursively).
|
|
1032
|
+
*
|
|
1033
|
+
* @param {FieldTree} tree - The target tree instance to update.
|
|
1034
|
+
* @param {FieldTreeSnapshot} snapshot - The source snapshot containing the desired state.
|
|
1035
|
+
*/
|
|
1036
|
+
patch(tree, snapshot) {
|
|
1037
|
+
const { __type, ...nodes } = snapshot;
|
|
1038
|
+
const snapshotKeys = new Set(Object.keys(nodes));
|
|
1039
|
+
const nodesToRemove = Array.from(tree.nodes.keys()).filter((key) => !snapshotKeys.has(key));
|
|
1040
|
+
tree.removeNode(nodesToRemove);
|
|
1041
|
+
for (const key in nodes) {
|
|
1042
|
+
const nodeData = nodes[key];
|
|
1043
|
+
if (isString(nodeData)) {
|
|
1044
|
+
continue;
|
|
1045
|
+
}
|
|
1046
|
+
if (!tree.has(key)) {
|
|
1047
|
+
this.addNodeFromSnapshot(tree, key, nodeData);
|
|
1048
|
+
} else {
|
|
1049
|
+
const treeNode = tree.getNode(key);
|
|
1050
|
+
if (treeNode.typeName !== nodeData.__type) {
|
|
1051
|
+
tree.removeNode(key);
|
|
1052
|
+
this.addNodeFromSnapshot(tree, key, nodeData);
|
|
1053
|
+
} else {
|
|
1054
|
+
if (nodeData.__type === FieldTree.typeName) {
|
|
1055
|
+
this.patch(treeNode, nodeData);
|
|
1056
|
+
} else if (nodeData.__type === Fields.typeName) {
|
|
1057
|
+
this.fieldsHydrator.patch(treeNode, nodeData);
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
/**
|
|
1064
|
+
* Helper method to instantiate and add a new node to the tree based on the snapshot type.
|
|
1065
|
+
*
|
|
1066
|
+
* It determines whether to create a nested `FieldTree` or a `Fields` container
|
|
1067
|
+
* by inspecting the `__type` property of the snapshot, hydrates it, and attaches it to the parent tree.
|
|
1068
|
+
*
|
|
1069
|
+
* @param {FieldTree} tree - The parent tree instance where the new node will be added.
|
|
1070
|
+
* @param {string} key - The name (key) for the new node.
|
|
1071
|
+
* @param {FieldsSnapshot | FieldTreeSnapshot} snapshot - The source snapshot data.
|
|
1072
|
+
* @throws If the snapshot contains an unsupported or unknown `__type`.
|
|
1073
|
+
*/
|
|
1074
|
+
addNodeFromSnapshot(tree, key, snapshot) {
|
|
1075
|
+
if (snapshot.__type === FieldTree.typeName) {
|
|
1076
|
+
tree.addNode(key, this.hydrate(snapshot));
|
|
1077
|
+
} else if (snapshot.__type === Fields.typeName) {
|
|
1078
|
+
tree.addNode(key, this.fieldsHydrator.hydrate(snapshot));
|
|
1079
|
+
} else {
|
|
1080
|
+
throwError(`Can't hydrate node with unsupported type: ${snapshot.__type}`);
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
};
|
|
1084
|
+
|
|
1085
|
+
// src/serializers/field-tree-snapshotter.ts
|
|
1086
|
+
var FieldTreeSnapshotter = class {
|
|
1087
|
+
constructor(fieldsSnapshotter) {
|
|
1088
|
+
this.fieldsSnapshotter = fieldsSnapshotter;
|
|
1089
|
+
}
|
|
1090
|
+
/**
|
|
1091
|
+
* Creates a serializable snapshot of the entire tree and its contained fields.
|
|
1092
|
+
* @returns A plain JavaScript object representing the complete state managed by this tree.
|
|
1093
|
+
*/
|
|
1094
|
+
snapshot(tree) {
|
|
1095
|
+
const res = {
|
|
1096
|
+
__type: tree.typeName
|
|
1097
|
+
};
|
|
1098
|
+
tree.nodes.forEach((node, key) => {
|
|
1099
|
+
if (node.typeName === tree.typeName) {
|
|
1100
|
+
res[key] = this.snapshot(node);
|
|
1101
|
+
} else if (node.typeName === Fields.typeName) {
|
|
1102
|
+
res[key] = this.fieldsSnapshotter.snapshot(node);
|
|
1103
|
+
}
|
|
1104
|
+
});
|
|
1105
|
+
return res;
|
|
1106
|
+
}
|
|
1006
1107
|
};
|
|
1007
1108
|
|
|
1008
1109
|
// src/data-store.ts
|
|
@@ -1225,6 +1326,18 @@ var DataStore = class _DataStore {
|
|
|
1225
1326
|
getInternalTree() {
|
|
1226
1327
|
return this._tree;
|
|
1227
1328
|
}
|
|
1329
|
+
/**
|
|
1330
|
+
* @internal Used for serialization
|
|
1331
|
+
*/
|
|
1332
|
+
getOrCreateInternalVariables() {
|
|
1333
|
+
return this.variables;
|
|
1334
|
+
}
|
|
1335
|
+
/**
|
|
1336
|
+
* @internal Used for serialization
|
|
1337
|
+
*/
|
|
1338
|
+
getOrCreateInternalTree() {
|
|
1339
|
+
return this.tree;
|
|
1340
|
+
}
|
|
1228
1341
|
/**
|
|
1229
1342
|
* @private
|
|
1230
1343
|
*/
|
|
@@ -1244,15 +1357,66 @@ var DataStore = class _DataStore {
|
|
|
1244
1357
|
}
|
|
1245
1358
|
};
|
|
1246
1359
|
|
|
1247
|
-
// src/
|
|
1360
|
+
// src/serializers/data-store-hydrator.ts
|
|
1248
1361
|
import { isNullOrUndefined as isNullOrUndefined4 } from "@axi-engine/utils";
|
|
1249
|
-
var
|
|
1362
|
+
var DataStoreHydrator = class {
|
|
1250
1363
|
/**
|
|
1251
1364
|
* Creates an instance of DataStoreSerializer.
|
|
1252
|
-
* @param {
|
|
1365
|
+
* @param {FieldTreeHydrator} fieldsFieldTreeHydrator - The serializer used for the underlying tree and fields.
|
|
1366
|
+
*/
|
|
1367
|
+
constructor(fieldsFieldTreeHydrator) {
|
|
1368
|
+
this.fieldsFieldTreeHydrator = fieldsFieldTreeHydrator;
|
|
1369
|
+
}
|
|
1370
|
+
/**
|
|
1371
|
+
* Reconstructs a DataStore instance from a snapshot.
|
|
1372
|
+
*
|
|
1373
|
+
* If the snapshot contains a tree, the store is initialized with it.
|
|
1374
|
+
* If not, the store is initialized with the factory (lazy mode), and the
|
|
1375
|
+
* detached variables are injected if present.
|
|
1376
|
+
*
|
|
1377
|
+
* @param {DataStoreSnapshot} snapshot - The snapshot to hydrate.
|
|
1378
|
+
* @returns {DataStore} A new, fully restored DataStore instance.
|
|
1253
1379
|
*/
|
|
1254
|
-
|
|
1255
|
-
|
|
1380
|
+
hydrate(snapshot) {
|
|
1381
|
+
const tree = isNullOrUndefined4(snapshot.tree) ? void 0 : this.fieldsFieldTreeHydrator.hydrate(snapshot.tree);
|
|
1382
|
+
const variables = isNullOrUndefined4(snapshot.variables) ? void 0 : this.fieldsFieldTreeHydrator.fieldsHydrator.hydrate(snapshot.variables);
|
|
1383
|
+
return new DataStore(tree ? tree : this.fieldsFieldTreeHydrator.factory, variables);
|
|
1384
|
+
}
|
|
1385
|
+
/**
|
|
1386
|
+
* Synchronizes a DataStore instance with a snapshot.
|
|
1387
|
+
*
|
|
1388
|
+
* This method ensures the DataStore's internal state matches the snapshot by:
|
|
1389
|
+
* 1. **Destroying** internal containers (variables/tree) if they are missing in the snapshot.
|
|
1390
|
+
* 2. **Patching** (updating/creating) contents if they exist in the snapshot.
|
|
1391
|
+
*
|
|
1392
|
+
* This allows for a granular update where only specific parts of the store (e.g., only variables)
|
|
1393
|
+
* are modified if the snapshot contains partial data, or a full reset if parts are missing.
|
|
1394
|
+
*
|
|
1395
|
+
* @param {DataStore} store - The target DataStore to update.
|
|
1396
|
+
* @param {DataStoreSnapshot} snapshot - The source snapshot.
|
|
1397
|
+
*/
|
|
1398
|
+
patch(store, snapshot) {
|
|
1399
|
+
if (!snapshot.variables) {
|
|
1400
|
+
store.getInternalVariables()?.destroy();
|
|
1401
|
+
} else {
|
|
1402
|
+
this.fieldsFieldTreeHydrator.fieldsHydrator.patch(store.getOrCreateInternalVariables(), snapshot.variables);
|
|
1403
|
+
}
|
|
1404
|
+
if (!snapshot.tree) {
|
|
1405
|
+
store.getInternalTree()?.destroy();
|
|
1406
|
+
} else {
|
|
1407
|
+
this.fieldsFieldTreeHydrator.patch(store.getOrCreateInternalTree(), snapshot.tree);
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
};
|
|
1411
|
+
|
|
1412
|
+
// src/serializers/data-store-snapshotter.ts
|
|
1413
|
+
var DataStoreSnapshotter = class {
|
|
1414
|
+
/**
|
|
1415
|
+
* Creates an instance of DataStoreSnapshotter.
|
|
1416
|
+
* @param {FieldTreeSnapshotter} treeSnapshotter - The serializer used for the underlying tree and fields.
|
|
1417
|
+
*/
|
|
1418
|
+
constructor(treeSnapshotter) {
|
|
1419
|
+
this.treeSnapshotter = treeSnapshotter;
|
|
1256
1420
|
}
|
|
1257
1421
|
/**
|
|
1258
1422
|
* Captures the current state of a DataStore into a serializable snapshot.
|
|
@@ -1269,29 +1433,14 @@ var DataStoreSerializer = class {
|
|
|
1269
1433
|
};
|
|
1270
1434
|
const variables = store.getInternalVariables();
|
|
1271
1435
|
if (variables) {
|
|
1272
|
-
snapshot.variables = this.
|
|
1436
|
+
snapshot.variables = this.treeSnapshotter.fieldsSnapshotter.snapshot(variables);
|
|
1273
1437
|
}
|
|
1274
1438
|
const tree = store.getInternalTree();
|
|
1275
1439
|
if (tree) {
|
|
1276
|
-
snapshot.tree = this.
|
|
1440
|
+
snapshot.tree = this.treeSnapshotter.snapshot(tree);
|
|
1277
1441
|
}
|
|
1278
1442
|
return snapshot;
|
|
1279
1443
|
}
|
|
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
1444
|
};
|
|
1296
1445
|
|
|
1297
1446
|
// src/setup.ts
|
|
@@ -1314,11 +1463,11 @@ function createCoreTreeNodeFactory(fieldRegistry) {
|
|
|
1314
1463
|
return new CoreTreeNodeFactory(fieldRegistry);
|
|
1315
1464
|
}
|
|
1316
1465
|
function createCoreTreeSerializer(fieldTreeNodeFactory, policySerializer) {
|
|
1317
|
-
return new
|
|
1466
|
+
return new FieldTreeHydrator(
|
|
1318
1467
|
fieldTreeNodeFactory,
|
|
1319
|
-
new
|
|
1468
|
+
new FieldsHydrator(
|
|
1320
1469
|
fieldTreeNodeFactory,
|
|
1321
|
-
new
|
|
1470
|
+
new FieldHydrator(fieldTreeNodeFactory.fieldRegistry, policySerializer ?? createCorePolicySerializer())
|
|
1322
1471
|
)
|
|
1323
1472
|
);
|
|
1324
1473
|
}
|
|
@@ -1344,13 +1493,17 @@ export {
|
|
|
1344
1493
|
CoreStringField,
|
|
1345
1494
|
CoreTreeNodeFactory,
|
|
1346
1495
|
DataStore,
|
|
1347
|
-
|
|
1496
|
+
DataStoreHydrator,
|
|
1497
|
+
DataStoreSnapshotter,
|
|
1498
|
+
FieldHydrator,
|
|
1348
1499
|
FieldRegistry,
|
|
1349
|
-
|
|
1500
|
+
FieldSnapshotter,
|
|
1350
1501
|
FieldTree,
|
|
1351
|
-
|
|
1502
|
+
FieldTreeHydrator,
|
|
1503
|
+
FieldTreeSnapshotter,
|
|
1352
1504
|
Fields,
|
|
1353
|
-
|
|
1505
|
+
FieldsHydrator,
|
|
1506
|
+
FieldsSnapshotter,
|
|
1354
1507
|
Policies,
|
|
1355
1508
|
PolicySerializer,
|
|
1356
1509
|
clampMaxPolicy,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axi-engine/fields",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.12",
|
|
4
4
|
"description": "A compact, reactive state management library based on a tree of observable fields.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
"dequal": "^2.0.3"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@axi-engine/utils": "^0.2.
|
|
39
|
+
"@axi-engine/utils": "^0.2.9"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"@axi-engine/utils": "^0.2.
|
|
42
|
+
"@axi-engine/utils": "^0.2.9"
|
|
43
43
|
}
|
|
44
44
|
}
|