@peter.naydenov/route-emitter
Version:
Changes in URL are converted in events according routes definition list
2 lines (1 loc) • 4.63 kB
JavaScript
import t from"@peter.naydenov/notice";import e from"url-pattern";import r from"ask-for-promise";var n={_historyActions:function(t,e){return function(r,{addressName:n,data:o,url:s}){const{eBus:i,API:a}=t,u=e.lastLocation;a.navigate(n,o,!0),u===s?i.emit("_RELOAD",n,o,s):i.emit("_CHANGE",n,o,s),r.done(n,o)}},_locationChange:function(t,e){return function(){const{eBus:r,history:n,API:o}=t;let s=!1,i=!0,a=!1;const u=sessionStorage.getItem(e.SSName),c=n.read();if(u&&u===c&&(s=!0),i=e.rt.every((({name:t,pattern:i,title:u,redirect:d,data:l={}})=>{let f=i.match(c);return!f||(d?(o.navigate(d,l,!0),a=!0,!1):(sessionStorage.setItem(e.SSName,c),e.lastLocation=c,e.lastAddress=t,n.write({state:{PGID:t,url:c,data:f},url:c,title:u},!0),s?r.emit("_RELOAD",t,f,c):r.emit("_CHANGE",t,f,c),!1))})),i){if(a)return;r.emit("_ERROR",{code:404,message:`There is no defined address for path "${c}".`})}else e.lastRoute=c}},_setAddressRecord:function(t,e){return function({name:r,path:n,title:o,inHistory:s,redirect:i,data:a}){if(null==r)return null;if(null==n)return null;null==o&&(o=e.appName),null==s&&(s=!1);const{UrlPattern:u}=t;return{name:r,path:n,title:o,inHistory:s,pattern:new u(n),redirect:i,data:a}}},createURL:function(t,e){return function(t,r={}){const{routes:n}=e;if(!n[t])return console.error(`Address "${t}" is not registered`),null;const{pattern:o}=n[t];try{return o.stringify(r)}catch(e){return console.error(`Data provided for address "${t}" is not correct.`),null}}},getCurrentAddress:function(t,e){return function(){const{lastAddress:t,lastLocation:r,routes:n}=e,{pattern:o}=t?n[t]:{pattern:"null"};let s=o.match(r);return[e.lastAddress,s]}},destroy:function(t,e){return function(){const{eBus:r,history:n,dead:o}=t;e.isActive=!1,r.off(),n.destroy(),sessionStorage.removeItem(e.SSName),t.API={on:o,navigate:o,destroy:o}}},listAciveAddresses:function(t,e){return function(){return e.rt.map((t=>t.name))}},listActiveRoutes:function(t,e){return function(){const{rt:t}=e;return t.map((t=>`${t.name} ---\x3e ${t.path}`))}},navigate:function(t,e){const{history:r,eBus:n}=t;return function t(o,s={},i=!1){if(!e.isActive)return void console.error("Router is not active. Use router.run() to activate it.");const{lastAddress:a,lastLocation:u,routes:c}=e;if(!c[o])return console.error(`Address "${o}" is not registered`),void n.emit("_ERROR",{code:404,message:`Address "${o}" is not registered`});let d=!1;const{pattern:l,title:f,redirect:m,data:p}=c[o];if(m)t(m,p);else{a&&(d=c[a].inHistory);try{const t=l.stringify(s);if(t===u)return;e.lastLocation=t,sessionStorage.setItem(e.SSName,t),e.lastAddress=o,i&&(d=!1),r.write({state:{PGID:o,url:t,data:s},url:t,title:f},d)}catch(t){return void n.emit("_ERROR",{code:400,message:`Data provided for address "${o}" is not correct. ${t}`})}}}},removeAddresses:function(t,e){return function(r){const{rt:n}=e;return e.rt=n.reduce(((t,n)=>{let{name:o}=n;return r.includes(o)?(delete e.routes[o],t):(t.push(n),t)}),[]),t.API}},run:function(t,e){return function(){const{inAPI:r,history:n}=t;e.isActive=!0,n.listen(r._historyActions),r._locationChange()}},setAddresses:function(t,e){return function(r,n=[]){const{_setAddressRecord:o}=t.inAPI;return r.forEach((t=>{const r=o(t);if(!r)return;if(n.includes(r.name))return;const s=r.name;e.rt.push(r),e.routes[s]=r})),t.API}}};function o(o){const s=t(),i=function(){let t=null;return{write:function({state:t,title:e,url:r},n){n?window.history.pushState(t,"",r):window.history.replaceState(t,"",r);const o="function"==typeof e;document.title=o?e(t.data):e},read:function(){return window.location.pathname},back:function(e=1){return t=r().timeout(1500,"expire"),window.history.back(e),t.onComplete((e=>{"expire"===e&&(t=null)})),t.promise},go:function(e=1){return t=r().timeout(1500,"expire"),window.history.go(e),t.onComplete((e=>{"expire"===e&&(t=null)})),t.promise},listen:function(e){onpopstate=function(n){let{PGID:o,url:s,data:i}=n.state;t||(t=r()),e(t,{addressName:o,data:i,url:s}),t=null}},destroy:function(){window.onpopstate=null}}}(),{appName:a,sessionStorageKey:u}=o||{},c={lastLocation:"",lastAddress:null,SSName:"_routeEmmiterLastLocation",appName:"App Name",rt:[],routes:{},isActive:!1},d={UrlPattern:e,eBus:s,history:i,dead:()=>console.error("Router was destroyed")},l={},f={};return a&&"string"==typeof a&&(c.appName=a),u&&"string"==typeof u&&(c.SSName=u),Object.entries(n).forEach((([t,e])=>{t.startsWith("_")?f[t]=e(d,c):l[t]=e(d,c)})),d.inAPI=f,d.API={onChange:t=>(s.on("_CHANGE",t),d.API),onError:t=>(s.on("_ERROR",t),d.API),onReload:t=>(s.on("_RELOAD",t),d.API),back:t=>i.back(t),forward:t=>i.go(t),...l},d.API}export{o as default};