text: "use strict";
  
  var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
  
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.default = exports.FormStore = void 0;
  
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
  
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
  
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
  
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
  
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
  
  var React = _interopRequireWildcard(require("react"));
  
  var _warning = _interopRequireDefault(require("warning"));
  
  var _FieldContext = require("./FieldContext");
  
  var _asyncUtil = require("./utils/asyncUtil");
  
  var _NameMap = _interopRequireDefault(require("./utils/NameMap"));
  
  var _messages = require("./utils/messages");
  
  var _valueUtil = require("./utils/valueUtil");
  
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
  
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
  
  var FormStore = function FormStore(forceRootUpdate) {
    var _this = this;
  
    (0, _classCallCheck2.default)(this, FormStore);
    this.formHooked = false;
    this.subscribable = true;
    this.store = {};
    this.fieldEntities = [];
    this.initialValues = {};
    this.callbacks = {};
    this.validateMessages = null;
    this.lastValidatePromise = null;
  
    this.getForm = function () {
      return {
        getFieldValue: _this.getFieldValue,
        getFieldsValue: _this.getFieldsValue,
        getFieldError: _this.getFieldError,
        getFieldsError: _this.getFieldsError,
        isFieldsTouched: _this.isFieldsTouched,
        isFieldTouched: _this.isFieldTouched,
        isFieldValidating: _this.isFieldValidating,
        isFieldsValidating: _this.isFieldsValidating,
        resetFields: _this.resetFields,
        setFields: _this.setFields,
        setFieldsValue: _this.setFieldsValue,
        validateFields: _this.validateFields,
        submit: _this.submit,
        getInternalHooks: _this.getInternalHooks
      };
    }; // ======================== Internal Hooks ========================
  
  
    this.getInternalHooks = function (key) {
      if (key === _FieldContext.HOOK_MARK) {
        _this.formHooked = true;
        return {
          dispatch: _this.dispatch,
          registerField: _this.registerField,
          useSubscribe: _this.useSubscribe,
          setInitialValues: _this.setInitialValues,
          setCallbacks: _this.setCallbacks,
          setValidateMessages: _this.setValidateMessages,
          getFields: _this.getFields
        };
      }
  
      (0, _warning.default)(false, '`getInternalHooks` is internal usage. Should not call directly.');
      return null;
    };
  
    this.useSubscribe = function (subscribable) {
      _this.subscribable = subscribable;
    };
    /**
     * First time `setInitialValues` should update store with initial value
     */
  
  
    this.setInitialValues = function (initialValues, init) {
      _this.initialValues = initialValues || {};
  
      if (init) {
        _this.store = (0, _valueUtil.setValues)({}, initialValues, _this.store);
      }
    };
  
    this.getInitialValue = function (namePath) {
      return (0, _valueUtil.getValue)(_this.initialValues, namePath);
    };
  
    this.setCallbacks = function (callbacks) {
      _this.callbacks = callbacks;
    };
  
    this.setValidateMessages = function (validateMessages) {
      _this.validateMessages = validateMessages;
    };
  
    this.warningUnhooked = function () {
      if (process.env.NODE_ENV !== 'production' && !_this.formHooked) {
        (0, _warning.default)(false, 'Instance created by `useForm` is not connect to any Form element. Forget to pass `form` prop?');
      }
    }; // ============================ Fields ============================
  
    /**
     * Get registered field entities.
     * @param pure Only return field which has a `name`. Default: false
     */
  
  
    this.getFieldEntities = function () {
      var pure = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
  
      if (!pure) {
        return _this.fieldEntities;
      }
  
      return _this.fieldEntities.filter(function (field) {
        return field.getNamePath().length;
      });
    };
  
    this.getFieldsMap = function () {
      var pure = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
      var cache = new _NameMap.default();
  
      _this.getFieldEntities(pure).forEach(function (field) {
        var namePath = field.getNamePath();
        cache.set(namePath, field);
      });
  
      return cache;
    };
  
    this.getFieldEntitiesForNamePathList = function (nameList) {
      if (!nameList) {
        return _this.getFieldEntities(true);
      }
  
      var cache = _this.getFieldsMap(true);
  
      return nameList.map(function (name) {
        var namePath = (0, _valueUtil.getNamePath)(name);
        return cache.get(namePath) || {
          INVALIDATE_NAME_PATH: (0, _valueUtil.getNamePath)(name)
        };
      });
    };
  
    this.getFieldsValue = function (nameList, filterFunc) {
      _this.warningUnhooked();
  
      if (nameList === true && !filterFunc) {
        return _this.store;
      }
  
      var fieldEntities = _this.getFieldEntitiesForNamePathList(Array.isArray(nameList) ? nameList : null);
  
      var filteredNameList = [];
      fieldEntities.forEach(function (entity) {
        var namePath = 'INVALIDATE_NAME_PATH' in entity ? entity.INVALIDATE_NAME_PATH : entity.getNamePath();
  
        if (!filterFunc) {
          filteredNameList.push(namePath);
        } else {
          var meta = 'getMeta' in entity ? entity.getMeta() : null;
  
          if (filterFunc(meta)) {
            filteredNameList.push(namePath);
          }
        }
      });
      return (0, _valueUtil.cloneByNamePathList)(_this.store, filteredNameList.map(_valueUtil.getNamePath));
    };
  
    this.getFieldValue = function (name) {
      _this.warningUnhooked();
  
      var namePath = (0, _valueUtil.getNamePath)(name);
      return (0, _valueUtil.getValue)(_this.store, namePath);
    };
  
    this.getFieldsError = function (nameList) {
      _this.warningUnhooked();
  
      var fieldEntities = _this.getFieldEntitiesForNamePathList(nameList);
  
      return fieldEntities.map(function (entity, index) {
        if (entity && !('INVALIDATE_NAME_PATH' in entity)) {
          return {
            name: entity.getNamePath(),
            errors: entity.getErrors()
          };
        }
  
        return {
          name: (0, _valueUtil.getNamePath)(nameList[index]),
          errors: []
        };
      });
    };
  
    this.getFieldError = function (name) {
      _this.warningUnhooked();
  
      var namePath = (0, _valueUtil.getNamePath)(name);
  
      var fieldError = _this.getFieldsError([namePath])[0];
  
      return fieldError.errors;
    };
  
    this.isFieldsTouched = function () {
      _this.warningUnhooked();
  
      for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }
  
      var arg0 = args[0],
          arg1 = args[1];
      var namePathList;
      var isAllFieldsTouched = false;
  
      if (args.length === 0) {
        namePathList = null;
      } else if (args.length === 1) {
        if (Array.isArray(arg0)) {
          namePathList = arg0.map(_valueUtil.getNamePath);
          isAllFieldsTouched = false;
        } else {
          namePathList = null;
          isAllFieldsTouched = arg0;
        }
      } else {
        namePathList = arg0.map(_valueUtil.getNamePath);
        isAllFieldsTouched = arg1;
      }
  
      var testTouched = function testTouched(field) {
        // Not provide `nameList` will check all the fields
        if (!namePathList) {
          return field.isFieldTouched();
        }
  
        var fieldNamePath = field.getNamePath();
  
        if ((0, _valueUtil.containsNamePath)(namePathList, fieldNamePath)) {
          return field.isFieldTouched();
        }
  
        return isAllFieldsTouched;
      };
  
      return isAllFieldsTouched ? _this.getFieldEntities(true).every(testTouched) : _this.getFieldEntities(true).some(testTouched);
    };
  
    this.isFieldTouched = function (name) {
      _this.warningUnhooked();
  
      return _this.isFieldsTouched([name]);
    };
  
    this.isFieldsValidating = function (nameList) {
      _this.warningUnhooked();
  
      var fieldEntities = _this.getFieldEntities();
  
      if (!nameList) {
        return fieldEntities.some(function (testField) {
          return testField.isFieldValidating();
        });
      }
  
      var namePathList = nameList.map(_valueUtil.getNamePath);
      return fieldEntities.some(function (testField) {
        var fieldNamePath = testField.getNamePath();
        return (0, _valueUtil.containsNamePath)(namePathList, fieldNamePath) && testField.isFieldValidating();
      });
    };
  
    this.isFieldValidating = function (name) {
      _this.warningUnhooked();
  
      return _this.isFieldsValidating([name]);
    };
  
    this.resetFields = function (nameList) {
      _this.warningUnhooked();
  
      var prevStore = _this.store;
  
      if (!nameList) {
        _this.store = (0, _valueUtil.setValues)({}, _this.initialValues);
  
        _this.notifyObservers(prevStore, null, {
          type: 'reset'
        });
  
        return;
      } // Reset by `nameList`
  
  
      var namePathList = nameList.map(_valueUtil.getNamePath);
      namePathList.forEach(function (namePath) {
        var initialValue = _this.getInitialValue(namePath);
  
        _this.store = (0, _valueUtil.setValue)(_this.store, namePath, initialValue);
      });
  
      _this.notifyObservers(prevStore, namePathList, {
        type: 'reset'
      });
    };
  
    this.setFields = function (fields) {
      _this.warningUnhooked();
  
      var prevStore = _this.store;
      fields.forEach(function (fieldData) {
        var name = fieldData.name,
            errors = fieldData.errors,
            data = (0, _objectWithoutProperties2.default)(fieldData, ["name", "errors"]);
        var namePath = (0, _valueUtil.getNamePath)(name); // Value
  
        if ('value' in data) {
          _this.store = (0, _valueUtil.setValue)(_this.store, namePath, data.value);
        }
  
        _this.notifyObservers(prevStore, [namePath], {
          type: 'setField',
          data: fieldData
        });
      });
    };
  
    this.getFields = function () {
      return _this.getFieldEntities(true).map(function (field) {
        var namePath = field.getNamePath();
        var meta = field.getMeta();
  
        var fieldData = _objectSpread({}, meta, {
          name: namePath,
          value: _this.getFieldValue(namePath)
        });
  
        Object.defineProperty(fieldData, 'originRCField', {
          value: true
        });
        return fieldData;
      });
    }; // =========================== Observer ===========================
  
  
    this.registerField = function (entity) {
      _this.fieldEntities.push(entity);
  
      return function () {
        _this.fieldEntities = _this.fieldEntities.filter(function (item) {
          return item !== entity;
        });
      };
    };
  
    this.dispatch = function (action) {
      switch (action.type) {
        case 'updateValue':
          {
            var namePath = action.namePath,
                value = action.value;
  
            _this.updateValue(namePath, value);
  
            break;
          }
  
        case 'validateField':
          {
            var _namePath = action.namePath,
                triggerName = action.triggerName;
  
            _this.validateFields([_namePath], {
              triggerName: triggerName
            });
  
            break;
          }
  
        default: // Currently we don't have other action. Do nothing.
  
      }
    };
  
    this.notifyObservers = function (prevStore, namePathList, info) {
      if (_this.subscribable) {
        _this.getFieldEntities().forEach(function (_ref) {
          var onStoreChange = _ref.onStoreChange;
          onStoreChange(prevStore, namePathList, info);
        });
      } else {
        _this.forceRootUpdate();
      }
    };
  
    this.updateValue = function (name, value) {
      var namePath = (0, _valueUtil.getNamePath)(name);
      var prevStore = _this.store;
      _this.store = (0, _valueUtil.setValue)(_this.store, namePath, value);
  
      _this.notifyObservers(prevStore, [namePath], {
        type: 'valueUpdate',
        source: 'internal'
      }); // Notify dependencies children with parent update
  
  
      var childrenFields = _this.getDependencyChildrenFields(namePath);
  
      _this.validateFields(childrenFields);
  
      _this.notifyObservers(prevStore, childrenFields, {
        type: 'dependenciesUpdate',
        relatedFields: [namePath].concat((0, _toConsumableArray2.default)(childrenFields))
      }); // trigger callback function
  
  
      var onValuesChange = _this.callbacks.onValuesChange;
  
      if (onValuesChange) {
        var changedValues = (0, _valueUtil.cloneByNamePathList)(_this.store, [namePath]);
        onValuesChange(changedValues, _this.store);
      }
  
      _this.triggerOnFieldsChange([namePath].concat((0, _toConsumableArray2.default)(childrenFields)));
    }; // Let all child Field get update.
  
  
    this.setFieldsValue = function (store) {
      _this.warningUnhooked();
  
      var prevStore = _this.store;
  
      if (store) {
        _this.store = (0, _valueUtil.setValues)(_this.store, store);
      }
  
      _this.notifyObservers(prevStore, null, {
        type: 'valueUpdate',
        source: 'external'
      });
    };
  
    this.getDependencyChildrenFields = function (rootNamePath) {
      var children = new Set();
      var childrenFields = [];
      var dependencies2fields = new _NameMap.default();
      /**
       * Generate maps
       * Can use cache to save perf if user report performance issue with this
       */
  
      _this.getFieldEntities().forEach(function (field) {
        var dependencies = field.props.dependencies;
        (dependencies || []).forEach(function (dependency) {
          var dependencyNamePath = (0, _valueUtil.getNamePath)(dependency);
          dependencies2fields.update(dependencyNamePath, function () {
            var fields = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Set();
            fields.add(field);
            return fields;
          });
        });
      });
  
      var fillChildren = function fillChildren(namePath) {
        var fields = dependencies2fields.get(namePath) || new Set();
        fields.forEach(function (field) {
          if (!children.has(field)) {
            children.add(field);
            var fieldNamePath = field.getNamePath();
  
            if (field.isFieldTouched() && fieldNamePath.length) {
              childrenFields.push(fieldNamePath);
              fillChildren(fieldNamePath);
            }
          }
        });
      };
  
      fillChildren(rootNamePath);
      return childrenFields;
    };
  
    this.triggerOnFieldsChange = function (namePathList, filedErrors) {
      var onFieldsChange = _this.callbacks.onFieldsChange;
  
      if (onFieldsChange) {
        var fields = _this.getFields();
        /**
         * Fill errors since `fields` may be replaced by controlled fields
         */
  
  
        if (filedErrors) {
          var cache = new _NameMap.default();
          filedErrors.forEach(function (_ref2) {
            var name = _ref2.name,
                errors = _ref2.errors;
            cache.set(name, errors);
          });
          fields.forEach(function (field) {
            // eslint-disable-next-line no-param-reassign
            field.errors = cache.get(field.name) || field.errors;
          });
        }
  
        var changedFields = fields.filter(function (_ref3) {
          var fieldName = _ref3.name;
          return (0, _valueUtil.containsNamePath)(namePathList, fieldName);
        });
        onFieldsChange(changedFields, fields);
      }
    }; // =========================== Validate ===========================
  
  
    this.validateFields = function (nameList, options) {
      _this.warningUnhooked();
  
      var provideNameList = !!nameList;
      var namePathList = provideNameList ? nameList.map(_valueUtil.getNamePath) : []; // Collect result in promise list
  
      var promiseList = [];
  
      _this.getFieldEntities(true).forEach(function (field) {
        // Add field if not provide `nameList`
        if (!provideNameList) {
          namePathList.push(field.getNamePath());
        } // Skip if without rule
  
  
        if (!field.props.rules || !field.props.rules.length) {
          return;
        }
  
        var fieldNamePath = field.getNamePath(); // Add field validate rule in to promise list
  
        if (!provideNameList || (0, _valueUtil.containsNamePath)(namePathList, fieldNamePath)) {
          var promise = field.validateRules(_objectSpread({
            validateMessages: _objectSpread({}, _messages.defaultValidateMessages, {}, _this.validateMessages)
          }, options)); // Wrap promise with field
  
          promiseList.push(promise.then(function () {
            return {
              name: fieldNamePath,
              errors: []
            };
          }).catch(function (errors) {
            return Promise.reject({
              name: fieldNamePath,
              errors: errors
            });
          }));
        }
      });
  
      var summaryPromise = (0, _asyncUtil.allPromiseFinish)(promiseList);
      _this.lastValidatePromise = summaryPromise; // Notify fields with rule that validate has finished and need update
  
      summaryPromise.catch(function (results) {
        return results;
      }).then(function (results) {
        var resultNamePathList = results.map(function (_ref4) {
          var name = _ref4.name;
          return name;
        });
  
        _this.notifyObservers(_this.store, resultNamePathList, {
          type: 'validateFinish'
        });
  
        _this.triggerOnFieldsChange(resultNamePathList, results);
      });
      var returnPromise = summaryPromise.then(function () {
        if (_this.lastValidatePromise === summaryPromise) {
          return Promise.resolve(_this.getFieldsValue(namePathList));
        }
  
        return Promise.reject([]);
      }).catch(function (results) {
        var errorList = results.filter(function (result) {
          return result && result.errors.length;
        });
        return Promise.reject({
          values: _this.getFieldsValue(namePathList),
          errorFields: errorList,
          outOfDate: _this.lastValidatePromise !== summaryPromise
        });
      }); // Do not throw in console
  
      returnPromise.catch(function (e) {
        return e;
      });
      return returnPromise;
    }; // ============================ Submit ============================
  
  
    this.submit = function () {
      _this.warningUnhooked();
  
      _this.validateFields().then(function (values) {
        var onFinish = _this.callbacks.onFinish;
  
        if (onFinish) {
          try {
            onFinish(values);
          } catch (err) {
            // Should print error if user `onFinish` callback failed
            console.error(err);
          }
        }
      }).catch(function (e) {
        var onFinishFailed = _this.callbacks.onFinishFailed;
  
        if (onFinishFailed) {
          onFinishFailed(e);
        }
      });
    };
  
    this.forceRootUpdate = forceRootUpdate;
  };
  
  exports.FormStore = FormStore;
  
  function useForm(form) {
    var formRef = React.useRef();
  
    var _React$useState = React.useState(),
        _React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2),
        forceUpdate = _React$useState2[1];
  
    if (!formRef.current) {
      if (form) {
        formRef.current = form;
      } else {
        // Create a new FormStore if not provided
        var forceReRender = function forceReRender() {
          forceUpdate({});
        };
  
        var formStore = new FormStore(forceReRender);
        formRef.current = formStore.getForm();
      }
    }
  
    return [formRef.current];
  }
  
  var _default = useForm;
  exports.default = _default;