@bolttech/form-engine-core 1.0.0-beta.10 → 1.0.0-beta.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Subject, Subscription, combineLatest, startWith, groupBy, mergeMap, debounceTime, filter, map, distinctUntilKeyChanged, distinctUntilChanged, skip } from 'rxjs';
1
+ import { Subject, Subscription, groupBy, mergeMap, debounceTime, filter, combineLatest, startWith, map, distinctUntilKeyChanged, distinctUntilChanged, skip } from 'rxjs';
2
2
  import creditCardType from 'credit-card-type';
3
3
  import { isNumber as isNumber$1, isFunction, cloneDeep, merge, isEqual, get, isNil, set } from 'lodash';
4
4
  import { getCurrencySymbol } from '@gaignoux/currency';
@@ -50,7 +50,7 @@ const TEMPLATE_REGEX_STRING_CONCATENATION_DETECTOR = /^\$\{(?:[^{}]|\{(?:[^{}]|\
50
50
  const TEMPLATE_REGEX_DELIMITATOR = /\$\{((?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*)\}/g;
51
51
  const TEMPLATE_REGEX_OPERATOR_SPLITTER = /\s*(\|\||&&|!)\s*/g;
52
52
  const TEMPLATE_REGEX_OPERATOR_MATCHER = /^\|\||&&|!$/;
53
- const TEMPLATE_AVALIABLE_SCOPES = ['fields', 'iVars'];
53
+ const TEMPLATE_AVALIABLE_SCOPES = ['fields', 'iVars', 'form'];
54
54
  const ALLOWED_RESET_PROPS_MUTATIONS = ['api', 'apiSchema', 'props', 'validations', 'visibilityConditions', 'resetValues'];
55
55
  const DEFAULT_LOG_VERBOSE = false;
56
56
 
@@ -2495,7 +2495,7 @@ class FormField {
2495
2495
  templateSubject$,
2496
2496
  fieldEventSubject$,
2497
2497
  dataSubject$,
2498
- formValidNotification$,
2498
+ fieldValidNotification$,
2499
2499
  mountSubject$,
2500
2500
  mapper,
2501
2501
  getFormValues,
@@ -2535,7 +2535,7 @@ class FormField {
2535
2535
  this.templateSubject$ = templateSubject$;
2536
2536
  this.fieldEventSubject$ = fieldEventSubject$;
2537
2537
  this.dataSubject$ = dataSubject$;
2538
- this.formValidNotification$ = formValidNotification$;
2538
+ this.fieldValidNotification$ = fieldValidNotification$;
2539
2539
  this.mountSubject$ = mountSubject$;
2540
2540
  this._props = FormField.filterProps(cloneDeep(schemaComponent.props || {}));
2541
2541
  this._metadata = '';
@@ -2554,11 +2554,14 @@ class FormField {
2554
2554
  status: null
2555
2555
  };
2556
2556
  return acc;
2557
- }, {})
2557
+ }, {}),
2558
+ apiState: {
2559
+ loading: false
2560
+ }
2558
2561
  };
2559
2562
  this._errors = {};
2560
2563
  this._mounted = false;
2561
- this._valid = true;
2564
+ this.valid = true;
2562
2565
  this.initializeObservers();
2563
2566
  }
2564
2567
  /**
@@ -2567,7 +2570,6 @@ class FormField {
2567
2570
  * emissions to unsubscribed fields
2568
2571
  */
2569
2572
  initializeObservers() {
2570
- var _a;
2571
2573
  if (!this.valueSubject$ || this.valueSubject$.closed) {
2572
2574
  this.valueSubject$ = new SafeSubject(() => this.mounted);
2573
2575
  }
@@ -2577,9 +2579,6 @@ class FormField {
2577
2579
  if (!this.visibilitySubject$ || this.visibilitySubject$.closed) {
2578
2580
  this.visibilitySubject$ = new SafeSubject(() => this.mounted);
2579
2581
  }
2580
- if (!this.apiSubject$ || this.apiSubject$.closed) {
2581
- this.apiSubject$ = new SafeSubject(() => this.mounted);
2582
- }
2583
2582
  if (!this.propsSubject$ || this.propsSubject$.closed) {
2584
2583
  this.propsSubject$ = new SafeSubject(() => this.mounted);
2585
2584
  }
@@ -2589,16 +2588,9 @@ class FormField {
2589
2588
  if (!this.apiEventQueueSubject$ || this.apiEventQueueSubject$.closed) {
2590
2589
  this.apiEventQueueSubject$ = new SafeSubject(() => this.mounted);
2591
2590
  }
2592
- this.fieldState$ = combineLatest({
2593
- visibility: this.visibilitySubject$.pipe(startWith(this._visibility)),
2594
- props: this.propsSubject$.pipe(startWith(this._props)),
2595
- errors: this.errorSubject$.pipe(startWith(Object.assign({}, ((_a = this.mapper.events) === null || _a === void 0 ? void 0 : _a.setErrorMessage) && {
2596
- [this.mapper.events.setErrorMessage]: this.errorsString
2597
- })))
2598
- });
2599
2591
  !this.apiEventQueueSubject$.observed && this.apiEventQueueSubject$.pipe(groupBy(({
2600
2592
  event
2601
- }) => event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultAPIdebounceTimeMS))), filter(() => this.apiSubject$ && !this.apiSubject$.closed)).subscribe(payload => {
2593
+ }) => event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultAPIdebounceTimeMS))), filter(() => this.apiEventQueueSubject$ && !this.apiEventQueueSubject$.closed)).subscribe(payload => {
2602
2594
  this.apiRequest(payload);
2603
2595
  });
2604
2596
  }
@@ -2739,12 +2731,11 @@ class FormField {
2739
2731
  * sets valid field state and notifies form instance via formValidNotification$
2740
2732
  */
2741
2733
  set valid(valid) {
2742
- if (this._valid !== valid) {
2743
- this._valid = valid;
2744
- this.formValidNotification$.next({
2745
- fieldTrigger: this.name
2746
- });
2747
- }
2734
+ if (typeof valid !== 'boolean' && this.valid === valid) return;
2735
+ this._valid = valid;
2736
+ this.fieldValidNotification$.next({
2737
+ fieldTrigger: this.name
2738
+ });
2748
2739
  }
2749
2740
  /**
2750
2741
  * Retrieves the validity status of the form field.
@@ -2799,13 +2790,12 @@ class FormField {
2799
2790
  * @param {TApiResponse} response - The new API response data to be set.
2800
2791
  */
2801
2792
  set api(response) {
2802
- if (typeof response === 'undefined' || isEqual(response, this.api)) return;
2793
+ if (typeof response === 'undefined') return;
2803
2794
  this._api = response;
2804
- this.apiSubject$.next(this.api);
2805
2795
  this.templateSubject$.next({
2806
2796
  scope: 'fields',
2807
2797
  key: this.name,
2808
- event: 'ON_API'
2798
+ event: 'ON_API_RESPONSE'
2809
2799
  });
2810
2800
  // this.apiResponseSubject$.next({ key: this.name });
2811
2801
  this.emitEvents({
@@ -2813,7 +2803,20 @@ class FormField {
2813
2803
  });
2814
2804
  }
2815
2805
  /**
2816
- * Retrieves the mounted status of the field.
2806
+ * notifies templates and event binded field configurations that a request starts it's processing
2807
+ */
2808
+ notifyApiRequest() {
2809
+ this._api.apiState.loading = true;
2810
+ this.templateSubject$.next({
2811
+ scope: 'fields',
2812
+ key: this.name,
2813
+ event: 'ON_API_REQUEST'
2814
+ });
2815
+ this.emitEvents({
2816
+ event: 'ON_API_FIELD_REQUEST'
2817
+ });
2818
+ }
2819
+ /** Retrieves the mounted status of the field.
2817
2820
  *
2818
2821
  * @returns {boolean} - the mounted status of the field.
2819
2822
  */
@@ -3009,6 +3012,7 @@ class FormField {
3009
3012
  }) {
3010
3013
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
3011
3014
  return __awaiter(this, void 0, void 0, function* () {
3015
+ let requestMadeOnce = false;
3012
3016
  const configRequest = config => __awaiter(this, void 0, void 0, function* () {
3013
3017
  var _k;
3014
3018
  try {
@@ -3034,20 +3038,23 @@ class FormField {
3034
3038
  };
3035
3039
  }
3036
3040
  });
3037
- if (!((_b = (_a = this.apiSchema) === null || _a === void 0 ? void 0 : _a.defaultConfig) === null || _b === void 0 ? void 0 : _b.events.includes(event)) && !(((_c = this.apiSchema) === null || _c === void 0 ? void 0 : _c.configs) && Object.keys((_d = this.apiSchema) === null || _d === void 0 ? void 0 : _d.configs).some(key => {
3041
+ if (this.api.apiState.lastEvent === 'ON_API_FIELD_RESPONSE' && event === 'ON_API_FIELD_RESPONSE' || !((_b = (_a = this.apiSchema) === null || _a === void 0 ? void 0 : _a.defaultConfig) === null || _b === void 0 ? void 0 : _b.events.includes(event)) && !(((_c = this.apiSchema) === null || _c === void 0 ? void 0 : _c.configs) && Object.keys((_d = this.apiSchema) === null || _d === void 0 ? void 0 : _d.configs).some(key => {
3038
3042
  var _a, _b;
3039
3043
  return (_b = (_a = this.apiSchema) === null || _a === void 0 ? void 0 : _a.configs) === null || _b === void 0 ? void 0 : _b[key].events.includes(event);
3040
3044
  }))) return;
3041
3045
  const responses = {
3042
3046
  default: Object.assign({}, this.api.default),
3043
- named: Object.assign({}, this.api.named)
3047
+ named: Object.assign({}, this.api.named),
3048
+ apiState: Object.assign({}, this.api.apiState)
3044
3049
  };
3045
3050
  const config = (_e = this.apiSchema.defaultConfig) === null || _e === void 0 ? void 0 : _e.config;
3046
3051
  if (config && ((_g = (_f = this.apiSchema) === null || _f === void 0 ? void 0 : _f.defaultConfig) === null || _g === void 0 ? void 0 : _g.events.includes(event)) && this.checkApiRequestValidations(config)) {
3052
+ !requestMadeOnce && this.notifyApiRequest();
3047
3053
  const {
3048
3054
  response,
3049
3055
  status
3050
3056
  } = yield configRequest(config);
3057
+ requestMadeOnce = true;
3051
3058
  responses.default = {
3052
3059
  response,
3053
3060
  status
@@ -3065,10 +3072,12 @@ class FormField {
3065
3072
  var _l, _m, _o, _p;
3066
3073
  const config = (_m = (_l = this.apiSchema) === null || _l === void 0 ? void 0 : _l.configs) === null || _m === void 0 ? void 0 : _m[configKey].config;
3067
3074
  if (config && ((_p = (_o = this.apiSchema) === null || _o === void 0 ? void 0 : _o.configs) === null || _p === void 0 ? void 0 : _p[configKey].events.includes(event)) && this.checkApiRequestValidations(config)) {
3075
+ !requestMadeOnce && this.notifyApiRequest();
3068
3076
  const {
3069
3077
  response,
3070
3078
  status
3071
3079
  } = yield configRequest(config);
3080
+ requestMadeOnce = true;
3072
3081
  return {
3073
3082
  name: configKey,
3074
3083
  result: {
@@ -3084,7 +3093,11 @@ class FormField {
3084
3093
  });
3085
3094
  }
3086
3095
  }
3087
- this.api = responses;
3096
+ if (requestMadeOnce) {
3097
+ responses.apiState.lastEvent = event;
3098
+ responses.apiState.loading = false;
3099
+ this.api = responses;
3100
+ }
3088
3101
  });
3089
3102
  }
3090
3103
  /**
@@ -3099,9 +3112,8 @@ class FormField {
3099
3112
  this.fieldStateSubscription$.unsubscribe();
3100
3113
  this.propsSubject$.unsubscribe();
3101
3114
  this.errorSubject$.unsubscribe();
3102
- this.apiSubject$.unsubscribe();
3103
3115
  this.apiEventQueueSubject$.unsubscribe();
3104
- !this.formValidNotification$.closed && this.formValidNotification$.next({
3116
+ !this.fieldValidNotification$.closed && this.fieldValidNotification$.next({
3105
3117
  fieldTrigger: this.name
3106
3118
  });
3107
3119
  }
@@ -3112,7 +3124,14 @@ class FormField {
3112
3124
  * @returns {void}
3113
3125
  */
3114
3126
  subscribeState(callback) {
3115
- this.fieldStateSubscription$ = this.fieldState$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS)).subscribe({
3127
+ var _a;
3128
+ this.fieldStateSubscription$ = combineLatest({
3129
+ visibility: this.visibilitySubject$.pipe(startWith(this.visibility)),
3130
+ props: this.propsSubject$.pipe(startWith(this.props)),
3131
+ errors: this.errorSubject$.pipe(startWith(Object.assign({}, ((_a = this.mapper.events) === null || _a === void 0 ? void 0 : _a.setErrorMessage) && {
3132
+ [this.mapper.events.setErrorMessage]: this.errorsString
3133
+ })))
3134
+ }).pipe(debounceTime(this.config.defaultStateRefreshTimeMS)).subscribe({
3116
3135
  next: callback
3117
3136
  });
3118
3137
  }
@@ -3152,6 +3171,8 @@ class FormCore {
3152
3171
  this.queuedFieldResetValuesEvents = new Map();
3153
3172
  this.queuedFieldResetPropertyEvents = new Map();
3154
3173
  this.queuedInitialValues = new Map();
3174
+ this._valid = false;
3175
+ this.index = entry.index;
3155
3176
  this.schema = entry.schema;
3156
3177
  this.fields = new Map();
3157
3178
  this.action = entry.action || ((_a = entry.schema) === null || _a === void 0 ? void 0 : _a.action);
@@ -3170,9 +3191,13 @@ class FormCore {
3170
3191
  this.fieldEventSubject$ = new Subject();
3171
3192
  this.dataSubject$ = new Subject();
3172
3193
  this.mountSubject$ = new Subject();
3194
+ this.fieldValidNotification$ = new Subject();
3173
3195
  this.formValidNotification$ = new Subject();
3174
3196
  this.subscribedTemplates = [];
3175
3197
  this.templateSubscription$ = this.templateSubject$.subscribe(this.refreshTemplates.bind(this));
3198
+ this.fieldValidNotification$.subscribe(() => {
3199
+ this.validateForm();
3200
+ });
3176
3201
  this.mountSubject$.subscribe(this.mountActions.bind(this));
3177
3202
  this.initialValues = entry.initialValues || ((_j = entry.schema) === null || _j === void 0 ? void 0 : _j.initialValues);
3178
3203
  this.iVars = entry.iVars || ((_k = entry.schema) === null || _k === void 0 ? void 0 : _k.iVars) || {};
@@ -3274,16 +3299,30 @@ class FormCore {
3274
3299
  });
3275
3300
  }
3276
3301
  /**
3277
- * Checks if the form is valid by validating all form fields.
3302
+ * Validates all form fields and sets the form valid flag
3278
3303
  *
3279
- * @returns {boolean} True if the form is valid; otherwise, false.
3280
3304
  */
3281
- get isValid() {
3282
- if (this.fields.size === 0) return false;
3305
+ validateForm() {
3306
+ if (this.fields.size === 0) return this.valid = false;
3283
3307
  for (const [, field] of this.fields) {
3284
- if (!field.valid) return false;
3308
+ if (!field.valid) return this.valid = false;
3285
3309
  }
3286
- return true;
3310
+ return this.valid = true;
3311
+ }
3312
+ get valid() {
3313
+ return this._valid;
3314
+ }
3315
+ set valid(valid) {
3316
+ if (this._valid === valid) return;
3317
+ this._valid = valid;
3318
+ this.templateSubject$.next({
3319
+ event: 'ON_FORM',
3320
+ scope: 'form'
3321
+ });
3322
+ this.formValidNotification$.next({
3323
+ formIndex: this.index,
3324
+ valid: this.valid
3325
+ });
3287
3326
  }
3288
3327
  /**
3289
3328
  * Subscribes to templates for dynamic updates.
@@ -3336,6 +3375,11 @@ class FormCore {
3336
3375
  const value = get(this.iVars, [key, ...(property ? [property] : []), ...path]);
3337
3376
  return value;
3338
3377
  }
3378
+ case 'form':
3379
+ {
3380
+ const value = get(this, [key, ...(property ? [property] : []), ...path]);
3381
+ return value;
3382
+ }
3339
3383
  case 'fields':
3340
3384
  {
3341
3385
  const field = this.fields.get(key);
@@ -3834,7 +3878,7 @@ class FormCore {
3834
3878
  templateSubject$: this.templateSubject$,
3835
3879
  fieldEventSubject$: this.fieldEventSubject$,
3836
3880
  dataSubject$: this.dataSubject$,
3837
- formValidNotification$: this.formValidNotification$,
3881
+ fieldValidNotification$: this.fieldValidNotification$,
3838
3882
  mountSubject$: this.mountSubject$,
3839
3883
  config: this.config,
3840
3884
  submitEvent: this.submit.bind(this),
@@ -3889,7 +3933,7 @@ class FormCore {
3889
3933
  templateSubject$: this.templateSubject$,
3890
3934
  fieldEventSubject$: this.fieldEventSubject$,
3891
3935
  dataSubject$: this.dataSubject$,
3892
- formValidNotification$: this.formValidNotification$,
3936
+ fieldValidNotification$: this.fieldValidNotification$,
3893
3937
  mountSubject$: this.mountSubject$,
3894
3938
  config: this.config,
3895
3939
  getFormValues: this.getFormValues.bind(this),
@@ -3989,7 +4033,7 @@ class FormCore {
3989
4033
  values,
3990
4034
  metadata,
3991
4035
  erroredFields,
3992
- isValid: this.isValid
4036
+ isValid: this.valid
3993
4037
  };
3994
4038
  }
3995
4039
  /**
@@ -4050,11 +4094,9 @@ class FormCore {
4050
4094
  * @param {(payload: TFormValidationPayload) => void} callback callback function to call onValid
4051
4095
  */
4052
4096
  subscribeFormValidation(callback) {
4053
- const sub = this.formValidNotification$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS), map(({
4054
- fieldTrigger
4055
- }) => ({
4056
- fieldTrigger,
4057
- valid: this.isValid
4097
+ const sub = this.formValidNotification$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS), map(() => ({
4098
+ formIndex: this.index,
4099
+ valid: this.valid
4058
4100
  })), distinctUntilKeyChanged('valid')).subscribe({
4059
4101
  next: callback
4060
4102
  });
@@ -4069,7 +4111,7 @@ class FormCore {
4069
4111
  event: 'ON_FIELD_VALIDATION'
4070
4112
  });
4071
4113
  });
4072
- if (!this.isValid) return;
4114
+ if (!this.valid) return;
4073
4115
  const values = this.getFormValues();
4074
4116
  this.submitSubject$.next(values);
4075
4117
  }
@@ -4081,7 +4123,7 @@ class FormCore {
4081
4123
  this.templateSubscription$.unsubscribe();
4082
4124
  this.fieldEventSubject$.unsubscribe();
4083
4125
  this.dataSubject$.unsubscribe();
4084
- this.formValidNotification$.unsubscribe();
4126
+ this.fieldValidNotification$.unsubscribe();
4085
4127
  this.fields.forEach(field => field.destroyField());
4086
4128
  }
4087
4129
  }
@@ -4298,11 +4340,11 @@ class FormGroup {
4298
4340
  }) {
4299
4341
  const subs = ids.reduce((acc, formId) => {
4300
4342
  var _a;
4301
- const sub = (_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.formValidNotification$.pipe(groupBy(payload => `${formId}.${payload.fieldTrigger}`), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), startWith({
4343
+ const sub = (_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.formValidNotification$.pipe(groupBy(payload => `${formId}.${payload.formIndex}`), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), startWith({
4302
4344
  fieldTrigger: null
4303
4345
  }), map(() => {
4304
4346
  var _a;
4305
- return ((_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.isValid) === false ? false : true;
4347
+ return ((_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.valid) === false ? false : true;
4306
4348
  }), distinctUntilChanged());
4307
4349
  if (sub) {
4308
4350
  acc[formId] = sub;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bolttech/form-engine-core",
3
- "version": "1.0.0-beta.10",
3
+ "version": "1.0.0-beta.12",
4
4
  "module": "./index.esm.js",
5
5
  "type": "module",
6
6
  "main": "./index.esm.js",
@@ -4,7 +4,7 @@ declare const TEMPLATE_REGEX_STRING_CONCATENATION_DETECTOR: RegExp;
4
4
  declare const TEMPLATE_REGEX_DELIMITATOR: RegExp;
5
5
  declare const TEMPLATE_REGEX_OPERATOR_SPLITTER: RegExp;
6
6
  declare const TEMPLATE_REGEX_OPERATOR_MATCHER: RegExp;
7
- declare const TEMPLATE_AVALIABLE_SCOPES: readonly ["fields", "iVars"];
7
+ declare const TEMPLATE_AVALIABLE_SCOPES: readonly ["fields", "iVars", "form"];
8
8
  declare const ALLOWED_RESET_PROPS_MUTATIONS: ("api" | "apiSchema" | "props" | "validations" | "visibilityConditions" | "resetValues")[];
9
9
  declare const DEFAULT_LOG_VERBOSE = false;
10
10
  export { DEFAULT_API_DEBOUNCE_TIME, DEFAULT_STATE_REFRESH_TIME, DEFAULT_LOG_VERBOSE, TEMPLATE_REGEX_STRING_CONCATENATION_DETECTOR, TEMPLATE_REGEX_DELIMITATOR, TEMPLATE_REGEX_OPERATOR_SPLITTER, TEMPLATE_REGEX_OPERATOR_MATCHER, TEMPLATE_AVALIABLE_SCOPES, ALLOWED_RESET_PROPS_MUTATIONS, };
@@ -1,8 +1,8 @@
1
- import { Observable, Subject, Subscription } from 'rxjs';
1
+ import { Subject, Subscription } from 'rxjs';
2
2
  import { TApiConfig, TApiEvent, TApiResponse, TErrorMessages, TFormatters, TMasks, TResetPathMethods, TResetValueMethods, TSchemaFormConfig, TValidations, TVisibility } from '../types/schema';
3
3
  import { IComponentSchema, IComponentSchemaAsFormField } from '../interfaces/schema';
4
4
  import { IState } from '../interfaces/state';
5
- import { TEvents, TFieldEvent, TFormValidationPayload, TValueChangeEvent } from '../types/event';
5
+ import { TEvents, TFieldEvent, TFieldValidationPayload, TValueChangeEvent } from '../types/event';
6
6
  import { TMapper } from '../types/mapper';
7
7
  import { SafeSubject } from '../helpers/SafeSubject';
8
8
  import { TTemplateEvent } from '../types/template';
@@ -44,19 +44,17 @@ declare class FormField {
44
44
  valueSubject$: SafeSubject<Record<string, unknown>>;
45
45
  valueSubscription$: Subscription;
46
46
  visibilitySubject$: SafeSubject<boolean>;
47
- apiSubject$: SafeSubject<TApiResponse>;
48
47
  fieldEventSubject$: Subject<TFieldEvent>;
49
48
  apiEventQueueSubject$: SafeSubject<{
50
49
  event: TEvents;
51
50
  }>;
52
- fieldState$: Observable<IState>;
53
51
  fieldStateSubscription$: Subscription;
54
52
  templateSubject$: Subject<TTemplateEvent>;
55
53
  dataSubject$: Subject<{
56
54
  key: string;
57
55
  event: TEvents;
58
56
  }>;
59
- formValidNotification$: Subject<Pick<TFormValidationPayload, 'fieldTrigger'>>;
57
+ fieldValidNotification$: Subject<TFieldValidationPayload>;
60
58
  mountSubject$: Subject<{
61
59
  key: string;
62
60
  status: boolean;
@@ -94,7 +92,7 @@ declare class FormField {
94
92
  * @param {TMapper<unknown>} options.mapper, - component generic mapper containing render parameters for adapters
95
93
  * @param {() => TFormValues<unknown>} options.getFormValues, - form instance function that builds onData parameter payload from fields
96
94
  */
97
- constructor({ schemaComponent, config, path, children, validateVisibility, resetValue, resetProperty, templateSubject$, fieldEventSubject$, dataSubject$, formValidNotification$, mountSubject$, mapper, getFormValues, submitEvent, visibility, }: {
95
+ constructor({ schemaComponent, config, path, children, validateVisibility, resetValue, resetProperty, templateSubject$, fieldEventSubject$, dataSubject$, fieldValidNotification$, mountSubject$, mapper, getFormValues, submitEvent, visibility, }: {
98
96
  schemaComponent: IComponentSchema;
99
97
  config?: TSchemaFormConfig;
100
98
  path?: string;
@@ -118,7 +116,7 @@ declare class FormField {
118
116
  key: string;
119
117
  event: TEvents;
120
118
  }>;
121
- formValidNotification$: Subject<Pick<TFormValidationPayload, 'fieldTrigger'>>;
119
+ fieldValidNotification$: Subject<TFieldValidationPayload>;
122
120
  mountSubject$: Subject<{
123
121
  key: string;
124
122
  status: boolean;
@@ -218,7 +216,10 @@ declare class FormField {
218
216
  */
219
217
  set api(response: TApiResponse);
220
218
  /**
221
- * Retrieves the mounted status of the field.
219
+ * notifies templates and event binded field configurations that a request starts it's processing
220
+ */
221
+ notifyApiRequest(): void;
222
+ /** Retrieves the mounted status of the field.
222
223
  *
223
224
  * @returns {boolean} - the mounted status of the field.
224
225
  */
@@ -3,7 +3,7 @@ import { Subject, Subscription } from 'rxjs';
3
3
  import { IComponentSchema, IComponentSchemaAsFormField, IFormSchema } from '../interfaces/schema';
4
4
  import { TSchemaFormConfig } from '../types/schema';
5
5
  import { TSubscribedTemplates, TTemplateEvent } from '../types/template';
6
- import { TEvents, TFieldEvent, TFormValidationPayload, TMutationEvents } from '../types/event';
6
+ import { TEvents, TFieldEvent, TFieldValidationPayload, TFormValidationPayload, TMutationEvents } from '../types/event';
7
7
  import { TFormEntry, TFormValues } from '../types/form';
8
8
  import { TMapper } from '../types/mapper';
9
9
  import { TEMPLATE_AVALIABLE_SCOPES } from '../constants/constants';
@@ -11,6 +11,7 @@ import { TEMPLATE_AVALIABLE_SCOPES } from '../constants/constants';
11
11
  * Represents the core logic for managing a form, including field management, validation, and submission.
12
12
  */
13
13
  declare class FormCore {
14
+ index: string;
14
15
  schema?: IFormSchema;
15
16
  fields: Map<string, IFormField>;
16
17
  private _iVars;
@@ -26,7 +27,8 @@ declare class FormCore {
26
27
  key: string;
27
28
  event: TEvents;
28
29
  }>;
29
- formValidNotification$: Subject<Pick<TFormValidationPayload, 'fieldTrigger'>>;
30
+ formValidNotification$: Subject<TFormValidationPayload>;
31
+ fieldValidNotification$: Subject<TFieldValidationPayload>;
30
32
  subscribedTemplates: TSubscribedTemplates[];
31
33
  action?: string;
32
34
  method?: string;
@@ -45,6 +47,7 @@ declare class FormCore {
45
47
  value: unknown;
46
48
  }>;
47
49
  queuedInitialValues: Map<string, unknown>;
50
+ _valid: boolean;
48
51
  /**
49
52
  * Creates an instance of FormCore.
50
53
  *
@@ -92,11 +95,12 @@ declare class FormCore {
92
95
  */
93
96
  set iVars(payload: Record<string, unknown>);
94
97
  /**
95
- * Checks if the form is valid by validating all form fields.
98
+ * Validates all form fields and sets the form valid flag
96
99
  *
97
- * @returns {boolean} True if the form is valid; otherwise, false.
98
100
  */
99
- get isValid(): boolean;
101
+ validateForm(): boolean;
102
+ get valid(): boolean;
103
+ set valid(valid: boolean);
100
104
  /**
101
105
  * Subscribes to templates for dynamic updates.
102
106
  */
@@ -330,7 +334,10 @@ declare class FormCore {
330
334
  *
331
335
  * @param {(payload: TFormValidationPayload) => void} callback callback function to call onValid
332
336
  */
333
- subscribeFormValidation(callback: (payload: TFormValidationPayload) => void): Subscription;
337
+ subscribeFormValidation(callback: (payload: {
338
+ formIndex: string;
339
+ valid: boolean;
340
+ }) => void): Subscription;
334
341
  /**
335
342
  * Submits the form by triggering form field events and invoking the onSubmit callback.
336
343
  */
@@ -9,7 +9,7 @@ import { TFormValues } from './form';
9
9
  * const event: TEvents = 'ON_FIELD_CHANGE';
10
10
  * ```
11
11
  */
12
- type TEvents = 'ON_FIELD_MOUNT' | 'ON_FIELD_CHANGE' | 'ON_FIELD_BLUR' | 'ON_FIELD_FOCUS' | 'ON_FIELD_CLICK' | 'ON_FIELD_KEYUP' | 'ON_FIELD_KEYDOWN' | 'ON_FIELD_CLEARED' | 'ON_FORM_SUBMIT' | 'ON_FIELD_VALIDATION' | 'ON_FORM_MOUNT' | 'ON_API_FIELD_RESPONSE';
12
+ type TEvents = 'ON_FIELD_MOUNT' | 'ON_FIELD_CHANGE' | 'ON_FIELD_BLUR' | 'ON_FIELD_FOCUS' | 'ON_FIELD_CLICK' | 'ON_FIELD_KEYUP' | 'ON_FIELD_KEYDOWN' | 'ON_FIELD_CLEARED' | 'ON_FORM_SUBMIT' | 'ON_FIELD_VALIDATION' | 'ON_FORM_MOUNT' | 'ON_API_FIELD_REQUEST' | 'ON_API_FIELD_RESPONSE';
13
13
  /**
14
14
  * @type TMutationEvents
15
15
  * Represents the different types of events that can occur internally that triggers templating.
@@ -19,7 +19,7 @@ type TEvents = 'ON_FIELD_MOUNT' | 'ON_FIELD_CHANGE' | 'ON_FIELD_BLUR' | 'ON_FIEL
19
19
  * const event: TMutationEvents = 'ON_VALUE';
20
20
  * ```
21
21
  */
22
- type TMutationEvents = 'ON_VALUE' | 'ON_PROPS' | 'ON_VISIBILITY' | 'ON_API' | 'ON_IVARS' | 'ON_FIELDS' | 'ON_RESET';
22
+ type TMutationEvents = 'ON_VALUE' | 'ON_PROPS' | 'ON_VISIBILITY' | 'ON_API_REQUEST' | 'ON_API_RESPONSE' | 'ON_IVARS' | 'ON_FIELDS' | 'ON_RESET' | 'ON_FORM';
23
23
  declare enum TMutationEnum {
24
24
  ON_VALUE = "value",
25
25
  ON_PROPS = "props",
@@ -56,9 +56,16 @@ type TFieldEvent = {
56
56
  * Form onValid event emmited payload on callback function parameter
57
57
  */
58
58
  type TFormValidationPayload = {
59
- fieldTrigger: string;
59
+ formIndex: string;
60
60
  valid: boolean;
61
61
  };
62
+ /**
63
+ * @type TFieldValidationPayload
64
+ * field event emmited payload on field validation
65
+ */
66
+ type TFieldValidationPayload = {
67
+ fieldTrigger: string;
68
+ };
62
69
  /**
63
70
  * @type TFormGroupOnDataEventPayload
64
71
  * Form Group onData event emitted payload on callback function parameter
@@ -81,4 +88,4 @@ type TFormGroupOnValidEventPayload = {
81
88
  * Form Group onSubmit event emitted payload on callback function parameter
82
89
  */
83
90
  type TFormGroupOnSubmitEventPayload<T> = Record<string, TFormValues<T> | undefined>;
84
- export { TEvents, TMutationEvents, TMutationEnum, TValueChangeEvent, TFieldEvent, TFormGroupOnDataEventPayload, TFormGroupOnValidEventPayload, TFormGroupOnSubmitEventPayload, TFormValidationPayload, };
91
+ export { TEvents, TMutationEvents, TMutationEnum, TValueChangeEvent, TFieldEvent, TFormGroupOnDataEventPayload, TFormGroupOnValidEventPayload, TFormGroupOnSubmitEventPayload, TFormValidationPayload, TFieldValidationPayload, };
@@ -667,7 +667,7 @@ type TResetValueMethods = Omit<TVisibility, 'showOnlyIfTrue' | 'validations'> &
667
667
  validations?: TSchemaValidation;
668
668
  };
669
669
  type TResetPathMethods = {
670
- property: typeof ALLOWED_RESET_PROPS_MUTATIONS[number];
670
+ property: (typeof ALLOWED_RESET_PROPS_MUTATIONS)[number];
671
671
  path: string;
672
672
  field: string;
673
673
  resettledValue: unknown;
@@ -816,6 +816,10 @@ type TApiResponsePayload = {
816
816
  type TApiResponse = {
817
817
  default: TApiResponsePayload;
818
818
  named?: Record<string, TApiResponsePayload>;
819
+ apiState: {
820
+ loading: boolean;
821
+ lastEvent?: TEvents;
822
+ };
819
823
  };
820
824
  /**
821
825
  * Represents the schema config structure