@bolttech/form-engine-core 1.0.8 → 1.0.10
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.d.ts +14 -3
- package/index.esm.js +66 -10
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as rxjs from 'rxjs';
|
|
2
|
-
import { Subject,
|
|
2
|
+
import { Subject, BehaviorSubject, Subscription } from 'rxjs';
|
|
3
3
|
import { TCurrencyLocalCode, TCurrencyCode } from '@gaignoux/currency';
|
|
4
4
|
import { OutgoingHttpHeaders } from 'http2';
|
|
5
5
|
|
|
@@ -330,7 +330,7 @@ type TLengthValidation = {
|
|
|
330
330
|
* const callbackValidation: TCallbackValidation = (value) => typeof value === 'string';
|
|
331
331
|
* ```
|
|
332
332
|
*/
|
|
333
|
-
type TCallbackValidation = (value: unknown, formValues: TFormValues<unknown>) => boolean;
|
|
333
|
+
type TCallbackValidation = (value: unknown, formValues: Pick<TFormValues<unknown>, 'values' | 'metadata'>) => boolean;
|
|
334
334
|
/**
|
|
335
335
|
* @type TBetweenValidation
|
|
336
336
|
* Represents validation rules that check if a value is between a range.
|
|
@@ -1314,6 +1314,16 @@ declare class SafeSubject<T> extends Subject<T> {
|
|
|
1314
1314
|
constructor(isMounted: () => boolean);
|
|
1315
1315
|
next(value: T): void;
|
|
1316
1316
|
}
|
|
1317
|
+
/**
|
|
1318
|
+
* Custom RXJS BehaviourSubject to gracefully handle errors on unsubscribed Subjects
|
|
1319
|
+
* since its fire and forget, no mount status needed to check if its available or not
|
|
1320
|
+
*/
|
|
1321
|
+
declare class SafeBehaviourSubject<T> extends BehaviorSubject<T> {
|
|
1322
|
+
defaultValue: T;
|
|
1323
|
+
constructor(value: T);
|
|
1324
|
+
next(value: T): void;
|
|
1325
|
+
get value(): T;
|
|
1326
|
+
}
|
|
1317
1327
|
|
|
1318
1328
|
type TTemplateAvaliableScopes = (typeof TEMPLATE_AVALIABLE_SCOPES)[number];
|
|
1319
1329
|
/**
|
|
@@ -1727,7 +1737,7 @@ declare class FormCore {
|
|
|
1727
1737
|
dataSubject$: Subject<TFormDataPayload>;
|
|
1728
1738
|
formValidSubject$: Subject<TFormValidationPayload>;
|
|
1729
1739
|
fieldValidNotification$: Subject<TFieldValidationPayload>;
|
|
1730
|
-
formValuesStateSubject$:
|
|
1740
|
+
formValuesStateSubject$: SafeBehaviourSubject<TFormValues<unknown>>;
|
|
1731
1741
|
subscribedTemplates: TSubscribedTemplates[];
|
|
1732
1742
|
action?: string;
|
|
1733
1743
|
method?: string;
|
|
@@ -1750,6 +1760,7 @@ declare class FormCore {
|
|
|
1750
1760
|
stopEventsOnSubmit: boolean;
|
|
1751
1761
|
submitted: boolean;
|
|
1752
1762
|
getFormValues: () => TFormValues<unknown>;
|
|
1763
|
+
isolatedFormInstance: boolean;
|
|
1753
1764
|
/**
|
|
1754
1765
|
* Creates an instance of FormCore.
|
|
1755
1766
|
*
|
package/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Subject, Subscription, groupBy, mergeMap, debounceTime, filter, combineLatest, startWith,
|
|
1
|
+
import { BehaviorSubject, Subject, Subscription, groupBy, mergeMap, debounceTime, filter, combineLatest, startWith, map, distinctUntilKeyChanged } from 'rxjs';
|
|
2
2
|
import creditCardType from 'credit-card-type';
|
|
3
3
|
import isNumber$1 from 'lodash/isNumber';
|
|
4
4
|
import { getCurrencySymbol } from '@gaignoux/currency';
|
|
@@ -1594,6 +1594,7 @@ const repeated = (value, validations) => {
|
|
|
1594
1594
|
*
|
|
1595
1595
|
* @param value - The value to be validated.
|
|
1596
1596
|
* @param validations - An object containing validation methods, including a custom callback function.
|
|
1597
|
+
* @param formValues - An object containing the form state, NOTE: validations might be dirty here
|
|
1597
1598
|
* @returns `true` if the custom callback validation function returns `true`, otherwise `false`.
|
|
1598
1599
|
*
|
|
1599
1600
|
* @example
|
|
@@ -1612,9 +1613,20 @@ const repeated = (value, validations) => {
|
|
|
1612
1613
|
* };
|
|
1613
1614
|
* ```
|
|
1614
1615
|
*/
|
|
1615
|
-
const callback = (value, validations,
|
|
1616
|
+
const callback = (value, validations, {
|
|
1617
|
+
values = [],
|
|
1618
|
+
metadata = []
|
|
1619
|
+
} = {
|
|
1620
|
+
values: [],
|
|
1621
|
+
metadata: [],
|
|
1622
|
+
erroredFields: [],
|
|
1623
|
+
isValid: true
|
|
1624
|
+
}) => {
|
|
1616
1625
|
if (!validations.callback || !((validations === null || validations === void 0 ? void 0 : validations.callback) instanceof Function)) return false;
|
|
1617
|
-
return validations.callback(value,
|
|
1626
|
+
return validations.callback(value, {
|
|
1627
|
+
values,
|
|
1628
|
+
metadata
|
|
1629
|
+
});
|
|
1618
1630
|
};
|
|
1619
1631
|
|
|
1620
1632
|
/**
|
|
@@ -2450,6 +2462,28 @@ class SafeSubject extends Subject {
|
|
|
2450
2462
|
}
|
|
2451
2463
|
}
|
|
2452
2464
|
}
|
|
2465
|
+
/**
|
|
2466
|
+
* Custom RXJS BehaviourSubject to gracefully handle errors on unsubscribed Subjects
|
|
2467
|
+
* since its fire and forget, no mount status needed to check if its available or not
|
|
2468
|
+
*/
|
|
2469
|
+
class SafeBehaviourSubject extends BehaviorSubject {
|
|
2470
|
+
constructor(value) {
|
|
2471
|
+
super(value);
|
|
2472
|
+
this.defaultValue = value;
|
|
2473
|
+
}
|
|
2474
|
+
next(value) {
|
|
2475
|
+
if (!this.closed) {
|
|
2476
|
+
super.next(value);
|
|
2477
|
+
}
|
|
2478
|
+
}
|
|
2479
|
+
get value() {
|
|
2480
|
+
if (!this.closed) {
|
|
2481
|
+
return super.value;
|
|
2482
|
+
} else {
|
|
2483
|
+
return this.defaultValue;
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2453
2487
|
|
|
2454
2488
|
/**
|
|
2455
2489
|
* @internal
|
|
@@ -2913,14 +2947,20 @@ class FormField {
|
|
|
2913
2947
|
valueSubscription,
|
|
2914
2948
|
propsSubscription
|
|
2915
2949
|
}) {
|
|
2950
|
+
/*
|
|
2951
|
+
NOTE: using emitEvents here will make ON_FIELD_MOUNT emit twice
|
|
2952
|
+
mount logic is managed on form.ts mountActions on first render
|
|
2953
|
+
*/
|
|
2916
2954
|
this.mounted = true;
|
|
2917
2955
|
this.subscribeValue(valueSubscription);
|
|
2918
2956
|
this.subscribeState(propsSubscription);
|
|
2919
2957
|
this.valueSubject$.next(this.stateValue);
|
|
2920
2958
|
this.propsSubject$.next(this.props);
|
|
2921
2959
|
this.visibilitySubject$.next(this.visibility);
|
|
2922
|
-
this.
|
|
2923
|
-
event: 'ON_FIELD_MOUNT'
|
|
2960
|
+
this.fieldEventSubject$.next({
|
|
2961
|
+
event: 'ON_FIELD_MOUNT',
|
|
2962
|
+
fieldName: this.name,
|
|
2963
|
+
fieldInstance: this
|
|
2924
2964
|
});
|
|
2925
2965
|
}
|
|
2926
2966
|
/**
|
|
@@ -3255,6 +3295,7 @@ class FormCore {
|
|
|
3255
3295
|
this._valid = false;
|
|
3256
3296
|
this.stopEventsOnSubmit = false;
|
|
3257
3297
|
this.submitted = false;
|
|
3298
|
+
this.isolatedFormInstance = false;
|
|
3258
3299
|
this.index = entry.index;
|
|
3259
3300
|
this.schema = entry.schema;
|
|
3260
3301
|
this.fields = new Map();
|
|
@@ -3268,7 +3309,10 @@ class FormCore {
|
|
|
3268
3309
|
(_h = entry.mappers) === null || _h === void 0 ? void 0 : _h.map(mapper => {
|
|
3269
3310
|
this.mappers.set(mapper.componentName, mapper);
|
|
3270
3311
|
});
|
|
3271
|
-
if (
|
|
3312
|
+
if (!entry.submitSubject$ || !entry.dataSubject$ || !entry.formValidSubject$) {
|
|
3313
|
+
this.isolatedFormInstance = true;
|
|
3314
|
+
if (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}`);
|
|
3315
|
+
}
|
|
3272
3316
|
if (this.schema) {
|
|
3273
3317
|
FormCore.checkIndexes(this.schema.components);
|
|
3274
3318
|
}
|
|
@@ -3279,7 +3323,7 @@ class FormCore {
|
|
|
3279
3323
|
this.submitSubject$ = entry.submitSubject$ ? entry.submitSubject$ : new Subject();
|
|
3280
3324
|
this.dataSubject$ = entry.dataSubject$ ? entry.dataSubject$ : new Subject();
|
|
3281
3325
|
this.formValidSubject$ = entry.formValidSubject$ ? entry.formValidSubject$ : new Subject();
|
|
3282
|
-
this.formValuesStateSubject$ = new
|
|
3326
|
+
this.formValuesStateSubject$ = new SafeBehaviourSubject({
|
|
3283
3327
|
erroredFields: [],
|
|
3284
3328
|
isValid: true,
|
|
3285
3329
|
metadata: [],
|
|
@@ -3291,9 +3335,19 @@ class FormCore {
|
|
|
3291
3335
|
this.fieldValidNotification$.subscribe(() => {
|
|
3292
3336
|
this.validateForm();
|
|
3293
3337
|
});
|
|
3338
|
+
/*
|
|
3339
|
+
@TODO check if this emissions can be merged
|
|
3340
|
+
every value update needs to occur after and before validations on field emitValue change
|
|
3341
|
+
so both callback validation and onData values are synced and fields and validations are correct
|
|
3342
|
+
|
|
3343
|
+
check field.ts emitValue and emitEvents
|
|
3344
|
+
*/
|
|
3294
3345
|
this.fieldEventSubject$.subscribe(() => {
|
|
3295
3346
|
this.formValuesStateSubject$.next(this.getFormState());
|
|
3296
3347
|
});
|
|
3348
|
+
this.dataSubject$.subscribe(() => {
|
|
3349
|
+
this.formValuesStateSubject$.next(this.getFormState());
|
|
3350
|
+
});
|
|
3297
3351
|
this.mountSubject$.subscribe(this.mountActions.bind(this));
|
|
3298
3352
|
this.initialValues = entry.initialValues || ((_j = entry.schema) === null || _j === void 0 ? void 0 : _j.initialValues);
|
|
3299
3353
|
this.iVars = entry.iVars || ((_k = entry.schema) === null || _k === void 0 ? void 0 : _k.iVars) || {};
|
|
@@ -4241,13 +4295,15 @@ class FormCore {
|
|
|
4241
4295
|
destroy() {
|
|
4242
4296
|
this.templateSubject$.unsubscribe();
|
|
4243
4297
|
this.templateSubscription$.unsubscribe();
|
|
4244
|
-
this.submitSubject$.unsubscribe();
|
|
4245
4298
|
this.mountSubject$.unsubscribe();
|
|
4246
4299
|
this.fieldEventSubject$.unsubscribe();
|
|
4247
|
-
this.dataSubject$.unsubscribe();
|
|
4248
|
-
this.formValidSubject$.unsubscribe();
|
|
4249
4300
|
this.fieldValidNotification$.unsubscribe();
|
|
4250
4301
|
this.formValuesStateSubject$.unsubscribe();
|
|
4302
|
+
if (this.isolatedFormInstance) {
|
|
4303
|
+
this.submitSubject$.unsubscribe();
|
|
4304
|
+
this.dataSubject$.unsubscribe();
|
|
4305
|
+
this.formValidSubject$.unsubscribe();
|
|
4306
|
+
}
|
|
4251
4307
|
this.fields.forEach(field => field.destroyField());
|
|
4252
4308
|
}
|
|
4253
4309
|
}
|