@reactables/forms 0.5.4-alpha.0 → 0.7.0-alpha.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.
Files changed (32) hide show
  1. package/README.md +208 -33
  2. package/dist/Helpers/buildHub2Source.d.ts +2 -2
  3. package/dist/Models/Configs.d.ts +1 -0
  4. package/dist/Models/Controls.d.ts +6 -2
  5. package/dist/Models/Payloads.d.ts +4 -4
  6. package/dist/Models/index.d.ts +1 -1
  7. package/dist/Reducers/Hub1/addControl.d.ts +2 -2
  8. package/dist/Reducers/Hub1/markControlAsPristine.d.ts +1 -1
  9. package/dist/Reducers/Hub1/markControlAsTouched.d.ts +2 -2
  10. package/dist/Reducers/Hub1/markControlAsUntouched.d.ts +1 -1
  11. package/dist/Reducers/Hub1/pushControl.d.ts +2 -2
  12. package/dist/Reducers/Hub1/removeControl.d.ts +1 -1
  13. package/dist/Reducers/Hub1/resetControl.d.ts +1 -1
  14. package/dist/Reducers/Hub1/updateAncestorValues.d.ts +2 -2
  15. package/dist/Reducers/Hub1/updateAncestorValuesAddControl.d.ts +2 -2
  16. package/dist/Reducers/Hub1/updateValues.d.ts +2 -2
  17. package/dist/Reducers/Hub2/{mergePushControl.d.ts → mergeControls.d.ts} +5 -6
  18. package/dist/RxForm/RxForm.d.ts +28 -8
  19. package/dist/RxForm/Tests/customReducers.test.d.ts +1 -0
  20. package/dist/RxForm/Tests/initialization.test.d.ts +1 -0
  21. package/dist/RxForm/Tests/markControlAsPristine.test.d.ts +1 -0
  22. package/dist/RxForm/Tests/markControlTouchStatus.test.d.ts +1 -0
  23. package/dist/RxForm/Tests/pushControl.test.d.ts +1 -0
  24. package/dist/RxForm/Tests/removeControl.test.d.ts +1 -0
  25. package/dist/RxForm/Tests/resetControl.test.d.ts +1 -0
  26. package/dist/RxForm/Tests/updateValues.test.d.ts +1 -0
  27. package/dist/RxForm/index.d.ts +1 -1
  28. package/dist/index.js +360 -296
  29. package/package.json +2 -2
  30. package/dist/Reducers/Hub2/mergeTouchUpdated.d.ts +0 -6
  31. package/dist/Reducers/Hub2/mergeValueUpdated.d.ts +0 -6
  32. /package/dist/RxForm/{RxForm.test.d.ts → Tests/addControl.test.d.ts} +0 -0
package/dist/index.js CHANGED
@@ -79,6 +79,18 @@ var __assign = function() {
79
79
  return __assign.apply(this, arguments);
80
80
  };
81
81
 
82
+ function __rest(s, e) {
83
+ var t = {};
84
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
85
+ t[p] = s[p];
86
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
87
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
88
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
89
+ t[p[i]] = s[p[i]];
90
+ }
91
+ return t;
92
+ }
93
+
82
94
  function __spreadArray(to, from, pack) {
83
95
  if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
84
96
  if (ar || !(i in from)) {
@@ -171,71 +183,10 @@ var buildFormState = function (config, form, controlRef) {
171
183
  if (form === void 0) { form = { root: null }; }
172
184
  if (controlRef === void 0) { controlRef = []; }
173
185
  return {
174
- form: buildState(config, form, controlRef),
175
- action: null
186
+ form: buildState(config, form, controlRef)
176
187
  };
177
188
  };
178
189
 
179
- var getControl = function (controlRef, form) {
180
- return form[getFormKey(controlRef)];
181
- };
182
-
183
- // Includes the original control of interest unless excludeSelf === true
184
- var getAncestorControls = function (controlRef, form, excludeSelf) {
185
- if (excludeSelf === void 0) { excludeSelf = false; }
186
- var formControls = controlRef.reduce(function (acc, key) {
187
- var currentRef = acc.currentRef.concat(key);
188
- var formControls = acc.formControls.concat(getControl(currentRef, form));
189
- return {
190
- currentRef: currentRef,
191
- formControls: formControls
192
- };
193
- }, {
194
- currentRef: [],
195
- formControls: []
196
- }).formControls;
197
- var root = form['root'];
198
- var result = [root].concat(formControls);
199
- return result.filter(function (control) {
200
- return excludeSelf ? getFormKey(control.controlRef) !== getFormKey(controlRef) : true;
201
- });
202
- };
203
-
204
- // Includes the original control of interest unless excludeSelf === true
205
- var getDescendantControls = function (controlRef, form, excludeSelf) {
206
- if (excludeSelf === void 0) { excludeSelf = false; }
207
- if (!controlRef.length) {
208
- return Object.values(form).filter(function (_a) {
209
- var controlRef = _a.controlRef;
210
- return excludeSelf ? controlRef.length !== 0 : true;
211
- });
212
- }
213
- var control = getControl(controlRef, form);
214
- var value = control.value, config = control.config;
215
- var descendants;
216
- if (Array.isArray(config.controls)) {
217
- // If control is a Form Array
218
- descendants = value.reduce(function (acc, item, index) {
219
- return acc.concat(getDescendantControls(controlRef.concat(index), form));
220
- }, []);
221
- }
222
- else if (config.controls) {
223
- // If control is a Form Group
224
- descendants = Object.keys(value).reduce(function (acc, key) {
225
- return acc.concat(getDescendantControls(controlRef.concat(key), form));
226
- }, []);
227
- }
228
- if (excludeSelf)
229
- return descendants;
230
- return [control].concat(descendants || []);
231
- };
232
-
233
- var getControlBranch = function (controlRef, form) {
234
- var ancestors = getAncestorControls(controlRef, form);
235
- var childControls = getDescendantControls(controlRef, form).slice(1);
236
- return ancestors.concat(childControls).sort(function (a, b) { return a.controlRef.length - b.controlRef.length; });
237
- };
238
-
239
190
  var getScopedEffectsForControl = function (formControl) {
240
191
  var config = formControl.config, key = formControl.key;
241
192
  var asyncValidators = config.asyncValidators;
@@ -270,44 +221,21 @@ var getAsyncValidationActions = function (formControls) {
270
221
  }, []);
271
222
  };
272
223
 
273
- var buildHub2Source = function (rx) {
274
- var hub1StateMapped$ = rx.state$.pipe(operators.map(function (payload) { return ({ type: 'formChange', payload: payload }); }));
224
+ var buildHub2Source = function (hub1State$) {
225
+ var hub1StateMapped$ = hub1State$.pipe(operators.map(function (payload) { return ({ type: 'formChange', payload: payload }); }));
275
226
  var sourceForHub2$ = hub1StateMapped$.pipe(operators.mergeMap(function (formChangeAction) {
276
- var _a = formChangeAction.payload, form = _a.form, action = _a.action;
277
- var newForm = form;
278
- var controlsToCheck;
279
- switch (action === null || action === void 0 ? void 0 : action.type) {
280
- case 'updateValues':
281
- controlsToCheck = getControlBranch(action.payload.controlRef, newForm);
282
- break;
283
- case 'pushControl':
284
- case 'addControl':
285
- var changedControl = getControl(action.payload.controlRef, newForm);
286
- if (Array.isArray(changedControl.config.controls)) {
287
- var index = changedControl.value.length - 1;
288
- var ref = action.payload.controlRef.concat(index);
289
- controlsToCheck = getControlBranch(ref, newForm);
290
- break;
291
- }
292
- else {
293
- controlsToCheck = getControlBranch(action.payload.controlRef, newForm);
294
- break;
295
- }
296
- case 'removeControl':
297
- controlsToCheck = getAncestorControls(action.payload.slice(0, -1), newForm);
298
- break;
299
- case 'resetControl':
300
- controlsToCheck = getControlBranch(action.payload, newForm);
301
- break;
302
- default:
303
- controlsToCheck = [];
304
- }
227
+ var changedControls = formChangeAction.payload.changedControls;
228
+ var controlsToCheck = changedControls ? Object.values(changedControls) : [];
305
229
  var asyncValidationActions = getAsyncValidationActions(controlsToCheck);
306
230
  return rxjs.of.apply(void 0, __spreadArray([formChangeAction], asyncValidationActions, false));
307
231
  }));
308
232
  return sourceForHub2$;
309
233
  };
310
234
 
235
+ var getControl = function (controlRef, form) {
236
+ return form[getFormKey(controlRef)];
237
+ };
238
+
311
239
  var UPDATE_ANCESTOR_VALUES = 'UPDATE_ANCESTOR_VALUES';
312
240
  var updateAncestorValues = function (form, _a) {
313
241
  var _b, _c;
@@ -342,17 +270,71 @@ var isChildRef = function (controlRef, parentRef) {
342
270
  controlRef.length === parentRef.length + 1);
343
271
  };
344
272
 
273
+ // Includes the original control of interest unless excludeSelf === true
274
+ var getDescendantControls = function (controlRef, form, excludeSelf) {
275
+ if (excludeSelf === void 0) { excludeSelf = false; }
276
+ if (!controlRef.length) {
277
+ return Object.values(form).filter(function (_a) {
278
+ var controlRef = _a.controlRef;
279
+ return excludeSelf ? controlRef.length !== 0 : true;
280
+ });
281
+ }
282
+ var control = getControl(controlRef, form);
283
+ var value = control.value, config = control.config;
284
+ var descendants;
285
+ if (Array.isArray(config.controls)) {
286
+ // If control is a Form Array
287
+ descendants = value.reduce(function (acc, item, index) {
288
+ return acc.concat(getDescendantControls(controlRef.concat(index), form));
289
+ }, []);
290
+ }
291
+ else if (config.controls) {
292
+ // If control is a Form Group
293
+ descendants = Object.keys(value).reduce(function (acc, key) {
294
+ return acc.concat(getDescendantControls(controlRef.concat(key), form));
295
+ }, []);
296
+ }
297
+ if (excludeSelf)
298
+ return descendants;
299
+ return [control].concat(descendants || []);
300
+ };
301
+
302
+ // Includes the original control of interest unless excludeSelf === true
303
+ var getAncestorControls = function (controlRef, form, excludeSelf) {
304
+ if (excludeSelf === void 0) { excludeSelf = false; }
305
+ var formControls = controlRef.reduce(function (acc, key) {
306
+ var currentRef = acc.currentRef.concat(key);
307
+ var formControls = acc.formControls.concat(getControl(currentRef, form));
308
+ return {
309
+ currentRef: currentRef,
310
+ formControls: formControls
311
+ };
312
+ }, {
313
+ currentRef: [],
314
+ formControls: []
315
+ }).formControls;
316
+ var root = form['root'];
317
+ var result = [root].concat(formControls);
318
+ return result.filter(function (control) {
319
+ return excludeSelf ? getFormKey(control.controlRef) !== getFormKey(controlRef) : true;
320
+ });
321
+ };
322
+
345
323
  var UPDATE_DESCENDANT_VALUES = 'UPDATE_DESCENDANT_VALUES';
346
- var updateDescendants = function (form, _a) {
324
+ var updateDescendants = function (state, _a) {
347
325
  var _b = _a.payload, controlRef = _b.controlRef, value = _b.value;
348
- var descendants = getDescendantControls(controlRef, form, true).map(function (control) { return [getFormKey(control.controlRef), control]; });
326
+ var descendants = getDescendantControls(controlRef, state.form, true).map(function (control) { return [getFormKey(control.controlRef), control]; });
349
327
  var result = descendants.reduce(function (acc, _a) {
350
- var _b;
328
+ var _b, _c;
351
329
  var key = _a[0], control = _a[1];
352
330
  if (isChildRef(control.controlRef, controlRef)) {
353
331
  var childValue = value[control.controlRef.at(-1)];
354
332
  var validatorErrors = getErrors(control, value);
355
- acc = __assign(__assign({}, acc), (_b = {}, _b[key] = __assign(__assign({}, control), { value: childValue, validatorErrors: validatorErrors, dirty: !isEqual__default["default"](childValue, control.pristineValue) }), _b));
333
+ var newControl = __assign(__assign({}, control), { value: childValue, validatorErrors: validatorErrors, dirty: !isEqual__default["default"](childValue, control.pristineValue) });
334
+ acc = {
335
+ form: __assign(__assign({}, acc.form), (_b = {}, _b[key] = newControl, _b)),
336
+ changedControls: __assign(__assign({}, acc.changedControls), (_c = {}, _c[newControl.key] = newControl, _c))
337
+ };
356
338
  var configControls = control.config.controls;
357
339
  if (configControls) {
358
340
  acc = updateDescendants(acc, {
@@ -362,38 +344,56 @@ var updateDescendants = function (form, _a) {
362
344
  }
363
345
  }
364
346
  return acc;
365
- }, form);
366
- return result;
347
+ }, { form: {}, changedControls: {} });
348
+ return {
349
+ form: __assign(__assign({}, state.form), result.form),
350
+ changedControls: __assign({}, result.changedControls)
351
+ };
367
352
  };
368
353
  // Will only update child controls that are present.
369
- // Use AddControl/RemoveControl action reducers to add/remove control
370
- var updateValues = function (_a, action) {
371
- var _b;
372
- var form = _a.form;
373
- var _c = action.payload, controlRef = _c.controlRef, value = _c.value;
354
+ // Use AddControlPayload/RemoveControl action reducers to add/remove control
355
+ var updateValues = function (_a, action, mergeChanges) {
356
+ var _b, _c;
357
+ var form = _a.form, _d = _a.changedControls, changedControls = _d === void 0 ? {} : _d, _e = _a.removedControls, removedControls = _e === void 0 ? {} : _e;
358
+ if (mergeChanges === void 0) { mergeChanges = false; }
359
+ var _f = action.payload, controlRef = _f.controlRef, value = _f.value;
374
360
  // Update its own value
375
361
  var ctrlKey = getFormKey(controlRef);
376
- var validatorErrors = getErrors(form[ctrlKey], value);
377
- var result = __assign(__assign({}, form), (_b = {}, _b[ctrlKey] = __assign(__assign({}, form[ctrlKey]), { validatorErrors: validatorErrors, dirty: !isEqual__default["default"](value, form[ctrlKey].pristineValue), value: value }), _b));
378
- var configControls = form[ctrlKey].config.controls;
362
+ var newValue = value;
363
+ var config = form[ctrlKey].config;
364
+ if (config.normalizers) {
365
+ newValue = config.normalizers.reduce(function (acc, normalizer) { return normalizer(acc); }, value);
366
+ }
367
+ var validatorErrors = getErrors(form[ctrlKey], newValue);
368
+ var newControl = __assign(__assign({}, form[ctrlKey]), { validatorErrors: validatorErrors, dirty: !isEqual__default["default"](value, form[ctrlKey].pristineValue), value: newValue });
369
+ var result = {
370
+ form: __assign(__assign({}, form), (_b = {}, _b[ctrlKey] = newControl, _b)),
371
+ changedControls: (_c = {}, _c[newControl.key] = newControl, _c)
372
+ };
373
+ var configControls = config.controls;
379
374
  // Update its children
380
375
  if (configControls) {
381
376
  result = updateDescendants(result, {
382
377
  type: UPDATE_DESCENDANT_VALUES,
383
378
  payload: {
384
379
  controlRef: controlRef,
385
- value: value
380
+ value: newValue
386
381
  }
387
382
  });
388
383
  }
389
384
  // Update its Ancestors
390
385
  if (controlRef.length) {
391
- result = updateAncestorValues(result, {
392
- type: UPDATE_ANCESTOR_VALUES,
393
- payload: { controlRef: controlRef, value: value }
394
- });
386
+ result = __assign(__assign({}, result), { form: updateAncestorValues(result.form, {
387
+ type: UPDATE_ANCESTOR_VALUES,
388
+ payload: { controlRef: controlRef, value: newValue }
389
+ }) });
395
390
  }
396
- return { form: result, action: action };
391
+ var changedAncestorControls = getAncestorControls(controlRef, result.form).reduce(function (acc, control) {
392
+ var _a;
393
+ return (__assign(__assign({}, acc), (_a = {}, _a[control.key] = control, _a)));
394
+ }, {});
395
+ var mergedResult = __assign(__assign({}, result), { changedControls: __assign(__assign(__assign({}, (mergeChanges ? changedControls : undefined)), changedAncestorControls), result.changedControls), removedControls: mergeChanges ? removedControls : undefined });
396
+ return mergedResult;
397
397
  };
398
398
 
399
399
  var UPDATE_ANCESTOR_VALUES_REMOVE_CONTROL = 'UPDATE_ANCESTOR_VALUES_REMOVE_CONTROL';
@@ -424,18 +424,22 @@ var updateAncestorValuesRemoveControl = function (form, _a) {
424
424
  return form;
425
425
  };
426
426
 
427
- var removeControl = function (_a, action) {
428
- var form = _a.form;
427
+ var removeControl = function (state, action, mergeChanges) {
428
+ var _a;
429
+ if (mergeChanges === void 0) { mergeChanges = false; }
430
+ var form = state.form;
429
431
  var controlRef = action.payload;
430
- if (!getControl(controlRef, form)) {
432
+ var controlToRemove = getControl(controlRef, form);
433
+ if (!controlToRemove) {
431
434
  throw 'Control not found';
432
435
  }
433
436
  // Can't remove the root of the form
434
437
  if (!controlRef.length)
435
- return { form: form, action: action };
438
+ return { form: form };
436
439
  var parentRef = controlRef.slice(0, -1);
437
440
  var parentIsFormArray = Array.isArray(getControl(parentRef, form).config.controls);
438
- var descendantkeys = getDescendantControls(controlRef, form).map(function (_a) {
441
+ var descendants = getDescendantControls(controlRef, form);
442
+ var descendantkeys = descendants.map(function (_a) {
439
443
  var controlRef = _a.controlRef;
440
444
  return getFormKey(controlRef);
441
445
  });
@@ -466,12 +470,50 @@ var removeControl = function (_a, action) {
466
470
  }
467
471
  return __assign(__assign({}, acc), (_c = {}, _c[key] = control, _c));
468
472
  }, {});
473
+ var result = updateAncestorValuesRemoveControl(controlRemoved, {
474
+ type: UPDATE_ANCESTOR_VALUES_REMOVE_CONTROL,
475
+ payload: controlRef
476
+ });
477
+ var changedControls = __assign(__assign({}, (mergeChanges ? state.changedControls || {} : undefined)), getAncestorControls(controlRef.slice(0, -1), result).reduce(function (acc, control) {
478
+ var _a;
479
+ return (__assign(__assign({}, acc), (_a = {}, _a[control.key] = control, _a)));
480
+ }, {}));
481
+ // Check for reindexing for changed controls
482
+ if (parentIsFormArray) {
483
+ changedControls = Object.entries(changedControls).reduce(function (acc, _a) {
484
+ var _b, _c;
485
+ var key = _a[0], control = _a[1];
486
+ var oldIndex = control.controlRef.at(parentRef.length);
487
+ if (
488
+ // If control is descendant.
489
+ parentRef.every(function (ref, index) { return control.controlRef[index] === ref; }) &&
490
+ control.controlRef.length > parentRef.length &&
491
+ // If the array item index was greater than the index of item removed
492
+ // we need to decrement its index by 1.
493
+ oldIndex > controlRef.at(-1)) {
494
+ var newRef = parentRef
495
+ .concat(oldIndex - 1)
496
+ .concat(control.controlRef.slice(parentRef.length + 1));
497
+ return __assign(__assign({}, acc), (_b = {}, _b[getFormKey(newRef)] = __assign(__assign({}, control), { controlRef: newRef }), _b));
498
+ }
499
+ else {
500
+ return __assign(__assign({}, acc), (_c = {}, _c[key] = control, _c));
501
+ }
502
+ }, {});
503
+ }
504
+ var removedControls = __assign(__assign({}, (mergeChanges ? state.removedControls || {} : undefined)), (_a = {}, _a[controlToRemove.key] = controlToRemove, _a));
505
+ descendants
506
+ .map(function (_a) {
507
+ var key = _a.key;
508
+ return key;
509
+ })
510
+ .forEach(function (key) {
511
+ delete changedControls[key];
512
+ });
469
513
  return {
470
- form: updateAncestorValuesRemoveControl(controlRemoved, {
471
- type: UPDATE_ANCESTOR_VALUES_REMOVE_CONTROL,
472
- payload: controlRef
473
- }),
474
- action: action
514
+ form: result,
515
+ changedControls: changedControls,
516
+ removedControls: removedControls
475
517
  };
476
518
  };
477
519
 
@@ -502,31 +544,38 @@ var updateAncestorValuesAddControl = function (form, _a) {
502
544
  return form;
503
545
  };
504
546
 
505
- var addControl = function (state, action) {
506
- var newControlRef;
547
+ var getControlBranch = function (controlRef, form) {
548
+ var ancestors = getAncestorControls(controlRef, form);
549
+ var childControls = getDescendantControls(controlRef, form).slice(1);
550
+ return ancestors.concat(childControls).sort(function (a, b) { return a.controlRef.length - b.controlRef.length; });
551
+ };
552
+
553
+ var addControl = function (state, action, mergeChanges) {
554
+ if (mergeChanges === void 0) { mergeChanges = false; }
507
555
  var _a = action.payload, config = _a.config, controlRef = _a.controlRef;
508
- var existingControl = getControl(controlRef, state.form);
509
- // If controlRef exists we are adding control to a Form Array
510
- if (existingControl && Array.isArray(existingControl.config.controls)) {
511
- newControlRef = controlRef.concat(existingControl.value.length);
556
+ // If controlRef does not exist we are adding control to a Form Group
557
+ if (!getControl(controlRef.slice(0, -1), state.form)) {
558
+ throw 'You are attempting to add a control to a non-existent form group';
512
559
  }
513
- else {
514
- // If controlRef does not exist we are adding control to a Form Group
515
- if (!getControl(controlRef.slice(0, -1), state.form)) {
516
- throw 'You are attempting to add a control to a non-existent form group';
517
- }
518
- newControlRef = controlRef;
519
- }
520
- var newForm = buildState(config, state.form, newControlRef);
521
- var newValue = getControl(newControlRef, newForm).value;
560
+ var newForm = buildState(config, state.form, controlRef);
561
+ var newValue = getControl(controlRef, newForm).value;
522
562
  var ancestorsUpdated = updateAncestorValuesAddControl(newForm, {
523
563
  type: UPDATE_ANCESTOR_VALUES_ADD_CONTROL,
524
- payload: { controlRef: newControlRef, value: newValue }
564
+ payload: { controlRef: controlRef, value: newValue }
525
565
  });
526
- return { form: ancestorsUpdated, action: action };
566
+ var changedControls = getControlBranch(controlRef, ancestorsUpdated).reduce(function (acc, control) {
567
+ var _a;
568
+ return (__assign(__assign({}, acc), (_a = {}, _a[control.key] = control, _a)));
569
+ }, {});
570
+ return {
571
+ form: ancestorsUpdated,
572
+ changedControls: __assign(__assign({}, (mergeChanges ? state.changedControls || {} : undefined)), changedControls),
573
+ removedControls: mergeChanges ? state.removedControls || {} : undefined
574
+ };
527
575
  };
528
576
 
529
- var pushControl = function (state, action) {
577
+ var pushControl = function (state, action, mergeChanges) {
578
+ if (mergeChanges === void 0) { mergeChanges = false; }
530
579
  var newControlRef;
531
580
  var _a = action.payload, config = _a.config, controlRef = _a.controlRef;
532
581
  var existingControl = getControl(controlRef, state.form);
@@ -545,7 +594,15 @@ var pushControl = function (state, action) {
545
594
  type: UPDATE_ANCESTOR_VALUES_ADD_CONTROL,
546
595
  payload: { controlRef: newControlRef, value: newValue }
547
596
  });
548
- return { form: ancestorsUpdated, action: action };
597
+ var changedControls = getControlBranch(newControlRef, ancestorsUpdated).reduce(function (acc, control) {
598
+ var _a;
599
+ return (__assign(__assign({}, acc), (_a = {}, _a[control.key] = control, _a)));
600
+ }, {});
601
+ return {
602
+ form: ancestorsUpdated,
603
+ changedControls: __assign(__assign({}, (mergeChanges ? state.changedControls || {} : undefined)), changedControls),
604
+ removedControls: mergeChanges ? state.removedControls || {} : undefined
605
+ };
549
606
  };
550
607
 
551
608
  // Same implementation as updateAncestor values except updating pristine values
@@ -584,8 +641,9 @@ var updateAncestorPristineValues = function (form, _a) {
584
641
  return form;
585
642
  };
586
643
 
587
- var markControlAsPristine = function (_a, action) {
588
- var form = _a.form;
644
+ var markControlAsPristine = function (state, action, mergeChanges) {
645
+ if (mergeChanges === void 0) { mergeChanges = false; }
646
+ var form = state.form;
589
647
  var controlRef = action.payload;
590
648
  var descendants = getDescendantControls(controlRef, form).reduce(function (acc, control) {
591
649
  var _a;
@@ -598,25 +656,44 @@ var markControlAsPristine = function (_a, action) {
598
656
  payload: controlRef
599
657
  });
600
658
  }
601
- return { form: result, action: action };
659
+ var changedControls = getControlBranch(controlRef, result).reduce(function (acc, control) {
660
+ var _a;
661
+ return (__assign(__assign({}, acc), (_a = {}, _a[control.key] = control, _a)));
662
+ }, {});
663
+ return {
664
+ form: result,
665
+ changedControls: __assign(__assign({}, (mergeChanges ? state.changedControls || {} : undefined)), changedControls),
666
+ removedControls: mergeChanges ? state.removedControls || {} : undefined
667
+ };
602
668
  };
603
669
 
604
- var markControlAsTouched = function (_a, action) {
605
- var form = _a.form;
606
- var _b = action.payload, controlRef = _b.controlRef, markAll = _b.markAll;
670
+ var markControlAsTouched = function (state, action, mergeChanges) {
671
+ if (mergeChanges === void 0) { mergeChanges = false; }
672
+ var form = state.form;
673
+ var _a = action.payload, controlRef = _a.controlRef, markAll = _a.markAll;
607
674
  var controls = (markAll ? getControlBranch(controlRef, form) : getAncestorControls(controlRef, form)).reduce(function (acc, control) {
608
675
  var _a;
609
676
  return (__assign(__assign({}, acc), (_a = {}, _a[getFormKey(control.controlRef)] = __assign(__assign({}, control), { touched: true }), _a)));
610
677
  }, {});
611
- return {
678
+ var result = {
612
679
  form: __assign(__assign({}, form), controls),
613
680
  action: action
614
681
  };
682
+ var changedControls = getControlBranch(controlRef, result.form).reduce(function (acc, control) {
683
+ var _a;
684
+ return (__assign(__assign({}, acc), (_a = {}, _a[control.key] = control, _a)));
685
+ }, {});
686
+ return {
687
+ form: __assign(__assign({}, form), controls),
688
+ changedControls: __assign(__assign({}, (mergeChanges ? state.changedControls || {} : undefined)), changedControls),
689
+ removedControls: mergeChanges ? state.removedControls || {} : undefined
690
+ };
615
691
  };
616
692
 
617
- var markControlAsUntouched = function (_a, action) {
618
- var _b;
619
- var form = _a.form;
693
+ var markControlAsUntouched = function (state, action, mergeChanges) {
694
+ var _a;
695
+ if (mergeChanges === void 0) { mergeChanges = false; }
696
+ var form = state.form;
620
697
  var controlRef = action.payload;
621
698
  var result = getDescendantControls(controlRef, form).reduce(function (acc, control) {
622
699
  var _a;
@@ -629,32 +706,59 @@ var markControlAsUntouched = function (_a, action) {
629
706
  while (currentRef.length > 0) {
630
707
  currentRef = currentRef.slice(0, -1);
631
708
  key = getFormKey(currentRef);
632
- result = __assign(__assign({}, result), (_b = {}, _b[key] = __assign(__assign({}, result[key]), { touched: getDescendantControls(currentRef, result, true).some(function (control) { return control.touched; }) }), _b));
709
+ result = __assign(__assign({}, result), (_a = {}, _a[key] = __assign(__assign({}, result[key]), { touched: getDescendantControls(currentRef, result, true).some(function (control) { return control.touched; }) }), _a));
633
710
  }
634
- return { form: result, action: action };
711
+ var changedControls = getControlBranch(controlRef, result).reduce(function (acc, control) {
712
+ var _a;
713
+ return (__assign(__assign({}, acc), (_a = {}, _a[control.key] = control, _a)));
714
+ }, {});
715
+ return {
716
+ form: result,
717
+ changedControls: __assign(__assign({}, (mergeChanges ? state.changedControls || {} : undefined)), changedControls),
718
+ removedControls: mergeChanges ? state.removedControls || {} : undefined
719
+ };
635
720
  };
636
721
 
637
- var resetControl = function (_a, action) {
638
- var form = _a.form;
722
+ var resetControl = function (state, action, mergeChanges) {
723
+ var _a;
724
+ if (mergeChanges === void 0) { mergeChanges = false; }
725
+ var form = state.form;
639
726
  var controlRef = action.payload;
640
727
  var controlToReset = getControl(controlRef, form);
728
+ var descendantsRemoved = __assign({}, form);
641
729
  var descendants = getDescendantControls(controlRef, form);
730
+ var descendantKeys = descendants.map(function (_a) {
731
+ var controlRef = _a.controlRef;
732
+ return getFormKey(controlRef);
733
+ });
734
+ descendantKeys.forEach(function (key) {
735
+ delete descendantsRemoved[key];
736
+ });
642
737
  // Remove all descendants
643
- var descendantsRemoved = Object.entries(form).reduce(function (acc, _a) {
644
- var _b;
645
- var key = _a[0], control = _a[1];
646
- if (descendants.includes(control))
647
- return acc;
648
- return __assign(__assign({}, acc), (_b = {}, _b[key] = control, _b));
649
- }, {});
650
738
  var restoredControls = buildState(controlToReset.config, descendantsRemoved, controlToReset.controlRef);
651
739
  var restoredControlValue = getControl(controlRef, restoredControls).value;
740
+ var result = updateAncestorValues(restoredControls, {
741
+ type: UPDATE_ANCESTOR_VALUES,
742
+ payload: { controlRef: controlRef, value: restoredControlValue }
743
+ });
744
+ var changedControls = __assign(__assign({}, (mergeChanges ? state.changedControls || {} : undefined)), getControlBranch(controlRef, result).reduce(function (acc, control) {
745
+ var _a;
746
+ return (__assign(__assign({}, acc), (_a = {}, _a[control.key] = control, _a)));
747
+ }, {}));
748
+ var removedControls = __assign(__assign({}, (mergeChanges ? state.removedControls || {} : undefined)), (_a = {}, _a[controlToReset.key] = controlToReset, _a));
749
+ // If control is removed, we can delete it from the changedControls check
750
+ descendants
751
+ .map(function (_a) {
752
+ var key = _a.key;
753
+ return key;
754
+ })
755
+ .forEach(function (key) {
756
+ delete changedControls[key];
757
+ });
652
758
  return {
653
- form: updateAncestorValues(restoredControls, {
654
- type: UPDATE_ANCESTOR_VALUES,
655
- payload: { controlRef: controlRef, value: restoredControlValue }
656
- }),
657
- action: action
759
+ form: result,
760
+ changedControls: changedControls,
761
+ removedControls: removedControls
658
762
  };
659
763
  };
660
764
 
@@ -672,7 +776,7 @@ var asyncValidation = function (form, _a) {
672
776
  return __assign(__assign({}, form), updatedSelfAndAncestors);
673
777
  };
674
778
 
675
- var hasErrors$4 = function (errors) {
779
+ var hasErrors$3 = function (errors) {
676
780
  return Object.values(errors).some(function (hasError) { return hasError; });
677
781
  };
678
782
  var mergeBranchErrors = function (form, controlRef) {
@@ -686,7 +790,7 @@ var mergeBranchErrors = function (form, controlRef) {
686
790
  var _b;
687
791
  var key = _a[0], control = _a[1];
688
792
  var errors = __assign(__assign({}, control.validatorErrors), control.asyncValidatorErrors);
689
- var selfValid = !hasErrors$4(errors);
793
+ var selfValid = !hasErrors$3(errors);
690
794
  var childrenValid = true;
691
795
  if (Array.isArray(control.config.controls)) {
692
796
  // If control is a FormArray
@@ -738,7 +842,7 @@ var asyncValidationResponseSuccess = function (form, _a) {
738
842
  return mergeBranchErrors(ancestorsUpdated, control.controlRef);
739
843
  };
740
844
 
741
- var hasErrors$3 = function (errors) {
845
+ var hasErrors$2 = function (errors) {
742
846
  return Object.values(errors).some(function (hasError) { return hasError; });
743
847
  };
744
848
  // TODO: update merge errors to not do the entire form but just a subset of it
@@ -750,7 +854,7 @@ var mergeErrors = function (form) {
750
854
  var _b;
751
855
  var key = _a[0], control = _a[1];
752
856
  var errors = __assign(__assign({}, control.validatorErrors), control.asyncValidatorErrors);
753
- var selfValid = !hasErrors$3(errors);
857
+ var selfValid = !hasErrors$2(errors);
754
858
  var childrenValid = true;
755
859
  if (Array.isArray(control.config.controls)) {
756
860
  // If control is a FormArray
@@ -771,40 +875,6 @@ var mergeErrors = function (form) {
771
875
  return restoredOrder;
772
876
  };
773
877
 
774
- var hasErrors$2 = function (errors) {
775
- return Object.values(errors).some(function (hasError) { return hasError; });
776
- };
777
- var mergeValueUpdated = function (state, form, controlRef) {
778
- var controlBranch = getControlBranch(controlRef, form)
779
- .reverse()
780
- .reduce(function (acc, control) {
781
- var _a;
782
- var key = getFormKey(control.controlRef);
783
- var existingControl = state[key] || structuredClone(DEFAULT_HUB2_FIELDS);
784
- var errors = __assign(__assign({}, control.validatorErrors), existingControl.asyncValidatorErrors);
785
- var selfValid = !hasErrors$2(errors);
786
- var childrenValid = true;
787
- if (Array.isArray(control.config.controls)) {
788
- // If control is a FormArray
789
- childrenValid = control.value.every(function (item, index) {
790
- var formKey = getFormKey(control.controlRef.concat(index));
791
- var valid = acc[formKey] === undefined ? state[formKey].valid : acc[formKey].valid;
792
- return valid;
793
- });
794
- }
795
- else if (control.config.controls) {
796
- // If control is a FormGroup
797
- childrenValid = Object.keys(control.value).every(function (childKey) {
798
- var formKey = getFormKey(control.controlRef.concat(childKey));
799
- var valid = acc[formKey] === undefined ? state[formKey].valid : acc[formKey].valid;
800
- return valid;
801
- });
802
- }
803
- return __assign(__assign({}, acc), (_a = {}, _a[key] = __assign(__assign(__assign({}, existingControl), control), { errors: errors, valid: selfValid && childrenValid, childrenValid: childrenValid }), _a));
804
- }, {});
805
- return __assign(__assign({}, state), controlBranch);
806
- };
807
-
808
878
  var hasErrors$1 = function (errors) {
809
879
  return Object.values(errors).some(function (hasError) { return hasError; });
810
880
  };
@@ -848,70 +918,55 @@ var mergeRemoveControl = function (state, form, controlRef) {
848
918
  return __assign(__assign({}, removedControls), updatedControlBranch);
849
919
  };
850
920
 
851
- var mergeTouchUpdated = function (state, form, controlRef) {
852
- var controlBranch = getControlBranch(controlRef, form).reduce(function (acc, control) {
853
- var _a;
854
- var key = getFormKey(control.controlRef);
855
- return __assign(__assign({}, acc), (_a = {}, _a[key] = __assign(__assign({}, state[key]), control), _a));
856
- }, {});
857
- return __assign(__assign({}, state), controlBranch);
858
- };
859
-
860
921
  var hasErrors = function (errors) {
861
922
  return Object.values(errors).some(function (hasError) { return hasError; });
862
923
  };
863
- var mergePushControl = function (state, form, controlRef) {
864
- var baseFormArray = getControl(controlRef, form);
865
- //If Form Array
866
- // use the added control (last index)
867
- // merge descendants with default stuff
868
- var newItemIndex = baseFormArray.value.length - 1;
869
- var descendants = getDescendantControls(controlRef.concat(newItemIndex), form);
870
- var mergedDescendants = mergeErrors(descendants.reduce(function (acc, control) {
871
- var _a;
872
- var formKey = getFormKey(control.controlRef);
873
- return __assign(__assign({}, acc), (_a = {}, _a[formKey] = __assign(__assign({}, control), structuredClone(DEFAULT_HUB2_FIELDS)), _a));
874
- }, {}));
875
- var ancestors = getAncestorControls(controlRef, state)
924
+ var mergeControls = function (state, _a) {
925
+ var form = _a.form, _b = _a.changedControls, changedControls = _b === void 0 ? {} : _b, removedControls = _a.removedControls;
926
+ var controlsRemoved = removedControls
927
+ ? Object.values(removedControls).reduce(function (acc, _a) {
928
+ var controlRef = _a.controlRef;
929
+ return mergeRemoveControl(acc, form, controlRef);
930
+ }, state)
931
+ : state;
932
+ var updatedBranch = Object.values(changedControls)
876
933
  .reverse()
877
- .reduce(function (acc, control, index, arr) {
934
+ .reduce(function (acc, control) {
878
935
  var _a;
879
936
  var formKey = getFormKey(control.controlRef);
880
- var errors = __assign(__assign({}, form[formKey].validatorErrors), control.asyncValidatorErrors);
937
+ var existingControl = controlsRemoved && controlsRemoved[formKey];
938
+ var newControl = __assign(__assign({}, (existingControl
939
+ ? existingControl
940
+ : structuredClone(DEFAULT_HUB2_FIELDS))), control);
941
+ var errors = __assign(__assign({}, newControl.validatorErrors), newControl.asyncValidatorErrors);
881
942
  var selfValid = !hasErrors(errors);
882
943
  var childrenValid = true;
883
- if (index === 0) {
884
- childrenValid =
885
- control.childrenValid &&
886
- mergedDescendants[getFormKey(controlRef.concat(newItemIndex))].valid;
944
+ if (Array.isArray(control.config.controls)) {
945
+ // If control is a FormArray
946
+ childrenValid = control.value.every(function (item, index) {
947
+ var formKey = getFormKey(control.controlRef.concat(index));
948
+ var valid = acc[formKey] === undefined ? controlsRemoved[formKey].valid : acc[formKey].valid;
949
+ return valid;
950
+ });
887
951
  }
888
- else {
889
- if (Array.isArray(control.config.controls)) {
890
- // If control is a FormArray
891
- childrenValid = control.value.every(function (item, index) {
892
- var formKey = getFormKey(control.controlRef.concat(index));
893
- var valid = acc[formKey] === undefined ? state[formKey].valid : acc[formKey].valid;
894
- return valid;
895
- });
896
- }
897
- else if (control.config.controls) {
898
- // If control is a FormGroup
899
- childrenValid = Object.keys(control.value).every(function (childKey) {
900
- var formKey = getFormKey(control.controlRef.concat(childKey));
901
- var valid = acc[formKey] === undefined ? state[formKey].valid : acc[formKey].valid;
902
- return valid;
903
- });
904
- }
952
+ else if (control.config.controls) {
953
+ // If control is a FormGroup
954
+ childrenValid = Object.keys(control.value).every(function (childKey) {
955
+ var formKey = getFormKey(control.controlRef.concat(childKey));
956
+ var valid = acc[formKey] === undefined ? controlsRemoved[formKey].valid : acc[formKey].valid;
957
+ return valid;
958
+ });
905
959
  }
906
- return __assign(__assign({}, acc), (_a = {}, _a[formKey] = __assign(__assign(__assign({}, control), form[formKey]), { errors: errors, valid: selfValid && childrenValid, childrenValid: childrenValid }), _a));
960
+ return __assign(__assign({}, acc), (_a = {}, _a[formKey] = __assign(__assign({}, newControl), { errors: errors, valid: selfValid && childrenValid, childrenValid: childrenValid }), _a));
907
961
  }, {});
908
- var controlBranchUpdated = __assign(__assign({}, ancestors), mergedDescendants);
909
- return __assign(__assign({}, state), controlBranchUpdated);
962
+ var result = __assign(__assign({}, controlsRemoved), updatedBranch);
963
+ return result;
910
964
  };
911
965
 
912
966
  var formChange = function (state, _a) {
913
967
  if (state === void 0) { state = null; }
914
- var _b = _a.payload, form = _b.form, action = _b.action;
968
+ var payload = _a.payload;
969
+ var form = payload.form;
915
970
  if (state === null) {
916
971
  return mergeErrors(Object.entries(form).reduce(function (acc, _a) {
917
972
  var _b;
@@ -919,30 +974,7 @@ var formChange = function (state, _a) {
919
974
  return __assign(__assign({}, acc), (_b = {}, _b[dictKey] = __assign(__assign({}, structuredClone(DEFAULT_HUB2_FIELDS)), baseControl), _b));
920
975
  }, {}));
921
976
  }
922
- switch (action === null || action === void 0 ? void 0 : action.type) {
923
- case 'pushControl':
924
- return mergePushControl(state, form, action.payload.controlRef);
925
- case 'addControl':
926
- case 'updateValues':
927
- return mergeValueUpdated(state, form, action.payload.controlRef);
928
- case 'resetControl':
929
- case 'removeControl':
930
- return mergeRemoveControl(state, form, action.payload);
931
- case 'markControlAsPristine':
932
- case 'markControlAsUntouched':
933
- return mergeTouchUpdated(state, form, action.payload);
934
- case 'markControlAsTouched':
935
- return mergeTouchUpdated(state, form, action.payload.controlRef);
936
- default:
937
- return mergeErrors(Object.entries(form).reduce(function (acc, _a) {
938
- var _b;
939
- var dictKey = _a[0], baseControl = _a[1];
940
- var existingControl = state && state[dictKey];
941
- return __assign(__assign({}, acc), (_b = {}, _b[dictKey] = __assign(__assign({}, (existingControl
942
- ? existingControl
943
- : structuredClone(DEFAULT_HUB2_FIELDS))), baseControl), _b));
944
- }, {}));
945
- }
977
+ return mergeControls(state, payload);
946
978
  };
947
979
 
948
980
  var control = function (config) {
@@ -961,20 +993,52 @@ var control = function (config) {
961
993
  };
962
994
  var array = function (config) { return config; };
963
995
  var group = function (config) { return config; };
996
+ var reducerTools = {
997
+ updateValues: function (state, payload) {
998
+ return updateValues(state, { payload: payload }, true);
999
+ },
1000
+ removeControl: function (state, payload) {
1001
+ return removeControl(state, { payload: payload }, true);
1002
+ },
1003
+ pushControl: function (state, payload) {
1004
+ return pushControl(state, { payload: payload }, true);
1005
+ },
1006
+ addControl: function (state, payload) {
1007
+ return addControl(state, { payload: payload }, true);
1008
+ },
1009
+ markControlAsPristine: function (state, payload) {
1010
+ return markControlAsPristine(state, { payload: payload }, true);
1011
+ },
1012
+ markControlAsTouched: function (state, payload) {
1013
+ return markControlAsTouched(state, { payload: payload }, true);
1014
+ },
1015
+ markControlAsUntouched: function (state, payload) {
1016
+ return markControlAsUntouched(state, { payload: payload }, true);
1017
+ },
1018
+ resetControl: function (state, payload) {
1019
+ return resetControl(state, { payload: payload }, true);
1020
+ }
1021
+ };
964
1022
  var build = function (config, options) {
1023
+ if (options === void 0) { options = {}; }
965
1024
  var initialState = buildFormState(config);
966
- var rxHub1 = core.RxBuilder(__assign({ initialState: initialState, reducers: {
967
- updateValues: updateValues,
968
- removeControl: removeControl,
969
- addControl: addControl,
970
- pushControl: pushControl,
971
- markControlAsPristine: markControlAsPristine,
972
- markControlAsTouched: markControlAsTouched,
973
- markControlAsUntouched: markControlAsUntouched,
974
- resetControl: resetControl
975
- } }, options));
976
- var rxHub2 = core.RxBuilder({
977
- sources: [buildHub2Source(rxHub1)],
1025
+ var reducers = options.reducers, otherOptions = __rest(options, ["reducers"]);
1026
+ var customReducers = Object.entries(reducers || {}).reduce(function (acc, _a) {
1027
+ var _b;
1028
+ var key = _a[0], _case = _a[1];
1029
+ var _reducer = typeof _case === 'function' ? _case : _case.reducer;
1030
+ var effects = typeof _case === 'function' ? [] : _case.effects;
1031
+ return __assign(__assign({}, acc), (_b = {}, _b[key] = {
1032
+ reducer: function (_a, action) {
1033
+ var form = _a.form;
1034
+ return _reducer(reducerTools, { form: form }, action);
1035
+ },
1036
+ effects: effects
1037
+ }, _b));
1038
+ }, {});
1039
+ var _a = core.RxBuilder(__assign({ initialState: initialState, reducers: __assign({ updateValues: updateValues, removeControl: removeControl, addControl: addControl, pushControl: pushControl, markControlAsPristine: markControlAsPristine, markControlAsTouched: markControlAsTouched, markControlAsUntouched: markControlAsUntouched, resetControl: resetControl }, customReducers) }, otherOptions)), hub1State$ = _a[0], hub1Actions = _a[1];
1040
+ var state$ = core.RxBuilder({
1041
+ sources: [buildHub2Source(hub1State$)],
978
1042
  initialState: null,
979
1043
  reducers: {
980
1044
  formChange: formChange,
@@ -987,11 +1051,11 @@ var build = function (config, options) {
987
1051
  },
988
1052
  asyncValidationResponseSuccess: asyncValidationResponseSuccess
989
1053
  }
990
- });
991
- return {
992
- state$: rxHub2.state$.pipe(operators.filter(function (form) { return form !== null; })),
993
- actions: rxHub1.actions
994
- };
1054
+ })[0];
1055
+ return [
1056
+ state$.pipe(operators.filter(function (form) { return form !== null; })),
1057
+ hub1Actions,
1058
+ ];
995
1059
  };
996
1060
 
997
1061
  var getArrayItems = function (controlRef, form) {