@devlusoft/devix 0.4.1-beta.12 → 0.4.1-beta.14
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/cli/build.js +63 -35
- package/dist/cli/build.js.map +4 -4
- package/dist/cli/dev-server.js +51 -23
- package/dist/cli/dev-server.js.map +4 -4
- package/dist/cli/generate.js +63 -35
- package/dist/cli/generate.js.map +4 -4
- package/dist/cli/index.js +45 -17
- package/dist/cli/index.js.map +4 -4
- package/dist/cli/start.js +1 -1
- package/dist/cli/start.js.map +3 -3
- package/dist/runtime/client-router.js +1 -1
- package/dist/runtime/client-router.js.map +3 -3
- package/dist/runtime/context.d.ts +1 -0
- package/dist/runtime/context.js.map +2 -2
- package/dist/runtime/fetch.d.ts +4 -35
- package/dist/runtime/fetch.js +1 -1
- package/dist/runtime/fetch.js.map +3 -3
- package/dist/runtime/index.d.ts +32 -4
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/index.js.map +4 -4
- package/dist/runtime/link.d.ts +3 -2
- package/dist/runtime/link.js +1 -1
- package/dist/runtime/link.js.map +4 -4
- package/dist/runtime/router-provider.js +1 -1
- package/dist/runtime/router-provider.js.map +3 -3
- package/dist/runtime/server-app.js +1 -1
- package/dist/runtime/server-app.js.map +3 -3
- package/dist/server/api-router.d.ts +0 -1
- package/dist/server/api-router.js +1 -1
- package/dist/server/api-router.js.map +3 -3
- package/dist/server/api.js +1 -1
- package/dist/server/api.js.map +3 -3
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +3 -3
- package/dist/server/pages-router.d.ts +0 -1
- package/dist/server/pages-router.js +1 -1
- package/dist/server/pages-router.js.map +3 -3
- package/dist/server/render.d.ts +15 -0
- package/dist/server/render.js +1 -1
- package/dist/server/render.js.map +3 -3
- package/dist/server/routes.js +1 -1
- package/dist/server/routes.js.map +3 -3
- package/dist/server/types.d.ts +4 -2
- package/dist/utils/banner.js +1 -1
- package/dist/utils/response.d.ts +13 -2
- package/dist/utils/response.js +1 -1
- package/dist/utils/response.js.map +3 -3
- package/dist/vite/codegen/entry-client.js +14 -1
- package/dist/vite/codegen/entry-client.js.map +2 -2
- package/dist/vite/codegen/page-types.d.ts +5 -0
- package/dist/vite/codegen/page-types.js +14 -0
- package/dist/vite/codegen/page-types.js.map +7 -0
- package/dist/vite/codegen/routes-dts.js +13 -10
- package/dist/vite/codegen/routes-dts.js.map +2 -2
- package/dist/vite/codegen/scan-api.js +1 -1
- package/dist/vite/codegen/scan-api.js.map +1 -1
- package/dist/vite/index.js +65 -37
- package/dist/vite/index.js.map +4 -4
- package/package.json +2 -2
package/dist/cli/start.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/cli/start.ts", "../../src/server/routes.ts", "../../src/utils/env.ts"],
|
|
4
|
-
"sourcesContent": ["import { readFileSync } from 'node:fs'\nimport { serve } from '@hono/node-server'\nimport { serveStatic } from '@hono/node-server/serve-static'\nimport { Hono } from 'hono'\nimport { resolve, join } from 'node:path'\nimport type { Manifest } from 'vite'\nimport { registerApiRoutes, registerSsrRoute } from '../server/routes'\nimport { loadDotenv } from '../utils/env'\nimport {pathToFileURL} from \"node:url\"\n\nloadDotenv('production')\n\nlet renderModule: any\nlet apiModule: any\nlet manifest: Manifest\nlet runtimeConfig: { port: number, host: string | boolean, loaderTimeout: number, output: 'server' | 'static' }\n\ntry {\n runtimeConfig = JSON.parse(readFileSync(join(process.cwd(), 'dist/devix.config.json'), 'utf-8'))\n if (runtimeConfig.output !== 'static') {\n renderModule = await import(pathToFileURL(resolve(process.cwd(), 'dist/server/render.js')).href)\n apiModule = await import(pathToFileURL(resolve(process.cwd(), 'dist/server/api.js')).href)\n }\n manifest = JSON.parse(readFileSync(join(process.cwd(), 'dist/client/.vite/manifest.json'), 'utf-8'))\n} catch {\n console.error('[devix] Build not found. Run \"devix build\" first.')\n process.exit(1)\n}\n\nconst port = Number(process.env.PORT) || runtimeConfig!.port || 3000\nconst host = typeof runtimeConfig!.host === 'string'\n ? runtimeConfig!.host\n : runtimeConfig!.host ? '0.0.0.0' : (process.env.HOST || '0.0.0.0')\n\nconst app = new Hono()\n\nconst clientRoot = join(process.cwd(), 'dist/client')\n\nif (runtimeConfig!.output === 'static') {\n app.get('/_data/*', (c) => {\n const pathname = c.req.path.replace(/^\\/_data/, '') || '/'\n const filePath = pathname === '/'\n ? join(clientRoot, '_data/index.json')\n : join(clientRoot, '_data', `${pathname}.json`)\n\n try {\n const data = readFileSync(filePath, 'utf-8')\n return c.json(JSON.parse(data))\n } catch {\n return c.json({ error: 'not found' }, 404)\n }\n })\n}\n\napp.use('/*', serveStatic({\n root: clientRoot,\n onFound: (_path, c) => {\n c.header('Cache-Control', _path.includes('/assets/')\n ? 'public, immutable, max-age=31536000'\n : 'no-cache')\n }\n}))\n\nif (runtimeConfig!.output === 'static') {\n console.log('[devix] Static mode \u2014 serving pre-generated files from dist/client')\n} else {\n registerApiRoutes(app, { renderModule, apiModule, manifest })\n registerSsrRoute(app, { renderModule, apiModule, manifest, loaderTimeout: runtimeConfig!.loaderTimeout })\n}\n\nserve({ fetch: app.fetch, port, hostname: host }, (info) => console.log(`http://${info.address}:${info.port}`))\n\nexport { }", "import type {Hono} from 'hono'\nimport type {Manifest} from 'vite'\n\ninterface ServerOptions {\n renderModule: any\n apiModule: any\n manifest?: Manifest\n loaderTimeout?: number\n}\n\nexport function registerApiRoutes(app: Hono, {apiModule, renderModule, loaderTimeout}: ServerOptions) {\n app.all('/api/*', async (c) => {\n try {\n return await apiModule.handleApiRequest(c.req.url, c.req.raw)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n\n app.get('/_data/*', async (c) => {\n try {\n const {pathname, search} = new URL(c.req.url, 'http://localhost')\n const url = pathname.replace(/^\\/_data/, '') + search\n\n const data = await renderModule.runLoader(url, c.req.raw, {loaderTimeout})\n if (data.error) return c.json({error: 'internal error'}, 500)\n return c.json(data)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n}\n\nexport function registerSsrRoute(app: Hono, {renderModule, manifest, loaderTimeout}: ServerOptions) {\n app.get('*', async (c) => {\n try {\n const {html, statusCode, headers} = await renderModule.render(c.req.url, c.req.raw, {manifest, loaderTimeout})\n const res = c.html(`<!DOCTYPE html>${html}`, statusCode)\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n res.headers.set(key, value)\n }\n return res\n } catch (e) {\n console.error(e)\n return c.text('Internal Server Error', 500)\n }\n })\n}", "import {loadEnv} from 'vite'\n\nexport function loadDotenv(mode: string) {\n const env = loadEnv(mode, process.cwd(), '')\n for (const [key, value] of Object.entries(env)) {\n if (process.env[key] === undefined) {\n process.env[key] = value\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "AAAA,OAAS,gBAAAA,MAAoB,UAC7B,OAAS,SAAAC,MAAa,oBACtB,OAAS,eAAAC,MAAmB,iCAC5B,OAAS,QAAAC,MAAY,OACrB,OAAS,WAAAC,EAAS,QAAAC,MAAY,YCMvB,SAASC,EAAkBC,EAAW,CAAC,UAAAC,EAAW,aAAAC,EAAc,cAAAC,CAAa,EAAkB,CAClGH,EAAI,IAAI,SAAU,MAAOI,GAAM,CAC3B,GAAI,CACA,OAAO,MAAMH,EAAU,iBAAiBG,EAAE,IAAI,IAAKA,EAAE,IAAI,GAAG,CAChE,OAASC,EAAG,CACR,eAAQ,MAAMA,CAAC,EACRD,EAAE,KAAK,CAAC,MAAO,gBAAgB,EAAG,GAAG,CAChD,CACJ,CAAC,EAEDJ,EAAI,IAAI,WAAY,MAAOI,GAAM,CAC7B,GAAI,CACA,GAAM,CAAC,SAAAE,EAAU,OAAAC,CAAM,EAAI,IAAI,IAAIH,EAAE,IAAI,IAAK,kBAAkB,EAC1DI,EAAMF,EAAS,QAAQ,WAAY,EAAE,EAAIC,EAEzCE,EAAO,MAAMP,EAAa,UAAUM,EAAKJ,EAAE,IAAI,IAAK,CAAC,cAAAD,CAAa,CAAC,EACzE,
|
|
6
|
-
"names": ["readFileSync", "serve", "serveStatic", "Hono", "resolve", "join", "registerApiRoutes", "app", "apiModule", "renderModule", "loaderTimeout", "c", "e", "pathname", "search", "url", "data", "
|
|
4
|
+
"sourcesContent": ["import { readFileSync } from 'node:fs'\nimport { serve } from '@hono/node-server'\nimport { serveStatic } from '@hono/node-server/serve-static'\nimport { Hono } from 'hono'\nimport { resolve, join } from 'node:path'\nimport type { Manifest } from 'vite'\nimport { registerApiRoutes, registerSsrRoute } from '../server/routes'\nimport { loadDotenv } from '../utils/env'\nimport {pathToFileURL} from \"node:url\"\n\nloadDotenv('production')\n\nlet renderModule: any\nlet apiModule: any\nlet manifest: Manifest\nlet runtimeConfig: { port: number, host: string | boolean, loaderTimeout: number, output: 'server' | 'static' }\n\ntry {\n runtimeConfig = JSON.parse(readFileSync(join(process.cwd(), 'dist/devix.config.json'), 'utf-8'))\n if (runtimeConfig.output !== 'static') {\n renderModule = await import(pathToFileURL(resolve(process.cwd(), 'dist/server/render.js')).href)\n apiModule = await import(pathToFileURL(resolve(process.cwd(), 'dist/server/api.js')).href)\n }\n manifest = JSON.parse(readFileSync(join(process.cwd(), 'dist/client/.vite/manifest.json'), 'utf-8'))\n} catch {\n console.error('[devix] Build not found. Run \"devix build\" first.')\n process.exit(1)\n}\n\nconst port = Number(process.env.PORT) || runtimeConfig!.port || 3000\nconst host = typeof runtimeConfig!.host === 'string'\n ? runtimeConfig!.host\n : runtimeConfig!.host ? '0.0.0.0' : (process.env.HOST || '0.0.0.0')\n\nconst app = new Hono()\n\nconst clientRoot = join(process.cwd(), 'dist/client')\n\nif (runtimeConfig!.output === 'static') {\n app.get('/_data/*', (c) => {\n const pathname = c.req.path.replace(/^\\/_data/, '') || '/'\n const filePath = pathname === '/'\n ? join(clientRoot, '_data/index.json')\n : join(clientRoot, '_data', `${pathname}.json`)\n\n try {\n const data = readFileSync(filePath, 'utf-8')\n return c.json(JSON.parse(data))\n } catch {\n return c.json({ error: 'not found' }, 404)\n }\n })\n}\n\napp.use('/*', serveStatic({\n root: clientRoot,\n onFound: (_path, c) => {\n c.header('Cache-Control', _path.includes('/assets/')\n ? 'public, immutable, max-age=31536000'\n : 'no-cache')\n }\n}))\n\nif (runtimeConfig!.output === 'static') {\n console.log('[devix] Static mode \u2014 serving pre-generated files from dist/client')\n} else {\n registerApiRoutes(app, { renderModule, apiModule, manifest })\n registerSsrRoute(app, { renderModule, apiModule, manifest, loaderTimeout: runtimeConfig!.loaderTimeout })\n}\n\nserve({ fetch: app.fetch, port, hostname: host }, (info) => console.log(`http://${info.address}:${info.port}`))\n\nexport { }", "import type {Hono} from 'hono'\nimport type {Manifest} from 'vite'\n\ninterface ServerOptions {\n renderModule: any\n apiModule: any\n manifest?: Manifest\n loaderTimeout?: number\n}\n\nexport function registerApiRoutes(app: Hono, {apiModule, renderModule, loaderTimeout}: ServerOptions) {\n app.all('/api/*', async (c) => {\n try {\n return await apiModule.handleApiRequest(c.req.url, c.req.raw)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n\n app.get('/_data/*', async (c) => {\n try {\n const {pathname, search} = new URL(c.req.url, 'http://localhost')\n const url = pathname.replace(/^\\/_data/, '') + search\n\n const data = await renderModule.runLoader(url, c.req.raw, {loaderTimeout})\n if (data.error) return c.json({error: 'internal error'}, 500)\n if ('loaderError' in data) {\n const {statusCode, message, data: errorData} = data.loaderError\n return c.json({statusCode, message, data: errorData}, statusCode)\n }\n return c.json(data)\n } catch (e) {\n console.error(e)\n return c.json({error: 'internal error'}, 500)\n }\n })\n}\n\nexport function registerSsrRoute(app: Hono, {renderModule, manifest, loaderTimeout}: ServerOptions) {\n app.get('*', async (c) => {\n try {\n const {html, statusCode, headers} = await renderModule.render(c.req.url, c.req.raw, {manifest, loaderTimeout})\n const res = c.html(`<!DOCTYPE html>${html}`, statusCode)\n for (const [key, value] of Object.entries(headers as Record<string, string>)) {\n res.headers.set(key, value)\n }\n return res\n } catch (e) {\n console.error(e)\n return c.text('Internal Server Error', 500)\n }\n })\n}", "import {loadEnv} from 'vite'\n\nexport function loadDotenv(mode: string) {\n const env = loadEnv(mode, process.cwd(), '')\n for (const [key, value] of Object.entries(env)) {\n if (process.env[key] === undefined) {\n process.env[key] = value\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["readFileSync", "serve", "serveStatic", "Hono", "resolve", "join", "registerApiRoutes", "app", "apiModule", "renderModule", "loaderTimeout", "c", "e", "pathname", "search", "url", "data", "statusCode", "message", "errorData", "registerSsrRoute", "manifest", "html", "headers", "res", "key", "value", "loadEnv", "loadDotenv", "mode", "env", "key", "value", "pathToFileURL", "loadDotenv", "renderModule", "apiModule", "manifest", "runtimeConfig", "readFileSync", "join", "resolve", "port", "host", "app", "Hono", "clientRoot", "c", "pathname", "filePath", "data", "serveStatic", "_path", "registerApiRoutes", "registerSsrRoute", "serve", "info"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function
|
|
1
|
+
function g(s){return s.replace(/\.(tsx|ts|jsx|js)$/,"").replace(/\(.*?\)\//g,"").replace(/^index$|\/index$/,"").replace(/\[([^\]]+)]/g,":$1")||"/"}function u(s,l){let c=s.slice(l.length);return g(c)}function h(s,l){let c=s.split("/"),t=[];for(let n=3;n<=c.length-1;n++){let e=c.slice(0,n).join("/"),r=`${e}/layout.tsx`,o=`${e}/layout.ts`;l[r]?t.push(l[r]):l[o]&&t.push(l[o])}return t}function d(s,l){let c=Object.keys(s).filter(t=>!t.split("/").pop().startsWith("layout")).map(t=>{let n=t.slice(0,t.indexOf("/pages/")+6),e=u(t,n),r=[...e.matchAll(/:([^/]+)/g)].map(o=>o[1]);return{file:t,pattern:e,params:r,load:s[t],loadLayouts:h(t,l)}}).sort((t,n)=>{let e=t.pattern.split("/").filter(Boolean),r=n.pattern.split("/").filter(Boolean),o=Math.max(e.length,r.length);for(let a=0;a<o;a++){let p=a<e.length?e[a].startsWith(":")?1:2:0,i=a<r.length?r[a].startsWith(":")?1:2:0;if(p!==i)return i-p}return n.pattern.length-t.pattern.length});return function(n){for(let e of c){let r=e.pattern.replace(/:[^/]+/g,"([^/]+)").replace(/\//g,"\\/"),o=n.match(new RegExp(`^${r}$`));if(o){let a={};return e.params.forEach((p,i)=>{a[p]=decodeURIComponent(o[i+1])}),{load:e.load,loadLayouts:e.loadLayouts,params:a}}}return null}}export{d as createMatcher};
|
|
2
2
|
//# sourceMappingURL=client-router.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/patterns.ts", "../../src/runtime/client-router.ts"],
|
|
4
|
-
"sourcesContent": ["export function routePattern(rel: string): string {\n return rel\n .replace(/\\.(tsx|ts|jsx|js)$/, '')\n .replace(/\\(.*?\\)\\//g, '')\n .replace(/^index$|\\/index$/, '')\n .replace(/\\[([^\\]]+)]/g, ':$1')\n || '/'\n}", "import {ComponentType} from \"react\";\nimport {routePattern} from \"../utils/patterns\";\n\nexport interface ClientMatch {\n load: () => Promise<{ default: ComponentType<any> }>\n loadLayouts: Array<() => Promise<{ default: ComponentType<any> }>>\n params: Record<string, string>\n}\n\ntype GlobMap = Record<string, () => Promise<any>>\n\nfunction fileToRoutePattern(filePath: string, pagesPrefix: string): string {\n const rel = filePath.slice(pagesPrefix.length)\n return routePattern(rel)\n}\n\nfunction collectLayoutChain(pageFile: string, layoutFiles: GlobMap): Array<() => Promise<any>> {\n const parts = pageFile.split('/')\n const chain: Array<() => Promise<any>> = []\n\n for (let i = 3; i <= parts.length - 1; i++) {\n const dir = parts.slice(0, i).join('/')\n const lp = `${dir}/layout.tsx`\n const lpts = `${dir}/layout.ts`\n if (layoutFiles[lp]) {\n chain.push(layoutFiles[lp])\n } else if (layoutFiles[lpts]) {\n chain.push(layoutFiles[lpts])\n }\n }\n\n return chain\n}\n\nexport function createMatcher(pageFiles: GlobMap, layoutFiles: GlobMap) {\n const routes = Object.keys(pageFiles)\n .filter(f => !f.split('/').pop()!.startsWith('layout'))\n .map(file => {\n const pagesPrefix = file.slice(0, file.indexOf('/pages/') + '/pages'.length)\n const pattern = fileToRoutePattern(file, pagesPrefix)\n const params = [...pattern.matchAll(/:([^/]+)/g)].map(m => m[1])\n return { file, pattern, params, load: pageFiles[file], loadLayouts: collectLayoutChain(file,\n layoutFiles) }\n })\n .sort((a, b) => {\n const
|
|
5
|
-
"mappings": "AAAO,SAASA,EAAaC,EAAqB,CAC9C,OAAOA,EACE,QAAQ,qBAAsB,EAAE,EAChC,QAAQ,aAAc,EAAE,EACxB,QAAQ,mBAAoB,EAAE,EAC9B,QAAQ,eAAgB,KAAK,GAC/B,GACX,CCIA,SAASC,EAAmBC,EAAkBC,EAA6B,CACvE,IAAMC,EAAMF,EAAS,MAAMC,EAAY,MAAM,EAC7C,OAAOE,EAAaD,CAAG,CAC3B,CAEA,SAASE,EAAmBC,EAAkBC,EAAiD,CAC3F,IAAMC,EAAQF,EAAS,MAAM,GAAG,EAC1BG,EAAmC,CAAC,EAE1C,QAASC,EAAI,EAAGA,GAAKF,EAAM,OAAS,EAAGE,IAAK,CACxC,IAAMC,EAAMH,EAAM,MAAM,EAAGE,CAAC,EAAE,KAAK,GAAG,EAChCE,EAAK,GAAGD,CAAG,cACXE,EAAO,GAAGF,CAAG,aACfJ,EAAYK,CAAE,EACdH,EAAM,KAAKF,EAAYK,CAAE,CAAC,EACnBL,EAAYM,CAAI,GACvBJ,EAAM,KAAKF,EAAYM,CAAI,CAAC,CAEpC,CAEA,OAAOJ,CACX,CAEO,SAASK,EAAcC,EAAoBR,EAAsB,CACpE,IAAMS,EAAS,OAAO,KAAKD,CAAS,EAC/B,OAAOE,GAAK,CAACA,EAAE,MAAM,GAAG,EAAE,IAAI,EAAG,WAAW,QAAQ,CAAC,EACrD,IAAIC,GAAQ,CACT,IAAMhB,EAAcgB,EAAK,MAAM,EAAGA,EAAK,QAAQ,SAAS,EAAI,CAAe,EACrEC,EAAUnB,EAAmBkB,EAAMhB,CAAW,EAC9CkB,EAAS,CAAC,GAAGD,EAAQ,SAAS,WAAW,CAAC,EAAE,IAAIE,GAAKA,EAAE,CAAC,CAAC,EAC/D,MAAO,CAAE,KAAAH,EAAM,QAAAC,EAAS,OAAAC,EAAQ,KAAML,EAAUG,CAAI,EAAG,YAAab,EAAmBa,EAC/EX,CAAW,CAAE,CACzB,CAAC,EACA,KAAK,CAACe,EAAGC,IAAM,CACZ,IAAMC,
|
|
6
|
-
"names": ["routePattern", "rel", "fileToRoutePattern", "filePath", "pagesPrefix", "rel", "routePattern", "collectLayoutChain", "pageFile", "layoutFiles", "parts", "chain", "i", "dir", "lp", "lpts", "createMatcher", "pageFiles", "routes", "f", "file", "pattern", "params", "m", "a", "b", "
|
|
4
|
+
"sourcesContent": ["export function routePattern(rel: string): string {\n return rel\n .replace(/\\.(tsx|ts|jsx|js)$/, '')\n .replace(/\\(.*?\\)\\//g, '')\n .replace(/^index$|\\/index$/, '')\n .replace(/\\[([^\\]]+)]/g, ':$1')\n || '/'\n}", "import {ComponentType} from \"react\";\nimport {routePattern} from \"../utils/patterns\";\n\nexport interface ClientMatch {\n load: () => Promise<{ default: ComponentType<any> }>\n loadLayouts: Array<() => Promise<{ default: ComponentType<any> }>>\n params: Record<string, string>\n}\n\ntype GlobMap = Record<string, () => Promise<any>>\n\nfunction fileToRoutePattern(filePath: string, pagesPrefix: string): string {\n const rel = filePath.slice(pagesPrefix.length)\n return routePattern(rel)\n}\n\nfunction collectLayoutChain(pageFile: string, layoutFiles: GlobMap): Array<() => Promise<any>> {\n const parts = pageFile.split('/')\n const chain: Array<() => Promise<any>> = []\n\n for (let i = 3; i <= parts.length - 1; i++) {\n const dir = parts.slice(0, i).join('/')\n const lp = `${dir}/layout.tsx`\n const lpts = `${dir}/layout.ts`\n if (layoutFiles[lp]) {\n chain.push(layoutFiles[lp])\n } else if (layoutFiles[lpts]) {\n chain.push(layoutFiles[lpts])\n }\n }\n\n return chain\n}\n\nexport function createMatcher(pageFiles: GlobMap, layoutFiles: GlobMap) {\n const routes = Object.keys(pageFiles)\n .filter(f => !f.split('/').pop()!.startsWith('layout'))\n .map(file => {\n const pagesPrefix = file.slice(0, file.indexOf('/pages/') + '/pages'.length)\n const pattern = fileToRoutePattern(file, pagesPrefix)\n const params = [...pattern.matchAll(/:([^/]+)/g)].map(m => m[1])\n return { file, pattern, params, load: pageFiles[file], loadLayouts: collectLayoutChain(file,\n layoutFiles) }\n })\n .sort((a, b) => {\n const aSegs = a.pattern.split('/').filter(Boolean)\n const bSegs = b.pattern.split('/').filter(Boolean)\n const len = Math.max(aSegs.length, bSegs.length)\n for (let i = 0; i < len; i++) {\n const aVal = i < aSegs.length ? (aSegs[i].startsWith(':') ? 1 : 2) : 0\n const bVal = i < bSegs.length ? (bSegs[i].startsWith(':') ? 1 : 2) : 0\n if (aVal !== bVal) return bVal - aVal\n }\n return b.pattern.length - a.pattern.length\n })\n\n return function matchClientRoute(pathname: string): ClientMatch | null {\n for (const route of routes) {\n const regexStr = route.pattern\n .replace(/:[^/]+/g, '([^/]+)')\n .replace(/\\//g, '\\\\/')\n const match = pathname.match(new RegExp(`^${regexStr}$`))\n\n if (match) {\n const params: Record<string, string> = {}\n route.params.forEach((name, i) => {\n params[name] = decodeURIComponent(match[i + 1])\n })\n return { load: route.load, loadLayouts: route.loadLayouts, params }\n }\n }\n return null\n }\n}"],
|
|
5
|
+
"mappings": "AAAO,SAASA,EAAaC,EAAqB,CAC9C,OAAOA,EACE,QAAQ,qBAAsB,EAAE,EAChC,QAAQ,aAAc,EAAE,EACxB,QAAQ,mBAAoB,EAAE,EAC9B,QAAQ,eAAgB,KAAK,GAC/B,GACX,CCIA,SAASC,EAAmBC,EAAkBC,EAA6B,CACvE,IAAMC,EAAMF,EAAS,MAAMC,EAAY,MAAM,EAC7C,OAAOE,EAAaD,CAAG,CAC3B,CAEA,SAASE,EAAmBC,EAAkBC,EAAiD,CAC3F,IAAMC,EAAQF,EAAS,MAAM,GAAG,EAC1BG,EAAmC,CAAC,EAE1C,QAASC,EAAI,EAAGA,GAAKF,EAAM,OAAS,EAAGE,IAAK,CACxC,IAAMC,EAAMH,EAAM,MAAM,EAAGE,CAAC,EAAE,KAAK,GAAG,EAChCE,EAAK,GAAGD,CAAG,cACXE,EAAO,GAAGF,CAAG,aACfJ,EAAYK,CAAE,EACdH,EAAM,KAAKF,EAAYK,CAAE,CAAC,EACnBL,EAAYM,CAAI,GACvBJ,EAAM,KAAKF,EAAYM,CAAI,CAAC,CAEpC,CAEA,OAAOJ,CACX,CAEO,SAASK,EAAcC,EAAoBR,EAAsB,CACpE,IAAMS,EAAS,OAAO,KAAKD,CAAS,EAC/B,OAAOE,GAAK,CAACA,EAAE,MAAM,GAAG,EAAE,IAAI,EAAG,WAAW,QAAQ,CAAC,EACrD,IAAIC,GAAQ,CACT,IAAMhB,EAAcgB,EAAK,MAAM,EAAGA,EAAK,QAAQ,SAAS,EAAI,CAAe,EACrEC,EAAUnB,EAAmBkB,EAAMhB,CAAW,EAC9CkB,EAAS,CAAC,GAAGD,EAAQ,SAAS,WAAW,CAAC,EAAE,IAAIE,GAAKA,EAAE,CAAC,CAAC,EAC/D,MAAO,CAAE,KAAAH,EAAM,QAAAC,EAAS,OAAAC,EAAQ,KAAML,EAAUG,CAAI,EAAG,YAAab,EAAmBa,EAC/EX,CAAW,CAAE,CACzB,CAAC,EACA,KAAK,CAACe,EAAGC,IAAM,CACZ,IAAMC,EAAQF,EAAE,QAAQ,MAAM,GAAG,EAAE,OAAO,OAAO,EAC3CG,EAAQF,EAAE,QAAQ,MAAM,GAAG,EAAE,OAAO,OAAO,EAC3CG,EAAM,KAAK,IAAIF,EAAM,OAAQC,EAAM,MAAM,EAC/C,QAASf,EAAI,EAAGA,EAAIgB,EAAKhB,IAAK,CAC1B,IAAMiB,EAAOjB,EAAIc,EAAM,OAAUA,EAAMd,CAAC,EAAE,WAAW,GAAG,EAAI,EAAI,EAAK,EAC/DkB,EAAOlB,EAAIe,EAAM,OAAUA,EAAMf,CAAC,EAAE,WAAW,GAAG,EAAI,EAAI,EAAK,EACrE,GAAIiB,IAASC,EAAM,OAAOA,EAAOD,CACrC,CACA,OAAOJ,EAAE,QAAQ,OAASD,EAAE,QAAQ,MACxC,CAAC,EAEL,OAAO,SAA0BO,EAAsC,CACnE,QAAWC,KAASd,EAAQ,CACxB,IAAMe,EAAWD,EAAM,QAClB,QAAQ,UAAW,SAAS,EAC5B,QAAQ,MAAO,KAAK,EACnBE,EAAQH,EAAS,MAAM,IAAI,OAAO,IAAIE,CAAQ,GAAG,CAAC,EAExD,GAAIC,EAAO,CACP,IAAMZ,EAAiC,CAAC,EACxC,OAAAU,EAAM,OAAO,QAAQ,CAACG,EAAM,IAAM,CAC9Bb,EAAOa,CAAI,EAAI,mBAAmBD,EAAM,EAAI,CAAC,CAAC,CAClD,CAAC,EACM,CAAE,KAAMF,EAAM,KAAM,YAAaA,EAAM,YAAa,OAAAV,CAAO,CACtE,CACJ,CACA,OAAO,IACX,CACJ",
|
|
6
|
+
"names": ["routePattern", "rel", "fileToRoutePattern", "filePath", "pagesPrefix", "rel", "routePattern", "collectLayoutChain", "pageFile", "layoutFiles", "parts", "chain", "i", "dir", "lp", "lpts", "createMatcher", "pageFiles", "routes", "f", "file", "pattern", "params", "m", "a", "b", "aSegs", "bSegs", "len", "aVal", "bVal", "pathname", "route", "regexStr", "match", "name"]
|
|
7
7
|
}
|
|
@@ -16,6 +16,7 @@ export interface RouterContextValue {
|
|
|
16
16
|
viewport?: Viewport;
|
|
17
17
|
navigate: (to: string, options?: NavigateOptions) => Promise<void>;
|
|
18
18
|
revalidate: () => Promise<void>;
|
|
19
|
+
prefetchRoute: (href: string) => void;
|
|
19
20
|
isNavigating: boolean;
|
|
20
21
|
}
|
|
21
22
|
export interface PageMetaContextValue {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/runtime/context.tsx"],
|
|
4
|
-
"sourcesContent": ["import {createContext, Context, ComponentType} from \"react\";\nimport {Metadata, Viewport} from \"../types\";\nimport {LayoutProps, PageProps} from \"../server/types\";\n\nexport interface NavigateOptions {\n replace?: boolean\n viewTransition?: boolean\n}\n\nexport interface RouterContextValue {\n pathname: string\n params: Record<string, string>\n loaderData: unknown\n layoutsData: unknown[]\n Page: ComponentType<PageProps>\n layouts: ComponentType<LayoutProps>[]\n metadata: Metadata | null\n viewport?: Viewport\n navigate: (to: string, options?: NavigateOptions) => Promise<void>\n revalidate: () => Promise<void>\n isNavigating: boolean\n}\n\nexport interface PageMetaContextValue {\n metadata: Metadata | null\n viewport?: Viewport\n clientEntry?: string\n}\n\nexport interface RouteDataContextValue {\n loaderData: unknown\n params: Record<string, string>\n}\n\nconst g = globalThis as any\n\ng.__devix_RouterContext__ ??= createContext<RouterContextValue | null>(null)\nexport const RouterContext: Context<RouterContextValue | null> = g.__devix_RouterContext__\n\ng.__devix_PageMetaContext__ ??= createContext<PageMetaContextValue | null>(null)\ng.__devix_RouteDataContext__ ??= createContext<RouteDataContextValue | null>(null)\n\nexport const PageMetaContext: Context<PageMetaContextValue | null> = g.__devix_PageMetaContext__\nexport const RouteDataContext: Context<RouteDataContextValue | null> = g.__devix_RouteDataContext__\n\n"],
|
|
5
|
-
"mappings": "AAAA,OAAQ,iBAAAA,MAA4C,
|
|
4
|
+
"sourcesContent": ["import {createContext, Context, ComponentType} from \"react\";\nimport {Metadata, Viewport} from \"../types\";\nimport {LayoutProps, PageProps} from \"../server/types\";\n\nexport interface NavigateOptions {\n replace?: boolean\n viewTransition?: boolean\n}\n\nexport interface RouterContextValue {\n pathname: string\n params: Record<string, string>\n loaderData: unknown\n layoutsData: unknown[]\n Page: ComponentType<PageProps>\n layouts: ComponentType<LayoutProps>[]\n metadata: Metadata | null\n viewport?: Viewport\n navigate: (to: string, options?: NavigateOptions) => Promise<void>\n revalidate: () => Promise<void>\n prefetchRoute: (href: string) => void\n isNavigating: boolean\n}\n\nexport interface PageMetaContextValue {\n metadata: Metadata | null\n viewport?: Viewport\n clientEntry?: string\n}\n\nexport interface RouteDataContextValue {\n loaderData: unknown\n params: Record<string, string>\n}\n\nconst g = globalThis as any\n\ng.__devix_RouterContext__ ??= createContext<RouterContextValue | null>(null)\nexport const RouterContext: Context<RouterContextValue | null> = g.__devix_RouterContext__\n\ng.__devix_PageMetaContext__ ??= createContext<PageMetaContextValue | null>(null)\ng.__devix_RouteDataContext__ ??= createContext<RouteDataContextValue | null>(null)\n\nexport const PageMetaContext: Context<PageMetaContextValue | null> = g.__devix_PageMetaContext__\nexport const RouteDataContext: Context<RouteDataContextValue | null> = g.__devix_RouteDataContext__\n\n"],
|
|
5
|
+
"mappings": "AAAA,OAAQ,iBAAAA,MAA4C,QAmCpD,IAAMC,EAAI,WAEVA,EAAE,0BAA4BD,EAAyC,IAAI,EACpE,IAAME,EAAoDD,EAAE,wBAEnEA,EAAE,4BAA8BD,EAA2C,IAAI,EAC/EC,EAAE,6BAA+BD,EAA4C,IAAI,EAE1E,IAAMG,EAAwDF,EAAE,0BAC1DG,EAA0DH,EAAE",
|
|
6
6
|
"names": ["createContext", "g", "RouterContext", "PageMetaContext", "RouteDataContext"]
|
|
7
7
|
}
|
package/dist/runtime/fetch.d.ts
CHANGED
|
@@ -1,39 +1,8 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
|
|
4
|
-
type ApiKey<M extends HttpMethod, P extends string> = `${M} ${P}`;
|
|
5
|
-
type RouteData<M extends HttpMethod, P extends string> = ApiKey<M, P> extends keyof ApiRoutes ? ApiRoutes[ApiKey<M, P>] : unknown;
|
|
6
|
-
type AllApiPaths = {
|
|
7
|
-
[K in keyof ApiRoutes]: K extends `${HttpMethod} ${infer P}` ? P : never;
|
|
8
|
-
}[keyof ApiRoutes];
|
|
9
|
-
type ApiPath = [AllApiPaths] extends [never] ? string : AllApiPaths | (string & {});
|
|
10
|
-
type ExtractBody<D> = D extends {
|
|
11
|
-
__body: infer B;
|
|
12
|
-
} ? B : never;
|
|
13
|
-
type UnwrapReturn<R> = R extends {
|
|
14
|
-
__body: infer B;
|
|
15
|
-
} ? B : R extends void | undefined ? never : R;
|
|
16
|
-
type ExtractResponse<D> = D extends {
|
|
17
|
-
__return: infer R;
|
|
18
|
-
} ? UnwrapReturn<R> : D extends {
|
|
19
|
-
__response: infer R;
|
|
20
|
-
} ? R : D;
|
|
21
|
-
type InferBody<M extends HttpMethod, P extends string> = ExtractBody<RouteData<M, P>>;
|
|
22
|
-
type InferResult<M extends HttpMethod, P extends string> = ExtractResponse<RouteData<M, P>>;
|
|
23
|
-
type BodyOption<M extends HttpMethod, P extends string> = [
|
|
24
|
-
InferBody<M, P>
|
|
25
|
-
] extends [never] ? unknown : InferBody<M, P>;
|
|
26
|
-
export interface FetchOptions<M extends HttpMethod = 'GET', P extends string = string> {
|
|
27
|
-
method?: M;
|
|
28
|
-
body?: BodyOption<M, P>;
|
|
29
|
-
headers?: HeadersInit;
|
|
30
|
-
signal?: AbortSignal;
|
|
31
|
-
}
|
|
32
|
-
export declare class FetchError extends Error {
|
|
1
|
+
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
|
|
2
|
+
export declare class FetchError<E = unknown> extends Error {
|
|
33
3
|
readonly status: number;
|
|
34
4
|
readonly statusText: string;
|
|
35
5
|
readonly response: Response;
|
|
36
|
-
|
|
6
|
+
readonly body?: E | undefined;
|
|
7
|
+
constructor(status: number, statusText: string, response: Response, body?: E | undefined);
|
|
37
8
|
}
|
|
38
|
-
export declare function $fetch<P extends ApiPath = ApiPath, M extends HttpMethod = 'GET'>(path: P, options?: FetchOptions<M, P>): Promise<InferResult<M, P>>;
|
|
39
|
-
export {};
|
package/dist/runtime/fetch.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var e=class extends Error{constructor(r,n,s,t){super(`HTTP ${r}: ${n}`);this.status=r;this.statusText=n;this.response=s;this.body=t;this.name="FetchError"}};export{e as FetchError};
|
|
2
2
|
//# sourceMappingURL=fetch.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/runtime/fetch.ts"],
|
|
4
|
-
"sourcesContent": ["export
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["FetchError", "status", "statusText", "response", "
|
|
4
|
+
"sourcesContent": ["export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'\n\nexport class FetchError<E = unknown> extends Error {\n constructor(\n public readonly status: number,\n public readonly statusText: string,\n public readonly response: Response,\n public readonly body?: E,\n ) {\n super(`HTTP ${status}: ${statusText}`)\n this.name = 'FetchError'\n }\n}\n"],
|
|
5
|
+
"mappings": "AAEO,IAAMA,EAAN,cAAsC,KAAM,CAC/C,YACoBC,EACAC,EACAC,EACAC,EAClB,CACE,MAAM,QAAQH,CAAM,KAAKC,CAAU,EAAE,EALrB,YAAAD,EACA,gBAAAC,EACA,cAAAC,EACA,UAAAC,EAGhB,KAAK,KAAO,YAChB,CACJ",
|
|
6
|
+
"names": ["FetchError", "status", "statusText", "response", "body"]
|
|
7
7
|
}
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -6,9 +6,37 @@ export type { PageProps, LayoutProps, PageModule, LayoutModule, ErrorProps } fro
|
|
|
6
6
|
export type { RouteHandler, RouteResult } from './api-context';
|
|
7
7
|
export { getCookie, setCookie, deleteCookie } from '../utils/cookies';
|
|
8
8
|
export type { CookieOptions } from '../utils/cookies';
|
|
9
|
-
export { json, text, redirect } from '../utils/response';
|
|
10
|
-
export type { JsonResponse, Redirect, RedirectOptions } from '../utils/response';
|
|
11
|
-
export { $fetch, FetchError } from './fetch';
|
|
12
|
-
export type { ApiRoutes, FetchOptions } from './fetch';
|
|
9
|
+
export { json, text, redirect, error } from '../utils/response';
|
|
10
|
+
export type { JsonResponse, Redirect, RedirectOptions, RouteError } from '../utils/response';
|
|
13
11
|
export { createHandler } from './create-handler';
|
|
14
12
|
export type { DevixHandler } from './create-handler';
|
|
13
|
+
export { FetchError } from './fetch';
|
|
14
|
+
export type { HttpMethod } from './fetch';
|
|
15
|
+
import { type HttpMethod } from './fetch';
|
|
16
|
+
export interface ApiRoutes {
|
|
17
|
+
}
|
|
18
|
+
type ApiKey<M extends HttpMethod, P extends string> = `${M} ${P}`;
|
|
19
|
+
type MatchingKey<M extends HttpMethod, P extends string> = {
|
|
20
|
+
[K in keyof ApiRoutes]: K extends ApiKey<M, P> ? K : never;
|
|
21
|
+
}[keyof ApiRoutes];
|
|
22
|
+
type RouteData<M extends HttpMethod, P extends string> = ApiRoutes[MatchingKey<M, P>];
|
|
23
|
+
type AllApiPaths = {
|
|
24
|
+
[K in keyof ApiRoutes]: K extends `${HttpMethod} ${infer P}` ? P : never;
|
|
25
|
+
}[keyof ApiRoutes];
|
|
26
|
+
type ApiPath = AllApiPaths | (string & {});
|
|
27
|
+
type ExtractBody<D> = D extends {
|
|
28
|
+
__body: infer B;
|
|
29
|
+
} ? B : never;
|
|
30
|
+
type ExtractResponse<D> = D extends {
|
|
31
|
+
__response: infer R;
|
|
32
|
+
} ? R : D;
|
|
33
|
+
type InferBody<M extends HttpMethod, P extends string> = ExtractBody<RouteData<M, P>>;
|
|
34
|
+
type InferResult<M extends HttpMethod, P extends string> = ExtractResponse<RouteData<M, P>>;
|
|
35
|
+
type BodyOption<M extends HttpMethod, P extends string> = [InferBody<M, P>] extends [never] ? unknown : InferBody<M, P>;
|
|
36
|
+
export interface FetchOptions<M extends HttpMethod = 'GET', P extends string = string> {
|
|
37
|
+
method?: M;
|
|
38
|
+
body?: BodyOption<M, P>;
|
|
39
|
+
headers?: HeadersInit;
|
|
40
|
+
signal?: AbortSignal;
|
|
41
|
+
}
|
|
42
|
+
export declare function $fetch<P extends ApiPath = ApiPath, M extends HttpMethod = 'GET'>(path: P & string, options?: FetchOptions<M, P>): Promise<InferResult<M, P>>;
|
package/dist/runtime/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useCallback as B,useContext as v,useEffect as ee,useRef as te,useState as U}from"react";import{RouterContext as b}from"virtual:devix/context";import{getDefaultErrorPage as z,loadErrorPage as G,matchClientRoute as re}from"virtual:devix/client-routes";import{Fragment as F,jsx as P}from"react/jsx-runtime";function X(e,t){let r=[];e.title&&r.push({tag:"title",children:e.title}),e.description&&r.push({tag:"meta",name:"description",content:e.description}),e.keywords?.length&&r.push({tag:"meta",name:"keywords",content:e.keywords.join(", ")});let o=e.og?.title??e.title;o&&r.push({tag:"meta",property:"og:title",content:o});let a=e.og?.description??e.description;a&&r.push({tag:"meta",property:"og:description",content:a}),e.og?.image&&r.push({tag:"meta",property:"og:image",content:e.og.image}),e.og?.type&&r.push({tag:"meta",property:"og:type",content:e.og.type}),e.og?.url&&r.push({tag:"meta",property:"og:url",content:e.og.url});let s=e.twitter?.title??e.title;s&&r.push({tag:"meta",name:"twitter:title",content:s});let h=e.twitter?.description??e.description;if(h&&r.push({tag:"meta",name:"twitter:description",content:h}),e.twitter?.card&&r.push({tag:"meta",name:"twitter:card",content:e.twitter.card}),e.twitter?.image&&r.push({tag:"meta",name:"twitter:image",content:e.twitter.image}),e.twitter?.creator&&r.push({tag:"meta",name:"twitter:creator",content:e.twitter.creator}),e.canonical&&r.push({tag:"link",rel:"canonical",href:e.canonical}),e.robots&&r.push({tag:"meta",name:"robots",content:e.robots}),e.alternates)for(let[c,d]of Object.entries(e.alternates))r.push({tag:"link",rel:"alternate",href:d,hrefLang:c});if(e.icons){let c=Array.isArray(e.icons)?e.icons:[e.icons];for(let d of c){let f=typeof d=="string"?{href:d}:d;r.push({tag:"link",rel:f.rel??"icon",href:f.href,...f.type&&{type:f.type},...f.sizes&&{sizes:f.sizes}})}}if(t){let c=[];t.width!==void 0&&c.push(`width=${t.width}`),t.initialScale!==void 0&&c.push(`initial-scale=${t.initialScale}`),t.maximumScale!==void 0&&c.push(`maximum-scale=${t.maximumScale}`),t.userScalable!==void 0&&c.push(`user-scalable=${t.userScalable?"yes":"no"}`),c.length&&r.push({tag:"meta",name:"viewport",content:c.join(", ")}),t.themeColor&&r.push({tag:"meta",name:"theme-color",content:t.themeColor})}return r}function O({metadata:e,viewport:t}){return typeof window>"u"||!e?null:P(F,{children:Y(e,t)})}function Y(e,t){let r=X(e,t);return P(F,{children:r.map((o,a)=>o.tag==="title"?P("title",{children:o.children},a):o.tag==="link"?P("link",{rel:o.rel,href:o.href,hrefLang:o.hrefLang,type:o.type,sizes:o.sizes},a):P("meta",{name:o.name,property:o.property,content:o.content},a))})}import{createContext as H}from"react";var w=globalThis;w.__devix_RouterContext__??=H(null);var Le=w.__devix_RouterContext__;w.__devix_PageMetaContext__??=H(null);w.__devix_RouteDataContext__??=H(null);var j=w.__devix_PageMetaContext__,C=w.__devix_RouteDataContext__;import{Component as Z}from"react";import{jsx as K}from"react/jsx-runtime";var D=class extends Z{state={error:null};static getDerivedStateFromError(t){return t instanceof N?{error:{statusCode:t.statusCode,message:t.message}}:{error:{statusCode:500,message:t instanceof Error?t.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?K(this.props.ErrorPage,{...this.state.error}):this.state.error?K("h1",{children:this.state.error.statusCode}):this.props.children}},N=class extends Error{statusCode;constructor(t,r){super(r),this.statusCode=t}};import{jsx as y,jsxs as ue}from"react/jsx-runtime";function oe(){return v(b)}var ne=()=>Promise.resolve(),ae=()=>Promise.resolve();function ie(){return v(b)?.navigate??ne}function se(){return v(b)?.revalidate??ae}function pe(){let e=v(C);if(!e)throw new Error("useParams must be used within a route or layout");return e.params}function le(){let e=v(C);if(!e)throw new Error("useLoaderData must be used within a route or layout");return e.loaderData}function de({initialData:e,initialParams:t,initialPage:r,initialLayouts:o=[],initialLayoutsData:a=[],initialMeta:s,initialViewport:h,initialError:c,initialErrorPage:d,clientEntry:f}){let[n,T]=U({pathname:window.location.pathname,params:t,loaderData:e,layoutsData:a,Page:r,layouts:o,metadata:s??null,viewport:h,pendingError:c,ErrorPage:d}),E=te(null),[q,V]=U(!1),R=B(async(p,l)=>{let u=p.split("?")[0].split("#")[0],i=re(u);if(!i){let m=await G()??z();T(S=>({...S,pathname:u,pendingError:{statusCode:404,message:"Not found"},ErrorPage:m??void 0}));return}let[x,...L]=await Promise.all([i.load(),...i.loadLayouts.map(m=>m())]);if(l.signal.aborted||!x.default)return;let M=await fetch(`/_data${p}`,{headers:{Accept:"application/json"},signal:l.signal});if(l.signal.aborted)return;if(!M.ok){if(M.status===404){window.location.href=p;return}let m=await G()??z();T(S=>({...S,pathname:u,pendingError:{statusCode:M.status,message:"Server error"},ErrorPage:m??void 0}));return}let g=await M.json();if(g.redirect){g.redirectReplace?window.history.replaceState(null,"",g.redirect):window.history.pushState(null,"",g.redirect),await R(g.redirect,l);return}T({pathname:u,params:g.params??{},loaderData:g.loaderData,layoutsData:(g.layouts??[]).map(m=>m.loaderData),Page:x.default,layouts:L.map(m=>m.default),metadata:g.metadata??null,viewport:g.viewport});let $=p.includes("#")?p.split("#")[1]:null,I=getComputedStyle(document.documentElement).scrollBehavior;$?requestAnimationFrame(()=>{document.getElementById($)?.scrollIntoView({behavior:I})}):window.scrollTo({top:0,behavior:I})},[]),_=B(async(p,l)=>{E.current?.abort();let u=new AbortController;E.current=u,V(!0);let i=async()=>{window.history[l?.replace?"replaceState":"pushState"](null,"",p),await R(p,u)};try{l?.viewTransition&&"startViewTransition"in document?await document.startViewTransition(i).finished:await i()}finally{u.signal.aborted||V(!1)}},[R]),Q=B(async()=>{let p=window.location.pathname+window.location.search,l=new AbortController,u=await fetch(`/_data${p}`,{headers:{Accept:"application/json"},signal:l.signal});if(!u.ok)return;let i=await u.json();if(i.redirect){await _(i.redirect,{replace:i.redirectReplace});return}T(x=>({...x,loaderData:i.loaderData,layoutsData:(i.layouts??[]).map(L=>L.loaderData),params:i.params??x.params,metadata:i.metadata??x.metadata,viewport:i.viewport??x.viewport}))},[_]);ee(()=>{let p=()=>{E.current?.abort();let l=new AbortController;E.current=l;let u=window.location.pathname+window.location.search;R(u,l).catch(i=>{i.name!=="AbortError"&&console.error("[router] popstate error:",i)})};return window.addEventListener("popstate",p),()=>window.removeEventListener("popstate",p)},[R]);let A;if(n.pendingError)A=n.ErrorPage?y(n.ErrorPage,{...n.pendingError}):y("h1",{children:n.pendingError.statusCode});else{let p=y(C,{value:{loaderData:n.loaderData,params:n.params},children:y(n.Page,{data:n.loaderData,params:n.params,url:n.pathname})});for(let l=n.layouts.length-1;l>=0;l--){let u=n.layouts[l],i=n.layoutsData[l];p=y(C,{value:{loaderData:i,params:n.params},children:y(u,{data:i,params:n.params,children:p})})}A=y(D,{ErrorPage:n.ErrorPage,children:p},n.pathname)}return ue(j,{value:{metadata:n.metadata,viewport:n.viewport,clientEntry:f},children:[y(O,{metadata:n.metadata,viewport:n.viewport}),y(b,{value:{...n,isNavigating:q,navigate:_,revalidate:Q},children:A})]})}import{useCallback as ce,useContext as fe}from"react";import{matchClientRoute as ge}from"virtual:devix/client-routes";import{RouterContext as me}from"virtual:devix/context";import{jsx as he}from"react/jsx-runtime";function J(e){if(e.startsWith("/")||e.startsWith("http"))return e;let t=window.location.pathname.endsWith("/")?window.location.href:window.location.href+"/",r=new URL(e,t).pathname;return r.length>1?r.replace(/\/$/,""):r}function ye({href:e,prefetch:t=!1,viewTransition:r=!1,children:o,...a}){let s=fe(me),h=ce(()=>{if(!t)return;let d=J(e),f=d.split("?")[0].split("#")[0],n=ge(f);n&&(n.load().catch(()=>{}),fetch(`/_data${d}`,{headers:{Accept:"application/json"}}).catch(()=>{}))},[e,t]);return he("a",{href:e,onClick:d=>{if(s&&!d.ctrlKey&&!d.metaKey&&!d.shiftKey&&d.button===0){d.preventDefault();let f=J(e);r&&typeof document.startViewTransition=="function"?document.startViewTransition(()=>s.navigate(f)):s.navigate(f)}},onMouseEnter:h,...a,children:o})}function xe(e,t){let r=e.headers.get("cookie");if(r)for(let o of r.split(";")){let[a,...s]=o.trim().split("=");if(a.trim()===t)return decodeURIComponent(s.join("="))}}function W(e,t,r,o={}){let a=`${t}=${encodeURIComponent(r)}; Path=${o.path??"/"}`;o.domain&&(a+=`; Domain=${o.domain}`),o.maxAge!==void 0&&(a+=`; Max-Age=${o.maxAge}`),o.expires&&(a+=`; Expires=${o.expires.toUTCString()}`),o.httpOnly&&(a+="; HttpOnly"),o.secure&&(a+="; Secure"),o.sameSite&&(a+=`; SameSite=${o.sameSite}`),e.append("Set-Cookie",a)}function we(e,t,r={}){W(e,t,"",{...r,maxAge:0,expires:new Date(0)})}var Re=(e,t=200)=>new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}}),Pe=(e,t=200)=>new Response(e,{status:t,headers:{"Content-Type":"text/plain; charset=utf-8"}}),Ce=Symbol("devix.redirect");function ve(e,t){let r=typeof t=="number"?t:t?.status??302,o=typeof t=="object"?t?.replace??!1:!1;return{[Ce]:!0,url:e,status:r,replace:o}}var k=class extends Error{constructor(r,o,a){super(`HTTP ${r}: ${o}`);this.status=r;this.statusText=o;this.response=a;this.name="FetchError"}};async function Te(e,t){let r=t?.method??"GET",o=new Headers(t?.headers),a;t?.body!==void 0&&(a=JSON.stringify(t.body),o.has("Content-Type")||o.set("Content-Type","application/json"));let s=await fetch(e,{method:r,headers:o,body:a,signal:t?.signal});if(!s.ok)throw new k(s.status,s.statusText,s);return(s.headers.get("Content-Type")??"").includes("application/json")?s.json():s.text()}var Ee="__devix_handler__";function Me(e){return{[Ee]:!0,fn:e}}export{Te as $fetch,k as FetchError,ye as Link,de as RouterProvider,Me as createHandler,we as deleteCookie,xe as getCookie,Re as json,ve as redirect,W as setCookie,Pe as text,le as useLoaderData,ie as useNavigate,pe as useParams,se as useRevalidate,oe as useRouter};
|
|
1
|
+
import{useCallback as $,useContext as S,useEffect as ge,useRef as ee,useState as te}from"react";import{RouterContext as j}from"virtual:devix/context";import{getDefaultErrorPage as re,loadErrorPage as ne,matchClientRoute as oe}from"virtual:devix/client-routes";import{Fragment as Q,jsx as _}from"react/jsx-runtime";function ce(e,t){let r=[];e.title&&r.push({tag:"title",children:e.title}),e.description&&r.push({tag:"meta",name:"description",content:e.description}),e.keywords?.length&&r.push({tag:"meta",name:"keywords",content:e.keywords.join(", ")});let n=e.og?.title??e.title;n&&r.push({tag:"meta",property:"og:title",content:n});let o=e.og?.description??e.description;o&&r.push({tag:"meta",property:"og:description",content:o}),e.og?.image&&r.push({tag:"meta",property:"og:image",content:e.og.image}),e.og?.type&&r.push({tag:"meta",property:"og:type",content:e.og.type}),e.og?.url&&r.push({tag:"meta",property:"og:url",content:e.og.url});let l=e.twitter?.title??e.title;l&&r.push({tag:"meta",name:"twitter:title",content:l});let y=e.twitter?.description??e.description;if(y&&r.push({tag:"meta",name:"twitter:description",content:y}),e.twitter?.card&&r.push({tag:"meta",name:"twitter:card",content:e.twitter.card}),e.twitter?.image&&r.push({tag:"meta",name:"twitter:image",content:e.twitter.image}),e.twitter?.creator&&r.push({tag:"meta",name:"twitter:creator",content:e.twitter.creator}),e.canonical&&r.push({tag:"link",rel:"canonical",href:e.canonical}),e.robots&&r.push({tag:"meta",name:"robots",content:e.robots}),e.alternates)for(let[c,d]of Object.entries(e.alternates))r.push({tag:"link",rel:"alternate",href:d,hrefLang:c});if(e.icons){let c=Array.isArray(e.icons)?e.icons:[e.icons];for(let d of c){let g=typeof d=="string"?{href:d}:d;r.push({tag:"link",rel:g.rel??"icon",href:g.href,...g.type&&{type:g.type},...g.sizes&&{sizes:g.sizes}})}}if(t){let c=[];t.width!==void 0&&c.push(`width=${t.width}`),t.initialScale!==void 0&&c.push(`initial-scale=${t.initialScale}`),t.maximumScale!==void 0&&c.push(`maximum-scale=${t.maximumScale}`),t.userScalable!==void 0&&c.push(`user-scalable=${t.userScalable?"yes":"no"}`),c.length&&r.push({tag:"meta",name:"viewport",content:c.join(", ")}),t.themeColor&&r.push({tag:"meta",name:"theme-color",content:t.themeColor})}return r}function q({metadata:e,viewport:t}){return typeof window>"u"||!e?null:_(Q,{children:de(e,t)})}function de(e,t){let r=ce(e,t);return _(Q,{children:r.map((n,o)=>n.tag==="title"?_("title",{children:n.children},o):n.tag==="link"?_("link",{rel:n.rel,href:n.href,hrefLang:n.hrefLang,type:n.type,sizes:n.sizes},o):_("meta",{name:n.name,property:n.property,content:n.content},o))})}import{createContext as J}from"react";var b=globalThis;b.__devix_RouterContext__??=J(null);var X=b.__devix_RouterContext__;b.__devix_PageMetaContext__??=J(null);b.__devix_RouteDataContext__??=J(null);var Y=b.__devix_PageMetaContext__,A=b.__devix_RouteDataContext__;import{Component as fe}from"react";import{jsx as Z}from"react/jsx-runtime";var V=class extends fe{state={error:null};static getDerivedStateFromError(t){return t instanceof z?{error:{statusCode:t.statusCode,message:t.message}}:{error:{statusCode:500,message:t instanceof Error?t.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?Z(this.props.ErrorPage,{...this.state.error}):this.state.error?Z("h1",{children:this.state.error.statusCode}):this.props.children}},z=class extends Error{statusCode;constructor(t,r){super(r),this.statusCode=t}};import{jsx as h,jsxs as Ce}from"react/jsx-runtime";function ye(){return S(j)}var me=()=>Promise.resolve(),he=()=>Promise.resolve();function xe(){return S(j)?.navigate??me}function Re(){return S(j)?.revalidate??he}function we(){let e=S(A);if(!e)throw new Error("useParams must be used within a route or layout");return e.params}function Pe(){let e=S(A);if(!e)throw new Error("useLoaderData must be used within a route or layout");return e.loaderData}function Te({initialData:e,initialParams:t,initialPage:r,initialLayouts:n=[],initialLayoutsData:o=[],initialMeta:l,initialViewport:y,initialError:c,initialErrorPage:d,clientEntry:g}){let[a,C]=te({pathname:window.location.pathname,params:t,loaderData:e,layoutsData:o,Page:r,layouts:n,metadata:l??null,viewport:y,pendingError:c,ErrorPage:d}),E=ee(null),[G,x]=te(!1),P=ee(new Map),se=$(s=>{if(P.current.has(s))return;let p=s.split("?")[0].split("#")[0],u=oe(p);if(!u)return;let i=new AbortController,m=Promise.all([Promise.all([u.load(),...u.loadLayouts.map(R=>R())]),fetch(`/_data${s}`,{headers:{Accept:"application/json"},signal:i.signal})]).then(async([[R,...D],f])=>{if(!f.ok||!R.default)return null;let N=await f.json();return{pageMod:R,layoutMods:D,data:N}}).catch(()=>null),v=setTimeout(()=>{i.abort(),P.current.delete(s)},3e3);m.finally(()=>clearTimeout(v)),P.current.set(s,{promise:m,controller:i})},[]),M=$(async(s,p)=>{let u=s.split("?")[0].split("#")[0],i=oe(u);if(!i){let w=await ne()??re();C(F=>({...F,pathname:u,pendingError:{statusCode:404,message:"Not found"},ErrorPage:w??void 0}));return}let m=P.current.get(s);m&&P.current.delete(s);let v=m?await m.promise:null;if(p.signal.aborted)return;let R,D,f;if(v)({pageMod:R,layoutMods:D,data:f}=v);else{let[[w,...F],T]=await Promise.all([Promise.all([i.load(),...i.loadLayouts.map(B=>B())]),fetch(`/_data${s}`,{headers:{Accept:"application/json"},signal:p.signal})]);if(p.signal.aborted||!w.default)return;if(!T.ok){let B=T.headers.get("Content-Type")??"",k=null;try{B.includes("application/json")?k=await T.json():B.includes("text/plain")&&(k={message:await T.text()})}catch{}let W={};T.headers.forEach((K,ue)=>{W[ue]=K});let pe=await ne()??re();C(K=>({...K,pathname:u,pendingError:{statusCode:k?.statusCode??T.status,message:k?.message??"Server error",data:k?.data,headers:W},ErrorPage:pe??void 0}));return}R=w,D=F,f=await T.json()}if(f.redirect){f.redirectReplace?window.history.replaceState(null,"",f.redirect):window.history.pushState(null,"",f.redirect),await M(f.redirect,p);return}C({pathname:u,params:f.params??{},loaderData:f.loaderData,layoutsData:(f.layouts??[]).map(w=>w.loaderData),Page:R.default,layouts:D.map(w=>w.default),metadata:f.metadata??null,viewport:f.viewport});let N=s.includes("#")?s.split("#")[1]:null,U=getComputedStyle(document.documentElement).scrollBehavior;N?requestAnimationFrame(()=>{document.getElementById(N)?.scrollIntoView({behavior:U})}):window.scrollTo({top:0,behavior:U})},[]),O=$(async(s,p)=>{E.current?.abort();let u=new AbortController;E.current=u,x(!0);let i=async()=>{window.history[p?.replace?"replaceState":"pushState"](null,"",s),await M(s,u)};try{p?.viewTransition&&"startViewTransition"in document?await document.startViewTransition(i).finished:await i()}finally{u.signal.aborted||x(!1)}},[M]),le=$(async()=>{let s=window.location.pathname+window.location.search,p=new AbortController,u=await fetch(`/_data${s}`,{headers:{Accept:"application/json"},signal:p.signal});if(!u.ok)return;let i=await u.json();if(i.redirect){await O(i.redirect,{replace:i.redirectReplace});return}C(m=>({...m,loaderData:i.loaderData,layoutsData:(i.layouts??[]).map(v=>v.loaderData),params:i.params??m.params,metadata:i.metadata??m.metadata,viewport:i.viewport??m.viewport}))},[O]);ge(()=>{let s=()=>{E.current?.abort();let p=new AbortController;E.current=p;let u=window.location.pathname+window.location.search;M(u,p).catch(i=>{i.name!=="AbortError"&&console.error("[router] popstate error:",i)})};return window.addEventListener("popstate",s),()=>window.removeEventListener("popstate",s)},[M]);let I;if(a.pendingError)I=a.ErrorPage?h(a.ErrorPage,{...a.pendingError}):h("h1",{children:a.pendingError.statusCode});else{let s=h(A,{value:{loaderData:a.loaderData,params:a.params},children:h(a.Page,{data:a.loaderData,params:a.params,url:a.pathname})});for(let p=a.layouts.length-1;p>=0;p--){let u=a.layouts[p],i=a.layoutsData[p];s=h(A,{value:{loaderData:i,params:a.params},children:h(u,{data:i,params:a.params,children:s})})}I=h(V,{ErrorPage:a.ErrorPage,children:s},a.pathname)}return Ce(Y,{value:{metadata:a.metadata,viewport:a.viewport,clientEntry:g},children:[h(q,{metadata:a.metadata,viewport:a.viewport}),h(j,{value:{...a,isNavigating:G,navigate:O,revalidate:le,prefetchRoute:se},children:I})]})}import{useCallback as L,useContext as Ee,useRef as ve}from"react";import{jsx as Me}from"react/jsx-runtime";function ae(e){if(e.startsWith("/")||e.startsWith("http"))return e;let t=window.location.pathname.endsWith("/")?window.location.href:window.location.href+"/",r=new URL(e,t).pathname;return r.length>1?r.replace(/\/$/,""):r}function be({href:e,prefetch:t="hover",replace:r=!1,viewTransition:n=!1,children:o,...l}){let y=Ee(X),c=ve(null),d=L(()=>{c.current!==null&&(clearTimeout(c.current),c.current=null)},[]),g=L(()=>{!y||t==="none"||y.prefetchRoute(ae(e))},[e,t,y]),a=L(()=>{t!=="none"&&(c.current=setTimeout(g,50))},[t,g]),C=L(()=>{d()},[d]),E=L(()=>{d(),g()},[d,g]);return Me("a",{href:e,onClick:x=>{if(d(),!!y&&!x.ctrlKey&&!x.metaKey&&!x.shiftKey&&x.button===0){x.preventDefault();let P={replace:r,viewTransition:n};y.navigate(ae(e),P)}},onMouseEnter:a,onMouseLeave:C,onTouchStart:E,...l,children:o})}function De(e,t){let r=e.headers.get("cookie");if(r)for(let n of r.split(";")){let[o,...l]=n.trim().split("=");if(o.trim()===t)return decodeURIComponent(l.join("="))}}function ie(e,t,r,n={}){let o=`${t}=${encodeURIComponent(r)}; Path=${n.path??"/"}`;n.domain&&(o+=`; Domain=${n.domain}`),n.maxAge!==void 0&&(o+=`; Max-Age=${n.maxAge}`),n.expires&&(o+=`; Expires=${n.expires.toUTCString()}`),n.httpOnly&&(o+="; HttpOnly"),n.secure&&(o+="; Secure"),n.sameSite&&(o+=`; SameSite=${n.sameSite}`),e.append("Set-Cookie",o)}function ke(e,t,r={}){ie(e,t,"",{...r,maxAge:0,expires:new Date(0)})}function _e(e,t=200){return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}})}var Ae=(e,t=200)=>new Response(e,{status:t,headers:{"Content-Type":"text/plain; charset=utf-8"}}),Se=Symbol("devix.redirect");function Le(e,t){let r=typeof t=="number"?t:t?.status??302,n=typeof t=="object"?t?.replace??!1:!1;return{[Se]:!0,url:e,status:r,replace:n}}var He=Symbol("devix.loaderError");function Ne(e,t,r){return{[He]:!0,statusCode:e,message:t,data:r}}var Be="__devix_handler__";function Ve(e){return{[Be]:!0,fn:e}}var H=class extends Error{constructor(r,n,o,l){super(`HTTP ${r}: ${n}`);this.status=r;this.statusText=n;this.response=o;this.body=l;this.name="FetchError"}};async function xt(e,t){let r=t?.method??"GET",n=new Headers(t?.headers),o;t?.body!==void 0&&(t.body instanceof FormData||t.body instanceof Blob||t.body instanceof ArrayBuffer?o=t.body:(o=JSON.stringify(t.body),n.has("Content-Type")||n.set("Content-Type","application/json")));let l=await fetch(e,{method:r,headers:n,body:o,signal:t?.signal});if(!l.ok){let d=(l.headers.get("Content-Type")??"").includes("application/json")?await l.json():void 0;throw new H(l.status,l.statusText,l,d)}return(l.headers.get("Content-Type")??"").includes("application/json")?l.json():l.text()}export{xt as $fetch,H as FetchError,be as Link,Te as RouterProvider,Ve as createHandler,ke as deleteCookie,Ne as error,De as getCookie,_e as json,Le as redirect,ie as setCookie,Ae as text,Pe as useLoaderData,xe as useNavigate,we as useParams,Re as useRevalidate,ye as useRouter};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../src/runtime/router-provider.tsx", "../../src/runtime/head.tsx", "../../src/runtime/context.tsx", "../../src/runtime/error-boundary.tsx", "../../src/runtime/link.tsx", "../../src/utils/cookies.ts", "../../src/utils/response.ts", "../../src/runtime/fetch.ts", "../../src/runtime/
|
|
4
|
-
"sourcesContent": ["import { ComponentType, ReactNode, useCallback, useContext, useEffect, useRef, useState } from \"react\";\nimport { RouterContext } from 'virtual:devix/context'\nimport { ErrorProps, LayoutProps, PageProps } from \"../server/types\";\nimport { Metadata, Viewport } from \"../types\";\nimport { getDefaultErrorPage, loadErrorPage, matchClientRoute } from \"virtual:devix/client-routes\";\nimport { HeadSlot } from \"./head\";\nimport { NavigateOptions, PageMetaContext, RouteDataContext } from \"./context\";\nimport { DevixErrorBoundary } from \"./error-boundary\";\nimport type { Redirect } from \"../utils/response\";\n\ninterface RouteState {\n pathname: string\n params: Record<string, string>\n loaderData: unknown\n layoutsData: unknown[]\n Page: ComponentType<PageProps>\n layouts: ComponentType<LayoutProps>[]\n metadata: Metadata | null\n viewport?: Viewport\n pendingError?: ErrorProps\n ErrorPage?: ComponentType<ErrorProps>\n}\n\nexport function useRouter() {\n return useContext(RouterContext)\n}\n\nconst noopNavigate = () => Promise.resolve()\nconst noopRevalidate = () => Promise.resolve()\n\nexport function useNavigate() {\n const ctx = useContext(RouterContext)\n return ctx?.navigate ?? noopNavigate\n}\n\nexport function useRevalidate() {\n const ctx = useContext(RouterContext)\n return ctx?.revalidate ?? noopRevalidate\n}\n\nexport function useParams<T extends Record<string, string>>() {\n const ctx = useContext(RouteDataContext)\n if (!ctx) throw new Error(\"useParams must be used within a route or layout\")\n return ctx.params as T\n}\n\ntype LoaderReturnType<T> = T extends (...args: any[]) => Promise<infer R>\n ? [Exclude<R, Redirect | void | undefined>] extends [never] ? undefined : Exclude<R, Redirect | void | undefined>\n : T extends (...args: any[]) => infer R\n ? [Exclude<R, Redirect | void | undefined>] extends [never] ? undefined : Exclude<R, Redirect | void | undefined>\n : T\n\nexport function useLoaderData<T>() {\n const ctx = useContext(RouteDataContext)\n if (!ctx) throw new Error(\"useLoaderData must be used within a route or layout\")\n return ctx.loaderData as LoaderReturnType<T>\n}\n\n\ninterface RouterProviderProps {\n initialData: unknown\n initialParams: Record<string, string>\n initialPage: ComponentType<PageProps>\n initialLayouts?: ComponentType<LayoutProps>[]\n initialLayoutsData?: unknown[]\n initialMeta?: Metadata | null\n initialViewport?: Viewport\n initialError?: ErrorProps\n initialErrorPage?: ComponentType<ErrorProps>\n clientEntry: string\n}\n\nexport function RouterProvider({\n initialData,\n initialParams,\n initialPage,\n initialLayouts = [],\n initialLayoutsData = [],\n initialMeta,\n initialViewport,\n initialError,\n initialErrorPage,\n clientEntry,\n}: RouterProviderProps) {\n\n const [state, setState] = useState<RouteState>({\n pathname: window.location.pathname,\n params: initialParams,\n loaderData: initialData,\n layoutsData: initialLayoutsData,\n Page: initialPage,\n layouts: initialLayouts,\n metadata: initialMeta ?? null,\n viewport: initialViewport,\n pendingError: initialError,\n ErrorPage: initialErrorPage,\n })\n\n const navigatingRef = useRef<AbortController | null>(null)\n const [isNavigating, setIsNavigating] = useState(false)\n\n const loadRoute = useCallback(async (to: string, controller: AbortController) => {\n const pathname = to.split('?')[0].split('#')[0]\n const matched = matchClientRoute(pathname)\n if (!matched) {\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n setState(prev => ({\n ...prev,\n pathname: pathname,\n pendingError: { statusCode: 404, message: 'Not found' },\n ErrorPage: ErrorPage ?? undefined,\n }))\n return\n }\n\n const [pageMod, ...layoutMods] = await Promise.all([\n matched.load(),\n ...matched.loadLayouts.map(l => l()),\n ])\n\n if (controller.signal.aborted) return\n if (!pageMod.default) return\n\n const dataRes = await fetch(`/_data${to}`, {\n headers: { Accept: 'application/json' },\n signal: controller.signal,\n })\n\n if (controller.signal.aborted) return\n\n if (!dataRes.ok) {\n if (dataRes.status === 404) {\n window.location.href = to\n return\n }\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n setState(prev => ({\n ...prev,\n pathname,\n pendingError: { statusCode: dataRes.status, message: 'Server error' },\n ErrorPage: ErrorPage ?? undefined,\n }))\n return\n }\n\n const data = await dataRes.json()\n\n if (data.redirect) {\n if (data.redirectReplace) {\n window.history.replaceState(null, '', data.redirect)\n } else {\n window.history.pushState(null, '', data.redirect)\n }\n await loadRoute(data.redirect, controller)\n return\n }\n\n setState({\n pathname,\n params: data.params ?? {},\n loaderData: data.loaderData,\n layoutsData: (data.layouts ?? []).map((l: any) => l.loaderData),\n Page: pageMod.default,\n layouts: layoutMods.map(m => m.default),\n metadata: data.metadata ?? null,\n viewport: data.viewport,\n })\n\n const hash = to.includes('#') ? to.split('#')[1] : null\n const scrollBehavior = getComputedStyle(document.documentElement).scrollBehavior as ScrollBehavior\n if (hash) {\n requestAnimationFrame(() => {\n document.getElementById(hash)?.scrollIntoView({ behavior: scrollBehavior })\n })\n } else {\n window.scrollTo({ top: 0, behavior: scrollBehavior })\n }\n }, [])\n\n const navigate = useCallback(async (to: string, options?: NavigateOptions) => {\n navigatingRef.current?.abort()\n const controller = new AbortController()\n navigatingRef.current = controller\n\n setIsNavigating(true)\n const run = async () => {\n window.history[options?.replace ? 'replaceState' : 'pushState'](null, '', to)\n await loadRoute(to, controller)\n }\n try {\n if (options?.viewTransition && 'startViewTransition' in document) {\n await (document as any).startViewTransition(run).finished\n } else {\n await run()\n }\n } finally {\n if (!controller.signal.aborted) setIsNavigating(false)\n }\n }, [loadRoute])\n\n const revalidate = useCallback(async () => {\n const to = window.location.pathname + window.location.search\n const controller = new AbortController()\n const dataRes = await fetch(`/_data${to}`, {\n headers: { Accept: 'application/json' },\n signal: controller.signal,\n })\n if (!dataRes.ok) return\n const data = await dataRes.json()\n if (data.redirect) {\n await navigate(data.redirect, { replace: data.redirectReplace })\n return\n }\n setState(prev => ({\n ...prev,\n loaderData: data.loaderData,\n layoutsData: (data.layouts ?? []).map((l: any) => l.loaderData),\n params: data.params ?? prev.params,\n metadata: data.metadata ?? prev.metadata,\n viewport: data.viewport ?? prev.viewport,\n }))\n }, [navigate])\n\n useEffect(() => {\n const handlePop = () => {\n navigatingRef.current?.abort()\n const controller = new AbortController()\n navigatingRef.current = controller\n\n const to = window.location.pathname + window.location.search\n loadRoute(to, controller).catch(err => {\n if (err.name !== 'AbortError') console.error('[router] popstate error:', err)\n })\n }\n window.addEventListener(\"popstate\", handlePop)\n return () => window.removeEventListener(\"popstate\", handlePop)\n }, [loadRoute])\n\n let content: ReactNode\n\n if (state.pendingError) {\n content = state.ErrorPage\n ? <state.ErrorPage {...state.pendingError} />\n : <h1>{state.pendingError.statusCode}</h1>\n } else {\n let tree: ReactNode = (\n <RouteDataContext value={{ loaderData: state.loaderData, params: state.params }}>\n <state.Page data={state.loaderData} params={state.params} url={state.pathname} />\n </RouteDataContext>\n )\n\n for (let i = state.layouts.length - 1; i >= 0; i--) {\n const Layout = state.layouts[i]\n const layoutData = state.layoutsData[i]\n tree = (\n <RouteDataContext value={{ loaderData: layoutData, params: state.params }}>\n <Layout data={layoutData} params={state.params}>{tree}</Layout>\n </RouteDataContext>\n )\n }\n\n content = (\n <DevixErrorBoundary key={state.pathname} ErrorPage={state.ErrorPage}>\n {tree}\n </DevixErrorBoundary>\n )\n }\n\n return (\n <PageMetaContext value={{\n metadata: state.metadata,\n viewport: state.viewport,\n clientEntry,\n }}>\n <HeadSlot metadata={state.metadata} viewport={state.viewport} />\n <RouterContext value={{ ...state, isNavigating, navigate, revalidate }}>\n {content}\n </RouterContext>\n </PageMetaContext>\n )\n}", "import { Metadata, MetadataIcon, Viewport } from \"../types\";\nimport { ReactNode } from \"react\";\n\ntype MetaTag =\n | { tag: 'title'; children: string }\n | { tag: 'meta'; name?: string; property?: string; content: string }\n | { tag: 'link'; rel: string; href: string; hrefLang?: string; type?: string; sizes?: string }\n\nfunction collectTags(metadata: Metadata, viewport?: Viewport): MetaTag[] {\n const tags: MetaTag[] = []\n\n if (metadata.title)\n tags.push({ tag: 'title', children: metadata.title })\n if (metadata.description)\n tags.push({ tag: 'meta', name: 'description', content: metadata.description })\n if (metadata.keywords?.length)\n tags.push({ tag: 'meta', name: 'keywords', content: metadata.keywords.join(', ') })\n\n const ogTitle = metadata.og?.title ?? metadata.title\n if (ogTitle) tags.push({ tag: 'meta', property: 'og:title', content: ogTitle })\n const ogDesc = metadata.og?.description ?? metadata.description\n if (ogDesc) tags.push({ tag: 'meta', property: 'og:description', content: ogDesc })\n if (metadata.og?.image) tags.push({ tag: 'meta', property: 'og:image', content: metadata.og.image })\n if (metadata.og?.type) tags.push({ tag: 'meta', property: 'og:type', content: metadata.og.type })\n if (metadata.og?.url) tags.push({ tag: 'meta', property: 'og:url', content: metadata.og.url })\n\n const twTitle = metadata.twitter?.title ?? metadata.title\n if (twTitle) tags.push({ tag: 'meta', name: 'twitter:title', content: twTitle })\n const twDesc = metadata.twitter?.description ?? metadata.description\n if (twDesc) tags.push({ tag: 'meta', name: 'twitter:description', content: twDesc })\n if (metadata.twitter?.card) tags.push({\n tag: 'meta', name: 'twitter:card', content:\n metadata.twitter.card\n })\n if (metadata.twitter?.image) tags.push({\n tag: 'meta', name: 'twitter:image', content:\n metadata.twitter.image\n })\n if (metadata.twitter?.creator) tags.push({\n tag: 'meta', name: 'twitter:creator', content:\n metadata.twitter.creator\n })\n\n if (metadata.canonical) tags.push({ tag: 'link', rel: 'canonical', href: metadata.canonical })\n if (metadata.robots) tags.push({ tag: 'meta', name: 'robots', content: metadata.robots })\n if (metadata.alternates) {\n for (const [lang, href] of Object.entries(metadata.alternates))\n tags.push({ tag: 'link', rel: 'alternate', href, hrefLang: lang })\n }\n\n if (metadata.icons) {\n const raw = Array.isArray(metadata.icons) ? metadata.icons : [metadata.icons]\n for (const icon of raw) {\n const resolved: MetadataIcon = typeof icon === 'string' ? { href: icon } : icon\n tags.push({\n tag: 'link',\n rel: resolved.rel ?? 'icon',\n href: resolved.href,\n ...(resolved.type && { type: resolved.type }),\n ...(resolved.sizes && { sizes: resolved.sizes }),\n })\n }\n }\n\n if (viewport) {\n const parts: string[] = []\n if (viewport.width !== undefined) parts.push(`width=${viewport.width}`)\n if (viewport.initialScale !== undefined) parts.push(`initial-scale=${viewport.initialScale}`)\n if (viewport.maximumScale !== undefined) parts.push(`maximum-scale=${viewport.maximumScale}`)\n if (viewport.userScalable !== undefined) parts.push(`user-scalable=${viewport.userScalable ? 'yes' :\n 'no'}`)\n if (parts.length) tags.push({ tag: 'meta', name: 'viewport', content: parts.join(', ') })\n if (viewport.themeColor) tags.push({\n tag: 'meta', name: 'theme-color', content: viewport.themeColor\n })\n }\n\n return tags\n}\n\nexport function HeadSlot({ metadata, viewport }: { metadata: Metadata | null, viewport?: Viewport }) {\n if (typeof window === 'undefined' || !metadata) return null\n return <>{buildHeadNodes(metadata, viewport)}</>\n}\n\nexport function buildHeadNodes(metadata: Metadata, viewport?: Viewport): ReactNode {\n const tags = collectTags(metadata, viewport)\n\n return <>\n {tags.map((t, i) => {\n if (t.tag === 'title') return <title key={i}>{t.children}</title>\n if (t.tag === 'link') return <link key={i} rel={t.rel} href={t.href} hrefLang={t.hrefLang} type={t.type} sizes={t.sizes} />\n return <meta key={i} name={t.name} property={t.property} content={t.content} />\n })}\n </>\n}", "import {createContext, Context, ComponentType} from \"react\";\nimport {Metadata, Viewport} from \"../types\";\nimport {LayoutProps, PageProps} from \"../server/types\";\n\nexport interface NavigateOptions {\n replace?: boolean\n viewTransition?: boolean\n}\n\nexport interface RouterContextValue {\n pathname: string\n params: Record<string, string>\n loaderData: unknown\n layoutsData: unknown[]\n Page: ComponentType<PageProps>\n layouts: ComponentType<LayoutProps>[]\n metadata: Metadata | null\n viewport?: Viewport\n navigate: (to: string, options?: NavigateOptions) => Promise<void>\n revalidate: () => Promise<void>\n isNavigating: boolean\n}\n\nexport interface PageMetaContextValue {\n metadata: Metadata | null\n viewport?: Viewport\n clientEntry?: string\n}\n\nexport interface RouteDataContextValue {\n loaderData: unknown\n params: Record<string, string>\n}\n\nconst g = globalThis as any\n\ng.__devix_RouterContext__ ??= createContext<RouterContextValue | null>(null)\nexport const RouterContext: Context<RouterContextValue | null> = g.__devix_RouterContext__\n\ng.__devix_PageMetaContext__ ??= createContext<PageMetaContextValue | null>(null)\ng.__devix_RouteDataContext__ ??= createContext<RouteDataContextValue | null>(null)\n\nexport const PageMetaContext: Context<PageMetaContextValue | null> = g.__devix_PageMetaContext__\nexport const RouteDataContext: Context<RouteDataContextValue | null> = g.__devix_RouteDataContext__\n\n", "import {Component, ComponentType, ReactNode} from \"react\";\nimport {ErrorProps} from \"../server/types\";\n\ninterface Props {\n ErrorPage?: ComponentType<ErrorProps>\n children: ReactNode\n}\n\ninterface State {\n error: ErrorProps | null\n}\n\nexport class DevixErrorBoundary extends Component<Props, State> {\n state: State = { error: null }\n\n static getDerivedStateFromError(err: unknown): State {\n if (err instanceof DevixError) {\n return {\n error: {statusCode: err.statusCode, message: err.message}\n }\n }\n return {\n error: {statusCode: 500, message: err instanceof Error ? err.message : 'Unknown error'}\n }\n }\n\n render() {\n if (this.state.error && this.props.ErrorPage) {\n return <this.props.ErrorPage {...this.state.error} />\n }\n if (this.state.error) {\n return <h1>{this.state.error.statusCode}</h1>\n }\n return this.props.children\n }\n}\n\nexport class DevixError extends Error {\n statusCode: number\n constructor(statusCode: number, message: string) {\n super(message)\n this.statusCode = statusCode\n }\n}\n", "import {AnchorHTMLAttributes, MouseEventHandler, useCallback, useContext} from \"react\";\nimport {matchClientRoute} from \"virtual:devix/client-routes\";\nimport {RouterContext} from 'virtual:devix/context'\n\ninterface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n href: string\n prefetch?: boolean\n viewTransition?: boolean\n}\n\nfunction resolveHref(href: string): string {\n if (href.startsWith('/') || href.startsWith('http')) return href\n const base = window.location.pathname.endsWith('/')\n ? window.location.href\n : window.location.href + '/'\n const resolved = new URL(href, base).pathname\n return resolved.length > 1 ? resolved.replace(/\\/$/, '') : resolved\n}\n\nexport function Link({ href, prefetch = false, viewTransition = false, children, ...props }: LinkProps) {\n const router = useContext(RouterContext)\n\n const handleMouseEnter = useCallback(() => {\n if (!prefetch) return\n const resolved = resolveHref(href)\n const pathname = resolved.split('?')[0].split('#')[0]\n const matched = matchClientRoute(pathname)\n if (matched) {\n matched.load().catch(() => {})\n fetch(`/_data${resolved}`, { headers: { Accept: 'application/json' } }).catch(() => {})\n }\n }, [href, prefetch])\n\n const handleClick: MouseEventHandler<HTMLAnchorElement> = (e) => {\n if (!router) return\n if (!e.ctrlKey && !e.metaKey && !e.shiftKey && e.button === 0) {\n e.preventDefault()\n const resolved = resolveHref(href)\n if (viewTransition && typeof document.startViewTransition === 'function') {\n document.startViewTransition(() => router.navigate(resolved))\n } else {\n router.navigate(resolved)\n }\n }\n }\n\n return (\n <a href={href} onClick={handleClick} onMouseEnter={handleMouseEnter} {...props}>\n {children}\n </a>\n )\n}", "export interface CookieOptions {\n httpOnly?: boolean\n secure?: boolean\n sameSite?: 'Strict' | 'Lax' | 'None'\n maxAge?: number\n expires?: Date\n path?: string\n domain?: string\n}\n\nexport function getCookie(req: Request, name: string): string | undefined {\n const header = req.headers.get('cookie')\n if (!header) return undefined\n for (const part of header.split(';')) {\n const [key, ...rest] = part.trim().split('=')\n if (key.trim() === name) return decodeURIComponent(rest.join('='))\n }\n return undefined\n}\n\nexport function setCookie(headers: Headers, name: string, value: string, options: CookieOptions = {}): void {\n let cookie = `${name}=${encodeURIComponent(value)}; Path=${options.path ?? '/'}`\n if (options.domain) cookie += `; Domain=${options.domain}`\n if (options.maxAge !== undefined) cookie += `; Max-Age=${options.maxAge}`\n if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`\n if (options.httpOnly) cookie += `; HttpOnly`\n if (options.secure) cookie += `; Secure`\n if (options.sameSite) cookie += `; SameSite=${options.sameSite}`\n headers.append('Set-Cookie', cookie)\n}\n\nexport function deleteCookie(headers: Headers, name: string, options: Pick<CookieOptions, 'path' | 'domain'> = {}): void {\n setCookie(headers, name, '', {...options, maxAge: 0, expires: new Date(0)})\n}\n", "export type JsonResponse<T = unknown> = Response & { readonly __body: T }\n\nexport const json = <const T>(data: T, status = 200): JsonResponse<T> =>\n new Response(JSON.stringify(data), {\n status,\n headers: {'Content-Type': 'application/json'},\n }) as JsonResponse<T>\n\nexport const text = (body: string, status = 200): Response =>\n new Response(body, {status, headers: {'Content-Type': 'text/plain; charset=utf-8'}})\n\nconst REDIRECT_BRAND = Symbol('devix.redirect')\n\nexport interface RedirectOptions {\n status?: number\n replace?: boolean\n}\n\nexport interface Redirect {\n readonly [REDIRECT_BRAND]: true\n readonly url: string\n readonly status: number\n readonly replace: boolean\n}\n\nexport function redirect(url: string, statusOrOptions?: number | RedirectOptions): Redirect {\n const status = typeof statusOrOptions === 'number' ? statusOrOptions : (statusOrOptions?.status ?? 302)\n const replace = typeof statusOrOptions === 'object' ? (statusOrOptions?.replace ?? false) : false\n return {[REDIRECT_BRAND]: true, url, status, replace} as Redirect\n}\n\nexport function isRedirect(value: unknown): value is Redirect {\n return typeof value === 'object' && value !== null && REDIRECT_BRAND in value\n}\n", "export interface ApiRoutes { }\n\ntype HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'\n\ntype ApiKey<M extends HttpMethod, P extends string> = `${M} ${P}`\n\ntype RouteData<M extends HttpMethod, P extends string> =\n ApiKey<M, P> extends keyof ApiRoutes ? ApiRoutes[ApiKey<M, P>] : unknown\n\ntype AllApiPaths = {\n [K in keyof ApiRoutes]: K extends `${HttpMethod} ${infer P}` ? P : never\n}[keyof ApiRoutes]\n\ntype ApiPath = [AllApiPaths] extends [never] ? string : AllApiPaths | (string & {})\n\ntype ExtractBody<D> = D extends { __body: infer B } ? B : never\ntype UnwrapReturn<R> =\n R extends { __body: infer B } ? B\n : R extends void | undefined ? never\n : R\ntype ExtractResponse<D> =\n D extends { __return: infer R } ? UnwrapReturn<R>\n : D extends { __response: infer R } ? R\n : D\n\ntype InferBody<M extends HttpMethod, P extends string> = ExtractBody<RouteData<M, P>>\ntype InferResult<M extends HttpMethod, P extends string> = ExtractResponse<RouteData<M, P>>\n\ntype BodyOption<M extends HttpMethod, P extends string> =\n [InferBody<M, P>] extends [never] ? unknown : InferBody<M, P>\n\nexport interface FetchOptions<M extends HttpMethod = 'GET', P extends string = string> {\n method?: M\n body?: BodyOption<M, P>\n headers?: HeadersInit\n signal?: AbortSignal\n}\n\nexport class FetchError extends Error {\n constructor(\n public readonly status: number,\n public readonly statusText: string,\n public readonly response: Response,\n ) {\n super(`HTTP ${status}: ${statusText}`)\n this.name = 'FetchError'\n }\n}\n\nexport async function $fetch<\n P extends ApiPath = ApiPath,\n M extends HttpMethod = 'GET',\n>(path: P, options?: FetchOptions<M, P>): Promise<InferResult<M, P>> {\n const method = (options?.method ?? 'GET') as string\n const headers = new Headers(options?.headers)\n\n let body: BodyInit | undefined\n if (options?.body !== undefined) {\n body = JSON.stringify(options.body)\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'application/json')\n }\n }\n\n const response = await fetch(path, { method, headers, body, signal: options?.signal })\n\n if (!response.ok) {\n throw new FetchError(response.status, response.statusText, response)\n }\n\n const contentType = response.headers.get('Content-Type') ?? ''\n if (contentType.includes('application/json')) {\n return response.json() as Promise<InferResult<M, P>>\n }\n\n return response.text() as unknown as Promise<InferResult<M, P>>\n}\n", "export const HANDLER_BRAND = '__devix_handler__' as const\n\nexport interface DevixHandler<TBody = undefined, TReturn = unknown> {\n readonly [HANDLER_BRAND]: true\n readonly fn: (...args: any[]) => any\n readonly __body: TBody\n readonly __return: TReturn\n}\n\ntype ExtractBody<TFn> = TFn extends (body: infer B) => any ? B : undefined\n\nexport function createHandler<TFn extends (...args: any[]) => any>(\n fn: TFn,\n): DevixHandler<ExtractBody<TFn>, Awaited<ReturnType<TFn>>> {\n return {[HANDLER_BRAND]: true, fn} as unknown as DevixHandler<ExtractBody<TFn>, Awaited<ReturnType<TFn>>>\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["useCallback", "useContext", "useEffect", "useRef", "useState", "RouterContext", "getDefaultErrorPage", "loadErrorPage", "matchClientRoute", "Fragment", "jsx", "collectTags", "metadata", "viewport", "tags", "ogTitle", "ogDesc", "twTitle", "twDesc", "lang", "href", "raw", "icon", "resolved", "parts", "HeadSlot", "buildHeadNodes", "t", "i", "createContext", "g", "RouterContext", "PageMetaContext", "RouteDataContext", "Component", "jsx", "DevixErrorBoundary", "err", "DevixError", "statusCode", "message", "jsx", "jsxs", "useRouter", "useContext", "RouterContext", "noopNavigate", "noopRevalidate", "useNavigate", "useRevalidate", "useParams", "ctx", "RouteDataContext", "useLoaderData", "RouterProvider", "initialData", "initialParams", "initialPage", "initialLayouts", "initialLayoutsData", "initialMeta", "initialViewport", "initialError", "initialErrorPage", "clientEntry", "state", "setState", "useState", "navigatingRef", "useRef", "isNavigating", "setIsNavigating", "
|
|
3
|
+
"sources": ["../../src/runtime/router-provider.tsx", "../../src/runtime/head.tsx", "../../src/runtime/context.tsx", "../../src/runtime/error-boundary.tsx", "../../src/runtime/link.tsx", "../../src/utils/cookies.ts", "../../src/utils/response.ts", "../../src/runtime/create-handler.ts", "../../src/runtime/fetch.ts", "../../src/runtime/index.ts"],
|
|
4
|
+
"sourcesContent": ["import { ComponentType, ReactNode, useCallback, useContext, useEffect, useRef, useState } from \"react\";\nimport { RouterContext } from 'virtual:devix/context'\nimport { ErrorProps, LayoutProps, PageProps } from \"../server/types\";\nimport { Metadata, Viewport } from \"../types\";\nimport { getDefaultErrorPage, loadErrorPage, matchClientRoute } from \"virtual:devix/client-routes\";\nimport { HeadSlot } from \"./head\";\nimport { NavigateOptions, PageMetaContext, RouteDataContext } from \"./context\";\nimport { DevixErrorBoundary } from \"./error-boundary\";\nimport type { Redirect } from \"../utils/response\";\n\ninterface RouteState {\n pathname: string\n params: Record<string, string>\n loaderData: unknown\n layoutsData: unknown[]\n Page: ComponentType<PageProps>\n layouts: ComponentType<LayoutProps>[]\n metadata: Metadata | null\n viewport?: Viewport\n pendingError?: ErrorProps\n ErrorPage?: ComponentType<ErrorProps>\n}\n\nexport function useRouter() {\n return useContext(RouterContext)\n}\n\nconst noopNavigate = () => Promise.resolve()\nconst noopRevalidate = () => Promise.resolve()\n\nexport function useNavigate() {\n const ctx = useContext(RouterContext)\n return ctx?.navigate ?? noopNavigate\n}\n\nexport function useRevalidate() {\n const ctx = useContext(RouterContext)\n return ctx?.revalidate ?? noopRevalidate\n}\n\nexport function useParams<T extends Record<string, string>>() {\n const ctx = useContext(RouteDataContext)\n if (!ctx) throw new Error(\"useParams must be used within a route or layout\")\n return ctx.params as T\n}\n\ntype LoaderReturnType<T> = T extends (...args: any[]) => Promise<infer R>\n ? [Exclude<R, Redirect | void | undefined>] extends [never] ? undefined : Exclude<R, Redirect | void | undefined>\n : T extends (...args: any[]) => infer R\n ? [Exclude<R, Redirect | void | undefined>] extends [never] ? undefined : Exclude<R, Redirect | void | undefined>\n : T\n\nexport function useLoaderData<T>() {\n const ctx = useContext(RouteDataContext)\n if (!ctx) throw new Error(\"useLoaderData must be used within a route or layout\")\n return ctx.loaderData as LoaderReturnType<T>\n}\n\ninterface PrefetchEntry {\n promise: Promise<{ pageMod: any; layoutMods: any[]; data: any } | null>\n controller: AbortController\n}\n\ninterface RouterProviderProps {\n initialData: unknown\n initialParams: Record<string, string>\n initialPage: ComponentType<PageProps>\n initialLayouts?: ComponentType<LayoutProps>[]\n initialLayoutsData?: unknown[]\n initialMeta?: Metadata | null\n initialViewport?: Viewport\n initialError?: ErrorProps\n initialErrorPage?: ComponentType<ErrorProps>\n clientEntry: string\n}\n\nexport function RouterProvider({\n initialData,\n initialParams,\n initialPage,\n initialLayouts = [],\n initialLayoutsData = [],\n initialMeta,\n initialViewport,\n initialError,\n initialErrorPage,\n clientEntry,\n}: RouterProviderProps) {\n\n const [state, setState] = useState<RouteState>({\n pathname: window.location.pathname,\n params: initialParams,\n loaderData: initialData,\n layoutsData: initialLayoutsData,\n Page: initialPage,\n layouts: initialLayouts,\n metadata: initialMeta ?? null,\n viewport: initialViewport,\n pendingError: initialError,\n ErrorPage: initialErrorPage,\n })\n\n const navigatingRef = useRef<AbortController | null>(null)\n const [isNavigating, setIsNavigating] = useState(false)\n\n const prefetchCacheRef = useRef<Map<string, PrefetchEntry>>(new Map())\n\n const prefetchRoute = useCallback((href: string) => {\n if (prefetchCacheRef.current.has(href)) return\n const pathname = href.split('?')[0].split('#')[0]\n const matched = matchClientRoute(pathname)\n if (!matched) return\n\n const controller = new AbortController()\n const promise = Promise.all([\n Promise.all([matched.load(), ...matched.loadLayouts.map(l => l())]),\n fetch(`/_data${href}`, { headers: { Accept: 'application/json' }, signal: controller.signal })\n ]).then(async ([[pageMod, ...layoutMods], dataRes]) => {\n if (!dataRes.ok || !pageMod.default) return null\n const data = await dataRes.json()\n return { pageMod, layoutMods, data }\n }).catch(() => null)\n\n const expireTimer = setTimeout(() => {\n controller.abort()\n prefetchCacheRef.current.delete(href)\n }, 3000)\n promise.finally(() => clearTimeout(expireTimer))\n\n prefetchCacheRef.current.set(href, { promise, controller })\n }, [])\n\n const loadRoute = useCallback(async (to: string, controller: AbortController) => {\n const pathname = to.split('?')[0].split('#')[0]\n const matched = matchClientRoute(pathname)\n if (!matched) {\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n setState(prev => ({\n ...prev,\n pathname: pathname,\n pendingError: { statusCode: 404, message: 'Not found' },\n ErrorPage: ErrorPage ?? undefined,\n }))\n return\n }\n\n const cached = prefetchCacheRef.current.get(to)\n if (cached) prefetchCacheRef.current.delete(to)\n const prefetched = cached ? await cached.promise : null\n\n if (controller.signal.aborted) return\n\n let pageMod: any, layoutMods: any[], data: any\n\n if (prefetched) {\n ;({ pageMod, layoutMods, data } = prefetched)\n } else {\n const [[pm, ...lm], dataRes] = await Promise.all([\n Promise.all([\n matched.load(),\n ...matched.loadLayouts.map(l => l()),\n ]),\n fetch(`/_data${to}`, {\n headers: { Accept: 'application/json' },\n signal: controller.signal,\n })\n ])\n\n if (controller.signal.aborted) return\n if (!pm.default) return\n\n if (!dataRes.ok) {\n const ct = dataRes.headers.get('Content-Type') ?? ''\n let errorBody: { statusCode?: number; message?: string; data?: unknown } | null = null\n try {\n if (ct.includes('application/json')) errorBody = await dataRes.json()\n else if (ct.includes('text/plain')) errorBody = { message: await dataRes.text() }\n } catch { /* ignorar errores de parsing */ }\n\n const headers: Record<string, string> = {}\n dataRes.headers.forEach((value, key) => { headers[key] = value })\n\n const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage()\n setState(prev => ({\n ...prev,\n pathname,\n pendingError: {\n statusCode: errorBody?.statusCode ?? dataRes.status,\n message: errorBody?.message ?? 'Server error',\n data: errorBody?.data,\n headers,\n },\n ErrorPage: ErrorPage ?? undefined,\n }))\n return\n }\n\n pageMod = pm\n layoutMods = lm\n data = await dataRes.json()\n }\n\n if (data.redirect) {\n if (data.redirectReplace) {\n window.history.replaceState(null, '', data.redirect)\n } else {\n window.history.pushState(null, '', data.redirect)\n }\n await loadRoute(data.redirect, controller)\n return\n }\n\n setState({\n pathname,\n params: data.params ?? {},\n loaderData: data.loaderData,\n layoutsData: (data.layouts ?? []).map((l: any) => l.loaderData),\n Page: pageMod.default,\n layouts: layoutMods.map(m => m.default),\n metadata: data.metadata ?? null,\n viewport: data.viewport,\n })\n\n const hash = to.includes('#') ? to.split('#')[1] : null\n const scrollBehavior = getComputedStyle(document.documentElement).scrollBehavior as ScrollBehavior\n if (hash) {\n requestAnimationFrame(() => {\n document.getElementById(hash)?.scrollIntoView({ behavior: scrollBehavior })\n })\n } else {\n window.scrollTo({ top: 0, behavior: scrollBehavior })\n }\n }, [])\n\n const navigate = useCallback(async (to: string, options?: NavigateOptions) => {\n navigatingRef.current?.abort()\n const controller = new AbortController()\n navigatingRef.current = controller\n\n setIsNavigating(true)\n const run = async () => {\n window.history[options?.replace ? 'replaceState' : 'pushState'](null, '', to)\n await loadRoute(to, controller)\n }\n try {\n if (options?.viewTransition && 'startViewTransition' in document) {\n await (document as any).startViewTransition(run).finished\n } else {\n await run()\n }\n } finally {\n if (!controller.signal.aborted) setIsNavigating(false)\n }\n }, [loadRoute])\n\n const revalidate = useCallback(async () => {\n const to = window.location.pathname + window.location.search\n const controller = new AbortController()\n const dataRes = await fetch(`/_data${to}`, {\n headers: { Accept: 'application/json' },\n signal: controller.signal,\n })\n if (!dataRes.ok) return\n const data = await dataRes.json()\n if (data.redirect) {\n await navigate(data.redirect, { replace: data.redirectReplace })\n return\n }\n setState(prev => ({\n ...prev,\n loaderData: data.loaderData,\n layoutsData: (data.layouts ?? []).map((l: any) => l.loaderData),\n params: data.params ?? prev.params,\n metadata: data.metadata ?? prev.metadata,\n viewport: data.viewport ?? prev.viewport,\n }))\n }, [navigate])\n\n useEffect(() => {\n const handlePop = () => {\n navigatingRef.current?.abort()\n const controller = new AbortController()\n navigatingRef.current = controller\n\n const to = window.location.pathname + window.location.search\n loadRoute(to, controller).catch(err => {\n if (err.name !== 'AbortError') console.error('[router] popstate error:', err)\n })\n }\n window.addEventListener(\"popstate\", handlePop)\n return () => window.removeEventListener(\"popstate\", handlePop)\n }, [loadRoute])\n\n let content: ReactNode\n\n if (state.pendingError) {\n content = state.ErrorPage\n ? <state.ErrorPage {...state.pendingError} />\n : <h1>{state.pendingError.statusCode}</h1>\n } else {\n let tree: ReactNode = (\n <RouteDataContext value={{ loaderData: state.loaderData, params: state.params }}>\n <state.Page data={state.loaderData} params={state.params} url={state.pathname} />\n </RouteDataContext>\n )\n\n for (let i = state.layouts.length - 1; i >= 0; i--) {\n const Layout = state.layouts[i]\n const layoutData = state.layoutsData[i]\n tree = (\n <RouteDataContext value={{ loaderData: layoutData, params: state.params }}>\n <Layout data={layoutData} params={state.params}>{tree}</Layout>\n </RouteDataContext>\n )\n }\n\n content = (\n <DevixErrorBoundary key={state.pathname} ErrorPage={state.ErrorPage}>\n {tree}\n </DevixErrorBoundary>\n )\n }\n\n return (\n <PageMetaContext value={{\n metadata: state.metadata,\n viewport: state.viewport,\n clientEntry,\n }}>\n <HeadSlot metadata={state.metadata} viewport={state.viewport} />\n <RouterContext value={{ ...state, isNavigating, navigate, revalidate, prefetchRoute }}>\n {content}\n </RouterContext>\n </PageMetaContext>\n )\n}", "import { Metadata, MetadataIcon, Viewport } from \"../types\";\nimport { ReactNode } from \"react\";\n\ntype MetaTag =\n | { tag: 'title'; children: string }\n | { tag: 'meta'; name?: string; property?: string; content: string }\n | { tag: 'link'; rel: string; href: string; hrefLang?: string; type?: string; sizes?: string }\n\nfunction collectTags(metadata: Metadata, viewport?: Viewport): MetaTag[] {\n const tags: MetaTag[] = []\n\n if (metadata.title)\n tags.push({ tag: 'title', children: metadata.title })\n if (metadata.description)\n tags.push({ tag: 'meta', name: 'description', content: metadata.description })\n if (metadata.keywords?.length)\n tags.push({ tag: 'meta', name: 'keywords', content: metadata.keywords.join(', ') })\n\n const ogTitle = metadata.og?.title ?? metadata.title\n if (ogTitle) tags.push({ tag: 'meta', property: 'og:title', content: ogTitle })\n const ogDesc = metadata.og?.description ?? metadata.description\n if (ogDesc) tags.push({ tag: 'meta', property: 'og:description', content: ogDesc })\n if (metadata.og?.image) tags.push({ tag: 'meta', property: 'og:image', content: metadata.og.image })\n if (metadata.og?.type) tags.push({ tag: 'meta', property: 'og:type', content: metadata.og.type })\n if (metadata.og?.url) tags.push({ tag: 'meta', property: 'og:url', content: metadata.og.url })\n\n const twTitle = metadata.twitter?.title ?? metadata.title\n if (twTitle) tags.push({ tag: 'meta', name: 'twitter:title', content: twTitle })\n const twDesc = metadata.twitter?.description ?? metadata.description\n if (twDesc) tags.push({ tag: 'meta', name: 'twitter:description', content: twDesc })\n if (metadata.twitter?.card) tags.push({\n tag: 'meta', name: 'twitter:card', content:\n metadata.twitter.card\n })\n if (metadata.twitter?.image) tags.push({\n tag: 'meta', name: 'twitter:image', content:\n metadata.twitter.image\n })\n if (metadata.twitter?.creator) tags.push({\n tag: 'meta', name: 'twitter:creator', content:\n metadata.twitter.creator\n })\n\n if (metadata.canonical) tags.push({ tag: 'link', rel: 'canonical', href: metadata.canonical })\n if (metadata.robots) tags.push({ tag: 'meta', name: 'robots', content: metadata.robots })\n if (metadata.alternates) {\n for (const [lang, href] of Object.entries(metadata.alternates))\n tags.push({ tag: 'link', rel: 'alternate', href, hrefLang: lang })\n }\n\n if (metadata.icons) {\n const raw = Array.isArray(metadata.icons) ? metadata.icons : [metadata.icons]\n for (const icon of raw) {\n const resolved: MetadataIcon = typeof icon === 'string' ? { href: icon } : icon\n tags.push({\n tag: 'link',\n rel: resolved.rel ?? 'icon',\n href: resolved.href,\n ...(resolved.type && { type: resolved.type }),\n ...(resolved.sizes && { sizes: resolved.sizes }),\n })\n }\n }\n\n if (viewport) {\n const parts: string[] = []\n if (viewport.width !== undefined) parts.push(`width=${viewport.width}`)\n if (viewport.initialScale !== undefined) parts.push(`initial-scale=${viewport.initialScale}`)\n if (viewport.maximumScale !== undefined) parts.push(`maximum-scale=${viewport.maximumScale}`)\n if (viewport.userScalable !== undefined) parts.push(`user-scalable=${viewport.userScalable ? 'yes' :\n 'no'}`)\n if (parts.length) tags.push({ tag: 'meta', name: 'viewport', content: parts.join(', ') })\n if (viewport.themeColor) tags.push({\n tag: 'meta', name: 'theme-color', content: viewport.themeColor\n })\n }\n\n return tags\n}\n\nexport function HeadSlot({ metadata, viewport }: { metadata: Metadata | null, viewport?: Viewport }) {\n if (typeof window === 'undefined' || !metadata) return null\n return <>{buildHeadNodes(metadata, viewport)}</>\n}\n\nexport function buildHeadNodes(metadata: Metadata, viewport?: Viewport): ReactNode {\n const tags = collectTags(metadata, viewport)\n\n return <>\n {tags.map((t, i) => {\n if (t.tag === 'title') return <title key={i}>{t.children}</title>\n if (t.tag === 'link') return <link key={i} rel={t.rel} href={t.href} hrefLang={t.hrefLang} type={t.type} sizes={t.sizes} />\n return <meta key={i} name={t.name} property={t.property} content={t.content} />\n })}\n </>\n}", "import {createContext, Context, ComponentType} from \"react\";\nimport {Metadata, Viewport} from \"../types\";\nimport {LayoutProps, PageProps} from \"../server/types\";\n\nexport interface NavigateOptions {\n replace?: boolean\n viewTransition?: boolean\n}\n\nexport interface RouterContextValue {\n pathname: string\n params: Record<string, string>\n loaderData: unknown\n layoutsData: unknown[]\n Page: ComponentType<PageProps>\n layouts: ComponentType<LayoutProps>[]\n metadata: Metadata | null\n viewport?: Viewport\n navigate: (to: string, options?: NavigateOptions) => Promise<void>\n revalidate: () => Promise<void>\n prefetchRoute: (href: string) => void\n isNavigating: boolean\n}\n\nexport interface PageMetaContextValue {\n metadata: Metadata | null\n viewport?: Viewport\n clientEntry?: string\n}\n\nexport interface RouteDataContextValue {\n loaderData: unknown\n params: Record<string, string>\n}\n\nconst g = globalThis as any\n\ng.__devix_RouterContext__ ??= createContext<RouterContextValue | null>(null)\nexport const RouterContext: Context<RouterContextValue | null> = g.__devix_RouterContext__\n\ng.__devix_PageMetaContext__ ??= createContext<PageMetaContextValue | null>(null)\ng.__devix_RouteDataContext__ ??= createContext<RouteDataContextValue | null>(null)\n\nexport const PageMetaContext: Context<PageMetaContextValue | null> = g.__devix_PageMetaContext__\nexport const RouteDataContext: Context<RouteDataContextValue | null> = g.__devix_RouteDataContext__\n\n", "import {Component, ComponentType, ReactNode} from \"react\";\nimport {ErrorProps} from \"../server/types\";\n\ninterface Props {\n ErrorPage?: ComponentType<ErrorProps>\n children: ReactNode\n}\n\ninterface State {\n error: ErrorProps | null\n}\n\nexport class DevixErrorBoundary extends Component<Props, State> {\n state: State = { error: null }\n\n static getDerivedStateFromError(err: unknown): State {\n if (err instanceof DevixError) {\n return {\n error: {statusCode: err.statusCode, message: err.message}\n }\n }\n return {\n error: {statusCode: 500, message: err instanceof Error ? err.message : 'Unknown error'}\n }\n }\n\n render() {\n if (this.state.error && this.props.ErrorPage) {\n return <this.props.ErrorPage {...this.state.error} />\n }\n if (this.state.error) {\n return <h1>{this.state.error.statusCode}</h1>\n }\n return this.props.children\n }\n}\n\nexport class DevixError extends Error {\n statusCode: number\n constructor(statusCode: number, message: string) {\n super(message)\n this.statusCode = statusCode\n }\n}\n", "import { AnchorHTMLAttributes, MouseEventHandler, useCallback, useContext, useRef } from \"react\"\nimport { NavigateOptions, RouterContext } from './context'\n\ninterface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n href: string\n prefetch?: 'hover' | 'none'\n replace?: boolean\n viewTransition?: boolean\n}\n\nfunction resolveHref(href: string): string {\n if (href.startsWith('/') || href.startsWith('http')) return href\n const base = window.location.pathname.endsWith('/')\n ? window.location.href\n : window.location.href + '/'\n const resolved = new URL(href, base).pathname\n return resolved.length > 1 ? resolved.replace(/\\/$/, '') : resolved\n}\n\nexport function Link({ href, prefetch = 'hover', replace = false, viewTransition = false, children, ...props }: LinkProps) {\n const router = useContext(RouterContext)\n const hoverTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n const cancelHoverTimer = useCallback(() => {\n if (hoverTimerRef.current !== null) {\n clearTimeout(hoverTimerRef.current)\n hoverTimerRef.current = null\n }\n }, [])\n\n const triggerPrefetch = useCallback(() => {\n if (!router || prefetch === 'none') return\n router.prefetchRoute(resolveHref(href))\n }, [href, prefetch, router])\n\n const handleMouseEnter = useCallback(() => {\n if (prefetch === 'none') return\n hoverTimerRef.current = setTimeout(triggerPrefetch, 50)\n }, [prefetch, triggerPrefetch])\n\n const handleMouseLeave = useCallback(() => {\n cancelHoverTimer()\n }, [cancelHoverTimer])\n\n const handleTouchStart = useCallback(() => {\n cancelHoverTimer()\n triggerPrefetch()\n }, [cancelHoverTimer, triggerPrefetch])\n\n const handleClick: MouseEventHandler<HTMLAnchorElement> = (e) => {\n cancelHoverTimer()\n if (!router) return\n if (!e.ctrlKey && !e.metaKey && !e.shiftKey && e.button === 0) {\n e.preventDefault()\n const options: NavigateOptions = { replace, viewTransition }\n router.navigate(resolveHref(href), options)\n }\n }\n\n return (\n <a\n href={href}\n onClick={handleClick}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onTouchStart={handleTouchStart}\n {...props}\n >\n {children}\n </a>\n )\n}", "export interface CookieOptions {\n httpOnly?: boolean\n secure?: boolean\n sameSite?: 'Strict' | 'Lax' | 'None'\n maxAge?: number\n expires?: Date\n path?: string\n domain?: string\n}\n\nexport function getCookie(req: Request, name: string): string | undefined {\n const header = req.headers.get('cookie')\n if (!header) return undefined\n for (const part of header.split(';')) {\n const [key, ...rest] = part.trim().split('=')\n if (key.trim() === name) return decodeURIComponent(rest.join('='))\n }\n return undefined\n}\n\nexport function setCookie(headers: Headers, name: string, value: string, options: CookieOptions = {}): void {\n let cookie = `${name}=${encodeURIComponent(value)}; Path=${options.path ?? '/'}`\n if (options.domain) cookie += `; Domain=${options.domain}`\n if (options.maxAge !== undefined) cookie += `; Max-Age=${options.maxAge}`\n if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`\n if (options.httpOnly) cookie += `; HttpOnly`\n if (options.secure) cookie += `; Secure`\n if (options.sameSite) cookie += `; SameSite=${options.sameSite}`\n headers.append('Set-Cookie', cookie)\n}\n\nexport function deleteCookie(headers: Headers, name: string, options: Pick<CookieOptions, 'path' | 'domain'> = {}): void {\n setCookie(headers, name, '', {...options, maxAge: 0, expires: new Date(0)})\n}\n", "export type JsonResponse<T = unknown, S extends number = number> = Response & {\n readonly __body: T\n readonly __status: S\n}\n\nexport function json<const T>(data: T): JsonResponse<T, 200>\nexport function json<const T, const S extends number>(data: T, status: S): JsonResponse<T, S>\nexport function json<const T>(data: T, status: number = 200): JsonResponse<T, any> {\n return new Response(JSON.stringify(data), {\n status,\n headers: {'Content-Type': 'application/json'},\n }) as JsonResponse<T, any>\n}\n\nexport const text = (body: string, status = 200): Response =>\n new Response(body, {status, headers: {'Content-Type': 'text/plain; charset=utf-8'}})\n\nconst REDIRECT_BRAND = Symbol('devix.redirect')\n\nexport interface RedirectOptions {\n status?: number\n replace?: boolean\n}\n\nexport interface Redirect {\n readonly [REDIRECT_BRAND]: true\n readonly url: string\n readonly status: number\n readonly replace: boolean\n}\n\nexport function redirect(url: string, statusOrOptions?: number | RedirectOptions): Redirect {\n const status = typeof statusOrOptions === 'number' ? statusOrOptions : (statusOrOptions?.status ?? 302)\n const replace = typeof statusOrOptions === 'object' ? (statusOrOptions?.replace ?? false) : false\n return {[REDIRECT_BRAND]: true, url, status, replace} as Redirect\n}\n\nexport function isRedirect(value: unknown): value is Redirect {\n return typeof value === 'object' && value !== null && REDIRECT_BRAND in value\n}\n\nconst ERROR_BRAND = Symbol('devix.loaderError')\n\nexport interface RouteError {\n readonly [ERROR_BRAND]: true\n readonly statusCode: number\n readonly message: string\n readonly data?: unknown\n}\n\nexport function error(statusCode: number, message: string, data?: unknown): RouteError {\n return { [ERROR_BRAND]: true, statusCode, message, data } as RouteError\n}\n\nexport function isLoaderError(value: unknown): value is RouteError {\n return typeof value === 'object' && value !== null && ERROR_BRAND in value\n}\n", "export const HANDLER_BRAND = '__devix_handler__' as const\n\nexport interface DevixHandler<TBody = undefined, TReturn = unknown> {\n readonly [HANDLER_BRAND]: true\n readonly fn: (...args: any[]) => any\n readonly __body: TBody\n readonly __return: TReturn\n}\n\ntype ExtractBody<TFn> = TFn extends (body: infer B) => any ? B : undefined\n\nexport function createHandler<TFn extends (...args: any[]) => any>(\n fn: TFn,\n): DevixHandler<ExtractBody<TFn>, Awaited<ReturnType<TFn>>> {\n return {[HANDLER_BRAND]: true, fn} as unknown as DevixHandler<ExtractBody<TFn>, Awaited<ReturnType<TFn>>>\n}\n", "export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'\n\nexport class FetchError<E = unknown> extends Error {\n constructor(\n public readonly status: number,\n public readonly statusText: string,\n public readonly response: Response,\n public readonly body?: E,\n ) {\n super(`HTTP ${status}: ${statusText}`)\n this.name = 'FetchError'\n }\n}\n", "export {useRouter, useNavigate, useRevalidate, useParams, useLoaderData, RouterProvider} from \"./router-provider\"\n\nexport {Link} from \"./link\"\n\nexport type { Metadata, MetadataIcon, Viewport, LoaderContext, LoaderContextWithGuard, LoaderFunction, GuardFunction } from '../types'\nexport type { NavigateOptions } from './context'\nexport type { PageProps, LayoutProps, PageModule, LayoutModule, ErrorProps } from '../server/types'\nexport type { RouteHandler, RouteResult } from './api-context'\nexport {getCookie, setCookie, deleteCookie} from '../utils/cookies'\nexport type {CookieOptions} from '../utils/cookies'\nexport {json, text, redirect, error} from '../utils/response'\nexport type {JsonResponse, Redirect, RedirectOptions, RouteError} from '../utils/response'\nexport {createHandler} from './create-handler'\nexport type {DevixHandler} from './create-handler'\nexport {FetchError} from './fetch'\nexport type {HttpMethod} from './fetch'\n\nimport {FetchError, type HttpMethod} from './fetch'\n\nexport interface ApiRoutes {}\n\ntype ApiKey<M extends HttpMethod, P extends string> = `${M} ${P}`\ntype MatchingKey<M extends HttpMethod, P extends string> = {\n [K in keyof ApiRoutes]: K extends ApiKey<M, P> ? K : never\n}[keyof ApiRoutes]\ntype RouteData<M extends HttpMethod, P extends string> = ApiRoutes[MatchingKey<M, P>]\ntype AllApiPaths = {\n [K in keyof ApiRoutes]: K extends `${HttpMethod} ${infer P}` ? P : never\n}[keyof ApiRoutes]\ntype ApiPath = AllApiPaths | (string & {})\ntype ExtractBody<D> = D extends { __body: infer B } ? B : never\ntype ExtractResponse<D> = D extends { __response: infer R } ? R : D\ntype InferBody<M extends HttpMethod, P extends string> = ExtractBody<RouteData<M, P>>\ntype InferResult<M extends HttpMethod, P extends string> = ExtractResponse<RouteData<M, P>>\ntype BodyOption<M extends HttpMethod, P extends string> = [InferBody<M, P>] extends [never] ? unknown : InferBody<M, P>\n\nexport interface FetchOptions<M extends HttpMethod = 'GET', P extends string = string> {\n method?: M\n body?: BodyOption<M, P>\n headers?: HeadersInit\n signal?: AbortSignal\n}\n\nexport async function $fetch<P extends ApiPath = ApiPath, M extends HttpMethod = 'GET'>(\n path: P & string,\n options?: FetchOptions<M, P>\n): Promise<InferResult<M, P>> {\n const method = options?.method ?? 'GET'\n const headers = new Headers(options?.headers)\n\n let body: BodyInit | undefined\n if (options?.body !== undefined) {\n if (options.body instanceof FormData || options.body instanceof Blob || options.body instanceof ArrayBuffer) {\n body = options.body\n } else {\n body = JSON.stringify(options.body)\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'application/json')\n }\n }\n }\n\n const response = await fetch(path, {method, headers, body, signal: options?.signal})\n\n if (!response.ok) {\n const contentType = response.headers.get('Content-Type') ?? ''\n const errorBody = contentType.includes('application/json')\n ? await response.json()\n : undefined\n throw new FetchError(response.status, response.statusText, response, errorBody)\n }\n\n const contentType = response.headers.get('Content-Type') ?? ''\n if (contentType.includes('application/json')) {\n return response.json() as Promise<InferResult<M, P>>\n }\n\n return response.text() as unknown as Promise<InferResult<M, P>>\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["useCallback", "useContext", "useEffect", "useRef", "useState", "RouterContext", "getDefaultErrorPage", "loadErrorPage", "matchClientRoute", "Fragment", "jsx", "collectTags", "metadata", "viewport", "tags", "ogTitle", "ogDesc", "twTitle", "twDesc", "lang", "href", "raw", "icon", "resolved", "parts", "HeadSlot", "buildHeadNodes", "t", "i", "createContext", "g", "RouterContext", "PageMetaContext", "RouteDataContext", "Component", "jsx", "DevixErrorBoundary", "err", "DevixError", "statusCode", "message", "jsx", "jsxs", "useRouter", "useContext", "RouterContext", "noopNavigate", "noopRevalidate", "useNavigate", "useRevalidate", "useParams", "ctx", "RouteDataContext", "useLoaderData", "RouterProvider", "initialData", "initialParams", "initialPage", "initialLayouts", "initialLayoutsData", "initialMeta", "initialViewport", "initialError", "initialErrorPage", "clientEntry", "state", "setState", "useState", "navigatingRef", "useRef", "isNavigating", "setIsNavigating", "prefetchCacheRef", "prefetchRoute", "useCallback", "href", "pathname", "matched", "matchClientRoute", "controller", "promise", "l", "pageMod", "layoutMods", "dataRes", "data", "expireTimer", "loadRoute", "to", "ErrorPage", "loadErrorPage", "getDefaultErrorPage", "prev", "cached", "prefetched", "pm", "lm", "ct", "errorBody", "headers", "value", "key", "m", "hash", "scrollBehavior", "navigate", "options", "run", "revalidate", "useEffect", "handlePop", "err", "content", "tree", "i", "Layout", "layoutData", "DevixErrorBoundary", "PageMetaContext", "HeadSlot", "useCallback", "useContext", "useRef", "jsx", "resolveHref", "href", "base", "resolved", "Link", "prefetch", "replace", "viewTransition", "children", "props", "router", "useContext", "RouterContext", "hoverTimerRef", "useRef", "cancelHoverTimer", "useCallback", "triggerPrefetch", "handleMouseEnter", "handleMouseLeave", "handleTouchStart", "e", "options", "getCookie", "req", "name", "header", "part", "key", "rest", "setCookie", "headers", "value", "options", "cookie", "deleteCookie", "json", "data", "status", "text", "body", "REDIRECT_BRAND", "redirect", "url", "statusOrOptions", "replace", "ERROR_BRAND", "error", "statusCode", "message", "data", "HANDLER_BRAND", "createHandler", "fn", "FetchError", "status", "statusText", "response", "body", "$fetch", "path", "options", "method", "headers", "body", "response", "errorBody", "FetchError"]
|
|
7
7
|
}
|
package/dist/runtime/link.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { AnchorHTMLAttributes } from "react";
|
|
2
2
|
interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
3
3
|
href: string;
|
|
4
|
-
prefetch?:
|
|
4
|
+
prefetch?: 'hover' | 'none';
|
|
5
|
+
replace?: boolean;
|
|
5
6
|
viewTransition?: boolean;
|
|
6
7
|
}
|
|
7
|
-
export declare function Link({ href, prefetch, viewTransition, children, ...props }: LinkProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export declare function Link({ href, prefetch, replace, viewTransition, children, ...props }: LinkProps): import("react/jsx-runtime").JSX.Element;
|
|
8
9
|
export {};
|
package/dist/runtime/link.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useCallback as
|
|
1
|
+
import{useCallback as l,useContext as h,useRef as R}from"react";import{createContext as c}from"react";var o=globalThis;o.__devix_RouterContext__??=c(null);var p=o.__devix_RouterContext__;o.__devix_PageMetaContext__??=c(null);o.__devix_RouteDataContext__??=c(null);var L=o.__devix_PageMetaContext__,V=o.__devix_RouteDataContext__;import{jsx as M}from"react/jsx-runtime";function x(t){if(t.startsWith("/")||t.startsWith("http"))return t;let e=window.location.pathname.endsWith("/")?window.location.href:window.location.href+"/",n=new URL(t,e).pathname;return n.length>1?n.replace(/\/$/,""):n}function N({href:t,prefetch:e="hover",replace:n=!1,viewTransition:g=!1,children:d,...v}){let a=h(p),u=R(null),r=l(()=>{u.current!==null&&(clearTimeout(u.current),u.current=null)},[]),s=l(()=>{!a||e==="none"||a.prefetchRoute(x(t))},[t,e,a]),C=l(()=>{e!=="none"&&(u.current=setTimeout(s,50))},[e,s]),_=l(()=>{r()},[r]),m=l(()=>{r(),s()},[r,s]);return M("a",{href:t,onClick:i=>{if(r(),!!a&&!i.ctrlKey&&!i.metaKey&&!i.shiftKey&&i.button===0){i.preventDefault();let f={replace:n,viewTransition:g};a.navigate(x(t),f)}},onMouseEnter:C,onMouseLeave:_,onTouchStart:m,...v,children:d})}export{N as Link};
|
|
2
2
|
//# sourceMappingURL=link.js.map
|