@flowerforce/flower-core 3.3.1-beta.2 → 4.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.
Files changed (35) hide show
  1. package/dist/index.cjs.js +238 -266
  2. package/dist/index.esm.js +228 -265
  3. package/dist/src/constants/index.d.ts +5 -0
  4. package/dist/src/event-emitter/index.d.ts +1 -0
  5. package/dist/src/index.d.ts +6 -8
  6. package/dist/src/interfaces/CoreInterface.d.ts +23 -17
  7. package/dist/src/interfaces/ReducerInterface.d.ts +109 -109
  8. package/dist/src/{rules-matcher/interface.d.ts → interfaces/RulesMatcherInterface.d.ts} +1 -1
  9. package/dist/src/interfaces/SelectorsInterface.d.ts +34 -25
  10. package/dist/src/interfaces/Store.d.ts +2 -10
  11. package/dist/src/interfaces/UtilsInterface.d.ts +1 -1
  12. package/dist/src/interfaces/index.d.ts +3 -0
  13. package/dist/src/rules-matcher/RulesMatcher.d.ts +2 -0
  14. package/dist/src/rules-matcher/index.d.ts +2 -0
  15. package/dist/src/rules-matcher/utils.d.ts +2 -3
  16. package/dist/src/state-manager/index.d.ts +2 -0
  17. package/dist/src/state-manager/state-functions/FlowerCoreMergedReducers.d.ts +2 -0
  18. package/dist/src/state-manager/state-functions/FlowerCoreStateFunctions.d.ts +5 -0
  19. package/dist/src/state-manager/state-functions/FlowerDataStateFunctions.d.ts +2 -0
  20. package/dist/src/state-manager/state-functions/index.d.ts +4 -0
  21. package/dist/src/state-manager/state-selectors/FlowerCoreStateSelectors.d.ts +2 -0
  22. package/dist/src/state-manager/state-selectors/FlowerDataStateSelectors.d.ts +2 -0
  23. package/dist/src/state-manager/state-selectors/FlowerSelectorsMerged.d.ts +2 -0
  24. package/dist/src/state-manager/state-selectors/index.d.ts +4 -0
  25. package/dist/src/{FlowerCoreStateUtils.d.ts → utils/FlowerCoreStateUtils.d.ts} +2 -2
  26. package/dist/src/{CoreUtils.d.ts → utils/FlowerCoreUtils.d.ts} +1 -2
  27. package/dist/src/utils/FlowerDataCoreUtils.d.ts +2 -0
  28. package/dist/src/utils/FlowerFlowUtils.d.ts +3 -0
  29. package/dist/src/utils/index.d.ts +4 -0
  30. package/package.json +1 -1
  31. package/dist/src/FlowerCoreStateFunctions.d.ts +0 -5
  32. package/dist/src/FlowerCoreStateSelectors.d.ts +0 -2
  33. package/dist/src/RulesMatcher.d.ts +0 -5
  34. package/dist/src/devtoolState.d.ts +0 -2
  35. /package/dist/src/{Emitter.d.ts → event-emitter/Emitter.d.ts} +0 -0
package/dist/index.cjs.js CHANGED
@@ -1,13 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var tinyEmitter = require('tiny-emitter');
4
- var _set = require('lodash/set');
5
- var _unset = require('lodash/unset');
6
4
  var _get = require('lodash/get');
7
- var _last = require('lodash/last');
8
- var _slice = require('lodash/slice');
9
- var _cloneDeep = require('lodash/cloneDeep');
10
- var lastIndexOf = require('lodash/lastIndexOf');
11
5
  var find = require('lodash/find');
12
6
  var keyBy = require('lodash/keyBy');
13
7
  var has = require('lodash/has');
@@ -18,10 +12,56 @@ var mapKeys = require('lodash/mapKeys');
18
12
  var mapValues = require('lodash/mapValues');
19
13
  var _trimStart = require('lodash/trimStart');
20
14
  var _intersection = require('lodash/intersection');
15
+ var _set = require('lodash/set');
16
+ var _last = require('lodash/last');
17
+ var _slice = require('lodash/slice');
18
+ var _cloneDeep = require('lodash/cloneDeep');
19
+ var lastIndexOf = require('lodash/lastIndexOf');
20
+ var _unset = require('lodash/unset');
21
21
  var flat = require('flat');
22
22
 
23
23
  const Emitter = new tinyEmitter.TinyEmitter();
24
24
 
25
+ exports.REDUCER_NAME = void 0;
26
+ (function (REDUCER_NAME) {
27
+ REDUCER_NAME["FLOWER_FLOW"] = "FlowerFlow";
28
+ REDUCER_NAME["FLOWER_DATA"] = "FlowerData";
29
+ })(exports.REDUCER_NAME || (exports.REDUCER_NAME = {}));
30
+ const devtoolState = {};
31
+
32
+ const FlowerStateUtils = {
33
+ getAllData: (state) => state &&
34
+ Object.entries(state ?? {}).reduce((acc, [k, v]) => ({ ...acc, [k]: v?.data ?? v }), {}),
35
+ selectFlowerDataNode: (name) => (state) => _get(state, name),
36
+ makeSelectCurrentNextRules: (name) => (state) => {
37
+ const nextRules = _get(state, [name, 'nextRules']);
38
+ const currentNodeId = FlowerStateUtils.makeSelectCurrentNodeId(name)(state);
39
+ return _get(nextRules, [currentNodeId]);
40
+ },
41
+ makeSelectCurrentNodeId: (name) => (state) => {
42
+ const subState = _get(state, [name]);
43
+ const startId = _get(state, ['startId']);
44
+ return _get(subState, ['current']) || startId;
45
+ },
46
+ makeSelectNodeErrors: (name) => (state) => {
47
+ const data = FlowerStateUtils.selectFlowerDataNode(name)(state);
48
+ return generateData(data);
49
+ }
50
+ };
51
+ const generateData = (data) => {
52
+ const validationErrors = data && data.errors;
53
+ const allErrors = Object.values(validationErrors || {});
54
+ return {
55
+ isSubmitted: data?.isSubmitted || false,
56
+ isDirty: Object.values(data?.dirty || {}).some(Boolean) || false,
57
+ hasFocus: data?.hasFocus,
58
+ errors: data?.errors,
59
+ customErrors: data?.customErrors,
60
+ isValidating: data?.isValidating,
61
+ isValid: allErrors.flat().length === 0
62
+ };
63
+ };
64
+
25
65
  const EMPTY_STRING_REGEXP = /^\s*$/;
26
66
  /**
27
67
  * Defines a utility object named rulesMatcherUtils, which contains various helper functions used for processing rules and data in a rule-matching context.
@@ -227,25 +267,21 @@ const operators = {
227
267
  .some((c) => c instanceof RegExp ? c.test(a) : new RegExp(c, opt).test(a))
228
268
  };
229
269
 
230
- const rulesMatcher = (rules, formValue = {}, apply = true, options) => {
270
+ const rulesMatcher = (rules, dataValue = {}, apply = true, options) => {
231
271
  if (!rules)
232
272
  return [apply];
233
273
  // if (typeof rules !== 'object' && !Array.isArray(rules)) {
234
274
  // throw new Error('Rules accept only array or object');
235
275
  // }
236
276
  if (typeof rules === 'function') {
237
- return [rules(formValue) === apply];
277
+ return [rules(dataValue) === apply];
238
278
  }
239
279
  const conditions = Array.isArray(rules)
240
280
  ? { $and: rules }
241
281
  : rules;
242
- const valid = rulesMatcherUtils.checkRule(conditions, formValue, options ?? {});
282
+ const valid = rulesMatcherUtils.checkRule(conditions, dataValue, options ?? {});
243
283
  return [valid === apply];
244
284
  };
245
- const MatchRules = {
246
- rulesMatcher,
247
- utils: rulesMatcherUtils
248
- };
249
285
 
250
286
  /* eslint-disable no-useless-escape */
251
287
  // TODO align this set of functions to selectors and reducers functions
@@ -268,36 +304,12 @@ const flattenRules = (ob) => {
268
304
  }
269
305
  return result;
270
306
  };
271
- // export const searchEmptyKeyRecursively = <T extends object>(
272
- // _key: "$and" | "$or",
273
- // obj: T
274
- // ) => {
275
- // if (
276
- // isEmpty(obj) ||
277
- // typeof obj !== "object" ||
278
- // Object.keys(obj).length === 0
279
- // ) {
280
- // return true;
281
- // }
282
- // if (Object.keys(obj).includes(_key)) {
283
- // if (obj[_key] && obj[_key].length === 0) return true;
284
- // return Object.keys(obj).map((key) =>
285
- // searchEmptyKeyRecursively(_key, obj[key])
286
- // );
287
- // }
288
- // return Object.keys(obj)
289
- // .map((key) => searchEmptyKeyRecursively(_key, obj[key]))
290
- // .every((v) => v === true);
291
- // };
292
307
  const getRulesExists = (rules) => {
293
- return Object.keys(rules).length ? CoreUtils.mapEdge(rules) : undefined;
308
+ return Object.keys(rules).length ? FlowUtils.mapEdge(rules) : undefined;
294
309
  };
295
- /**
296
- * Defines a collection of utility functions for processing rules, nodes and graph-like structures
297
- */
298
- const CoreUtils = {
310
+ const FlowUtils = {
299
311
  generateRulesName: (nextRules) => {
300
- const a = nextRules.reduce((acc, inc) => {
312
+ return nextRules.reduce((acc, inc) => {
301
313
  const n = typeof inc.rules === 'string'
302
314
  ? inc.rules || '__ERROR_NAME__'
303
315
  : inc.rules?.name || '__ERROR_NAME__';
@@ -306,7 +318,6 @@ const CoreUtils = {
306
318
  [n]: inc.nodeId
307
319
  };
308
320
  }, {});
309
- return a;
310
321
  },
311
322
  mapKeysDeepLodash: (obj, cb, isRecursive) => {
312
323
  /* istanbul ignore next */
@@ -322,13 +333,13 @@ const CoreUtils = {
322
333
  }
323
334
  }
324
335
  if (Array.isArray(obj)) {
325
- return obj.map((item) => CoreUtils.mapKeysDeepLodash(item, cb, true));
336
+ return obj.map((item) => FlowUtils.mapKeysDeepLodash(item, cb, true));
326
337
  }
327
338
  if (!isPlainObject(obj)) {
328
339
  return obj;
329
340
  }
330
341
  const result = mapKeys(obj, cb);
331
- return mapValues(result, (value) => CoreUtils.mapKeysDeepLodash(value, cb, true));
342
+ return mapValues(result, (value) => FlowUtils.mapKeysDeepLodash(value, cb, true));
332
343
  },
333
344
  generateNodes: (nodes) => keyBy(nodes.map((s) => omit(s, 'nextRules')), 'nodeId'),
334
345
  makeObjectRules: (nodes) => nodes.reduce((acc, inc) => ({ ...acc, [inc.nodeId]: inc.nextRules }), {}),
@@ -345,17 +356,18 @@ const CoreUtils = {
345
356
  },
346
357
  mapEdge: (nextNode) => {
347
358
  const res = nextNode.sort((a, b) => {
348
- const x = CoreUtils.isEmptyRules(a.rules);
349
- const y = CoreUtils.isEmptyRules(b.rules);
359
+ const x = FlowUtils.isEmptyRules(a.rules);
360
+ const y = FlowUtils.isEmptyRules(b.rules);
350
361
  return Number(x) - Number(y);
351
362
  });
352
363
  return res;
353
364
  },
354
365
  makeRules: (rules) => Object.entries(rules).reduce((acc2, [k, v]) => [...acc2, { nodeId: k, rules: v }], []),
366
+ // TODO: This function is strictly related to React nodes, could make sense to move it in the flower-react folder
355
367
  generateNodesForFlowerJson: (nodes) => nodes
356
368
  .filter((e) => !!_get(e, 'props.id'))
357
369
  .map((e) => {
358
- const rules = CoreUtils.makeRules(e.props.to ?? {});
370
+ const rules = FlowUtils.makeRules(e.props.to ?? {});
359
371
  const nextRules = getRulesExists(rules);
360
372
  const children = e.props.data?.children;
361
373
  return {
@@ -368,29 +380,6 @@ const CoreUtils = {
368
380
  disabled: e.props.disabled
369
381
  };
370
382
  }),
371
- cleanPath: (name, char = '^') => _trimStart(name, char),
372
- getPath: (idValue) => {
373
- if (!idValue) {
374
- return {
375
- path: []
376
- };
377
- }
378
- if (idValue === '*') {
379
- return {
380
- path: '*'
381
- };
382
- }
383
- if (idValue.indexOf('^') === 0) {
384
- const [flowNameFromPath, ...rest] = CoreUtils.cleanPath(idValue).split('.');
385
- return {
386
- flowNameFromPath,
387
- path: rest
388
- };
389
- }
390
- return {
391
- path: idValue.split('.')
392
- };
393
- },
394
383
  allEqual: (arr, arr2) => arr.length === arr2.length && arr.every((v) => arr2.includes(v)),
395
384
  findValidRule: (nextRules, value, prefix) => find(nextRules, (rule) => {
396
385
  // fix per evitare di entrare in un nodo senza regole, ma con un name,
@@ -410,53 +399,52 @@ const CoreUtils = {
410
399
  if (typeof rule.rules.rules === 'string') {
411
400
  return false;
412
401
  }
413
- const [valid] = MatchRules.rulesMatcher(rule.rules.rules, value, true, {
402
+ const [valid] = rulesMatcher(rule.rules.rules, value, true, {
414
403
  prefix
415
404
  });
416
405
  return valid;
417
406
  })
418
407
  };
419
408
 
420
- const FlowerStateUtils = {
421
- getAllData: (state) => state &&
422
- Object.entries(state ?? {}).reduce((acc, [k, v]) => ({ ...acc, [k]: v.data }), {}),
423
- selectFlowerFormNode: (name, id) => (state) => _get(state, [name, 'form', id]),
424
- makeSelectCurrentNextRules: (name) => (state) => {
425
- const nextRules = _get(state, [name, 'nextRules']);
426
- const currentNodeId = FlowerStateUtils.makeSelectCurrentNodeId(name)(state);
427
- return _get(nextRules, [currentNodeId]);
428
- },
429
- makeSelectCurrentNodeId: (name) => (state) => {
430
- const subState = _get(state, [name]);
431
- const startId = _get(state, ['startId']);
432
- return _get(subState, ['current']) || startId;
433
- },
434
- makeSelectNodeErrors: (name, currentNodeId) => (state) => {
435
- const form = FlowerStateUtils.selectFlowerFormNode(name, currentNodeId)(state);
436
- return createFormData(form);
409
+ const DataUtils = {
410
+ cleanPath: (name, char = '^') => _trimStart(name, char),
411
+ getPath: (idValue) => {
412
+ if (!idValue) {
413
+ return {
414
+ path: []
415
+ };
416
+ }
417
+ if (idValue === '*') {
418
+ return {
419
+ path: '*'
420
+ };
421
+ }
422
+ if (idValue.indexOf('^') === 0) {
423
+ const [rootName, ...rest] = DataUtils.cleanPath(idValue).split('.');
424
+ return {
425
+ rootName,
426
+ path: rest
427
+ };
428
+ }
429
+ return {
430
+ path: idValue.split('.')
431
+ };
437
432
  }
438
433
  };
439
- const createFormData = (form) => {
440
- const validationErrors = form && form.errors;
441
- const allErrors = Object.values(validationErrors || {});
442
- return {
443
- isSubmitted: form?.isSubmitted || false,
444
- isDirty: Object.values(form?.dirty || {}).some(Boolean) || false,
445
- hasFocus: form?.hasFocus,
446
- errors: form?.errors,
447
- customErrors: form?.customErrors,
448
- isValidating: form?.isValidating,
449
- isValid: allErrors.flat().length === 0
450
- };
451
- };
452
434
 
453
- const devtoolState = {};
435
+ /**
436
+ * Defines a collection of utility functions for processing rules, nodes and graph-like structures
437
+ */
438
+ const CoreUtils = {
439
+ ...FlowUtils,
440
+ ...DataUtils
441
+ };
454
442
 
455
- const { generateNodes, hasNode, makeObjectRules, generateRulesName, findValidRule, getPath } = CoreUtils;
443
+ const { generateNodes, hasNode, makeObjectRules, generateRulesName, findValidRule } = CoreUtils;
456
444
  /**
457
445
  * These functions are Redux reducers used in a Flux architecture for managing state transitions and updates in a Flower application.
458
446
  */
459
- const FlowerCoreReducers = {
447
+ const FlowerCoreBaseReducers = {
460
448
  historyAdd: (state, { payload }) => {
461
449
  if (hasNode(state, payload.name, payload.node)) {
462
450
  state[payload.name].history.push(payload.node);
@@ -475,27 +463,11 @@ const FlowerCoreReducers = {
475
463
  }
476
464
  return state;
477
465
  },
478
- setFormTouched: (state, { payload }) => {
479
- if (!_get(state, [
480
- typeof payload === 'string' ? payload : payload.flowName,
481
- 'nodes',
482
- typeof payload === 'string' ? payload : payload.currentNode
483
- ])) {
484
- return state;
485
- }
486
- _set(state, [
487
- typeof payload === 'string' ? payload : payload.flowName,
488
- 'form',
489
- typeof payload === 'string' ? payload : payload.currentNode,
490
- 'isSubmitted'
491
- ], true);
492
- return state;
493
- },
494
466
  // TODO check internal logic and use case
495
467
  /* istanbul ignore next */
496
468
  forceAddHistory: (state, { payload }) => {
497
469
  const { name, flowName, history } = payload;
498
- const key = name || flowName || '' || '';
470
+ const key = name || flowName || '';
499
471
  const resultHistory = history.slice(1, -1);
500
472
  state[key].history.push(...resultHistory);
501
473
  return state;
@@ -568,7 +540,8 @@ const FlowerCoreReducers = {
568
540
  return state;
569
541
  },
570
542
  destroy: (state, { payload }) => {
571
- _set(state, [payload.name], {});
543
+ delete state[payload.name];
544
+ return state;
572
545
  },
573
546
  initNodes: (state, { payload }) => {
574
547
  if (payload.persist && _get(state, [payload.name, 'persist']))
@@ -591,8 +564,7 @@ const FlowerCoreReducers = {
591
564
  current,
592
565
  history,
593
566
  nodes: generateNodes(payload.nodes),
594
- nextRules: makeObjectRules(payload.nodes),
595
- data: payload.initialData
567
+ nextRules: makeObjectRules(payload.nodes)
596
568
  });
597
569
  },
598
570
  // TODO usato solo da flower su vscode
@@ -609,91 +581,14 @@ const FlowerCoreReducers = {
609
581
  }
610
582
  }
611
583
  },
612
- formAddCustomErrors: (state, { payload }) => {
613
- _set(state, [payload.name, 'form', payload.currentNode, 'customErrors', payload.id], payload.errors);
614
- },
615
- formAddErrors: (state, { payload }) => {
616
- _set(state, [payload.name, 'form', payload.currentNode, 'errors', payload.id], payload.errors);
617
- },
618
- formRemoveErrors: (state, { payload }) => {
619
- _unset(state, [
620
- payload.name,
621
- 'form',
622
- payload.currentNode,
623
- 'errors',
624
- payload.id
625
- ]);
626
- _unset(state, [
627
- payload.name,
628
- 'form',
629
- payload.currentNode,
630
- 'customErrors',
631
- payload.id
632
- ]);
633
- _unset(state, [payload.name, 'form', payload.currentNode, 'isValidating']);
634
- },
635
- formFieldTouch: (state, { payload }) => {
636
- _set(state, [payload.name, 'form', payload.currentNode, 'touches', payload.id], payload.touched);
637
- },
638
- formFieldDirty: (state, { payload }) => {
639
- _set(state, [payload.name, 'form', payload.currentNode, 'dirty', payload.id], payload.dirty);
640
- },
641
- formFieldFocus: (state, { payload }) => {
642
- if (!payload.focused) {
643
- _unset(state, [payload.name, 'form', payload.currentNode, 'hasFocus']);
644
- return;
645
- }
646
- _set(state, [payload.name, 'form', payload.currentNode, 'hasFocus'], payload.id);
647
- },
648
- addData: (state, { payload }) => {
649
- const prevData = _get(state, [payload.flowName, 'data']);
650
- _set(state, [payload.flowName, 'data'], { ...prevData, ...payload.value });
651
- },
652
- addDataByPath: (state, { payload }) => {
653
- const { path: newpath } = getPath(payload.id);
654
- const currentNode = FlowerStateUtils.makeSelectCurrentNodeId(payload.flowName)(state);
655
- if (payload.id && payload.id.length) {
656
- _set(state, [payload.flowName, 'data', ...newpath], payload.value);
657
- if (payload && payload.dirty) {
658
- _set(state, [payload.flowName, 'form', currentNode, 'dirty', payload.id], payload.dirty);
659
- }
660
- }
661
- },
662
- // TODO usato al momento solo il devtool
663
- replaceData: /* istanbul ignore next */ (state, { payload }) => {
664
- /* istanbul ignore next */
665
- _set(state, [payload.flowName, 'data'], payload.value);
666
- },
667
- unsetData: (state, { payload }) => {
668
- _unset(state, [payload.flowName, 'data', ...payload.id]);
669
- },
670
- setFormIsValidating: (state, { payload }) => {
671
- _set(state, [payload.name, 'form', payload.currentNode, 'isValidating'], payload.isValidating);
672
- },
673
- resetForm: (state, { payload }) => {
674
- const touchedFields = _get(state, [payload.flowName, 'form', payload.id, 'errors'], {});
675
- Object.keys(touchedFields).forEach((key) => {
676
- const { flowNameFromPath = payload.flowName, path } = getPath(key);
677
- _unset(state, [flowNameFromPath, 'data', ...path]);
678
- });
679
- _unset(state, [payload.flowName, 'form', payload.id, 'touches']);
680
- _unset(state, [payload.flowName, 'form', payload.id, 'dirty']);
681
- _unset(state, [payload.flowName, 'form', payload.id, 'isSubmitted']);
682
- },
683
584
  node: (state, { payload }) => {
684
585
  const { name, history } = payload;
685
586
  const node = payload.nodeId || payload.node || '';
686
587
  const flowName = name || payload.flowName || '';
687
- const startNode = _get(state, [payload.name, 'startId']);
688
- const currentNodeId = _get(state, [payload.name, 'current'], startNode);
689
- FlowerCoreReducers.setFormTouched(state, {
690
- type: 'setFormTouched',
691
- payload: { flowName, currentNode: currentNodeId }
692
- });
693
588
  /* istanbul ignore next */
694
589
  // eslint-disable-next-line no-underscore-dangle
695
590
  if (devtoolState && _get(devtoolState, '__FLOWER_DEVTOOLS__') && history) {
696
- FlowerCoreReducers.forceAddHistory(state, {
591
+ FlowerCoreBaseReducers.forceAddHistory(state, {
697
592
  type: 'forceAddHistory',
698
593
  payload: {
699
594
  name,
@@ -702,34 +597,35 @@ const FlowerCoreReducers = {
702
597
  }
703
598
  });
704
599
  }
705
- FlowerCoreReducers.historyAdd(state, {
600
+ FlowerCoreBaseReducers.historyAdd(state, {
706
601
  type: 'historyAdd',
707
602
  payload: { name: name || flowName || '', node }
708
603
  });
709
604
  },
710
605
  prevToNode: (state, { payload }) => {
711
606
  const { node, name, flowName } = payload;
712
- FlowerCoreReducers.historyPrevToNode(state, {
607
+ FlowerCoreBaseReducers.historyPrevToNode(state, {
713
608
  type: 'historyPrevToNode',
714
609
  payload: { name: name || flowName || '', node }
715
610
  });
716
611
  },
717
612
  next: (state, { payload }) => {
718
- const { name, data = {}, route } = payload;
719
- const flowName = name || payload.flowName || '';
613
+ const { name, route, flowName: flow, data = {}, dataIn = {} } = payload;
614
+ const flowName = name || flow || '';
615
+ const { FlowerData, FlowerFlow, ...external } = data;
720
616
  const currentNodeId = FlowerStateUtils.makeSelectCurrentNodeId(flowName)(state);
721
617
  const currentNextRules = FlowerStateUtils.makeSelectCurrentNextRules(flowName)(state);
722
- const form = FlowerStateUtils.makeSelectNodeErrors(flowName, currentNodeId)(state);
723
- const clonedData = _cloneDeep(FlowerStateUtils.getAllData(state));
618
+ const $data = FlowerStateUtils.makeSelectNodeErrors(flowName, currentNodeId)(FlowerData);
619
+ const internalClonedData = _cloneDeep(FlowerStateUtils.getAllData(FlowerData));
620
+ const externalClonedData = _cloneDeep(FlowerStateUtils.getAllData(external));
724
621
  const stateWithNodeData = {
725
- $in: data,
726
- $form: form,
727
- ...clonedData
622
+ $in: dataIn,
623
+ /** @deprecated use $data instead */
624
+ $form: $data,
625
+ $data,
626
+ ...externalClonedData,
627
+ ...internalClonedData
728
628
  };
729
- FlowerCoreReducers.setFormTouched(state, {
730
- type: 'setFormTouched',
731
- payload: { flowName, currentNode: currentNodeId }
732
- });
733
629
  if (!currentNextRules) {
734
630
  return;
735
631
  }
@@ -738,7 +634,7 @@ const FlowerCoreReducers = {
738
634
  if (!rulesByName[route]) {
739
635
  return;
740
636
  }
741
- FlowerCoreReducers.historyAdd(state, {
637
+ FlowerCoreBaseReducers.historyAdd(state, {
742
638
  type: 'historyAdd',
743
639
  payload: { name: flowName, node: rulesByName[route] }
744
640
  });
@@ -749,51 +645,120 @@ const FlowerCoreReducers = {
749
645
  if (!nextNumberNode) {
750
646
  return;
751
647
  }
752
- FlowerCoreReducers.historyAdd(state, {
648
+ FlowerCoreBaseReducers.historyAdd(state, {
753
649
  type: 'historyAdd',
754
650
  payload: { name: flowName, node: nextNumberNode }
755
651
  });
756
652
  },
757
653
  prev: (state, { payload }) => {
758
654
  const { name, flowName } = payload;
759
- FlowerCoreReducers.historyPop(state, {
655
+ FlowerCoreBaseReducers.historyPop(state, {
760
656
  type: 'historyPop',
761
657
  payload: { name: name || flowName || '' }
762
658
  });
763
659
  },
764
660
  restart: (state, { payload }) => {
765
661
  const { name, flowName } = payload;
766
- FlowerCoreReducers.restoreHistory(state, {
662
+ FlowerCoreBaseReducers.restoreHistory(state, {
767
663
  type: 'restoreHistory',
768
664
  payload: { name: name || flowName || '' }
769
665
  });
770
666
  },
771
667
  reset: (state, { payload }) => {
772
- const { name, flowName, initialData } = payload;
773
- FlowerCoreReducers.restoreHistory(state, {
668
+ const { name, flowName } = payload;
669
+ FlowerCoreBaseReducers.restoreHistory(state, {
774
670
  type: 'restoreHistory',
775
671
  payload: { name: name || flowName || '' }
776
672
  });
777
- _set(state, [name || flowName || '', 'form'], {});
778
- _set(state, [name || flowName || '', 'data'], initialData);
779
673
  }
780
674
  };
781
675
 
782
- const FlowerCoreStateSelectors = {
783
- selectGlobal: (state) => state && state.flower,
676
+ const { getPath } = CoreUtils;
677
+ const FlowerCoreDataReducers = {
678
+ setFormSubmitted: (state, { payload }) => {
679
+ const rootPath = typeof payload === 'string' ? payload : payload.rootName;
680
+ if (!_get(state, [rootPath])) {
681
+ return state;
682
+ }
683
+ _set(state, [rootPath, 'isSubmitted'], true);
684
+ return state;
685
+ },
686
+ addCustomDataErrors: (state, { payload }) => {
687
+ _set(state, [payload.rootName, 'customErrors', payload.id], payload.errors);
688
+ },
689
+ addDataErrors: (state, { payload }) => {
690
+ _set(state, [payload.rootName, 'errors', payload.id], payload.errors);
691
+ },
692
+ removeDataErrors: (state, { payload }) => {
693
+ _unset(state, [payload.rootName, 'errors', payload.id]);
694
+ _unset(state, [payload.rootName, 'customErrors', payload.id]);
695
+ _unset(state, [payload.rootName, 'isValidating']);
696
+ },
697
+ fieldTouch: (state, { payload }) => {
698
+ _set(state, [payload.rootName, 'touches', payload.id], payload.touched);
699
+ },
700
+ fieldDirty: (state, { payload }) => {
701
+ _set(state, [payload.rootName, 'dirty', payload.id], payload.dirty);
702
+ },
703
+ fieldFocus: (state, { payload }) => {
704
+ if (!payload.focused) {
705
+ _unset(state, [payload.rootName, 'hasFocus']);
706
+ return;
707
+ }
708
+ _set(state, [payload.rootName, 'hasFocus'], payload.id);
709
+ },
710
+ addData: (state, { payload }) => {
711
+ const prevData = _get(state, [payload.rootName, 'data'], {});
712
+ _set(state, [payload.rootName, 'data'], { ...prevData, ...payload.value });
713
+ },
714
+ addDataByPath: (state, { payload }) => {
715
+ const { path: newpath } = getPath(payload.id);
716
+ if (payload.id && payload.id.length) {
717
+ _set(state, [payload.rootName, 'data', ...newpath], payload.value);
718
+ if (payload && payload.dirty) {
719
+ _set(state, [payload.rootName, 'dirty', payload.id], payload.dirty);
720
+ }
721
+ }
722
+ },
723
+ // TODO usato al momento solo il devtool
724
+ replaceData: /* istanbul ignore next */ (state, { payload }) => {
725
+ /* istanbul ignore next */
726
+ _set(state, [payload.rootName, 'data'], payload.value);
727
+ },
728
+ unsetData: (state, { payload }) => {
729
+ _unset(state, [payload.rootName, 'data', ...payload.id]);
730
+ },
731
+ setIsDataValidating: (state, { payload }) => {
732
+ _set(state, [payload.rootName, 'isValidating'], payload.isValidating);
733
+ },
734
+ resetData: (state, { payload: { rootName, initialData } }) => {
735
+ const touchedFields = _get(state, [rootName, 'errors'], {});
736
+ const newStateData = initialData
737
+ ? Object.keys(touchedFields).reduce((acc, key) => {
738
+ const { path } = getPath(key);
739
+ const initialDataByPath = _get(initialData, [...path], undefined);
740
+ _set(acc, [...path], initialDataByPath);
741
+ return acc;
742
+ }, {})
743
+ : {};
744
+ _set(state, [rootName, 'data'], newStateData);
745
+ _unset(state, [rootName, 'touches']);
746
+ _unset(state, [rootName, 'dirty']);
747
+ _unset(state, [rootName, 'isSubmitted']);
748
+ },
749
+ initData: (state, { payload: { rootName, initialData } }) => {
750
+ _set(state, [rootName, 'data'], initialData);
751
+ }
752
+ };
753
+
754
+ const FlowerCoreReducers = { ...FlowerCoreBaseReducers, ...FlowerCoreDataReducers };
755
+
756
+ const FlowerCoreStateBaseSelectors = {
757
+ selectGlobal: (state) => state && state[exports.REDUCER_NAME.FLOWER_FLOW],
784
758
  selectFlower: (name) => (state) => _get(state, [name]),
785
- selectFlowerFormNode: (id) => (state) => _get(state, ['form', id]),
786
759
  selectFlowerHistory: (flower) => _get(flower, ['history'], []),
787
760
  makeSelectNodesIds: (flower) => _get(flower, ['nodes']),
788
761
  makeSelectStartNodeId: (flower) => _get(flower, ['startId']),
789
- getDataByFlow: (flower) => _get(flower, ['data']) ?? {},
790
- getDataFromState: (id) => (data) => (id === '*' ? data : _get(data, id)),
791
- makeSelectNodeFormSubmitted: (form) => form && form.isSubmitted,
792
- makeSelectNodeFormFieldTouched: (id) => (form) => form && form.touches && form.touches[id],
793
- makeSelectNodeFormFieldFocused: (id) => (form) => {
794
- return form && form.hasFocus === id ? id : undefined;
795
- },
796
- makeSelectNodeFormFieldDirty: (id) => (form) => form && form.dirty && form.dirty[id],
797
762
  makeSelectCurrentNodeId: (flower, startNodeId) => _get(flower, ['current']) || startNodeId,
798
763
  makeSelectCurrentNodeDisabled: (nodes, current) => !!_get(nodes, [current, 'disabled']),
799
764
  makeSelectPrevNodeRetain: (nodes, history, current) => {
@@ -814,14 +779,29 @@ const FlowerCoreStateSelectors = {
814
779
  return nodes[prevFlowerNode] && nodes[prevFlowerNode].retain
815
780
  ? prevFlowerNode
816
781
  : undefined;
782
+ }
783
+ };
784
+
785
+ const FlowerCoreStateDataSelectors = {
786
+ selectGlobalReducerByName: (name) => (state) => state[name] ?? state[exports.REDUCER_NAME.FLOWER_DATA][name],
787
+ selectGlobalData: (state) => {
788
+ return state && state[exports.REDUCER_NAME.FLOWER_DATA];
817
789
  },
818
- makeSelectNodeErrors: createFormData,
819
- makeSelectFieldError: (name, id, validate) => (data, form) => {
820
- const customErrors = Object.entries((form && form.customErrors) || {})
790
+ // getDataByFlow: (flower) => _get(flower, 'data') ?? {},
791
+ getDataFromState: (id) => (data) => (id === '*' ? data : _get(data, id)),
792
+ makeSelectNodeDataSubmitted: (data) => data && data.isSubmitted,
793
+ makeSelectNodeDataFieldTouched: (id) => (data) => data && data.touches && data.touches[id],
794
+ makeSelectNodeDataFieldFocused: (id) => (data) => {
795
+ return data && data.hasFocus === id ? id : undefined;
796
+ },
797
+ makeSelectNodeDataFieldDirty: (id) => (data) => data && data.dirty && data.dirty[id],
798
+ makeSelectNodeErrors: generateData,
799
+ makeSelectFieldError: (name, id, validate) => (globalData, data) => {
800
+ const customErrors = Object.entries((data && data.customErrors) || {})
821
801
  .filter(([k]) => k === id)
822
802
  .map(([, v]) => v)
823
803
  .flat();
824
- if (!validate || !data)
804
+ if (!validate || !globalData)
825
805
  return [];
826
806
  const errors = validate.filter((rule) => {
827
807
  if (!rule)
@@ -829,7 +809,7 @@ const FlowerCoreStateSelectors = {
829
809
  if (!rule.rules)
830
810
  return true;
831
811
  const transformSelf = CoreUtils.mapKeysDeepLodash(rule.rules, (v, key) => key === '$self' ? id : key);
832
- const [hasError] = MatchRules.rulesMatcher(transformSelf, data, false, {
812
+ const [hasError] = rulesMatcher(transformSelf, globalData, false, {
833
813
  prefix: name
834
814
  });
835
815
  return hasError;
@@ -837,8 +817,8 @@ const FlowerCoreStateSelectors = {
837
817
  const result = errors.map((r) => (r && r.message) || 'error');
838
818
  return [...customErrors, ...(result.length === 0 ? [] : result)];
839
819
  },
840
- selectorRulesDisabled: (id, rules, keys, flowName, value) => (data, form) => {
841
- const newState = { ...data, ...value, $form: form };
820
+ selectorRulesDisabled: (id, rules, keys, flowName, value) => (globalData, data) => {
821
+ const newState = { ...globalData, ...value, $data: data, $form: data };
842
822
  const state = Object.assign(newState, id ? { $self: _get(newState, [flowName, ...id.split('.')]) } : {});
843
823
  if (!rules)
844
824
  return false;
@@ -851,39 +831,31 @@ const FlowerCoreStateSelectors = {
851
831
  const k = inc;
852
832
  return Object.assign(acc, { [k]: _get(state, k) });
853
833
  }, {});
854
- const [disabled] = MatchRules.rulesMatcher(rules, { ...flat.unflatten(res) }, false, { prefix: flowName });
834
+ const [disabled] = rulesMatcher(rules, { ...flat.unflatten(res) }, false, {
835
+ prefix: flowName
836
+ });
855
837
  return disabled;
856
838
  }
857
839
  };
858
840
 
859
- exports.RulesOperators = void 0;
860
- (function (RulesOperators) {
861
- RulesOperators["$exists"] = "$exists";
862
- RulesOperators["$eq"] = "$eq";
863
- RulesOperators["$ne"] = "$ne";
864
- RulesOperators["$gt"] = "$gt";
865
- RulesOperators["$gte"] = "$gte";
866
- RulesOperators["$lt"] = "$lt";
867
- RulesOperators["$lte"] = "$lte";
868
- RulesOperators["$strGt"] = "$strGt";
869
- RulesOperators["$strGte"] = "$strGte";
870
- RulesOperators["$strLt"] = "$strLt";
871
- RulesOperators["$strLte"] = "$strLte";
872
- RulesOperators["$in"] = "$in";
873
- RulesOperators["$nin"] = "$nin";
874
- RulesOperators["$all"] = "$all";
875
- RulesOperators["$regex"] = "$regex";
876
- })(exports.RulesOperators || (exports.RulesOperators = {}));
877
- exports.RulesModes = void 0;
878
- (function (RulesModes) {
879
- RulesModes["$and"] = "$and";
880
- RulesModes["$or"] = "$or";
881
- })(exports.RulesModes || (exports.RulesModes = {}));
841
+ const FlowerCoreStateSelectors = {
842
+ ...FlowerCoreStateBaseSelectors,
843
+ ...FlowerCoreStateDataSelectors
844
+ };
882
845
 
883
846
  exports.CoreUtils = CoreUtils;
847
+ exports.DataUtils = DataUtils;
884
848
  exports.Emitter = Emitter;
849
+ exports.FlowUtils = FlowUtils;
850
+ exports.FlowerCoreBaseReducers = FlowerCoreBaseReducers;
851
+ exports.FlowerCoreDataReducers = FlowerCoreDataReducers;
885
852
  exports.FlowerCoreReducers = FlowerCoreReducers;
853
+ exports.FlowerCoreStateBaseSelectors = FlowerCoreStateBaseSelectors;
854
+ exports.FlowerCoreStateDataSelectors = FlowerCoreStateDataSelectors;
855
+ exports.FlowerCoreStateSelectors = FlowerCoreStateSelectors;
886
856
  exports.FlowerStateUtils = FlowerStateUtils;
887
- exports.MatchRules = MatchRules;
888
- exports.Selectors = FlowerCoreStateSelectors;
889
857
  exports.devtoolState = devtoolState;
858
+ exports.flattenRules = flattenRules;
859
+ exports.generateData = generateData;
860
+ exports.rulesMatcher = rulesMatcher;
861
+ exports.rulesMatcherUtils = rulesMatcherUtils;