@bolttech/form-engine-core 1.0.0-beta.9 → 1.0.1-beta.1

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',
@@ -2637,6 +2632,7 @@ class FormField {
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
  */
@@ -2867,11 +2884,12 @@ class FormField {
2867
2884
  emitValue(prop) {
2868
2885
  if (!this.visibility || !this.mounted) return;
2869
2886
  this.value = prop.value;
2870
- this.emitEvents({
2871
- event: prop.event
2872
- });
2873
2887
  this.dataSubject$.next({
2874
- key: this.name,
2888
+ event: prop.event,
2889
+ fieldIndex: this.name,
2890
+ formIndex: this.formIndex
2891
+ });
2892
+ this.emitEvents({
2875
2893
  event: prop.event
2876
2894
  });
2877
2895
  }
@@ -2930,16 +2948,17 @@ class FormField {
2930
2948
  const errors = {};
2931
2949
  const schemaValidations = (_a = this.validations) === null || _a === void 0 ? void 0 : _a.methods;
2932
2950
  schemaValidations && Object.keys(schemaValidations).forEach(validationKey => {
2951
+ var _a;
2933
2952
  const error = handleValidation(this.value, schemaValidations, validations, validationKey);
2934
2953
  // setting valid flag
2935
2954
  valid = !error && valid;
2936
2955
  // setting error messages
2937
- if (error && this.errorMessages) {
2938
- if (validationKey in this.errorMessages) {
2939
- 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;
2940
2959
  errors[validationKey] = messages[validationKey];
2941
- } else if ('default' in this.errorMessages) {
2942
- errors[validationKey] = this.errorMessages.default;
2960
+ } else if ('default' in this.validations.messages) {
2961
+ errors[validationKey] = this.validations.messages.default;
2943
2962
  }
2944
2963
  } else {
2945
2964
  delete errors[validationKey];
@@ -3009,6 +3028,7 @@ class FormField {
3009
3028
  }) {
3010
3029
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
3011
3030
  return __awaiter(this, void 0, void 0, function* () {
3031
+ let requestMadeOnce = false;
3012
3032
  const configRequest = config => __awaiter(this, void 0, void 0, function* () {
3013
3033
  var _k;
3014
3034
  try {
@@ -3034,20 +3054,23 @@ class FormField {
3034
3054
  };
3035
3055
  }
3036
3056
  });
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 => {
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 => {
3038
3058
  var _a, _b;
3039
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);
3040
3060
  }))) return;
3041
3061
  const responses = {
3042
3062
  default: Object.assign({}, this.api.default),
3043
- named: Object.assign({}, this.api.named)
3063
+ named: Object.assign({}, this.api.named),
3064
+ apiState: Object.assign({}, this.api.apiState)
3044
3065
  };
3045
3066
  const config = (_e = this.apiSchema.defaultConfig) === null || _e === void 0 ? void 0 : _e.config;
3046
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();
3047
3069
  const {
3048
3070
  response,
3049
3071
  status
3050
3072
  } = yield configRequest(config);
3073
+ requestMadeOnce = true;
3051
3074
  responses.default = {
3052
3075
  response,
3053
3076
  status
@@ -3065,10 +3088,12 @@ class FormField {
3065
3088
  var _l, _m, _o, _p;
3066
3089
  const config = (_m = (_l = this.apiSchema) === null || _l === void 0 ? void 0 : _l.configs) === null || _m === void 0 ? void 0 : _m[configKey].config;
3067
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();
3068
3092
  const {
3069
3093
  response,
3070
3094
  status
3071
3095
  } = yield configRequest(config);
3096
+ requestMadeOnce = true;
3072
3097
  return {
3073
3098
  name: configKey,
3074
3099
  result: {
@@ -3084,7 +3109,11 @@ class FormField {
3084
3109
  });
3085
3110
  }
3086
3111
  }
3087
- this.api = responses;
3112
+ if (requestMadeOnce) {
3113
+ responses.apiState.lastEvent = event;
3114
+ responses.apiState.loading = false;
3115
+ this.api = responses;
3116
+ }
3088
3117
  });
3089
3118
  }
3090
3119
  /**
@@ -3099,10 +3128,16 @@ class FormField {
3099
3128
  this.fieldStateSubscription$.unsubscribe();
3100
3129
  this.propsSubject$.unsubscribe();
3101
3130
  this.errorSubject$.unsubscribe();
3102
- this.apiSubject$.unsubscribe();
3103
3131
  this.apiEventQueueSubject$.unsubscribe();
3104
- !this.formValidNotification$.closed && this.formValidNotification$.next({
3105
- fieldTrigger: this.name
3132
+ this.dataSubject$.next({
3133
+ event: 'ON_FIELD_UNMOUNT',
3134
+ fieldIndex: this.name,
3135
+ formIndex: this.formIndex
3136
+ });
3137
+ !this.fieldEventSubject$.closed && this.fieldEventSubject$.next({
3138
+ event: 'ON_FIELD_UNMOUNT',
3139
+ fieldName: this.name,
3140
+ fieldInstance: this
3106
3141
  });
3107
3142
  }
3108
3143
  /**
@@ -3112,7 +3147,14 @@ class FormField {
3112
3147
  * @returns {void}
3113
3148
  */
3114
3149
  subscribeState(callback) {
3115
- this.fieldStateSubscription$ = this.fieldState$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS)).subscribe({
3150
+ var _a;
3151
+ this.fieldStateSubscription$ = combineLatest({
3152
+ visibility: this.visibilitySubject$.pipe(startWith(this.visibility)),
3153
+ props: this.propsSubject$.pipe(startWith(this.props)),
3154
+ errors: this.errorSubject$.pipe(startWith(Object.assign({}, ((_a = this.mapper.events) === null || _a === void 0 ? void 0 : _a.setErrorMessage) && {
3155
+ [this.mapper.events.setErrorMessage]: this.errorsString
3156
+ })))
3157
+ }).pipe(debounceTime(this.config.defaultStateRefreshTimeMS)).subscribe({
3116
3158
  next: callback
3117
3159
  });
3118
3160
  }
@@ -3152,6 +3194,8 @@ class FormCore {
3152
3194
  this.queuedFieldResetValuesEvents = new Map();
3153
3195
  this.queuedFieldResetPropertyEvents = new Map();
3154
3196
  this.queuedInitialValues = new Map();
3197
+ this._valid = false;
3198
+ this.index = entry.index;
3155
3199
  this.schema = entry.schema;
3156
3200
  this.fields = new Map();
3157
3201
  this.action = entry.action || ((_a = entry.schema) === null || _a === void 0 ? void 0 : _a.action);
@@ -3164,15 +3208,20 @@ class FormCore {
3164
3208
  (_h = entry.mappers) === null || _h === void 0 ? void 0 : _h.map(mapper => {
3165
3209
  this.mappers.set(mapper.componentName, mapper);
3166
3210
  });
3211
+ 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}`);
3167
3212
  this.schema && FormCore.checkIndexes(this.schema.components);
3168
3213
  this.templateSubject$ = new Subject();
3169
- this.submitSubject$ = new Subject();
3170
3214
  this.fieldEventSubject$ = new Subject();
3171
- this.dataSubject$ = new Subject();
3172
3215
  this.mountSubject$ = new Subject();
3173
- this.formValidNotification$ = new Subject();
3216
+ this.fieldValidNotification$ = new Subject();
3217
+ this.submitSubject$ = entry.submitSubject$ ? entry.submitSubject$ : new Subject();
3218
+ this.dataSubject$ = entry.dataSubject$ ? entry.dataSubject$ : new Subject();
3219
+ this.formValidSubject$ = entry.formValidSubject$ ? entry.formValidSubject$ : new Subject();
3174
3220
  this.subscribedTemplates = [];
3175
3221
  this.templateSubscription$ = this.templateSubject$.subscribe(this.refreshTemplates.bind(this));
3222
+ this.fieldValidNotification$.subscribe(() => {
3223
+ this.validateForm();
3224
+ });
3176
3225
  this.mountSubject$.subscribe(this.mountActions.bind(this));
3177
3226
  this.initialValues = entry.initialValues || ((_j = entry.schema) === null || _j === void 0 ? void 0 : _j.initialValues);
3178
3227
  this.iVars = entry.iVars || ((_k = entry.schema) === null || _k === void 0 ? void 0 : _k.iVars) || {};
@@ -3201,7 +3250,6 @@ class FormCore {
3201
3250
  key,
3202
3251
  status
3203
3252
  }) {
3204
- var _a;
3205
3253
  if (status) {
3206
3254
  const field = this.fields.get(key);
3207
3255
  if (!field) {
@@ -3209,7 +3257,7 @@ class FormCore {
3209
3257
  @TODO check a better way to handle nested fields unmounted by visiblity conditions from a parent
3210
3258
  since they are dependent on adapter field recycling runtimes
3211
3259
  */
3212
- this.config.defaultLogVerbose && console.log(`field ${key} was mounted but since it's parent has some visibility condition the field was already removed`);
3260
+ this.config.defaultLogVerbose && console.warn(`field ${key} was mounted but since it's parent has some visibility condition the field was already removed`);
3213
3261
  return;
3214
3262
  }
3215
3263
  this.subscribeTemplates();
@@ -3221,15 +3269,12 @@ class FormCore {
3221
3269
  scope: 'iVars',
3222
3270
  event: 'ON_IVARS'
3223
3271
  });
3224
- if (!this.queuedInitialValues.has(key)) {
3225
- 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) || ''];
3226
- !(field === null || field === void 0 ? void 0 : field.value) ? field.emitValue({
3227
- value: typeof propValue === 'string' && !propValue.includes('${') ? propValue : '',
3228
- event: 'ON_FIELD_MOUNT'
3229
- }) : field.emitEvents({
3230
- event: 'ON_FIELD_MOUNT'
3231
- });
3232
- }
3272
+ if (!this.queuedInitialValues.has(key)) field.valuePropName && !field.value ? field.emitValue({
3273
+ event: 'ON_FIELD_MOUNT',
3274
+ value: ''
3275
+ }) : field.emitEvents({
3276
+ event: 'ON_FIELD_MOUNT'
3277
+ });
3233
3278
  this.checkFieldEventQueues(key);
3234
3279
  }
3235
3280
  }
@@ -3274,16 +3319,30 @@ class FormCore {
3274
3319
  });
3275
3320
  }
3276
3321
  /**
3277
- * Checks if the form is valid by validating all form fields.
3322
+ * Validates all form fields and sets the form valid flag
3278
3323
  *
3279
- * @returns {boolean} True if the form is valid; otherwise, false.
3280
3324
  */
3281
- get isValid() {
3282
- if (this.fields.size === 0) return false;
3325
+ validateForm() {
3326
+ if (this.fields.size === 0) return this.valid = false;
3283
3327
  for (const [, field] of this.fields) {
3284
- if (!field.valid) return false;
3328
+ if (!field.valid) return this.valid = false;
3285
3329
  }
3286
- return true;
3330
+ return this.valid = true;
3331
+ }
3332
+ get valid() {
3333
+ return this._valid;
3334
+ }
3335
+ set valid(valid) {
3336
+ if (this._valid === valid) return;
3337
+ this._valid = valid;
3338
+ this.templateSubject$.next({
3339
+ event: 'ON_FORM',
3340
+ scope: 'form'
3341
+ });
3342
+ this.formValidSubject$.next({
3343
+ formIndex: this.index,
3344
+ valid: this.valid
3345
+ });
3287
3346
  }
3288
3347
  /**
3289
3348
  * Subscribes to templates for dynamic updates.
@@ -3336,6 +3395,11 @@ class FormCore {
3336
3395
  const value = get(this.iVars, [key, ...(property ? [property] : []), ...path]);
3337
3396
  return value;
3338
3397
  }
3398
+ case 'form':
3399
+ {
3400
+ const value = get(this, [key, ...(property ? [property] : []), ...path]);
3401
+ return value;
3402
+ }
3339
3403
  case 'fields':
3340
3404
  {
3341
3405
  const field = this.fields.get(key);
@@ -3620,12 +3684,21 @@ class FormCore {
3620
3684
  * and trigger the validation when it's visible
3621
3685
  */
3622
3686
  if (fieldInstance.visibility) {
3623
- fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.emitValue({
3624
- value: this.queuedInitialValues.get(field) || '',
3625
- event: 'ON_FIELD_MOUNT'
3626
- });
3627
- this.queuedInitialValues.delete(field);
3687
+ if (this.queuedInitialValues.has(field)) {
3688
+ fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.emitValue({
3689
+ value: this.queuedInitialValues.get(field) || '',
3690
+ event: 'ON_FIELD_MOUNT'
3691
+ });
3692
+ this.queuedInitialValues.delete(field);
3693
+ } else {
3694
+ fieldInstance.emitEvents({
3695
+ event: 'ON_FIELD_MOUNT'
3696
+ });
3697
+ }
3628
3698
  } else {
3699
+ if (fieldInstance.persistValue) {
3700
+ this.queuedInitialValues.set(fieldInstance.name, fieldInstance.value);
3701
+ }
3629
3702
  fieldInstance.value = '';
3630
3703
  fieldInstance.valid = true;
3631
3704
  }
@@ -3753,7 +3826,7 @@ class FormCore {
3753
3826
  value
3754
3827
  }) {
3755
3828
  const field = this.fields.get(key);
3756
- if (!field || field.mounted) {
3829
+ if (!field) {
3757
3830
  this.queuedFieldResetPropertyEvents.set(key, {
3758
3831
  property,
3759
3832
  path,
@@ -3815,15 +3888,23 @@ class FormCore {
3815
3888
  */
3816
3889
  addField({
3817
3890
  fieldSchema,
3818
- mapperElement
3891
+ mapperElement,
3892
+ path
3819
3893
  }) {
3820
- var _a;
3894
+ var _a, _b, _c, _d;
3821
3895
  if (this.fields.has(fieldSchema.name)) {
3822
3896
  throw new Error(`field name ${fieldSchema.name} already defined`);
3823
3897
  }
3824
3898
  const mapper = mapperElement || ((_a = this.mappers) === null || _a === void 0 ? void 0 : _a.get(fieldSchema.component));
3825
3899
  if (!mapper) throw new Error(`mapper not found for ${fieldSchema.component}, add it to the mappers configuration`);
3900
+ if ((_b = mapper.events) === null || _b === void 0 ? void 0 : _b.setValue) {
3901
+ 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];
3902
+ if (!(typeof initialValue === 'undefined') && !this.queuedInitialValues.has(fieldSchema.name) && !(typeof initialValue === 'string' && initialValue.includes('${'))) {
3903
+ this.queuedInitialValues.set(fieldSchema.name, cloneDeep(initialValue));
3904
+ }
3905
+ }
3826
3906
  this.fields.set(fieldSchema.name, new FormField({
3907
+ formIndex: this.index,
3827
3908
  schemaComponent: fieldSchema,
3828
3909
  mapper,
3829
3910
  children: fieldSchema.children ? fieldSchema.children.map(el => el.name) : [],
@@ -3834,11 +3915,13 @@ class FormCore {
3834
3915
  templateSubject$: this.templateSubject$,
3835
3916
  fieldEventSubject$: this.fieldEventSubject$,
3836
3917
  dataSubject$: this.dataSubject$,
3837
- formValidNotification$: this.formValidNotification$,
3918
+ fieldValidNotification$: this.fieldValidNotification$,
3838
3919
  mountSubject$: this.mountSubject$,
3839
3920
  config: this.config,
3840
3921
  submitEvent: this.submit.bind(this),
3841
- visibility: fieldSchema.visibility
3922
+ visibility: fieldSchema.visibility,
3923
+ persistValue: fieldSchema.persistValue,
3924
+ path
3842
3925
  }));
3843
3926
  }
3844
3927
  /**
@@ -3858,6 +3941,7 @@ class FormCore {
3858
3941
  key,
3859
3942
  event: 'ON_FIELDS'
3860
3943
  });
3944
+ this.validateForm();
3861
3945
  }
3862
3946
  /**
3863
3947
  * Serializes the schema structure to create form fields.
@@ -3868,36 +3952,16 @@ class FormCore {
3868
3952
  serializeStructure(struct, path) {
3869
3953
  if (!struct) return;
3870
3954
  struct.forEach(structElement => {
3871
- var _a, _b;
3955
+ var _a;
3872
3956
  const currField = this.fields.get(structElement.name);
3873
3957
  if (!currField) {
3874
- let mapper;
3875
- if (structElement === null || structElement === void 0 ? void 0 : structElement.mapper) {
3876
- mapper = structElement === null || structElement === void 0 ? void 0 : structElement.mapper;
3877
- } else {
3878
- mapper = (_a = this.mappers) === null || _a === void 0 ? void 0 : _a.get(structElement.component);
3879
- }
3880
- if (!mapper) throw new Error(`mapper not found for ${structElement.component}, add it to the mappers configuration`);
3881
- this.fields.set(structElement.name, new FormField({
3882
- schemaComponent: structElement,
3883
- mapper,
3884
- path,
3885
- children: structElement.children ? structElement.children.map(el => el.name) : [],
3886
- validateVisibility: this.validateVisibility.bind(this),
3887
- resetValue: this.resetValue.bind(this),
3888
- resetProperty: this.resetProperty.bind(this),
3889
- templateSubject$: this.templateSubject$,
3890
- fieldEventSubject$: this.fieldEventSubject$,
3891
- dataSubject$: this.dataSubject$,
3892
- formValidNotification$: this.formValidNotification$,
3893
- mountSubject$: this.mountSubject$,
3894
- config: this.config,
3895
- getFormValues: this.getFormValues.bind(this),
3896
- submitEvent: this.submit.bind(this),
3897
- visibility: structElement.visibility
3898
- }));
3958
+ this.addField({
3959
+ fieldSchema: structElement,
3960
+ mapperElement: structElement.mapper,
3961
+ path
3962
+ });
3899
3963
  } else {
3900
- 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) || [];
3901
3965
  currField.path = path;
3902
3966
  currField.originalSchema = structElement;
3903
3967
  currField.templateSubject$ = this.templateSubject$;
@@ -3959,13 +4023,7 @@ class FormCore {
3959
4023
  * Prints the current values of all form fields.
3960
4024
  */
3961
4025
  printValues() {
3962
- const values = {};
3963
- this.fields.forEach((val, key) => {
3964
- if (val.value) {
3965
- set(values, val.nameToSubmit || key, val.value);
3966
- }
3967
- });
3968
- console.table(values);
4026
+ console.table(this.getFormValues().values);
3969
4027
  }
3970
4028
  /**
3971
4029
  * Gets the current values of all form fields.
@@ -3977,7 +4035,7 @@ class FormCore {
3977
4035
  const metadata = {};
3978
4036
  const erroredFields = [];
3979
4037
  this.fields.forEach((val, key) => {
3980
- if (val.value) {
4038
+ if (!(typeof val.value === 'string' && val.value.length === 0) && typeof val.value !== 'undefined' && val.value !== null) {
3981
4039
  set(values, val.nameToSubmit || key, val.value);
3982
4040
  metadata[key] = val.metadata;
3983
4041
  }
@@ -3989,7 +4047,7 @@ class FormCore {
3989
4047
  values,
3990
4048
  metadata,
3991
4049
  erroredFields,
3992
- isValid: this.isValid
4050
+ isValid: this.valid
3993
4051
  };
3994
4052
  }
3995
4053
  /**
@@ -4001,7 +4059,7 @@ class FormCore {
4001
4059
  subscribeFieldEvent({
4002
4060
  callback
4003
4061
  }) {
4004
- const sub = this.fieldEventSubject$.pipe(groupBy(payload => payload.event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS)))).subscribe({
4062
+ const sub = this.fieldEventSubject$.pipe(groupBy(payload => `${payload.event}|${payload.fieldName}`), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS)))).subscribe({
4005
4063
  next: callback
4006
4064
  });
4007
4065
  return sub;
@@ -4023,10 +4081,12 @@ class FormCore {
4023
4081
  * @param {(payload: { field: string; data: TFormValues }) => void} callback callback function to call onData
4024
4082
  */
4025
4083
  subscribeData(callback) {
4026
- const sub = this.dataSubject$.pipe(groupBy(payload => payload.event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), map(({
4027
- 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
4028
4088
  }) => ({
4029
- field: key,
4089
+ field: fieldIndex,
4030
4090
  data: this.getFormValues()
4031
4091
  }))).subscribe({
4032
4092
  next: callback
@@ -4039,7 +4099,11 @@ class FormCore {
4039
4099
  * @param {(payload: TFormValues<T>) => void} callback callback function to call when the submit action occurs
4040
4100
  */
4041
4101
  subscribeOnSubmit(callback) {
4042
- const sub = this.submitSubject$.subscribe({
4102
+ const sub = this.submitSubject$.pipe(filter(({
4103
+ formIndex
4104
+ }) => formIndex === this.index), map(({
4105
+ values
4106
+ }) => values)).subscribe({
4043
4107
  next: callback
4044
4108
  });
4045
4109
  return sub;
@@ -4050,12 +4114,15 @@ class FormCore {
4050
4114
  * @param {(payload: TFormValidationPayload) => void} callback callback function to call onValid
4051
4115
  */
4052
4116
  subscribeFormValidation(callback) {
4053
- const sub = this.formValidNotification$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS), map(({
4054
- fieldTrigger
4055
- }) => ({
4056
- fieldTrigger,
4057
- valid: this.isValid
4058
- })), 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({
4059
4126
  next: callback
4060
4127
  });
4061
4128
  return sub;
@@ -4069,19 +4136,20 @@ class FormCore {
4069
4136
  event: 'ON_FIELD_VALIDATION'
4070
4137
  });
4071
4138
  });
4072
- if (!this.isValid) return;
4139
+ if (!this.valid) return;
4073
4140
  const values = this.getFormValues();
4074
- this.submitSubject$.next(values);
4141
+ this.submitSubject$.next({
4142
+ formIndex: this.index,
4143
+ values
4144
+ });
4075
4145
  }
4076
4146
  /**
4077
4147
  * recycles all the Suscriptions, to be called from the adapter when the form leaves the page
4078
4148
  */
4079
4149
  destroy() {
4080
- this.submitSubject$.unsubscribe();
4081
4150
  this.templateSubscription$.unsubscribe();
4082
4151
  this.fieldEventSubject$.unsubscribe();
4083
- this.dataSubject$.unsubscribe();
4084
- this.formValidNotification$.unsubscribe();
4152
+ this.fieldValidNotification$.unsubscribe();
4085
4153
  this.fields.forEach(field => field.destroyField());
4086
4154
  }
4087
4155
  }
@@ -4124,6 +4192,9 @@ class FormGroup {
4124
4192
  var _a, _b, _c, _d, _e;
4125
4193
  this.destroy = () => {
4126
4194
  this.forms.forEach(form => form.destroy());
4195
+ this.dataSubject$.unsubscribe();
4196
+ this.formValidSubject$.unsubscribe();
4197
+ this.submitSubject$.unsubscribe();
4127
4198
  };
4128
4199
  this.forms = new Map();
4129
4200
  this.config = {
@@ -4131,6 +4202,9 @@ class FormGroup {
4131
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,
4132
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
4133
4204
  };
4205
+ this.dataSubject$ = new Subject();
4206
+ this.formValidSubject$ = new Subject();
4207
+ this.submitSubject$ = new Subject();
4134
4208
  }
4135
4209
  /**
4136
4210
  * Creates an empty form with given index
@@ -4142,14 +4216,13 @@ class FormGroup {
4142
4216
  index,
4143
4217
  mappers
4144
4218
  }) {
4145
- const formInstance = new FormCore({
4146
- index,
4147
- mappers,
4148
- config: this.config
4149
- });
4150
4219
  this.addForm({
4151
4220
  key: index,
4152
- formInstance
4221
+ params: {
4222
+ index,
4223
+ mappers,
4224
+ config: this.config
4225
+ }
4153
4226
  });
4154
4227
  }
4155
4228
  /**
@@ -4161,11 +4234,16 @@ class FormGroup {
4161
4234
  */
4162
4235
  addForm({
4163
4236
  key,
4164
- formInstance
4237
+ params
4165
4238
  }) {
4166
4239
  this.checkIndexes({
4167
- key
4240
+ key: key
4168
4241
  });
4242
+ const formInstance = new FormCore(Object.assign(Object.assign({}, params), {
4243
+ dataSubject$: this.dataSubject$,
4244
+ formValidSubject$: this.formValidSubject$,
4245
+ submitSubject$: this.submitSubject$
4246
+ }));
4169
4247
  if (!formInstance.config) {
4170
4248
  formInstance.config = this.config;
4171
4249
  }
@@ -4207,10 +4285,10 @@ class FormGroup {
4207
4285
  formIndex,
4208
4286
  fieldIndex
4209
4287
  }) {
4210
- var _a;
4211
4288
  const form = this.forms.get(formIndex);
4212
- (_a = form === null || form === void 0 ? void 0 : form.fields.get(fieldIndex)) === null || _a === void 0 ? void 0 : _a.destroyField();
4213
- 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
+ });
4214
4292
  if ((form === null || form === void 0 ? void 0 : form.fields.size) === 0) {
4215
4293
  this.removeForm({
4216
4294
  key: formIndex
@@ -4268,52 +4346,49 @@ class FormGroup {
4268
4346
  ids,
4269
4347
  callback
4270
4348
  }) {
4271
- const subs = ids.reduce((acc, formId) => {
4272
- var _a, _b;
4273
- 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(({
4274
- key
4275
- }) => {
4276
- var _a;
4277
- return {
4278
- formField: key,
4279
- 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()
4280
4364
  };
4281
- }), startWith({
4282
- formField: null,
4283
- values: (_b = this.forms.get(formId)) === null || _b === void 0 ? void 0 : _b.getFormValues()
4284
- }));
4285
- if (sub) {
4286
- acc[formId] = sub;
4287
- } else {
4288
- this.config.defaultLogVerbose && console.warn(`failed to register form id ${formId}`);
4289
4365
  }
4290
4366
  return acc;
4291
- }, {});
4292
- const sub = combineLatest(subs).subscribe(callback);
4367
+ }, {}))).subscribe(callback);
4293
4368
  return sub;
4294
4369
  }
4295
4370
  onValidSubscription({
4296
4371
  ids,
4297
4372
  callback
4298
4373
  }) {
4299
- const subs = ids.reduce((acc, formId) => {
4300
- 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({
4302
- fieldTrigger: null
4303
- }), 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 => {
4304
4382
  var _a;
4305
- return ((_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.isValid) === false ? false : true;
4306
- }), distinctUntilChanged());
4307
- if (sub) {
4308
- acc[formId] = sub;
4309
- } else {
4310
- this.config.defaultLogVerbose && console.warn(`failed to register validation subscription form id ${formId}`);
4311
- }
4312
- return acc;
4313
- }, {});
4314
- const sub = combineLatest(subs).pipe(map(forms => ({
4315
- groupValid: Object.keys(forms).every(formId => forms[formId]),
4316
- 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
+ }, {})
4317
4392
  }))).subscribe(callback);
4318
4393
  return sub;
4319
4394
  }
@@ -4321,17 +4396,15 @@ class FormGroup {
4321
4396
  ids,
4322
4397
  callback
4323
4398
  }) {
4324
- const subs = ids.reduce((acc, formId) => {
4325
- const form = this.forms.get(formId);
4326
- const sub = form === null || form === void 0 ? void 0 : form.submitSubject$.pipe(map(() => form === null || form === void 0 ? void 0 : form.getFormValues()), startWith(undefined));
4327
- if (sub) {
4328
- acc[formId] = sub;
4329
- } else {
4330
- 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();
4331
4405
  }
4332
4406
  return acc;
4333
- }, {});
4334
- const sub = combineLatest(subs).pipe(skip(1)).subscribe(callback);
4407
+ }, {}))).subscribe(callback);
4335
4408
  return sub;
4336
4409
  }
4337
4410
  }