@bgroup/wise-form 1.0.3 → 1.0.6
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/README.md +1 -1
- package/package.json +23 -4
- package/postcss.config.js +6 -0
- package/src/form/styles.css +11 -37
- package/src/form/view/components/containers/index.tsx +33 -4
- package/src/form/view/components/error.tsx +0 -3
- package/src/form/view/components/field/container.tsx +1 -1
- package/src/form/view/components/field/index.tsx +42 -7
- package/src/form/view/components/rows/row-container.tsx +37 -9
- package/src/form/view/components/rows/wrapper.tsx +17 -6
- package/src/form/view/components/wrapped-form.tsx +38 -5
- package/src/form/view/hooks/use-model.ts +91 -25
- package/src/form/view/index.tsx +32 -6
- package/src/formulas/variants/array-formula.ts +6 -1
- package/src/models/base.ts +31 -5
- package/src/models/callback-manager.ts +169 -91
- package/src/models/field.ts +504 -538
- package/src/models/wrapper.ts +32 -7
- package/tailwind.config.js +11 -0
- package/tsconfig.json +2 -0
- package/vite.config.ts +59 -0
- package/dist/components/ui/Checkbox.d.ts +0 -14
- package/dist/components/ui/Checkbox.d.ts.map +0 -1
- package/dist/components/ui/Checkbox.js +0 -43
- package/dist/components/ui/Checkbox.js.map +0 -1
- package/dist/components/ui/CheckboxGroup.d.ts +0 -15
- package/dist/components/ui/CheckboxGroup.d.ts.map +0 -1
- package/dist/components/ui/CheckboxGroup.js +0 -33
- package/dist/components/ui/CheckboxGroup.js.map +0 -1
- package/dist/components/ui/Input.d.ts +0 -14
- package/dist/components/ui/Input.d.ts.map +0 -1
- package/dist/components/ui/Input.js +0 -49
- package/dist/components/ui/Input.js.map +0 -1
- package/dist/components/ui/Radio.d.ts +0 -14
- package/dist/components/ui/Radio.d.ts.map +0 -1
- package/dist/components/ui/Radio.js +0 -43
- package/dist/components/ui/Radio.js.map +0 -1
- package/dist/components/ui/Select.d.ts +0 -18
- package/dist/components/ui/Select.d.ts.map +0 -1
- package/dist/components/ui/Select.js +0 -44
- package/dist/components/ui/Select.js.map +0 -1
- package/dist/components/ui/Textarea.d.ts +0 -13
- package/dist/components/ui/Textarea.d.ts.map +0 -1
- package/dist/components/ui/Textarea.js +0 -42
- package/dist/components/ui/Textarea.js.map +0 -1
- package/dist/components/ui/index.d.ts +0 -13
- package/dist/components/ui/index.d.ts.map +0 -1
- package/dist/components/ui/index.js +0 -7
- package/dist/components/ui/index.js.map +0 -1
- package/dist/form/index.d.ts +0 -10
- package/dist/form/index.d.ts.map +0 -1
- package/dist/form/index.js +0 -5
- package/dist/form/index.js.map +0 -1
- package/dist/form/interfaces/field-container.d.ts +0 -8
- package/dist/form/interfaces/field-container.d.ts.map +0 -1
- package/dist/form/interfaces/field-container.js +0 -2
- package/dist/form/interfaces/field-container.js.map +0 -1
- package/dist/form/interfaces/interfaces.d.ts +0 -8
- package/dist/form/interfaces/interfaces.d.ts.map +0 -1
- package/dist/form/interfaces/interfaces.js +0 -2
- package/dist/form/interfaces/interfaces.js.map +0 -1
- package/dist/form/interfaces/settings.d.ts +0 -10
- package/dist/form/interfaces/settings.d.ts.map +0 -1
- package/dist/form/interfaces/settings.js +0 -2
- package/dist/form/interfaces/settings.js.map +0 -1
- package/dist/form/interfaces/template.d.ts +0 -6
- package/dist/form/interfaces/template.d.ts.map +0 -1
- package/dist/form/interfaces/template.js +0 -2
- package/dist/form/interfaces/template.js.map +0 -1
- package/dist/form/interfaces/wise-form-specs.d.ts +0 -9
- package/dist/form/interfaces/wise-form-specs.d.ts.map +0 -1
- package/dist/form/interfaces/wise-form-specs.js +0 -2
- package/dist/form/interfaces/wise-form-specs.js.map +0 -1
- package/dist/form/view/components/containers/index.d.ts +0 -3
- package/dist/form/view/components/containers/index.d.ts.map +0 -1
- package/dist/form/view/components/containers/index.js +0 -12
- package/dist/form/view/components/containers/index.js.map +0 -1
- package/dist/form/view/components/error.d.ts +0 -5
- package/dist/form/view/components/error.d.ts.map +0 -1
- package/dist/form/view/components/error.js +0 -8
- package/dist/form/view/components/error.js.map +0 -1
- package/dist/form/view/components/field/container.d.ts +0 -5
- package/dist/form/view/components/field/container.d.ts.map +0 -1
- package/dist/form/view/components/field/container.js +0 -5
- package/dist/form/view/components/field/container.js.map +0 -1
- package/dist/form/view/components/field/index.d.ts +0 -18
- package/dist/form/view/components/field/index.d.ts.map +0 -1
- package/dist/form/view/components/field/index.js +0 -89
- package/dist/form/view/components/field/index.js.map +0 -1
- package/dist/form/view/components/field/selection.d.ts +0 -2
- package/dist/form/view/components/field/selection.d.ts.map +0 -1
- package/dist/form/view/components/field/selection.js +0 -35
- package/dist/form/view/components/field/selection.js.map +0 -1
- package/dist/form/view/components/field/use-field.d.ts +0 -4
- package/dist/form/view/components/field/use-field.d.ts.map +0 -1
- package/dist/form/view/components/field/use-field.js +0 -41
- package/dist/form/view/components/field/use-field.js.map +0 -1
- package/dist/form/view/components/rows/row-container.d.ts +0 -18
- package/dist/form/view/components/rows/row-container.d.ts.map +0 -1
- package/dist/form/view/components/rows/row-container.js +0 -89
- package/dist/form/view/components/rows/row-container.js.map +0 -1
- package/dist/form/view/components/rows/wrapper.d.ts +0 -12
- package/dist/form/view/components/rows/wrapper.d.ts.map +0 -1
- package/dist/form/view/components/rows/wrapper.js +0 -27
- package/dist/form/view/components/rows/wrapper.js.map +0 -1
- package/dist/form/view/components/wrapped-form.d.ts +0 -6
- package/dist/form/view/components/wrapped-form.d.ts.map +0 -1
- package/dist/form/view/components/wrapped-form.js +0 -26
- package/dist/form/view/components/wrapped-form.js.map +0 -1
- package/dist/form/view/context.d.ts +0 -23
- package/dist/form/view/context.d.ts.map +0 -1
- package/dist/form/view/context.js +0 -7
- package/dist/form/view/context.js.map +0 -1
- package/dist/form/view/hooks/use-model.d.ts +0 -10
- package/dist/form/view/hooks/use-model.d.ts.map +0 -1
- package/dist/form/view/hooks/use-model.js +0 -31
- package/dist/form/view/hooks/use-model.js.map +0 -1
- package/dist/form/view/hooks/use-template.d.ts +0 -14
- package/dist/form/view/hooks/use-template.d.ts.map +0 -1
- package/dist/form/view/hooks/use-template.js +0 -57
- package/dist/form/view/hooks/use-template.js.map +0 -1
- package/dist/form/view/hooks/use-types.d.ts +0 -2
- package/dist/form/view/hooks/use-types.d.ts.map +0 -1
- package/dist/form/view/hooks/use-types.js +0 -19
- package/dist/form/view/hooks/use-types.js.map +0 -1
- package/dist/form/view/index.d.ts +0 -3
- package/dist/form/view/index.d.ts.map +0 -1
- package/dist/form/view/index.js +0 -38
- package/dist/form/view/index.js.map +0 -1
- package/dist/formulas/helpers/condition-types.d.ts +0 -5
- package/dist/formulas/helpers/condition-types.d.ts.map +0 -1
- package/dist/formulas/helpers/condition-types.js +0 -5
- package/dist/formulas/helpers/condition-types.js.map +0 -1
- package/dist/formulas/helpers/evaluations.d.ts +0 -15
- package/dist/formulas/helpers/evaluations.d.ts.map +0 -1
- package/dist/formulas/helpers/evaluations.js +0 -44
- package/dist/formulas/helpers/evaluations.js.map +0 -1
- package/dist/formulas/helpers/formula.d.ts +0 -6
- package/dist/formulas/helpers/formula.d.ts.map +0 -1
- package/dist/formulas/helpers/formula.js +0 -26
- package/dist/formulas/helpers/formula.js.map +0 -1
- package/dist/formulas/helpers/lexer.d.ts +0 -10
- package/dist/formulas/helpers/lexer.d.ts.map +0 -1
- package/dist/formulas/helpers/lexer.js +0 -73
- package/dist/formulas/helpers/lexer.js.map +0 -1
- package/dist/formulas/helpers/parser.d.ts +0 -24
- package/dist/formulas/helpers/parser.d.ts.map +0 -1
- package/dist/formulas/helpers/parser.js +0 -48
- package/dist/formulas/helpers/parser.js.map +0 -1
- package/dist/formulas/helpers/token.d.ts +0 -14
- package/dist/formulas/helpers/token.d.ts.map +0 -1
- package/dist/formulas/helpers/token.js +0 -14
- package/dist/formulas/helpers/token.js.map +0 -1
- package/dist/formulas/index.d.ts +0 -59
- package/dist/formulas/index.d.ts.map +0 -1
- package/dist/formulas/index.js +0 -186
- package/dist/formulas/index.js.map +0 -1
- package/dist/formulas/types/formulas.d.ts +0 -68
- package/dist/formulas/types/formulas.d.ts.map +0 -1
- package/dist/formulas/types/formulas.js +0 -2
- package/dist/formulas/types/formulas.js.map +0 -1
- package/dist/formulas/types/index.d.ts +0 -5
- package/dist/formulas/types/index.d.ts.map +0 -1
- package/dist/formulas/types/index.js +0 -2
- package/dist/formulas/types/index.js.map +0 -1
- package/dist/formulas/variants/array-formula.d.ts +0 -24
- package/dist/formulas/variants/array-formula.d.ts.map +0 -1
- package/dist/formulas/variants/array-formula.js +0 -142
- package/dist/formulas/variants/array-formula.js.map +0 -1
- package/dist/formulas/variants/base.d.ts +0 -6
- package/dist/formulas/variants/base.d.ts.map +0 -1
- package/dist/formulas/variants/base.js +0 -3
- package/dist/formulas/variants/base.js.map +0 -1
- package/dist/formulas/variants/basic.d.ts +0 -18
- package/dist/formulas/variants/basic.d.ts.map +0 -1
- package/dist/formulas/variants/basic.js +0 -128
- package/dist/formulas/variants/basic.js.map +0 -1
- package/dist/formulas/variants/comparison.d.ts +0 -25
- package/dist/formulas/variants/comparison.d.ts.map +0 -1
- package/dist/formulas/variants/comparison.js +0 -153
- package/dist/formulas/variants/comparison.js.map +0 -1
- package/dist/formulas/variants/conditional.d.ts +0 -18
- package/dist/formulas/variants/conditional.d.ts.map +0 -1
- package/dist/formulas/variants/conditional.js +0 -183
- package/dist/formulas/variants/conditional.js.map +0 -1
- package/dist/formulas/variants/iterative-array.d.ts +0 -20
- package/dist/formulas/variants/iterative-array.d.ts.map +0 -1
- package/dist/formulas/variants/iterative-array.js +0 -155
- package/dist/formulas/variants/iterative-array.js.map +0 -1
- package/dist/formulas/variants/per-value.d.ts +0 -20
- package/dist/formulas/variants/per-value.d.ts.map +0 -1
- package/dist/formulas/variants/per-value.js +0 -154
- package/dist/formulas/variants/per-value.js.map +0 -1
- package/dist/index.d.ts +0 -5
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -6
- package/dist/index.js.map +0 -1
- package/dist/models/base.d.ts +0 -55
- package/dist/models/base.d.ts.map +0 -1
- package/dist/models/base.js +0 -146
- package/dist/models/base.js.map +0 -1
- package/dist/models/callback-manager.d.ts +0 -7
- package/dist/models/callback-manager.d.ts.map +0 -1
- package/dist/models/callback-manager.js +0 -89
- package/dist/models/callback-manager.js.map +0 -1
- package/dist/models/field.d.ts +0 -121
- package/dist/models/field.d.ts.map +0 -1
- package/dist/models/field.js +0 -515
- package/dist/models/field.js.map +0 -1
- package/dist/models/index.d.ts +0 -13
- package/dist/models/index.d.ts.map +0 -1
- package/dist/models/index.js +0 -7
- package/dist/models/index.js.map +0 -1
- package/dist/models/model.d.ts +0 -37
- package/dist/models/model.d.ts.map +0 -1
- package/dist/models/model.js +0 -245
- package/dist/models/model.js.map +0 -1
- package/dist/models/plugins/base.d.ts +0 -9
- package/dist/models/plugins/base.d.ts.map +0 -1
- package/dist/models/plugins/base.js +0 -3
- package/dist/models/plugins/base.js.map +0 -1
- package/dist/models/plugins/formula.d.ts +0 -18
- package/dist/models/plugins/formula.d.ts.map +0 -1
- package/dist/models/plugins/formula.js +0 -82
- package/dist/models/plugins/formula.js.map +0 -1
- package/dist/models/plugins/index.d.ts +0 -11
- package/dist/models/plugins/index.d.ts.map +0 -1
- package/dist/models/plugins/index.js +0 -52
- package/dist/models/plugins/index.js.map +0 -1
- package/dist/models/plugins/plugins.d.ts +0 -7
- package/dist/models/plugins/plugins.d.ts.map +0 -1
- package/dist/models/plugins/plugins.js +0 -7
- package/dist/models/plugins/plugins.js.map +0 -1
- package/dist/models/types/base-wise-model.d.ts +0 -7
- package/dist/models/types/base-wise-model.d.ts.map +0 -1
- package/dist/models/types/base-wise-model.js +0 -2
- package/dist/models/types/base-wise-model.js.map +0 -1
- package/dist/models/types/callbacks.d.ts +0 -19
- package/dist/models/types/callbacks.d.ts.map +0 -1
- package/dist/models/types/callbacks.js +0 -2
- package/dist/models/types/callbacks.js.map +0 -1
- package/dist/models/types/disabled.d.ts +0 -8
- package/dist/models/types/disabled.d.ts.map +0 -1
- package/dist/models/types/disabled.js +0 -2
- package/dist/models/types/disabled.js.map +0 -1
- package/dist/models/types/form-field.d.ts +0 -25
- package/dist/models/types/form-field.d.ts.map +0 -1
- package/dist/models/types/form-field.js +0 -2
- package/dist/models/types/form-field.js.map +0 -1
- package/dist/models/types/model.d.ts +0 -13
- package/dist/models/types/model.d.ts.map +0 -1
- package/dist/models/types/model.js +0 -2
- package/dist/models/types/model.js.map +0 -1
- package/dist/models/types/plugins.d.ts +0 -13
- package/dist/models/types/plugins.d.ts.map +0 -1
- package/dist/models/types/plugins.js +0 -2
- package/dist/models/types/plugins.js.map +0 -1
- package/dist/models/types/wrapped-form-model-props.d.ts +0 -11
- package/dist/models/types/wrapped-form-model-props.d.ts.map +0 -1
- package/dist/models/types/wrapped-form-model-props.js +0 -2
- package/dist/models/types/wrapped-form-model-props.js.map +0 -1
- package/dist/models/wrapper.d.ts +0 -30
- package/dist/models/wrapper.d.ts.map +0 -1
- package/dist/models/wrapper.js +0 -213
- package/dist/models/wrapper.js.map +0 -1
- package/dist/settings/index.d.ts +0 -7
- package/dist/settings/index.d.ts.map +0 -1
- package/dist/settings/index.js +0 -26
- package/dist/settings/index.js.map +0 -1
- package/dist/utils/pending-promise.d.ts +0 -6
- package/dist/utils/pending-promise.d.ts.map +0 -1
- package/dist/utils/pending-promise.js +0 -24
- package/dist/utils/pending-promise.js.map +0 -1
package/src/models/base.ts
CHANGED
|
@@ -100,28 +100,54 @@ export class BaseWiseModel extends ReactiveModel<IBaseWiseModel> {
|
|
|
100
100
|
/**
|
|
101
101
|
* Retrieves a field or nested wrapper by name. Supports dot notation for accessing deeply nested fields.
|
|
102
102
|
* @param {string} name - The name of the field or nested wrapper to retrieve.
|
|
103
|
+
* @param {Set<BaseWiseModel | WrappedFormModel>} visited - Set of already visited models to prevent infinite recursion.
|
|
103
104
|
* @returns {FormField | WrappedFormModel | undefined} The requested instance, or undefined if not found.
|
|
104
105
|
*/
|
|
105
|
-
getField(name: string) {
|
|
106
|
-
if (!name)
|
|
106
|
+
getField(name: string, visited: Set<BaseWiseModel | WrappedFormModel> = new Set()) {
|
|
107
|
+
if (!name) {
|
|
108
|
+
console.warn('[WiseForm.getField] Empty field name provided in form', this.#settings.name);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Protección contra recursión circular
|
|
113
|
+
if (visited.has(this)) {
|
|
114
|
+
console.error(
|
|
115
|
+
`[WiseForm.getField] Circular reference detected in form "${this.#settings.name}" while searching for field "${name}". This usually indicates a configuration issue with nested wrappers.`
|
|
116
|
+
);
|
|
117
|
+
console.log(
|
|
118
|
+
`[WiseForm.getField] PROTECTION ACTIVE: Circular reference prevented. Form: "${this.#settings.name}", Field: "${name}", Visited models count: ${visited.size}`
|
|
119
|
+
);
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
visited.add(this);
|
|
107
123
|
|
|
108
124
|
if (!name.includes('.')) {
|
|
109
125
|
let field = this.#fields.get(name);
|
|
110
126
|
|
|
111
127
|
if (!field) {
|
|
112
128
|
this.#wrappers.forEach(item => {
|
|
113
|
-
|
|
114
|
-
|
|
129
|
+
if (!visited.has(item)) {
|
|
130
|
+
const foundField = item.getField(name, visited);
|
|
131
|
+
if (foundField) field = foundField;
|
|
132
|
+
}
|
|
115
133
|
});
|
|
116
134
|
}
|
|
117
135
|
return field;
|
|
118
136
|
}
|
|
119
137
|
|
|
138
|
+
// Dot notation path
|
|
120
139
|
const [wrapperName, ...others] = name.split('.');
|
|
121
140
|
const currentWrapper = this.#wrappers.get(wrapperName);
|
|
122
141
|
|
|
142
|
+
if (!currentWrapper) {
|
|
143
|
+
console.warn(
|
|
144
|
+
`[WiseForm.getField] Wrapper "${wrapperName}" not found in form "${this.#settings.name}" while searching for "${name}". Available wrappers: ${Array.from(this.#wrappers.keys()).join(', ') || 'none'}`
|
|
145
|
+
);
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
|
|
123
149
|
const otherWrapper = others.join('.');
|
|
124
|
-
return currentWrapper.getField(otherWrapper);
|
|
150
|
+
return currentWrapper.getField(otherWrapper, visited);
|
|
125
151
|
}
|
|
126
152
|
|
|
127
153
|
/**
|
|
@@ -2,101 +2,179 @@ import type { FormField } from './field';
|
|
|
2
2
|
import type { FormModel } from './model';
|
|
3
3
|
import { CallbackFunction, ICallbackProps } from './types/callbacks';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Maximum number of recursive executions allowed for a callback before preventing further execution.
|
|
7
|
+
* This can be overridden if specific use cases require a higher limit.
|
|
8
|
+
*/
|
|
9
|
+
export const MAX_CALLBACK_RECURSION_DEPTH = 3;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Map to track callback execution depth per unique execution context.
|
|
13
|
+
* Key format: "callbackName:fieldName:dependencyName" or "callbackName:fieldName" if no dependency
|
|
14
|
+
*/
|
|
15
|
+
const callbackExecutionDepth = new Map<string, number>();
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Set to track callbacks currently executing (prevents concurrent executions of the same callback)
|
|
19
|
+
*/
|
|
20
|
+
const currentlyExecutingCallbacks = new Set<string>();
|
|
21
|
+
|
|
5
22
|
export class CallbackManager {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
23
|
+
#field: FormField;
|
|
24
|
+
#model: FormModel;
|
|
25
|
+
#callbacks: CallbackFunction[] = [];
|
|
26
|
+
#listeners = [];
|
|
27
|
+
constructor(model, field) {
|
|
28
|
+
this.#field = field;
|
|
29
|
+
this.#model = model;
|
|
30
|
+
this.#callbacks = model.callbacks;
|
|
31
|
+
this.initialize();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
initialize() {
|
|
35
|
+
const instance = this.#field;
|
|
36
|
+
const checkField = async settings => {
|
|
37
|
+
const dependency = this.#model.getField(this.#model.getFieldName(settings.field));
|
|
38
|
+
await dependency.isReady;
|
|
39
|
+
const required = ['field', 'callback'];
|
|
40
|
+
required.forEach(prop => {
|
|
41
|
+
if (!settings[prop]) throw new Error(`${settings?.field} is missing ${prop}`);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
if (!dependency) throw new Error(`${settings?.field} is not a registered field`);
|
|
45
|
+
|
|
46
|
+
if (!this.#callbacks[settings.callback]) {
|
|
47
|
+
throw new Error(`${settings.callback} is not a registered callback ${settings.name}`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// saved in listener array to be able to remove the listener if is required.
|
|
51
|
+
const event = settings.event || 'value.change';
|
|
52
|
+
const caller = () => this.executeCallback(settings);
|
|
53
|
+
this.#listeners.push(caller);
|
|
54
|
+
dependency.on(event, caller);
|
|
55
|
+
|
|
56
|
+
//callback({ dependency, settings, field: instance, form: this });
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
instance?.specs?.dependentOn.forEach(checkField);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Generates a unique execution key for tracking callback recursion.
|
|
64
|
+
* Format: "callbackName:fieldName:dependencyName"
|
|
65
|
+
*/
|
|
66
|
+
#getExecutionKey(callbackName: string, fieldName: string, dependencyName?: string): string {
|
|
67
|
+
const fieldNameStr = fieldName || 'unknown';
|
|
68
|
+
const dependencyNameStr = dependencyName || 'unknown';
|
|
69
|
+
return `${callbackName}:${fieldNameStr}:${dependencyNameStr}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
executeCallback = async settings => {
|
|
73
|
+
if (!settings) {
|
|
74
|
+
console.warn('the field does not have dependentOn settings');
|
|
75
|
+
return;
|
|
15
76
|
}
|
|
16
77
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
this.#model.getFieldName(settings.field)
|
|
22
|
-
);
|
|
23
|
-
await dependency.isReady;
|
|
24
|
-
const required = ['field', 'callback'];
|
|
25
|
-
required.forEach((prop) => {
|
|
26
|
-
if (!settings[prop])
|
|
27
|
-
throw new Error(`${settings?.field} is missing ${prop}`);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
if (!dependency)
|
|
31
|
-
throw new Error(`${settings?.field} is not a registered field`);
|
|
32
|
-
|
|
33
|
-
if (!this.#callbacks[settings.callback]) {
|
|
34
|
-
throw new Error(
|
|
35
|
-
`${settings.callback} is not a registered callback ${settings.name}`
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// saved in listener array to be able to remove the listener if is required.
|
|
40
|
-
const event = settings.event || 'value.change';
|
|
41
|
-
const caller = () => this.executeCallback(settings);
|
|
42
|
-
this.#listeners.push(caller);
|
|
43
|
-
dependency.on(event, caller);
|
|
44
|
-
|
|
45
|
-
//callback({ dependency, settings, field: instance, form: this });
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
instance?.specs?.dependentOn.forEach(checkField);
|
|
78
|
+
const callbackName = settings.callback;
|
|
79
|
+
if (!callbackName) {
|
|
80
|
+
console.warn('[CallbackManager] executeCallback called without callback name in settings');
|
|
81
|
+
return;
|
|
49
82
|
}
|
|
50
83
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
84
|
+
const fieldName = (this.#field as { name?: string })?.name || 'unknown';
|
|
85
|
+
const dependencyFieldName = typeof settings.field === 'string' ? settings.field : settings.field?.field || 'unknown';
|
|
86
|
+
|
|
87
|
+
const executionKey = this.#getExecutionKey(callbackName, fieldName, dependencyFieldName);
|
|
88
|
+
|
|
89
|
+
// Check if already executing (prevent concurrent executions)
|
|
90
|
+
if (currentlyExecutingCallbacks.has(executionKey)) {
|
|
91
|
+
console.warn(
|
|
92
|
+
`[CallbackManager] Callback "${callbackName}" is already executing for field "${fieldName}" with dependency "${dependencyFieldName}". Skipping concurrent execution.`
|
|
93
|
+
);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Check recursion depth
|
|
98
|
+
const currentDepth = callbackExecutionDepth.get(executionKey) || 0;
|
|
99
|
+
const maxDepth = settings.maxRecursionDepth !== undefined ? settings.maxRecursionDepth : MAX_CALLBACK_RECURSION_DEPTH;
|
|
100
|
+
|
|
101
|
+
if (currentDepth >= maxDepth) {
|
|
102
|
+
console.error(
|
|
103
|
+
`[CallbackManager] RECURSION DETECTED: Callback "${callbackName}" exceeded maximum recursion depth of ${maxDepth}`,
|
|
104
|
+
`\n Field: ${fieldName}`,
|
|
105
|
+
`\n Dependency: ${dependencyFieldName}`,
|
|
106
|
+
`\n Current depth: ${currentDepth + 1}`,
|
|
107
|
+
`\n Execution key: ${executionKey}`,
|
|
108
|
+
`\n This indicates a circular dependency in callbacks. Please review the form configuration.`
|
|
109
|
+
);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Mark as currently executing and increment depth
|
|
114
|
+
currentlyExecutingCallbacks.add(executionKey);
|
|
115
|
+
callbackExecutionDepth.set(executionKey, currentDepth + 1);
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
const params: ICallbackProps = {
|
|
119
|
+
...settings,
|
|
120
|
+
form: this.#model,
|
|
121
|
+
field: this.#field,
|
|
122
|
+
settings,
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const callback: CallbackFunction = this.#callbacks[callbackName];
|
|
126
|
+
|
|
127
|
+
if (!callback) {
|
|
128
|
+
console.error(`[CallbackManager] Callback "${callbackName}" not found in registered callbacks`);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const dependency = this.#model.getField(this.#model.getFieldName(settings.field));
|
|
133
|
+
await dependency.isReady;
|
|
134
|
+
const fields = { [dependency.name]: dependency };
|
|
135
|
+
if (settings.hasOwnProperty('fields')) {
|
|
136
|
+
for (const field of settings.fields) {
|
|
137
|
+
const instance = this.#model.getField(this.#model.getFieldName(field));
|
|
138
|
+
if (instance) await instance.isReady;
|
|
139
|
+
const propName = typeof field === 'string' ? field : field.alias;
|
|
140
|
+
fields[propName] = instance;
|
|
98
141
|
}
|
|
99
|
-
callback(params);
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
142
|
|
|
143
|
+
params.fields = fields;
|
|
144
|
+
}
|
|
145
|
+
params.dependency = dependency;
|
|
146
|
+
|
|
147
|
+
//global wiseForm params
|
|
148
|
+
if (settings.hasOwnProperty('params')) {
|
|
149
|
+
const specs = {};
|
|
150
|
+
settings.params.forEach(param => {
|
|
151
|
+
if (!this.#model?.getParams(param)) {
|
|
152
|
+
console.warn(`param ${param} is not registered in the form`);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
specs[param] = this.#model.getParams(param);
|
|
157
|
+
});
|
|
158
|
+
params.specs = specs;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Execute the callback (handle both sync and async callbacks)
|
|
162
|
+
const result = callback(params) as any;
|
|
163
|
+
if (result && typeof result.then === 'function') {
|
|
164
|
+
await result;
|
|
165
|
+
}
|
|
166
|
+
} catch (error) {
|
|
167
|
+
console.error(`[CallbackManager] Error executing callback "${callbackName}":`, error);
|
|
168
|
+
} finally {
|
|
169
|
+
// Clean up execution tracking
|
|
170
|
+
currentlyExecutingCallbacks.delete(executionKey);
|
|
171
|
+
|
|
172
|
+
const finalDepth = callbackExecutionDepth.get(executionKey) || 0;
|
|
173
|
+
if (finalDepth <= 1) {
|
|
174
|
+
callbackExecutionDepth.delete(executionKey);
|
|
175
|
+
} else {
|
|
176
|
+
callbackExecutionDepth.set(executionKey, finalDepth - 1);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
}
|