@ramstack/alpinegear-router 1.1.0-preview.1

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.
@@ -0,0 +1 @@
1
+ !function(){"use strict";const e=(...e)=>console.warn("alpine-gear.js:",...e),t=Array.isArray,n=e=>null==e,r=e=>e instanceof HTMLTemplateElement,a=e=>"function"==typeof e,o=e=>t(e)?e:[e],i=e=>a(e)&&"AsyncFunction"===e.constructor?.name?e:function(...t){const n=e.apply(this,t);return a(n?.then)?n:Promise.resolve(n)},s=(e,t,n,r)=>(e.addEventListener(t,n,r),()=>e.removeEventListener(t,n,r)),l=(e,t)=>{for(;e&&!t(e);)e=(e._x_teleportBack??e).parentElement;return e},u=Object.freeze({regex(e){const t=new RegExp(e);return{test(e){return t.test(e)}}},bool:()=>({test(e){return/^(?:true|false)$/i.test(e)},transform(e){return 4===e.length}}),int:()=>({test(e){return/^\d+$/.test(e)},transform(e){return+e}}),number:()=>({test(e){return/^[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?$/.test(e)&&isFinite(parseFloat(e))},transform(e){return parseFloat(e)}}),alpha:()=>({test(e){return/^[a-z]+$/i.test(e)}}),min:e=>({test(t){return t>=+e}}),max:e=>({test(t){return+e>=t}}),range(e){let[t,n]=e.split(",",2).map((e=>e.trim()));return{test(e){return e>=+t&&+n>=e}}},length:e=>({test(t){return t.length===+e}}),minlength:e=>({test(t){return t.length>=+e}}),maxlength:e=>({test(t){return+e>=t.length}})});class c{#e;#t;#n;#r;#a;get template(){return this.#t}get regex(){return this.#e}get constraints(){return this.#a}constructor(e,t=null){this.#t=e,this.#e=function(e,t,r,a){t.push(...function(e,t){return function(e){e.find((e=>e.parts.length>1&&e.parts.every((e=>e.optional))))&&l("Using all segment parameters as optional is not permitted");const r=new Map;return e.flatMap((e=>e.parts)).forEach(((e,a,o)=>{if("literal"!==e.kind||0>e.value.indexOf("?")||l("Literal segments cannot contain the '?' character"),"parameter"===e.kind){e.catch_all&&a!==o.length-1&&l("A catch-all parameter can only appear as the last segment"),r.has(e.name)&&l(`The route parameter name '${e.name}' appears more than one time`),"*"===e.quantifier&&n(e.default)&&(e.default=""),""===e.default&&"*"!==e.quantifier&&(e.default=null),r.set(e.name,!0);for(let r of e.constraints){const e=t?.[name]??u[r.name];n(e)&&l(`Unknown constraint '${r.name}'`),Object.assign(r,e(r.argument))}}})),e}(function(){const t=[];for(let n=0;e.length>n;){const e=r(n);e.template&&t.push(e),n+=e.template.length+1}return t}());function r(t){let n=[],r=t;for(;e.length>r&&"/"!==e[r];){const e=o(r)||a(r);n.push(e),r+=e.template.length}return{template:e.slice(t,r),parts:n}}function a(t){if("{"!==e[t])return null;const r=i(t),a=function(e){const t=e.match(/^(?<name>[a-z_$][a-z0-9_$-]*?)(?:[:?+*]|$)/i)?.groups?.name;return 0>(t?.length??-1)&&l("Invalid parameter name"),t}(r),o=e.slice(t,t+r.length+2),u=(()=>{const e=r[a.length];return"*"===e||"+"===e||"?"===e?e:""})(),c=function(e,t){const r=[];for(let a=t;e.length>a;){":"!==e[a]&&l();const t=s(e.slice(a+1));a+=t.length+1;const o="("===e[a]?i(a,e):null;n(o)||(a+=o.length+2),t||o||l(),r.push({name:""===t?"regex":"="===t?"default":t,argument:o??""})}return r}(r,a.length+u.length);return{kind:"parameter",template:o,name:a,quantifier:u,constraints:c.filter((e=>"default"!==e.name)),default:c.find((e=>"default"===e.name))?.argument,required:"+"===u||""===u,optional:"?"===u||"*"===u,catch_all:"+"===u||"*"===u}}function o(t){for(let n=t;;n++)if(n>=e.length||"/"===e[n]||"{"===e[n]){if(n===t)return null;const r=e.slice(t,n);return{kind:"literal",template:r,value:r}}}function i(t,n){n??=e;const r=[];e:for(let e=t;n.length>e;e++){switch(n[e]){case"{":r.push("}");break;case"(":r.push(")");break;case"}":case")":if(r.pop()!==n[e])break e}if(0===r.length)return n.slice(t+1,e)}l()}function s(e){const t=e.match(/^(?<name>=|[a-z0-9_$]*)(?=[/:(]|$)/i)?.groups?.name;return 0>(t?.length??-1)&&l("Invalid constraint name"),t}function l(t="Invalid pattern"){throw new Error(`${t}: ${e}`)}}(e,a));let o=t.map((e=>e.parts.map(((t,n)=>{if("literal"===t.kind)return n?t.value:`/${t.value}`;if(r.set(t.name,t),1===e.parts.length&&"?"===t.quantifier)return`(?:/(?<${t.name}>[^/]+?))?`;if(t.catch_all){let e=`(?<${t.name}>.${t.quantifier})`;return n||(e=`(?:/${e})`),"*"===t.quantifier&&(e+="?"),"*"===t.quantifier?e+"?":e}{const e=`(?<${t.name}>[^/]+?)${t.quantifier}`;return n?e:`/${e}`}})).join(""))).join("")||"/";return"/"!==o&&(o+="/?"),new RegExp(`^${o}$`)}(e,this.#n=[],this.#r=new Map,this.#a=t??{})}match(e){let t=this.#e.exec(e);if(n(t))return null;t=t.groups??{};for(let[e,r]of this.#r.entries()){let a=t[e];if(n(a)&&n(r.default))continue;a||n(r.default)||(a=r.default);const o=r.catch_all?a.split("/").filter((e=>e.length)):[a];for(let e=0;o.length>e;e++)for(let t of r.constraints){if(t.test&&!t.test(o[e]))return null;t.transform&&(o[e]=t.transform(o[e]))}t[e]=r.catch_all?o:o[0]}return t}resolve(e){e=new Map(Object.entries(e));const t=[];for(let r of this.#n){const a=[];for(let t of r.parts)if("literal"===t.kind)a.push(t.value);else{let r=e.get(t.name);if(e.delete(t.name),(n(r)||""===r)&&(r=this.#r.get(t.name)?.default,t.catch_all&&r&&(r=r.split("/"))),n(r)||""===r){if(t.required)return null;if(t.optional&&t.default===r)continue}t.catch_all?(r=o(r),a.push(...r.map((e=>encodeURIComponent(e))).join("/"))):a.push(encodeURIComponent(r))}a.length&&t.push(a.join(""))}let r=[...e.entries()].map((([e,t])=>encodeURIComponent(e)+"="+encodeURIComponent(t))).join("&");r&&(r="?"+r);const a=t.join("/")+r;return"/"!==a[0]?"/"+a:a}}function f({directive:t,magic:a,$data:o}){t("route",((t,{expression:a,value:s},{cleanup:u,evaluate:f})=>{if(!r(t))return void e("x-route can only be used on a 'template' tag");const h=l(t,(e=>e._b_route))?._b_route;if(!n(h)||"view"!==s&&"handler"!==s)switch(s){case"view":h.view=()=>async function(t){let n;try{n=await fetch(t)}catch{}if(!n?.ok)return e(`Failed to load template from ${t}`),new DocumentFragment;const r=new DocumentFragment,a=(new DOMParser).parseFromString(await n.text(),"text/html");return r.append(...a.body.childNodes),r}(a),u((()=>{h.view=()=>new Promise((e=>e(new DocumentFragment)))}));break;case"handler":!function(){a||(a="[]"),a.startsWith("[")||(a=`[${a}]`);const e=f(a).map(i),r=o(t);h.handler=async t=>{for(let a of e){const e=await a.call(r,t);if(!n(e))return e}},u((()=>h.handler=null))}();break;default:!function(){const r=l(t,(e=>e._b_router))?._b_router;n(r)?e("no x-router directive found"):(t._b_route=Object.assign(new c(a),{el:t,view:()=>new Promise((e=>e(t.content))),handler(){return Promise.resolve()}}),r.routes.push(t._b_route),u((()=>{r.routes=r.routes.filter((e=>e!==t._b_route))})))}()}else e("no x-route directive found")})),a("route",(e=>l(e,(e=>e._b_router))?._b_router.values))}let h,p;function m(){for(let e in h)e in location&&(h[e]=location[e])}const d={get path(){return p.hash.slice(1)||"/"},get location(){return p},resolve(e){let t=new URL(e);return t.hash?t.hash.slice(1)||"/":t.pathname},navigate(e,t=!1){0>e.indexOf("#")&&(e="#"+e),v(e,t)}},g={get path(){return p.pathname},get location(){return p},resolve:e=>new URL(e).pathname,navigate(e,t=!1){v(e,t)}};function v(e,t){history[t?"replaceState":"pushState"]({},"",e),p.refresh()}const _={html5:g,hash:d};function w({directive:t,magic:a,reactive:i}){t("router",((t,{expression:a,value:u},{cleanup:c,effect:f,evaluate:d,evaluateLater:v})=>{u||(u="html5");const w=l(t,(e=>e._b_router))?._b_router;if(!n(w)||"outlet"!==u&&"link"!==u)switch(u){case"outlet":w.outlet&&e("x-router:outlet already specified",w.outlet),w.outlet||(w.outlet=t),c((()=>w.outlet=null));break;case"link":!function(){const e=(t.getAttribute("target")??"").indexOf("_blank")>=0,n=s(t,"click",(n=>{n.metaKey||n.altKey||n.ctrlKey||n.shiftKey||n.defaultPrevented||n.button>0||e||(n.preventDefault(),w.navigate(`${t.pathname}${t.search}${t.hash}`))}));if(a){const e=function(e){const t=e("$active");return()=>{let e;return t((t=>e=t)),n=e,"function"==typeof n?.get?e.get():e;var n}}(v),n=o(d(a));f((()=>{const r=e();for(let e of n)t.classList.toggle(e,r)})),c((()=>t.classList.remove(...n)))}c(n)}();break;default:!function(){if(r(t))return void e("x-router cannot be used on a 'template' tag");const o=i({pattern:"",path:"",params:""}),l=n(u)&&a?d(a):function(t){p??=(h||(h=Alpine.reactive({hash:"",host:"",hostname:"",href:"",origin:"",pathname:"",port:0,protocol:"",search:"",refresh(){m()}}),m(),s(window,"hashchange",m),s(window,"popstate",m)),h),t||="html5";let n=_[t];return n||(e(`Unknown history API: '${t}'`),n=g),n}(u),f={routes:[],outlet:null,active:null,history:l,values:o,async match(e){for(let t of this.routes){const n=t.match(e);if(n){const r={router:f,route:t,params:n,path:e};if(!1!==await t.handler(r))return r}}},navigate:(e,t=!1)=>(l.navigate(e,t),!0)};function v(){if(f.active){for(let e of f.active.nodes??[])e.remove();f.active.nodes=null,f.active=null}}t._b_router=f;const w=function(e,t,n=null){const{effect:r,release:a}=Alpine;let o,i,s=!1;const l=r((()=>{o=e(),s||(n?.deep&&JSON.stringify(o),i=o),(s||(n?.immediate??1))&&setTimeout((()=>{t(o,i),i=o}),0),s=!0}));return()=>a(l)}((()=>l.path),(async e=>{const t=await f.match(e);t?e===l.path&&function(e,t,n){if(e.nodes?.length&&o.path===t)return;v(),o.path=t,o.pattern=e.template,o.params=n,f.active=e;const a=f.outlet;a&&e.view().then((i=>{o.path===t&&o.pattern===e.template&&JSON.stringify(o.params)===JSON.stringify(n)&&(e.nodes=[...i.cloneNode(!0).childNodes],r(a)?e.nodes.forEach((e=>a.parentElement.insertBefore(e,a))):e.nodes.forEach((e=>a.append(e))))}))}(t.route,t.path,t.params):v()}));c(w),c(v)}()}else e("no x-router directive found")})),a("router",(e=>l(e,(e=>e._b_router))?._b_router)),a("active",(t=>{const r=l(t,(e=>e._b_router))?._b_router;if(!n(r))return r.history.resolve(t.href)===r.values.path;e("No x-router directive found")}))}function b(e){window.RoutePattern=c,e.plugin([w,f])}document.addEventListener("alpine:init",(()=>{Alpine.plugin(b)}))}();
package/package.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "@ramstack/alpinegear-router",
3
+ "version": "1.1.0-preview.1",
4
+ "description": "@ramstack/alpinegear-router provides routing-related directives for Alpine.js, enabling client-side navigation and routing functionality.",
5
+ "author": "Rameel Burhan",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/rameel/ramstack.alpinegear.js.git",
10
+ "directory": "src/plugins/router"
11
+ },
12
+ "keywords": [
13
+ "alpine.js",
14
+ "alpinejs"
15
+ ],
16
+ "main": "alpinegear-router.js",
17
+ "module": "alpinegear-router.esm.js"
18
+ }