@devlusoft/devix 0.4.0-beta.2 → 0.4.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -3
- package/dist/cli/build.js +9 -9
- package/dist/cli/build.js.map +3 -3
- package/dist/cli/dev.js +1 -154
- package/dist/cli/dev.js.map +4 -4
- package/dist/cli/devix-dev-server.js +155 -0
- package/dist/cli/devix-dev-server.js.map +7 -0
- package/dist/cli/generate.js +9 -9
- package/dist/cli/generate.js.map +3 -3
- package/dist/cli/index.js +24 -26
- 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/config.js.map +2 -2
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/index.js.map +2 -2
- package/dist/runtime/link.js +1 -1
- package/dist/runtime/link.js.map +2 -2
- package/dist/runtime/router-provider.js +1 -1
- package/dist/runtime/router-provider.js.map +2 -2
- package/dist/server/collect-css.js +1 -1
- package/dist/server/collect-css.js.map +2 -2
- package/dist/src/cli/start.d.ts +1 -0
- package/dist/{config.d.ts → src/config.d.ts} +1 -0
- package/dist/utils/banner.js +1 -1
- package/dist/vite/index.js +11 -11
- package/dist/vite/index.js.map +3 -3
- package/package.json +3 -2
- /package/dist/{cli → src/cli}/build.d.ts +0 -0
- /package/dist/{cli → src/cli}/dev.d.ts +0 -0
- /package/dist/{cli/generate.d.ts → src/cli/devix-dev-server.d.ts} +0 -0
- /package/dist/{cli/start.d.ts → src/cli/generate.d.ts} +0 -0
- /package/dist/{cli → src/cli}/index.d.ts +0 -0
- /package/dist/{runtime → src/runtime}/api-context.d.ts +0 -0
- /package/dist/{runtime → src/runtime}/client-router.d.ts +0 -0
- /package/dist/{runtime → src/runtime}/context.d.ts +0 -0
- /package/dist/{runtime → src/runtime}/create-handler.d.ts +0 -0
- /package/dist/{runtime → src/runtime}/error-boundary.d.ts +0 -0
- /package/dist/{runtime → src/runtime}/fetch.d.ts +0 -0
- /package/dist/{runtime → src/runtime}/head.d.ts +0 -0
- /package/dist/{runtime → src/runtime}/index.d.ts +0 -0
- /package/dist/{runtime → src/runtime}/link.d.ts +0 -0
- /package/dist/{runtime → src/runtime}/metadata.d.ts +0 -0
- /package/dist/{runtime → src/runtime}/router-provider.d.ts +0 -0
- /package/dist/{runtime → src/runtime}/server-app.d.ts +0 -0
- /package/dist/{server → src/server}/api-router.d.ts +0 -0
- /package/dist/{server → src/server}/api.d.ts +0 -0
- /package/dist/{server → src/server}/collect-css.d.ts +0 -0
- /package/dist/{server → src/server}/handler-store.d.ts +0 -0
- /package/dist/{server → src/server}/index.d.ts +0 -0
- /package/dist/{server → src/server}/pages-router.d.ts +0 -0
- /package/dist/{server → src/server}/public-index.d.ts +0 -0
- /package/dist/{server → src/server}/render.d.ts +0 -0
- /package/dist/{server → src/server}/routes.d.ts +0 -0
- /package/dist/{server → src/server}/types.d.ts +0 -0
- /package/dist/{types.d.ts → src/types.d.ts} +0 -0
- /package/dist/{utils → src/utils}/async.d.ts +0 -0
- /package/dist/{utils → src/utils}/banner.d.ts +0 -0
- /package/dist/{utils → src/utils}/cookies.d.ts +0 -0
- /package/dist/{utils → src/utils}/duration.d.ts +0 -0
- /package/dist/{utils → src/utils}/env.d.ts +0 -0
- /package/dist/{utils → src/utils}/html.d.ts +0 -0
- /package/dist/{utils → src/utils}/patterns.d.ts +0 -0
- /package/dist/{utils → src/utils}/response.d.ts +0 -0
- /package/dist/{vite → src/vite}/codegen/api.d.ts +0 -0
- /package/dist/{vite → src/vite}/codegen/client-routes.d.ts +0 -0
- /package/dist/{vite → src/vite}/codegen/context.d.ts +0 -0
- /package/dist/{vite → src/vite}/codegen/entry-client.d.ts +0 -0
- /package/dist/{vite → src/vite}/codegen/extract-methods.d.ts +0 -0
- /package/dist/{vite → src/vite}/codegen/render.d.ts +0 -0
- /package/dist/{vite → src/vite}/codegen/routes-dts.d.ts +0 -0
- /package/dist/{vite → src/vite}/codegen/scan-api.d.ts +0 -0
- /package/dist/{vite → src/vite}/codegen/write-routes-dts.d.ts +0 -0
- /package/dist/{vite → src/vite}/index.d.ts +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
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/create-handler.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\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]\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 window.scrollTo(0, 0)\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\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, 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 }\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 (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}/>\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]\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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",
|
|
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 window.scrollTo(0, 0)\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\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, 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 }\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 (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}/>\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
6
|
"names": ["useCallback", "useContext", "useEffect", "useRef", "useState", "RouterContext", "getDefaultErrorPage", "loadErrorPage", "matchClientRoute", "Fragment", "jsx", "collectTags", "metadata", "viewport", "tags", "ogTitle", "ogDesc", "twTitle", "twDesc", "lang", "href", "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", "loadRoute", "useCallback", "to", "controller", "pathname", "matched", "matchClientRoute", "ErrorPage", "loadErrorPage", "getDefaultErrorPage", "prev", "pageMod", "layoutMods", "l", "dataRes", "data", "m", "navigate", "options", "run", "revalidate", "useEffect", "handlePop", "err", "content", "tree", "i", "Layout", "layoutData", "DevixErrorBoundary", "PageMetaContext", "HeadSlot", "useCallback", "useContext", "matchClientRoute", "RouterContext", "jsx", "resolveHref", "href", "base", "resolved", "Link", "prefetch", "viewTransition", "children", "props", "router", "handleMouseEnter", "pathname", "matched", "e", "getCookie", "req", "name", "header", "part", "key", "rest", "setCookie", "headers", "value", "options", "cookie", "deleteCookie", "json", "data", "status", "text", "body", "REDIRECT_BRAND", "redirect", "url", "statusOrOptions", "replace", "FetchError", "status", "statusText", "response", "$fetch", "path", "options", "method", "headers", "body", "HANDLER_BRAND", "createHandler", "fn"]
|
|
7
7
|
}
|
package/dist/runtime/link.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useCallback as h,useContext as d}from"react";import{matchClientRoute as f}from"virtual:devix/client-routes";import{RouterContext as p}from"virtual:devix/context";import{jsx as m}from"react/jsx-runtime";function s(t){if(t.startsWith("/")||t.startsWith("http"))return t;let o=window.location.pathname.endsWith("/")?window.location.href:window.location.href+"/",e=new URL(t,o).pathname;return e.length>1?e.replace(/\/$/,""):e}function A({href:t,prefetch:o=!1,viewTransition:e=!1,children:c,...l}){let r=d(p),u=h(()=>{if(!o)return;let n=s(t),i=n.split("?")[0],a=f(i);a&&(a.load().catch(()=>{}),fetch(`/_data${n}`,{headers:{Accept:"application/json"}}).catch(()=>{}))},[t,o]);return m("a",{href:t,onClick:n=>{if(r&&!n.ctrlKey&&!n.metaKey&&!n.shiftKey&&n.button===0){n.preventDefault();let i=s(t);e&&typeof document.startViewTransition=="function"?document.startViewTransition(()=>r.navigate(i)):r.navigate(i)}},onMouseEnter:u,...l,children:c})}export{A as Link};
|
|
1
|
+
import{useCallback as h,useContext as d}from"react";import{matchClientRoute as f}from"virtual:devix/client-routes";import{RouterContext as p}from"virtual:devix/context";import{jsx as m}from"react/jsx-runtime";function s(t){if(t.startsWith("/")||t.startsWith("http"))return t;let o=window.location.pathname.endsWith("/")?window.location.href:window.location.href+"/",e=new URL(t,o).pathname;return e.length>1?e.replace(/\/$/,""):e}function A({href:t,prefetch:o=!1,viewTransition:e=!1,children:c,...l}){let r=d(p),u=h(()=>{if(!o)return;let n=s(t),i=n.split("?")[0].split("#")[0],a=f(i);a&&(a.load().catch(()=>{}),fetch(`/_data${n}`,{headers:{Accept:"application/json"}}).catch(()=>{}))},[t,o]);return m("a",{href:t,onClick:n=>{if(r&&!n.ctrlKey&&!n.metaKey&&!n.shiftKey&&n.button===0){n.preventDefault();let i=s(t);e&&typeof document.startViewTransition=="function"?document.startViewTransition(()=>r.navigate(i)):r.navigate(i)}},onMouseEnter:u,...l,children:c})}export{A as Link};
|
|
2
2
|
//# sourceMappingURL=link.js.map
|
package/dist/runtime/link.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/runtime/link.tsx"],
|
|
4
|
-
"sourcesContent": ["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]\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}"],
|
|
5
|
-
"mappings": "AAAA,OAAiD,eAAAA,EAAa,cAAAC,MAAiB,QAC/E,OAAQ,oBAAAC,MAAuB,8BAC/B,OAAQ,iBAAAC,MAAoB,wBA6CpB,cAAAC,MAAA,oBArCR,SAASC,EAAYC,EAAsB,CACvC,GAAIA,EAAK,WAAW,GAAG,GAAKA,EAAK,WAAW,MAAM,EAAG,OAAOA,EAC5D,IAAMC,EAAO,OAAO,SAAS,SAAS,SAAS,GAAG,EAC5C,OAAO,SAAS,KAChB,OAAO,SAAS,KAAO,IACvBC,EAAW,IAAI,IAAIF,EAAMC,CAAI,EAAE,SACrC,OAAOC,EAAS,OAAS,EAAIA,EAAS,QAAQ,MAAO,EAAE,EAAIA,CAC/D,CAEO,SAASC,EAAK,CAAE,KAAAH,EAAM,SAAAI,EAAW,GAAO,eAAAC,EAAiB,GAAO,SAAAC,EAAU,GAAGC,CAAM,EAAc,CACpG,IAAMC,EAASb,EAAWE,CAAa,EAEjCY,EAAmBf,EAAY,IAAM,CACvC,GAAI,CAACU,EAAU,OACf,IAAMF,EAAWH,EAAYC,CAAI,EAC3BU,EAAWR,EAAS,MAAM,GAAG,EAAE,CAAC,
|
|
4
|
+
"sourcesContent": ["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}"],
|
|
5
|
+
"mappings": "AAAA,OAAiD,eAAAA,EAAa,cAAAC,MAAiB,QAC/E,OAAQ,oBAAAC,MAAuB,8BAC/B,OAAQ,iBAAAC,MAAoB,wBA6CpB,cAAAC,MAAA,oBArCR,SAASC,EAAYC,EAAsB,CACvC,GAAIA,EAAK,WAAW,GAAG,GAAKA,EAAK,WAAW,MAAM,EAAG,OAAOA,EAC5D,IAAMC,EAAO,OAAO,SAAS,SAAS,SAAS,GAAG,EAC5C,OAAO,SAAS,KAChB,OAAO,SAAS,KAAO,IACvBC,EAAW,IAAI,IAAIF,EAAMC,CAAI,EAAE,SACrC,OAAOC,EAAS,OAAS,EAAIA,EAAS,QAAQ,MAAO,EAAE,EAAIA,CAC/D,CAEO,SAASC,EAAK,CAAE,KAAAH,EAAM,SAAAI,EAAW,GAAO,eAAAC,EAAiB,GAAO,SAAAC,EAAU,GAAGC,CAAM,EAAc,CACpG,IAAMC,EAASb,EAAWE,CAAa,EAEjCY,EAAmBf,EAAY,IAAM,CACvC,GAAI,CAACU,EAAU,OACf,IAAMF,EAAWH,EAAYC,CAAI,EAC3BU,EAAWR,EAAS,MAAM,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,EAC9CS,EAAUf,EAAiBc,CAAQ,EACrCC,IACAA,EAAQ,KAAK,EAAE,MAAM,IAAM,CAAC,CAAC,EAC7B,MAAM,SAAST,CAAQ,GAAI,CAAE,QAAS,CAAE,OAAQ,kBAAmB,CAAE,CAAC,EAAE,MAAM,IAAM,CAAC,CAAC,EAE9F,EAAG,CAACF,EAAMI,CAAQ,CAAC,EAenB,OACIN,EAAC,KAAE,KAAME,EAAM,QAdwCY,GAAM,CAC7D,GAAKJ,GACD,CAACI,EAAE,SAAW,CAACA,EAAE,SAAW,CAACA,EAAE,UAAYA,EAAE,SAAW,EAAG,CAC3DA,EAAE,eAAe,EACjB,IAAMV,EAAWH,EAAYC,CAAI,EAC7BK,GAAkB,OAAO,SAAS,qBAAwB,WAC1D,SAAS,oBAAoB,IAAMG,EAAO,SAASN,CAAQ,CAAC,EAE5DM,EAAO,SAASN,CAAQ,CAEhC,CACJ,EAGyC,aAAcO,EAAmB,GAAGF,EACpE,SAAAD,EACL,CAER",
|
|
6
6
|
"names": ["useCallback", "useContext", "matchClientRoute", "RouterContext", "jsx", "resolveHref", "href", "base", "resolved", "Link", "prefetch", "viewTransition", "children", "props", "router", "handleMouseEnter", "pathname", "matched", "e"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useCallback as N,useContext as x,useEffect as Q,useRef as W,useState as B}from"react";import{RouterContext as T}from"virtual:devix/context";import{getDefaultErrorPage as F,loadErrorPage as I,matchClientRoute as X}from"virtual:devix/client-routes";import{Fragment as O,jsx as h}from"react/jsx-runtime";function G(t,e){let r=[];t.title&&r.push({tag:"title",children:t.title}),t.description&&r.push({tag:"meta",name:"description",content:t.description}),t.keywords?.length&&r.push({tag:"meta",name:"keywords",content:t.keywords.join(", ")});let l=t.og?.title??t.title;l&&r.push({tag:"meta",property:"og:title",content:l});let g=t.og?.description??t.description;g&&r.push({tag:"meta",property:"og:description",content:g}),t.og?.image&&r.push({tag:"meta",property:"og:image",content:t.og.image}),t.og?.type&&r.push({tag:"meta",property:"og:type",content:t.og.type}),t.og?.url&&r.push({tag:"meta",property:"og:url",content:t.og.url});let P=t.twitter?.title??t.title;P&&r.push({tag:"meta",name:"twitter:title",content:P});let C=t.twitter?.description??t.description;if(C&&r.push({tag:"meta",name:"twitter:description",content:C}),t.twitter?.card&&r.push({tag:"meta",name:"twitter:card",content:t.twitter.card}),t.twitter?.image&&r.push({tag:"meta",name:"twitter:image",content:t.twitter.image}),t.twitter?.creator&&r.push({tag:"meta",name:"twitter:creator",content:t.twitter.creator}),t.canonical&&r.push({tag:"link",rel:"canonical",href:t.canonical}),t.robots&&r.push({tag:"meta",name:"robots",content:t.robots}),t.alternates)for(let[u,_]of Object.entries(t.alternates))r.push({tag:"link",rel:"alternate",href:_,hrefLang:u});if(e){let u=[];e.width!==void 0&&u.push(`width=${e.width}`),e.initialScale!==void 0&&u.push(`initial-scale=${e.initialScale}`),e.maximumScale!==void 0&&u.push(`maximum-scale=${e.maximumScale}`),e.userScalable!==void 0&&u.push(`user-scalable=${e.userScalable?"yes":"no"}`),u.length&&r.push({tag:"meta",name:"viewport",content:u.join(", ")}),e.themeColor&&r.push({tag:"meta",name:"theme-color",content:e.themeColor})}return r}function $({metadata:t,viewport:e}){return typeof window>"u"||!t?null:h(O,{children:J(t,e)})}function J(t,e){let r=G(t,e);return h(O,{children:r.map((l,g)=>l.tag==="title"?h("title",{children:l.children},g):l.tag==="link"?h("link",{rel:l.rel,href:l.href,hrefLang:l.hrefLang},g):h("meta",{name:l.name,property:l.property,content:l.content},g))})}import{createContext as V}from"react";var f=globalThis;f.__devix_RouterContext__??=V(null);var it=f.__devix_RouterContext__;f.__devix_PageMetaContext__??=V(null);f.__devix_RouteDataContext__??=V(null);var j=f.__devix_PageMetaContext__,y=f.__devix_RouteDataContext__;import{Component as K}from"react";import{jsx as H}from"react/jsx-runtime";var D=class extends K{state={error:null};static getDerivedStateFromError(e){return e instanceof L?{error:{statusCode:e.statusCode,message:e.message}}:{error:{statusCode:500,message:e instanceof Error?e.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?H(this.props.ErrorPage,{...this.state.error}):this.state.error?H("h1",{children:this.state.error.statusCode}):this.props.children}},L=class extends Error{statusCode;constructor(e,r){super(r),this.statusCode=e}};import{jsx as d,jsxs as tt}from"react/jsx-runtime";function Rt(){return x(T)}var Y=()=>Promise.resolve(),Z=()=>Promise.resolve();function vt(){return x(T)?.navigate??Y}function Et(){return x(T)?.revalidate??Z}function Dt(){let t=x(y);if(!t)throw new Error("useParams must be used within a route or layout");return t.params}function Tt(){let t=x(y);if(!t)throw new Error("useLoaderData must be used within a route or layout");return t.loaderData}function _t({initialData:t,initialParams:e,initialPage:r,initialLayouts:l=[],initialLayoutsData:g=[],initialMeta:P,initialViewport:C,initialError:u,initialErrorPage:_,clientEntry:U}){let[o,R]=B({pathname:window.location.pathname,params:e,loaderData:t,layoutsData:g,Page:r,layouts:l,metadata:P??null,viewport:C,pendingError:u,ErrorPage:_}),v=W(null),[q,A]=B(!1),w=N(async(i,n)=>{let s=i.split("?")[0],a=X(s);if(!a){let c=await I()??F();R(S=>({...S,pathname:s,pendingError:{statusCode:404,message:"Not found"},ErrorPage:c??void 0}));return}let[m,...M]=await Promise.all([a.load(),...a.loadLayouts.map(c=>c())]);if(n.signal.aborted||!m.default)return;let E=await fetch(`/_data${i}`,{headers:{Accept:"application/json"},signal:n.signal});if(n.signal.aborted)return;if(!E.ok){if(E.status===404){window.location.href=i;return}let c=await I()??F();R(S=>({...S,pathname:s,pendingError:{statusCode:E.status,message:"Server error"},ErrorPage:c??void 0}));return}let p=await E.json();if(p.redirect){p.redirectReplace?window.history.replaceState(null,"",p.redirect):window.history.pushState(null,"",p.redirect),await w(p.redirect,n);return}window.scrollTo(0,0),R({pathname:s,params:p.params??{},loaderData:p.loaderData,layoutsData:(p.layouts??[]).map(c=>c.loaderData),Page:m.default,layouts:M.map(c=>c.default),metadata:p.metadata??null,viewport:p.viewport})},[]),b=N(async(i,n)=>{v.current?.abort();let s=new AbortController;v.current=s,A(!0);let a=async()=>{window.history[n?.replace?"replaceState":"pushState"](null,"",i),await w(i,s)};try{n?.viewTransition&&"startViewTransition"in document?await document.startViewTransition(a).finished:await a()}finally{s.signal.aborted||A(!1)}},[w]),z=N(async()=>{let i=window.location.pathname+window.location.search,n=new AbortController,s=await fetch(`/_data${i}`,{headers:{Accept:"application/json"},signal:n.signal});if(!s.ok)return;let a=await s.json();if(a.redirect){await b(a.redirect,{replace:a.redirectReplace});return}R(m=>({...m,loaderData:a.loaderData,layoutsData:(a.layouts??[]).map(M=>M.loaderData),params:a.params??m.params,metadata:a.metadata??m.metadata,viewport:a.viewport??m.viewport}))},[b]);Q(()=>{let i=()=>{v.current?.abort();let n=new AbortController;v.current=n;let s=window.location.pathname+window.location.search;w(s,n).catch(a=>{a.name!=="AbortError"&&console.error("[router] popstate error:",a)})};return window.addEventListener("popstate",i),()=>window.removeEventListener("popstate",i)},[w]);let k;if(o.pendingError)k=o.ErrorPage?d(o.ErrorPage,{...o.pendingError}):d("h1",{children:o.pendingError.statusCode});else{let i=d(y,{value:{loaderData:o.loaderData,params:o.params},children:d(o.Page,{data:o.loaderData,params:o.params,url:o.pathname})});for(let n=o.layouts.length-1;n>=0;n--){let s=o.layouts[n],a=o.layoutsData[n];i=d(y,{value:{loaderData:a,params:o.params},children:d(s,{data:a,params:o.params,children:i})})}k=d(D,{ErrorPage:o.ErrorPage,children:i},o.pathname)}return tt(j,{value:{metadata:o.metadata,viewport:o.viewport,clientEntry:U},children:[d($,{metadata:o.metadata,viewport:o.viewport}),d(T,{value:{...o,isNavigating:q,navigate:b,revalidate:z},children:k})]})}export{_t as RouterProvider,Tt as useLoaderData,vt as useNavigate,Dt as useParams,Et as useRevalidate,Rt as useRouter};
|
|
1
|
+
import{useCallback as N,useContext as x,useEffect as Q,useRef as W,useState as B}from"react";import{RouterContext as T}from"virtual:devix/context";import{getDefaultErrorPage as F,loadErrorPage as I,matchClientRoute as X}from"virtual:devix/client-routes";import{Fragment as O,jsx as h}from"react/jsx-runtime";function G(t,e){let r=[];t.title&&r.push({tag:"title",children:t.title}),t.description&&r.push({tag:"meta",name:"description",content:t.description}),t.keywords?.length&&r.push({tag:"meta",name:"keywords",content:t.keywords.join(", ")});let l=t.og?.title??t.title;l&&r.push({tag:"meta",property:"og:title",content:l});let g=t.og?.description??t.description;g&&r.push({tag:"meta",property:"og:description",content:g}),t.og?.image&&r.push({tag:"meta",property:"og:image",content:t.og.image}),t.og?.type&&r.push({tag:"meta",property:"og:type",content:t.og.type}),t.og?.url&&r.push({tag:"meta",property:"og:url",content:t.og.url});let P=t.twitter?.title??t.title;P&&r.push({tag:"meta",name:"twitter:title",content:P});let C=t.twitter?.description??t.description;if(C&&r.push({tag:"meta",name:"twitter:description",content:C}),t.twitter?.card&&r.push({tag:"meta",name:"twitter:card",content:t.twitter.card}),t.twitter?.image&&r.push({tag:"meta",name:"twitter:image",content:t.twitter.image}),t.twitter?.creator&&r.push({tag:"meta",name:"twitter:creator",content:t.twitter.creator}),t.canonical&&r.push({tag:"link",rel:"canonical",href:t.canonical}),t.robots&&r.push({tag:"meta",name:"robots",content:t.robots}),t.alternates)for(let[u,_]of Object.entries(t.alternates))r.push({tag:"link",rel:"alternate",href:_,hrefLang:u});if(e){let u=[];e.width!==void 0&&u.push(`width=${e.width}`),e.initialScale!==void 0&&u.push(`initial-scale=${e.initialScale}`),e.maximumScale!==void 0&&u.push(`maximum-scale=${e.maximumScale}`),e.userScalable!==void 0&&u.push(`user-scalable=${e.userScalable?"yes":"no"}`),u.length&&r.push({tag:"meta",name:"viewport",content:u.join(", ")}),e.themeColor&&r.push({tag:"meta",name:"theme-color",content:e.themeColor})}return r}function $({metadata:t,viewport:e}){return typeof window>"u"||!t?null:h(O,{children:J(t,e)})}function J(t,e){let r=G(t,e);return h(O,{children:r.map((l,g)=>l.tag==="title"?h("title",{children:l.children},g):l.tag==="link"?h("link",{rel:l.rel,href:l.href,hrefLang:l.hrefLang},g):h("meta",{name:l.name,property:l.property,content:l.content},g))})}import{createContext as V}from"react";var f=globalThis;f.__devix_RouterContext__??=V(null);var it=f.__devix_RouterContext__;f.__devix_PageMetaContext__??=V(null);f.__devix_RouteDataContext__??=V(null);var j=f.__devix_PageMetaContext__,y=f.__devix_RouteDataContext__;import{Component as K}from"react";import{jsx as H}from"react/jsx-runtime";var D=class extends K{state={error:null};static getDerivedStateFromError(e){return e instanceof L?{error:{statusCode:e.statusCode,message:e.message}}:{error:{statusCode:500,message:e instanceof Error?e.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?H(this.props.ErrorPage,{...this.state.error}):this.state.error?H("h1",{children:this.state.error.statusCode}):this.props.children}},L=class extends Error{statusCode;constructor(e,r){super(r),this.statusCode=e}};import{jsx as d,jsxs as tt}from"react/jsx-runtime";function Rt(){return x(T)}var Y=()=>Promise.resolve(),Z=()=>Promise.resolve();function vt(){return x(T)?.navigate??Y}function Et(){return x(T)?.revalidate??Z}function Dt(){let t=x(y);if(!t)throw new Error("useParams must be used within a route or layout");return t.params}function Tt(){let t=x(y);if(!t)throw new Error("useLoaderData must be used within a route or layout");return t.loaderData}function _t({initialData:t,initialParams:e,initialPage:r,initialLayouts:l=[],initialLayoutsData:g=[],initialMeta:P,initialViewport:C,initialError:u,initialErrorPage:_,clientEntry:U}){let[o,R]=B({pathname:window.location.pathname,params:e,loaderData:t,layoutsData:g,Page:r,layouts:l,metadata:P??null,viewport:C,pendingError:u,ErrorPage:_}),v=W(null),[q,A]=B(!1),w=N(async(i,n)=>{let s=i.split("?")[0].split("#")[0],a=X(s);if(!a){let c=await I()??F();R(S=>({...S,pathname:s,pendingError:{statusCode:404,message:"Not found"},ErrorPage:c??void 0}));return}let[m,...M]=await Promise.all([a.load(),...a.loadLayouts.map(c=>c())]);if(n.signal.aborted||!m.default)return;let E=await fetch(`/_data${i}`,{headers:{Accept:"application/json"},signal:n.signal});if(n.signal.aborted)return;if(!E.ok){if(E.status===404){window.location.href=i;return}let c=await I()??F();R(S=>({...S,pathname:s,pendingError:{statusCode:E.status,message:"Server error"},ErrorPage:c??void 0}));return}let p=await E.json();if(p.redirect){p.redirectReplace?window.history.replaceState(null,"",p.redirect):window.history.pushState(null,"",p.redirect),await w(p.redirect,n);return}window.scrollTo(0,0),R({pathname:s,params:p.params??{},loaderData:p.loaderData,layoutsData:(p.layouts??[]).map(c=>c.loaderData),Page:m.default,layouts:M.map(c=>c.default),metadata:p.metadata??null,viewport:p.viewport})},[]),b=N(async(i,n)=>{v.current?.abort();let s=new AbortController;v.current=s,A(!0);let a=async()=>{window.history[n?.replace?"replaceState":"pushState"](null,"",i),await w(i,s)};try{n?.viewTransition&&"startViewTransition"in document?await document.startViewTransition(a).finished:await a()}finally{s.signal.aborted||A(!1)}},[w]),z=N(async()=>{let i=window.location.pathname+window.location.search,n=new AbortController,s=await fetch(`/_data${i}`,{headers:{Accept:"application/json"},signal:n.signal});if(!s.ok)return;let a=await s.json();if(a.redirect){await b(a.redirect,{replace:a.redirectReplace});return}R(m=>({...m,loaderData:a.loaderData,layoutsData:(a.layouts??[]).map(M=>M.loaderData),params:a.params??m.params,metadata:a.metadata??m.metadata,viewport:a.viewport??m.viewport}))},[b]);Q(()=>{let i=()=>{v.current?.abort();let n=new AbortController;v.current=n;let s=window.location.pathname+window.location.search;w(s,n).catch(a=>{a.name!=="AbortError"&&console.error("[router] popstate error:",a)})};return window.addEventListener("popstate",i),()=>window.removeEventListener("popstate",i)},[w]);let k;if(o.pendingError)k=o.ErrorPage?d(o.ErrorPage,{...o.pendingError}):d("h1",{children:o.pendingError.statusCode});else{let i=d(y,{value:{loaderData:o.loaderData,params:o.params},children:d(o.Page,{data:o.loaderData,params:o.params,url:o.pathname})});for(let n=o.layouts.length-1;n>=0;n--){let s=o.layouts[n],a=o.layoutsData[n];i=d(y,{value:{loaderData:a,params:o.params},children:d(s,{data:a,params:o.params,children:i})})}k=d(D,{ErrorPage:o.ErrorPage,children:i},o.pathname)}return tt(j,{value:{metadata:o.metadata,viewport:o.viewport,clientEntry:U},children:[d($,{metadata:o.metadata,viewport:o.viewport}),d(T,{value:{...o,isNavigating:q,navigate:b,revalidate:z},children:k})]})}export{_t as RouterProvider,Tt as useLoaderData,vt as useNavigate,Dt as useParams,Et as useRevalidate,Rt as useRouter};
|
|
2
2
|
//# sourceMappingURL=router-provider.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/runtime/router-provider.tsx", "../../src/runtime/head.tsx", "../../src/runtime/context.tsx", "../../src/runtime/error-boundary.tsx"],
|
|
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]\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 window.scrollTo(0, 0)\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\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, 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 }\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 (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}/>\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"],
|
|
5
|
-
"mappings": "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
|
|
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 window.scrollTo(0, 0)\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\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, 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 }\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 (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}/>\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"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["useCallback", "useContext", "useEffect", "useRef", "useState", "RouterContext", "getDefaultErrorPage", "loadErrorPage", "matchClientRoute", "Fragment", "jsx", "collectTags", "metadata", "viewport", "tags", "ogTitle", "ogDesc", "twTitle", "twDesc", "lang", "href", "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", "loadRoute", "useCallback", "to", "controller", "pathname", "matched", "matchClientRoute", "ErrorPage", "loadErrorPage", "getDefaultErrorPage", "prev", "pageMod", "layoutMods", "l", "dataRes", "data", "m", "navigate", "options", "run", "revalidate", "useEffect", "handlePop", "err", "content", "tree", "i", "Layout", "layoutData", "DevixErrorBoundary", "PageMetaContext", "HeadSlot"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
async function
|
|
1
|
+
async function i(t){let s=new Set;for(let[,e]of t.moduleGraph.idToModuleMap)e.id&&(e.id.endsWith(".css")||e.id.includes(".css?"))&&e.url.startsWith("/")&&s.add(e.url);return[...s]}export{i as collectCss};
|
|
2
2
|
//# sourceMappingURL=collect-css.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/server/collect-css.ts"],
|
|
4
|
-
"sourcesContent": ["import type {ViteDevServer} from 'vite'\n\nexport async function collectCss(vite: ViteDevServer): Promise<string[]> {\n const cssUrls = new Set<string>()\n\n for (const [, mod] of vite.moduleGraph.idToModuleMap) {\n if (!mod.id) continue\n if (mod.id.endsWith('.css') || mod.id.includes('.css?')) {\n cssUrls.add(mod.url)\n }\n }\n\n return [...cssUrls]\n}"],
|
|
5
|
-
"mappings": "AAEA,eAAsBA,EAAWC,EAAwC,CACrE,IAAMC,EAAU,IAAI,IAEpB,OAAW,CAAC,CAAEC,CAAG,IAAKF,EAAK,YAAY,cAC9BE,EAAI,
|
|
4
|
+
"sourcesContent": ["import type {ViteDevServer} from 'vite'\n\nexport async function collectCss(vite: ViteDevServer): Promise<string[]> {\n const cssUrls = new Set<string>()\n\n for (const [, mod] of vite.moduleGraph.idToModuleMap) {\n if (!mod.id) continue\n if ((mod.id.endsWith('.css') || mod.id.includes('.css?')) && mod.url.startsWith('/')) {\n cssUrls.add(mod.url)\n }\n }\n\n return [...cssUrls]\n}"],
|
|
5
|
+
"mappings": "AAEA,eAAsBA,EAAWC,EAAwC,CACrE,IAAMC,EAAU,IAAI,IAEpB,OAAW,CAAC,CAAEC,CAAG,IAAKF,EAAK,YAAY,cAC9BE,EAAI,KACJA,EAAI,GAAG,SAAS,MAAM,GAAKA,EAAI,GAAG,SAAS,OAAO,IAAMA,EAAI,IAAI,WAAW,GAAG,GAC/ED,EAAQ,IAAIC,EAAI,GAAG,EAI3B,MAAO,CAAC,GAAGD,CAAO,CACtB",
|
|
6
6
|
"names": ["collectCss", "vite", "cssUrls", "mod"]
|
|
7
7
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/utils/banner.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import o from"picocolors";import{networkInterfaces as r}from"node:os";function s(e){let l=r();for(let n of Object.values(l))for(let t of n??[])if(t.family==="IPv4"&&!t.internal)return`http://${t.address}:${e}/`;return null}function $(e){let l="0.4.
|
|
1
|
+
import o from"picocolors";import{networkInterfaces as r}from"node:os";function s(e){let l=r();for(let n of Object.values(l))for(let t of n??[])if(t.family==="IPv4"&&!t.internal)return`http://${t.address}:${e}/`;return null}function $(e){let l="0.4.1-beta.1",n=s(e);console.log(),console.log(` ${o.bold(o.yellow("devix"))} ${o.dim(`v${l}`)}`),console.log(),console.log(` ${o.green("\u279C")} ${o.bold("Local:")} ${o.cyan(`http://localhost:${e}/`)}`),console.log(n?` ${o.green("\u279C")} ${o.bold("Network:")} ${o.cyan(n)}`:` ${o.green("\u279C")} ${o.bold("Network:")} ${o.dim("use --host to expose")}`),console.log()}export{$ as printDevBanner};
|
|
2
2
|
//# sourceMappingURL=banner.js.map
|
package/dist/vite/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{mergeConfig as
|
|
2
|
-
${t.map(
|
|
1
|
+
import{mergeConfig as ot}from"vite";import it from"@vitejs/plugin-react";import{fileURLToPath as at}from"node:url";import{dirname as st,resolve as u}from"node:path";function b({cssUrls:t}){return`
|
|
2
|
+
${t.map(n=>`import '${n}'`).join(`
|
|
3
3
|
`)}
|
|
4
4
|
import "@vitejs/plugin-react/preamble"
|
|
5
5
|
import React from "react"
|
|
@@ -54,7 +54,7 @@ if (!window.__DEVIX__) {
|
|
|
54
54
|
)
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
`}function
|
|
57
|
+
`}function I({pagesDir:t,matcherPath:e}){return`
|
|
58
58
|
import React from 'react'
|
|
59
59
|
import { createMatcher } from '${e}'
|
|
60
60
|
const pageFiles = import.meta.glob(['/${t}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])
|
|
@@ -82,7 +82,7 @@ export function getDefaultErrorPage() {
|
|
|
82
82
|
)
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
-
`}function
|
|
85
|
+
`}function L({pagesDir:t,renderPath:e}){return`
|
|
86
86
|
import { render as _render, runLoader as _runLoader, getStaticRoutes as _getStaticRoutes } from '${e}'
|
|
87
87
|
|
|
88
88
|
const _pages = import.meta.glob(['/${t}/**/*.tsx', '!**/error.tsx', '!**/layout.tsx'])
|
|
@@ -105,7 +105,7 @@ export function runLoader(url, request, options) {
|
|
|
105
105
|
export function getStaticRoutes() {
|
|
106
106
|
return _getStaticRoutes(_glob)
|
|
107
107
|
}
|
|
108
|
-
`}function
|
|
108
|
+
`}function M({apiPath:t,appDir:e}){return`
|
|
109
109
|
import { handleApiRequest as _handleApiRequest } from '${t}'
|
|
110
110
|
|
|
111
111
|
const _routes = import.meta.glob(['/${e}/api/**/*.ts', '!**/middleware.ts'])
|
|
@@ -120,16 +120,16 @@ const _glob = {
|
|
|
120
120
|
export function handleApiRequest(url, request) {
|
|
121
121
|
return _handleApiRequest(url, request, _glob)
|
|
122
122
|
}
|
|
123
|
-
`}function
|
|
123
|
+
`}function y(t){return t.replace(/\.(tsx|ts|jsx|js)$/,"").replace(/\(.*?\)\//g,"").replace(/^index$|\/index$/,"").replace(/\[([^\]]+)]/g,":$1")||"/"}var J=null;function R(){J=null}function O(t,e){let n=t.slice(e.length+1).replace(/\\/g,"/"),i=y(n);return i==="/"?"/api":`/api/${i}`.replace("/api//","/api/")}var X=null;function E(){X=null}function U(){return`
|
|
124
124
|
export {RouterContext} from '@devlusoft/devix/runtime/context'
|
|
125
|
-
`}import{readFileSync as
|
|
125
|
+
`}import{readFileSync as Y,readdirSync as Z,statSync as K}from"node:fs";import{join as _,relative as Q}from"node:path";var B=/export\s+(?:const|async\s+function|function)\s+(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\b/g;function z(t){return t.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"")}function H(t){let e=new Set;for(let n of z(t).matchAll(B))e.add(n[1]);return[...e]}function G(t,e){return"_api_"+t.slice(`${e}/`.length).replace(/\.(ts|tsx)$/,"").replace(/[^a-zA-Z0-9]/g,"_")}function k(t,e,n){return{filePath:t,urlPattern:O(t,e),identifier:G(t,e),methods:n}}function P(t,e){if(t.length===0)return`// auto-generado por devix \u2014 no editar
|
|
126
126
|
declare module '@devlusoft/devix' {
|
|
127
127
|
interface ApiRoutes {}
|
|
128
128
|
}
|
|
129
|
-
`;let
|
|
130
|
-
`),i=t.flatMap(o=>o.methods.map(
|
|
129
|
+
`;let n=t.map(o=>{let p="../"+o.filePath.replace(/\.(ts|tsx)$/,"");return`import type * as ${o.identifier} from '${p}'`}).join(`
|
|
130
|
+
`),i=t.flatMap(o=>o.methods.map(p=>` '${p} ${o.urlPattern}': InferRoute<(typeof ${o.identifier})['${p}']>`)).join(`
|
|
131
131
|
`);return`// auto-generado por devix \u2014 no editar
|
|
132
|
-
${
|
|
132
|
+
${n}
|
|
133
133
|
|
|
134
134
|
type JsonResponse<T> = Response & { readonly __body: T }
|
|
135
135
|
type UnwrapJson<T> = T extends JsonResponse<infer U> ? U : never
|
|
@@ -149,5 +149,5 @@ declare module '@devlusoft/devix' {
|
|
|
149
149
|
${i}
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
|
-
`}function
|
|
152
|
+
`}function F(t,e){let n=[];for(let i of Z(t)){let o=_(t,i);K(o).isDirectory()?n.push(...F(o,e)):/\.(ts|tsx)$/.test(i)&&n.push(Q(e,o).replace(/\\/g,"/"))}return n}function T(t,e){let n=_(e,t,"api"),i;try{i=F(n,e)}catch{return[]}return i.filter(o=>!o.endsWith("middleware.ts")&&!o.endsWith("middleware.tsx")).flatMap(o=>{try{let p=Y(_(e,o),"utf-8"),m=H(p);return m.length===0?[]:[k(o,`${t}/api`,m)]}catch{return[]}})}import{mkdirSync as tt,readFileSync as et,writeFileSync as rt,existsSync as nt}from"node:fs";import{join as j}from"node:path";function v(t,e){let n=j(e,".devix"),i=j(n,"routes.d.ts");return tt(n,{recursive:!0}),nt(i)&&et(i,"utf-8")===t?!1:(rt(i,t,"utf-8"),!0)}import{parseSync as ct}from"oxc-parser";var $=st(at(import.meta.url)),w="virtual:devix/entry-client",A="virtual:devix/client-routes",D="virtual:devix/render",C="virtual:devix/api",S="virtual:devix/context",q=new Set(["loader","guard","generateStaticParams","headers"]);function Bt(t){let e=t.appDir??"app",n=`${e}/pages`,i=(t.css??[]).map(r=>r.startsWith("/")?r:`/${r.replace(/^\.\//,"")}`),o=u($,"../server/render.js").replace(/\\/g,"/"),p=u($,"../server/api.js").replace(/\\/g,"/"),m=u($,"../runtime/client-router.js").replace(/\\/g,"/"),V={name:"devix",enforce:"pre",resolveId(r){if(r===w)return`\0${w}`;if(r===A)return`\0${A}`;if(r===D)return`\0${D}`;if(r===C)return`\0${C}`;if(r===S)return`\0${S}`},load(r){if(r===`\0${w}`)return b({cssUrls:i});if(r===`\0${A}`)return I({pagesDir:n,matcherPath:m});if(r===`\0${D}`)return L({pagesDir:n,renderPath:o});if(r===`\0${C}`)return M({apiPath:p,appDir:e});if(r===`\0${S}`)return U()},transform(r,c,d){if(d?.ssr)return;let a=u(process.cwd(),n);if(!c.startsWith(a))return;let N=ct(c,r,{sourceType:"module"}),g=[];for(let s of N.program.body){if(s.type!=="ExportNamedDeclaration"||!s.declaration)continue;let l=s.declaration;if(l.type==="FunctionDeclaration"&&l.id&&q.has(l.id.name)&&g.push({start:s.start,end:s.end,name:l.id.name}),l.type==="VariableDeclaration"){let h=new Set;for(let x of l.declarations)x.id.type==="Identifier"&&q.has(x.id.name)&&(h.has(s.start)||(h.add(s.start),g.push({start:s.start,end:s.end,name:x.id.name})))}}if(g.length===0)return;g.sort((s,l)=>l.start-s.start);let f=r;for(let{start:s,end:l,name:h}of g)f=f.slice(0,s)+`export const ${h} = undefined`+f.slice(l);return{code:f,map:null}},buildStart(){let r=process.cwd(),c=T(e,r);v(P(c,`${e}/api`),r)},configureServer(r){let c=process.cwd(),d=()=>{let a=T(e,c);v(P(a,`${e}/api`),c)};r.watcher.add(u(c,"devix.config.ts")),r.watcher.on("change",a=>{a===u(c,"devix.config.ts")&&(console.log("[devix] Config changed, restarting..."),process.exit(75))}),r.watcher.on("add",a=>{a.startsWith(u(c,n))&&R(),a.includes(`${e}/api`)&&(E(),d())}),r.watcher.on("unlink",a=>{a.startsWith(u(c,n))&&R(),a.includes(`${e}/api`)&&(E(),d())}),r.watcher.on("change",a=>{a.includes(`${e}/api`)&&!a.endsWith("middleware.ts")&&d()})}},W={plugins:[it(),V],publicDir:u(process.cwd(),t.publicDir??"public"),ssr:{noExternal:["@devlusoft/devix"]},...t.envPrefix?{envPrefix:t.envPrefix}:{}};return ot(W,t.vite??{})}export{Bt as devix};
|
|
153
153
|
//# sourceMappingURL=index.js.map
|