@bolttech/form-engine-core 1.0.0-beta.5 → 1.0.0-beta.7

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
1
  import { Subject, Subscription, combineLatest, startWith, groupBy, mergeMap, debounceTime, filter, map, distinctUntilKeyChanged, distinctUntilChanged, skip } from 'rxjs';
2
2
  import creditCardType from 'credit-card-type';
3
- import { isNumber as isNumber$1, isFunction, cloneDeep, isEqual, get, isNil, set } from 'lodash';
3
+ import { isNumber as isNumber$1, isFunction, cloneDeep, merge, isEqual, get, isNil, set } from 'lodash';
4
4
  import { getCurrencySymbol } from '@gaignoux/currency';
5
5
 
6
6
  var TMutationEnum;
@@ -2496,9 +2496,11 @@ class FormField {
2496
2496
  fieldEventSubject$,
2497
2497
  dataSubject$,
2498
2498
  formValidNotification$,
2499
+ mountSubject$,
2499
2500
  mapper,
2500
2501
  getFormValues,
2501
- submitEvent
2502
+ submitEvent,
2503
+ visibility
2502
2504
  }) {
2503
2505
  var _a, _b, _c, _d, _e, _f, _g;
2504
2506
  this.valueSubscription$ = new Subscription();
@@ -2534,11 +2536,12 @@ class FormField {
2534
2536
  this.fieldEventSubject$ = fieldEventSubject$;
2535
2537
  this.dataSubject$ = dataSubject$;
2536
2538
  this.formValidNotification$ = formValidNotification$;
2537
- this._props = cloneDeep(schemaComponent.props || {});
2539
+ this.mountSubject$ = mountSubject$;
2540
+ this._props = FormField.filterProps(cloneDeep(schemaComponent.props || {}));
2538
2541
  this._metadata = '';
2539
2542
  this.errorsString = '';
2540
2543
  this.errorsList = [];
2541
- this._visibility = true;
2544
+ this._visibility = typeof visibility === 'boolean' ? visibility : true;
2542
2545
  this._api = {
2543
2546
  default: {
2544
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) || '',
@@ -2554,7 +2557,7 @@ class FormField {
2554
2557
  }, {})
2555
2558
  };
2556
2559
  this._errors = {};
2557
- this._mounted = true;
2560
+ this._mounted = false;
2558
2561
  this._valid = false;
2559
2562
  this.initializeObservers();
2560
2563
  }
@@ -2564,25 +2567,25 @@ class FormField {
2564
2567
  initializeObservers() {
2565
2568
  var _a;
2566
2569
  if (!this.valueSubject$ || this.valueSubject$.closed) {
2567
- this.valueSubject$ = new SafeSubject(() => this._mounted);
2570
+ this.valueSubject$ = new SafeSubject(() => this.mounted);
2568
2571
  }
2569
2572
  if (!this.errorSubject$ || this.errorSubject$.closed) {
2570
- this.errorSubject$ = new SafeSubject(() => this._mounted);
2573
+ this.errorSubject$ = new SafeSubject(() => this.mounted);
2571
2574
  }
2572
2575
  if (!this.visibilitySubject$ || this.visibilitySubject$.closed) {
2573
- this.visibilitySubject$ = new SafeSubject(() => this._mounted);
2576
+ this.visibilitySubject$ = new SafeSubject(() => this.mounted);
2574
2577
  }
2575
2578
  if (!this.apiSubject$ || this.apiSubject$.closed) {
2576
- this.apiSubject$ = new SafeSubject(() => this._mounted);
2579
+ this.apiSubject$ = new SafeSubject(() => this.mounted);
2577
2580
  }
2578
2581
  if (!this.propsSubject$ || this.propsSubject$.closed) {
2579
- this.propsSubject$ = new SafeSubject(() => this._mounted);
2582
+ this.propsSubject$ = new SafeSubject(() => this.mounted);
2580
2583
  }
2581
2584
  if (!this.fieldStateSubscription$ || this.fieldStateSubscription$.closed) {
2582
2585
  this.fieldStateSubscription$ = new Subscription();
2583
2586
  }
2584
2587
  if (!this.apiEventQueueSubject$ || this.apiEventQueueSubject$.closed) {
2585
- this.apiEventQueueSubject$ = new SafeSubject(() => this._mounted);
2588
+ this.apiEventQueueSubject$ = new SafeSubject(() => this.mounted);
2586
2589
  }
2587
2590
  this.fieldState$ = combineLatest({
2588
2591
  visibility: this.visibilitySubject$.pipe(startWith(this._visibility)),
@@ -2611,8 +2614,9 @@ class FormField {
2611
2614
  * @param {Record<string, unknown>} props - The new properties to be set.
2612
2615
  */
2613
2616
  set props(props) {
2614
- if (typeof props === 'undefined' || isEqual(props, this.props)) return;
2615
- this._props = props;
2617
+ const diffProps = merge(cloneDeep(this.props), props);
2618
+ if (typeof diffProps === 'undefined' || isEqual(diffProps, this.props)) return;
2619
+ this._props = diffProps;
2616
2620
  this.propsSubject$.next(this.props);
2617
2621
  this.templateSubject$.next({
2618
2622
  scope: 'fields',
@@ -2620,6 +2624,22 @@ class FormField {
2620
2624
  event: 'ON_PROPS'
2621
2625
  });
2622
2626
  }
2627
+ static filterProps(props) {
2628
+ if (Array.isArray(props)) {
2629
+ return props.filter(el => typeof el === 'string' && el.includes('${') ? false : true).map(el => FormField.filterProps(el));
2630
+ }
2631
+ if (typeof props === 'object' && props !== null) {
2632
+ return Object.keys(props).reduce((acc, curr) => {
2633
+ const propValue = props[curr];
2634
+ if (typeof propValue === 'string' && propValue.includes('${')) {
2635
+ return acc;
2636
+ }
2637
+ acc[curr] = FormField.filterProps(props[curr]);
2638
+ return acc;
2639
+ }, {});
2640
+ }
2641
+ return props;
2642
+ }
2623
2643
  /**
2624
2644
  * Retrieves the current state value of the form field.
2625
2645
  *
@@ -2784,6 +2804,17 @@ class FormField {
2784
2804
  event: 'ON_API_FIELD_RESPONSE'
2785
2805
  });
2786
2806
  }
2807
+ get mounted() {
2808
+ return this._mounted;
2809
+ }
2810
+ set mounted(mountedStatus) {
2811
+ if (typeof mountedStatus === 'undefined' || mountedStatus === this.mounted) return;
2812
+ this._mounted = mountedStatus;
2813
+ this.mountSubject$.next({
2814
+ key: this.name,
2815
+ status: this.mounted
2816
+ });
2817
+ }
2787
2818
  /**
2788
2819
  * Mounts the form field by initializing necessary subjects and combining their streams.
2789
2820
  *
@@ -2796,10 +2827,15 @@ class FormField {
2796
2827
  valueSubscription,
2797
2828
  propsSubscription
2798
2829
  }) {
2799
- this.initializeObservers();
2800
2830
  this.subscribeValue(valueSubscription);
2801
2831
  this.subscribeState(propsSubscription);
2802
- this._mounted = true;
2832
+ this.mounted = true;
2833
+ this.valueSubject$.next(this.stateValue);
2834
+ this.propsSubject$.next(this.props);
2835
+ this.visibilitySubject$.next(this.visibility);
2836
+ this.setFieldValidity({
2837
+ event: 'ON_FIELD_MOUNT'
2838
+ });
2803
2839
  }
2804
2840
  /**
2805
2841
  * Sets the value of the form field and emits associated events.
@@ -2809,7 +2845,7 @@ class FormField {
2809
2845
  * @returns {void}
2810
2846
  */
2811
2847
  emitValue(prop) {
2812
- if (!this.visibility) return;
2848
+ if (!this.visibility || !this.mounted) return;
2813
2849
  this.value = prop.value;
2814
2850
  this.emitEvents({
2815
2851
  event: prop.event
@@ -2831,13 +2867,13 @@ class FormField {
2831
2867
  if (event === 'ON_FORM_SUBMIT') {
2832
2868
  return this.submitEvent();
2833
2869
  }
2834
- this.setFieldValidity({
2835
- event
2836
- });
2837
2870
  this.validateVisibility({
2838
2871
  event,
2839
2872
  key: this.name
2840
2873
  });
2874
+ this.setFieldValidity({
2875
+ event
2876
+ });
2841
2877
  this.resetValue({
2842
2878
  event,
2843
2879
  key: this.name
@@ -3037,7 +3073,7 @@ class FormField {
3037
3073
  * @returns {void}
3038
3074
  */
3039
3075
  destroyField() {
3040
- this._mounted = false;
3076
+ this.mounted = false;
3041
3077
  this.valueSubscription$.unsubscribe();
3042
3078
  this.visibilitySubject$.unsubscribe();
3043
3079
  this.fieldStateSubscription$.unsubscribe();
@@ -3089,7 +3125,7 @@ class FormCore {
3089
3125
  * @param {((payload: {field: string;data: TFormValues;}) => void) | undefined} [entry.onData] - A callback function to handle data emission.
3090
3126
  */
3091
3127
  constructor(entry) {
3092
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
3128
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
3093
3129
  this.templateSubscription$ = new Subscription();
3094
3130
  this.mappers = new Map();
3095
3131
  this.queuedFieldVisibilityEvents = new Map();
@@ -3117,40 +3153,71 @@ class FormCore {
3117
3153
  this.mountSubject$ = new Subject();
3118
3154
  this.formValidNotification$ = new Subject();
3119
3155
  this.subscribedTemplates = [];
3120
- this.schema && this.serializeStructure(this.schema.components);
3121
- this.schema && this.subscribeTemplates();
3156
+ // this.schema && this.serializeStructure(this.schema.components);
3157
+ // this.schema && this.subscribeTemplates();
3122
3158
  this.templateSubscription$ = this.templateSubject$.subscribe(this.refreshTemplates.bind(this));
3123
- this.templateSubject$.next({
3124
- scope: 'iVars',
3125
- event: 'ON_IVARS'
3126
- });
3159
+ this.mountSubject$.subscribe(this.mountActions.bind(this));
3160
+ // this.templateSubject$.next({
3161
+ // scope: 'iVars',
3162
+ // event: 'ON_IVARS',
3163
+ // });
3127
3164
  /*
3128
3165
  only emits event ON_FIELD_MOUNT if does not have initialValue, if has initialValue, initialValues class property setter will
3129
3166
  emit the value along with ON_FIELD_MOUNT event
3130
3167
  */
3131
- const initialValues = entry.initialValues || ((_k = entry.schema) === null || _k === void 0 ? void 0 : _k.initialValues);
3132
- this.fields.forEach((field, key) => {
3133
- var _a;
3134
- if (!initialValues || initialValues && !Object.keys(initialValues).includes(key)) {
3135
- 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) || ''];
3136
- !(field === null || field === void 0 ? void 0 : field.value) && (field === null || field === void 0 ? void 0 : field.emitValue({
3137
- value: typeof propValue === 'string' && !propValue.includes('${') ? propValue : '',
3138
- event: 'ON_FIELD_MOUNT'
3139
- }));
3140
- }
3168
+ // const initialValues = entry.initialValues || entry.schema?.initialValues;
3169
+ // this.fields.forEach((field, key) => {
3170
+ // if (
3171
+ // !initialValues ||
3172
+ // (initialValues && !Object.keys(initialValues).includes(key))
3173
+ // ) {
3174
+ // const propValue = field?.props?.[field?.valuePropName || ''];
3175
+ // !field?.value &&
3176
+ // field?.emitValue({
3177
+ // value:
3178
+ // typeof propValue === 'string' && !propValue.includes('${')
3179
+ // ? propValue
3180
+ // : '',
3181
+ // event: 'ON_FIELD_MOUNT',
3182
+ // });
3183
+ // }
3184
+ // this.refreshTemplates({ scope: 'fields', key, event: 'ON_FIELDS' });
3185
+ // });
3186
+ // this.setInitialValues(initialValues);
3187
+ }
3188
+ mountActions({
3189
+ status,
3190
+ key
3191
+ }) {
3192
+ var _a;
3193
+ if (status) {
3194
+ this.subscribeTemplates();
3141
3195
  this.refreshTemplates({
3142
3196
  scope: 'fields',
3143
- key,
3144
3197
  event: 'ON_FIELDS'
3145
3198
  });
3146
- });
3147
- this.setInitialValues(initialValues);
3199
+ this.templateSubject$.next({
3200
+ scope: 'iVars',
3201
+ event: 'ON_IVARS'
3202
+ });
3203
+ if (!this.queuedInitialValues.has(key)) {
3204
+ const field = this.fields.get(key);
3205
+ 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) || ''];
3206
+ !(field === null || field === void 0 ? void 0 : field.value) ? field.emitValue({
3207
+ value: typeof propValue === 'string' && !propValue.includes('${') ? propValue : '',
3208
+ event: 'ON_FIELD_MOUNT'
3209
+ }) : field.emitEvents({
3210
+ event: 'ON_FIELD_MOUNT'
3211
+ });
3212
+ }
3213
+ this.checkFieldEventQueues(key);
3214
+ }
3148
3215
  }
3149
- setInitialValues(payload) {
3216
+ set initialValues(payload) {
3150
3217
  if (payload) {
3151
3218
  Object.keys(payload).forEach(key => {
3152
3219
  const field = this.fields.get(key);
3153
- if (!field || !(field === null || field === void 0 ? void 0 : field.visibility)) {
3220
+ if (!field || !(field === null || field === void 0 ? void 0 : field.visibility) || !(field === null || field === void 0 ? void 0 : field.mounted)) {
3154
3221
  this.queuedInitialValues.set(key, payload === null || payload === void 0 ? void 0 : payload[key]);
3155
3222
  } else {
3156
3223
  field.emitValue({
@@ -3187,6 +3254,7 @@ class FormCore {
3187
3254
  * @returns {boolean} True if the form is valid; otherwise, false.
3188
3255
  */
3189
3256
  get isValid() {
3257
+ if (this.fields.size === 0) return false;
3190
3258
  for (const [, field] of this.fields) {
3191
3259
  if (!field.valid) return false;
3192
3260
  }
@@ -3293,10 +3361,8 @@ class FormCore {
3293
3361
  }
3294
3362
  const fieldProp = field[property];
3295
3363
  let propState;
3296
- if (Array.isArray(fieldProp)) {
3297
- propState = [...fieldProp];
3298
- } else if (typeof fieldProp === 'object' && !isNil(fieldProp)) {
3299
- propState = Object.assign({}, fieldProp);
3364
+ if (Array.isArray(fieldProp) || typeof fieldProp === 'object' && !isNil(fieldProp)) {
3365
+ propState = cloneDeep(fieldProp);
3300
3366
  } else {
3301
3367
  this.config.defaultLogVerbose && console.warn(`invalid template property, skipping evaluation of ${field.name} with ${fieldProp}`);
3302
3368
  return;
@@ -3466,6 +3532,8 @@ class FormCore {
3466
3532
  * @param {string} field field to check
3467
3533
  */
3468
3534
  checkFieldEventQueues(field) {
3535
+ var _a;
3536
+ if (!((_a = this.fields.get(field)) === null || _a === void 0 ? void 0 : _a.mounted)) return;
3469
3537
  if (this.queuedFieldVisibilityEvents.has(field)) {
3470
3538
  this.setFieldVisibility(Object.assign({
3471
3539
  field: field
@@ -3473,10 +3541,11 @@ class FormCore {
3473
3541
  this.queuedFieldVisibilityEvents.delete(field);
3474
3542
  }
3475
3543
  if (this.queuedInitialValues.has(field)) {
3476
- this.setInitialValues({
3477
- [field]: this.queuedInitialValues.get(field)
3478
- });
3544
+ const value = this.queuedInitialValues.get(field);
3479
3545
  this.queuedInitialValues.delete(field);
3546
+ this.initialValues = {
3547
+ [field]: value
3548
+ };
3480
3549
  }
3481
3550
  if (this.queuedFieldResetValuesEvents.has(field)) {
3482
3551
  this.setResetFieldValue(Object.assign({
@@ -3506,14 +3575,16 @@ class FormCore {
3506
3575
  showOnlyIfTrue
3507
3576
  }) {
3508
3577
  const fieldInstance = this.fields.get(field);
3509
- if (!fieldInstance) {
3578
+ if (!fieldInstance || !fieldInstance.mounted) {
3510
3579
  this.queuedFieldVisibilityEvents.set(field, {
3511
3580
  hasError,
3512
3581
  showOnlyIfTrue
3513
3582
  });
3514
3583
  } else {
3584
+ const currentVisibility = fieldInstance.visibility;
3515
3585
  const visibility = showOnlyIfTrue ? hasError : !hasError;
3516
3586
  fieldInstance.visibility = visibility;
3587
+ if (currentVisibility === visibility) return;
3517
3588
  /**
3518
3589
  * I was sure I would not require to gambiarra, but..
3519
3590
  * in order to ignore an hidden value on a form submit
@@ -3585,12 +3656,12 @@ class FormCore {
3585
3656
  key,
3586
3657
  value
3587
3658
  }) {
3588
- if (!this.fields.has(key)) {
3659
+ const field = this.fields.get(key);
3660
+ if (!field || !(field === null || field === void 0 ? void 0 : field.mounted)) {
3589
3661
  this.queuedFieldResetValuesEvents.set(key, {
3590
3662
  value
3591
3663
  });
3592
3664
  } else {
3593
- const field = this.fields.get(key);
3594
3665
  field.emitValue({
3595
3666
  value: value,
3596
3667
  event: 'ON_FIELD_CLEARED'
@@ -3656,7 +3727,8 @@ class FormCore {
3656
3727
  path,
3657
3728
  value
3658
3729
  }) {
3659
- if (!this.fields.has(key)) {
3730
+ const field = this.fields.get(key);
3731
+ if (!field || field.mounted) {
3660
3732
  this.queuedFieldResetPropertyEvents.set(key, {
3661
3733
  property,
3662
3734
  path,
@@ -3720,7 +3792,7 @@ class FormCore {
3720
3792
  fieldSchema,
3721
3793
  mapperElement
3722
3794
  }) {
3723
- var _a, _b;
3795
+ var _a;
3724
3796
  if (this.fields.has(fieldSchema.name)) {
3725
3797
  throw new Error(`field name ${fieldSchema.name} already defined`);
3726
3798
  }
@@ -3738,23 +3810,29 @@ class FormCore {
3738
3810
  fieldEventSubject$: this.fieldEventSubject$,
3739
3811
  dataSubject$: this.dataSubject$,
3740
3812
  formValidNotification$: this.formValidNotification$,
3813
+ mountSubject$: this.mountSubject$,
3741
3814
  config: this.config,
3742
- submitEvent: this.submit.bind(this)
3815
+ submitEvent: this.submit.bind(this),
3816
+ visibility: fieldSchema.visibility
3743
3817
  }));
3744
- this.subscribeTemplates();
3745
- this.refreshTemplates({
3746
- scope: 'fields',
3747
- event: 'ON_FIELDS'
3748
- });
3749
- if (!this.queuedInitialValues.has(fieldSchema.name)) {
3750
- const field = this.fields.get(fieldSchema.name);
3751
- const propValue = (_b = field === null || field === void 0 ? void 0 : field.props) === null || _b === void 0 ? void 0 : _b[(field === null || field === void 0 ? void 0 : field.valuePropName) || ''];
3752
- !(field === null || field === void 0 ? void 0 : field.value) && (field === null || field === void 0 ? void 0 : field.emitValue({
3753
- value: typeof propValue === 'string' && !propValue.includes('${') ? propValue : '',
3754
- event: 'ON_FIELD_MOUNT'
3755
- }));
3756
- }
3757
- this.checkFieldEventQueues(fieldSchema.name);
3818
+ // this.subscribeTemplates();
3819
+ // this.refreshTemplates({
3820
+ // scope: 'fields',
3821
+ // event: 'ON_FIELDS',
3822
+ // });
3823
+ // // if (!this.queuedInitialValues.has(fieldSchema.name)) {
3824
+ // // const field = this.fields.get(fieldSchema.name);
3825
+ // // const propValue = field?.props?.[field?.valuePropName || ''];
3826
+ // // !field?.value &&
3827
+ // // field?.emitValue({
3828
+ // // value:
3829
+ // // typeof propValue === 'string' && !propValue.includes('${')
3830
+ // // ? propValue
3831
+ // // : '',
3832
+ // // event: 'ON_FIELD_MOUNT',
3833
+ // // });
3834
+ // // }
3835
+ // this.checkFieldEventQueues(fieldSchema.name);
3758
3836
  }
3759
3837
  removeField({
3760
3838
  key
@@ -3769,64 +3847,6 @@ class FormCore {
3769
3847
  event: 'ON_FIELDS'
3770
3848
  });
3771
3849
  }
3772
- static serializeStructure({
3773
- struct,
3774
- path,
3775
- fields = new Map(),
3776
- mappers
3777
- }) {
3778
- if (!struct) return fields;
3779
- struct.forEach(structElement => {
3780
- var _a;
3781
- const currField = fields.get(structElement.name);
3782
- if (!currField) {
3783
- let mapper;
3784
- if (structElement === null || structElement === void 0 ? void 0 : structElement.mapper) {
3785
- mapper = structElement === null || structElement === void 0 ? void 0 : structElement.mapper;
3786
- } else {
3787
- mapper = mappers === null || mappers === void 0 ? void 0 : mappers.find(el => el.componentName === structElement.component);
3788
- }
3789
- if (!mapper) throw new Error(`mapper not found for ${structElement.component}, add it to the mappers configuration`);
3790
- fields.set(structElement.name, new FormField({
3791
- schemaComponent: structElement,
3792
- mapper,
3793
- path,
3794
- children: structElement.children ? structElement.children.map(el => el.name) : [],
3795
- // eslint-disable-next-line @typescript-eslint/no-empty-function
3796
- validateVisibility: () => {},
3797
- // eslint-disable-next-line @typescript-eslint/no-empty-function
3798
- resetValue: () => {},
3799
- // eslint-disable-next-line @typescript-eslint/no-empty-function
3800
- resetProperty: () => {},
3801
- templateSubject$: new Subject(),
3802
- fieldEventSubject$: new Subject(),
3803
- dataSubject$: new Subject(),
3804
- formValidNotification$: new Subject(),
3805
- getFormValues: () => ({
3806
- erroredFields: [],
3807
- isValid: false,
3808
- values: []
3809
- }),
3810
- // eslint-disable-next-line @typescript-eslint/no-empty-function
3811
- submitEvent: () => {}
3812
- }));
3813
- } else {
3814
- 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) || [];
3815
- currField.path = path;
3816
- currField.originalSchema = structElement;
3817
- currField.templateSubject$ = new Subject();
3818
- }
3819
- if (structElement.children) {
3820
- this.serializeStructure({
3821
- fields,
3822
- path: `${path ? `${path}.` : ``}${structElement.name}`,
3823
- mappers: mappers,
3824
- struct: structElement.children
3825
- });
3826
- }
3827
- });
3828
- return fields;
3829
- }
3830
3850
  /**
3831
3851
  * Serializes the schema structure to create form fields.
3832
3852
  *
@@ -3858,9 +3878,11 @@ class FormCore {
3858
3878
  fieldEventSubject$: this.fieldEventSubject$,
3859
3879
  dataSubject$: this.dataSubject$,
3860
3880
  formValidNotification$: this.formValidNotification$,
3881
+ mountSubject$: this.mountSubject$,
3861
3882
  config: this.config,
3862
3883
  getFormValues: this.getFormValues.bind(this),
3863
- submitEvent: this.submit.bind(this)
3884
+ submitEvent: this.submit.bind(this),
3885
+ visibility: structElement.visibility
3864
3886
  }));
3865
3887
  } else {
3866
3888
  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) || [];
@@ -3940,10 +3962,12 @@ class FormCore {
3940
3962
  */
3941
3963
  getFormValues() {
3942
3964
  const values = {};
3965
+ const metadata = {};
3943
3966
  const erroredFields = [];
3944
3967
  this.fields.forEach((val, key) => {
3945
3968
  if (val.value) {
3946
3969
  set(values, val.nameToSubmit || key, val.value);
3970
+ metadata[key] = val.metadata;
3947
3971
  }
3948
3972
  if (!val.valid) {
3949
3973
  erroredFields.push(key);
@@ -3951,6 +3975,7 @@ class FormCore {
3951
3975
  });
3952
3976
  return {
3953
3977
  values,
3978
+ metadata,
3954
3979
  erroredFields,
3955
3980
  isValid: this.isValid
3956
3981
  };
@@ -4005,18 +4030,6 @@ class FormCore {
4005
4030
  });
4006
4031
  return sub;
4007
4032
  }
4008
- /**
4009
- * Submits the form by triggering form field events and invoking the onSubmit callback.
4010
- */
4011
- mounted() {
4012
- this.fields.forEach(field => {
4013
- field.emitEvents({
4014
- event: 'ON_FORM_MOUNT'
4015
- });
4016
- });
4017
- const values = this.getFormValues();
4018
- this.mountSubject$.next(values);
4019
- }
4020
4033
  /**
4021
4034
  * Submits the form by triggering form field events and invoking the onSubmit callback.
4022
4035
  */
@@ -4031,6 +4044,7 @@ class FormCore {
4031
4044
  this.submitSubject$.next(values);
4032
4045
  }
4033
4046
  destroy() {
4047
+ console.log('removing form');
4034
4048
  this.submitSubject$.unsubscribe();
4035
4049
  this.templateSubscription$.unsubscribe();
4036
4050
  this.fieldEventSubject$.unsubscribe();
@@ -4161,9 +4175,15 @@ class FormGroup {
4161
4175
  formIndex,
4162
4176
  fieldIndex
4163
4177
  }) {
4164
- var _a, _b, _c;
4165
- (_b = (_a = this.forms.get(formIndex)) === null || _a === void 0 ? void 0 : _a.fields.get(fieldIndex)) === null || _b === void 0 ? void 0 : _b.destroyField();
4166
- (_c = this.forms.get(formIndex)) === null || _c === void 0 ? void 0 : _c.fields.delete(fieldIndex);
4178
+ var _a;
4179
+ const form = this.forms.get(formIndex);
4180
+ (_a = form === null || form === void 0 ? void 0 : form.fields.get(fieldIndex)) === null || _a === void 0 ? void 0 : _a.destroyField();
4181
+ form === null || form === void 0 ? void 0 : form.fields.delete(fieldIndex);
4182
+ if ((form === null || form === void 0 ? void 0 : form.fields.size) === 0) {
4183
+ this.removeForm({
4184
+ key: formIndex
4185
+ });
4186
+ }
4167
4187
  }
4168
4188
  /**
4169
4189
  * Checks if the specified key already exists in the form group.
@@ -4194,6 +4214,7 @@ class FormGroup {
4194
4214
  submitMultipleFormsByIndex(indexes, callback) {
4195
4215
  let isValid = true;
4196
4216
  let values = {};
4217
+ let metadata = {};
4197
4218
  let erroredFields = [];
4198
4219
  indexes.forEach(index => {
4199
4220
  var _a, _b;
@@ -4201,12 +4222,14 @@ class FormGroup {
4201
4222
  const res = (_b = this.forms.get(index)) === null || _b === void 0 ? void 0 : _b.getFormValues();
4202
4223
  isValid = isValid && ((res === null || res === void 0 ? void 0 : res.isValid) || false);
4203
4224
  values = Object.assign(Object.assign({}, values), (res === null || res === void 0 ? void 0 : res.values) || {});
4225
+ metadata = Object.assign(Object.assign({}, metadata), (res === null || res === void 0 ? void 0 : res.metadata) || {});
4204
4226
  erroredFields = [...erroredFields, ...((res === null || res === void 0 ? void 0 : res.erroredFields) || [])];
4205
4227
  });
4206
4228
  isValid && callback && callback({
4207
4229
  erroredFields,
4208
4230
  isValid,
4209
- values
4231
+ values,
4232
+ metadata
4210
4233
  });
4211
4234
  }
4212
4235
  onDataSubscription({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bolttech/form-engine-core",
3
- "version": "1.0.0-beta.5",
3
+ "version": "1.0.0-beta.7",
4
4
  "module": "./index.esm.js",
5
5
  "type": "module",
6
6
  "main": "./index.esm.js",
@@ -62,6 +62,7 @@ interface IComponentSchema {
62
62
  formatters?: TFormatters;
63
63
  masks?: TMasks;
64
64
  children?: IComponentSchema[];
65
+ visibility?: boolean;
65
66
  }
66
67
  interface IComponentSchemaAsFormField<T> extends IComponentSchema {
67
68
  mapper?: TMapper<T>;
@@ -57,6 +57,10 @@ declare class FormField {
57
57
  event: TEvents;
58
58
  }>;
59
59
  formValidNotification$: Subject<Pick<TFormValidationPayload, 'fieldTrigger'>>;
60
+ mountSubject$: Subject<{
61
+ key: string;
62
+ status: boolean;
63
+ }>;
60
64
  validateVisibility: (payload: {
61
65
  event: TEvents;
62
66
  key: string;
@@ -90,7 +94,7 @@ declare class FormField {
90
94
  * @param {TMapper<unknown>} options.mapper, - component generic mapper containing render parameters for adapters
91
95
  * @param {() => TFormValues<unknown>} options.getFormValues, - form instance function that builds onData parameter payload from fields
92
96
  */
93
- constructor({ schemaComponent, config, path, children, validateVisibility, resetValue, resetProperty, templateSubject$, fieldEventSubject$, dataSubject$, formValidNotification$, mapper, getFormValues, submitEvent, }: {
97
+ constructor({ schemaComponent, config, path, children, validateVisibility, resetValue, resetProperty, templateSubject$, fieldEventSubject$, dataSubject$, formValidNotification$, mountSubject$, mapper, getFormValues, submitEvent, visibility, }: {
94
98
  schemaComponent: IComponentSchema;
95
99
  config?: TSchemaFormConfig;
96
100
  path?: string;
@@ -115,8 +119,13 @@ declare class FormField {
115
119
  event: TEvents;
116
120
  }>;
117
121
  formValidNotification$: Subject<Pick<TFormValidationPayload, 'fieldTrigger'>>;
122
+ mountSubject$: Subject<{
123
+ key: string;
124
+ status: boolean;
125
+ }>;
118
126
  mapper: TMapper<unknown>;
119
127
  getFormValues: () => TFormValues<unknown>;
128
+ visibility?: boolean;
120
129
  });
121
130
  /**
122
131
  * method to initialize all recycled Subjects and initialize Observers on field instance creation or rerender
@@ -134,6 +143,7 @@ declare class FormField {
134
143
  * @param {Record<string, unknown>} props - The new properties to be set.
135
144
  */
136
145
  set props(props: Record<string, unknown>);
146
+ static filterProps(props: unknown): unknown;
137
147
  /**
138
148
  * Retrieves the current state value of the form field.
139
149
  *
@@ -199,6 +209,8 @@ declare class FormField {
199
209
  * @param {TApiResponse} response - The new API response data to be set.
200
210
  */
201
211
  set api(response: TApiResponse);
212
+ get mounted(): boolean;
213
+ set mounted(mountedStatus: boolean);
202
214
  /**
203
215
  * Mounts the form field by initializing necessary subjects and combining their streams.
204
216
  *
@@ -17,7 +17,10 @@ declare class FormCore {
17
17
  templateSubject$: Subject<TTemplateEvent>;
18
18
  templateSubscription$: Subscription;
19
19
  submitSubject$: Subject<TFormValues<any>>;
20
- mountSubject$: Subject<TFormValues<any>>;
20
+ mountSubject$: Subject<{
21
+ key: string;
22
+ status: boolean;
23
+ }>;
21
24
  fieldEventSubject$: Subject<TFieldEvent>;
22
25
  dataSubject$: Subject<{
23
26
  key: string;
@@ -54,7 +57,11 @@ declare class FormCore {
54
57
  * @param {((payload: {field: string;data: TFormValues;}) => void) | undefined} [entry.onData] - A callback function to handle data emission.
55
58
  */
56
59
  constructor(entry: TFormEntry & Omit<IFormSchema, 'components'>);
57
- setInitialValues(payload: Record<string, unknown> | undefined): void;
60
+ mountActions({ status, key }: {
61
+ key: string;
62
+ status: boolean;
63
+ }): void;
64
+ set initialValues(payload: Record<string, unknown> | undefined);
58
65
  /**
59
66
  * Retrieves the internal variables (iVars) of the form.
60
67
  *
@@ -233,12 +240,6 @@ declare class FormCore {
233
240
  removeField({ key }: {
234
241
  key: string;
235
242
  }): void;
236
- static serializeStructure({ struct, path, fields, mappers, }: {
237
- struct?: IComponentSchemaAsFormField<unknown>[];
238
- path?: string;
239
- fields?: Map<string, IFormField>;
240
- mappers: TMapper<unknown>[];
241
- }): Map<string, IFormField>;
242
243
  /**
243
244
  * Serializes the schema structure to create form fields.
244
245
  *
@@ -290,10 +291,6 @@ declare class FormCore {
290
291
  * @param {(payload: TFormValidationPayload) => void} callback callback function to call onValid
291
292
  */
292
293
  subscribeFormValidation(callback: (payload: TFormValidationPayload) => void): Subscription;
293
- /**
294
- * Submits the form by triggering form field events and invoking the onSubmit callback.
295
- */
296
- mounted<T>(): void;
297
294
  /**
298
295
  * Submits the form by triggering form field events and invoking the onSubmit callback.
299
296
  */
@@ -19,6 +19,7 @@ import { TMapper } from './mapper';
19
19
  */
20
20
  type TFormValues<T> = {
21
21
  values: T;
22
+ metadata: unknown;
22
23
  erroredFields: string[];
23
24
  isValid: boolean;
24
25
  };