@argon-router/core 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("effector"),a=require("query-string"),r=require("patronum");const n={any:Symbol("any"),number:Symbol("number"),string:Symbol("string"),array:Symbol("array"),boolean:Symbol("boolean")};function t(e,a){for(const r of e)if(a.includes(r))return!0;return!1}function s(e,a){for(const r in a){const t=a[r];if(Array.isArray(t)&&(!e[r]||JSON.stringify(t)!==e[r]))return!1;switch(typeof t){case"number":if(!e[r]||t.toString()!==e[r])return!1;break;case"object":if(!e[r]||JSON.stringify(t)!==e[r])return!1;break;case"string":if(!e[r]||t!==e[r])return!1;break;case"boolean":if(!e[r]||!["0","1","false","true"].includes(e[r]))return!1}switch(t){case n.any:if(!e[r])return!1;break;case n.string:if(!e[r]||Array.isArray(e[r]))return!1;break;case n.array:if(!e[r]||!Array.isArray(e[r]))return!1;break;case n.number:if(!e[r]||Array.isArray(e[r])||isNaN(parseInt(e[r]))&&isNaN(parseFloat(e[r])))return!1;break;case n.boolean:if(!e[r]||Array.isArray(e[r])||!["0","1","false","true"].includes(e[r]))return!1}}return!0}function o(a){let{$query:r,navigate:n}=a;return i({$activeRoutes:e.createStore([],{name:"$activeRoutes",sid:"85ms46"}),$query:r,navigate:n})}function i(a){let{$activeRoutes:r,$query:o,navigate:i}=a;return a=>{const{parameters:c,forRoutes:p}=a,l=e.createStore(!1,{name:"$entered",sid:"-mo5ecc"}),d=e.createEvent({name:"entered",sid:"kuzfr"}),u=e.createEvent({name:"exited",sid:"-jzwna6"}),m=e.createEvent({name:"exit",sid:"7hfy2r"}),f=e.createEvent({name:"changeEntered",sid:"qh8w6v"});return e.sample({and:[{clock:f,target:l}],or:{sid:"-gf1fe4"}}),e.sample({and:[{source:{activeRoutes:r,query:o},filter:e=>{let{activeRoutes:a,query:r}=e;return(!p||t(p,a))&&s(r,c)},fn:e=>{let{query:a}=e;return function(e,a){const r={};for(const t in a){const s=a[t],o=e[t];if(Array.isArray(s)){const a=e[t];r[t]=a;continue}switch(typeof s){case"number":r[t]=isNaN(parseInt(o))?parseFloat(o):parseInt(o);break;case"object":r[t]=JSON.parse(o);break;case"string":r[t]=o;case"boolean":r[t]="1"===o||"true"===o}switch(s){case n.any:case n.string:case n.array:r[t]=e[t];break;case n.number:{const a=e[t];r[t]=isNaN(parseInt(a))?parseFloat(a):parseInt(a);break}case n.boolean:{const a=e[t];r[t]="1"===a||"true"===a;break}}}return r}(a,c)},target:[d,f.prepend(()=>!0)]}],or:{sid:"-gcagfb"}}),e.sample({and:[{source:{activeRoutes:r,query:o,entered:l},filter:e=>{let{activeRoutes:a,query:r,entered:n}=e;return n&&!((!p||t(p,a))&&s(r,c))},target:[u.prepend(()=>{}),f.prepend(()=>!1)]}],or:{sid:"-fvsmmh"}}),e.sample({and:[{clock:m,source:o,fn:(e,a)=>{if(a&&a.ignoreParams){const r={};for(const n of a.ignoreParams)e[n]&&(r[n]=e[n]);return{query:r}}return{query:{}}},target:i}],or:{sid:"-f105e9"}}),{entered:d,exited:u,exit:m}}}function c(e){return a=>{const r=a.split("/").map(e=>e.trim()).filter(e=>""!==e);let n=null;function t(e,a){n||(n={}),n[e]=a}if(0===e.length)return 0===r.length?{path:a,params:null}:null;for(let s=0;s<e.length;s++){const a=e[s];switch(a.type){case"const":if(a.name!==r.shift())return null;continue;case"parameter":{const{arrayProps:n,genericProps:o,required:i}=a.payload;if(n){const i=[];let c;for(;c=r.shift(),c;){switch(null==o?void 0:o.type){case"number":if(isNaN(+c))return null;i.push(+c);break;case"union":if(!o.items.includes(c))return null;i.push(c);break;default:i.push(c)}if(i.length>=(n.max??1/0))break}if(i.length<(n.min??0))return null;if(r.length>0&&!e[s+1])return null;t(a.name,i);break}const c=r.shift();if(i&&!c)return null;if(!c){t(a.name,void 0);continue}switch(null==o?void 0:o.type){case"number":if(isNaN(+c))return null;t(a.name,+c);break;case"union":if(!o.items.includes(c))return null;t(a.name,c);break;default:t(a.name,c)}}}}return r.length>0?null:{path:a,params:n}}}function p(e){if(!e)return null;const a=e[1];let r,n,t;for(const s of e.slice(2))s&&(s.includes("<")?r=s.replaceAll(/\s/g,"").replace("<","").replace(">",""):(s.includes("{")&&(n=s.replace("{","").replace("}","").split(",").map(e=>parseInt(e))),["*","?","+"].includes(s)&&(t=s)));return{name:a,genericProps:r,arrayProps:n,modificator:t}}function l(e){return a=>{const r=[];if(0===e.length)return"/";for(const n of e)switch(n.type){case"const":r.push(n.name);break;case"parameter":if(!a[n.name])continue;if(Array.isArray(a[n.name]))for(const e of a[n.name])r.push(e.toString());else r.push(a[n.name].toString())}return`/${r.join("/")}`}}function d(){const r=e.createStore(null,{and:{serialize:"ignore"},name:"$history",sid:"-ld7lzl"}),n=e.createStore({query:{},path:null},{name:"$locationState",sid:"-4u3w85"}),t=n.map(e=>e.query),s=n.map(e=>e.path),i=e.createEvent({name:"setHistory",sid:"-ormmkk"}),c=e.createEvent({name:"navigate",sid:"tawqep"}),p=e.createEvent({name:"back",sid:"bxy8rt"}),l=e.createEvent({name:"forward",sid:"-bpmzb1"}),d=e.createEvent({name:"locationUpdated",sid:"lkzldx"}),u=e.attach({and:{source:r,effect:(e,r)=>{let{path:n,query:t,replace:s}=r;if(!e)throw new Error("history not found");const o={pathname:n,search:`?${a.stringify(t)}`};s?e.replace(o):e.push(o)}},or:{name:"navigateFx",sid:"-ov1xn7"}}),m=e.createEffect(r=>{const n=e.scopeBind(d);if(n({pathname:r.location.pathname,query:{...a.parse(r.location.search)}}),!r)throw new Error;r.listen(e=>{let{location:r}=e;n({pathname:r.pathname,query:{...a.parse(r.search)}})})},{name:"subscribeHistoryFx",sid:"-m60vds"});return e.sample({and:[{clock:i,target:r}],or:{sid:"ii4q"}}),e.sample({and:[{clock:r,filter:Boolean,target:m}],or:{sid:"39h3j"}}),e.sample({and:[{clock:d,fn:e=>({path:e.pathname,query:e.query}),target:n}],or:{sid:"i3x4a"}}),e.sample({and:[{clock:c,source:s,fn:(e,a)=>({path:e,...a}),target:u}],or:{sid:"ylqx4"}}),{$history:r,$locationState:n,$query:t,$path:s,setHistory:i,navigate:c,back:p,forward:l,locationUpdated:d,trackQuery:o({$query:t,navigate:c})}}function u(){let a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:e.createStore(!1,{and:{name:"pending",sid:"r89aiv"},name:"pending",sid:"r89aiv"});const r=e.createStore(null,{name:"$params",sid:"-ftspin"}),n=e.createStore(!1,{name:"$isOpened",sid:"-v6936c"}),t=a,s=e.createEvent({name:"open",sid:"juc47v"}),o=e.createEvent({name:"opened",sid:"-quc8vc"}),i=e.createEvent({name:"openedOnServer",sid:"n25rh4"}),c=e.createEvent({name:"openedOnClient",sid:"-auqikx"}),p=e.createEvent({name:"close",sid:"4zlqo6"}),l=e.createEvent({name:"closed",sid:"wbpfrk"}),d=e.createEvent({name:"cancelled",sid:"-q3x5sf"});return e.sample({and:[{clock:s,target:o}],or:{sid:"-u8b34x"}}),e.split({and:[{source:o,match:()=>"undefined"==typeof window?"server":"client",cases:{server:i,client:c}}],or:{sid:"-u5k464"}}),e.sample({and:[{clock:p,target:l}],or:{sid:"-tp2ada"}}),e.sample({and:[{clock:[o.map(()=>!0),l.map(()=>!1)],target:n}],or:{sid:"-tarmxw"}}),{$params:r,$isOpened:n,$isPending:t,open:s,opened:o,openedOnClient:c,openedOnServer:i,close:p,closed:l,cancelled:d,path:null,"@@unitShape":()=>({params:r,isOpened:n,isPending:t,onOpen:s})}}exports.chainRoute=function(a){const{route:r,beforeOpen:n,openOn:t,cancelOn:s}=a;let o;const i=e.createEffect(()=>null==o?void 0:o(),{name:"waitForAsyncBundleFx",sid:"-tvp99n"}),c=e.createEffect(async e=>{await i();for(const a of[].concat(n))await a(e)},{name:"openFx",sid:"-9kc1je"}),p=u(c.pending);return e.sample({and:[{clock:r.opened,target:c}],or:{sid:"1162lk"}}),e.sample({and:[{clock:r.opened,fn:e=>e&&"params"in e?e.params:null,target:p.$params}],or:{sid:"13x1kd"}}),t&&e.sample({and:[{clock:t,source:{params:p.$params},fn:e=>{let{params:a}=e;return{params:a}},target:p.open}],or:{sid:"1kevex"}}),s&&(e.sample({and:[{clock:[r.closed].concat(s),target:p.close}],or:{sid:"20wp7r"}}),e.sample({and:[{clock:[].concat(s),target:p.cancelled}],or:{sid:"2f7cn5"}})),Object.assign(p,{internal:{setAsyncImport:e=>o=e}})},exports.createRoute=function(a){let r;const n=e.createEffect(()=>null==r?void 0:r(),{name:"waitForAsyncBundleFx",sid:"1y76ms"}),t=e.createEffect(async()=>{for(const e of a.beforeOpen??[])await e()},{name:"beforeOpenFx",sid:"-65tb76"}),s=e.createEffect(async e=>{await n(),await t();const r=a.parent;return r&&await r.internal.openFx({...e??{params:{}},navigate:!1}),e},{name:"openFx",sid:"p3u4q7"}),o=e.createStore({},{name:"$params",sid:"-a34rm3"}),i=e.createStore(!1,{name:"$isOpened",sid:"7m6f5g"}),c=s.pending,p=e.createEvent({name:"open",sid:"ur5fa6"}),l=e.createEvent({name:"close",sid:"-k33yie"}),d=e.createEvent({name:"opened",sid:"-nt8hns"}),u=e.createEvent({name:"openedOnServer",sid:"hbjexo"}),m=e.createEvent({name:"openedOnClient",sid:"h92wzn"}),f=e.createEvent({name:"navigated",sid:"-8amrhe"}),y=e.createEvent({name:"closed",sid:"-pql6th"});e.sample({and:[{clock:p,target:s}],or:{sid:"ymah4t"}});const h={};return e.sample({and:[{clock:f,fn:e=>e&&"params"in e?{...e.params}:h,target:o}],or:{sid:"z1opqx"}}),e.split({and:[{source:f,match:()=>"undefined"==typeof window?"server":"client",cases:{server:u,client:m}}],or:{sid:"-zha4na"}}),e.sample({and:[{clock:[m,u],target:d}],or:{sid:"-z08i93"}}),e.sample({and:[{clock:l,target:y}],or:{sid:"-yxhjaa"}}),e.sample({and:[{clock:[d.map(()=>!0),y.map(()=>!1)],target:i}],or:{sid:"-yj6vuw"}}),{$params:o,$isOpened:i,$isPending:c,open:p,closed:y,opened:d,openedOnClient:m,openedOnServer:u,...a,internal:{navigated:f,close:l,openFx:s,setAsyncImport:e=>r=e},"@@unitShape":()=>({params:o,isPending:c,isOpened:i,onOpen:p})}},exports.createRouter=function(a){const{base:r="/",routes:n}=a,{$path:t,$query:s,back:o,forward:u,navigate:m,setHistory:f,locationUpdated:y}=d(),h=n.map(e=>{let a=e;const n=[];for(n.unshift(a.path);a.parent;)a=a.parent,"/"!==a.path&&n.unshift(a.path);const t="/"===r?n.join(""):[r,...n].join(""),{build:s,parse:o}=function(e){const a=[],r=/:(\w+)(<[\s?\w|]+>)?({\d+\,\d+})?([+*?])?/,n=e.split("/").filter(Boolean);for(let t=0;t<n.length;t++){const s=n[t];if(!s)continue;const o=p(s.match(r));if(!o){a.push({type:"const",name:s,payload:void 0});continue}const{arrayProps:i,genericProps:c,modificator:l,name:d}=o;if(!d)throw new Error(`Invalid path: "${e}". Name for argument must be provided`);const u={type:"parameter",name:d,payload:{required:!0}};switch(c&&"number"===c&&(u.payload.genericProps={type:"number"}),c&&c.includes("|")&&(u.payload.genericProps={type:"union",items:c.split("|")}),l){case"*":u.payload.arrayProps={};break;case"+":u.payload.arrayProps={min:1};break;case"?":u.payload.required=!1}i&&(u.payload.arrayProps={...u.payload.arrayProps,min:i[0],max:i[1]}),a.push(u)}return{parse:c(a),build:l(a)}}(t);return{route:e,path:t,build:s,parse:o}}),g=t.map(e=>{const a=[];if(!e)return a;for(const{route:r,parse:n}of h)n(e)&&a.push(r);return a}),v=e.attach({and:{source:{query:s,path:t},effect:async a=>{let{query:r,path:n}=a;for(const{route:t,parse:s}of h){const a=s(n),[o,i]=[e.scopeBind(t.internal.close),e.scopeBind(t.internal.navigated)];a?i({query:r,params:a.params}):o()}}},or:{name:"openRoutesByPathFx",sid:"-3zl7vq"}});for(const{route:i,build:c}of h)e.sample({and:[{clock:i.internal.openFx.doneData,filter:e=>!1!==(null==e?void 0:e.navigate),fn:e=>({path:c(e&&"params"in e?e.params:void 0),query:(null==e?void 0:e.query)??{},replace:null==e?void 0:e.replace}),target:m}],or:{sid:"exzzqg"}});return e.sample({and:[{clock:y,fn:e=>({path:e.pathname,query:e.query}),target:v}],or:{sid:"ficdn3"}}),{$query:s,$path:t,$activeRoutes:g,back:o,forward:u,navigate:m,routes:n,setHistory:f,mappedRoutes:h,trackQuery:i({$activeRoutes:g,$query:s,navigate:m}),"@@unitShape":()=>({query:s,path:t,activeRoutes:g,onBack:o,onForward:u,onNavigate:m})}},exports.createRouterControls=d,exports.createVirtualRoute=u,exports.group=function(a){const n=u(e.withFactory({sid:"-uirglg",fn:()=>r.or(...a.map(e=>e.$isPending)),name:"$isPending",method:"or"}));return e.sample({and:[{clock:a.map(e=>e.$isOpened),filter:e.withFactory({sid:"6pispd",fn:()=>r.or(...a.map(e=>e.$isOpened)),name:"filter",method:"or"}),fn:()=>{},target:n.open}],or:{sid:"-xn8czd"}}),e.sample({and:[{clock:a.map(e=>e.$isOpened),filter:e.withFactory({sid:"a0u5gq",fn:()=>r.not(e.withFactory({sid:"xb4bx2",fn:()=>r.or(...a.map(e=>e.$isOpened)),name:"fn",method:"or"})),name:"filter",method:"not"}),fn:()=>{},target:n.close}],or:{sid:"-x7u4d9"}}),n},exports.parameters=n;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("effector"),a=require("query-string"),n=require("patronum");function t(e,a){for(const n of e)if(a.includes(n))return!0;return!1}function r(a){let{$query:n,navigate:t}=a;return o({$activeRoutes:e.createStore([],{name:"$activeRoutes",sid:"ni3bf8"}),$query:n,navigate:t})}function o(a){let{$activeRoutes:n,$query:r,navigate:o}=a;return a=>{const{parameters:s,forRoutes:i}=a,c=e.createStore(!1,{name:"$entered",sid:"-i5493b"}),d=e.createEvent({name:"entered",sid:"9i8bun"}),l=e.createEvent({name:"exited",sid:"-p2hcsy"}),p=e.createEvent({name:"enter",sid:"30cmky"}),u=e.createEvent({name:"exit",sid:"-2657ec"}),m=e.createEvent({name:"changeEntered",sid:"-5jm7r1"});return e.sample({and:[{clock:m,target:c}],or:{sid:"-j6nk9y"}}),e.sample({and:[{source:{activeRoutes:n,query:r},filter:e=>{let{activeRoutes:a,query:n}=e;return(!i||t(i,a))&&s.safeParse(n).success},fn:e=>{let{query:a}=e;return s.safeParse(a).data},target:[d,m.prepend(()=>!0)]}],or:{sid:"-iscwuk"}}),e.sample({and:[{source:{activeRoutes:n,query:r,entered:c},filter:e=>{let{activeRoutes:a,query:n,entered:r}=e;return r&&!((!i||t(i,a))&&s.safeParse(n).success)},target:[l.prepend(()=>{}),m.prepend(()=>!1)]}],or:{sid:"-ibv31q"}}),e.sample({and:[{clock:p,source:r,fn:(e,a)=>({query:{...e,...a}}),target:o}],or:{sid:"-hsmaa3"}}),e.sample({and:[{clock:u,source:r,fn:(e,a)=>{if(a&&a.ignoreParams){const n={};for(const t of a.ignoreParams)e[t]&&(n[t]=e[t]);return{query:n}}return{query:{}}},target:o}],or:{sid:"-whgzm0"}}),{enter:p,entered:d,exited:l,exit:u}}}function s(e){return a=>{const n=a.split("/").map(e=>e.trim()).filter(e=>""!==e);let t=null;function r(e,a){t||(t={}),t[e]=a}if(0===e.length)return 0===n.length?{path:a,params:null}:null;for(let o=0;o<e.length;o++){const a=e[o];switch(a.type){case"const":if(a.name!==n.shift())return null;continue;case"parameter":{const{arrayProps:t,genericProps:s,required:i}=a.payload;if(t){const i=[];let c;for(;c=n.shift(),c;){switch(null==s?void 0:s.type){case"number":if(isNaN(+c))return null;i.push(+c);break;case"union":if(!s.items.includes(c))return null;i.push(c);break;default:i.push(c)}if(i.length>=(t.max??1/0))break}if(i.length<(t.min??0))return null;if(n.length>0&&!e[o+1])return null;r(a.name,i);break}const c=n.shift();if(i&&!c)return null;if(!c){r(a.name,void 0);continue}switch(null==s?void 0:s.type){case"number":if(isNaN(+c))return null;r(a.name,+c);break;case"union":if(!s.items.includes(c))return null;r(a.name,c);break;default:r(a.name,c)}}}}return n.length>0?null:{path:a,params:t}}}function i(e){if(!e)return null;const a=e[1];let n,t,r;for(const o of e.slice(2))o&&(o.includes("<")?n=o.replaceAll(/\s/g,"").replace("<","").replace(">",""):(o.includes("{")&&(t=o.replace("{","").replace("}","").split(",").map(e=>parseInt(e))),["*","?","+"].includes(o)&&(r=o)));return{name:a,genericProps:n,arrayProps:t,modificator:r}}function c(e){return a=>{const n=[];if(0===e.length)return"/";for(const t of e)switch(t.type){case"const":n.push(t.name);break;case"parameter":if(!a[t.name])continue;if(Array.isArray(a[t.name]))for(const e of a[t.name])n.push(e.toString());else n.push(a[t.name].toString())}return`/${n.join("/")}`}}function d(){const n=e.createStore(null,{and:{serialize:"ignore"},name:"$history",sid:"-ld7lzl"}),t=e.createStore({query:{},path:null},{name:"$locationState",sid:"-4u3w85"}),o=t.map(e=>e.query),s=t.map(e=>e.path),i=e.createEvent({name:"setHistory",sid:"-ormmkk"}),c=e.createEvent({name:"navigate",sid:"tawqep"}),d=e.createEvent({name:"back",sid:"bxy8rt"}),l=e.createEvent({name:"forward",sid:"-bpmzb1"}),p=e.createEvent({name:"locationUpdated",sid:"lkzldx"}),u=e.attach({and:{source:n,effect:(e,n)=>{let{path:t,query:r,replace:o}=n;if(!e)throw new Error("history not found");const s={pathname:t,search:`?${a.stringify(r)}`};o?e.replace(s):e.push(s)}},or:{name:"navigateFx",sid:"-ov1xn7"}}),m=e.createEffect(n=>{const t=e.scopeBind(p);if(t({pathname:n.location.pathname,query:{...a.parse(n.location.search)}}),!n)throw new Error;n.listen(e=>{let{location:n}=e;t({pathname:n.pathname,query:{...a.parse(n.search)}})})},{name:"subscribeHistoryFx",sid:"-m60vds"});return e.sample({and:[{clock:i,target:n}],or:{sid:"ii4q"}}),e.sample({and:[{clock:n,filter:Boolean,target:m}],or:{sid:"39h3j"}}),e.sample({and:[{clock:p,fn:e=>({path:e.pathname,query:e.query}),target:t}],or:{sid:"i3x4a"}}),e.sample({and:[{clock:c,source:s,fn:(e,a)=>({path:e,...a}),target:u}],or:{sid:"ylqx4"}}),{$history:n,$locationState:t,$query:o,$path:s,setHistory:i,navigate:c,back:d,forward:l,locationUpdated:p,trackQuery:r({$query:o,navigate:c})}}function l(){let a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{beforeOpen:n,$isPending:t=e.createStore(!1,{name:"$isPending",sid:"-f18bwu"}),transformer:r=e=>e??null}=a,o=e.createStore(null,{name:"$params",sid:"v2ropa"}),s=e.createStore(!1,{name:"$isOpened",sid:"mzzqqr"}),i=e.createEvent({name:"open",sid:"f33vnd"}),c=e.createEvent({name:"opened",sid:"-efpvez"}),d=e.createEvent({name:"openedOnServer",sid:"o8st20"}),l=e.createEvent({name:"openedOnClient",sid:"xaagqn"}),p=e.createEvent({name:"close",sid:"-20upkw"}),u=e.createEvent({name:"closed",sid:"avevxu"}),m=e.createEvent({name:"cancelled",sid:"808tq5"});return e.sample({and:[{clock:i,target:[c]}],or:{sid:"p3r2ad"}}),e.sample({and:[{clock:i,fn:r,target:o}],or:{sid:"p6i196"}}),e.split({and:[{source:c,match:()=>"undefined"==typeof window?"server":"client",cases:{server:d,client:l}}],or:{sid:"plch9x"}}),e.sample({and:[{clock:p,target:u}],or:{sid:"q1ub2r"}}),e.sample({and:[{clock:[c.map(()=>!0),u.map(()=>!1)],target:s}],or:{sid:"q4la1k"}}),{$params:o,$isOpened:s,$isPending:t,open:i,opened:c,openedOnClient:l,openedOnServer:d,close:p,closed:u,cancelled:m,path:"",beforeOpen:n,"@@unitShape":()=>({params:o,isOpened:s,isPending:t,onOpen:i,onClose:p})}}exports.chainRoute=function(a){const{route:n,beforeOpen:t,openOn:r,cancelOn:o}=a;let s;const i=e.createEffect(()=>null==s?void 0:s(),{name:"waitForAsyncBundleFx",sid:"qdkcuo"}),c=e.createEffect(async e=>{await i();for(const a of[].concat(t))await a(e)},{name:"openFx",sid:"-fwntqy"}),d=e=>e&&"params"in e?e.params:null,p=l({transformer:d});return e.sample({and:[{clock:n.opened,target:c}],or:{sid:"-s9xf6p"}}),e.sample({and:[{clock:n.opened,fn:d,target:p.$params}],or:{sid:"-1u78yc"}}),r&&e.sample({and:[{clock:r,source:p.$params,fn:e=>e,target:p.open}],or:{sid:"-1qcor3"}}),o&&(e.sample({and:[{clock:[n.closed].concat(o),target:p.close}],or:{sid:"-19uuy9"}}),e.sample({and:[{clock:[].concat(o),target:p.cancelled}],or:{sid:"-vk7iv"}})),Object.assign(p,{internal:{setAsyncImport:e=>s=e}})},exports.createRoute=function(a){let n;const t=e.createEffect(async e=>{await f(),await y();const n=a.parent;return n&&await n.internal.openFx({...e??{params:{}},navigate:!1}),e},{name:"openFx",sid:"awhgwd"}),r=e.createStore({},{name:"$params",sid:"-oahffx"}),o=e.createStore(!1,{name:"$isOpened",sid:"-6l68oe"}),s=t.pending,i=e.createEvent({name:"open",sid:"gjsrgc"}),c=e.createEvent({name:"close",sid:"-yagmc8"}),d=e.createEvent({name:"opened",sid:"x0iwhi"}),l=e.createEvent({name:"openedOnServer",sid:"346r3u"}),p=e.createEvent({name:"openedOnClient",sid:"31q95t"}),u=e.createEvent({name:"navigated",sid:"-t30l0x"}),m=e.createEvent({name:"closed",sid:"uue4ce"}),f=e.createEffect(()=>null==n?void 0:n(),{name:"waitForAsyncBundleFx",sid:"-nml5ho"}),y=e.createEffect(async()=>{for(const e of a.beforeOpen??[])await e()},{name:"beforeOpenFx",sid:"-vqlnbm"}),h=e.attach({and:{effect:t},or:{name:"navigatedFx",sid:"a4yadj"}}),g={};return e.sample({and:[{clock:i,target:t}],or:{sid:"ynxuww"}}),e.sample({and:[{clock:u,fn:e=>({navigate:!1,...e}),target:h}],or:{sid:"z28ica"}}),e.sample({and:[{clock:h.doneData,fn:e=>e&&"params"in e?{...e.params}:g,target:r}],or:{sid:"z5j9wg"}}),e.sample({and:[{clock:h.failData,fn:()=>g,target:r}],or:{sid:"-z1vw16"}}),e.split({and:[{source:h.doneData,match:()=>"undefined"==typeof window?"server":"client",cases:{server:l,client:p}}],or:{sid:"-yyl4h0"}}),e.sample({and:[{clock:[p,l],target:d}],or:{sid:"-yhji2t"}}),e.sample({and:[{clock:c,target:m}],or:{sid:"-y38unf"}}),e.sample({and:[{clock:[d.map(()=>!0),m.map(()=>!1)],target:o}],or:{sid:"-y0hvom"}}),{$params:r,$isOpened:o,$isPending:s,open:i,closed:m,opened:d,openedOnClient:p,openedOnServer:l,...a,internal:{navigated:u,close:c,openFx:t,setAsyncImport:e=>n=e},"@@unitShape":()=>({params:r,isPending:s,isOpened:o,onOpen:i})}},exports.createRouter=function(a){const{base:n="/",routes:t}=a,{$path:r,$query:l,back:p,forward:u,navigate:m,setHistory:f,locationUpdated:y}=d(),h=t.map(e=>{let a=e;const t=[];for(t.unshift(a.path);a.parent;)a=a.parent,"/"!==a.path&&t.unshift(a.path);const r="/"===n?t.join(""):[n,...t].join(""),{build:o,parse:d}=function(e){const a=[],n=/:(\w+)(<[\s?\w|]+>)?({\d+\,\d+})?([+*?])?/,t=e.split("/").filter(Boolean);for(let r=0;r<t.length;r++){const o=t[r];if(!o)continue;const s=i(o.match(n));if(!s){a.push({type:"const",name:o,payload:void 0});continue}const{arrayProps:c,genericProps:d,modificator:l,name:p}=s;if(!p)throw new Error(`Invalid path: "${e}". Name for argument must be provided`);const u={type:"parameter",name:p,payload:{required:!0}};switch(d&&"number"===d&&(u.payload.genericProps={type:"number"}),d&&d.includes("|")&&(u.payload.genericProps={type:"union",items:d.split("|")}),l){case"*":u.payload.arrayProps={};break;case"+":u.payload.arrayProps={min:1};break;case"?":u.payload.required=!1}c&&(u.payload.arrayProps={...u.payload.arrayProps,min:c[0],max:c[1]}),a.push(u)}return{parse:s(a),build:c(a)}}(r);return{route:e,path:r,build:o,parse:d}}),g=r.map(e=>{const a=[];if(!e)return a;for(const{route:n,parse:t}of h)t(e)&&a.push(n);return a}),v=e.attach({and:{source:{query:l,path:r},effect:async a=>{let{query:n,path:t}=a;for(const{route:r,parse:o}of h){const a=o(t),[s,i]=[e.scopeBind(r.internal.close),e.scopeBind(r.internal.navigated)];a?i({query:n,params:a.params}):s()}}},or:{name:"openRoutesByPathFx",sid:"-3zl7vq"}});for(const{route:o,build:s}of h)e.sample({and:[{clock:o.internal.openFx.doneData,filter:e=>!1!==(null==e?void 0:e.navigate),fn:e=>({path:s(e&&"params"in e?e.params:void 0),query:(null==e?void 0:e.query)??{},replace:null==e?void 0:e.replace}),target:m}],or:{sid:"exzzqg"}});return e.sample({and:[{clock:y,fn:e=>({path:e.pathname,query:e.query}),target:v}],or:{sid:"ficdn3"}}),{$query:l,$path:r,$activeRoutes:g,back:p,forward:u,navigate:m,routes:t,setHistory:f,mappedRoutes:h,trackQuery:o({$activeRoutes:g,$query:l,navigate:m}),"@@unitShape":()=>({query:l,path:r,activeRoutes:g,onBack:p,onForward:u,onNavigate:m})}},exports.createRouterControls=d,exports.createVirtualRoute=l,exports.group=function(a){const t=l({$isPending:e.withFactory({sid:"-u1putn",fn:()=>n.or(...a.map(e=>e.$isPending)),name:"$isPending",method:"or"})});return e.sample({and:[{clock:a.map(e=>e.$isOpened),filter:e.withFactory({sid:"76kf3k",fn:()=>n.or(...a.map(e=>e.$isOpened)),name:"filter",method:"or"}),fn:()=>{},target:t.open}],or:{sid:"-xmoke0"}}),e.sample({and:[{clock:a.map(e=>e.$isOpened),filter:e.withFactory({sid:"ahvrux",fn:()=>n.not(e.withFactory({sid:"xs5yb9",fn:()=>n.or(...a.map(e=>e.$isOpened)),name:"fn",method:"or"})),name:"filter",method:"not"}),fn:()=>{},target:t.close}],or:{sid:"-x7abrw"}}),t};
package/dist/index.d.ts CHANGED
@@ -9,23 +9,13 @@ import { Store } from 'effector';
9
9
  import { StoreWritable } from 'effector';
10
10
  import { Unit } from 'effector';
11
11
  import { ValidatePath } from '@argon-router/paths';
12
-
13
- declare type AnyParameter = typeof anySymbol;
14
-
15
- declare const anySymbol: unique symbol;
16
-
17
- declare type ArrayParameter = typeof arraySymbol;
18
-
19
- declare const arraySymbol: unique symbol;
12
+ import { z } from 'zod';
13
+ import { ZodType } from 'zod';
20
14
 
21
15
  declare type BeforeOpenUnit<T> = (T extends void ? EventCallable<void> | EventCallable<OpenPayloadBase> : EventCallable<{
22
16
  params: T;
23
17
  } & OpenPayloadBase>) | Effect<RouteOpenedPayload<T>, any>;
24
18
 
25
- declare type BooleanParameter = typeof booleanSymbol;
26
-
27
- declare const booleanSymbol: unique symbol;
28
-
29
19
  /**
30
20
  * @link https://movpushmov.dev/argon-router/core/chain-route.html
31
21
  * @param props Chain route props
@@ -67,7 +57,7 @@ declare const booleanSymbol: unique symbol;
67
57
  * const postLoadedRoute = chainRoute({ route: authorizedRoute, ... });
68
58
  * ```
69
59
  */
70
- export declare function chainRoute<T>(props: ChainRouteProps<T>): VirtualRoute<T>;
60
+ export declare function chainRoute<T>(props: ChainRouteProps<T>): VirtualRoute<RouteOpenedPayload<T>, T>;
71
61
 
72
62
  declare interface ChainRouteProps<T> {
73
63
  route: Route<T>;
@@ -179,7 +169,7 @@ export declare function createRouter(config: RouterConfig): Router;
179
169
  */
180
170
  export declare function createRouterControls(): RouterControls;
181
171
 
182
- export declare function createVirtualRoute<T>(pending?: Store<boolean>): VirtualRoute<T>;
172
+ export declare function createVirtualRoute<T = void, TransformerResult = void>(options?: VirtualRouteOptions<T, TransformerResult>): VirtualRoute<T, TransformerResult>;
183
173
 
184
174
  /**
185
175
  * @description Create virtual route which opens when some passed routes is opened. Closes if all passed routes are closed.
@@ -199,7 +189,7 @@ export declare function createVirtualRoute<T>(pending?: Store<boolean>): Virtual
199
189
  * signUpRoute.close(); // authorizationRoute.$isOpened —> false
200
190
  * ```
201
191
  */
202
- export declare function group(routes: Route<any>[]): VirtualRoute<void>;
192
+ export declare function group(routes: Route<any>[]): VirtualRoute<void, void>;
203
193
 
204
194
  declare type LocationState = {
205
195
  path: string;
@@ -212,46 +202,27 @@ export declare type NavigatePayload = {
212
202
  replace?: boolean;
213
203
  };
214
204
 
215
- declare type NumberParameter = typeof numberSymbol;
216
-
217
- declare const numberSymbol: unique symbol;
218
-
219
205
  export declare type OpenPayloadBase = {
220
206
  query?: Query;
221
207
  replace?: boolean;
222
208
  };
223
209
 
224
- export declare const parameters: Parameters_2;
225
-
226
- declare type Parameters_2 = {
227
- any: AnyParameter;
228
- number: NumberParameter;
229
- string: StringParameter;
230
- array: ArrayParameter;
231
- boolean: BooleanParameter;
232
- };
233
-
234
210
  export declare type Query = Record<string, string | null | Array<string | null>>;
235
211
 
236
- export declare interface QueryTracker<ParametersConfig extends RawConfig> {
237
- entered: Event_2<ReadyConfig<ParametersConfig>>;
212
+ export declare interface QueryTracker<ParametersConfig extends ZodType> {
213
+ entered: Event_2<z.infer<ParametersConfig>>;
238
214
  exited: Event_2<void>;
215
+ enter: EventCallable<z.infer<ParametersConfig>>;
239
216
  exit: EventCallable<{
240
217
  ignoreParams: string[];
241
218
  } | void>;
242
219
  }
243
220
 
244
- export declare type QueryTrackerConfig<ParametersConfig extends RawConfig> = {
221
+ export declare type QueryTrackerConfig<ParametersConfig extends ZodType> = {
245
222
  forRoutes?: Route<any>[];
246
223
  parameters: ParametersConfig;
247
224
  };
248
225
 
249
- export declare type RawConfig = Record<string, AnyParameter | ArrayParameter | NumberParameter | StringParameter | BooleanParameter | SupportedPrimitive | SupportedPrimitive[]>;
250
-
251
- export declare type ReadyConfig<T extends RawConfig> = {
252
- [K in keyof T]: T[K] extends StringParameter ? string : T[K] extends NumberParameter ? number : T[K] extends ArrayParameter ? string[] : T[K] extends AnyParameter ? string | string[] : never;
253
- };
254
-
255
226
  export declare interface Route<T = void> {
256
227
  $params: Store<T>;
257
228
  $isOpened: Store<boolean>;
@@ -310,7 +281,7 @@ export declare interface Router {
310
281
  * // /team?dialog=team&id=not_number
311
282
  * ```
312
283
  */
313
- trackQuery: <ParametersConfig extends RawConfig>(config: QueryTrackerConfig<ParametersConfig>) => QueryTracker<ParametersConfig>;
284
+ trackQuery: <ParametersConfig extends ZodType>(config: QueryTrackerConfig<ParametersConfig>) => QueryTracker<ParametersConfig>;
314
285
  mappedRoutes: {
315
286
  route: Route<any>;
316
287
  path: string;
@@ -350,14 +321,16 @@ declare interface RouterControls {
350
321
  * @param config Query tacker config
351
322
  * @link https://movpushmov.dev/argon-router/core/track-query.html
352
323
  * @example ```ts
353
- * import { parameters } from '@argon-router/core';
324
+ * import { z } from 'zod';
354
325
  * import { router } from '@shared/router';
355
326
  * import { createDialog } from '...';
356
327
  *
357
328
  * const dialog = createDialog();
358
329
  * const tracker = router.trackQuery({
359
- * dialog: 'team-member',
360
- * id: parameters.number,
330
+ * parameters: {
331
+ * dialog: z.literal('team-member'),
332
+ * id: z.cource.number(),
333
+ * },
361
334
  * });
362
335
  *
363
336
  * // triggered for:
@@ -370,19 +343,35 @@ declare interface RouterControls {
370
343
  * // /team?dialog=team&id=not_number
371
344
  * ```
372
345
  */
373
- trackQuery: <T extends RawConfig>(config: Omit<QueryTrackerConfig<T>, 'forRoutes'>) => QueryTracker<T>;
346
+ trackQuery: <T extends ZodType>(config: Omit<QueryTrackerConfig<T>, 'forRoutes'>) => QueryTracker<T>;
374
347
  }
375
348
 
376
- declare type StringParameter = typeof stringSymbol;
377
-
378
- declare const stringSymbol: unique symbol;
379
-
380
- declare type SupportedPrimitive = string | number | Date | boolean;
381
-
382
- export declare interface VirtualRoute<T = any> extends Route<T> {
383
- $params: StoreWritable<T>;
349
+ export declare interface VirtualRoute<T, TransformerResult> {
350
+ $params: StoreWritable<TransformerResult>;
351
+ $isOpened: StoreWritable<boolean>;
352
+ $isPending: Store<boolean>;
353
+ open: EventCallable<T>;
354
+ opened: Event_2<T>;
355
+ openedOnServer: Event_2<T>;
356
+ openedOnClient: Event_2<T>;
384
357
  close: EventCallable<void>;
358
+ closed: Event_2<void>;
385
359
  cancelled: Event_2<void>;
360
+ path: string;
361
+ beforeOpen?: Effect<any, any, any>[];
362
+ '@@unitShape': () => {
363
+ params: Store<TransformerResult>;
364
+ isOpened: Store<boolean>;
365
+ isPending: Store<boolean>;
366
+ onOpen: EventCallable<T>;
367
+ onClose: EventCallable<void>;
368
+ };
369
+ }
370
+
371
+ declare interface VirtualRouteOptions<T, TransformerResult> {
372
+ beforeOpen?: Effect<void, any, any>[];
373
+ $isPending?: Store<boolean>;
374
+ transformer?: (payload: T) => TransformerResult;
386
375
  }
387
376
 
388
377
  export { }
package/dist/index.js CHANGED
@@ -1,20 +1,8 @@
1
- import { createEffect, createStore, createEvent, sample, split, attach, scopeBind, withFactory } from "effector";
1
+ import { createEffect, createStore, createEvent, attach, sample, split, scopeBind, withFactory } from "effector";
2
2
  import queryString from "query-string";
3
3
  import { or, not } from "patronum";
4
4
  function createRoute(config) {
5
5
  let asyncImport;
6
- const waitForAsyncBundleFx = createEffect(() => asyncImport == null ? void 0 : asyncImport(), {
7
- name: "waitForAsyncBundleFx",
8
- sid: "1y76ms"
9
- });
10
- const beforeOpenFx = createEffect(async () => {
11
- for (const fx of config.beforeOpen ?? []) {
12
- await fx();
13
- }
14
- }, {
15
- name: "beforeOpenFx",
16
- sid: "-65tb76"
17
- });
18
6
  const openFx = createEffect(async (payload) => {
19
7
  await waitForAsyncBundleFx();
20
8
  await beforeOpenFx();
@@ -30,58 +18,92 @@ function createRoute(config) {
30
18
  return payload;
31
19
  }, {
32
20
  name: "openFx",
33
- sid: "p3u4q7"
21
+ sid: "awhgwd"
34
22
  });
35
23
  const $params = createStore({}, {
36
24
  name: "$params",
37
- sid: "-a34rm3"
25
+ sid: "-oahffx"
38
26
  });
39
27
  const $isOpened = createStore(false, {
40
28
  name: "$isOpened",
41
- sid: "7m6f5g"
29
+ sid: "-6l68oe"
42
30
  });
43
31
  const $isPending = openFx.pending;
44
32
  const open = createEvent({
45
33
  name: "open",
46
- sid: "ur5fa6"
34
+ sid: "gjsrgc"
47
35
  });
48
36
  const close = createEvent({
49
37
  name: "close",
50
- sid: "-k33yie"
38
+ sid: "-yagmc8"
51
39
  });
52
40
  const opened = createEvent({
53
41
  name: "opened",
54
- sid: "-nt8hns"
42
+ sid: "x0iwhi"
55
43
  });
56
44
  const openedOnServer = createEvent({
57
45
  name: "openedOnServer",
58
- sid: "hbjexo"
46
+ sid: "346r3u"
59
47
  });
60
48
  const openedOnClient = createEvent({
61
49
  name: "openedOnClient",
62
- sid: "h92wzn"
50
+ sid: "31q95t"
63
51
  });
64
52
  const navigated = createEvent({
65
53
  name: "navigated",
66
- sid: "-8amrhe"
54
+ sid: "-t30l0x"
67
55
  });
68
56
  const closed = createEvent({
69
57
  name: "closed",
70
- sid: "-pql6th"
58
+ sid: "uue4ce"
59
+ });
60
+ const waitForAsyncBundleFx = createEffect(() => asyncImport == null ? void 0 : asyncImport(), {
61
+ name: "waitForAsyncBundleFx",
62
+ sid: "-nml5ho"
63
+ });
64
+ const beforeOpenFx = createEffect(async () => {
65
+ for (const fx of config.beforeOpen ?? []) {
66
+ await fx();
67
+ }
68
+ }, {
69
+ name: "beforeOpenFx",
70
+ sid: "-vqlnbm"
71
71
  });
72
+ const navigatedFx = attach({
73
+ and: {
74
+ effect: openFx
75
+ },
76
+ or: {
77
+ name: "navigatedFx",
78
+ sid: "a4yadj"
79
+ }
80
+ });
81
+ const defaultParams = {};
72
82
  sample({
73
83
  and: [{
74
84
  clock: open,
75
85
  target: openFx
76
86
  }],
77
87
  or: {
78
- sid: "ymah4t"
88
+ sid: "ynxuww"
79
89
  }
80
90
  });
81
- const defaultParams = {};
82
91
  sample({
83
92
  and: [{
84
93
  clock: navigated,
94
+ fn: (payload) => ({
95
+ navigate: false,
96
+ ...payload
97
+ }),
98
+ target: navigatedFx
99
+ }],
100
+ or: {
101
+ sid: "z28ica"
102
+ }
103
+ });
104
+ sample({
105
+ and: [{
106
+ clock: navigatedFx.doneData,
85
107
  fn: (payload) => {
86
108
  if (!payload) {
87
109
  return defaultParams;
@@ -93,12 +115,22 @@ function createRoute(config) {
93
115
  target: $params
94
116
  }],
95
117
  or: {
96
- sid: "z1opqx"
118
+ sid: "z5j9wg"
119
+ }
120
+ });
121
+ sample({
122
+ and: [{
123
+ clock: navigatedFx.failData,
124
+ fn: () => defaultParams,
125
+ target: $params
126
+ }],
127
+ or: {
128
+ sid: "-z1vw16"
97
129
  }
98
130
  });
99
131
  split({
100
132
  and: [{
101
- source: navigated,
133
+ source: navigatedFx.doneData,
102
134
  match: () => typeof window === "undefined" ? "server" : "client",
103
135
  cases: {
104
136
  server: openedOnServer,
@@ -106,7 +138,7 @@ function createRoute(config) {
106
138
  }
107
139
  }],
108
140
  or: {
109
- sid: "-zha4na"
141
+ sid: "-yyl4h0"
110
142
  }
111
143
  });
112
144
  sample({
@@ -115,7 +147,7 @@ function createRoute(config) {
115
147
  target: opened
116
148
  }],
117
149
  or: {
118
- sid: "-z08i93"
150
+ sid: "-yhji2t"
119
151
  }
120
152
  });
121
153
  sample({
@@ -124,7 +156,7 @@ function createRoute(config) {
124
156
  target: closed
125
157
  }],
126
158
  or: {
127
- sid: "-yxhjaa"
159
+ sid: "-y38unf"
128
160
  }
129
161
  });
130
162
  sample({
@@ -133,7 +165,7 @@ function createRoute(config) {
133
165
  target: $isOpened
134
166
  }],
135
167
  or: {
136
- sid: "-yj6vuw"
168
+ sid: "-y0hvom"
137
169
  }
138
170
  });
139
171
  return {
@@ -160,18 +192,6 @@ function createRoute(config) {
160
192
  })
161
193
  };
162
194
  }
163
- const anySymbol = Symbol("any");
164
- const numberSymbol = Symbol("number");
165
- const stringSymbol = Symbol("string");
166
- const arraySymbol = Symbol("array");
167
- const booleanSymbol = Symbol("boolean");
168
- const parameters = {
169
- any: anySymbol,
170
- number: numberSymbol,
171
- string: stringSymbol,
172
- array: arraySymbol,
173
- boolean: booleanSymbol
174
- };
175
195
  function isForRouteActive(forRoutes, activeRoutes) {
176
196
  for (const route of forRoutes) {
177
197
  if (activeRoutes.includes(route)) {
@@ -180,121 +200,6 @@ function isForRouteActive(forRoutes, activeRoutes) {
180
200
  }
181
201
  return false;
182
202
  }
183
- function isHaveValidParams(query, neededParameters) {
184
- for (const key in neededParameters) {
185
- const parameterType = neededParameters[key];
186
- if (Array.isArray(parameterType) && (!query[key] || JSON.stringify(parameterType) !== query[key])) {
187
- return false;
188
- }
189
- switch (typeof parameterType) {
190
- case "number": {
191
- if (!query[key] || parameterType.toString() !== query[key]) {
192
- return false;
193
- }
194
- break;
195
- }
196
- case "object": {
197
- if (!query[key] || JSON.stringify(parameterType) !== query[key]) {
198
- return false;
199
- }
200
- break;
201
- }
202
- case "string": {
203
- if (!query[key] || parameterType !== query[key]) {
204
- return false;
205
- }
206
- break;
207
- }
208
- case "boolean": {
209
- if (!query[key] || !["0", "1", "false", "true"].includes(query[key])) {
210
- return false;
211
- }
212
- break;
213
- }
214
- }
215
- switch (parameterType) {
216
- case parameters.any: {
217
- if (!query[key]) {
218
- return false;
219
- }
220
- break;
221
- }
222
- case parameters.string: {
223
- if (!query[key] || Array.isArray(query[key])) {
224
- return false;
225
- }
226
- break;
227
- }
228
- case parameters.array: {
229
- if (!query[key] || !Array.isArray(query[key])) {
230
- return false;
231
- }
232
- break;
233
- }
234
- case parameters.number: {
235
- if (!query[key] || Array.isArray(query[key]) || isNaN(parseInt(query[key])) && isNaN(parseFloat(query[key]))) {
236
- return false;
237
- }
238
- break;
239
- }
240
- case parameters.boolean: {
241
- if (!query[key] || Array.isArray(query[key]) || !["0", "1", "false", "true"].includes(query[key])) {
242
- return false;
243
- }
244
- break;
245
- }
246
- }
247
- }
248
- return true;
249
- }
250
- function transformParams(query, neededParameters) {
251
- const result = {};
252
- for (const key in neededParameters) {
253
- const parameterType = neededParameters[key];
254
- const data = query[key];
255
- if (Array.isArray(parameterType)) {
256
- const arrayData = query[key];
257
- result[key] = arrayData;
258
- continue;
259
- }
260
- switch (typeof parameterType) {
261
- case "number": {
262
- result[key] = isNaN(parseInt(data)) ? parseFloat(data) : parseInt(data);
263
- break;
264
- }
265
- case "object": {
266
- result[key] = JSON.parse(data);
267
- break;
268
- }
269
- case "string": {
270
- result[key] = data;
271
- }
272
- case "boolean": {
273
- result[key] = data === "1" || data === "true";
274
- break;
275
- }
276
- }
277
- switch (parameterType) {
278
- case parameters.any:
279
- case parameters.string:
280
- case parameters.array: {
281
- result[key] = query[key];
282
- break;
283
- }
284
- case parameters.number: {
285
- const data2 = query[key];
286
- result[key] = isNaN(parseInt(data2)) ? parseFloat(data2) : parseInt(data2);
287
- break;
288
- }
289
- case parameters.boolean: {
290
- const data2 = query[key];
291
- result[key] = data2 === "1" || data2 === "true";
292
- break;
293
- }
294
- }
295
- }
296
- return result;
297
- }
298
203
  function trackQueryControlsFactory(_ref) {
299
204
  let {
300
205
  $query,
@@ -303,7 +208,7 @@ function trackQueryControlsFactory(_ref) {
303
208
  return trackQueryFactory({
304
209
  $activeRoutes: createStore([], {
305
210
  name: "$activeRoutes",
306
- sid: "85ms46"
211
+ sid: "ni3bf8"
307
212
  }),
308
213
  $query,
309
214
  navigate
@@ -317,28 +222,32 @@ function trackQueryFactory(_ref2) {
317
222
  } = _ref2;
318
223
  return (config) => {
319
224
  const {
320
- parameters: parameters2,
225
+ parameters,
321
226
  forRoutes
322
227
  } = config;
323
228
  const $entered = createStore(false, {
324
229
  name: "$entered",
325
- sid: "-mo5ecc"
230
+ sid: "-i5493b"
326
231
  });
327
232
  const entered = createEvent({
328
233
  name: "entered",
329
- sid: "kuzfr"
234
+ sid: "9i8bun"
330
235
  });
331
236
  const exited = createEvent({
332
237
  name: "exited",
333
- sid: "-jzwna6"
238
+ sid: "-p2hcsy"
239
+ });
240
+ const enter = createEvent({
241
+ name: "enter",
242
+ sid: "30cmky"
334
243
  });
335
244
  const exit = createEvent({
336
245
  name: "exit",
337
- sid: "7hfy2r"
246
+ sid: "-2657ec"
338
247
  });
339
248
  const changeEntered = createEvent({
340
249
  name: "changeEntered",
341
- sid: "qh8w6v"
250
+ sid: "-5jm7r1"
342
251
  });
343
252
  sample({
344
253
  and: [{
@@ -346,7 +255,7 @@ function trackQueryFactory(_ref2) {
346
255
  target: $entered
347
256
  }],
348
257
  or: {
349
- sid: "-gf1fe4"
258
+ sid: "-j6nk9y"
350
259
  }
351
260
  });
352
261
  sample({
@@ -360,18 +269,18 @@ function trackQueryFactory(_ref2) {
360
269
  activeRoutes,
361
270
  query
362
271
  } = _ref3;
363
- return (!forRoutes || isForRouteActive(forRoutes, activeRoutes)) && isHaveValidParams(query, parameters2);
272
+ return (!forRoutes || isForRouteActive(forRoutes, activeRoutes)) && parameters.safeParse(query).success;
364
273
  },
365
274
  fn: (_ref4) => {
366
275
  let {
367
276
  query
368
277
  } = _ref4;
369
- return transformParams(query, parameters2);
278
+ return parameters.safeParse(query).data;
370
279
  },
371
280
  target: [entered, changeEntered.prepend(() => true)]
372
281
  }],
373
282
  or: {
374
- sid: "-gcagfb"
283
+ sid: "-iscwuk"
375
284
  }
376
285
  });
377
286
  sample({
@@ -387,12 +296,30 @@ function trackQueryFactory(_ref2) {
387
296
  query,
388
297
  entered: entered2
389
298
  } = _ref5;
390
- return entered2 && !((!forRoutes || isForRouteActive(forRoutes, activeRoutes)) && isHaveValidParams(query, parameters2));
299
+ return entered2 && !((!forRoutes || isForRouteActive(forRoutes, activeRoutes)) && parameters.safeParse(query).success);
391
300
  },
392
301
  target: [exited.prepend(() => void 0), changeEntered.prepend(() => false)]
393
302
  }],
394
303
  or: {
395
- sid: "-fvsmmh"
304
+ sid: "-ibv31q"
305
+ }
306
+ });
307
+ sample({
308
+ and: [{
309
+ clock: enter,
310
+ source: $query,
311
+ fn: (query, payload) => {
312
+ return {
313
+ query: {
314
+ ...query,
315
+ ...payload
316
+ }
317
+ };
318
+ },
319
+ target: navigate
320
+ }],
321
+ or: {
322
+ sid: "-hsmaa3"
396
323
  }
397
324
  });
398
325
  sample({
@@ -418,10 +345,11 @@ function trackQueryFactory(_ref2) {
418
345
  target: navigate
419
346
  }],
420
347
  or: {
421
- sid: "-f105e9"
348
+ sid: "-whgzm0"
422
349
  }
423
350
  });
424
351
  return {
352
+ enter,
425
353
  entered,
426
354
  exited,
427
355
  exit
@@ -610,8 +538,8 @@ function compile(path) {
610
538
  if (!parsedToken) {
611
539
  continue;
612
540
  }
613
- const parameters2 = getTokenParameters(parsedToken.match(regexp));
614
- if (!parameters2) {
541
+ const parameters = getTokenParameters(parsedToken.match(regexp));
542
+ if (!parameters) {
615
543
  tokens.push({
616
544
  type: "const",
617
545
  name: parsedToken,
@@ -624,7 +552,7 @@ function compile(path) {
624
552
  genericProps,
625
553
  modificator,
626
554
  name
627
- } = parameters2;
555
+ } = parameters;
628
556
  if (!name) {
629
557
  throw new Error(`Invalid path: "${path}". Name for argument must be provided`);
630
558
  }
@@ -982,58 +910,68 @@ function createRouter(config) {
982
910
  };
983
911
  }
984
912
  function createVirtualRoute() {
985
- let pending = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : createStore(false, {
986
- and: {
987
- name: "pending",
988
- sid: "r89aiv"
989
- },
990
- name: "pending",
991
- sid: "r89aiv"
992
- });
913
+ let options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
914
+ const {
915
+ beforeOpen,
916
+ $isPending = createStore(false, {
917
+ name: "$isPending",
918
+ sid: "-f18bwu"
919
+ }),
920
+ transformer = (payload) => payload ?? null
921
+ } = options;
993
922
  const $params = createStore(null, {
994
923
  name: "$params",
995
- sid: "-ftspin"
924
+ sid: "v2ropa"
996
925
  });
997
926
  const $isOpened = createStore(false, {
998
927
  name: "$isOpened",
999
- sid: "-v6936c"
928
+ sid: "mzzqqr"
1000
929
  });
1001
- const $isPending = pending;
1002
930
  const open = createEvent({
1003
931
  name: "open",
1004
- sid: "juc47v"
932
+ sid: "f33vnd"
1005
933
  });
1006
934
  const opened = createEvent({
1007
935
  name: "opened",
1008
- sid: "-quc8vc"
936
+ sid: "-efpvez"
1009
937
  });
1010
938
  const openedOnServer = createEvent({
1011
939
  name: "openedOnServer",
1012
- sid: "n25rh4"
940
+ sid: "o8st20"
1013
941
  });
1014
942
  const openedOnClient = createEvent({
1015
943
  name: "openedOnClient",
1016
- sid: "-auqikx"
944
+ sid: "xaagqn"
1017
945
  });
1018
946
  const close = createEvent({
1019
947
  name: "close",
1020
- sid: "4zlqo6"
948
+ sid: "-20upkw"
1021
949
  });
1022
950
  const closed = createEvent({
1023
951
  name: "closed",
1024
- sid: "wbpfrk"
952
+ sid: "avevxu"
1025
953
  });
1026
954
  const cancelled = createEvent({
1027
955
  name: "cancelled",
1028
- sid: "-q3x5sf"
956
+ sid: "808tq5"
1029
957
  });
1030
958
  sample({
1031
959
  and: [{
1032
960
  clock: open,
1033
- target: opened
961
+ target: [opened]
962
+ }],
963
+ or: {
964
+ sid: "p3r2ad"
965
+ }
966
+ });
967
+ sample({
968
+ and: [{
969
+ clock: open,
970
+ fn: transformer,
971
+ target: $params
1034
972
  }],
1035
973
  or: {
1036
- sid: "-u8b34x"
974
+ sid: "p6i196"
1037
975
  }
1038
976
  });
1039
977
  split({
@@ -1046,7 +984,7 @@ function createVirtualRoute() {
1046
984
  }
1047
985
  }],
1048
986
  or: {
1049
- sid: "-u5k464"
987
+ sid: "plch9x"
1050
988
  }
1051
989
  });
1052
990
  sample({
@@ -1055,7 +993,7 @@ function createVirtualRoute() {
1055
993
  target: closed
1056
994
  }],
1057
995
  or: {
1058
- sid: "-tp2ada"
996
+ sid: "q1ub2r"
1059
997
  }
1060
998
  });
1061
999
  sample({
@@ -1064,7 +1002,7 @@ function createVirtualRoute() {
1064
1002
  target: $isOpened
1065
1003
  }],
1066
1004
  or: {
1067
- sid: "-tarmxw"
1005
+ sid: "q4la1k"
1068
1006
  }
1069
1007
  });
1070
1008
  return {
@@ -1078,13 +1016,14 @@ function createVirtualRoute() {
1078
1016
  close,
1079
1017
  closed,
1080
1018
  cancelled,
1081
- // @ts-expect-error emulated path for virtual route
1082
- path: null,
1019
+ path: "",
1020
+ beforeOpen,
1083
1021
  "@@unitShape": () => ({
1084
1022
  params: $params,
1085
1023
  isOpened: $isOpened,
1086
1024
  isPending: $isPending,
1087
- onOpen: open
1025
+ onOpen: open,
1026
+ onClose: close
1088
1027
  })
1089
1028
  };
1090
1029
  }
@@ -1098,7 +1037,7 @@ function chainRoute(props) {
1098
1037
  let asyncImport;
1099
1038
  const waitForAsyncBundleFx = createEffect(() => asyncImport == null ? void 0 : asyncImport(), {
1100
1039
  name: "waitForAsyncBundleFx",
1101
- sid: "-tvp99n"
1040
+ sid: "qdkcuo"
1102
1041
  });
1103
1042
  const openFx = createEffect(async (payload) => {
1104
1043
  await waitForAsyncBundleFx();
@@ -1107,47 +1046,46 @@ function chainRoute(props) {
1107
1046
  }
1108
1047
  }, {
1109
1048
  name: "openFx",
1110
- sid: "-9kc1je"
1049
+ sid: "-fwntqy"
1050
+ });
1051
+ const transformer = (payload) => {
1052
+ if (!payload) {
1053
+ return null;
1054
+ }
1055
+ return "params" in payload ? payload.params : null;
1056
+ };
1057
+ const virtualRoute = createVirtualRoute({
1058
+ transformer
1111
1059
  });
1112
- const virtualRoute = createVirtualRoute(openFx.pending);
1113
1060
  sample({
1114
1061
  and: [{
1115
1062
  clock: route.opened,
1116
1063
  target: openFx
1117
1064
  }],
1118
1065
  or: {
1119
- sid: "1162lk"
1066
+ sid: "-s9xf6p"
1120
1067
  }
1121
1068
  });
1122
1069
  sample({
1123
1070
  and: [{
1124
1071
  clock: route.opened,
1125
- fn: (payload) => payload && "params" in payload ? payload.params : null,
1072
+ fn: transformer,
1126
1073
  target: virtualRoute.$params
1127
1074
  }],
1128
1075
  or: {
1129
- sid: "13x1kd"
1076
+ sid: "-1u78yc"
1130
1077
  }
1131
1078
  });
1132
1079
  if (openOn) {
1133
1080
  sample({
1134
1081
  and: [{
1135
1082
  clock: openOn,
1136
- source: {
1137
- params: virtualRoute.$params
1138
- },
1139
- fn: (_ref) => {
1140
- let {
1141
- params
1142
- } = _ref;
1143
- return {
1144
- params
1145
- };
1146
- },
1083
+ source: virtualRoute.$params,
1084
+ fn: (params) => params,
1147
1085
  target: virtualRoute.open
1148
1086
  }],
1149
1087
  or: {
1150
- sid: "1kevex"
1088
+ sid: "-1qcor3"
1151
1089
  }
1152
1090
  });
1153
1091
  }
@@ -1158,7 +1096,7 @@ function chainRoute(props) {
1158
1096
  target: virtualRoute.close
1159
1097
  }],
1160
1098
  or: {
1161
- sid: "20wp7r"
1099
+ sid: "-19uuy9"
1162
1100
  }
1163
1101
  });
1164
1102
  sample({
@@ -1167,7 +1105,7 @@ function chainRoute(props) {
1167
1105
  target: virtualRoute.cancelled
1168
1106
  }],
1169
1107
  or: {
1170
- sid: "2f7cn5"
1108
+ sid: "-vk7iv"
1171
1109
  }
1172
1110
  });
1173
1111
  }
@@ -1178,18 +1116,19 @@ function chainRoute(props) {
1178
1116
  });
1179
1117
  }
1180
1118
  function group(routes) {
1181
- const $isPending = withFactory({
1182
- sid: "-uirglg",
1183
- fn: () => or(...routes.map((route) => route.$isPending)),
1184
- name: "$isPending",
1185
- method: "or"
1119
+ const virtual = createVirtualRoute({
1120
+ $isPending: withFactory({
1121
+ sid: "-u1putn",
1122
+ fn: () => or(...routes.map((route) => route.$isPending)),
1123
+ name: "$isPending",
1124
+ method: "or"
1125
+ })
1186
1126
  });
1187
- const virtual = createVirtualRoute($isPending);
1188
1127
  sample({
1189
1128
  and: [{
1190
1129
  clock: routes.map((route) => route.$isOpened),
1191
1130
  filter: withFactory({
1192
- sid: "6pispd",
1131
+ sid: "76kf3k",
1193
1132
  fn: () => or(...routes.map((route) => route.$isOpened)),
1194
1133
  name: "filter",
1195
1134
  method: "or"
@@ -1198,16 +1137,16 @@ function group(routes) {
1198
1137
  target: virtual.open
1199
1138
  }],
1200
1139
  or: {
1201
- sid: "-xn8czd"
1140
+ sid: "-xmoke0"
1202
1141
  }
1203
1142
  });
1204
1143
  sample({
1205
1144
  and: [{
1206
1145
  clock: routes.map((route) => route.$isOpened),
1207
1146
  filter: withFactory({
1208
- sid: "a0u5gq",
1147
+ sid: "ahvrux",
1209
1148
  fn: () => not(withFactory({
1210
- sid: "xb4bx2",
1149
+ sid: "xs5yb9",
1211
1150
  fn: () => or(...routes.map((route) => route.$isOpened)),
1212
1151
  name: "fn",
1213
1152
  method: "or"
@@ -1219,7 +1158,7 @@ function group(routes) {
1219
1158
  target: virtual.close
1220
1159
  }],
1221
1160
  or: {
1222
- sid: "-x7u4d9"
1161
+ sid: "-x7abrw"
1223
1162
  }
1224
1163
  });
1225
1164
  return virtual;
@@ -1230,6 +1169,5 @@ export {
1230
1169
  createRouter,
1231
1170
  createRouterControls,
1232
1171
  createVirtualRoute,
1233
- group,
1234
- parameters
1172
+ group
1235
1173
  };
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "registry": "https://registry.npmjs.org/"
6
6
  },
7
7
  "private": false,
8
- "version": "0.10.0",
8
+ "version": "0.11.0",
9
9
  "description": "Router with power of effector",
10
10
  "keywords": [
11
11
  "effector",
@@ -49,10 +49,11 @@
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/history": "^4.7.11",
52
- "query-string": "^9.1.1"
52
+ "query-string": "^9.1.1",
53
+ "zod": "^3.25.71"
53
54
  },
54
55
  "dependencies": {
55
- "@argon-router/paths": "^0.10.0"
56
+ "@argon-router/paths": "^0.11.0"
56
57
  },
57
- "gitHead": "7f8d946c9b6d11a4a828bdf2bafcf012970aa4d7"
58
+ "gitHead": "0180f75dbbc73a123e706ff48961f8e57d57ce65"
58
59
  }