@axi-engine/fields 0.3.9 → 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 CHANGED
@@ -788,11 +788,6 @@ interface FieldSnapshot {
788
788
  * plain, storable data (snapshots) and vice-versa. It uses a `FieldRegistry`
789
789
  * to resolve class constructors and a `PolicySerializer` to handle the state
790
790
  * of any attached policies.
791
- *
792
- * @todo Implement a `patch(field, snapshot)` method.
793
- * Unlike `hydrate`, which creates a new
794
- * instance, `patch` should update the state of an *existing* field instance
795
- * without breaking external references to it.
796
791
  */
797
792
  declare class FieldSerializer {
798
793
  private readonly fieldRegistry;
@@ -819,6 +814,18 @@ declare class FieldSerializer {
819
814
  * @throws If the snapshot is invalid, missing a `__type`, or if the type is not registered.
820
815
  */
821
816
  hydrate(snapshot: FieldSnapshot): Field<any>;
817
+ /**
818
+ * Updates an existing Field instance with data from a snapshot.
819
+ *
820
+ * This method modifies the field in-place, preserving the object reference.
821
+ * It updates the field's value and completely replaces its current policies
822
+ * with the ones defined in the snapshot.
823
+ *
824
+ * @param {Field<any>} field - The existing Field instance to update.
825
+ * @param {FieldSnapshot} snapshot - The snapshot containing the new state.
826
+ */
827
+ patch(field: Field<any>, snapshot: FieldSnapshot): void;
828
+ private hydratePolicies;
822
829
  }
823
830
 
824
831
  /**
@@ -899,8 +906,10 @@ interface FieldTreeSnapshot {
899
906
  * patching nodes in place to maintain object references.
900
907
  */
901
908
  declare class FieldTreeSerializer<TFields extends Fields> {
902
- private readonly fieldTreeNodeFactory;
903
- private readonly fieldsSerializer;
909
+ _factory: FieldTreeFactory<TFields>;
910
+ _fieldsSerializer: FieldsSerializer<TFields>;
911
+ get factory(): FieldTreeFactory<TFields>;
912
+ get fieldsSerializer(): FieldsSerializer<TFields>;
904
913
  constructor(fieldTreeNodeFactory: FieldTreeFactory<TFields>, fieldsSerializer: FieldsSerializer<TFields>);
905
914
  /**
906
915
  * Creates a serializable snapshot of the entire tree and its contained fields.
@@ -915,6 +924,30 @@ declare class FieldTreeSerializer<TFields extends Fields> {
915
924
  hydrate(snapshot: FieldTreeSnapshot): FieldTree<TFields>;
916
925
  }
917
926
 
927
+ /**
928
+ * A plain object representation of a DataStore's state, used for serialization.
929
+ *
930
+ * It captures both the detached 'flat' variables (used for stack frames/local scopes)
931
+ * and the hierarchical 'tree' structure (used for global/persistent data).
932
+ */
933
+ interface DataStoreSnapshot {
934
+ /**
935
+ * The type identifier for the store (e.g., 'dataStore').
936
+ * Used for type guards and polymorphic deserialization.
937
+ */
938
+ __type: string;
939
+ /**
940
+ * Snapshot of the independent, root-level variables (CoreFields).
941
+ * Present only if the store contained detached variables.
942
+ */
943
+ variables?: FieldsSnapshot;
944
+ /**
945
+ * Snapshot of the nested data hierarchy (CoreFieldTree).
946
+ * Present only if the store managed a complex tree structure.
947
+ */
948
+ tree?: FieldTreeSnapshot;
949
+ }
950
+
918
951
  interface StoreCreateFieldOptions {
919
952
  /** Allows to explicitly specify the field type, overriding the automatic type detection. */
920
953
  fieldType?: string;
@@ -925,6 +958,8 @@ interface StoreCreateFieldOptions {
925
958
  * both type-safe and dynamic methods for manipulating data.
926
959
  */
927
960
  interface Store extends DataStorage {
961
+ /**
962
+ */
928
963
  readonly typeName: string;
929
964
  /**
930
965
  * Retrieves the raw value of a Field at a specific path.
@@ -1073,14 +1108,15 @@ interface DataStoreFieldResolver {
1073
1108
  }
1074
1109
 
1075
1110
  declare class DataStore implements Store {
1076
- private readonly tree;
1077
1111
  static readonly typeName = "dataStore";
1078
1112
  readonly typeName = "dataStore";
1079
1113
  private readonly resolvers;
1080
- private readonly rootFieldsName;
1081
- private _rootFields;
1082
- private get rootFields();
1083
- constructor(tree: CoreFieldTree);
1114
+ private _variables;
1115
+ private _tree;
1116
+ private readonly _factory;
1117
+ private get variables();
1118
+ private get tree();
1119
+ constructor(treeOrFactory: CoreFieldTree | FieldTreeFactory<CoreFields>, variables?: CoreFields);
1084
1120
  registerResolver(resolver: DataStoreFieldResolver): void;
1085
1121
  clearResolvers(): void;
1086
1122
  getValue<T>(path: PathType): T;
@@ -1101,8 +1137,6 @@ declare class DataStore implements Store {
1101
1137
  getFields(path: PathType): CoreFields;
1102
1138
  getTree(path: PathType): CoreFieldTree;
1103
1139
  remove(path: PathType): void;
1104
- private isPathToRootFields;
1105
- private getDestinationFields;
1106
1140
  /**
1107
1141
  * Creates a new, independent instance of the Store with a fresh, empty data state (FieldsTree).
1108
1142
  *
@@ -1120,6 +1154,59 @@ declare class DataStore implements Store {
1120
1154
  create(path: PathType, value: unknown): void;
1121
1155
  upset(path: PathType, value: unknown): void;
1122
1156
  delete(path: PathType): void;
1157
+ /**
1158
+ * @internal Used for serialization
1159
+ */
1160
+ getInternalVariables(): CoreFields | undefined;
1161
+ /**
1162
+ * @internal Used for serialization
1163
+ */
1164
+ getInternalTree(): CoreFieldTree | undefined;
1165
+ /**
1166
+ * @private
1167
+ */
1168
+ private isPathToVariables;
1169
+ /**
1170
+ * @private
1171
+ */
1172
+ private getDestinationFields;
1173
+ }
1174
+
1175
+ /**
1176
+ * Handles the serialization and deserialization of DataStore instances.
1177
+ *
1178
+ * This class ensures that both components of a DataStore (the detached variables
1179
+ * and the hierarchical tree) are correctly persisted and restored. It delegates
1180
+ * the actual serialization of the inner structures to the `FieldTreeSerializer`.
1181
+ */
1182
+ declare class DataStoreSerializer {
1183
+ private readonly fieldTreeSerializer;
1184
+ /**
1185
+ * Creates an instance of DataStoreSerializer.
1186
+ * @param {FieldTreeSerializer} fieldTreeSerializer - The serializer used for the underlying tree and fields.
1187
+ */
1188
+ constructor(fieldTreeSerializer: FieldTreeSerializer<CoreFields>);
1189
+ /**
1190
+ * Captures the current state of a DataStore into a serializable snapshot.
1191
+ *
1192
+ * It checks for the existence of internal variables and the internal tree,
1193
+ * serializing them only if they have been initialized (lazy serialization).
1194
+ *
1195
+ * @param {DataStore} store - The store instance to serialize.
1196
+ * @returns {DataStoreSnapshot} The snapshot object.
1197
+ */
1198
+ snapshot(store: DataStore): DataStoreSnapshot;
1199
+ /**
1200
+ * Reconstructs a DataStore instance from a snapshot.
1201
+ *
1202
+ * If the snapshot contains a tree, the store is initialized with it.
1203
+ * If not, the store is initialized with the factory (lazy mode), and the
1204
+ * detached variables are injected if present.
1205
+ *
1206
+ * @param {DataStoreSnapshot} snapshot - The snapshot to hydrate.
1207
+ * @returns {DataStore} A new, fully restored DataStore instance.
1208
+ */
1209
+ hydrate(snapshot: DataStoreSnapshot): DataStore;
1123
1210
  }
1124
1211
 
1125
1212
  /**
@@ -1196,4 +1283,4 @@ declare function createCoreFieldSystem(config?: CoreFieldSystemConfig): {
1196
1283
  serializer: FieldTreeSerializer<CoreFields>;
1197
1284
  };
1198
1285
 
1199
- export { type BooleanField, ClampMaxPolicy, ClampMaxPolicySerializerHandler, ClampMinPolicy, ClampMinPolicySerializerHandler, ClampPolicy, ClampPolicySerializerHandler, CoreBooleanField, type CoreBooleanFieldOptions, CoreField, type CoreFieldSystemConfig, CoreFieldTree, CoreFields, CoreFieldsFactory, CoreNumericField, type CoreNumericFieldOptions, CoreStringField, type CoreStringFieldOptions, CoreTreeNodeFactory, DataStore, type Field, type FieldOptions, FieldRegistry, FieldSerializer, type FieldSnapshot, FieldTree, type FieldTreeFactory, FieldTreeSerializer, type FieldTreeSnapshot, Fields, type FieldsFactory, FieldsSerializer, type FieldsSnapshot, type NumericField, Policies, type Policy, PolicySerializer, type PolicySerializerHandler, type Store, type StoreCreateFieldOptions, type StringField, type TreeNode, clampMaxPolicy, clampMinPolicy, clampPolicy, createCoreFieldRegistry, createCoreFieldSystem, createCorePolicySerializer, createCoreTreeNodeFactory, createCoreTreeSerializer, createTypedMethodsMixin, isDataStore, isFieldTree, isFields };
1286
+ export { type BooleanField, ClampMaxPolicy, ClampMaxPolicySerializerHandler, ClampMinPolicy, ClampMinPolicySerializerHandler, ClampPolicy, ClampPolicySerializerHandler, CoreBooleanField, type CoreBooleanFieldOptions, CoreField, type CoreFieldSystemConfig, CoreFieldTree, CoreFields, CoreFieldsFactory, CoreNumericField, type CoreNumericFieldOptions, CoreStringField, type CoreStringFieldOptions, CoreTreeNodeFactory, DataStore, DataStoreSerializer, type DataStoreSnapshot, type Field, type FieldOptions, FieldRegistry, FieldSerializer, type FieldSnapshot, FieldTree, type FieldTreeFactory, FieldTreeSerializer, type FieldTreeSnapshot, Fields, type FieldsFactory, FieldsSerializer, type FieldsSnapshot, type NumericField, Policies, type Policy, PolicySerializer, type PolicySerializerHandler, type Store, type StoreCreateFieldOptions, type StringField, type TreeNode, clampMaxPolicy, clampMinPolicy, clampPolicy, createCoreFieldRegistry, createCoreFieldSystem, createCorePolicySerializer, createCoreTreeNodeFactory, createCoreTreeSerializer, createTypedMethodsMixin, isDataStore, isFieldTree, isFields };
package/dist/index.d.ts CHANGED
@@ -788,11 +788,6 @@ interface FieldSnapshot {
788
788
  * plain, storable data (snapshots) and vice-versa. It uses a `FieldRegistry`
789
789
  * to resolve class constructors and a `PolicySerializer` to handle the state
790
790
  * of any attached policies.
791
- *
792
- * @todo Implement a `patch(field, snapshot)` method.
793
- * Unlike `hydrate`, which creates a new
794
- * instance, `patch` should update the state of an *existing* field instance
795
- * without breaking external references to it.
796
791
  */
797
792
  declare class FieldSerializer {
798
793
  private readonly fieldRegistry;
@@ -819,6 +814,18 @@ declare class FieldSerializer {
819
814
  * @throws If the snapshot is invalid, missing a `__type`, or if the type is not registered.
820
815
  */
821
816
  hydrate(snapshot: FieldSnapshot): Field<any>;
817
+ /**
818
+ * Updates an existing Field instance with data from a snapshot.
819
+ *
820
+ * This method modifies the field in-place, preserving the object reference.
821
+ * It updates the field's value and completely replaces its current policies
822
+ * with the ones defined in the snapshot.
823
+ *
824
+ * @param {Field<any>} field - The existing Field instance to update.
825
+ * @param {FieldSnapshot} snapshot - The snapshot containing the new state.
826
+ */
827
+ patch(field: Field<any>, snapshot: FieldSnapshot): void;
828
+ private hydratePolicies;
822
829
  }
823
830
 
824
831
  /**
@@ -899,8 +906,10 @@ interface FieldTreeSnapshot {
899
906
  * patching nodes in place to maintain object references.
900
907
  */
901
908
  declare class FieldTreeSerializer<TFields extends Fields> {
902
- private readonly fieldTreeNodeFactory;
903
- private readonly fieldsSerializer;
909
+ _factory: FieldTreeFactory<TFields>;
910
+ _fieldsSerializer: FieldsSerializer<TFields>;
911
+ get factory(): FieldTreeFactory<TFields>;
912
+ get fieldsSerializer(): FieldsSerializer<TFields>;
904
913
  constructor(fieldTreeNodeFactory: FieldTreeFactory<TFields>, fieldsSerializer: FieldsSerializer<TFields>);
905
914
  /**
906
915
  * Creates a serializable snapshot of the entire tree and its contained fields.
@@ -915,6 +924,30 @@ declare class FieldTreeSerializer<TFields extends Fields> {
915
924
  hydrate(snapshot: FieldTreeSnapshot): FieldTree<TFields>;
916
925
  }
917
926
 
927
+ /**
928
+ * A plain object representation of a DataStore's state, used for serialization.
929
+ *
930
+ * It captures both the detached 'flat' variables (used for stack frames/local scopes)
931
+ * and the hierarchical 'tree' structure (used for global/persistent data).
932
+ */
933
+ interface DataStoreSnapshot {
934
+ /**
935
+ * The type identifier for the store (e.g., 'dataStore').
936
+ * Used for type guards and polymorphic deserialization.
937
+ */
938
+ __type: string;
939
+ /**
940
+ * Snapshot of the independent, root-level variables (CoreFields).
941
+ * Present only if the store contained detached variables.
942
+ */
943
+ variables?: FieldsSnapshot;
944
+ /**
945
+ * Snapshot of the nested data hierarchy (CoreFieldTree).
946
+ * Present only if the store managed a complex tree structure.
947
+ */
948
+ tree?: FieldTreeSnapshot;
949
+ }
950
+
918
951
  interface StoreCreateFieldOptions {
919
952
  /** Allows to explicitly specify the field type, overriding the automatic type detection. */
920
953
  fieldType?: string;
@@ -925,6 +958,8 @@ interface StoreCreateFieldOptions {
925
958
  * both type-safe and dynamic methods for manipulating data.
926
959
  */
927
960
  interface Store extends DataStorage {
961
+ /**
962
+ */
928
963
  readonly typeName: string;
929
964
  /**
930
965
  * Retrieves the raw value of a Field at a specific path.
@@ -1073,14 +1108,15 @@ interface DataStoreFieldResolver {
1073
1108
  }
1074
1109
 
1075
1110
  declare class DataStore implements Store {
1076
- private readonly tree;
1077
1111
  static readonly typeName = "dataStore";
1078
1112
  readonly typeName = "dataStore";
1079
1113
  private readonly resolvers;
1080
- private readonly rootFieldsName;
1081
- private _rootFields;
1082
- private get rootFields();
1083
- constructor(tree: CoreFieldTree);
1114
+ private _variables;
1115
+ private _tree;
1116
+ private readonly _factory;
1117
+ private get variables();
1118
+ private get tree();
1119
+ constructor(treeOrFactory: CoreFieldTree | FieldTreeFactory<CoreFields>, variables?: CoreFields);
1084
1120
  registerResolver(resolver: DataStoreFieldResolver): void;
1085
1121
  clearResolvers(): void;
1086
1122
  getValue<T>(path: PathType): T;
@@ -1101,8 +1137,6 @@ declare class DataStore implements Store {
1101
1137
  getFields(path: PathType): CoreFields;
1102
1138
  getTree(path: PathType): CoreFieldTree;
1103
1139
  remove(path: PathType): void;
1104
- private isPathToRootFields;
1105
- private getDestinationFields;
1106
1140
  /**
1107
1141
  * Creates a new, independent instance of the Store with a fresh, empty data state (FieldsTree).
1108
1142
  *
@@ -1120,6 +1154,59 @@ declare class DataStore implements Store {
1120
1154
  create(path: PathType, value: unknown): void;
1121
1155
  upset(path: PathType, value: unknown): void;
1122
1156
  delete(path: PathType): void;
1157
+ /**
1158
+ * @internal Used for serialization
1159
+ */
1160
+ getInternalVariables(): CoreFields | undefined;
1161
+ /**
1162
+ * @internal Used for serialization
1163
+ */
1164
+ getInternalTree(): CoreFieldTree | undefined;
1165
+ /**
1166
+ * @private
1167
+ */
1168
+ private isPathToVariables;
1169
+ /**
1170
+ * @private
1171
+ */
1172
+ private getDestinationFields;
1173
+ }
1174
+
1175
+ /**
1176
+ * Handles the serialization and deserialization of DataStore instances.
1177
+ *
1178
+ * This class ensures that both components of a DataStore (the detached variables
1179
+ * and the hierarchical tree) are correctly persisted and restored. It delegates
1180
+ * the actual serialization of the inner structures to the `FieldTreeSerializer`.
1181
+ */
1182
+ declare class DataStoreSerializer {
1183
+ private readonly fieldTreeSerializer;
1184
+ /**
1185
+ * Creates an instance of DataStoreSerializer.
1186
+ * @param {FieldTreeSerializer} fieldTreeSerializer - The serializer used for the underlying tree and fields.
1187
+ */
1188
+ constructor(fieldTreeSerializer: FieldTreeSerializer<CoreFields>);
1189
+ /**
1190
+ * Captures the current state of a DataStore into a serializable snapshot.
1191
+ *
1192
+ * It checks for the existence of internal variables and the internal tree,
1193
+ * serializing them only if they have been initialized (lazy serialization).
1194
+ *
1195
+ * @param {DataStore} store - The store instance to serialize.
1196
+ * @returns {DataStoreSnapshot} The snapshot object.
1197
+ */
1198
+ snapshot(store: DataStore): DataStoreSnapshot;
1199
+ /**
1200
+ * Reconstructs a DataStore instance from a snapshot.
1201
+ *
1202
+ * If the snapshot contains a tree, the store is initialized with it.
1203
+ * If not, the store is initialized with the factory (lazy mode), and the
1204
+ * detached variables are injected if present.
1205
+ *
1206
+ * @param {DataStoreSnapshot} snapshot - The snapshot to hydrate.
1207
+ * @returns {DataStore} A new, fully restored DataStore instance.
1208
+ */
1209
+ hydrate(snapshot: DataStoreSnapshot): DataStore;
1123
1210
  }
1124
1211
 
1125
1212
  /**
@@ -1196,4 +1283,4 @@ declare function createCoreFieldSystem(config?: CoreFieldSystemConfig): {
1196
1283
  serializer: FieldTreeSerializer<CoreFields>;
1197
1284
  };
1198
1285
 
1199
- export { type BooleanField, ClampMaxPolicy, ClampMaxPolicySerializerHandler, ClampMinPolicy, ClampMinPolicySerializerHandler, ClampPolicy, ClampPolicySerializerHandler, CoreBooleanField, type CoreBooleanFieldOptions, CoreField, type CoreFieldSystemConfig, CoreFieldTree, CoreFields, CoreFieldsFactory, CoreNumericField, type CoreNumericFieldOptions, CoreStringField, type CoreStringFieldOptions, CoreTreeNodeFactory, DataStore, type Field, type FieldOptions, FieldRegistry, FieldSerializer, type FieldSnapshot, FieldTree, type FieldTreeFactory, FieldTreeSerializer, type FieldTreeSnapshot, Fields, type FieldsFactory, FieldsSerializer, type FieldsSnapshot, type NumericField, Policies, type Policy, PolicySerializer, type PolicySerializerHandler, type Store, type StoreCreateFieldOptions, type StringField, type TreeNode, clampMaxPolicy, clampMinPolicy, clampPolicy, createCoreFieldRegistry, createCoreFieldSystem, createCorePolicySerializer, createCoreTreeNodeFactory, createCoreTreeSerializer, createTypedMethodsMixin, isDataStore, isFieldTree, isFields };
1286
+ export { type BooleanField, ClampMaxPolicy, ClampMaxPolicySerializerHandler, ClampMinPolicy, ClampMinPolicySerializerHandler, ClampPolicy, ClampPolicySerializerHandler, CoreBooleanField, type CoreBooleanFieldOptions, CoreField, type CoreFieldSystemConfig, CoreFieldTree, CoreFields, CoreFieldsFactory, CoreNumericField, type CoreNumericFieldOptions, CoreStringField, type CoreStringFieldOptions, CoreTreeNodeFactory, DataStore, DataStoreSerializer, type DataStoreSnapshot, type Field, type FieldOptions, FieldRegistry, FieldSerializer, type FieldSnapshot, FieldTree, type FieldTreeFactory, FieldTreeSerializer, type FieldTreeSnapshot, Fields, type FieldsFactory, FieldsSerializer, type FieldsSnapshot, type NumericField, Policies, type Policy, PolicySerializer, type PolicySerializerHandler, type Store, type StoreCreateFieldOptions, type StringField, type TreeNode, clampMaxPolicy, clampMinPolicy, clampPolicy, createCoreFieldRegistry, createCoreFieldSystem, createCorePolicySerializer, createCoreTreeNodeFactory, createCoreTreeSerializer, createTypedMethodsMixin, isDataStore, isFieldTree, isFields };
package/dist/index.js CHANGED
@@ -35,6 +35,7 @@ __export(index_exports, {
35
35
  CoreStringField: () => CoreStringField,
36
36
  CoreTreeNodeFactory: () => CoreTreeNodeFactory,
37
37
  DataStore: () => DataStore,
38
+ DataStoreSerializer: () => DataStoreSerializer,
38
39
  FieldRegistry: () => FieldRegistry,
39
40
  FieldSerializer: () => FieldSerializer,
40
41
  FieldTree: () => FieldTree,
@@ -934,13 +935,35 @@ var FieldSerializer = class {
934
935
  const fieldType = snapshot.__type;
935
936
  (0, import_utils7.throwIfEmpty)(fieldType, 'Invalid field snapshot: missing "__type" identifier.');
936
937
  const Ctor = this.fieldRegistry.getOrThrow(fieldType);
937
- let policies;
938
- if (!(0, import_utils7.isNullOrUndefined)(snapshot.policies)) {
939
- policies = [];
940
- snapshot.policies.forEach((p) => policies.push(this.policySerializer.hydrate(p)));
941
- }
938
+ let policies = this.hydratePolicies(snapshot);
942
939
  return new Ctor(snapshot.name, snapshot.value, { policies });
943
940
  }
941
+ /**
942
+ * Updates an existing Field instance with data from a snapshot.
943
+ *
944
+ * This method modifies the field in-place, preserving the object reference.
945
+ * It updates the field's value and completely replaces its current policies
946
+ * with the ones defined in the snapshot.
947
+ *
948
+ * @param {Field<any>} field - The existing Field instance to update.
949
+ * @param {FieldSnapshot} snapshot - The snapshot containing the new state.
950
+ */
951
+ patch(field, snapshot) {
952
+ let policies = this.hydratePolicies(snapshot);
953
+ field.policies.clear();
954
+ if (policies) {
955
+ policies.forEach((p) => field.policies.add(p));
956
+ }
957
+ field.value = snapshot.value;
958
+ }
959
+ hydratePolicies(snapshot) {
960
+ if ((0, import_utils7.isNullOrUndefined)(snapshot.policies)) {
961
+ return void 0;
962
+ }
963
+ const policies = [];
964
+ snapshot.policies.forEach((p) => policies.push(this.policySerializer.hydrate(p)));
965
+ return policies;
966
+ }
944
967
  };
945
968
 
946
969
  // src/serializer/fields-serializer.ts
@@ -991,9 +1014,17 @@ var FieldsSerializer = class {
991
1014
  // src/serializer/field-tree-serializer.ts
992
1015
  var import_utils8 = require("@axi-engine/utils");
993
1016
  var FieldTreeSerializer = class {
1017
+ _factory;
1018
+ _fieldsSerializer;
1019
+ get factory() {
1020
+ return this._factory;
1021
+ }
1022
+ get fieldsSerializer() {
1023
+ return this._fieldsSerializer;
1024
+ }
994
1025
  constructor(fieldTreeNodeFactory, fieldsSerializer) {
995
- this.fieldTreeNodeFactory = fieldTreeNodeFactory;
996
- this.fieldsSerializer = fieldsSerializer;
1026
+ this._factory = fieldTreeNodeFactory;
1027
+ this._fieldsSerializer = fieldsSerializer;
997
1028
  }
998
1029
  /**
999
1030
  * Creates a serializable snapshot of the entire tree and its contained fields.
@@ -1019,7 +1050,7 @@ var FieldTreeSerializer = class {
1019
1050
  */
1020
1051
  hydrate(snapshot) {
1021
1052
  const { __type, ...nodes } = snapshot;
1022
- const tree = this.fieldTreeNodeFactory.tree();
1053
+ const tree = this._factory.tree();
1023
1054
  for (const key in nodes) {
1024
1055
  const nodeData = nodes[key];
1025
1056
  if ((0, import_utils8.isString)(nodeData)) {
@@ -1036,7 +1067,7 @@ var FieldTreeSerializer = class {
1036
1067
  };
1037
1068
 
1038
1069
  // src/data-store.ts
1039
- var import_utils10 = require("@axi-engine/utils");
1070
+ var import_utils11 = require("@axi-engine/utils");
1040
1071
 
1041
1072
  // src/data-store-field-resolver.ts
1042
1073
  var import_utils9 = require("@axi-engine/utils");
@@ -1059,24 +1090,51 @@ var StringFieldResolver = class {
1059
1090
  }
1060
1091
  };
1061
1092
 
1093
+ // src/guards.ts
1094
+ var import_utils10 = require("@axi-engine/utils");
1095
+ function isFields(value) {
1096
+ return !(0, import_utils10.isNullOrUndefined)(value) && value.typeName === Fields.typeName;
1097
+ }
1098
+ function isFieldTree(value) {
1099
+ return !(0, import_utils10.isNullOrUndefined)(value) && value.typeName === FieldTree.typeName;
1100
+ }
1101
+ function isDataStore(value) {
1102
+ return !(0, import_utils10.isNullOrUndefined)(value) && value.typeName === DataStore.typeName;
1103
+ }
1104
+
1062
1105
  // src/data-store.ts
1063
1106
  var DataStore = class _DataStore {
1064
- constructor(tree) {
1065
- this.tree = tree;
1066
- this.registerResolver(new NumericFieldResolver());
1067
- this.registerResolver(new BooleanFieldResolver());
1068
- this.registerResolver(new StringFieldResolver());
1069
- }
1070
1107
  static typeName = "dataStore";
1071
1108
  typeName = _DataStore.typeName;
1072
1109
  resolvers = [];
1073
- rootFieldsName = "__root_fields";
1074
- _rootFields;
1075
- get rootFields() {
1076
- if (!this._rootFields) {
1077
- this._rootFields = this.tree.getOrCreateFields(this.rootFieldsName);
1110
+ _variables;
1111
+ _tree;
1112
+ _factory;
1113
+ get variables() {
1114
+ if (!this._variables) {
1115
+ this._variables = this._factory.fields();
1116
+ }
1117
+ return this._variables;
1118
+ }
1119
+ get tree() {
1120
+ if (!this._tree) {
1121
+ this._tree = this._factory.tree();
1122
+ }
1123
+ return this._tree;
1124
+ }
1125
+ constructor(treeOrFactory, variables) {
1126
+ if (!isFieldTree(treeOrFactory)) {
1127
+ this._factory = treeOrFactory;
1128
+ } else {
1129
+ this._tree = treeOrFactory;
1130
+ this._factory = this._tree.factory;
1078
1131
  }
1079
- return this._rootFields;
1132
+ if (variables) {
1133
+ this._variables = variables;
1134
+ }
1135
+ this.registerResolver(new NumericFieldResolver());
1136
+ this.registerResolver(new BooleanFieldResolver());
1137
+ this.registerResolver(new StringFieldResolver());
1080
1138
  }
1081
1139
  registerResolver(resolver) {
1082
1140
  this.resolvers.unshift(resolver);
@@ -1145,10 +1203,10 @@ var DataStore = class _DataStore {
1145
1203
  return this.getField(path);
1146
1204
  }
1147
1205
  getField(path) {
1148
- const pathArr = (0, import_utils10.ensurePathArray)(path);
1149
- (0, import_utils10.throwIfEmpty)(pathArr, `Wrong path or path is empty: ${(0, import_utils10.ensurePathString)(path)}, should contain at least one path segment`);
1150
- if (this.isPathToRootFields(pathArr)) {
1151
- return this.rootFields.get(pathArr[0]);
1206
+ const pathArr = (0, import_utils11.ensurePathArray)(path);
1207
+ (0, import_utils11.throwIfEmpty)(pathArr, `Wrong path or path is empty: ${(0, import_utils11.ensurePathString)(path)}, should contain at least one path segment`);
1208
+ if (this.isPathToVariables(pathArr)) {
1209
+ return this.variables.get(pathArr[0]);
1152
1210
  }
1153
1211
  const fieldName = pathArr.pop();
1154
1212
  const fields = this.tree.getFields(pathArr);
@@ -1167,10 +1225,10 @@ var DataStore = class _DataStore {
1167
1225
  return this.tree.getFieldTree(path);
1168
1226
  }
1169
1227
  remove(path) {
1170
- const pathArr = (0, import_utils10.ensurePathArray)(path);
1171
- (0, import_utils10.throwIfEmpty)(pathArr, `Wrong path or path is empty: ${(0, import_utils10.ensurePathString)(path)}, should contain at least one path segment`);
1172
- if (this.isPathToRootFields(pathArr)) {
1173
- this.rootFields.remove(pathArr);
1228
+ const pathArr = (0, import_utils11.ensurePathArray)(path);
1229
+ (0, import_utils11.throwIfEmpty)(pathArr, `Wrong path or path is empty: ${(0, import_utils11.ensurePathString)(path)}, should contain at least one path segment`);
1230
+ if (this.isPathToVariables(pathArr)) {
1231
+ this.variables.remove(pathArr);
1174
1232
  return;
1175
1233
  }
1176
1234
  const node = this.tree.findParentNode(pathArr);
@@ -1181,17 +1239,6 @@ var DataStore = class _DataStore {
1181
1239
  node.removeNode(leafName);
1182
1240
  }
1183
1241
  }
1184
- isPathToRootFields(path) {
1185
- return (0, import_utils10.ensurePathArray)(path).length === 1;
1186
- }
1187
- getDestinationFields(path) {
1188
- const pathArr = (0, import_utils10.ensurePathArray)(path);
1189
- if (this.isPathToRootFields(pathArr)) {
1190
- return { fields: this.rootFields, leafName: pathArr[0] };
1191
- }
1192
- const leafName = pathArr.pop();
1193
- return { fields: this.tree.getOrCreateFields(path), leafName };
1194
- }
1195
1242
  /**
1196
1243
  * Creates a new, independent instance of the Store with a fresh, empty data state (FieldsTree).
1197
1244
  *
@@ -1202,13 +1249,13 @@ var DataStore = class _DataStore {
1202
1249
  * @returns {DataStore} A new, isolated DataStore instance.
1203
1250
  */
1204
1251
  createIsolated() {
1205
- return new _DataStore(this.tree.createDetachedTree());
1252
+ return new _DataStore(this._factory);
1206
1253
  }
1207
1254
  /** code below -> implementation of the DataStore from utils */
1208
1255
  has(path) {
1209
- const pathArr = (0, import_utils10.ensurePathArray)(path);
1210
- if (this.isPathToRootFields(pathArr)) {
1211
- return this.rootFields.has(pathArr[0]);
1256
+ const pathArr = (0, import_utils11.ensurePathArray)(path);
1257
+ if (this.isPathToVariables(pathArr)) {
1258
+ return this.variables.has(pathArr[0]);
1212
1259
  }
1213
1260
  return this.tree.hasPath(pathArr);
1214
1261
  }
@@ -1227,19 +1274,86 @@ var DataStore = class _DataStore {
1227
1274
  delete(path) {
1228
1275
  this.remove(path);
1229
1276
  }
1277
+ /**
1278
+ * @internal Used for serialization
1279
+ */
1280
+ getInternalVariables() {
1281
+ return this._variables;
1282
+ }
1283
+ /**
1284
+ * @internal Used for serialization
1285
+ */
1286
+ getInternalTree() {
1287
+ return this._tree;
1288
+ }
1289
+ /**
1290
+ * @private
1291
+ */
1292
+ isPathToVariables(path) {
1293
+ return (0, import_utils11.ensurePathArray)(path).length === 1;
1294
+ }
1295
+ /**
1296
+ * @private
1297
+ */
1298
+ getDestinationFields(path) {
1299
+ const pathArr = (0, import_utils11.ensurePathArray)(path);
1300
+ if (this.isPathToVariables(pathArr)) {
1301
+ return { fields: this.variables, leafName: pathArr[0] };
1302
+ }
1303
+ const leafName = pathArr.pop();
1304
+ return { fields: this.tree.getOrCreateFields(path), leafName };
1305
+ }
1230
1306
  };
1231
1307
 
1232
- // src/guards.ts
1233
- var import_utils11 = require("@axi-engine/utils");
1234
- function isFields(value) {
1235
- return !(0, import_utils11.isNullOrUndefined)(value) && value.typeName === Fields.typeName;
1236
- }
1237
- function isFieldTree(value) {
1238
- return !(0, import_utils11.isNullOrUndefined)(value) && value.typeName === FieldTree.typeName;
1239
- }
1240
- function isDataStore(value) {
1241
- return !(0, import_utils11.isNullOrUndefined)(value) && value.typeName === DataStore.typeName;
1242
- }
1308
+ // src/serializer/data-store-serializer.ts
1309
+ var import_utils12 = require("@axi-engine/utils");
1310
+ var DataStoreSerializer = class {
1311
+ /**
1312
+ * Creates an instance of DataStoreSerializer.
1313
+ * @param {FieldTreeSerializer} fieldTreeSerializer - The serializer used for the underlying tree and fields.
1314
+ */
1315
+ constructor(fieldTreeSerializer) {
1316
+ this.fieldTreeSerializer = fieldTreeSerializer;
1317
+ }
1318
+ /**
1319
+ * Captures the current state of a DataStore into a serializable snapshot.
1320
+ *
1321
+ * It checks for the existence of internal variables and the internal tree,
1322
+ * serializing them only if they have been initialized (lazy serialization).
1323
+ *
1324
+ * @param {DataStore} store - The store instance to serialize.
1325
+ * @returns {DataStoreSnapshot} The snapshot object.
1326
+ */
1327
+ snapshot(store) {
1328
+ let snapshot = {
1329
+ __type: store.typeName
1330
+ };
1331
+ const variables = store.getInternalVariables();
1332
+ if (variables) {
1333
+ snapshot.variables = this.fieldTreeSerializer.fieldsSerializer.snapshot(variables);
1334
+ }
1335
+ const tree = store.getInternalTree();
1336
+ if (tree) {
1337
+ snapshot.tree = this.fieldTreeSerializer.snapshot(tree);
1338
+ }
1339
+ return snapshot;
1340
+ }
1341
+ /**
1342
+ * Reconstructs a DataStore instance from a snapshot.
1343
+ *
1344
+ * If the snapshot contains a tree, the store is initialized with it.
1345
+ * If not, the store is initialized with the factory (lazy mode), and the
1346
+ * detached variables are injected if present.
1347
+ *
1348
+ * @param {DataStoreSnapshot} snapshot - The snapshot to hydrate.
1349
+ * @returns {DataStore} A new, fully restored DataStore instance.
1350
+ */
1351
+ hydrate(snapshot) {
1352
+ const tree = (0, import_utils12.isNullOrUndefined)(snapshot.tree) ? void 0 : this.fieldTreeSerializer.hydrate(snapshot.tree);
1353
+ const variables = (0, import_utils12.isNullOrUndefined)(snapshot.variables) ? void 0 : this.fieldTreeSerializer.fieldsSerializer.hydrate(snapshot.variables);
1354
+ return new DataStore(tree ? tree : this.fieldTreeSerializer.factory, variables);
1355
+ }
1356
+ };
1243
1357
 
1244
1358
  // src/setup.ts
1245
1359
  function createCoreFieldRegistry() {
@@ -1292,6 +1406,7 @@ function createCoreFieldSystem(config) {
1292
1406
  CoreStringField,
1293
1407
  CoreTreeNodeFactory,
1294
1408
  DataStore,
1409
+ DataStoreSerializer,
1295
1410
  FieldRegistry,
1296
1411
  FieldSerializer,
1297
1412
  FieldTree,
package/dist/index.mjs CHANGED
@@ -874,13 +874,35 @@ var FieldSerializer = class {
874
874
  const fieldType = snapshot.__type;
875
875
  throwIfEmpty3(fieldType, 'Invalid field snapshot: missing "__type" identifier.');
876
876
  const Ctor = this.fieldRegistry.getOrThrow(fieldType);
877
- let policies;
878
- if (!isNullOrUndefined2(snapshot.policies)) {
879
- policies = [];
880
- snapshot.policies.forEach((p) => policies.push(this.policySerializer.hydrate(p)));
881
- }
877
+ let policies = this.hydratePolicies(snapshot);
882
878
  return new Ctor(snapshot.name, snapshot.value, { policies });
883
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
+ }
884
906
  };
885
907
 
886
908
  // src/serializer/fields-serializer.ts
@@ -931,9 +953,17 @@ var FieldsSerializer = class {
931
953
  // src/serializer/field-tree-serializer.ts
932
954
  import { isString } from "@axi-engine/utils";
933
955
  var FieldTreeSerializer = class {
956
+ _factory;
957
+ _fieldsSerializer;
958
+ get factory() {
959
+ return this._factory;
960
+ }
961
+ get fieldsSerializer() {
962
+ return this._fieldsSerializer;
963
+ }
934
964
  constructor(fieldTreeNodeFactory, fieldsSerializer) {
935
- this.fieldTreeNodeFactory = fieldTreeNodeFactory;
936
- this.fieldsSerializer = fieldsSerializer;
965
+ this._factory = fieldTreeNodeFactory;
966
+ this._fieldsSerializer = fieldsSerializer;
937
967
  }
938
968
  /**
939
969
  * Creates a serializable snapshot of the entire tree and its contained fields.
@@ -959,7 +989,7 @@ var FieldTreeSerializer = class {
959
989
  */
960
990
  hydrate(snapshot) {
961
991
  const { __type, ...nodes } = snapshot;
962
- const tree = this.fieldTreeNodeFactory.tree();
992
+ const tree = this._factory.tree();
963
993
  for (const key in nodes) {
964
994
  const nodeData = nodes[key];
965
995
  if (isString(nodeData)) {
@@ -999,24 +1029,51 @@ var StringFieldResolver = class {
999
1029
  }
1000
1030
  };
1001
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
+
1002
1044
  // src/data-store.ts
1003
1045
  var DataStore = class _DataStore {
1004
- constructor(tree) {
1005
- this.tree = tree;
1006
- this.registerResolver(new NumericFieldResolver());
1007
- this.registerResolver(new BooleanFieldResolver());
1008
- this.registerResolver(new StringFieldResolver());
1009
- }
1010
1046
  static typeName = "dataStore";
1011
1047
  typeName = _DataStore.typeName;
1012
1048
  resolvers = [];
1013
- rootFieldsName = "__root_fields";
1014
- _rootFields;
1015
- get rootFields() {
1016
- if (!this._rootFields) {
1017
- this._rootFields = this.tree.getOrCreateFields(this.rootFieldsName);
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();
1018
1061
  }
1019
- return this._rootFields;
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
+ }
1074
+ this.registerResolver(new NumericFieldResolver());
1075
+ this.registerResolver(new BooleanFieldResolver());
1076
+ this.registerResolver(new StringFieldResolver());
1020
1077
  }
1021
1078
  registerResolver(resolver) {
1022
1079
  this.resolvers.unshift(resolver);
@@ -1087,8 +1144,8 @@ var DataStore = class _DataStore {
1087
1144
  getField(path) {
1088
1145
  const pathArr = ensurePathArray2(path);
1089
1146
  throwIfEmpty4(pathArr, `Wrong path or path is empty: ${ensurePathString2(path)}, should contain at least one path segment`);
1090
- if (this.isPathToRootFields(pathArr)) {
1091
- return this.rootFields.get(pathArr[0]);
1147
+ if (this.isPathToVariables(pathArr)) {
1148
+ return this.variables.get(pathArr[0]);
1092
1149
  }
1093
1150
  const fieldName = pathArr.pop();
1094
1151
  const fields = this.tree.getFields(pathArr);
@@ -1109,8 +1166,8 @@ var DataStore = class _DataStore {
1109
1166
  remove(path) {
1110
1167
  const pathArr = ensurePathArray2(path);
1111
1168
  throwIfEmpty4(pathArr, `Wrong path or path is empty: ${ensurePathString2(path)}, should contain at least one path segment`);
1112
- if (this.isPathToRootFields(pathArr)) {
1113
- this.rootFields.remove(pathArr);
1169
+ if (this.isPathToVariables(pathArr)) {
1170
+ this.variables.remove(pathArr);
1114
1171
  return;
1115
1172
  }
1116
1173
  const node = this.tree.findParentNode(pathArr);
@@ -1121,17 +1178,6 @@ var DataStore = class _DataStore {
1121
1178
  node.removeNode(leafName);
1122
1179
  }
1123
1180
  }
1124
- isPathToRootFields(path) {
1125
- return ensurePathArray2(path).length === 1;
1126
- }
1127
- getDestinationFields(path) {
1128
- const pathArr = ensurePathArray2(path);
1129
- if (this.isPathToRootFields(pathArr)) {
1130
- return { fields: this.rootFields, leafName: pathArr[0] };
1131
- }
1132
- const leafName = pathArr.pop();
1133
- return { fields: this.tree.getOrCreateFields(path), leafName };
1134
- }
1135
1181
  /**
1136
1182
  * Creates a new, independent instance of the Store with a fresh, empty data state (FieldsTree).
1137
1183
  *
@@ -1142,13 +1188,13 @@ var DataStore = class _DataStore {
1142
1188
  * @returns {DataStore} A new, isolated DataStore instance.
1143
1189
  */
1144
1190
  createIsolated() {
1145
- return new _DataStore(this.tree.createDetachedTree());
1191
+ return new _DataStore(this._factory);
1146
1192
  }
1147
1193
  /** code below -> implementation of the DataStore from utils */
1148
1194
  has(path) {
1149
1195
  const pathArr = ensurePathArray2(path);
1150
- if (this.isPathToRootFields(pathArr)) {
1151
- return this.rootFields.has(pathArr[0]);
1196
+ if (this.isPathToVariables(pathArr)) {
1197
+ return this.variables.has(pathArr[0]);
1152
1198
  }
1153
1199
  return this.tree.hasPath(pathArr);
1154
1200
  }
@@ -1167,19 +1213,86 @@ var DataStore = class _DataStore {
1167
1213
  delete(path) {
1168
1214
  this.remove(path);
1169
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
+ }
1170
1245
  };
1171
1246
 
1172
- // src/guards.ts
1173
- import { isNullOrUndefined as isNullOrUndefined3 } from "@axi-engine/utils";
1174
- function isFields(value) {
1175
- return !isNullOrUndefined3(value) && value.typeName === Fields.typeName;
1176
- }
1177
- function isFieldTree(value) {
1178
- return !isNullOrUndefined3(value) && value.typeName === FieldTree.typeName;
1179
- }
1180
- function isDataStore(value) {
1181
- return !isNullOrUndefined3(value) && value.typeName === DataStore.typeName;
1182
- }
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
+ };
1183
1296
 
1184
1297
  // src/setup.ts
1185
1298
  function createCoreFieldRegistry() {
@@ -1231,6 +1344,7 @@ export {
1231
1344
  CoreStringField,
1232
1345
  CoreTreeNodeFactory,
1233
1346
  DataStore,
1347
+ DataStoreSerializer,
1234
1348
  FieldRegistry,
1235
1349
  FieldSerializer,
1236
1350
  FieldTree,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axi-engine/fields",
3
- "version": "0.3.9",
3
+ "version": "0.3.10",
4
4
  "description": "A compact, reactive state management library based on a tree of observable fields.",
5
5
  "license": "MIT",
6
6
  "repository": {