@axi-engine/fields 0.3.8 → 0.3.9

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
@@ -75,35 +75,137 @@ declare class Policies<T> {
75
75
  apply(val: T): T;
76
76
  }
77
77
 
78
+ /**
79
+ * Configuration options for creating a new Field instance.
80
+ * @template T The type of the value stored in the field.
81
+ */
78
82
  interface FieldOptions<T> {
83
+ /**
84
+ * An optional array of policies to apply to this field.
85
+ * Policies can enforce validation rules, transform values, or handle constraints.
86
+ */
79
87
  policies?: Policy<T>[];
80
88
  }
89
+ /**
90
+ * Represents a reactive data holder for a specific value type.
91
+ *
92
+ * A Field wraps a raw value, providing features like change observation (`onChange`),
93
+ * policy enforcement (validation/transformation), and metadata management (`name`, `typeName`).
94
+ *
95
+ * @template T The type of the value stored in the field.
96
+ */
81
97
  interface Field<T> {
98
+ /**
99
+ * A unique string identifier for the field type (e.g., 'numeric', 'boolean').
100
+ * Used for serialization and type guards.
101
+ */
82
102
  readonly typeName: string;
103
+ /**
104
+ * The name or key of this field within its parent container.
105
+ */
83
106
  readonly name: string;
107
+ /**
108
+ * The current value of the field.
109
+ * Assigning a new value triggers policies and emits the `onChange` event
110
+ * if the value is different from the current one.
111
+ */
84
112
  value: T;
113
+ /**
114
+ * The collection of policies applied to this field.
115
+ */
85
116
  policies: Policies<T>;
117
+ /**
118
+ * Updates the field's value without triggering the `onChange` event.
119
+ * Useful for internal synchronization or restoring state where side effects are undesirable.
120
+ * @param val The new value to set.
121
+ */
86
122
  setValueSilently(val: T): void;
123
+ /**
124
+ * Performs an atomic-like update using a callback function.
125
+ * The callback receives the current value and should return the new value.
126
+ * @param updateFn A function that transforms the current value into a new one.
127
+ */
87
128
  batchUpdate(updateFn: (currentValue: T) => T): void;
129
+ /**
130
+ * An observable stream that emits an event whenever the value changes.
131
+ * The payload contains the new value and the old value.
132
+ */
88
133
  onChange: Subscribable<[newValue: T, oldValue: T]>;
134
+ /**
135
+ * Cleans up the field, removing all listeners and releasing resources.
136
+ * Should be called when the field is no longer needed.
137
+ */
89
138
  destroy(): void;
90
139
  }
140
+ /**
141
+ * A specialized Field for handling numeric values.
142
+ * Provides capabilities for range clamping (min/max) and arithmetic operations.
143
+ */
91
144
  interface NumericField extends Field<number> {
145
+ /** The minimum allowed value for this field, or undefined if no lower bound exists. */
92
146
  readonly min: number | undefined;
147
+ /** The maximum allowed value for this field, or undefined if no upper bound exists. */
93
148
  readonly max: number | undefined;
149
+ /**
150
+ * Checks if the current value is equal to or less than the minimum limit.
151
+ */
94
152
  isMin(): boolean;
153
+ /**
154
+ * Checks if the current value is equal to or greater than the maximum limit.
155
+ */
95
156
  isMax(): boolean;
157
+ /**
158
+ * Increments the current value by the specified amount.
159
+ * @param val The amount to add.
160
+ */
96
161
  inc(val: number): void;
162
+ /**
163
+ * Decrements the current value by the specified amount.
164
+ * @param val The amount to subtract.
165
+ */
97
166
  dec(val: number): void;
98
167
  }
168
+ /**
169
+ * A specialized Field for handling boolean values.
170
+ * Provides toggle functionality.
171
+ */
99
172
  interface BooleanField extends Field<boolean> {
173
+ /**
174
+ * Inverts the current boolean value (true -> false, false -> true).
175
+ * @returns {boolean} The new value after toggling.
176
+ */
100
177
  toggle(): boolean;
101
178
  }
179
+ /**
180
+ * A specialized Field for handling string values.
181
+ * Provides chainable methods for common string manipulations.
182
+ */
102
183
  interface StringField extends Field<string> {
184
+ /**
185
+ * Appends a string or number to the end of the current value.
186
+ * @param str The value to append.
187
+ * @returns {this} The field instance for chaining.
188
+ */
103
189
  append(str: string | number): this;
190
+ /**
191
+ * Prepends a string or number to the beginning of the current value.
192
+ * @param str The value to prepend.
193
+ * @returns {this} The field instance for chaining.
194
+ */
104
195
  prepend(str: string | number): this;
196
+ /**
197
+ * Removes whitespace from both ends of the current string value.
198
+ * @returns {this} The field instance for chaining.
199
+ */
105
200
  trim(): this;
201
+ /**
202
+ * Checks if the current string is empty (length is 0).
203
+ * @returns {boolean} `true` if the string is empty, otherwise `false`.
204
+ */
106
205
  isEmpty(): boolean;
206
+ /**
207
+ * Sets the value to an empty string.
208
+ */
107
209
  clear(): void;
108
210
  }
109
211
 
@@ -144,6 +246,9 @@ declare class Fields {
144
246
  }]>;
145
247
  /**
146
248
  * Gets the read-only map of all `Field` instances in this container.
249
+ *
250
+ * @internal
251
+ *
147
252
  * @returns {Map<string, Field<any>>} The collection of fields.
148
253
  */
149
254
  get fields(): Map<string, Field<any>>;
@@ -379,9 +484,24 @@ declare class FieldTree<TFields extends Fields> {
379
484
  names: string[];
380
485
  }]>;
381
486
  /**
382
- * Gets the collection of direct child nodes of this tree branch.
487
+ * Provides direct access to the internal node storage.
488
+ *
489
+ * @remarks
490
+ * This is primarily intended for **serialization**, debugging, or low-level iteration.
491
+ * Avoid modifying this map directly to maintain internal consistency; use {@link addNode} or {@link removeNode} instead.
492
+ * @internal
383
493
  */
384
494
  get nodes(): Map<string, TreeNode<TFields>>;
495
+ /**
496
+ * Exposes the internal factory instance used by this tree.
497
+ *
498
+ * @remarks
499
+ * Direct usage of this getter is generally unnecessary.
500
+ * Prefer using {@link createDetachedTree} or {@link createDetachedFields} to create isolated instances.
501
+ *
502
+ * @returns {FieldTreeFactory} The factory instance.
503
+ */
504
+ get factory(): FieldTreeFactory<TFields>;
385
505
  /**
386
506
  * Creates an instance of FieldTree.
387
507
  * @param {FieldTreeFactory} factory - A factory responsible for creating new nodes within the tree.
@@ -488,6 +608,19 @@ declare class FieldTree<TFields extends Fields> {
488
608
  * This method should be called when a node is no longer needed.
489
609
  */
490
610
  destroy(): void;
611
+ /**
612
+ * Creates a new, detached FieldTree instance using the same factory as this tree.
613
+ * This new tree has no parent and is completely isolated.
614
+ *
615
+ * @returns A new instance of the same tree type.
616
+ */
617
+ createDetachedTree(): FieldTree<TFields>;
618
+ /**
619
+ * Creates a new, detached Fields container using the same factory.
620
+ *
621
+ * @returns
622
+ */
623
+ createDetachedFields(): TFields;
491
624
  /**
492
625
  * @private
493
626
  * Navigates the tree to the parent of a target node.
@@ -792,6 +925,7 @@ interface StoreCreateFieldOptions {
792
925
  * both type-safe and dynamic methods for manipulating data.
793
926
  */
794
927
  interface Store extends DataStorage {
928
+ readonly typeName: string;
795
929
  /**
796
930
  * Retrieves the raw value of a Field at a specific path.
797
931
  * @template T The expected type of the value.
@@ -912,6 +1046,16 @@ interface Store extends DataStorage {
912
1046
  * @param path The path to the node to remove.
913
1047
  */
914
1048
  remove(path: PathType): void;
1049
+ /**
1050
+ * Creates a new, independent instance of the Store.
1051
+ *
1052
+ * The returned store must operate on a completely separate data structure,
1053
+ * ensuring that operations on the new instance do not affect the current one (and vice versa).
1054
+ * Typically used for creating local execution scopes, stack frames, or sandbox environments.
1055
+ *
1056
+ * @returns {Store} A new, isolated Store instance.
1057
+ */
1058
+ createIsolated(): Store;
915
1059
  }
916
1060
 
917
1061
  interface DataStoreFieldResolver {
@@ -930,6 +1074,8 @@ interface DataStoreFieldResolver {
930
1074
 
931
1075
  declare class DataStore implements Store {
932
1076
  private readonly tree;
1077
+ static readonly typeName = "dataStore";
1078
+ readonly typeName = "dataStore";
933
1079
  private readonly resolvers;
934
1080
  private readonly rootFieldsName;
935
1081
  private _rootFields;
@@ -957,8 +1103,18 @@ declare class DataStore implements Store {
957
1103
  remove(path: PathType): void;
958
1104
  private isPathToRootFields;
959
1105
  private getDestinationFields;
1106
+ /**
1107
+ * Creates a new, independent instance of the Store with a fresh, empty data state (FieldsTree).
1108
+ *
1109
+ * The new instance retains the same capabilities (e.g., factory configuration)
1110
+ * as the current one but is completely detached from the existing data hierarchy.
1111
+ * This is useful for creating local scopes, stack frames, or temporary data contexts.
1112
+ *
1113
+ * @returns {DataStore} A new, isolated DataStore instance.
1114
+ */
1115
+ createIsolated(): DataStore;
1116
+ /** code below -> implementation of the DataStore from utils */
960
1117
  has(path: PathType): boolean;
961
- /** implementation of the DataStore from utils */
962
1118
  get(path: PathType): unknown;
963
1119
  set(path: PathType, value: unknown): void;
964
1120
  create(path: PathType, value: unknown): void;
@@ -983,18 +1139,15 @@ declare function isFields(value: unknown): value is Fields;
983
1139
  */
984
1140
  declare function isFieldTree(value: unknown): value is FieldTree<any>;
985
1141
  /**
986
- * Type guard that checks if an unknown value conforms to the `Store` interface.
987
- *
988
- * It performs a structural check (duck typing) by verifying the presence of methods
989
- * that are unique to the `Store` interface and are not part of the simpler `DataSource`
990
- * or `DataStorage` contracts, such as `createFields` and `createTree`.
1142
+ * Type guard that checks if a value is an instance of the `DataStore` class.
1143
+ * It verifies this by checking the static `typeName` property on the instance.
991
1144
  *
992
1145
  * @param value The `unknown` value to check.
993
- * @returns {boolean} `true` if the value is a `Store`-like object, `false` otherwise.
1146
+ * @returns {boolean} `true` if the value is a `DataStore` instance, otherwise `false`.
994
1147
  *
995
1148
  * @example
996
- * function processData(source: DataSource) {
997
- * if (isStore(source)) {
1149
+ * function processData(source: DataStore) {
1150
+ * if (isDataStore(source)) {
998
1151
  * // Inside this block, TypeScript now knows `source` is a full `Store`.
999
1152
  * // We can safely call Store-specific methods like `createFields`.
1000
1153
  * source.createFields('new.data.group');
@@ -1004,7 +1157,7 @@ declare function isFieldTree(value: unknown): value is FieldTree<any>;
1004
1157
  * }
1005
1158
  * }
1006
1159
  */
1007
- declare function isStore(value: unknown): value is Store;
1160
+ declare function isDataStore(value: unknown): value is DataStore;
1008
1161
 
1009
1162
  /**
1010
1163
  * Creates and configures a FieldRegistry with all the core field types.
@@ -1043,4 +1196,4 @@ declare function createCoreFieldSystem(config?: CoreFieldSystemConfig): {
1043
1196
  serializer: FieldTreeSerializer<CoreFields>;
1044
1197
  };
1045
1198
 
1046
- 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, isFieldTree, isFields, isStore };
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 };
package/dist/index.d.ts CHANGED
@@ -75,35 +75,137 @@ declare class Policies<T> {
75
75
  apply(val: T): T;
76
76
  }
77
77
 
78
+ /**
79
+ * Configuration options for creating a new Field instance.
80
+ * @template T The type of the value stored in the field.
81
+ */
78
82
  interface FieldOptions<T> {
83
+ /**
84
+ * An optional array of policies to apply to this field.
85
+ * Policies can enforce validation rules, transform values, or handle constraints.
86
+ */
79
87
  policies?: Policy<T>[];
80
88
  }
89
+ /**
90
+ * Represents a reactive data holder for a specific value type.
91
+ *
92
+ * A Field wraps a raw value, providing features like change observation (`onChange`),
93
+ * policy enforcement (validation/transformation), and metadata management (`name`, `typeName`).
94
+ *
95
+ * @template T The type of the value stored in the field.
96
+ */
81
97
  interface Field<T> {
98
+ /**
99
+ * A unique string identifier for the field type (e.g., 'numeric', 'boolean').
100
+ * Used for serialization and type guards.
101
+ */
82
102
  readonly typeName: string;
103
+ /**
104
+ * The name or key of this field within its parent container.
105
+ */
83
106
  readonly name: string;
107
+ /**
108
+ * The current value of the field.
109
+ * Assigning a new value triggers policies and emits the `onChange` event
110
+ * if the value is different from the current one.
111
+ */
84
112
  value: T;
113
+ /**
114
+ * The collection of policies applied to this field.
115
+ */
85
116
  policies: Policies<T>;
117
+ /**
118
+ * Updates the field's value without triggering the `onChange` event.
119
+ * Useful for internal synchronization or restoring state where side effects are undesirable.
120
+ * @param val The new value to set.
121
+ */
86
122
  setValueSilently(val: T): void;
123
+ /**
124
+ * Performs an atomic-like update using a callback function.
125
+ * The callback receives the current value and should return the new value.
126
+ * @param updateFn A function that transforms the current value into a new one.
127
+ */
87
128
  batchUpdate(updateFn: (currentValue: T) => T): void;
129
+ /**
130
+ * An observable stream that emits an event whenever the value changes.
131
+ * The payload contains the new value and the old value.
132
+ */
88
133
  onChange: Subscribable<[newValue: T, oldValue: T]>;
134
+ /**
135
+ * Cleans up the field, removing all listeners and releasing resources.
136
+ * Should be called when the field is no longer needed.
137
+ */
89
138
  destroy(): void;
90
139
  }
140
+ /**
141
+ * A specialized Field for handling numeric values.
142
+ * Provides capabilities for range clamping (min/max) and arithmetic operations.
143
+ */
91
144
  interface NumericField extends Field<number> {
145
+ /** The minimum allowed value for this field, or undefined if no lower bound exists. */
92
146
  readonly min: number | undefined;
147
+ /** The maximum allowed value for this field, or undefined if no upper bound exists. */
93
148
  readonly max: number | undefined;
149
+ /**
150
+ * Checks if the current value is equal to or less than the minimum limit.
151
+ */
94
152
  isMin(): boolean;
153
+ /**
154
+ * Checks if the current value is equal to or greater than the maximum limit.
155
+ */
95
156
  isMax(): boolean;
157
+ /**
158
+ * Increments the current value by the specified amount.
159
+ * @param val The amount to add.
160
+ */
96
161
  inc(val: number): void;
162
+ /**
163
+ * Decrements the current value by the specified amount.
164
+ * @param val The amount to subtract.
165
+ */
97
166
  dec(val: number): void;
98
167
  }
168
+ /**
169
+ * A specialized Field for handling boolean values.
170
+ * Provides toggle functionality.
171
+ */
99
172
  interface BooleanField extends Field<boolean> {
173
+ /**
174
+ * Inverts the current boolean value (true -> false, false -> true).
175
+ * @returns {boolean} The new value after toggling.
176
+ */
100
177
  toggle(): boolean;
101
178
  }
179
+ /**
180
+ * A specialized Field for handling string values.
181
+ * Provides chainable methods for common string manipulations.
182
+ */
102
183
  interface StringField extends Field<string> {
184
+ /**
185
+ * Appends a string or number to the end of the current value.
186
+ * @param str The value to append.
187
+ * @returns {this} The field instance for chaining.
188
+ */
103
189
  append(str: string | number): this;
190
+ /**
191
+ * Prepends a string or number to the beginning of the current value.
192
+ * @param str The value to prepend.
193
+ * @returns {this} The field instance for chaining.
194
+ */
104
195
  prepend(str: string | number): this;
196
+ /**
197
+ * Removes whitespace from both ends of the current string value.
198
+ * @returns {this} The field instance for chaining.
199
+ */
105
200
  trim(): this;
201
+ /**
202
+ * Checks if the current string is empty (length is 0).
203
+ * @returns {boolean} `true` if the string is empty, otherwise `false`.
204
+ */
106
205
  isEmpty(): boolean;
206
+ /**
207
+ * Sets the value to an empty string.
208
+ */
107
209
  clear(): void;
108
210
  }
109
211
 
@@ -144,6 +246,9 @@ declare class Fields {
144
246
  }]>;
145
247
  /**
146
248
  * Gets the read-only map of all `Field` instances in this container.
249
+ *
250
+ * @internal
251
+ *
147
252
  * @returns {Map<string, Field<any>>} The collection of fields.
148
253
  */
149
254
  get fields(): Map<string, Field<any>>;
@@ -379,9 +484,24 @@ declare class FieldTree<TFields extends Fields> {
379
484
  names: string[];
380
485
  }]>;
381
486
  /**
382
- * Gets the collection of direct child nodes of this tree branch.
487
+ * Provides direct access to the internal node storage.
488
+ *
489
+ * @remarks
490
+ * This is primarily intended for **serialization**, debugging, or low-level iteration.
491
+ * Avoid modifying this map directly to maintain internal consistency; use {@link addNode} or {@link removeNode} instead.
492
+ * @internal
383
493
  */
384
494
  get nodes(): Map<string, TreeNode<TFields>>;
495
+ /**
496
+ * Exposes the internal factory instance used by this tree.
497
+ *
498
+ * @remarks
499
+ * Direct usage of this getter is generally unnecessary.
500
+ * Prefer using {@link createDetachedTree} or {@link createDetachedFields} to create isolated instances.
501
+ *
502
+ * @returns {FieldTreeFactory} The factory instance.
503
+ */
504
+ get factory(): FieldTreeFactory<TFields>;
385
505
  /**
386
506
  * Creates an instance of FieldTree.
387
507
  * @param {FieldTreeFactory} factory - A factory responsible for creating new nodes within the tree.
@@ -488,6 +608,19 @@ declare class FieldTree<TFields extends Fields> {
488
608
  * This method should be called when a node is no longer needed.
489
609
  */
490
610
  destroy(): void;
611
+ /**
612
+ * Creates a new, detached FieldTree instance using the same factory as this tree.
613
+ * This new tree has no parent and is completely isolated.
614
+ *
615
+ * @returns A new instance of the same tree type.
616
+ */
617
+ createDetachedTree(): FieldTree<TFields>;
618
+ /**
619
+ * Creates a new, detached Fields container using the same factory.
620
+ *
621
+ * @returns
622
+ */
623
+ createDetachedFields(): TFields;
491
624
  /**
492
625
  * @private
493
626
  * Navigates the tree to the parent of a target node.
@@ -792,6 +925,7 @@ interface StoreCreateFieldOptions {
792
925
  * both type-safe and dynamic methods for manipulating data.
793
926
  */
794
927
  interface Store extends DataStorage {
928
+ readonly typeName: string;
795
929
  /**
796
930
  * Retrieves the raw value of a Field at a specific path.
797
931
  * @template T The expected type of the value.
@@ -912,6 +1046,16 @@ interface Store extends DataStorage {
912
1046
  * @param path The path to the node to remove.
913
1047
  */
914
1048
  remove(path: PathType): void;
1049
+ /**
1050
+ * Creates a new, independent instance of the Store.
1051
+ *
1052
+ * The returned store must operate on a completely separate data structure,
1053
+ * ensuring that operations on the new instance do not affect the current one (and vice versa).
1054
+ * Typically used for creating local execution scopes, stack frames, or sandbox environments.
1055
+ *
1056
+ * @returns {Store} A new, isolated Store instance.
1057
+ */
1058
+ createIsolated(): Store;
915
1059
  }
916
1060
 
917
1061
  interface DataStoreFieldResolver {
@@ -930,6 +1074,8 @@ interface DataStoreFieldResolver {
930
1074
 
931
1075
  declare class DataStore implements Store {
932
1076
  private readonly tree;
1077
+ static readonly typeName = "dataStore";
1078
+ readonly typeName = "dataStore";
933
1079
  private readonly resolvers;
934
1080
  private readonly rootFieldsName;
935
1081
  private _rootFields;
@@ -957,8 +1103,18 @@ declare class DataStore implements Store {
957
1103
  remove(path: PathType): void;
958
1104
  private isPathToRootFields;
959
1105
  private getDestinationFields;
1106
+ /**
1107
+ * Creates a new, independent instance of the Store with a fresh, empty data state (FieldsTree).
1108
+ *
1109
+ * The new instance retains the same capabilities (e.g., factory configuration)
1110
+ * as the current one but is completely detached from the existing data hierarchy.
1111
+ * This is useful for creating local scopes, stack frames, or temporary data contexts.
1112
+ *
1113
+ * @returns {DataStore} A new, isolated DataStore instance.
1114
+ */
1115
+ createIsolated(): DataStore;
1116
+ /** code below -> implementation of the DataStore from utils */
960
1117
  has(path: PathType): boolean;
961
- /** implementation of the DataStore from utils */
962
1118
  get(path: PathType): unknown;
963
1119
  set(path: PathType, value: unknown): void;
964
1120
  create(path: PathType, value: unknown): void;
@@ -983,18 +1139,15 @@ declare function isFields(value: unknown): value is Fields;
983
1139
  */
984
1140
  declare function isFieldTree(value: unknown): value is FieldTree<any>;
985
1141
  /**
986
- * Type guard that checks if an unknown value conforms to the `Store` interface.
987
- *
988
- * It performs a structural check (duck typing) by verifying the presence of methods
989
- * that are unique to the `Store` interface and are not part of the simpler `DataSource`
990
- * or `DataStorage` contracts, such as `createFields` and `createTree`.
1142
+ * Type guard that checks if a value is an instance of the `DataStore` class.
1143
+ * It verifies this by checking the static `typeName` property on the instance.
991
1144
  *
992
1145
  * @param value The `unknown` value to check.
993
- * @returns {boolean} `true` if the value is a `Store`-like object, `false` otherwise.
1146
+ * @returns {boolean} `true` if the value is a `DataStore` instance, otherwise `false`.
994
1147
  *
995
1148
  * @example
996
- * function processData(source: DataSource) {
997
- * if (isStore(source)) {
1149
+ * function processData(source: DataStore) {
1150
+ * if (isDataStore(source)) {
998
1151
  * // Inside this block, TypeScript now knows `source` is a full `Store`.
999
1152
  * // We can safely call Store-specific methods like `createFields`.
1000
1153
  * source.createFields('new.data.group');
@@ -1004,7 +1157,7 @@ declare function isFieldTree(value: unknown): value is FieldTree<any>;
1004
1157
  * }
1005
1158
  * }
1006
1159
  */
1007
- declare function isStore(value: unknown): value is Store;
1160
+ declare function isDataStore(value: unknown): value is DataStore;
1008
1161
 
1009
1162
  /**
1010
1163
  * Creates and configures a FieldRegistry with all the core field types.
@@ -1043,4 +1196,4 @@ declare function createCoreFieldSystem(config?: CoreFieldSystemConfig): {
1043
1196
  serializer: FieldTreeSerializer<CoreFields>;
1044
1197
  };
1045
1198
 
1046
- 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, isFieldTree, isFields, isStore };
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 };
package/dist/index.js CHANGED
@@ -52,9 +52,9 @@ __export(index_exports, {
52
52
  createCoreTreeNodeFactory: () => createCoreTreeNodeFactory,
53
53
  createCoreTreeSerializer: () => createCoreTreeSerializer,
54
54
  createTypedMethodsMixin: () => createTypedMethodsMixin,
55
+ isDataStore: () => isDataStore,
55
56
  isFieldTree: () => isFieldTree,
56
- isFields: () => isFields,
57
- isStore: () => isStore
57
+ isFields: () => isFields
58
58
  });
59
59
  module.exports = __toCommonJS(index_exports);
60
60
 
@@ -378,6 +378,9 @@ var Fields = class _Fields {
378
378
  onRemove = new import_utils4.Emitter();
379
379
  /**
380
380
  * Gets the read-only map of all `Field` instances in this container.
381
+ *
382
+ * @internal
383
+ *
381
384
  * @returns {Map<string, Field<any>>} The collection of fields.
382
385
  */
383
386
  get fields() {
@@ -524,11 +527,28 @@ var FieldTree = class _FieldTree {
524
527
  */
525
528
  onRemove = new import_utils5.Emitter();
526
529
  /**
527
- * Gets the collection of direct child nodes of this tree branch.
530
+ * Provides direct access to the internal node storage.
531
+ *
532
+ * @remarks
533
+ * This is primarily intended for **serialization**, debugging, or low-level iteration.
534
+ * Avoid modifying this map directly to maintain internal consistency; use {@link addNode} or {@link removeNode} instead.
535
+ * @internal
528
536
  */
529
537
  get nodes() {
530
538
  return this._nodes;
531
539
  }
540
+ /**
541
+ * Exposes the internal factory instance used by this tree.
542
+ *
543
+ * @remarks
544
+ * Direct usage of this getter is generally unnecessary.
545
+ * Prefer using {@link createDetachedTree} or {@link createDetachedFields} to create isolated instances.
546
+ *
547
+ * @returns {FieldTreeFactory} The factory instance.
548
+ */
549
+ get factory() {
550
+ return this._factory;
551
+ }
532
552
  /**
533
553
  * Creates an instance of FieldTree.
534
554
  * @param {FieldTreeFactory} factory - A factory responsible for creating new nodes within the tree.
@@ -700,6 +720,23 @@ var FieldTree = class _FieldTree {
700
720
  this.onAdd.clear();
701
721
  this.onRemove.clear();
702
722
  }
723
+ /**
724
+ * Creates a new, detached FieldTree instance using the same factory as this tree.
725
+ * This new tree has no parent and is completely isolated.
726
+ *
727
+ * @returns A new instance of the same tree type.
728
+ */
729
+ createDetachedTree() {
730
+ return this._factory.tree();
731
+ }
732
+ /**
733
+ * Creates a new, detached Fields container using the same factory.
734
+ *
735
+ * @returns
736
+ */
737
+ createDetachedFields() {
738
+ return this._factory.fields();
739
+ }
703
740
  /**
704
741
  * @private
705
742
  * Navigates the tree to the parent of a target node.
@@ -1023,13 +1060,15 @@ var StringFieldResolver = class {
1023
1060
  };
1024
1061
 
1025
1062
  // src/data-store.ts
1026
- var DataStore = class {
1063
+ var DataStore = class _DataStore {
1027
1064
  constructor(tree) {
1028
1065
  this.tree = tree;
1029
1066
  this.registerResolver(new NumericFieldResolver());
1030
1067
  this.registerResolver(new BooleanFieldResolver());
1031
1068
  this.registerResolver(new StringFieldResolver());
1032
1069
  }
1070
+ static typeName = "dataStore";
1071
+ typeName = _DataStore.typeName;
1033
1072
  resolvers = [];
1034
1073
  rootFieldsName = "__root_fields";
1035
1074
  _rootFields;
@@ -1153,6 +1192,19 @@ var DataStore = class {
1153
1192
  const leafName = pathArr.pop();
1154
1193
  return { fields: this.tree.getOrCreateFields(path), leafName };
1155
1194
  }
1195
+ /**
1196
+ * Creates a new, independent instance of the Store with a fresh, empty data state (FieldsTree).
1197
+ *
1198
+ * The new instance retains the same capabilities (e.g., factory configuration)
1199
+ * as the current one but is completely detached from the existing data hierarchy.
1200
+ * This is useful for creating local scopes, stack frames, or temporary data contexts.
1201
+ *
1202
+ * @returns {DataStore} A new, isolated DataStore instance.
1203
+ */
1204
+ createIsolated() {
1205
+ return new _DataStore(this.tree.createDetachedTree());
1206
+ }
1207
+ /** code below -> implementation of the DataStore from utils */
1156
1208
  has(path) {
1157
1209
  const pathArr = (0, import_utils10.ensurePathArray)(path);
1158
1210
  if (this.isPathToRootFields(pathArr)) {
@@ -1160,7 +1212,6 @@ var DataStore = class {
1160
1212
  }
1161
1213
  return this.tree.hasPath(pathArr);
1162
1214
  }
1163
- /** implementation of the DataStore from utils */
1164
1215
  get(path) {
1165
1216
  return this.getField(path).value;
1166
1217
  }
@@ -1181,13 +1232,13 @@ var DataStore = class {
1181
1232
  // src/guards.ts
1182
1233
  var import_utils11 = require("@axi-engine/utils");
1183
1234
  function isFields(value) {
1184
- return value != null && value.typeName === Fields.typeName;
1235
+ return !(0, import_utils11.isNullOrUndefined)(value) && value.typeName === Fields.typeName;
1185
1236
  }
1186
1237
  function isFieldTree(value) {
1187
- return value != null && value.typeName === FieldTree.typeName;
1238
+ return !(0, import_utils11.isNullOrUndefined)(value) && value.typeName === FieldTree.typeName;
1188
1239
  }
1189
- function isStore(value) {
1190
- return !(0, import_utils11.isNullOrUndefined)(value) && typeof value.createFields === "function" && typeof value.createTree === "function";
1240
+ function isDataStore(value) {
1241
+ return !(0, import_utils11.isNullOrUndefined)(value) && value.typeName === DataStore.typeName;
1191
1242
  }
1192
1243
 
1193
1244
  // src/setup.ts
@@ -1258,7 +1309,7 @@ function createCoreFieldSystem(config) {
1258
1309
  createCoreTreeNodeFactory,
1259
1310
  createCoreTreeSerializer,
1260
1311
  createTypedMethodsMixin,
1312
+ isDataStore,
1261
1313
  isFieldTree,
1262
- isFields,
1263
- isStore
1314
+ isFields
1264
1315
  });
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
- * Gets the collection of direct child nodes of this tree branch.
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.
@@ -963,13 +1000,15 @@ var StringFieldResolver = class {
963
1000
  };
964
1001
 
965
1002
  // src/data-store.ts
966
- var DataStore = class {
1003
+ var DataStore = class _DataStore {
967
1004
  constructor(tree) {
968
1005
  this.tree = tree;
969
1006
  this.registerResolver(new NumericFieldResolver());
970
1007
  this.registerResolver(new BooleanFieldResolver());
971
1008
  this.registerResolver(new StringFieldResolver());
972
1009
  }
1010
+ static typeName = "dataStore";
1011
+ typeName = _DataStore.typeName;
973
1012
  resolvers = [];
974
1013
  rootFieldsName = "__root_fields";
975
1014
  _rootFields;
@@ -1093,6 +1132,19 @@ var DataStore = class {
1093
1132
  const leafName = pathArr.pop();
1094
1133
  return { fields: this.tree.getOrCreateFields(path), leafName };
1095
1134
  }
1135
+ /**
1136
+ * Creates a new, independent instance of the Store with a fresh, empty data state (FieldsTree).
1137
+ *
1138
+ * The new instance retains the same capabilities (e.g., factory configuration)
1139
+ * as the current one but is completely detached from the existing data hierarchy.
1140
+ * This is useful for creating local scopes, stack frames, or temporary data contexts.
1141
+ *
1142
+ * @returns {DataStore} A new, isolated DataStore instance.
1143
+ */
1144
+ createIsolated() {
1145
+ return new _DataStore(this.tree.createDetachedTree());
1146
+ }
1147
+ /** code below -> implementation of the DataStore from utils */
1096
1148
  has(path) {
1097
1149
  const pathArr = ensurePathArray2(path);
1098
1150
  if (this.isPathToRootFields(pathArr)) {
@@ -1100,7 +1152,6 @@ var DataStore = class {
1100
1152
  }
1101
1153
  return this.tree.hasPath(pathArr);
1102
1154
  }
1103
- /** implementation of the DataStore from utils */
1104
1155
  get(path) {
1105
1156
  return this.getField(path).value;
1106
1157
  }
@@ -1121,13 +1172,13 @@ var DataStore = class {
1121
1172
  // src/guards.ts
1122
1173
  import { isNullOrUndefined as isNullOrUndefined3 } from "@axi-engine/utils";
1123
1174
  function isFields(value) {
1124
- return value != null && value.typeName === Fields.typeName;
1175
+ return !isNullOrUndefined3(value) && value.typeName === Fields.typeName;
1125
1176
  }
1126
1177
  function isFieldTree(value) {
1127
- return value != null && value.typeName === FieldTree.typeName;
1178
+ return !isNullOrUndefined3(value) && value.typeName === FieldTree.typeName;
1128
1179
  }
1129
- function isStore(value) {
1130
- return !isNullOrUndefined3(value) && typeof value.createFields === "function" && typeof value.createTree === "function";
1180
+ function isDataStore(value) {
1181
+ return !isNullOrUndefined3(value) && value.typeName === DataStore.typeName;
1131
1182
  }
1132
1183
 
1133
1184
  // src/setup.ts
@@ -1197,7 +1248,7 @@ export {
1197
1248
  createCoreTreeNodeFactory,
1198
1249
  createCoreTreeSerializer,
1199
1250
  createTypedMethodsMixin,
1251
+ isDataStore,
1200
1252
  isFieldTree,
1201
- isFields,
1202
- isStore
1253
+ isFields
1203
1254
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axi-engine/fields",
3
- "version": "0.3.8",
3
+ "version": "0.3.9",
4
4
  "description": "A compact, reactive state management library based on a tree of observable fields.",
5
5
  "license": "MIT",
6
6
  "repository": {