@bolttech/form-engine-core 1.0.0-beta.8 → 1.0.1-beta.0

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,6 +1,6 @@
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 } from 'rxjs';
2
2
  import creditCardType from 'credit-card-type';
3
- import { isNumber as isNumber$1, isFunction, cloneDeep, merge, isEqual, get, isNil, set } from 'lodash';
3
+ import { isNumber as isNumber$1, isFunction, cloneDeep, isEqual, get, isNil, set } from 'lodash';
4
4
  import { getCurrencySymbol } from '@gaignoux/currency';
5
5
 
6
6
  var TMutationEnum;
@@ -48,9 +48,9 @@ const DEFAULT_API_DEBOUNCE_TIME = 1000;
48
48
  const DEFAULT_STATE_REFRESH_TIME = 100;
49
49
  const TEMPLATE_REGEX_STRING_CONCATENATION_DETECTOR = /^\$\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\}$/;
50
50
  const TEMPLATE_REGEX_DELIMITATOR = /\$\{((?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*)\}/g;
51
- const TEMPLATE_REGEX_OPERATOR_SPLITTER = /\s*(\|\||&&|!)\s*/g;
52
- const TEMPLATE_REGEX_OPERATOR_MATCHER = /^\|\||&&|!$/;
53
- const TEMPLATE_AVALIABLE_SCOPES = ['fields', 'iVars'];
51
+ const TEMPLATE_REGEX_OPERATOR_SPLITTER = /\s*(\|\||&&|!+)\s*/g;
52
+ const TEMPLATE_REGEX_OPERATOR_MATCHER = /^\|\||&&|!+$/;
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
 
@@ -72,11 +72,12 @@ function makeRequest(method, url, headers, body, queryParams) {
72
72
  return new Promise(function (resolve, reject) {
73
73
  const xhr = new XMLHttpRequest();
74
74
  if (queryParams) {
75
- const newUrl = new URL(url);
75
+ const [baseUrl, existingParamsString] = url.split('?');
76
+ const searchParams = new URLSearchParams(existingParamsString);
76
77
  Object.keys(queryParams).forEach(param => {
77
- newUrl.searchParams.append(param, queryParams[param]);
78
+ searchParams.append(param, queryParams[param]);
78
79
  });
79
- url = newUrl.toString();
80
+ url = `${baseUrl}?${searchParams.toString()}`;
80
81
  }
81
82
  xhr.open(method, url, true);
82
83
  if (headers) {
@@ -577,7 +578,7 @@ const formatters = {
577
578
  * console.log(maskedValue); // Output: 'ab***gh###'
578
579
  * ```
579
580
  */
580
- var generic = ((value, masks) => {
581
+ var generic = (value, masks) => {
581
582
  if (!(masks === null || masks === void 0 ? void 0 : masks.generic)) return value;
582
583
  let masked = value;
583
584
  masks.generic.forEach(item => {
@@ -596,7 +597,7 @@ var generic = ((value, masks) => {
596
597
  masked = masked.slice(0, from - 1) + maskedPortion + masked.slice(to);
597
598
  });
598
599
  return masked;
599
- });
600
+ };
600
601
 
601
602
  /**
602
603
  * Replaces all characters in a string with a specified replacement string or character.
@@ -881,7 +882,7 @@ const masks = {
881
882
  * console.log(isValid); // Output: true or false based on validation
882
883
  * ```
883
884
  */
884
- var length = ((value, validations) => {
885
+ var length = (value, validations) => {
885
886
  if (!validations.length || !value) return false;
886
887
  let targetValue = value;
887
888
  // We want length even if it is a numeric
@@ -897,7 +898,7 @@ var length = ((value, validations) => {
897
898
  greaterOrEqual: targetValue.length < validations.length.target
898
899
  };
899
900
  return condition[validations.length.rule];
900
- });
901
+ };
901
902
 
902
903
  /**
903
904
  * Validates a Spanish NIF (Número de Identificación Fiscal).
@@ -1135,7 +1136,7 @@ const CIF = value => {
1135
1136
  * console.log(isValid); // Output: true or false based on validation
1136
1137
  * ```
1137
1138
  */
1138
- var document = ((value, validations) => {
1139
+ var document = (value, validations) => {
1139
1140
  if (!value || !validations.document) return true;
1140
1141
  const validation = {
1141
1142
  NIF: (value, locale) => NIF(value, locale),
@@ -1144,7 +1145,7 @@ var document = ((value, validations) => {
1144
1145
  IBAN: value => IBAN(value)
1145
1146
  };
1146
1147
  return validation[validations.document.type](value, validations.document.locale);
1147
- });
1148
+ };
1148
1149
 
1149
1150
  /**
1150
1151
  * Validates if a value exceeds the maximum allowed value.
@@ -2262,10 +2263,10 @@ function run$1(value, handlers, validations) {
2262
2263
  * const isValid = validateValue(value, methods);
2263
2264
  * console.log(isValid); // Output: true
2264
2265
  */
2265
- var namedRule = ((value, methods, validations) => {
2266
+ var namedRule = (value, methods, validations) => {
2266
2267
  if (!methods) return false;
2267
2268
  return run$1(value, methods, validations).some(validation => validation);
2268
- });
2269
+ };
2269
2270
 
2270
2271
  /**
2271
2272
  * @internal
@@ -2485,6 +2486,7 @@ class FormField {
2485
2486
  * @param {() => TFormValues<unknown>} options.getFormValues, - form instance function that builds onData parameter payload from fields
2486
2487
  */
2487
2488
  constructor({
2489
+ formIndex,
2488
2490
  schemaComponent,
2489
2491
  config,
2490
2492
  path,
@@ -2495,16 +2497,18 @@ class FormField {
2495
2497
  templateSubject$,
2496
2498
  fieldEventSubject$,
2497
2499
  dataSubject$,
2498
- formValidNotification$,
2500
+ fieldValidNotification$,
2499
2501
  mountSubject$,
2500
2502
  mapper,
2501
2503
  getFormValues,
2502
2504
  submitEvent,
2503
- visibility
2505
+ visibility,
2506
+ persistValue
2504
2507
  }) {
2505
- var _a, _b, _c, _d, _e, _f, _g;
2508
+ var _a, _b, _c, _d, _e, _f;
2506
2509
  this.valueSubscription$ = new Subscription();
2507
2510
  this.fieldStateSubscription$ = new Subscription();
2511
+ this.formIndex = formIndex;
2508
2512
  this.originalSchema = cloneDeep(schemaComponent);
2509
2513
  this.config = {
2510
2514
  defaultAPIdebounceTimeMS: Number(config === null || config === void 0 ? void 0 : config.defaultAPIdebounceTimeMS) ? Number(config === null || config === void 0 ? void 0 : config.defaultAPIdebounceTimeMS) : DEFAULT_API_DEBOUNCE_TIME,
@@ -2517,7 +2521,6 @@ class FormField {
2517
2521
  this.path = path;
2518
2522
  this.children = children;
2519
2523
  this.validations = cloneDeep(schemaComponent.validations);
2520
- this.errorMessages = cloneDeep((_a = schemaComponent.validations) === null || _a === void 0 ? void 0 : _a.messages);
2521
2524
  this.visibilityConditions = cloneDeep(schemaComponent.visibilityConditions);
2522
2525
  this.resetValues = cloneDeep(schemaComponent.resetValues);
2523
2526
  this.resetPropertyValues = cloneDeep(schemaComponent.resetPropertyValues);
@@ -2525,7 +2528,7 @@ class FormField {
2525
2528
  this.formatters = cloneDeep(schemaComponent.formatters);
2526
2529
  this.masks = cloneDeep(schemaComponent.masks);
2527
2530
  if (mapper.valueChangeEvent) this.valueChangeEvent = mapper.valueChangeEvent;
2528
- if ((_b = mapper.events) === null || _b === void 0 ? void 0 : _b.setValue) this.valuePropName = mapper.events.setValue;
2531
+ if ((_a = mapper.events) === null || _a === void 0 ? void 0 : _a.setValue) this.valuePropName = mapper.events.setValue;
2529
2532
  this.mapper = mapper;
2530
2533
  this.validateVisibility = validateVisibility;
2531
2534
  this.resetValue = resetValue;
@@ -2535,7 +2538,7 @@ class FormField {
2535
2538
  this.templateSubject$ = templateSubject$;
2536
2539
  this.fieldEventSubject$ = fieldEventSubject$;
2537
2540
  this.dataSubject$ = dataSubject$;
2538
- this.formValidNotification$ = formValidNotification$;
2541
+ this.fieldValidNotification$ = fieldValidNotification$;
2539
2542
  this.mountSubject$ = mountSubject$;
2540
2543
  this._props = FormField.filterProps(cloneDeep(schemaComponent.props || {}));
2541
2544
  this._metadata = '';
@@ -2544,21 +2547,25 @@ class FormField {
2544
2547
  this._visibility = typeof visibility === 'boolean' ? visibility : true;
2545
2548
  this._api = {
2546
2549
  default: {
2547
- response: ((_e = (_d = (_c = this.apiSchema) === null || _c === void 0 ? void 0 : _c.defaultConfig) === null || _d === void 0 ? void 0 : _d.config) === null || _e === void 0 ? void 0 : _e.fallbackValue) || '',
2550
+ response: ((_d = (_c = (_b = this.apiSchema) === null || _b === void 0 ? void 0 : _b.defaultConfig) === null || _c === void 0 ? void 0 : _c.config) === null || _d === void 0 ? void 0 : _d.fallbackValue) || '',
2548
2551
  status: null
2549
2552
  },
2550
- named: ((_f = this.apiSchema) === null || _f === void 0 ? void 0 : _f.configs) && Object.keys((_g = this.apiSchema) === null || _g === void 0 ? void 0 : _g.configs).reduce((acc, curr) => {
2553
+ named: ((_e = this.apiSchema) === null || _e === void 0 ? void 0 : _e.configs) && Object.keys((_f = this.apiSchema) === null || _f === void 0 ? void 0 : _f.configs).reduce((acc, curr) => {
2551
2554
  var _a, _b;
2552
2555
  acc[curr] = {
2553
2556
  response: ((_b = (_a = this.apiSchema) === null || _a === void 0 ? void 0 : _a.configs) === null || _b === void 0 ? void 0 : _b[curr].config.fallbackValue) || '',
2554
2557
  status: null
2555
2558
  };
2556
2559
  return acc;
2557
- }, {})
2560
+ }, {}),
2561
+ apiState: {
2562
+ loading: false
2563
+ }
2558
2564
  };
2559
2565
  this._errors = {};
2560
2566
  this._mounted = false;
2561
- this._valid = false;
2567
+ this.valid = true;
2568
+ this.persistValue = persistValue;
2562
2569
  this.initializeObservers();
2563
2570
  }
2564
2571
  /**
@@ -2567,7 +2574,6 @@ class FormField {
2567
2574
  * emissions to unsubscribed fields
2568
2575
  */
2569
2576
  initializeObservers() {
2570
- var _a;
2571
2577
  if (!this.valueSubject$ || this.valueSubject$.closed) {
2572
2578
  this.valueSubject$ = new SafeSubject(() => this.mounted);
2573
2579
  }
@@ -2577,9 +2583,6 @@ class FormField {
2577
2583
  if (!this.visibilitySubject$ || this.visibilitySubject$.closed) {
2578
2584
  this.visibilitySubject$ = new SafeSubject(() => this.mounted);
2579
2585
  }
2580
- if (!this.apiSubject$ || this.apiSubject$.closed) {
2581
- this.apiSubject$ = new SafeSubject(() => this.mounted);
2582
- }
2583
2586
  if (!this.propsSubject$ || this.propsSubject$.closed) {
2584
2587
  this.propsSubject$ = new SafeSubject(() => this.mounted);
2585
2588
  }
@@ -2589,16 +2592,9 @@ class FormField {
2589
2592
  if (!this.apiEventQueueSubject$ || this.apiEventQueueSubject$.closed) {
2590
2593
  this.apiEventQueueSubject$ = new SafeSubject(() => this.mounted);
2591
2594
  }
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
2595
  !this.apiEventQueueSubject$.observed && this.apiEventQueueSubject$.pipe(groupBy(({
2600
2596
  event
2601
- }) => event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultAPIdebounceTimeMS))), filter(() => this.apiSubject$ && !this.apiSubject$.closed)).subscribe(payload => {
2597
+ }) => event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultAPIdebounceTimeMS))), filter(() => this.apiEventQueueSubject$ && !this.apiEventQueueSubject$.closed)).subscribe(payload => {
2602
2598
  this.apiRequest(payload);
2603
2599
  });
2604
2600
  }
@@ -2616,9 +2612,8 @@ class FormField {
2616
2612
  * @param {Record<string, unknown>} props - The new properties to be set.
2617
2613
  */
2618
2614
  set props(props) {
2619
- const diffProps = merge(cloneDeep(this.props), props);
2620
- if (typeof diffProps === 'undefined' || isEqual(diffProps, this.props)) return;
2621
- this._props = diffProps;
2615
+ if (typeof props === 'undefined' || isEqual(props, this.props)) return;
2616
+ this._props = props;
2622
2617
  this.propsSubject$.next(this.props);
2623
2618
  this.templateSubject$.next({
2624
2619
  scope: 'fields',
@@ -2627,16 +2622,17 @@ class FormField {
2627
2622
  });
2628
2623
  }
2629
2624
  /**
2630
- * Static function to remove templates form the component props that will be shown when
2631
- * the field mounts and the template routine executes, to be used on the adapter
2632
- *
2633
- * @param {unknown} props - the properties from the adapter components.
2634
- */
2625
+ * Static function to remove templates form the component props that will be shown when
2626
+ * the field mounts and the template routine executes, to be used on the adapter
2627
+ *
2628
+ * @param {unknown} props - the properties from the adapter components.
2629
+ */
2635
2630
  static filterProps(props) {
2636
2631
  if (Array.isArray(props)) {
2637
2632
  return props.filter(el => typeof el === 'string' && el.includes('${') ? false : true).map(el => FormField.filterProps(el));
2638
2633
  }
2639
2634
  if (typeof props === 'object' && props !== null) {
2635
+ if (props instanceof Date) return props;
2640
2636
  return Object.keys(props).reduce((acc, curr) => {
2641
2637
  const propValue = props[curr];
2642
2638
  if (typeof propValue === 'string' && propValue.includes('${')) {
@@ -2739,12 +2735,9 @@ class FormField {
2739
2735
  * sets valid field state and notifies form instance via formValidNotification$
2740
2736
  */
2741
2737
  set valid(valid) {
2742
- if (this._valid !== valid) {
2743
- this._valid = valid;
2744
- this.formValidNotification$.next({
2745
- fieldTrigger: this.name
2746
- });
2747
- }
2738
+ if (typeof valid !== 'boolean' && this.valid === valid) return;
2739
+ this._valid = valid;
2740
+ this.triggerFieldValidNotification();
2748
2741
  }
2749
2742
  /**
2750
2743
  * Retrieves the validity status of the form field.
@@ -2754,6 +2747,18 @@ class FormField {
2754
2747
  get valid() {
2755
2748
  return this._valid;
2756
2749
  }
2750
+ /**
2751
+ * triggers field valid notification to handle the form instance valid notification
2752
+ *
2753
+ * Note: since form unmount can occur before field unmount, this subject might already be closed by form instance
2754
+ * quick workaround is to check if the subject is already closed before emitting
2755
+ * if form instance onValid or template form.valid doesn't work properly, might be due to this workaround
2756
+ */
2757
+ triggerFieldValidNotification() {
2758
+ !this.fieldValidNotification$.closed && this.fieldValidNotification$.next({
2759
+ fieldTrigger: this.name
2760
+ });
2761
+ }
2757
2762
  /**
2758
2763
  * Retrieves the error messages associated with the form field.
2759
2764
  *
@@ -2799,13 +2804,12 @@ class FormField {
2799
2804
  * @param {TApiResponse} response - The new API response data to be set.
2800
2805
  */
2801
2806
  set api(response) {
2802
- if (typeof response === 'undefined' || isEqual(response, this.api)) return;
2807
+ if (typeof response === 'undefined') return;
2803
2808
  this._api = response;
2804
- this.apiSubject$.next(this.api);
2805
2809
  this.templateSubject$.next({
2806
2810
  scope: 'fields',
2807
2811
  key: this.name,
2808
- event: 'ON_API'
2812
+ event: 'ON_API_RESPONSE'
2809
2813
  });
2810
2814
  // this.apiResponseSubject$.next({ key: this.name });
2811
2815
  this.emitEvents({
@@ -2813,7 +2817,20 @@ class FormField {
2813
2817
  });
2814
2818
  }
2815
2819
  /**
2816
- * Retrieves the mounted status of the field.
2820
+ * notifies templates and event binded field configurations that a request starts it's processing
2821
+ */
2822
+ notifyApiRequest() {
2823
+ this._api.apiState.loading = true;
2824
+ this.templateSubject$.next({
2825
+ scope: 'fields',
2826
+ key: this.name,
2827
+ event: 'ON_API_REQUEST'
2828
+ });
2829
+ this.emitEvents({
2830
+ event: 'ON_API_FIELD_REQUEST'
2831
+ });
2832
+ }
2833
+ /** Retrieves the mounted status of the field.
2817
2834
  *
2818
2835
  * @returns {boolean} - the mounted status of the field.
2819
2836
  */
@@ -2829,6 +2846,7 @@ class FormField {
2829
2846
  set mounted(mountedStatus) {
2830
2847
  if (typeof mountedStatus === 'undefined' || mountedStatus === this.mounted) return;
2831
2848
  this._mounted = mountedStatus;
2849
+ this.initializeObservers();
2832
2850
  this.mountSubject$.next({
2833
2851
  key: this.name,
2834
2852
  status: this.mounted
@@ -2846,9 +2864,9 @@ class FormField {
2846
2864
  valueSubscription,
2847
2865
  propsSubscription
2848
2866
  }) {
2867
+ this.mounted = true;
2849
2868
  this.subscribeValue(valueSubscription);
2850
2869
  this.subscribeState(propsSubscription);
2851
- this.mounted = true;
2852
2870
  this.valueSubject$.next(this.stateValue);
2853
2871
  this.propsSubject$.next(this.props);
2854
2872
  this.visibilitySubject$.next(this.visibility);
@@ -2866,11 +2884,12 @@ class FormField {
2866
2884
  emitValue(prop) {
2867
2885
  if (!this.visibility || !this.mounted) return;
2868
2886
  this.value = prop.value;
2869
- this.emitEvents({
2870
- event: prop.event
2871
- });
2872
2887
  this.dataSubject$.next({
2873
- key: this.name,
2888
+ event: prop.event,
2889
+ fieldIndex: this.name,
2890
+ formIndex: this.formIndex
2891
+ });
2892
+ this.emitEvents({
2874
2893
  event: prop.event
2875
2894
  });
2876
2895
  }
@@ -2929,16 +2948,17 @@ class FormField {
2929
2948
  const errors = {};
2930
2949
  const schemaValidations = (_a = this.validations) === null || _a === void 0 ? void 0 : _a.methods;
2931
2950
  schemaValidations && Object.keys(schemaValidations).forEach(validationKey => {
2951
+ var _a;
2932
2952
  const error = handleValidation(this.value, schemaValidations, validations, validationKey);
2933
2953
  // setting valid flag
2934
2954
  valid = !error && valid;
2935
2955
  // setting error messages
2936
- if (error && this.errorMessages) {
2937
- if (validationKey in this.errorMessages) {
2938
- const messages = this.errorMessages;
2956
+ if (error && ((_a = this.validations) === null || _a === void 0 ? void 0 : _a.messages)) {
2957
+ if (validationKey in this.validations.messages) {
2958
+ const messages = this.validations.messages;
2939
2959
  errors[validationKey] = messages[validationKey];
2940
- } else if ('default' in this.errorMessages) {
2941
- errors[validationKey] = this.errorMessages.default;
2960
+ } else if ('default' in this.validations.messages) {
2961
+ errors[validationKey] = this.validations.messages.default;
2942
2962
  }
2943
2963
  } else {
2944
2964
  delete errors[validationKey];
@@ -3008,6 +3028,7 @@ class FormField {
3008
3028
  }) {
3009
3029
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
3010
3030
  return __awaiter(this, void 0, void 0, function* () {
3031
+ let requestMadeOnce = false;
3011
3032
  const configRequest = config => __awaiter(this, void 0, void 0, function* () {
3012
3033
  var _k;
3013
3034
  try {
@@ -3033,20 +3054,23 @@ class FormField {
3033
3054
  };
3034
3055
  }
3035
3056
  });
3036
- 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 => {
3057
+ 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 => {
3037
3058
  var _a, _b;
3038
3059
  return (_b = (_a = this.apiSchema) === null || _a === void 0 ? void 0 : _a.configs) === null || _b === void 0 ? void 0 : _b[key].events.includes(event);
3039
3060
  }))) return;
3040
3061
  const responses = {
3041
3062
  default: Object.assign({}, this.api.default),
3042
- named: Object.assign({}, this.api.named)
3063
+ named: Object.assign({}, this.api.named),
3064
+ apiState: Object.assign({}, this.api.apiState)
3043
3065
  };
3044
3066
  const config = (_e = this.apiSchema.defaultConfig) === null || _e === void 0 ? void 0 : _e.config;
3045
3067
  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)) {
3068
+ !requestMadeOnce && this.notifyApiRequest();
3046
3069
  const {
3047
3070
  response,
3048
3071
  status
3049
3072
  } = yield configRequest(config);
3073
+ requestMadeOnce = true;
3050
3074
  responses.default = {
3051
3075
  response,
3052
3076
  status
@@ -3064,10 +3088,12 @@ class FormField {
3064
3088
  var _l, _m, _o, _p;
3065
3089
  const config = (_m = (_l = this.apiSchema) === null || _l === void 0 ? void 0 : _l.configs) === null || _m === void 0 ? void 0 : _m[configKey].config;
3066
3090
  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)) {
3091
+ !requestMadeOnce && this.notifyApiRequest();
3067
3092
  const {
3068
3093
  response,
3069
3094
  status
3070
3095
  } = yield configRequest(config);
3096
+ requestMadeOnce = true;
3071
3097
  return {
3072
3098
  name: configKey,
3073
3099
  result: {
@@ -3083,7 +3109,11 @@ class FormField {
3083
3109
  });
3084
3110
  }
3085
3111
  }
3086
- this.api = responses;
3112
+ if (requestMadeOnce) {
3113
+ responses.apiState.lastEvent = event;
3114
+ responses.apiState.loading = false;
3115
+ this.api = responses;
3116
+ }
3087
3117
  });
3088
3118
  }
3089
3119
  /**
@@ -3098,10 +3128,17 @@ class FormField {
3098
3128
  this.fieldStateSubscription$.unsubscribe();
3099
3129
  this.propsSubject$.unsubscribe();
3100
3130
  this.errorSubject$.unsubscribe();
3101
- this.apiSubject$.unsubscribe();
3102
3131
  this.apiEventQueueSubject$.unsubscribe();
3103
- !this.formValidNotification$.closed && this.formValidNotification$.next({
3104
- fieldTrigger: this.name
3132
+ this.triggerFieldValidNotification();
3133
+ this.dataSubject$.next({
3134
+ event: 'ON_FIELD_UNMOUNT',
3135
+ fieldIndex: this.name,
3136
+ formIndex: this.formIndex
3137
+ });
3138
+ !this.fieldEventSubject$.closed && this.fieldEventSubject$.next({
3139
+ event: 'ON_FIELD_UNMOUNT',
3140
+ fieldName: this.name,
3141
+ fieldInstance: this
3105
3142
  });
3106
3143
  }
3107
3144
  /**
@@ -3111,7 +3148,14 @@ class FormField {
3111
3148
  * @returns {void}
3112
3149
  */
3113
3150
  subscribeState(callback) {
3114
- this.fieldStateSubscription$ = this.fieldState$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS)).subscribe({
3151
+ var _a;
3152
+ this.fieldStateSubscription$ = combineLatest({
3153
+ visibility: this.visibilitySubject$.pipe(startWith(this.visibility)),
3154
+ props: this.propsSubject$.pipe(startWith(this.props)),
3155
+ errors: this.errorSubject$.pipe(startWith(Object.assign({}, ((_a = this.mapper.events) === null || _a === void 0 ? void 0 : _a.setErrorMessage) && {
3156
+ [this.mapper.events.setErrorMessage]: this.errorsString
3157
+ })))
3158
+ }).pipe(debounceTime(this.config.defaultStateRefreshTimeMS)).subscribe({
3115
3159
  next: callback
3116
3160
  });
3117
3161
  }
@@ -3151,6 +3195,8 @@ class FormCore {
3151
3195
  this.queuedFieldResetValuesEvents = new Map();
3152
3196
  this.queuedFieldResetPropertyEvents = new Map();
3153
3197
  this.queuedInitialValues = new Map();
3198
+ this._valid = false;
3199
+ this.index = entry.index;
3154
3200
  this.schema = entry.schema;
3155
3201
  this.fields = new Map();
3156
3202
  this.action = entry.action || ((_a = entry.schema) === null || _a === void 0 ? void 0 : _a.action);
@@ -3163,15 +3209,20 @@ class FormCore {
3163
3209
  (_h = entry.mappers) === null || _h === void 0 ? void 0 : _h.map(mapper => {
3164
3210
  this.mappers.set(mapper.componentName, mapper);
3165
3211
  });
3212
+ if ((!entry.submitSubject$ || !entry.dataSubject$ || !entry.formValidSubject$) && this.config.defaultLogVerbose) console.warn(`some formGroup events are not properly instanciated, any onData, onValid, onSubmit events managed by formGroup won't trigger on form: ${this.index}`);
3166
3213
  this.schema && FormCore.checkIndexes(this.schema.components);
3167
3214
  this.templateSubject$ = new Subject();
3168
- this.submitSubject$ = new Subject();
3169
3215
  this.fieldEventSubject$ = new Subject();
3170
- this.dataSubject$ = new Subject();
3171
3216
  this.mountSubject$ = new Subject();
3172
- this.formValidNotification$ = new Subject();
3217
+ this.fieldValidNotification$ = new Subject();
3218
+ this.submitSubject$ = entry.submitSubject$ ? entry.submitSubject$ : new Subject();
3219
+ this.dataSubject$ = entry.dataSubject$ ? entry.dataSubject$ : new Subject();
3220
+ this.formValidSubject$ = entry.formValidSubject$ ? entry.formValidSubject$ : new Subject();
3173
3221
  this.subscribedTemplates = [];
3174
3222
  this.templateSubscription$ = this.templateSubject$.subscribe(this.refreshTemplates.bind(this));
3223
+ this.fieldValidNotification$.subscribe(() => {
3224
+ this.validateForm();
3225
+ });
3175
3226
  this.mountSubject$.subscribe(this.mountActions.bind(this));
3176
3227
  this.initialValues = entry.initialValues || ((_j = entry.schema) === null || _j === void 0 ? void 0 : _j.initialValues);
3177
3228
  this.iVars = entry.iVars || ((_k = entry.schema) === null || _k === void 0 ? void 0 : _k.iVars) || {};
@@ -3200,8 +3251,16 @@ class FormCore {
3200
3251
  key,
3201
3252
  status
3202
3253
  }) {
3203
- var _a;
3204
3254
  if (status) {
3255
+ const field = this.fields.get(key);
3256
+ if (!field) {
3257
+ /*
3258
+ @TODO check a better way to handle nested fields unmounted by visiblity conditions from a parent
3259
+ since they are dependent on adapter field recycling runtimes
3260
+ */
3261
+ this.config.defaultLogVerbose && console.warn(`field ${key} was mounted but since it's parent has some visibility condition the field was already removed`);
3262
+ return;
3263
+ }
3205
3264
  this.subscribeTemplates();
3206
3265
  this.refreshTemplates({
3207
3266
  scope: 'fields',
@@ -3211,16 +3270,12 @@ class FormCore {
3211
3270
  scope: 'iVars',
3212
3271
  event: 'ON_IVARS'
3213
3272
  });
3214
- if (!this.queuedInitialValues.has(key)) {
3215
- const field = this.fields.get(key);
3216
- const propValue = (_a = field === null || field === void 0 ? void 0 : field.props) === null || _a === void 0 ? void 0 : _a[(field === null || field === void 0 ? void 0 : field.valuePropName) || ''];
3217
- !(field === null || field === void 0 ? void 0 : field.value) ? field.emitValue({
3218
- value: typeof propValue === 'string' && !propValue.includes('${') ? propValue : '',
3219
- event: 'ON_FIELD_MOUNT'
3220
- }) : field.emitEvents({
3221
- event: 'ON_FIELD_MOUNT'
3222
- });
3223
- }
3273
+ if (!this.queuedInitialValues.has(key)) field.valuePropName && !field.value ? field.emitValue({
3274
+ event: 'ON_FIELD_MOUNT',
3275
+ value: ''
3276
+ }) : field.emitEvents({
3277
+ event: 'ON_FIELD_MOUNT'
3278
+ });
3224
3279
  this.checkFieldEventQueues(key);
3225
3280
  }
3226
3281
  }
@@ -3265,16 +3320,30 @@ class FormCore {
3265
3320
  });
3266
3321
  }
3267
3322
  /**
3268
- * Checks if the form is valid by validating all form fields.
3323
+ * Validates all form fields and sets the form valid flag
3269
3324
  *
3270
- * @returns {boolean} True if the form is valid; otherwise, false.
3271
3325
  */
3272
- get isValid() {
3273
- if (this.fields.size === 0) return false;
3326
+ validateForm() {
3327
+ if (this.fields.size === 0) return this.valid = false;
3274
3328
  for (const [, field] of this.fields) {
3275
- if (!field.valid) return false;
3329
+ if (!field.valid) return this.valid = false;
3276
3330
  }
3277
- return true;
3331
+ return this.valid = true;
3332
+ }
3333
+ get valid() {
3334
+ return this._valid;
3335
+ }
3336
+ set valid(valid) {
3337
+ if (this._valid === valid) return;
3338
+ this._valid = valid;
3339
+ this.templateSubject$.next({
3340
+ event: 'ON_FORM',
3341
+ scope: 'form'
3342
+ });
3343
+ this.formValidSubject$.next({
3344
+ formIndex: this.index,
3345
+ valid: this.valid
3346
+ });
3278
3347
  }
3279
3348
  /**
3280
3349
  * Subscribes to templates for dynamic updates.
@@ -3327,6 +3396,11 @@ class FormCore {
3327
3396
  const value = get(this.iVars, [key, ...(property ? [property] : []), ...path]);
3328
3397
  return value;
3329
3398
  }
3399
+ case 'form':
3400
+ {
3401
+ const value = get(this, [key, ...(property ? [property] : []), ...path]);
3402
+ return value;
3403
+ }
3330
3404
  case 'fields':
3331
3405
  {
3332
3406
  const field = this.fields.get(key);
@@ -3611,12 +3685,21 @@ class FormCore {
3611
3685
  * and trigger the validation when it's visible
3612
3686
  */
3613
3687
  if (fieldInstance.visibility) {
3614
- fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.emitValue({
3615
- value: this.queuedInitialValues.get(field) || '',
3616
- event: 'ON_FIELD_MOUNT'
3617
- });
3618
- this.queuedInitialValues.delete(field);
3688
+ if (this.queuedInitialValues.has(field)) {
3689
+ fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.emitValue({
3690
+ value: this.queuedInitialValues.get(field) || '',
3691
+ event: 'ON_FIELD_MOUNT'
3692
+ });
3693
+ this.queuedInitialValues.delete(field);
3694
+ } else {
3695
+ fieldInstance.emitEvents({
3696
+ event: 'ON_FIELD_MOUNT'
3697
+ });
3698
+ }
3619
3699
  } else {
3700
+ if (fieldInstance.persistValue) {
3701
+ this.queuedInitialValues.set(fieldInstance.name, fieldInstance.value);
3702
+ }
3620
3703
  fieldInstance.value = '';
3621
3704
  fieldInstance.valid = true;
3622
3705
  }
@@ -3744,7 +3827,7 @@ class FormCore {
3744
3827
  value
3745
3828
  }) {
3746
3829
  const field = this.fields.get(key);
3747
- if (!field || field.mounted) {
3830
+ if (!field) {
3748
3831
  this.queuedFieldResetPropertyEvents.set(key, {
3749
3832
  property,
3750
3833
  path,
@@ -3806,15 +3889,23 @@ class FormCore {
3806
3889
  */
3807
3890
  addField({
3808
3891
  fieldSchema,
3809
- mapperElement
3892
+ mapperElement,
3893
+ path
3810
3894
  }) {
3811
- var _a;
3895
+ var _a, _b, _c, _d;
3812
3896
  if (this.fields.has(fieldSchema.name)) {
3813
3897
  throw new Error(`field name ${fieldSchema.name} already defined`);
3814
3898
  }
3815
3899
  const mapper = mapperElement || ((_a = this.mappers) === null || _a === void 0 ? void 0 : _a.get(fieldSchema.component));
3816
3900
  if (!mapper) throw new Error(`mapper not found for ${fieldSchema.component}, add it to the mappers configuration`);
3901
+ if ((_b = mapper.events) === null || _b === void 0 ? void 0 : _b.setValue) {
3902
+ const initialValue = (_c = fieldSchema === null || fieldSchema === void 0 ? void 0 : fieldSchema.props) === null || _c === void 0 ? void 0 : _c[(_d = mapper === null || mapper === void 0 ? void 0 : mapper.events) === null || _d === void 0 ? void 0 : _d.setValue];
3903
+ if (!(typeof initialValue === 'undefined') && !this.queuedInitialValues.has(fieldSchema.name) && !(typeof initialValue === 'string' && initialValue.includes('${'))) {
3904
+ this.queuedInitialValues.set(fieldSchema.name, cloneDeep(initialValue));
3905
+ }
3906
+ }
3817
3907
  this.fields.set(fieldSchema.name, new FormField({
3908
+ formIndex: this.index,
3818
3909
  schemaComponent: fieldSchema,
3819
3910
  mapper,
3820
3911
  children: fieldSchema.children ? fieldSchema.children.map(el => el.name) : [],
@@ -3825,11 +3916,13 @@ class FormCore {
3825
3916
  templateSubject$: this.templateSubject$,
3826
3917
  fieldEventSubject$: this.fieldEventSubject$,
3827
3918
  dataSubject$: this.dataSubject$,
3828
- formValidNotification$: this.formValidNotification$,
3919
+ fieldValidNotification$: this.fieldValidNotification$,
3829
3920
  mountSubject$: this.mountSubject$,
3830
3921
  config: this.config,
3831
3922
  submitEvent: this.submit.bind(this),
3832
- visibility: fieldSchema.visibility
3923
+ visibility: fieldSchema.visibility,
3924
+ persistValue: fieldSchema.persistValue,
3925
+ path
3833
3926
  }));
3834
3927
  }
3835
3928
  /**
@@ -3859,36 +3952,16 @@ class FormCore {
3859
3952
  serializeStructure(struct, path) {
3860
3953
  if (!struct) return;
3861
3954
  struct.forEach(structElement => {
3862
- var _a, _b;
3955
+ var _a;
3863
3956
  const currField = this.fields.get(structElement.name);
3864
3957
  if (!currField) {
3865
- let mapper;
3866
- if (structElement === null || structElement === void 0 ? void 0 : structElement.mapper) {
3867
- mapper = structElement === null || structElement === void 0 ? void 0 : structElement.mapper;
3868
- } else {
3869
- mapper = (_a = this.mappers) === null || _a === void 0 ? void 0 : _a.get(structElement.component);
3870
- }
3871
- if (!mapper) throw new Error(`mapper not found for ${structElement.component}, add it to the mappers configuration`);
3872
- this.fields.set(structElement.name, new FormField({
3873
- schemaComponent: structElement,
3874
- mapper,
3875
- path,
3876
- children: structElement.children ? structElement.children.map(el => el.name) : [],
3877
- validateVisibility: this.validateVisibility.bind(this),
3878
- resetValue: this.resetValue.bind(this),
3879
- resetProperty: this.resetProperty.bind(this),
3880
- templateSubject$: this.templateSubject$,
3881
- fieldEventSubject$: this.fieldEventSubject$,
3882
- dataSubject$: this.dataSubject$,
3883
- formValidNotification$: this.formValidNotification$,
3884
- mountSubject$: this.mountSubject$,
3885
- config: this.config,
3886
- getFormValues: this.getFormValues.bind(this),
3887
- submitEvent: this.submit.bind(this),
3888
- visibility: structElement.visibility
3889
- }));
3958
+ this.addField({
3959
+ fieldSchema: structElement,
3960
+ mapperElement: structElement.mapper,
3961
+ path
3962
+ });
3890
3963
  } else {
3891
- currField.children = ((_b = structElement === null || structElement === void 0 ? void 0 : structElement.children) === null || _b === void 0 ? void 0 : _b.map(el => el.name)) || (currField === null || currField === void 0 ? void 0 : currField.children) || [];
3964
+ currField.children = ((_a = structElement === null || structElement === void 0 ? void 0 : structElement.children) === null || _a === void 0 ? void 0 : _a.map(el => el.name)) || (currField === null || currField === void 0 ? void 0 : currField.children) || [];
3892
3965
  currField.path = path;
3893
3966
  currField.originalSchema = structElement;
3894
3967
  currField.templateSubject$ = this.templateSubject$;
@@ -3950,13 +4023,7 @@ class FormCore {
3950
4023
  * Prints the current values of all form fields.
3951
4024
  */
3952
4025
  printValues() {
3953
- const values = {};
3954
- this.fields.forEach((val, key) => {
3955
- if (val.value) {
3956
- set(values, val.nameToSubmit || key, val.value);
3957
- }
3958
- });
3959
- console.table(values);
4026
+ console.table(this.getFormValues().values);
3960
4027
  }
3961
4028
  /**
3962
4029
  * Gets the current values of all form fields.
@@ -3968,7 +4035,7 @@ class FormCore {
3968
4035
  const metadata = {};
3969
4036
  const erroredFields = [];
3970
4037
  this.fields.forEach((val, key) => {
3971
- if (val.value) {
4038
+ if (!(typeof val.value === 'string' && val.value.length === 0) && typeof val.value !== 'undefined' && val.value !== null) {
3972
4039
  set(values, val.nameToSubmit || key, val.value);
3973
4040
  metadata[key] = val.metadata;
3974
4041
  }
@@ -3980,7 +4047,7 @@ class FormCore {
3980
4047
  values,
3981
4048
  metadata,
3982
4049
  erroredFields,
3983
- isValid: this.isValid
4050
+ isValid: this.valid
3984
4051
  };
3985
4052
  }
3986
4053
  /**
@@ -4014,10 +4081,12 @@ class FormCore {
4014
4081
  * @param {(payload: { field: string; data: TFormValues }) => void} callback callback function to call onData
4015
4082
  */
4016
4083
  subscribeData(callback) {
4017
- const sub = this.dataSubject$.pipe(groupBy(payload => payload.event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), map(({
4018
- key
4084
+ const sub = this.dataSubject$.pipe(filter(({
4085
+ formIndex
4086
+ }) => this.index === formIndex), groupBy(payload => payload.event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), map(({
4087
+ fieldIndex
4019
4088
  }) => ({
4020
- field: key,
4089
+ field: fieldIndex,
4021
4090
  data: this.getFormValues()
4022
4091
  }))).subscribe({
4023
4092
  next: callback
@@ -4030,7 +4099,11 @@ class FormCore {
4030
4099
  * @param {(payload: TFormValues<T>) => void} callback callback function to call when the submit action occurs
4031
4100
  */
4032
4101
  subscribeOnSubmit(callback) {
4033
- const sub = this.submitSubject$.subscribe({
4102
+ const sub = this.submitSubject$.pipe(filter(({
4103
+ formIndex
4104
+ }) => formIndex === this.index), map(({
4105
+ values
4106
+ }) => values)).subscribe({
4034
4107
  next: callback
4035
4108
  });
4036
4109
  return sub;
@@ -4041,12 +4114,15 @@ class FormCore {
4041
4114
  * @param {(payload: TFormValidationPayload) => void} callback callback function to call onValid
4042
4115
  */
4043
4116
  subscribeFormValidation(callback) {
4044
- const sub = this.formValidNotification$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS), map(({
4045
- fieldTrigger
4046
- }) => ({
4047
- fieldTrigger,
4048
- valid: this.isValid
4049
- })), distinctUntilKeyChanged('valid')).subscribe({
4117
+ const sub = this.formValidSubject$.pipe(filter(({
4118
+ formIndex
4119
+ }) => this.index === formIndex), debounceTime(this.config.defaultStateRefreshTimeMS), map(() => ({
4120
+ formIndex: this.index,
4121
+ valid: this.valid
4122
+ })), distinctUntilKeyChanged('valid'), startWith({
4123
+ formIndex: this.index,
4124
+ valid: this.valid
4125
+ })).subscribe({
4050
4126
  next: callback
4051
4127
  });
4052
4128
  return sub;
@@ -4059,21 +4135,21 @@ class FormCore {
4059
4135
  field.emitEvents({
4060
4136
  event: 'ON_FIELD_VALIDATION'
4061
4137
  });
4062
- console.log(`${field.name} is ${field.valid}`);
4063
4138
  });
4064
- if (!this.isValid) return;
4139
+ if (!this.valid) return;
4065
4140
  const values = this.getFormValues();
4066
- this.submitSubject$.next(values);
4141
+ this.submitSubject$.next({
4142
+ formIndex: this.index,
4143
+ values
4144
+ });
4067
4145
  }
4068
4146
  /**
4069
4147
  * recycles all the Suscriptions, to be called from the adapter when the form leaves the page
4070
4148
  */
4071
4149
  destroy() {
4072
- this.submitSubject$.unsubscribe();
4073
4150
  this.templateSubscription$.unsubscribe();
4074
4151
  this.fieldEventSubject$.unsubscribe();
4075
- this.dataSubject$.unsubscribe();
4076
- this.formValidNotification$.unsubscribe();
4152
+ this.fieldValidNotification$.unsubscribe();
4077
4153
  this.fields.forEach(field => field.destroyField());
4078
4154
  }
4079
4155
  }
@@ -4116,6 +4192,9 @@ class FormGroup {
4116
4192
  var _a, _b, _c, _d, _e;
4117
4193
  this.destroy = () => {
4118
4194
  this.forms.forEach(form => form.destroy());
4195
+ this.dataSubject$.unsubscribe();
4196
+ this.formValidSubject$.unsubscribe();
4197
+ this.submitSubject$.unsubscribe();
4119
4198
  };
4120
4199
  this.forms = new Map();
4121
4200
  this.config = {
@@ -4123,6 +4202,9 @@ class FormGroup {
4123
4202
  defaultStateRefreshTimeMS: Number((_c = entry === null || entry === void 0 ? void 0 : entry.config) === null || _c === void 0 ? void 0 : _c.defaultStateRefreshTimeMS) ? Number((_d = entry === null || entry === void 0 ? void 0 : entry.config) === null || _d === void 0 ? void 0 : _d.defaultStateRefreshTimeMS) : DEFAULT_STATE_REFRESH_TIME,
4124
4203
  defaultLogVerbose: ((_e = entry === null || entry === void 0 ? void 0 : entry.config) === null || _e === void 0 ? void 0 : _e.defaultLogVerbose) ? entry.config.defaultLogVerbose : DEFAULT_LOG_VERBOSE
4125
4204
  };
4205
+ this.dataSubject$ = new Subject();
4206
+ this.formValidSubject$ = new Subject();
4207
+ this.submitSubject$ = new Subject();
4126
4208
  }
4127
4209
  /**
4128
4210
  * Creates an empty form with given index
@@ -4134,14 +4216,13 @@ class FormGroup {
4134
4216
  index,
4135
4217
  mappers
4136
4218
  }) {
4137
- const formInstance = new FormCore({
4138
- index,
4139
- mappers,
4140
- config: this.config
4141
- });
4142
4219
  this.addForm({
4143
4220
  key: index,
4144
- formInstance
4221
+ params: {
4222
+ index,
4223
+ mappers,
4224
+ config: this.config
4225
+ }
4145
4226
  });
4146
4227
  }
4147
4228
  /**
@@ -4153,11 +4234,16 @@ class FormGroup {
4153
4234
  */
4154
4235
  addForm({
4155
4236
  key,
4156
- formInstance
4237
+ params
4157
4238
  }) {
4158
4239
  this.checkIndexes({
4159
- key
4240
+ key: key
4160
4241
  });
4242
+ const formInstance = new FormCore(Object.assign(Object.assign({}, params), {
4243
+ dataSubject$: this.dataSubject$,
4244
+ formValidSubject$: this.formValidSubject$,
4245
+ submitSubject$: this.submitSubject$
4246
+ }));
4161
4247
  if (!formInstance.config) {
4162
4248
  formInstance.config = this.config;
4163
4249
  }
@@ -4199,10 +4285,10 @@ class FormGroup {
4199
4285
  formIndex,
4200
4286
  fieldIndex
4201
4287
  }) {
4202
- var _a;
4203
4288
  const form = this.forms.get(formIndex);
4204
- (_a = form === null || form === void 0 ? void 0 : form.fields.get(fieldIndex)) === null || _a === void 0 ? void 0 : _a.destroyField();
4205
- form === null || form === void 0 ? void 0 : form.fields.delete(fieldIndex);
4289
+ form === null || form === void 0 ? void 0 : form.removeField({
4290
+ key: fieldIndex
4291
+ });
4206
4292
  if ((form === null || form === void 0 ? void 0 : form.fields.size) === 0) {
4207
4293
  this.removeForm({
4208
4294
  key: formIndex
@@ -4260,52 +4346,49 @@ class FormGroup {
4260
4346
  ids,
4261
4347
  callback
4262
4348
  }) {
4263
- const subs = ids.reduce((acc, formId) => {
4264
- var _a, _b;
4265
- const sub = (_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.dataSubject$.pipe(groupBy(payload => `${formId}.${payload.event}`), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), map(({
4266
- key
4267
- }) => {
4268
- var _a;
4269
- return {
4270
- formField: key,
4271
- values: (_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.getFormValues()
4349
+ const sub = this.dataSubject$.pipe(filter(({
4350
+ formIndex
4351
+ }) => ids.includes(formIndex)), groupBy(({
4352
+ event,
4353
+ formIndex
4354
+ }) => `${event}.${formIndex}`), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), map(({
4355
+ fieldIndex,
4356
+ formIndex
4357
+ }) => ids.reduce((acc, curr) => {
4358
+ const formInstance = this.forms.get(curr);
4359
+ if (formInstance) {
4360
+ acc[curr] = {
4361
+ formId: formIndex,
4362
+ formField: fieldIndex,
4363
+ values: formInstance.getFormValues()
4272
4364
  };
4273
- }), startWith({
4274
- formField: null,
4275
- values: (_b = this.forms.get(formId)) === null || _b === void 0 ? void 0 : _b.getFormValues()
4276
- }));
4277
- if (sub) {
4278
- acc[formId] = sub;
4279
- } else {
4280
- this.config.defaultLogVerbose && console.warn(`failed to register form id ${formId}`);
4281
4365
  }
4282
4366
  return acc;
4283
- }, {});
4284
- const sub = combineLatest(subs).subscribe(callback);
4367
+ }, {}))).subscribe(callback);
4285
4368
  return sub;
4286
4369
  }
4287
4370
  onValidSubscription({
4288
4371
  ids,
4289
4372
  callback
4290
4373
  }) {
4291
- const subs = ids.reduce((acc, formId) => {
4292
- var _a;
4293
- 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({
4294
- fieldTrigger: null
4295
- }), map(() => {
4374
+ const sub = this.formValidSubject$.pipe(filter(({
4375
+ formIndex
4376
+ }) => ids.includes(formIndex)), groupBy(({
4377
+ formIndex
4378
+ }) => formIndex), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), startWith({
4379
+ fieldTrigger: null
4380
+ }), map(() => ({
4381
+ groupValid: ids.every(id => {
4296
4382
  var _a;
4297
- return ((_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.isValid) === false ? false : true;
4298
- }), distinctUntilChanged());
4299
- if (sub) {
4300
- acc[formId] = sub;
4301
- } else {
4302
- this.config.defaultLogVerbose && console.warn(`failed to register validation subscription form id ${formId}`);
4303
- }
4304
- return acc;
4305
- }, {});
4306
- const sub = combineLatest(subs).pipe(map(forms => ({
4307
- groupValid: Object.keys(forms).every(formId => forms[formId]),
4308
- forms
4383
+ return !this.forms.get(id) || ((_a = this.forms.get(id)) === null || _a === void 0 ? void 0 : _a.valid);
4384
+ }),
4385
+ forms: ids.reduce((acc, curr) => {
4386
+ const formInstance = this.forms.get(curr);
4387
+ if (formInstance) {
4388
+ acc[curr] = formInstance.valid;
4389
+ }
4390
+ return acc;
4391
+ }, {})
4309
4392
  }))).subscribe(callback);
4310
4393
  return sub;
4311
4394
  }
@@ -4313,17 +4396,15 @@ class FormGroup {
4313
4396
  ids,
4314
4397
  callback
4315
4398
  }) {
4316
- const subs = ids.reduce((acc, formId) => {
4317
- const form = this.forms.get(formId);
4318
- const sub = form === null || form === void 0 ? void 0 : form.submitSubject$.pipe(map(() => form === null || form === void 0 ? void 0 : form.getFormValues()), startWith(undefined));
4319
- if (sub) {
4320
- acc[formId] = sub;
4321
- } else {
4322
- this.config.defaultLogVerbose && console.warn(`failed to register form id ${formId}`);
4399
+ const sub = this.submitSubject$.pipe(filter(({
4400
+ formIndex
4401
+ }) => ids.includes(formIndex)), map(() => ids.reduce((acc, curr) => {
4402
+ const formInstance = this.forms.get(curr);
4403
+ if (formInstance) {
4404
+ acc[curr] = formInstance.getFormValues();
4323
4405
  }
4324
4406
  return acc;
4325
- }, {});
4326
- const sub = combineLatest(subs).pipe(skip(1)).subscribe(callback);
4407
+ }, {}))).subscribe(callback);
4327
4408
  return sub;
4328
4409
  }
4329
4410
  }