@axi-engine/fields 0.3.2 → 0.3.4

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.
Files changed (160) hide show
  1. package/README.md +6 -2
  2. package/dist/core-field-tree-factory.d.ts +13 -0
  3. package/dist/core-field-tree-factory.d.ts.map +1 -0
  4. package/dist/core-field-tree-factory.js +14 -0
  5. package/dist/core-field-tree-factory.js.map +1 -0
  6. package/dist/core-field-tree.d.ts +5 -0
  7. package/dist/core-field-tree.d.ts.map +1 -0
  8. package/dist/core-field-tree.js +4 -0
  9. package/dist/core-field-tree.js.map +1 -0
  10. package/dist/core-fields-factory.d.ts +10 -0
  11. package/dist/core-fields-factory.d.ts.map +1 -0
  12. package/dist/core-fields-factory.js +14 -0
  13. package/dist/core-fields-factory.js.map +1 -0
  14. package/dist/core-fields.d.ts +47 -0
  15. package/dist/core-fields.d.ts.map +1 -0
  16. package/dist/core-fields.js +8 -0
  17. package/dist/core-fields.js.map +1 -0
  18. package/dist/data-store-field-resolver.d.ts +26 -0
  19. package/dist/data-store-field-resolver.d.ts.map +1 -0
  20. package/dist/data-store-field-resolver.js +21 -0
  21. package/dist/data-store-field-resolver.js.map +1 -0
  22. package/dist/data-store.d.ts +38 -0
  23. package/dist/data-store.d.ts.map +1 -0
  24. package/dist/data-store.js +141 -0
  25. package/dist/data-store.js.map +1 -0
  26. package/dist/field-definitions/core-boolean-field.d.ts +11 -0
  27. package/dist/field-definitions/core-boolean-field.d.ts.map +1 -0
  28. package/dist/field-definitions/core-boolean-field.js +13 -0
  29. package/dist/field-definitions/core-boolean-field.js.map +1 -0
  30. package/dist/field-definitions/core-field.d.ts +51 -0
  31. package/dist/field-definitions/core-field.d.ts.map +1 -0
  32. package/dist/field-definitions/core-field.js +74 -0
  33. package/dist/field-definitions/core-field.js.map +1 -0
  34. package/dist/field-definitions/core-numeric-field.d.ts +18 -0
  35. package/dist/field-definitions/core-numeric-field.d.ts.map +1 -0
  36. package/dist/field-definitions/core-numeric-field.js +45 -0
  37. package/dist/field-definitions/core-numeric-field.js.map +1 -0
  38. package/dist/field-definitions/core-string-field.d.ts +15 -0
  39. package/dist/field-definitions/core-string-field.d.ts.map +1 -0
  40. package/dist/field-definitions/core-string-field.js +27 -0
  41. package/dist/field-definitions/core-string-field.js.map +1 -0
  42. package/dist/field-definitions/index.d.ts +5 -0
  43. package/dist/field-definitions/index.d.ts.map +1 -0
  44. package/dist/field-definitions/index.js +5 -0
  45. package/dist/field-definitions/index.js.map +1 -0
  46. package/dist/field-registry.d.ts +5 -0
  47. package/dist/field-registry.d.ts.map +1 -0
  48. package/dist/field-registry.js +4 -0
  49. package/dist/field-registry.js.map +1 -0
  50. package/dist/field-tree-factory.d.ts +12 -0
  51. package/dist/field-tree-factory.d.ts.map +1 -0
  52. package/dist/field-tree-factory.js +2 -0
  53. package/dist/field-tree-factory.js.map +1 -0
  54. package/dist/field-tree.d.ts +171 -0
  55. package/dist/field-tree.d.ts.map +1 -0
  56. package/dist/field-tree.js +248 -0
  57. package/dist/field-tree.js.map +1 -0
  58. package/dist/field.d.ts +34 -0
  59. package/dist/field.d.ts.map +1 -0
  60. package/dist/field.js +2 -0
  61. package/dist/field.js.map +1 -0
  62. package/dist/fields-factory.d.ts +5 -0
  63. package/dist/fields-factory.d.ts.map +1 -0
  64. package/dist/fields-factory.js +2 -0
  65. package/dist/fields-factory.js.map +1 -0
  66. package/dist/fields.d.ts +101 -0
  67. package/dist/fields.d.ts.map +1 -0
  68. package/dist/fields.js +143 -0
  69. package/dist/fields.js.map +1 -0
  70. package/dist/index.d.mts +112 -112
  71. package/dist/index.d.ts +18 -997
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +18 -1228
  74. package/dist/index.js.map +1 -0
  75. package/dist/index.mjs +2 -2
  76. package/dist/mixins/mixin-factory.d.ts +29 -0
  77. package/dist/mixins/mixin-factory.d.ts.map +1 -0
  78. package/dist/mixins/mixin-factory.js +32 -0
  79. package/dist/mixins/mixin-factory.js.map +1 -0
  80. package/dist/mixins/with-boolean-fields.mixin.d.ts +9 -0
  81. package/dist/mixins/with-boolean-fields.mixin.d.ts.map +1 -0
  82. package/dist/mixins/with-boolean-fields.mixin.js +4 -0
  83. package/dist/mixins/with-boolean-fields.mixin.js.map +1 -0
  84. package/dist/mixins/with-default-generic-fields.mixin.d.ts +31 -0
  85. package/dist/mixins/with-default-generic-fields.mixin.d.ts.map +1 -0
  86. package/dist/mixins/with-default-generic-fields.mixin.js +15 -0
  87. package/dist/mixins/with-default-generic-fields.mixin.js.map +1 -0
  88. package/dist/mixins/with-numeric-fields.mixin.d.ts +9 -0
  89. package/dist/mixins/with-numeric-fields.mixin.d.ts.map +1 -0
  90. package/dist/mixins/with-numeric-fields.mixin.js +4 -0
  91. package/dist/mixins/with-numeric-fields.mixin.js.map +1 -0
  92. package/dist/mixins/with-string-fields.mixin.d.ts +9 -0
  93. package/dist/mixins/with-string-fields.mixin.d.ts.map +1 -0
  94. package/dist/mixins/with-string-fields.mixin.js +4 -0
  95. package/dist/mixins/with-string-fields.mixin.js.map +1 -0
  96. package/dist/policies/clamp-max-policy.d.ts +11 -0
  97. package/dist/policies/clamp-max-policy.d.ts.map +1 -0
  98. package/dist/policies/clamp-max-policy.js +18 -0
  99. package/dist/policies/clamp-max-policy.js.map +1 -0
  100. package/dist/policies/clamp-min-policy.d.ts +11 -0
  101. package/dist/policies/clamp-min-policy.d.ts.map +1 -0
  102. package/dist/policies/clamp-min-policy.js +18 -0
  103. package/dist/policies/clamp-min-policy.js.map +1 -0
  104. package/dist/policies/clamp-policy.d.ts +12 -0
  105. package/dist/policies/clamp-policy.d.ts.map +1 -0
  106. package/dist/policies/clamp-policy.js +21 -0
  107. package/dist/policies/clamp-policy.js.map +1 -0
  108. package/dist/policies/index.d.ts +6 -0
  109. package/dist/policies/index.d.ts.map +1 -0
  110. package/dist/policies/index.js +6 -0
  111. package/dist/policies/index.js.map +1 -0
  112. package/dist/policies/policies.d.ts +38 -0
  113. package/dist/policies/policies.d.ts.map +1 -0
  114. package/dist/policies/policies.js +62 -0
  115. package/dist/policies/policies.js.map +1 -0
  116. package/dist/policies/policy.d.ts +6 -0
  117. package/dist/policies/policy.d.ts.map +1 -0
  118. package/dist/policies/policy.js +2 -0
  119. package/dist/policies/policy.js.map +1 -0
  120. package/dist/serializer/field-serializer.d.ts +52 -0
  121. package/dist/serializer/field-serializer.d.ts.map +1 -0
  122. package/dist/serializer/field-serializer.js +66 -0
  123. package/dist/serializer/field-serializer.js.map +1 -0
  124. package/dist/serializer/field-tree-serializer.d.ts +50 -0
  125. package/dist/serializer/field-tree-serializer.d.ts.map +1 -0
  126. package/dist/serializer/field-tree-serializer.js +68 -0
  127. package/dist/serializer/field-tree-serializer.js.map +1 -0
  128. package/dist/serializer/fields-serializer.d.ts +49 -0
  129. package/dist/serializer/fields-serializer.d.ts.map +1 -0
  130. package/dist/serializer/fields-serializer.js +57 -0
  131. package/dist/serializer/fields-serializer.js.map +1 -0
  132. package/dist/serializer/index.d.ts +8 -0
  133. package/dist/serializer/index.d.ts.map +1 -0
  134. package/dist/serializer/index.js +8 -0
  135. package/dist/serializer/index.js.map +1 -0
  136. package/dist/serializer/policies/clamp-max-policy-serializer-handler.d.ts +13 -0
  137. package/dist/serializer/policies/clamp-max-policy-serializer-handler.d.ts.map +1 -0
  138. package/dist/serializer/policies/clamp-max-policy-serializer-handler.js +10 -0
  139. package/dist/serializer/policies/clamp-max-policy-serializer-handler.js.map +1 -0
  140. package/dist/serializer/policies/clamp-min-policy-serializer-handler.d.ts +13 -0
  141. package/dist/serializer/policies/clamp-min-policy-serializer-handler.d.ts.map +1 -0
  142. package/dist/serializer/policies/clamp-min-policy-serializer-handler.js +10 -0
  143. package/dist/serializer/policies/clamp-min-policy-serializer-handler.js.map +1 -0
  144. package/dist/serializer/policies/clamp-policy-serializer-handler.d.ts +16 -0
  145. package/dist/serializer/policies/clamp-policy-serializer-handler.d.ts.map +1 -0
  146. package/dist/serializer/policies/clamp-policy-serializer-handler.js +10 -0
  147. package/dist/serializer/policies/clamp-policy-serializer-handler.js.map +1 -0
  148. package/dist/serializer/policy-serializer.d.ts +41 -0
  149. package/dist/serializer/policy-serializer.d.ts.map +1 -0
  150. package/dist/serializer/policy-serializer.js +43 -0
  151. package/dist/serializer/policy-serializer.js.map +1 -0
  152. package/dist/setup.d.ts +41 -0
  153. package/dist/setup.d.ts.map +1 -0
  154. package/dist/setup.js +57 -0
  155. package/dist/setup.js.map +1 -0
  156. package/dist/store.d.ts +137 -0
  157. package/dist/store.d.ts.map +1 -0
  158. package/dist/store.js +2 -0
  159. package/dist/store.js.map +1 -0
  160. package/package.json +7 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field.js","sourceRoot":"","sources":["../src/field.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ import { Fields } from './fields';
2
+ export interface FieldsFactory<TFields extends Fields> {
3
+ fields(): TFields;
4
+ }
5
+ //# sourceMappingURL=fields-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fields-factory.d.ts","sourceRoot":"","sources":["../src/fields-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAC;AAEhC,MAAM,WAAW,aAAa,CAAC,OAAO,SAAS,MAAM;IACnD,MAAM,IAAI,OAAO,CAAC;CACnB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=fields-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fields-factory.js","sourceRoot":"","sources":["../src/fields-factory.ts"],"names":[],"mappings":""}
@@ -0,0 +1,101 @@
1
+ import { Emitter } from '@axi-engine/utils';
2
+ import { FieldRegistry } from './field-registry';
3
+ import { Field } from './field';
4
+ /**
5
+ * A container for a collection of named `Field` instances.
6
+ *
7
+ * This class acts as a "leaf" node in the `FieldTree` hierarchy, managing a flat
8
+ * key-value store of reactive data points. It uses a `FieldRegistry` to dynamically
9
+ * create `Field` instances of different types.
10
+ */
11
+ export declare class Fields {
12
+ static readonly typeName = "fields";
13
+ readonly typeName = "fields";
14
+ readonly _fields: Map<string, Field<any>>;
15
+ readonly _fieldRegistry: FieldRegistry;
16
+ /**
17
+ * An event emitter that fires when a new field is added to the collection.
18
+ * @event
19
+ * @param {object} event - The event payload.
20
+ * @param {string} event.name - The name of the added field.
21
+ * @param {Field<any>} event.field - The `Field` instance that was added.
22
+ */
23
+ onAdd: Emitter<[event: {
24
+ name: string;
25
+ field: Field<any>;
26
+ }]>;
27
+ /**
28
+ * An event emitter that fires after one or more fields have been removed.
29
+ * @event
30
+ * @param {object} event - The event payload.
31
+ * @param {string[]} event.names - An array of names of the fields that were successfully removed.
32
+ */
33
+ onRemove: Emitter<[event: {
34
+ names: string[];
35
+ }]>;
36
+ /**
37
+ * Gets the read-only map of all `Field` instances in this container.
38
+ * @returns {Map<string, Field<any>>} The collection of fields.
39
+ */
40
+ get fields(): Map<string, Field<any>>;
41
+ /**
42
+ * Creates an instance of Fields.
43
+ * @param {FieldRegistry} fieldRegistry - The registry used to create new `Field` instances.
44
+ */
45
+ constructor(fieldRegistry: FieldRegistry);
46
+ /**
47
+ * Checks if a field with the given name exists in the collection.
48
+ * @param {string} name The name of the field to check.
49
+ * @returns {boolean} `true` if the field exists, otherwise `false`.
50
+ */
51
+ has(name: string): boolean;
52
+ /**
53
+ * Adds a pre-existing `Field` instance to the collection and fires the `onAdd` event.
54
+ * @template T - The specific `Field` type being added.
55
+ * @param {Field<any>} field - The `Field` instance to add.
56
+ * @returns {T} The added `Field` instance, cast to type `T`.
57
+ * @throws If a field with the same name already exists.
58
+ */
59
+ add<T extends Field<any>>(field: Field<any>): T;
60
+ /**
61
+ * Creates a new `Field` instance of a specified type, adds it to the collection, and returns it.
62
+ * This is the primary factory method for creating fields within this container.
63
+ * @template T - The expected `Field` type to be returned.
64
+ * @param {string} typeName - The registered type name of the field to create (e.g., 'numeric', 'boolean').
65
+ * @param {string} name - The unique name for the new field.
66
+ * @param {*} initialValue - The initial value for the new field.
67
+ * @param {*} [options] - Optional configuration passed to the field's constructor.
68
+ * @returns {T} The newly created `Field` instance.
69
+ */
70
+ create<T extends Field<any>>(typeName: string, name: string, initialValue: any, options?: any): T;
71
+ /**
72
+ * Updates an existing field's value or creates a new one if it doesn't exist.
73
+ * @template T - The expected `Field` type.
74
+ * @param {string} typeName - The type name to use if a new field needs to be created.
75
+ * @param {string} name - The name of the field to update or create.
76
+ * @param {*} value - The new value to set.
77
+ * @param {*} [options] - Optional configuration, used only if a new field is created.
78
+ * @returns {T} The existing or newly created `Field` instance.
79
+ */
80
+ upset<T extends Field<any>>(typeName: string, name: string, value: any, options?: any): T;
81
+ /**
82
+ * Retrieves a field by its name.
83
+ * @template TField - The expected `Field` type to be returned.
84
+ * @param {string} name - The name of the field to retrieve.
85
+ * @returns {TField} The `Field` instance.
86
+ * @throws If the field does not exist.
87
+ */
88
+ get<TField extends Field<any>>(name: string): TField;
89
+ /**
90
+ * Removes one or more fields from the collection.
91
+ * This method ensures that the `destroy` method of each removed field is called to clean up its resources.
92
+ * @param {string| string[]} names A single name or an array of names to remove.
93
+ */
94
+ remove(names: string | string[]): void;
95
+ /**
96
+ * Removes all fields from the collection, ensuring each is properly destroyed.
97
+ */
98
+ clear(): void;
99
+ destroy(): void;
100
+ }
101
+ //# sourceMappingURL=fields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../src/fields.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAU,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAC,KAAK,EAAC,MAAM,SAAS,CAAC;AAE9B;;;;;;GAMG;AACH,qBAAa,MAAM;IACjB,MAAM,CAAC,QAAQ,CAAC,QAAQ,YAAY;IACpC,QAAQ,CAAC,QAAQ,YAAmB;IAEpC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAa;IACtD,QAAQ,CAAC,cAAc,EAAE,aAAa,CAAC;IAEvC;;;;;;OAMG;IACH,KAAK;cACG,MAAM;eACL,KAAK,CAAC,GAAG,CAAC;QACb;IAEN;;;;;OAKG;IACH,QAAQ;eACC,MAAM,EAAE;QACX;IAEN;;;OAGG;IACH,IAAI,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAEpC;IAED;;;OAGG;gBACS,aAAa,EAAE,aAAa;IAIxC;;;;OAIG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B;;;;;;OAMG;IACH,GAAG,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;IAa/C;;;;;;;;;OASG;IACH,MAAM,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,EACzB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,GAAG,EACjB,OAAO,CAAC,EAAE,GAAG,GACZ,CAAC;IAOJ;;;;;;;;OAQG;IACH,KAAK,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,EACxB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,GAAG,EACV,OAAO,CAAC,EAAE,GAAG,GACZ,CAAC;IASJ;;;;;;OAMG;IACH,GAAG,CAAC,MAAM,SAAS,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAKpD;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAkB/B;;OAEG;IACH,KAAK;IAIL,OAAO;CAKR"}
package/dist/fields.js ADDED
@@ -0,0 +1,143 @@
1
+ import { Emitter, throwIf } from '@axi-engine/utils';
2
+ /**
3
+ * A container for a collection of named `Field` instances.
4
+ *
5
+ * This class acts as a "leaf" node in the `FieldTree` hierarchy, managing a flat
6
+ * key-value store of reactive data points. It uses a `FieldRegistry` to dynamically
7
+ * create `Field` instances of different types.
8
+ */
9
+ export class Fields {
10
+ static typeName = 'fields';
11
+ typeName = Fields.typeName;
12
+ _fields = new Map();
13
+ _fieldRegistry;
14
+ /**
15
+ * An event emitter that fires when a new field is added to the collection.
16
+ * @event
17
+ * @param {object} event - The event payload.
18
+ * @param {string} event.name - The name of the added field.
19
+ * @param {Field<any>} event.field - The `Field` instance that was added.
20
+ */
21
+ onAdd = new Emitter();
22
+ /**
23
+ * An event emitter that fires after one or more fields have been removed.
24
+ * @event
25
+ * @param {object} event - The event payload.
26
+ * @param {string[]} event.names - An array of names of the fields that were successfully removed.
27
+ */
28
+ onRemove = new Emitter();
29
+ /**
30
+ * Gets the read-only map of all `Field` instances in this container.
31
+ * @returns {Map<string, Field<any>>} The collection of fields.
32
+ */
33
+ get fields() {
34
+ return this._fields;
35
+ }
36
+ /**
37
+ * Creates an instance of Fields.
38
+ * @param {FieldRegistry} fieldRegistry - The registry used to create new `Field` instances.
39
+ */
40
+ constructor(fieldRegistry) {
41
+ this._fieldRegistry = fieldRegistry;
42
+ }
43
+ /**
44
+ * Checks if a field with the given name exists in the collection.
45
+ * @param {string} name The name of the field to check.
46
+ * @returns {boolean} `true` if the field exists, otherwise `false`.
47
+ */
48
+ has(name) {
49
+ return this._fields.has(name);
50
+ }
51
+ /**
52
+ * Adds a pre-existing `Field` instance to the collection and fires the `onAdd` event.
53
+ * @template T - The specific `Field` type being added.
54
+ * @param {Field<any>} field - The `Field` instance to add.
55
+ * @returns {T} The added `Field` instance, cast to type `T`.
56
+ * @throws If a field with the same name already exists.
57
+ */
58
+ add(field) {
59
+ throwIf(this.has(field.name), `Field with name '${field.name}' already exists`);
60
+ this._fields.set(field.name, field);
61
+ this.onAdd.emit({
62
+ name: field.name,
63
+ field: field
64
+ });
65
+ return field;
66
+ }
67
+ /**
68
+ * Creates a new `Field` instance of a specified type, adds it to the collection, and returns it.
69
+ * This is the primary factory method for creating fields within this container.
70
+ * @template T - The expected `Field` type to be returned.
71
+ * @param {string} typeName - The registered type name of the field to create (e.g., 'numeric', 'boolean').
72
+ * @param {string} name - The unique name for the new field.
73
+ * @param {*} initialValue - The initial value for the new field.
74
+ * @param {*} [options] - Optional configuration passed to the field's constructor.
75
+ * @returns {T} The newly created `Field` instance.
76
+ */
77
+ create(typeName, name, initialValue, options) {
78
+ const Ctor = this._fieldRegistry.get(typeName);
79
+ const field = new Ctor(name, initialValue, options);
80
+ this.add(field);
81
+ return field;
82
+ }
83
+ /**
84
+ * Updates an existing field's value or creates a new one if it doesn't exist.
85
+ * @template T - The expected `Field` type.
86
+ * @param {string} typeName - The type name to use if a new field needs to be created.
87
+ * @param {string} name - The name of the field to update or create.
88
+ * @param {*} value - The new value to set.
89
+ * @param {*} [options] - Optional configuration, used only if a new field is created.
90
+ * @returns {T} The existing or newly created `Field` instance.
91
+ */
92
+ upset(typeName, name, value, options) {
93
+ if (this.has(name)) {
94
+ const field = this.get(name);
95
+ field.value = value;
96
+ return field;
97
+ }
98
+ return this.create(typeName, name, value, options);
99
+ }
100
+ /**
101
+ * Retrieves a field by its name.
102
+ * @template TField - The expected `Field` type to be returned.
103
+ * @param {string} name - The name of the field to retrieve.
104
+ * @returns {TField} The `Field` instance.
105
+ * @throws If the field does not exist.
106
+ */
107
+ get(name) {
108
+ throwIf(!this._fields.has(name), `Field with name '${name}' not exists`);
109
+ return this._fields.get(name);
110
+ }
111
+ /**
112
+ * Removes one or more fields from the collection.
113
+ * This method ensures that the `destroy` method of each removed field is called to clean up its resources.
114
+ * @param {string| string[]} names A single name or an array of names to remove.
115
+ */
116
+ remove(names) {
117
+ const namesToRemove = Array.isArray(names) ? names : [names];
118
+ const reallyRemoved = namesToRemove.filter(name => {
119
+ const field = this._fields.get(name);
120
+ if (!field) {
121
+ return false;
122
+ }
123
+ field.destroy();
124
+ return this._fields.delete(name);
125
+ });
126
+ if (!reallyRemoved.length) {
127
+ return;
128
+ }
129
+ this.onRemove.emit({ names: reallyRemoved });
130
+ }
131
+ /**
132
+ * Removes all fields from the collection, ensuring each is properly destroyed.
133
+ */
134
+ clear() {
135
+ this.remove(Array.from(this._fields.keys()));
136
+ }
137
+ destroy() {
138
+ this.clear();
139
+ this.onAdd.clear();
140
+ this.onRemove.clear();
141
+ }
142
+ }
143
+ //# sourceMappingURL=fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fields.js","sourceRoot":"","sources":["../src/fields.ts"],"names":[],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _axi_engine_utils from '@axi-engine/utils';
2
- import { Constructor, Subscribable, ConstructorRegistry, Emitter, PathType } from '@axi-engine/utils';
2
+ import { Subscribable, ConstructorRegistry, Emitter, Constructor, PathType } from '@axi-engine/utils';
3
3
 
4
4
  interface Policy<T> {
5
5
  readonly id: string;
@@ -75,31 +75,6 @@ declare class Policies<T> {
75
75
  apply(val: T): T;
76
76
  }
77
77
 
78
- /**
79
- * extract field type
80
- */
81
- type GetValueType<TField extends Field<any>> = TField extends Field<infer U> ? U : any;
82
- /**
83
- * A mapped type that creates the method signatures for a typed mixin.
84
- * e.g., createBoolean, upsetBoolean, getBoolean
85
- */
86
- type TypedMethods<TCtor extends Constructor<Field<any>>, TBaseName extends string> = {
87
- [K in `create${TBaseName}`]: (name: string, initialValue: GetValueType<InstanceType<TCtor>>, options?: ConstructorParameters<TCtor>[2]) => InstanceType<TCtor>;
88
- } & {
89
- [K in `upset${TBaseName}`]: (name: string, value: GetValueType<InstanceType<TCtor>>, options?: ConstructorParameters<TCtor>[2]) => InstanceType<TCtor>;
90
- } & {
91
- [K in `get${TBaseName}`]: (name: string) => InstanceType<TCtor>;
92
- };
93
- /**
94
- * A higher-order function that generates a mixin for a specific Field type.
95
- * This factory removes the need to write boilerplate mixin code for every new field type.
96
- *
97
- * @param typeName The `typeName` of the Field to create (e.g., 'boolean', 'my-signal-field').
98
- * @param baseMethodName The base name for the generated methods (e.g., 'Boolean', 'MySignal').
99
- * @returns A fully functional, typed mixin.
100
- */
101
- declare function createTypedMethodsMixin<TCtor extends Constructor<Field<any>>, TBaseName extends string>(typeName: string, baseMethodName: TBaseName): <TBase extends Constructor<Fields>>(Base: TBase) => Constructor<InstanceType<TBase> & TypedMethods<TCtor, TBaseName>>;
102
-
103
78
  interface FieldOptions<T> {
104
79
  policies?: Policy<T>[];
105
80
  }
@@ -132,92 +107,6 @@ interface StringField extends Field<string> {
132
107
  clear(): void;
133
108
  }
134
109
 
135
- /**
136
- * A state container that wraps a value.
137
- * It allows applying a pipeline of transformation or validation "policies" before any new value is set.
138
- *
139
- * @template T The type of the value this field holds.
140
- *
141
- */
142
- declare class CoreField<T> implements Field<T> {
143
- /** A type keyword of the field */
144
- static readonly typeName: string;
145
- readonly typeName: string;
146
- /** A unique identifier for the field. */
147
- private readonly _name;
148
- private _value;
149
- private readonly _onChange;
150
- readonly onChange: Subscribable<[newValue: T, oldvalue: T]>;
151
- readonly policies: Policies<T>;
152
- get name(): string;
153
- /**
154
- * Gets the current raw value of the field.
155
- * For reactive updates, it's recommended to use the `.signal` property instead.
156
- */
157
- get value(): T;
158
- /**
159
- * Sets a new value for the field.
160
- * The provided value will be processed by all registered policies before the underlying signal is updated.
161
- * @param val The new value to set.
162
- */
163
- set value(val: T);
164
- /**
165
- * Creates an instance of a Field.
166
- * @param name A unique identifier for the field.
167
- * @param initialVal The initial value of the field.
168
- * @param options Optional configuration for the field.
169
- * @param options.policies An array of policies to apply to the field's value on every `set` operation.
170
- * @param options.isEqual An function for compare old and new value, by default uses the strictEquals from `utils`
171
- *
172
- */
173
- constructor(name: string, initialVal: T, options?: FieldOptions<T>);
174
- setValueSilently(val: T): void;
175
- batchUpdate(updateFn: (currentValue: T) => T): void;
176
- /**
177
- * Cleans up resources used by the field and its policies.
178
- * This should be called when the field is no longer needed to prevent memory leaks from reactive policies.
179
- */
180
- destroy(): void;
181
- }
182
-
183
- interface CoreBooleanFieldOptions extends FieldOptions<boolean> {
184
- }
185
- declare class CoreBooleanField extends CoreField<boolean> implements BooleanField {
186
- static readonly typeName: string;
187
- readonly typeName: string;
188
- constructor(name: string, initialVal: boolean, options?: CoreBooleanFieldOptions);
189
- toggle(): boolean;
190
- }
191
-
192
- interface CoreStringFieldOptions extends FieldOptions<string> {
193
- }
194
- declare class CoreStringField extends CoreField<string> implements StringField {
195
- static readonly typeName: string;
196
- readonly typeName: string;
197
- constructor(name: string, initialVal: string, options?: CoreStringFieldOptions);
198
- append(str: string | number): this;
199
- prepend(str: string | number): this;
200
- trim(): this;
201
- isEmpty(): boolean;
202
- clear(): void;
203
- }
204
-
205
- interface CoreNumericFieldOptions extends FieldOptions<number> {
206
- min?: number;
207
- max?: number;
208
- }
209
- declare class CoreNumericField extends CoreField<number> implements NumericField {
210
- static readonly typeName: string;
211
- readonly typeName: string;
212
- get min(): number | undefined;
213
- get max(): number | undefined;
214
- constructor(name: string, initialVal: number, options?: CoreNumericFieldOptions);
215
- isMin(): boolean;
216
- isMax(): boolean;
217
- inc(amount?: number): void;
218
- dec(amount?: number): void;
219
- }
220
-
221
110
  declare class FieldRegistry extends ConstructorRegistry<Field<any>> {
222
111
  }
223
112
 
@@ -319,6 +208,117 @@ declare class Fields {
319
208
  destroy(): void;
320
209
  }
321
210
 
211
+ /**
212
+ * extract field type
213
+ */
214
+ type GetValueType<TField extends Field<any>> = TField extends Field<infer U> ? U : any;
215
+ /**
216
+ * A mapped type that creates the method signatures for a typed mixin.
217
+ * e.g., createBoolean, upsetBoolean, getBoolean
218
+ */
219
+ type TypedMethods<TCtor extends Constructor<Field<any>>, TBaseName extends string> = {
220
+ [K in `create${TBaseName}`]: (name: string, initialValue: GetValueType<InstanceType<TCtor>>, options?: ConstructorParameters<TCtor>[2]) => InstanceType<TCtor>;
221
+ } & {
222
+ [K in `upset${TBaseName}`]: (name: string, value: GetValueType<InstanceType<TCtor>>, options?: ConstructorParameters<TCtor>[2]) => InstanceType<TCtor>;
223
+ } & {
224
+ [K in `get${TBaseName}`]: (name: string) => InstanceType<TCtor>;
225
+ };
226
+ /**
227
+ * A higher-order function that generates a mixin for a specific Field type.
228
+ * This factory removes the need to write boilerplate mixin code for every new field type.
229
+ *
230
+ * @param typeName The `typeName` of the Field to create (e.g., 'boolean', 'my-signal-field').
231
+ * @param baseMethodName The base name for the generated methods (e.g., 'Boolean', 'MySignal').
232
+ * @returns A fully functional, typed mixin.
233
+ */
234
+ declare function createTypedMethodsMixin<TCtor extends Constructor<Field<any>>, TBaseName extends string>(typeName: string, baseMethodName: TBaseName): <TBase extends Constructor<Fields>>(Base: TBase) => Constructor<InstanceType<TBase> & TypedMethods<TCtor, TBaseName>>;
235
+
236
+ /**
237
+ * A state container that wraps a value.
238
+ * It allows applying a pipeline of transformation or validation "policies" before any new value is set.
239
+ *
240
+ * @template T The type of the value this field holds.
241
+ *
242
+ */
243
+ declare class CoreField<T> implements Field<T> {
244
+ /** A type keyword of the field */
245
+ static readonly typeName: string;
246
+ readonly typeName: string;
247
+ /** A unique identifier for the field. */
248
+ private readonly _name;
249
+ private _value;
250
+ private readonly _onChange;
251
+ readonly onChange: Subscribable<[newValue: T, oldvalue: T]>;
252
+ readonly policies: Policies<T>;
253
+ get name(): string;
254
+ /**
255
+ * Gets the current raw value of the field.
256
+ * For reactive updates, it's recommended to use the `.signal` property instead.
257
+ */
258
+ get value(): T;
259
+ /**
260
+ * Sets a new value for the field.
261
+ * The provided value will be processed by all registered policies before the underlying signal is updated.
262
+ * @param val The new value to set.
263
+ */
264
+ set value(val: T);
265
+ /**
266
+ * Creates an instance of a Field.
267
+ * @param name A unique identifier for the field.
268
+ * @param initialVal The initial value of the field.
269
+ * @param options Optional configuration for the field.
270
+ * @param options.policies An array of policies to apply to the field's value on every `set` operation.
271
+ * @param options.isEqual An function for compare old and new value, by default uses the strictEquals from `utils`
272
+ *
273
+ */
274
+ constructor(name: string, initialVal: T, options?: FieldOptions<T>);
275
+ setValueSilently(val: T): void;
276
+ batchUpdate(updateFn: (currentValue: T) => T): void;
277
+ /**
278
+ * Cleans up resources used by the field and its policies.
279
+ * This should be called when the field is no longer needed to prevent memory leaks from reactive policies.
280
+ */
281
+ destroy(): void;
282
+ }
283
+
284
+ interface CoreBooleanFieldOptions extends FieldOptions<boolean> {
285
+ }
286
+ declare class CoreBooleanField extends CoreField<boolean> implements BooleanField {
287
+ static readonly typeName: string;
288
+ readonly typeName: string;
289
+ constructor(name: string, initialVal: boolean, options?: CoreBooleanFieldOptions);
290
+ toggle(): boolean;
291
+ }
292
+
293
+ interface CoreStringFieldOptions extends FieldOptions<string> {
294
+ }
295
+ declare class CoreStringField extends CoreField<string> implements StringField {
296
+ static readonly typeName: string;
297
+ readonly typeName: string;
298
+ constructor(name: string, initialVal: string, options?: CoreStringFieldOptions);
299
+ append(str: string | number): this;
300
+ prepend(str: string | number): this;
301
+ trim(): this;
302
+ isEmpty(): boolean;
303
+ clear(): void;
304
+ }
305
+
306
+ interface CoreNumericFieldOptions extends FieldOptions<number> {
307
+ min?: number;
308
+ max?: number;
309
+ }
310
+ declare class CoreNumericField extends CoreField<number> implements NumericField {
311
+ static readonly typeName: string;
312
+ readonly typeName: string;
313
+ get min(): number | undefined;
314
+ get max(): number | undefined;
315
+ constructor(name: string, initialVal: number, options?: CoreNumericFieldOptions);
316
+ isMin(): boolean;
317
+ isMax(): boolean;
318
+ inc(amount?: number): void;
319
+ dec(amount?: number): void;
320
+ }
321
+
322
322
  interface FieldsFactory<TFields extends Fields> {
323
323
  fields(): TFields;
324
324
  }