Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@metronlabs/rx-form-data

Package Overview
Dependencies
Maintainers
2
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@metronlabs/rx-form-data - npm Package Compare versions

Comparing version 0.0.6 to 0.0.7

lib/types/datatypes/Decoder.d.ts

2

lib/index.js

@@ -1,1 +0,1 @@

"use strict";const e=e=>"string"==typeof e,t=t=>Boolean(e(t)&&t.trim().length),n=e=>"[object RegExp]"===Object.prototype.toString.call(e),r={_is:"None"};function a(e){return{_is:"Some",value:e}}function c(e){return"Some"===e._is}function i(e){return"None"===e._is}function s(e,t){return n=>i(n)?e():t(n.value)}function o(e,t,n){return i(e)&&i(t)?r:c(e)&&c(t)?n?a(n(e.value,t.value)):t:c(e)&&i(t)?e:i(e)&&c(t)?t:r}function u(e){return null===e||void 0===e?r:a(e)}function l(e){return isNaN(Number(e))?r:a(Number(e))}function E(n,c){return e(n)?c?t(n)?a(n):r:a(n):r}const f={INPUT_TEXT:"input:text",INPUT_NUMBER:"input:number",INPUT_EMAIL:"input:email",INPUT_PASSWORD:"input:password",INPUT_CHECKBOX:"input:checkbox",INPUT_RADIO:"input:radio",INPUT_COLOR:"input:color",INPUT_DATE:"input:date",INPUT_DATETIME_LOCAL:"input:datetime-local",INPUT_FILE:"input:file",INPUT_HIDDEN:"input:hidden",INPUT_MONTH:"input:month",INPUT_RANGE:"input:range",INPUT_SEARCH:"input:search",INPUT_TEL:"input:tel",INPUT_TIME:"input:time",INPUT_URL:"input:url",INPUT_WEEK:"input:week",TEXTAREA:"textarea:textarea",SELECT_SINGLE:"select:select-one",SELECT_MULTIPLE:"select:select-multiple"},T={FOCUS:"focus",INPUT:"input",CHANGE:"change",BLUR:"blur",SUBMIT:"submit",RESET:"reset"},m="REGISTER_ALL",d="UNREGISTER_ALL",I="REGISTER",N="UNREGISTER",_="UPSERT_FIELD",R="DELETE_FIELD",U="CLEAR_FIELDS",v="RESET",L={EMIT_FORM_VALUES:"EMIT_FORM_VALUES"},A="ADD",S="DELETE",b="CLEAR",p={REGISTER:"REGISTER_FIELDS",REGISTER_ALL:"REGISTER_ALL_FIELDS",UNREGISTER:"UNREGISTER_FIELDS",UNREGISTER_ALL:"UNREGISTER_ALL_FIELDS",DESTROY:"DESTROY_PROGRAM"};function P(e){return e instanceof HTMLFormElement}function O(e){return e instanceof HTMLInputElement}function y(e){return e instanceof HTMLTextAreaElement}function h(e){return e instanceof HTMLSelectElement}function w(e){return O(e)||h(e)||y(e)}function D(e){return w(e)?O(e)?function(e){if(!O(e))return r;const n=`${e.tagName.toLowerCase()}:${e.type}`;switch(n){case f.INPUT_TEXT:case f.INPUT_SEARCH:case f.INPUT_EMAIL:case f.INPUT_COLOR:case f.INPUT_HIDDEN:return a(e.value.trim());case f.INPUT_PASSWORD:return a(e.value);case f.INPUT_NUMBER:case f.INPUT_RANGE:return l(Number(e.value.trim()));case f.INPUT_URL:try{return a(new URL(e.value.trim()).href.trim())}catch(t){return console.warn("[RxFormData] Failed to decode url input field value into URL object",e.value,t),r}case f.INPUT_TEL:return a(e.value.trim().replace(/\D/g,""));case f.INPUT_FILE:return s(()=>r,e=>a(Object.freeze(Array.from(Array(e.length).keys()).reduce((t,n)=>{const r=e.item(n);return r?t.concat(r):t},[]))))(u(e.files));case f.INPUT_DATE:case f.INPUT_DATETIME_LOCAL:case f.INPUT_TIME:case f.INPUT_WEEK:return l(e.valueAsNumber);case f.INPUT_MONTH:try{return a(new Date(e.value+"-1").getTime())}catch(e){return console.error("[RxFormData] Failed to decode month input field value into number",e),r}case f.INPUT_RADIO:case f.INPUT_CHECKBOX:{const c=n.split(":")[1],s=u(e.form);if(i(s))return r;const o=s.value.querySelectorAll(`input[type='${c}'][name='${e.name}']:checked`);return a(Object.freeze(Array.from(o).map((n,r)=>O(n)&&t(n.value)?n.value.trim():`${e.name}[${r}]`)))}default:return r}}(e):h(e)?function(e){if(!h(e))return r;switch(`${e.tagName.toLowerCase()}:${e.type}`){case f.SELECT_SINGLE:case f.SELECT_MULTIPLE:return a(Object.freeze(Array.from(e.selectedOptions).map((n,r)=>t(n.value)?n.value.trim():`${e.name}[${r}]`)));default:return r}}(e):y(e)?function(e){return y(e)?a(e.value.trim()):r}(e):r:r}function g(t){return!!e(t)||("number"==typeof t||!(!Array.isArray(t)||!t.every(e)&&!t.every(e=>e instanceof File)))}function M(e){return t(e)&&Object.keys(f).includes(e)}function C(e){if(e instanceof Error)throw e;const t=new Error("[RxFormData] ERROR!");throw t.details=JSON.stringify(e),t}function j(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)&&"Object"===e.constructor.name}const F=Object.freeze({$:r,tag:r,name:r,value:r,validity:r,touched:!1,modified:!1,visited:!1});function k(e){if(!j(e))return!1;const n=Object.keys(F);if(!Object.keys(e).every(e=>n.includes(e)))return!1;const r=(e,n)=>j(e)&&t(e._is)&&["none","some"].includes(e._is)&&("some"!==e._is||n(e.value));return Object.entries(e).reduce((e,[n,a])=>{switch(n){case"$":return e&&r(a,w);case"tag":return e&&r(a,M);case"name":return e&&r(a,t);case"value":return e&&r(a,g);case"validity":return e&&r(a,e=>e instanceof ValidityState);case"touched":case"visited":case"modified":return"boolean"==typeof a;default:return!1}},!0)}function G(e,t){const n=s(()=>t,e=>e)(e.$),r=s(()=>t,e=>e)(e.tag),a=s(()=>t,e=>e)(e.name),c=s(()=>t,e=>e)(e.validity);return Object.freeze({$:n,tag:r,name:a,value:(()=>{if(r===t)return t;const n=s(()=>t,e=>e)(e.value);if(n===t)return n;switch(r){case f.INPUT_TEXT:case f.INPUT_SEARCH:case f.INPUT_EMAIL:case f.INPUT_COLOR:case f.INPUT_HIDDEN:case f.TEXTAREA:case f.INPUT_URL:case f.INPUT_TEL:case f.INPUT_PASSWORD:return String(n);case f.INPUT_NUMBER:case f.INPUT_RANGE:case f.INPUT_DATE:case f.INPUT_DATETIME_LOCAL:case f.INPUT_TIME:case f.INPUT_WEEK:case f.INPUT_MONTH:return Number(n);case f.INPUT_FILE:return Array.isArray(n)?Object.freeze(n.map(e=>Object.freeze(e))):[];case f.INPUT_RADIO:case f.INPUT_CHECKBOX:case f.SELECT_SINGLE:case f.SELECT_MULTIPLE:return Array.isArray(n)?Object.freeze(n.map(String)):[];default:return t}})(),validity:c,touched:e.touched,modified:e.modified,visited:e.visited})}function $(e,t){if(i(t.name))return e;const n=t.name.value,r=u(e.get(n)),a=s(()=>t,e=>{return n=e,r=t,Object.freeze({$:o(n.$,r.$),tag:o(n.tag,r.tag),name:o(n.name,r.name),value:o(n.value,r.value),validity:o(n.validity,r.validity,(e,t)=>({...e,...t})),touched:n.touched||r.touched,modified:n.modified||r.modified,visited:n.visited||r.visited});var n,r})(r);return e.set(n,a)}function z(e,t){return e.clear(),t?new Map(t.entries()):e}function H(e,n,r){for(let e=0,t=r.length;e<t;e++)n.delete(r[e]);for(const n of e.keys()){r.some(e=>e instanceof RegExp?e.test(n):!!t(e)&&e.trim()===n.trim())&&e.delete(n)}return[n,e]}function x(e,t){const n=new CustomEvent(L.EMIT_FORM_VALUES,{detail:Object.freeze(new Map(t.entries()))});e.dispatchEvent(n)}function B(r){const a=new Map;if(i(r))return void C("[RxFormData] invalid form element for form field storage initialization");const c=r.value,o=new Map;o.set(a,new Map(a.entries()));const u=()=>{const e=o.get(a);return e?new Map(e.entries()):new Map},l=new Set,f=(new Map).set(l,l),T=()=>{const e=f.get(l);return e?new Set(e.values()):new Set};return{storage:u,action:(r,L)=>{switch(r){case _:if(k(L)){const e=s(()=>"",e=>e.trim())(L.name);[...T().keys()].some(r=>t(r)?r.trim()===e.trim():!!n(r)&&r.test(e))&&(o.set(a,$(u(),L)),x(c,u()))}break;case U:o.set(a,z(u())),f.set(l,new Set),x(c,u());break;case m:{const e=Array.from(c.elements).reduce((e,t)=>w(t)?e.concat(t.name):e,[]);f.set(l,new Set(e));break}case d:f.set(l,new Set);break;case R:{const n=Array.isArray(L)?L.filter(e=>t(e)||k(e)):[];n.length&&(o.set(a,function(n,r){return r.reduce((n,r)=>{const a=e(r)?E(r,!0):r.name;return i(a)?n:t(a.value)?(n.delete(a.value.trim()),n):n},n)}(u(),n)),x(c,u()));break}case v:o.set(a,z(u(),a)),x(c,u());break;case I:{const e=Array.isArray(L)?L.filter(e=>t(e)||n(e)):[];e.length&&f.set(l,function(e,t){for(let n=0,r=t.length;n<r;n++)e.add(t[n]);return e}(T(),e));break}case N:if(L&&j(L)){const e=Array.isArray(L.use)?L.use.filter(e=>t(e)||n(e)):[];if(e.length){const t=H(u(),T(),e);f.set(l,t[0]),L.keepvalues||(o.set(a,t[1]),x(c,u()))}}else{const e=Array.isArray(L)?L.filter(e=>t(e)||n(e)):[];if(e.length){const t=H(u(),T(),e);f.set(l,t[0])}}}}}}function X(e,t){t(_,function(e){const t=u(e.target);if(i(t))return F;if(!w(t.value))return F;const n=t.value,r=E(n.name,!0),c=a(`${n.tagName}:${n.type}`.toLowerCase()),s=D(n),o=[T.CHANGE,T.BLUR].includes(e.type),l=[T.CHANGE].includes(e.type),f=[T.FOCUS,T.BLUR].includes(e.type);return Object.freeze({$:a(n),name:r,tag:c,value:s,validity:a(Object.freeze(n.validity)),touched:o,modified:l,visited:f})}(e))}function K(e,t,n,r){return function(a){if(a instanceof CustomEvent)switch(a.type){case L.EMIT_FORM_VALUES:{const e=r.subscribers(),t=null,a=[...n.storage().entries()].reduce((e,[n,r])=>(e[n]=G(r,t),e),{});for(const t of e)t(a);break}}else switch(a.type){case T.SUBMIT:a.preventDefault(),async function(e,t,n){const r=new FormData(e);new Promise((a,c)=>{Promise.resolve().then(()=>{const e=[...t.entries()].reduce((e,[t,n])=>(e[t]=G(n,null),e),{});return Promise.resolve(n(Object.freeze(e),r))}).then(()=>{console.info(`[RxFormData #${e.id}] form submission handler success`),a()}).catch(t=>{console.error(`[RxFormData #${e.id}] form submission handler error(s)`,t),c(t)})})}(e,n.storage(),t);break;case T.FOCUS:case T.INPUT:case T.CHANGE:case T.BLUR:X(a,n.action);break;case T.RESET:n.action(v)}}}module.exports=function(e,c){const s=function(e){if(P(e))return a(e);if(i(E(e,!0)))return r;const t=u(document.querySelector("form#"+e.trim()));return i(t)?r:P(t.value)?a(t.value):r}(e);if(i(s))return void C("Invalid form element. Form id provided did not match any form element in the DOM.");const o=B(s)||null,l=o?function(e,t,n){const r=new Set;if(i(e))return void C("[RxFormData] invalid form element for events initialization");const a=new Map;a.set(r,new Set(r.values()));const c=()=>{const e=a.get(r);return e||new Set},s=(e,t)=>{switch(e){case A:t instanceof Function&&a.set(r,new Set(c().values()).add(t));break;case S:if(t instanceof Function){const e=new Set(c().values());e.delete(t),a.set(r,e)}break;case b:a.set(r,new Set)}},o={subscribers:c,action:s},u=e.value,l=K(u,t,n,o);return[...Object.values(T),...Object.values(L)].forEach(e=>{u.addEventListener(e,l,!0)}),{...o,cleanup:()=>{[...Object.values(T),...Object.values(L)].forEach(e=>{u.removeEventListener(e,l,!0)}),s(b),n.action(U)}}}(s,c,o):null;return o&&l?Object.freeze({ACTION_TYPE:Object.freeze(p),register:Object.freeze(e=>(o.action(I,e),Object.freeze(()=>{o.action(N,e)}))),subscribe:Object.freeze(e=>(l.action(A,e),Object.freeze(()=>{l.action(S,e)}))),dispatch:Object.freeze((r,a)=>{switch(r){case p.REGISTER_ALL:o.action(m);break;case p.REGISTER:{const e=Array.isArray(a)?a.reduce((e,r)=>t(r)||n(r)?e.concat(r):e,[]):[];e.length&&o.action(I,e);break}case p.UNREGISTER_ALL:o.action(d),!(!1!==a)&&o.action(v);break;case p.UNREGISTER:{const e=Array.isArray(a)?a.reduce((e,r)=>t(r)||n(r)?e.concat(r):e,[]):[];e.length&&o.action(N,e);break}case p.DESTROY:o.action(v),o.action(d),l.cleanup&&l.cleanup();break;default:return void console.debug(`[RxFormData: #${e}] uknown action dispatched...`,a)}})}):void 0};
"use strict";const e=e=>"string"==typeof e,t=t=>Boolean(e(t)&&t.trim().length),r=e=>"[object RegExp]"===Object.prototype.toString.call(e),n={_is:"None"};function a(e){return{_is:"Some",value:e}}function s(e){return"Some"===e._is}function c(e){return"None"===e._is}function i(e,t){return r=>c(r)?e():t(r.value)}function o(e,t,r){return c(e)&&c(t)?n:s(e)&&s(t)?r?a(r(e.value,t.value)):t:s(e)&&c(t)?e:c(e)&&s(t)?t:n}function u(e){return null===e||void 0===e?n:a(e)}function l(e){return isNaN(Number(e))?n:a(Number(e))}function E(r,s){return e(r)?s?t(r)?a(r):n:a(r):n}const f={INPUT_TEXT:"input:text",INPUT_NUMBER:"input:number",INPUT_EMAIL:"input:email",INPUT_PASSWORD:"input:password",INPUT_CHECKBOX:"input:checkbox",INPUT_RADIO:"input:radio",INPUT_COLOR:"input:color",INPUT_DATE:"input:date",INPUT_DATETIME_LOCAL:"input:datetime-local",INPUT_FILE:"input:file",INPUT_HIDDEN:"input:hidden",INPUT_MONTH:"input:month",INPUT_RANGE:"input:range",INPUT_SEARCH:"input:search",INPUT_TEL:"input:tel",INPUT_TIME:"input:time",INPUT_URL:"input:url",INPUT_WEEK:"input:week",TEXTAREA:"textarea:textarea",SELECT_SINGLE:"select:select-one",SELECT_MULTIPLE:"select:select-multiple"},m={FOCUS:"focus",INPUT:"input",CHANGE:"change",BLUR:"blur",SUBMIT:"submit",RESET:"reset"},d="REGISTER_ALL",T="UNREGISTER_ALL",I="REGISTER",R="UNREGISTER",_="UPSERT_FIELD",A="DELETE_FIELD",v="CLEAR_FIELDS",N="RESET",O="UPSERT_DECODER",U="REMOVE_DECODER",S="CLEAR_DECODERS",y={EMIT_FORM_VALUES:"EMIT_FORM_VALUES"},L="ADD",b="DELETE",p="CLEAR",D={REGISTER:"REGISTER_FIELDS",REGISTER_ALL:"REGISTER_ALL_FIELDS",UNREGISTER:"UNREGISTER_FIELDS",UNREGISTER_ALL:"UNREGISTER_ALL_FIELDS",ADD_DECODERS:"ADD_DECODERS",REMOVE_DECODERS:"REMOVE_DECODERS",CLEAR_DECODERS:"CLEAR_DECODERS",DESTROY:"DESTROY_PROGRAM"};function P(e){return e instanceof HTMLFormElement}function h(e){return e instanceof HTMLInputElement}function g(e){return e instanceof HTMLTextAreaElement}function w(e){return e instanceof HTMLSelectElement}function M(e){return h(e)||w(e)||g(e)}function C(e){return M(e)?h(e)?function(e){if(!h(e))return n;const r=`${e.tagName.toLowerCase()}:${e.type}`;switch(r){case f.INPUT_TEXT:case f.INPUT_SEARCH:case f.INPUT_EMAIL:case f.INPUT_COLOR:case f.INPUT_HIDDEN:return a(e.value.trim());case f.INPUT_PASSWORD:return a(e.value);case f.INPUT_NUMBER:case f.INPUT_RANGE:return l(Number(e.value.trim()));case f.INPUT_URL:try{return a(new URL(e.value.trim()).href.trim())}catch(t){return console.warn("[RxFormData] Failed to decode url input field value into URL object",e.value,t),n}case f.INPUT_TEL:return a(e.value.trim().replace(/\D/g,""));case f.INPUT_FILE:return i(()=>n,e=>a(Object.freeze(Array.from(Array(e.length).keys()).reduce((t,r)=>{const n=e.item(r);return n?t.concat(n):t},[]))))(u(e.files));case f.INPUT_DATE:case f.INPUT_DATETIME_LOCAL:case f.INPUT_TIME:case f.INPUT_WEEK:return l(e.valueAsNumber);case f.INPUT_MONTH:try{return a(new Date(e.value+"-1").getTime())}catch(e){return console.error("[RxFormData] Failed to decode month input field value into number",e),n}case f.INPUT_RADIO:case f.INPUT_CHECKBOX:{const s=r.split(":")[1],i=u(e.form);if(c(i))return n;const o=i.value.querySelectorAll(`input[type='${s}'][name='${e.name}']:checked`);return a(Object.freeze(Array.from(o).map((r,n)=>h(r)&&t(r.value)?r.value.trim():`${e.name}[${n}]`)))}default:return n}}(e):w(e)?function(e){if(!w(e))return n;switch(`${e.tagName.toLowerCase()}:${e.type}`){case f.SELECT_SINGLE:case f.SELECT_MULTIPLE:return a(Object.freeze(Array.from(e.selectedOptions).map((r,n)=>t(r.value)?r.value.trim():`${e.name}[${n}]`)));default:return n}}(e):g(e)?function(e){return g(e)?a(e.value.trim()):n}(e):n:n}function j(t){return!!e(t)||("number"==typeof t||!(!Array.isArray(t)||!t.every(e)&&!t.every(e=>e instanceof File)))}function F(e){return t(e)&&Object.keys(f).includes(e)}function k(n){return e(n)?t(n.trim()):r(n)}function z(e){if(e instanceof Error)throw e;const t=new Error("[RxFormData] ERROR!");throw t.details=JSON.stringify(e),t}function G(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)&&"Object"===e.constructor.name}const $=Object.freeze({$:n,tag:n,name:n,value:n,validity:a(Object.freeze({badInput:!1,customError:!1,patternMismatch:!1,rangeOverflow:!1,rangeUnderflow:!1,stepMismatch:!1,tooLong:!1,tooShort:!1,typeMismatch:!1,valid:!1,valueMissing:!1})),touched:!1,modified:!1,visited:!1});function H(e){if(!G(e))return!1;const r=Object.keys($);if(!Object.keys(e).every(e=>r.includes(e)))return!1;const n=(e,r)=>G(e)&&t(e._is)&&["none","some"].includes(e._is)&&("some"!==e._is||r(e.value));return Object.entries(e).reduce((e,[r,a])=>{switch(r){case"$":return e&&n(a,M);case"tag":return e&&n(a,F);case"name":return e&&n(a,t);case"value":return e&&n(a,j);case"validity":return e&&n(a,e=>G(e)||e instanceof ValidityState);case"touched":case"visited":case"modified":return"boolean"==typeof a;default:return!1}},!0)}function x(e,t){const r=i(()=>t,e=>e)(e.$),n=i(()=>t,e=>e)(e.tag),a=i(()=>t,e=>e)(e.name),s=i(()=>t,e=>e)(e.validity);return Object.freeze({$:r,tag:n,name:a,value:(()=>{if(n===t)return t;const r=i(()=>t,e=>e)(e.value);if(r===t)return r;switch(n){case f.INPUT_TEXT:case f.INPUT_SEARCH:case f.INPUT_EMAIL:case f.INPUT_COLOR:case f.INPUT_HIDDEN:case f.TEXTAREA:case f.INPUT_URL:case f.INPUT_TEL:case f.INPUT_PASSWORD:return String(r);case f.INPUT_NUMBER:case f.INPUT_RANGE:case f.INPUT_DATE:case f.INPUT_DATETIME_LOCAL:case f.INPUT_TIME:case f.INPUT_WEEK:case f.INPUT_MONTH:return Number(r);case f.INPUT_FILE:return Array.isArray(r)?Object.freeze(r.map(e=>Object.freeze(e))):[];case f.INPUT_RADIO:case f.INPUT_CHECKBOX:case f.SELECT_SINGLE:case f.SELECT_MULTIPLE:return Array.isArray(r)?Object.freeze(r.map(String)):[];default:return t}})(),validity:s,touched:e.touched,modified:e.modified,visited:e.visited})}function B(e){if(!G(e))return n;if(!t(e.name))return n;if(!Array.isArray(e.use))return n;if(!e.use.every(e=>e instanceof Function))return n;if(!(Array.isArray(e.messages)&&e.messages.every(t)||e.messages instanceof Function))return n;return a({name:e.name.trim(),input:[],use:e.use,messages:Array.isArray(e.messages)?()=>e.messages:e.messages})}function V(e){return s(B(e))}async function X(e,r){return new Promise(n=>{Promise.resolve().then(()=>Promise.all(e.use.map(e=>e(r)))).then(t=>t.every(e=>!0===e)?Promise.resolve([]):Promise.resolve(e.messages({inputs:r,outputs:t}))).then(r=>{Array.isArray(r)?r.length?n({decoder:e.name,success:!1,errors:r.filter(t)}):n({decoder:e.name,success:!0,errors:[]}):t(r)?n({decoder:e.name,success:!1,errors:[r]}):n({decoder:e.name,success:!1,errors:["Decoder error(s): "+JSON.stringify(r)]})}).catch(t=>{console.error("[RxFormData] An error occured while running decoder resolvers",e,t),n({decoder:e.name,success:!1,errors:["Decoder implementation error(s)"]})})})}function K(e,t){if(c(t.name))return e;const r=t.name.value,n=u(e.get(r)),a=i(()=>t,e=>{return r=e,n=t,Object.freeze({$:o(r.$,n.$),tag:o(r.tag,n.tag),name:o(r.name,n.name),value:o(r.value,n.value),validity:o(r.validity,n.validity),touched:r.touched||n.touched,modified:r.modified||n.modified,visited:r.visited||n.visited});var r,n})(n);return e.set(r,a)}function W(e,t){return e.clear(),t?new Map(t.entries()):e}function Y(e,r,n){for(let e=0,t=n.length;e<t;e++)r.delete(n[e]);for(const r of e.keys()){n.some(e=>e instanceof RegExp?e.test(r):!!t(e)&&e.trim()===r.trim())&&e.delete(r)}return[r,e]}function q(e,t){const r=new CustomEvent(y.EMIT_FORM_VALUES,{detail:Object.freeze(new Map(t.entries()))});e.dispatchEvent(r)}function J(n){const a=new Map;if(c(n))return void z("[RxFormData] invalid form element for form field storage initialization");const s=n.value,o=new Map;o.set(a,new Map(a.entries()));const u=()=>{const e=o.get(a);return e?new Map(e.entries()):new Map},l=new Set,f=(new Map).set(l,l),m=()=>{const e=f.get(l);return e?new Set(e.values()):new Set},y=new Map,L=(new Map).set(y,y),b=()=>{const e=L.get(y);return e?new Map(e.entries()):new Map};return{storage:u,decoders:b,action:(n,p)=>{switch(n){case _:if(H(p)){const e=i(()=>"",e=>e.trim())(p.name);[...m().keys()].some(n=>t(n)?n.trim()===e.trim():!!r(n)&&n.test(e))&&(o.set(a,K(u(),p)),q(s,u()))}break;case v:o.set(a,W(u())),f.set(l,new Set),L.set(y,new Map),q(s,u());break;case d:{const e=Array.from(s.elements).reduce((e,t)=>M(t)?e.concat(t.name):e,[]);f.set(l,new Set(e));break}case T:f.set(l,new Set);break;case A:{const r=Array.isArray(p)?p.filter(e=>t(e)||H(e)):[];r.length&&(o.set(a,function(r,n){return n.reduce((r,n)=>{const a=e(n)?E(n,!0):n.name;return c(a)?r:t(a.value)?(r.delete(a.value.trim()),r):r},r)}(u(),r)),q(s,u()));break}case N:o.set(a,W(u(),a)),q(s,u());break;case I:{const e=Array.isArray(p)?p.filter(e=>t(e)||r(e)):[];e.length&&f.set(l,function(e,t){for(let r=0,n=t.length;r<n;r++)e.add(t[r]);return e}(m(),e));break}case R:if(p&&G(p)){const e=Array.isArray(p.use)?p.use.filter(e=>t(e)||r(e)):[];if(e.length){const t=Y(u(),m(),e);f.set(l,t[0]),p.keepvalues||(o.set(a,t[1]),q(s,u()))}}else{const e=Array.isArray(p)?p.filter(e=>t(e)||r(e)):[];if(e.length){const t=Y(u(),m(),e);f.set(l,t[0])}}break;case O:if(Array.isArray(p)&&p.every(V)){const e=b();for(let t=0,r=p.length;t<r;t++){const r=p[t];e.set(r.name,r)}L.set(y,e)}break;case U:if(Array.isArray(p)){const e=b();for(let n=0,a=p.length;n<a;n++){const a=p[n];if(k(a))for(const[n]of e)(t(a)&&a===n||r(a)&&a.test(n))&&e.delete(n)}L.set(y,e)}break;case S:L.set(y,new Map)}}}}function Q(e,t){t(_,function(e){const t=u(e.target);if(c(t))return $;if(!M(t.value))return $;const r=t.value,n=E(r.name,!0),s=a(`${r.tagName}:${r.type}`.toLowerCase()),i=C(r),o=[m.CHANGE,m.BLUR].includes(e.type),l=[m.CHANGE].includes(e.type),f=[m.FOCUS,m.BLUR].includes(e.type);return Object.freeze({$:a(r),name:n,tag:s,value:i,validity:a(Object.freeze(r.validity)),touched:o,modified:l,visited:f})}(e))}function Z(e,t,r,n){return function(a){if(a instanceof CustomEvent)switch(a.type){case y.EMIT_FORM_VALUES:{const e=n.subscribers(),t=null,a=Object.freeze([...r.storage().entries()].reduce((e,[r,n])=>(e[r]=x(n,t),e),{}));Promise.all([...r.decoders().values()].map(e=>X(e,a))).then(t=>{const r=t.reduce((e,t)=>(e[t.decoder]=Object.freeze(t),e),{});for(const t of e)t(a,Object.freeze(r))}).catch(t=>{const r=new Error("[RxFormData] An an error occured while running decoders. Check the error details for more info.");r.details=t;for(const t of e)t(a,r)});break}}else switch(a.type){case m.SUBMIT:a.preventDefault(),async function(e,t,r,n){const a=new FormData(e);new Promise((s,c)=>{Promise.resolve().then(()=>{const e=[...t.entries()].reduce((e,[t,r])=>(e[t]=x(r,null),e),{});return Promise.all([null,e,Promise.all(Array.from(r.values()).map(t=>X(t,e)))])}).then(([e,t,r])=>{const s=r.reduce((e,t)=>Object.assign({},e,Object.freeze(t)),{});return Promise.resolve(n(Object.freeze(t),Object.freeze(s),a))}).then(()=>{console.info(`[RxFormData #${e.id}] form submission handler success`),s()}).catch(t=>{console.error(`[RxFormData #${e.id}] form submission handler error(s)`,t),c(t)})})}(e,r.storage(),r.decoders(),t);break;case m.FOCUS:case m.INPUT:case m.CHANGE:case m.BLUR:Q(a,r.action);break;case m.RESET:r.action(N)}}}module.exports=function(e,i){const o=function(e){if(P(e))return a(e);if(c(E(e,!0)))return n;const t=u(document.querySelector("form#"+e.trim()));return c(t)?n:P(t.value)?a(t.value):n}(e);if(c(o))return void z("Invalid form element. Form id provided did not match any form element in the DOM.");const l=J(o)||null,f=l?function(e,t,r){const n=new Set;if(c(e))return void z("[RxFormData] invalid form element for events initialization");const a=new Map;a.set(n,new Set(n.values()));const s=()=>{const e=a.get(n);return e||new Set},i=(e,t)=>{switch(e){case L:t instanceof Function&&a.set(n,new Set(s().values()).add(t));break;case b:if(t instanceof Function){const e=new Set(s().values());e.delete(t),a.set(n,e)}break;case p:a.set(n,new Set)}},o={subscribers:s,action:i},u=e.value,l=Z(u,t,r,o);return[...Object.values(m),...Object.values(y)].forEach(e=>{u.addEventListener(e,l,!0)}),{...o,cleanup:()=>{[...Object.values(m),...Object.values(y)].forEach(e=>{u.removeEventListener(e,l,!0)}),i(p),r.action(v)}}}(o,i,l):null;return l&&f?Object.freeze({ACTION_TYPE:Object.freeze(D),register:Object.freeze(e=>(l.action(I,e),Object.freeze(()=>{l.action(R,e)}))),subscribe:Object.freeze(e=>(f.action(L,e),Object.freeze(()=>{f.action(b,e)}))),dispatch:Object.freeze((n,a)=>{switch(n){case D.REGISTER_ALL:l.action(d);break;case D.REGISTER:{const e=Array.isArray(a)?a.reduce((e,n)=>t(n)||r(n)?e.concat(n):e,[]):[];e.length&&l.action(I,e);break}case D.UNREGISTER_ALL:l.action(T),!(!1!==a)&&l.action(N);break;case D.UNREGISTER:{const e=Array.isArray(a)?a.reduce((e,n)=>t(n)||r(n)?e.concat(n):e,[]):[];e.length&&l.action(R,e);break}case D.DESTROY:l.action(N),l.action(T),l.action(S),f.cleanup&&f.cleanup();break;case D.ADD_DECODERS:if(Array.isArray(a)){const e=a.reduce((e,t)=>{const r=B(t);return s(r)?e.concat(r.value):e},[]);e.length&&l.action(O,e)}break;case D.REMOVE_DECODERS:Array.isArray(a)&&l.action(U,a.filter(k));break;case D.CLEAR_DECODERS:l.action(S);break;default:return void console.debug(`[RxFormData: #${e}] uknown action dispatched...`,a)}})}):void 0};

@@ -1,1 +0,1 @@

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).RxFormData=t()}(this,(function(){"use strict";const e=e=>"string"==typeof e,t=t=>Boolean(e(t)&&t.trim().length),n=e=>"[object RegExp]"===Object.prototype.toString.call(e),r={_is:"None"};function a(e){return{_is:"Some",value:e}}function c(e){return"Some"===e._is}function i(e){return"None"===e._is}function s(e,t){return n=>i(n)?e():t(n.value)}function o(e,t,n){return i(e)&&i(t)?r:c(e)&&c(t)?n?a(n(e.value,t.value)):t:c(e)&&i(t)?e:i(e)&&c(t)?t:r}function u(e){return null===e||void 0===e?r:a(e)}function l(e){return isNaN(Number(e))?r:a(Number(e))}function f(n,c){return e(n)?c?t(n)?a(n):r:a(n):r}const E={INPUT_TEXT:"input:text",INPUT_NUMBER:"input:number",INPUT_EMAIL:"input:email",INPUT_PASSWORD:"input:password",INPUT_CHECKBOX:"input:checkbox",INPUT_RADIO:"input:radio",INPUT_COLOR:"input:color",INPUT_DATE:"input:date",INPUT_DATETIME_LOCAL:"input:datetime-local",INPUT_FILE:"input:file",INPUT_HIDDEN:"input:hidden",INPUT_MONTH:"input:month",INPUT_RANGE:"input:range",INPUT_SEARCH:"input:search",INPUT_TEL:"input:tel",INPUT_TIME:"input:time",INPUT_URL:"input:url",INPUT_WEEK:"input:week",TEXTAREA:"textarea:textarea",SELECT_SINGLE:"select:select-one",SELECT_MULTIPLE:"select:select-multiple"},T={FOCUS:"focus",INPUT:"input",CHANGE:"change",BLUR:"blur",SUBMIT:"submit",RESET:"reset"},d="REGISTER_ALL",m="UNREGISTER_ALL",I="REGISTER",N="UNREGISTER",_="UPSERT_FIELD",R="DELETE_FIELD",U="CLEAR_FIELDS",v="RESET",L={EMIT_FORM_VALUES:"EMIT_FORM_VALUES"},A="ADD",S="DELETE",b="CLEAR",p={REGISTER:"REGISTER_FIELDS",REGISTER_ALL:"REGISTER_ALL_FIELDS",UNREGISTER:"UNREGISTER_FIELDS",UNREGISTER_ALL:"UNREGISTER_ALL_FIELDS",DESTROY:"DESTROY_PROGRAM"};function y(e){return e instanceof HTMLFormElement}function P(e){return e instanceof HTMLInputElement}function O(e){return e instanceof HTMLTextAreaElement}function h(e){return e instanceof HTMLSelectElement}function D(e){return P(e)||h(e)||O(e)}function w(e){return D(e)?P(e)?function(e){if(!P(e))return r;const n=`${e.tagName.toLowerCase()}:${e.type}`;switch(n){case E.INPUT_TEXT:case E.INPUT_SEARCH:case E.INPUT_EMAIL:case E.INPUT_COLOR:case E.INPUT_HIDDEN:return a(e.value.trim());case E.INPUT_PASSWORD:return a(e.value);case E.INPUT_NUMBER:case E.INPUT_RANGE:return l(Number(e.value.trim()));case E.INPUT_URL:try{return a(new URL(e.value.trim()).href.trim())}catch(t){return console.warn("[RxFormData] Failed to decode url input field value into URL object",e.value,t),r}case E.INPUT_TEL:return a(e.value.trim().replace(/\D/g,""));case E.INPUT_FILE:return s(()=>r,e=>a(Object.freeze(Array.from(Array(e.length).keys()).reduce((t,n)=>{const r=e.item(n);return r?t.concat(r):t},[]))))(u(e.files));case E.INPUT_DATE:case E.INPUT_DATETIME_LOCAL:case E.INPUT_TIME:case E.INPUT_WEEK:return l(e.valueAsNumber);case E.INPUT_MONTH:try{return a(new Date(e.value+"-1").getTime())}catch(e){return console.error("[RxFormData] Failed to decode month input field value into number",e),r}case E.INPUT_RADIO:case E.INPUT_CHECKBOX:{const c=n.split(":")[1],s=u(e.form);if(i(s))return r;const o=s.value.querySelectorAll(`input[type='${c}'][name='${e.name}']:checked`);return a(Object.freeze(Array.from(o).map((n,r)=>P(n)&&t(n.value)?n.value.trim():`${e.name}[${r}]`)))}default:return r}}(e):h(e)?function(e){if(!h(e))return r;switch(`${e.tagName.toLowerCase()}:${e.type}`){case E.SELECT_SINGLE:case E.SELECT_MULTIPLE:return a(Object.freeze(Array.from(e.selectedOptions).map((n,r)=>t(n.value)?n.value.trim():`${e.name}[${r}]`)));default:return r}}(e):O(e)?function(e){return O(e)?a(e.value.trim()):r}(e):r:r}function g(t){return!!e(t)||("number"==typeof t||!(!Array.isArray(t)||!t.every(e)&&!t.every(e=>e instanceof File)))}function M(e){return t(e)&&Object.keys(E).includes(e)}function C(e){if(e instanceof Error)throw e;const t=new Error("[RxFormData] ERROR!");throw t.details=JSON.stringify(e),t}function j(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)&&"Object"===e.constructor.name}const F=Object.freeze({$:r,tag:r,name:r,value:r,validity:r,touched:!1,modified:!1,visited:!1});function k(e){if(!j(e))return!1;const n=Object.keys(F);if(!Object.keys(e).every(e=>n.includes(e)))return!1;const r=(e,n)=>j(e)&&t(e._is)&&["none","some"].includes(e._is)&&("some"!==e._is||n(e.value));return Object.entries(e).reduce((e,[n,a])=>{switch(n){case"$":return e&&r(a,D);case"tag":return e&&r(a,M);case"name":return e&&r(a,t);case"value":return e&&r(a,g);case"validity":return e&&r(a,e=>e instanceof ValidityState);case"touched":case"visited":case"modified":return"boolean"==typeof a;default:return!1}},!0)}function G(e,t){const n=s(()=>t,e=>e)(e.$),r=s(()=>t,e=>e)(e.tag),a=s(()=>t,e=>e)(e.name),c=s(()=>t,e=>e)(e.validity);return Object.freeze({$:n,tag:r,name:a,value:(()=>{if(r===t)return t;const n=s(()=>t,e=>e)(e.value);if(n===t)return n;switch(r){case E.INPUT_TEXT:case E.INPUT_SEARCH:case E.INPUT_EMAIL:case E.INPUT_COLOR:case E.INPUT_HIDDEN:case E.TEXTAREA:case E.INPUT_URL:case E.INPUT_TEL:case E.INPUT_PASSWORD:return String(n);case E.INPUT_NUMBER:case E.INPUT_RANGE:case E.INPUT_DATE:case E.INPUT_DATETIME_LOCAL:case E.INPUT_TIME:case E.INPUT_WEEK:case E.INPUT_MONTH:return Number(n);case E.INPUT_FILE:return Array.isArray(n)?Object.freeze(n.map(e=>Object.freeze(e))):[];case E.INPUT_RADIO:case E.INPUT_CHECKBOX:case E.SELECT_SINGLE:case E.SELECT_MULTIPLE:return Array.isArray(n)?Object.freeze(n.map(String)):[];default:return t}})(),validity:c,touched:e.touched,modified:e.modified,visited:e.visited})}function $(e,t){if(i(t.name))return e;const n=t.name.value,r=u(e.get(n)),a=s(()=>t,e=>{return n=e,r=t,Object.freeze({$:o(n.$,r.$),tag:o(n.tag,r.tag),name:o(n.name,r.name),value:o(n.value,r.value),validity:o(n.validity,r.validity,(e,t)=>({...e,...t})),touched:n.touched||r.touched,modified:n.modified||r.modified,visited:n.visited||r.visited});var n,r})(r);return e.set(n,a)}function z(e,t){return e.clear(),t?new Map(t.entries()):e}function H(e,n,r){for(let e=0,t=r.length;e<t;e++)n.delete(r[e]);for(const n of e.keys()){r.some(e=>e instanceof RegExp?e.test(n):!!t(e)&&e.trim()===n.trim())&&e.delete(n)}return[n,e]}function x(e,t){const n=new CustomEvent(L.EMIT_FORM_VALUES,{detail:Object.freeze(new Map(t.entries()))});e.dispatchEvent(n)}function B(r){const a=new Map;if(i(r))return void C("[RxFormData] invalid form element for form field storage initialization");const c=r.value,o=new Map;o.set(a,new Map(a.entries()));const u=()=>{const e=o.get(a);return e?new Map(e.entries()):new Map},l=new Set,E=(new Map).set(l,l),T=()=>{const e=E.get(l);return e?new Set(e.values()):new Set};return{storage:u,action:(r,L)=>{switch(r){case _:if(k(L)){const e=s(()=>"",e=>e.trim())(L.name);[...T().keys()].some(r=>t(r)?r.trim()===e.trim():!!n(r)&&r.test(e))&&(o.set(a,$(u(),L)),x(c,u()))}break;case U:o.set(a,z(u())),E.set(l,new Set),x(c,u());break;case d:{const e=Array.from(c.elements).reduce((e,t)=>D(t)?e.concat(t.name):e,[]);E.set(l,new Set(e));break}case m:E.set(l,new Set);break;case R:{const n=Array.isArray(L)?L.filter(e=>t(e)||k(e)):[];n.length&&(o.set(a,function(n,r){return r.reduce((n,r)=>{const a=e(r)?f(r,!0):r.name;return i(a)?n:t(a.value)?(n.delete(a.value.trim()),n):n},n)}(u(),n)),x(c,u()));break}case v:o.set(a,z(u(),a)),x(c,u());break;case I:{const e=Array.isArray(L)?L.filter(e=>t(e)||n(e)):[];e.length&&E.set(l,function(e,t){for(let n=0,r=t.length;n<r;n++)e.add(t[n]);return e}(T(),e));break}case N:if(L&&j(L)){const e=Array.isArray(L.use)?L.use.filter(e=>t(e)||n(e)):[];if(e.length){const t=H(u(),T(),e);E.set(l,t[0]),L.keepvalues||(o.set(a,t[1]),x(c,u()))}}else{const e=Array.isArray(L)?L.filter(e=>t(e)||n(e)):[];if(e.length){const t=H(u(),T(),e);E.set(l,t[0])}}}}}}function X(e,t){t(_,function(e){const t=u(e.target);if(i(t))return F;if(!D(t.value))return F;const n=t.value,r=f(n.name,!0),c=a(`${n.tagName}:${n.type}`.toLowerCase()),s=w(n),o=[T.CHANGE,T.BLUR].includes(e.type),l=[T.CHANGE].includes(e.type),E=[T.FOCUS,T.BLUR].includes(e.type);return Object.freeze({$:a(n),name:r,tag:c,value:s,validity:a(Object.freeze(n.validity)),touched:o,modified:l,visited:E})}(e))}function K(e,t,n,r){return function(a){if(a instanceof CustomEvent)switch(a.type){case L.EMIT_FORM_VALUES:{const e=r.subscribers(),t=null,a=[...n.storage().entries()].reduce((e,[n,r])=>(e[n]=G(r,t),e),{});for(const t of e)t(a);break}}else switch(a.type){case T.SUBMIT:a.preventDefault(),async function(e,t,n){const r=new FormData(e);new Promise((a,c)=>{Promise.resolve().then(()=>{const e=[...t.entries()].reduce((e,[t,n])=>(e[t]=G(n,null),e),{});return Promise.resolve(n(Object.freeze(e),r))}).then(()=>{console.info(`[RxFormData #${e.id}] form submission handler success`),a()}).catch(t=>{console.error(`[RxFormData #${e.id}] form submission handler error(s)`,t),c(t)})})}(e,n.storage(),t);break;case T.FOCUS:case T.INPUT:case T.CHANGE:case T.BLUR:X(a,n.action);break;case T.RESET:n.action(v)}}}return function(e,c){const s=function(e){if(y(e))return a(e);if(i(f(e,!0)))return r;const t=u(document.querySelector("form#"+e.trim()));return i(t)?r:y(t.value)?a(t.value):r}(e);if(i(s))return void C("Invalid form element. Form id provided did not match any form element in the DOM.");const o=B(s)||null,l=o?function(e,t,n){const r=new Set;if(i(e))return void C("[RxFormData] invalid form element for events initialization");const a=new Map;a.set(r,new Set(r.values()));const c=()=>{const e=a.get(r);return e||new Set},s=(e,t)=>{switch(e){case A:t instanceof Function&&a.set(r,new Set(c().values()).add(t));break;case S:if(t instanceof Function){const e=new Set(c().values());e.delete(t),a.set(r,e)}break;case b:a.set(r,new Set)}},o={subscribers:c,action:s},u=e.value,l=K(u,t,n,o);return[...Object.values(T),...Object.values(L)].forEach(e=>{u.addEventListener(e,l,!0)}),{...o,cleanup:()=>{[...Object.values(T),...Object.values(L)].forEach(e=>{u.removeEventListener(e,l,!0)}),s(b),n.action(U)}}}(s,c,o):null;return o&&l?Object.freeze({ACTION_TYPE:Object.freeze(p),register:Object.freeze(e=>(o.action(I,e),Object.freeze(()=>{o.action(N,e)}))),subscribe:Object.freeze(e=>(l.action(A,e),Object.freeze(()=>{l.action(S,e)}))),dispatch:Object.freeze((r,a)=>{switch(r){case p.REGISTER_ALL:o.action(d);break;case p.REGISTER:{const e=Array.isArray(a)?a.reduce((e,r)=>t(r)||n(r)?e.concat(r):e,[]):[];e.length&&o.action(I,e);break}case p.UNREGISTER_ALL:o.action(m),!(!1!==a)&&o.action(v);break;case p.UNREGISTER:{const e=Array.isArray(a)?a.reduce((e,r)=>t(r)||n(r)?e.concat(r):e,[]):[];e.length&&o.action(N,e);break}case p.DESTROY:o.action(v),o.action(m),l.cleanup&&l.cleanup();break;default:return void console.debug(`[RxFormData: #${e}] uknown action dispatched...`,a)}})}):void 0}}));
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).RxFormData=t()}(this,(function(){"use strict";const e=e=>"string"==typeof e,t=t=>Boolean(e(t)&&t.trim().length),r=e=>"[object RegExp]"===Object.prototype.toString.call(e),n={_is:"None"};function a(e){return{_is:"Some",value:e}}function s(e){return"Some"===e._is}function c(e){return"None"===e._is}function i(e,t){return r=>c(r)?e():t(r.value)}function o(e,t,r){return c(e)&&c(t)?n:s(e)&&s(t)?r?a(r(e.value,t.value)):t:s(e)&&c(t)?e:c(e)&&s(t)?t:n}function u(e){return null===e||void 0===e?n:a(e)}function l(e){return isNaN(Number(e))?n:a(Number(e))}function E(r,s){return e(r)?s?t(r)?a(r):n:a(r):n}const f={INPUT_TEXT:"input:text",INPUT_NUMBER:"input:number",INPUT_EMAIL:"input:email",INPUT_PASSWORD:"input:password",INPUT_CHECKBOX:"input:checkbox",INPUT_RADIO:"input:radio",INPUT_COLOR:"input:color",INPUT_DATE:"input:date",INPUT_DATETIME_LOCAL:"input:datetime-local",INPUT_FILE:"input:file",INPUT_HIDDEN:"input:hidden",INPUT_MONTH:"input:month",INPUT_RANGE:"input:range",INPUT_SEARCH:"input:search",INPUT_TEL:"input:tel",INPUT_TIME:"input:time",INPUT_URL:"input:url",INPUT_WEEK:"input:week",TEXTAREA:"textarea:textarea",SELECT_SINGLE:"select:select-one",SELECT_MULTIPLE:"select:select-multiple"},m={FOCUS:"focus",INPUT:"input",CHANGE:"change",BLUR:"blur",SUBMIT:"submit",RESET:"reset"},d="REGISTER_ALL",T="UNREGISTER_ALL",I="REGISTER",R="UNREGISTER",_="UPSERT_FIELD",A="DELETE_FIELD",v="CLEAR_FIELDS",N="RESET",y="UPSERT_DECODER",O="REMOVE_DECODER",U="CLEAR_DECODERS",S={EMIT_FORM_VALUES:"EMIT_FORM_VALUES"},p="ADD",L="DELETE",b="CLEAR",D={REGISTER:"REGISTER_FIELDS",REGISTER_ALL:"REGISTER_ALL_FIELDS",UNREGISTER:"UNREGISTER_FIELDS",UNREGISTER_ALL:"UNREGISTER_ALL_FIELDS",ADD_DECODERS:"ADD_DECODERS",REMOVE_DECODERS:"REMOVE_DECODERS",CLEAR_DECODERS:"CLEAR_DECODERS",DESTROY:"DESTROY_PROGRAM"};function P(e){return e instanceof HTMLFormElement}function h(e){return e instanceof HTMLInputElement}function g(e){return e instanceof HTMLTextAreaElement}function w(e){return e instanceof HTMLSelectElement}function M(e){return h(e)||w(e)||g(e)}function C(e){return M(e)?h(e)?function(e){if(!h(e))return n;const r=`${e.tagName.toLowerCase()}:${e.type}`;switch(r){case f.INPUT_TEXT:case f.INPUT_SEARCH:case f.INPUT_EMAIL:case f.INPUT_COLOR:case f.INPUT_HIDDEN:return a(e.value.trim());case f.INPUT_PASSWORD:return a(e.value);case f.INPUT_NUMBER:case f.INPUT_RANGE:return l(Number(e.value.trim()));case f.INPUT_URL:try{return a(new URL(e.value.trim()).href.trim())}catch(t){return console.warn("[RxFormData] Failed to decode url input field value into URL object",e.value,t),n}case f.INPUT_TEL:return a(e.value.trim().replace(/\D/g,""));case f.INPUT_FILE:return i(()=>n,e=>a(Object.freeze(Array.from(Array(e.length).keys()).reduce((t,r)=>{const n=e.item(r);return n?t.concat(n):t},[]))))(u(e.files));case f.INPUT_DATE:case f.INPUT_DATETIME_LOCAL:case f.INPUT_TIME:case f.INPUT_WEEK:return l(e.valueAsNumber);case f.INPUT_MONTH:try{return a(new Date(e.value+"-1").getTime())}catch(e){return console.error("[RxFormData] Failed to decode month input field value into number",e),n}case f.INPUT_RADIO:case f.INPUT_CHECKBOX:{const s=r.split(":")[1],i=u(e.form);if(c(i))return n;const o=i.value.querySelectorAll(`input[type='${s}'][name='${e.name}']:checked`);return a(Object.freeze(Array.from(o).map((r,n)=>h(r)&&t(r.value)?r.value.trim():`${e.name}[${n}]`)))}default:return n}}(e):w(e)?function(e){if(!w(e))return n;switch(`${e.tagName.toLowerCase()}:${e.type}`){case f.SELECT_SINGLE:case f.SELECT_MULTIPLE:return a(Object.freeze(Array.from(e.selectedOptions).map((r,n)=>t(r.value)?r.value.trim():`${e.name}[${n}]`)));default:return n}}(e):g(e)?function(e){return g(e)?a(e.value.trim()):n}(e):n:n}function j(t){return!!e(t)||("number"==typeof t||!(!Array.isArray(t)||!t.every(e)&&!t.every(e=>e instanceof File)))}function F(e){return t(e)&&Object.keys(f).includes(e)}function k(n){return e(n)?t(n.trim()):r(n)}function z(e){if(e instanceof Error)throw e;const t=new Error("[RxFormData] ERROR!");throw t.details=JSON.stringify(e),t}function G(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)&&"Object"===e.constructor.name}const $=Object.freeze({$:n,tag:n,name:n,value:n,validity:a(Object.freeze({badInput:!1,customError:!1,patternMismatch:!1,rangeOverflow:!1,rangeUnderflow:!1,stepMismatch:!1,tooLong:!1,tooShort:!1,typeMismatch:!1,valid:!1,valueMissing:!1})),touched:!1,modified:!1,visited:!1});function x(e){if(!G(e))return!1;const r=Object.keys($);if(!Object.keys(e).every(e=>r.includes(e)))return!1;const n=(e,r)=>G(e)&&t(e._is)&&["none","some"].includes(e._is)&&("some"!==e._is||r(e.value));return Object.entries(e).reduce((e,[r,a])=>{switch(r){case"$":return e&&n(a,M);case"tag":return e&&n(a,F);case"name":return e&&n(a,t);case"value":return e&&n(a,j);case"validity":return e&&n(a,e=>G(e)||e instanceof ValidityState);case"touched":case"visited":case"modified":return"boolean"==typeof a;default:return!1}},!0)}function H(e,t){const r=i(()=>t,e=>e)(e.$),n=i(()=>t,e=>e)(e.tag),a=i(()=>t,e=>e)(e.name),s=i(()=>t,e=>e)(e.validity);return Object.freeze({$:r,tag:n,name:a,value:(()=>{if(n===t)return t;const r=i(()=>t,e=>e)(e.value);if(r===t)return r;switch(n){case f.INPUT_TEXT:case f.INPUT_SEARCH:case f.INPUT_EMAIL:case f.INPUT_COLOR:case f.INPUT_HIDDEN:case f.TEXTAREA:case f.INPUT_URL:case f.INPUT_TEL:case f.INPUT_PASSWORD:return String(r);case f.INPUT_NUMBER:case f.INPUT_RANGE:case f.INPUT_DATE:case f.INPUT_DATETIME_LOCAL:case f.INPUT_TIME:case f.INPUT_WEEK:case f.INPUT_MONTH:return Number(r);case f.INPUT_FILE:return Array.isArray(r)?Object.freeze(r.map(e=>Object.freeze(e))):[];case f.INPUT_RADIO:case f.INPUT_CHECKBOX:case f.SELECT_SINGLE:case f.SELECT_MULTIPLE:return Array.isArray(r)?Object.freeze(r.map(String)):[];default:return t}})(),validity:s,touched:e.touched,modified:e.modified,visited:e.visited})}function B(e){if(!G(e))return n;if(!t(e.name))return n;if(!Array.isArray(e.use))return n;if(!e.use.every(e=>e instanceof Function))return n;if(!(Array.isArray(e.messages)&&e.messages.every(t)||e.messages instanceof Function))return n;return a({name:e.name.trim(),input:[],use:e.use,messages:Array.isArray(e.messages)?()=>e.messages:e.messages})}function V(e){return s(B(e))}async function X(e,r){return new Promise(n=>{Promise.resolve().then(()=>Promise.all(e.use.map(e=>e(r)))).then(t=>t.every(e=>!0===e)?Promise.resolve([]):Promise.resolve(e.messages({inputs:r,outputs:t}))).then(r=>{Array.isArray(r)?r.length?n({decoder:e.name,success:!1,errors:r.filter(t)}):n({decoder:e.name,success:!0,errors:[]}):t(r)?n({decoder:e.name,success:!1,errors:[r]}):n({decoder:e.name,success:!1,errors:["Decoder error(s): "+JSON.stringify(r)]})}).catch(t=>{console.error("[RxFormData] An error occured while running decoder resolvers",e,t),n({decoder:e.name,success:!1,errors:["Decoder implementation error(s)"]})})})}function K(e,t){if(c(t.name))return e;const r=t.name.value,n=u(e.get(r)),a=i(()=>t,e=>{return r=e,n=t,Object.freeze({$:o(r.$,n.$),tag:o(r.tag,n.tag),name:o(r.name,n.name),value:o(r.value,n.value),validity:o(r.validity,n.validity),touched:r.touched||n.touched,modified:r.modified||n.modified,visited:r.visited||n.visited});var r,n})(n);return e.set(r,a)}function W(e,t){return e.clear(),t?new Map(t.entries()):e}function Y(e,r,n){for(let e=0,t=n.length;e<t;e++)r.delete(n[e]);for(const r of e.keys()){n.some(e=>e instanceof RegExp?e.test(r):!!t(e)&&e.trim()===r.trim())&&e.delete(r)}return[r,e]}function q(e,t){const r=new CustomEvent(S.EMIT_FORM_VALUES,{detail:Object.freeze(new Map(t.entries()))});e.dispatchEvent(r)}function J(n){const a=new Map;if(c(n))return void z("[RxFormData] invalid form element for form field storage initialization");const s=n.value,o=new Map;o.set(a,new Map(a.entries()));const u=()=>{const e=o.get(a);return e?new Map(e.entries()):new Map},l=new Set,f=(new Map).set(l,l),m=()=>{const e=f.get(l);return e?new Set(e.values()):new Set},S=new Map,p=(new Map).set(S,S),L=()=>{const e=p.get(S);return e?new Map(e.entries()):new Map};return{storage:u,decoders:L,action:(n,b)=>{switch(n){case _:if(x(b)){const e=i(()=>"",e=>e.trim())(b.name);[...m().keys()].some(n=>t(n)?n.trim()===e.trim():!!r(n)&&n.test(e))&&(o.set(a,K(u(),b)),q(s,u()))}break;case v:o.set(a,W(u())),f.set(l,new Set),p.set(S,new Map),q(s,u());break;case d:{const e=Array.from(s.elements).reduce((e,t)=>M(t)?e.concat(t.name):e,[]);f.set(l,new Set(e));break}case T:f.set(l,new Set);break;case A:{const r=Array.isArray(b)?b.filter(e=>t(e)||x(e)):[];r.length&&(o.set(a,function(r,n){return n.reduce((r,n)=>{const a=e(n)?E(n,!0):n.name;return c(a)?r:t(a.value)?(r.delete(a.value.trim()),r):r},r)}(u(),r)),q(s,u()));break}case N:o.set(a,W(u(),a)),q(s,u());break;case I:{const e=Array.isArray(b)?b.filter(e=>t(e)||r(e)):[];e.length&&f.set(l,function(e,t){for(let r=0,n=t.length;r<n;r++)e.add(t[r]);return e}(m(),e));break}case R:if(b&&G(b)){const e=Array.isArray(b.use)?b.use.filter(e=>t(e)||r(e)):[];if(e.length){const t=Y(u(),m(),e);f.set(l,t[0]),b.keepvalues||(o.set(a,t[1]),q(s,u()))}}else{const e=Array.isArray(b)?b.filter(e=>t(e)||r(e)):[];if(e.length){const t=Y(u(),m(),e);f.set(l,t[0])}}break;case y:if(Array.isArray(b)&&b.every(V)){const e=L();for(let t=0,r=b.length;t<r;t++){const r=b[t];e.set(r.name,r)}p.set(S,e)}break;case O:if(Array.isArray(b)){const e=L();for(let n=0,a=b.length;n<a;n++){const a=b[n];if(k(a))for(const[n]of e)(t(a)&&a===n||r(a)&&a.test(n))&&e.delete(n)}p.set(S,e)}break;case U:p.set(S,new Map)}}}}function Q(e,t){t(_,function(e){const t=u(e.target);if(c(t))return $;if(!M(t.value))return $;const r=t.value,n=E(r.name,!0),s=a(`${r.tagName}:${r.type}`.toLowerCase()),i=C(r),o=[m.CHANGE,m.BLUR].includes(e.type),l=[m.CHANGE].includes(e.type),f=[m.FOCUS,m.BLUR].includes(e.type);return Object.freeze({$:a(r),name:n,tag:s,value:i,validity:a(Object.freeze(r.validity)),touched:o,modified:l,visited:f})}(e))}function Z(e,t,r,n){return function(a){if(a instanceof CustomEvent)switch(a.type){case S.EMIT_FORM_VALUES:{const e=n.subscribers(),t=null,a=Object.freeze([...r.storage().entries()].reduce((e,[r,n])=>(e[r]=H(n,t),e),{}));Promise.all([...r.decoders().values()].map(e=>X(e,a))).then(t=>{const r=t.reduce((e,t)=>(e[t.decoder]=Object.freeze(t),e),{});for(const t of e)t(a,Object.freeze(r))}).catch(t=>{const r=new Error("[RxFormData] An an error occured while running decoders. Check the error details for more info.");r.details=t;for(const t of e)t(a,r)});break}}else switch(a.type){case m.SUBMIT:a.preventDefault(),async function(e,t,r,n){const a=new FormData(e);new Promise((s,c)=>{Promise.resolve().then(()=>{const e=[...t.entries()].reduce((e,[t,r])=>(e[t]=H(r,null),e),{});return Promise.all([null,e,Promise.all(Array.from(r.values()).map(t=>X(t,e)))])}).then(([e,t,r])=>{const s=r.reduce((e,t)=>Object.assign({},e,Object.freeze(t)),{});return Promise.resolve(n(Object.freeze(t),Object.freeze(s),a))}).then(()=>{console.info(`[RxFormData #${e.id}] form submission handler success`),s()}).catch(t=>{console.error(`[RxFormData #${e.id}] form submission handler error(s)`,t),c(t)})})}(e,r.storage(),r.decoders(),t);break;case m.FOCUS:case m.INPUT:case m.CHANGE:case m.BLUR:Q(a,r.action);break;case m.RESET:r.action(N)}}}return function(e,i){const o=function(e){if(P(e))return a(e);if(c(E(e,!0)))return n;const t=u(document.querySelector("form#"+e.trim()));return c(t)?n:P(t.value)?a(t.value):n}(e);if(c(o))return void z("Invalid form element. Form id provided did not match any form element in the DOM.");const l=J(o)||null,f=l?function(e,t,r){const n=new Set;if(c(e))return void z("[RxFormData] invalid form element for events initialization");const a=new Map;a.set(n,new Set(n.values()));const s=()=>{const e=a.get(n);return e||new Set},i=(e,t)=>{switch(e){case p:t instanceof Function&&a.set(n,new Set(s().values()).add(t));break;case L:if(t instanceof Function){const e=new Set(s().values());e.delete(t),a.set(n,e)}break;case b:a.set(n,new Set)}},o={subscribers:s,action:i},u=e.value,l=Z(u,t,r,o);return[...Object.values(m),...Object.values(S)].forEach(e=>{u.addEventListener(e,l,!0)}),{...o,cleanup:()=>{[...Object.values(m),...Object.values(S)].forEach(e=>{u.removeEventListener(e,l,!0)}),i(b),r.action(v)}}}(o,i,l):null;return l&&f?Object.freeze({ACTION_TYPE:Object.freeze(D),register:Object.freeze(e=>(l.action(I,e),Object.freeze(()=>{l.action(R,e)}))),subscribe:Object.freeze(e=>(f.action(p,e),Object.freeze(()=>{f.action(L,e)}))),dispatch:Object.freeze((n,a)=>{switch(n){case D.REGISTER_ALL:l.action(d);break;case D.REGISTER:{const e=Array.isArray(a)?a.reduce((e,n)=>t(n)||r(n)?e.concat(n):e,[]):[];e.length&&l.action(I,e);break}case D.UNREGISTER_ALL:l.action(T),!(!1!==a)&&l.action(N);break;case D.UNREGISTER:{const e=Array.isArray(a)?a.reduce((e,n)=>t(n)||r(n)?e.concat(n):e,[]):[];e.length&&l.action(R,e);break}case D.DESTROY:l.action(N),l.action(T),l.action(U),f.cleanup&&f.cleanup();break;case D.ADD_DECODERS:if(Array.isArray(a)){const e=a.reduce((e,t)=>{const r=B(t);return s(r)?e.concat(r.value):e},[]);e.length&&l.action(y,e)}break;case D.REMOVE_DECODERS:Array.isArray(a)&&l.action(O,a.filter(k));break;case D.CLEAR_DECODERS:l.action(U);break;default:return void console.debug(`[RxFormData: #${e}] uknown action dispatched...`,a)}})}):void 0}}));

@@ -41,2 +41,5 @@ export declare const HTML_FORM_FIELD_TAG: {

readonly RESET: "RESET";
readonly UPSERT_DECODER: "UPSERT_DECODER";
readonly REMOVE_DECODER: "REMOVE_DECODER";
readonly CLEAR_DECODERS: "CLEAR_DECODERS";
};

@@ -56,3 +59,6 @@ export declare const HTML_FORM_CUSTOM_EVENT_TYPE: {

readonly UNREGISTER_ALL: "UNREGISTER_ALL_FIELDS";
readonly ADD_DECODERS: "ADD_DECODERS";
readonly REMOVE_DECODERS: "REMOVE_DECODERS";
readonly CLEAR_DECODERS: "CLEAR_DECODERS";
readonly DESTROY: "DESTROY_PROGRAM";
};
import { HTML_FORM_FIELD_TAG, HTML_FORM_NATIVE_EVENT_TYPE, FORM_FIELD_STORAGE_ACTION_TYPE, HTML_FORM_CUSTOM_EVENT_TYPE, FORM_FIELDS_SUBSCRIBERS_ACTION_TYPE, PROGRAM_INTERFACE_ACTION_TYPE } from "../constants";
import { FormField, SerializedFormField } from "./Field";
import { FormFieldStorage, FormFieldSelectorExpression } from "../repository";
import { FormFieldStorage, FormDecoders } from "../repository";
import { DecoderResult, Decoder } from "./Decoder";
export declare type Predicate<T> = (x: T) => boolean;
export declare type SubmissionHandlerConfigOption = <T, U = never>(formvalues: Readonly<Record<string, SerializedFormField<U>>>, formdata: FormData) => T;
export declare type FormFieldStorageActionFn = (type: FormFieldStorageActionType, payload?: FormField | Array<string | FormField> | FormFieldSelectorExpression[]) => void;
export declare type SubmissionHandlerConfigOption = <T, U = never>(formvalues: Readonly<Record<string, SerializedFormField<U>>>, formvalidation: Error | Readonly<Record<string, Readonly<DecoderResult>>>, formdata: FormData) => T;
export declare type FormFieldStorageActionFn = (type: FormFieldStorageActionType, payload?: FormFieldSelectorExpression | FormField | Array<string | FormField> | FormFieldSelectorExpression[] | {
use: FormFieldSelectorExpression[];
keepvalues: boolean;
} | Decoder[]) => void;
export declare type FormFieldStorageInterface = Readonly<{
storage: () => FormFieldStorage;
decoders: () => FormDecoders;
action: FormFieldStorageActionFn;

@@ -18,5 +23,6 @@ cleanup?: () => void;

}>;
export declare type FormFieldSubscriber = <T>(formvalues: Readonly<Record<string, SerializedFormField<T>>>) => void;
export declare type FormFieldSubscriber = <T>(formvalues: Readonly<Record<string, SerializedFormField<T>>>, formvalidation: Error | Readonly<Record<string, Readonly<DecoderResult>>>) => void;
export declare type HTMLFormFieldElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
export declare type HTMLFormFieldValue = string | number | ReadonlyArray<string> | ReadonlyArray<File>;
export declare type FormFieldSelectorExpression = string | RegExp;
export declare type HTMLFormFieldTag = typeof HTML_FORM_FIELD_TAG[keyof typeof HTML_FORM_FIELD_TAG];

@@ -23,0 +29,0 @@ export declare type HTMLFormNativeEventType = typeof HTML_FORM_NATIVE_EVENT_TYPE[keyof typeof HTML_FORM_NATIVE_EVENT_TYPE];

@@ -1,8 +0,9 @@

import { FormFieldStorage } from "./repository";
import { FormFieldStorage, FormDecoders } from "./repository";
import { FormField, SerializedFormField } from "./datatypes/Field";
import { FormFieldStorageActionFn, FormFieldStorageInterface, FormEventsInterface, SubmissionHandlerConfigOption } from "./datatypes/base";
import { Option } from "./datatypes/Option";
export declare function onsubmit<T>($form: HTMLFormElement, storage: FormFieldStorage, handler: <K extends T, U>(formvalues: Readonly<Record<string, SerializedFormField<U>>>, formdata: FormData) => K): Promise<T>;
import { DecoderResult } from "./datatypes/Decoder";
export declare function onsubmit<T>($form: HTMLFormElement, storage: FormFieldStorage, decoders: FormDecoders, handler: <K extends T, U>(formvalues: Readonly<Record<string, SerializedFormField<U>>>, formvalidation: Error | Readonly<Record<string, Readonly<DecoderResult>>>, formdata: FormData) => K): Promise<T>;
export declare function onfieldevent(evt: Event, action: FormFieldStorageActionFn): void;
export declare function getFormEventListener($target: HTMLFormElement, submissionHanlder: SubmissionHandlerConfigOption, storageinterface: FormFieldStorageInterface, subscribersinterface: FormEventsInterface): (evt: Event | CustomEvent<Readonly<Map<string, FormField>>>) => void;
export declare function initialize($formElement: Option<HTMLFormElement>, submissionHanlder: SubmissionHandlerConfigOption, storageinterface: FormFieldStorageInterface): FormEventsInterface | void;
import { Option } from "../datatypes/Option";
import { HTMLFormFieldElement, HTMLFormFieldValue, HTMLFormFieldTag } from "../datatypes/base";
import { HTMLFormFieldElement, HTMLFormFieldValue, HTMLFormFieldTag, FormFieldSelectorExpression } from "../datatypes/base";
export declare function isFormElement(x: unknown): x is HTMLFormElement;

@@ -17,1 +17,2 @@ export declare function isInputFieldElement(x: unknown): x is HTMLInputElement;

export declare function isFormFieldInternalTag(x: unknown): x is HTMLFormFieldTag;
export declare function isFormFieldSelectorExpression(x: unknown): x is FormFieldSelectorExpression;
import { FormField } from "./datatypes/Field";
import { Option } from "./datatypes/Option";
import { FormFieldStorageInterface } from "./datatypes/base";
import { FormFieldStorageInterface, FormFieldSelectorExpression } from "./datatypes/base";
import { Decoder } from "./datatypes/Decoder";
export declare type FormFieldStorage = Map<string, FormField>;
export declare type FormFieldSelectorExpression = string | RegExp;
export declare type FormFieldRegister = Set<FormFieldSelectorExpression>;
export declare type FormDecoders = Map<string, Decoder>;
export declare function put(storage: FormFieldStorage, msg: FormField): FormFieldStorage;

@@ -8,0 +9,0 @@ export declare function remove(storage: FormFieldStorage, selection: Array<string | FormField>): FormFieldStorage;

{
"name": "@metronlabs/rx-form-data",
"version": "0.0.6",
"version": "0.0.7",
"description": "Framework agnostic reactive form data streaming",

@@ -35,6 +35,7 @@ "keywords": [

"lint": "eslint --ext .js,.ts src/* --fix && prettier --write \"src/**/*.{js,ts}\"",
"clean": "rimraf lib/*",
"clean": "rimraf lib/* && rimraf examples/dist/*",
"prebuild": "npm run lint && npm run clean",
"build": "rollup -c rollup.config.ts && ./node_modules/.bin/ttsc -p ./tsconfig.types.json",
"prepare": "npm run build"
"prepare": "npm run build",
"postbuild": "cp lib/index.umd.js examples/dist"
},

@@ -41,0 +42,0 @@ "devDependencies": {

@@ -42,3 +42,6 @@ export const HTML_FORM_FIELD_TAG = {

CLEAR: "CLEAR_FIELDS",
RESET: "RESET"
RESET: "RESET",
UPSERT_DECODER: "UPSERT_DECODER",
REMOVE_DECODER: "REMOVE_DECODER",
CLEAR_DECODERS: "CLEAR_DECODERS"
} as const;

@@ -61,3 +64,6 @@

UNREGISTER_ALL: "UNREGISTER_ALL_FIELDS",
ADD_DECODERS: "ADD_DECODERS",
REMOVE_DECODERS: "REMOVE_DECODERS",
CLEAR_DECODERS: "CLEAR_DECODERS",
DESTROY: "DESTROY_PROGRAM"
} as const;

@@ -10,3 +10,4 @@ import {

import { FormField, SerializedFormField } from "@datatypes/Field";
import { FormFieldStorage, FormFieldSelectorExpression } from "@/repository";
import { FormFieldStorage, FormDecoders } from "@/repository";
import { DecoderResult, Decoder } from "@datatypes/Decoder";

@@ -16,2 +17,3 @@ export type Predicate<T> = (x: T) => boolean;

formvalues: Readonly<Record<string, SerializedFormField<U>>>,
formvalidation: Error | Readonly<Record<string, Readonly<DecoderResult>>>,
formdata: FormData

@@ -22,5 +24,8 @@ ) => T;

payload?:
| FormFieldSelectorExpression
| FormField
| Array<string | FormField>
| FormFieldSelectorExpression[]
| { use: FormFieldSelectorExpression[]; keepvalues: boolean }
| Decoder[]
) => void;

@@ -30,2 +35,3 @@

storage: () => FormFieldStorage;
decoders: () => FormDecoders;
action: FormFieldStorageActionFn;

@@ -47,3 +53,4 @@ cleanup?: () => void;

export type FormFieldSubscriber = <T>(
formvalues: Readonly<Record<string, SerializedFormField<T>>>
formvalues: Readonly<Record<string, SerializedFormField<T>>>,
formvalidation: Error | Readonly<Record<string, Readonly<DecoderResult>>>
) => void;

@@ -62,2 +69,4 @@

export type FormFieldSelectorExpression = string | RegExp;
export type HTMLFormFieldTag = typeof HTML_FORM_FIELD_TAG[keyof typeof HTML_FORM_FIELD_TAG];

@@ -64,0 +73,0 @@ export type HTMLFormNativeEventType = typeof HTML_FORM_NATIVE_EVENT_TYPE[keyof typeof HTML_FORM_NATIVE_EVENT_TYPE];

@@ -58,3 +58,17 @@ import {

value: none as Option<HTMLFormFieldValue>,
validity: none as Option<Readonly<ValidityState>>,
validity: some(
Object.freeze({
badInput: false,
customError: false,
patternMismatch: false,
rangeOverflow: false,
rangeUnderflow: false,
stepMismatch: false,
tooLong: false,
tooShort: false,
typeMismatch: false,
valid: false,
valueMissing: false
})
),
touched: false,

@@ -117,3 +131,4 @@ modified: false,

value,
(u: unknown) => u instanceof ValidityState
//TODO: make a proper predicate for the validity datatype
(u: unknown) => isPlainObject(u) || u instanceof ValidityState
)

@@ -139,7 +154,2 @@ );

export function concat(x: FormField, y: FormField): FormField {
const concatValidity = (
a: Readonly<ValidityState>,
b: Readonly<ValidityState>
): Readonly<ValidityState> => ({ ...a, ...b });
return Object.freeze({

@@ -150,3 +160,3 @@ $: optionconcat(x.$, y.$),

value: optionconcat(x.value, y.value),
validity: optionconcat(x.validity, y.validity, concatValidity),
validity: optionconcat(x.validity, y.validity),
touched: x.touched || y.touched,

@@ -153,0 +163,0 @@ modified: x.modified || y.modified,

@@ -1,2 +0,2 @@

import { FormFieldStorage } from "@/repository";
import { FormFieldStorage, FormDecoders } from "@/repository";
import {

@@ -26,7 +26,11 @@ FormField,

import { run as runDecoder, DecoderResult } from "@datatypes/Decoder";
export async function onsubmit<T>(
$form: HTMLFormElement,
storage: FormFieldStorage,
decoders: FormDecoders,
handler: <K extends T, U>(
formvalues: Readonly<Record<string, SerializedFormField<U>>>,
formvalidation: Error | Readonly<Record<string, Readonly<DecoderResult>>>,
formdata: FormData

@@ -51,4 +55,27 @@ ) => K

);
return Promise.all([
nilvalue,
formvalues,
Promise.all(
Array.from(decoders.values()).map((decoder) =>
runDecoder(decoder, formvalues)
)
)
]);
})
.then(([nil, formvalues, decoderResults]) => {
const validation = decoderResults.reduce(
(collection: Record<string, Readonly<DecoderResult>>, result) => {
return Object.assign({}, collection, Object.freeze(result));
},
{} as Record<string, Readonly<DecoderResult>>
);
return Promise.resolve(
handler<T, typeof nilvalue>(Object.freeze(formvalues), formdata)
handler<T, typeof nil>(
Object.freeze(formvalues),
Object.freeze(validation),
formdata
)
);

@@ -93,16 +120,48 @@ })

const nilvalue = null;
const formvalues = [...storageinterface.storage().entries()].reduce(
(
values: Record<string, SerializedFormField<typeof nilvalue>>,
[fieldname, fielddata]
) => {
values[fieldname] = serialize(fielddata, nilvalue);
return values;
},
{} as Record<string, SerializedFormField<typeof nilvalue>>
const formvalues = Object.freeze(
[...storageinterface.storage().entries()].reduce(
(
values: Record<string, SerializedFormField<typeof nilvalue>>,
[fieldname, fielddata]
) => {
values[fieldname] = serialize(fielddata, nilvalue);
return values;
},
{} as Record<string, SerializedFormField<typeof nilvalue>>
)
);
for (const fn of subscribers) {
fn(formvalues);
}
Promise.all(
[...storageinterface.decoders().values()].map((decoder) =>
runDecoder(decoder, formvalues)
)
)
.then((decoderResults) => {
const validation = decoderResults.reduce(
(
collection: Record<string, Readonly<DecoderResult>>,
result
) => {
collection[result.decoder] = Object.freeze(result);
return collection;
},
{} as Record<string, Readonly<DecoderResult>>
);
for (const fn of subscribers) {
fn(formvalues, Object.freeze(validation));
}
})
.catch((err) => {
const error = new Error(
"[RxFormData] An an error occured while running decoders. Check the error details for more info."
);
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
//@ts-ignore
error.details = err;
for (const fn of subscribers) {
fn(formvalues, error);
}
});
break;

@@ -118,2 +177,3 @@ }

storageinterface.storage(),
storageinterface.decoders(),
submissionHanlder

@@ -120,0 +180,0 @@ );

@@ -1,8 +0,5 @@

import { $getform } from "@operators/dom";
import { isNone } from "@datatypes/Option";
import { $getform, isFormFieldSelectorExpression } from "@operators/dom";
import { isNone, isSome } from "@datatypes/Option";
import { panic } from "@operators/error";
import {
initialize as repositoryInitialization,
FormFieldSelectorExpression
} from "@/repository";
import { initialize as repositoryInitialization } from "@/repository";
import { initialize as eventsInitialization } from "@/events";

@@ -13,3 +10,4 @@ import {

ProgramInterfaceActionType,
FormFieldSubscriber
FormFieldSubscriber,
FormFieldSelectorExpression
} from "@datatypes/base";

@@ -22,2 +20,3 @@ import {

import { isNonEmptyString, isRegExp } from "@operators/string";
import { create as createDecoder, Decoder } from "@datatypes/Decoder";

@@ -130,2 +129,3 @@ export default function RxFormData(

repository.action(FORM_FIELD_STORAGE_ACTION_TYPE.UNREGISTER_ALL);
repository.action(FORM_FIELD_STORAGE_ACTION_TYPE.CLEAR_DECODERS);
if (events.cleanup) {

@@ -136,2 +136,37 @@ events.cleanup();

}
case PROGRAM_INTERFACE_ACTION_TYPE.ADD_DECODERS: {
if (Array.isArray(payload)) {
const params = payload.reduce(
(decoders: Decoder[], config: unknown) => {
const decoder = createDecoder(config);
if (isSome(decoder)) return decoders.concat(decoder.value);
return decoders;
},
[] as Decoder[]
);
if (params.length)
repository.action(
FORM_FIELD_STORAGE_ACTION_TYPE.UPSERT_DECODER,
params
);
}
break;
}
case PROGRAM_INTERFACE_ACTION_TYPE.REMOVE_DECODERS: {
if (Array.isArray(payload)) {
repository.action(
FORM_FIELD_STORAGE_ACTION_TYPE.REMOVE_DECODER,
payload.filter(isFormFieldSelectorExpression)
);
}
break;
}
case PROGRAM_INTERFACE_ACTION_TYPE.CLEAR_DECODERS: {
repository.action(FORM_FIELD_STORAGE_ACTION_TYPE.CLEAR_DECODERS);
break;
}
default: {

@@ -138,0 +173,0 @@ console.debug(

@@ -14,5 +14,6 @@ import {

HTMLFormFieldValue,
HTMLFormFieldTag
HTMLFormFieldTag,
FormFieldSelectorExpression
} from "@datatypes/base";
import { isNonEmptyString, isString } from "@operators/string";
import { isNonEmptyString, isString, isRegExp } from "@operators/string";
import { HTML_FORM_FIELD_TAG } from "@/constants";

@@ -256,1 +257,10 @@

}
export function isFormFieldSelectorExpression(
x: unknown
): x is FormFieldSelectorExpression {
if (isString(x)) {
return isNonEmptyString(x.trim());
}
return isRegExp(x);
}

@@ -18,3 +18,4 @@ import {

FormFieldStorageActionType,
FormFieldStorageInterface
FormFieldStorageInterface,
FormFieldSelectorExpression
} from "@datatypes/base";

@@ -28,7 +29,11 @@ import {

import { isPlainObject } from "@operators/struct";
import { isFormFieldElement } from "./operators/dom";
import {
isFormFieldElement,
isFormFieldSelectorExpression
} from "./operators/dom";
import { Decoder, isDecoder } from "@datatypes/Decoder";
export type FormFieldStorage = Map<string, FormField>;
export type FormFieldSelectorExpression = string | RegExp;
export type FormFieldRegister = Set<FormFieldSelectorExpression>;
export type FormDecoders = Map<string, Decoder>;

@@ -162,2 +167,15 @@ export function put(

const decoders = new Map<string, Decoder>();
const decodersref = new Map<FormDecoders, FormDecoders>().set(
decoders,
decoders
);
const getdecoders = (): FormDecoders => {
const latest = decodersref.get(decoders);
return latest
? new Map<string, Decoder>(latest.entries())
: new Map<string, Decoder>();
};
const action = (

@@ -171,2 +189,3 @@ type: FormFieldStorageActionType,

| { use: FormFieldSelectorExpression[]; keepvalues: boolean }
| Decoder[]
): void => {

@@ -198,2 +217,3 @@ switch (type) {

registerref.set(register, new Set<FormFieldSelectorExpression>());
decodersref.set(decoders, new Map<string, Decoder>());
publish($target, getstorage());

@@ -284,2 +304,38 @@ break;

}
case FORM_FIELD_STORAGE_ACTION_TYPE.UPSERT_DECODER: {
if (Array.isArray(payload) && payload.every(isDecoder)) {
const collection = getdecoders();
for (let idx = 0, length = payload.length; idx < length; idx++) {
const decoder = payload[idx] as Decoder;
collection.set(decoder.name, decoder);
}
decodersref.set(decoders, collection);
}
break;
}
case FORM_FIELD_STORAGE_ACTION_TYPE.REMOVE_DECODER: {
if (Array.isArray(payload)) {
const collection = getdecoders();
for (let idx = 0, length = payload.length; idx < length; idx++) {
const expression = payload[idx];
if (!isFormFieldSelectorExpression(expression)) continue;
for (const [key] of collection) {
if (isNonEmptyString(expression) && expression === key) {
collection.delete(key);
} else if (isRegExp(expression) && expression.test(key)) {
collection.delete(key);
}
}
}
decodersref.set(decoders, collection);
}
break;
}
case FORM_FIELD_STORAGE_ACTION_TYPE.CLEAR_DECODERS: {
decodersref.set(decoders, new Map<string, Decoder>());
break;
}
}

@@ -290,4 +346,5 @@ };

storage: getstorage,
decoders: getdecoders,
action
} as const;
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc