UNPKG

@vaadin/hilla-lit-form

Version:

Hilla form utils

356 lines 16.8 kB
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _BinderNode_instances, _BinderNode_ownErrors, _BinderNode_validators, _BinderNode_validityStateValidator, _BinderNode_visited, _BinderNode_getChildBinderNodes, _BinderNode_isArray, _BinderNode_isArrayItem, _BinderNode_isObject, _BinderNode_requestValidationOfDescendants, _BinderNode_requestValidationWithAncestors, _BinderNode_runOwnValidators, _BinderNode_setValueState, _a; import { _createEmptyItemValue, _key, _parent, _validators, AbstractModel, ArrayModel, getObjectModelOwnAndParentGetters, ObjectModel, } from './Models.js'; import { ValidityStateValidator } from './Validators.js'; import { _validity } from './Validity.js'; export const _updateValidation = Symbol('updateValidation'); export const _update = Symbol('update'); export const _setErrorsWithDescendants = Symbol('setErrorsWithDescendants'); export const _clearValidation = Symbol('clearValidation'); const nodes = new WeakMap(); export function getBinderNode(model) { let node = nodes.get(model); if (!node) { node = new BinderNode(model); nodes.set(model, node); } return node; } function getErrorPropertyName(valueError) { return typeof valueError.property === 'string' ? valueError.property : getBinderNode(valueError.property).name; } function updateObjectOrArrayKey(model, value, key, keyValue) { if (model instanceof ObjectModel) { return { ...value, [key]: keyValue, }; } if (keyValue === undefined) { throw new TypeError('Unexpected undefined value'); } if (model instanceof ArrayModel) { const array = value.slice(); array[key] = keyValue; return array; } throw new TypeError(`Unknown model type ${model.constructor.name}`); } export const CHANGED = new Event('binder-node-changed'); class NotArrayModelError extends Error { constructor() { super('The model does not represent array'); } } class NotArrayItemModelError extends Error { constructor() { super('The model does not represent array item'); } } const defaultArrayItemCache = new WeakMap(); export class BinderNode extends EventTarget { constructor(model) { super(); _BinderNode_instances.add(this); Object.defineProperty(this, "model", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, _a, { enumerable: true, configurable: true, writable: true, value: void 0 }); _BinderNode_ownErrors.set(this, void 0); _BinderNode_validators.set(this, void 0); _BinderNode_validityStateValidator.set(this, void 0); _BinderNode_visited.set(this, false); this.model = model; nodes.set(model, this); __classPrivateFieldSet(this, _BinderNode_validityStateValidator, new ValidityStateValidator(), "f"); __classPrivateFieldSet(this, _BinderNode_validators, model[_validators], "f"); if (this.constructor === BinderNode) { this.initializeValue(); } } get binder() { const binder = this.parent?.binder; if (!binder) { throw new TypeError('BinderNode is detached'); } return binder; } get defaultValue() { const key = this.model[_key]; const parentDefaultValue = this.parent.defaultValue; if (__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_isArrayItem).call(this) && !(key in parentDefaultValue)) { if (defaultArrayItemCache.has(this.parent)) { return defaultArrayItemCache.get(this.parent); } const value = this.model.constructor.createEmptyValue(); defaultArrayItemCache.set(this.parent, value); return value; } return parentDefaultValue[key]; } get dirty() { return this.value !== this.defaultValue; } get errors() { return [...Array.from(__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_getChildBinderNodes).call(this), (node) => node.errors).flat(), ...this.ownErrors]; } get invalid() { return this.errors.length > 0; } get name() { let { model } = this; let name = ''; while (model[_parent] instanceof AbstractModel) { name = `${String(model[_key])}${name ? `.${name}` : ''}`; model = model[_parent]; } return name; } get ownErrors() { return __classPrivateFieldGet(this, _BinderNode_ownErrors, "f") ? __classPrivateFieldGet(this, _BinderNode_ownErrors, "f") : []; } get parent() { const modelParent = this.model[_parent]; return modelParent instanceof AbstractModel ? getBinderNode(modelParent) : undefined; } get required() { return __classPrivateFieldGet(this, _BinderNode_validators, "f").some((validator) => validator.impliesRequired); } get validators() { return __classPrivateFieldGet(this, _BinderNode_validators, "f"); } set validators(validators) { __classPrivateFieldSet(this, _BinderNode_validators, validators, "f"); this.dispatchEvent(CHANGED); } get value() { if (!this.parent) { return undefined; } this.initializeValue(); const key = this.model[_key]; return this.parent.value[key]; } set value(value) { this.initializeValue(true); const oldValue = this.value; if (value !== oldValue) { __classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_setValueState).call(this, value, undefined); this[_updateValidation]().catch(() => { }); } } get visited() { return __classPrivateFieldGet(this, _BinderNode_visited, "f"); } set visited(v) { if (__classPrivateFieldGet(this, _BinderNode_visited, "f") !== v) { __classPrivateFieldSet(this, _BinderNode_visited, v, "f"); this.dispatchEvent(CHANGED); } } addValidator(validator) { this.validators = [...__classPrivateFieldGet(this, _BinderNode_validators, "f"), validator]; this.dispatchEvent(CHANGED); } appendItem(item) { if (__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_isArray).call(this)) { const itemValueOrEmptyValue = item ?? this.model[_createEmptyItemValue](); const newValue = [...(this.value ?? []), itemValueOrEmptyValue]; const newDefaultValue = [...(this.defaultValue ?? []), itemValueOrEmptyValue]; __classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_setValueState).call(this, newValue, newDefaultValue); } else { throw new NotArrayModelError(); } } for(model) { const binderNode = getBinderNode(model); if (binderNode.binder !== this.binder) { throw new Error('Unknown binder'); } return binderNode; } prependItem(item) { if (__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_isArray).call(this)) { const itemValueOrEmptyValue = item ?? this.model[_createEmptyItemValue](); const newValue = [itemValueOrEmptyValue, ...(this.value ?? [])]; const newDefaultValue = [itemValueOrEmptyValue, ...(this.defaultValue ?? [])]; __classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_setValueState).call(this, newValue, newDefaultValue); } else { throw new NotArrayModelError(); } } removeSelf() { var _b; if (__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_isArrayItem).call(this)) { const newValue = (this.parent.value ?? []).filter((_, i) => i !== this.model[_key]); const newDefaultValue = (this.parent.defaultValue ?? []).filter((_, i) => i !== this.model[_key]); __classPrivateFieldGet((_b = this.parent), _BinderNode_instances, "m", _BinderNode_setValueState).call(_b, newValue, newDefaultValue); } else { throw new NotArrayItemModelError(); } } async validate() { const errors = await Promise.all([ ...__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_requestValidationOfDescendants).call(this), ...__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_requestValidationWithAncestors).call(this), ]).then((arr) => arr.flat()); this[_setErrorsWithDescendants](errors.length ? errors : undefined); this[_update](); return errors; } [(_BinderNode_ownErrors = new WeakMap(), _BinderNode_validators = new WeakMap(), _BinderNode_validityStateValidator = new WeakMap(), _BinderNode_visited = new WeakMap(), _BinderNode_instances = new WeakSet(), _a = _validity, _clearValidation)]() { if (__classPrivateFieldGet(this, _BinderNode_visited, "f")) { __classPrivateFieldSet(this, _BinderNode_visited, false, "f"); this.dispatchEvent(CHANGED); } let needsUpdate = false; if (__classPrivateFieldGet(this, _BinderNode_ownErrors, "f")) { __classPrivateFieldSet(this, _BinderNode_ownErrors, undefined, "f"); needsUpdate = true; this.dispatchEvent(CHANGED); } if ([...__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_getChildBinderNodes).call(this)].filter((childBinderNode) => childBinderNode[_clearValidation]()).length > 0) { needsUpdate = true; } return needsUpdate; } [_setErrorsWithDescendants](errors) { const { name } = this; const ownErrors = errors ? errors.filter((valueError) => getErrorPropertyName(valueError) === name) : undefined; const relatedErrors = errors ? errors.filter((valueError) => getErrorPropertyName(valueError).startsWith(name)) : undefined; __classPrivateFieldSet(this, _BinderNode_ownErrors, ownErrors, "f"); for (const childBinderNode of __classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_getChildBinderNodes).call(this)) { childBinderNode[_setErrorsWithDescendants](relatedErrors); } this.dispatchEvent(CHANGED); } [_update](_) { if (this.parent) { this.parent[_update](); } } async [_updateValidation]() { if (this.invalid) { await this.validate(); } } initializeValue(forceInitialize = false) { if (this.parent && (this.parent.value === undefined || this.parent.defaultValue === undefined)) { this.parent.initializeValue(true); } const key = this.model[_key]; let value = this.parent ? this.parent.value[this.model[_key]] : undefined; const defaultValue = this.parent ? this.parent.defaultValue[this.model[_key]] : undefined; if (value === undefined) { if (forceInitialize || !this.parent) { value = this.model.constructor.createEmptyValue(); __classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_setValueState).call(this, value, defaultValue === undefined ? value : defaultValue); } else if (this.parent.model instanceof ObjectModel && !(key in (this.parent.value || {}))) { __classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_setValueState).call(this, undefined, defaultValue === undefined ? value : defaultValue); } } } } _BinderNode_getChildBinderNodes = function* _BinderNode_getChildBinderNodes() { if (this.value === undefined || this.defaultValue === undefined) { return; } if (__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_isObject).call(this)) { for (const [, getter] of getObjectModelOwnAndParentGetters(this.model)) { const childModel = getter.call(this.model); if (childModel[_key] in this.defaultValue) { yield getBinderNode(childModel); } } } else if (__classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_isArray).call(this)) { for (const childBinderNode of this.model) { yield childBinderNode; } } }, _BinderNode_isArray = function _BinderNode_isArray() { return this.model instanceof ArrayModel; }, _BinderNode_isArrayItem = function _BinderNode_isArrayItem() { return this.model[_parent] instanceof ArrayModel; }, _BinderNode_isObject = function _BinderNode_isObject() { return this.model instanceof ObjectModel; }, _BinderNode_requestValidationOfDescendants = function* _BinderNode_requestValidationOfDescendants() { for (const node of __classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_getChildBinderNodes).call(this)) { yield* __classPrivateFieldGet(node, _BinderNode_instances, "m", _BinderNode_runOwnValidators).call(node); yield* __classPrivateFieldGet(node, _BinderNode_instances, "m", _BinderNode_requestValidationOfDescendants).call(node); } }, _BinderNode_requestValidationWithAncestors = function* _BinderNode_requestValidationWithAncestors() { var _b; yield* __classPrivateFieldGet(this, _BinderNode_instances, "m", _BinderNode_runOwnValidators).call(this); if (this.parent) { yield* __classPrivateFieldGet((_b = this.parent), _BinderNode_instances, "m", _BinderNode_requestValidationWithAncestors).call(_b); } }, _BinderNode_runOwnValidators = function* _BinderNode_runOwnValidators() { const hasInvalidState = this[_validity] && !this[_validity].valid; const hasBadInput = !!this[_validity]?.badInput; if ((hasInvalidState && !hasBadInput) || !hasInvalidState) { for (const validator of __classPrivateFieldGet(this, _BinderNode_validators, "f")) { yield this.binder.requestValidation(this.model, validator); } } if (hasInvalidState) { yield this.binder.requestValidation(this.model, __classPrivateFieldGet(this, _BinderNode_validityStateValidator, "f")); } }, _BinderNode_setValueState = function _BinderNode_setValueState(value, defaultValue) { const { parent } = this; if (parent) { const key = this.model[_key]; const parentValue = updateObjectOrArrayKey(parent.model, parent.value, key, value); const keepPristine = value === defaultValue && parent.value === parent.defaultValue; if (keepPristine) { __classPrivateFieldGet(parent, _BinderNode_instances, "m", _BinderNode_setValueState).call(parent, parentValue, parentValue); } else if (defaultValue !== undefined) { const parentDefaultValue = updateObjectOrArrayKey(parent.model, parent.defaultValue, key, defaultValue); __classPrivateFieldGet(parent, _BinderNode_instances, "m", _BinderNode_setValueState).call(parent, parentValue, parentDefaultValue); } else { __classPrivateFieldGet(parent, _BinderNode_instances, "m", _BinderNode_setValueState).call(parent, parentValue, undefined); } } else { const binder = this; if (defaultValue !== undefined) { binder.defaultValue = defaultValue; } binder.value = value; } }; //# sourceMappingURL=BinderNode.js.map