@native-router/react 1.3.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +0,0 @@
1
- let e=require("react"),r=require("history"),t=require("react/jsx-runtime"),n=require("@native-router/core"),o=require("@native-router/core/util"),u=require("use-sync-external-store/shim");var i=(0,e.createContext)(null);function a(e){return(0,t.jsx)(i.Provider,{...e})}function c(){return(0,e.useContext)(i)}var s=(0,e.createContext)(null);function l(){const r=c(),t=(0,e.useContext)(s);return r??t}var d=(0,e.createContext)([void 0,{}]);function f(){return(0,e.useContext)(d)}function x(){return f()[1]}function p({children:r,name:n,data:o}){const u=x(),i=(0,e.useMemo)(()=>[o,n?{...u,[n]:o}:u],[o,n,u]);return(0,t.jsx)(d.Provider,{value:i,children:r})}var h=(0,e.createContext)(void 0);function m(){return(0,e.useContext)(h)}function v(e){const[r,t]=f();return e?t[e]:r}var y=(0,e.createContext)(void 0);function b(){return(0,e.useContext)(y)}function g(e,r){return C(e,r,(e,r)=>e?.(r))}var j=new WeakMap;function P(e,r){const t=new Array(e.length);return C(e,r,(e,r)=>Promise.resolve(e?.(r)).then(e=>t[r.index]=e)).then(e=>(j.set(e,t),e))}function C(e,{router:r,location:o,signal:u},i){return Promise.all(e.map(({route:a},c)=>{const s={matched:e,params:(0,n.mergeMatchedParams)(e,c),index:c,router:r,location:o,search:(0,n.parseSearchInput)(o.search),signal:u??(new AbortController).signal};return Promise.all([a.search?(0,n.parseSearch)(a.search,o.search).then(e=>(s.search=e,i(a.data,s))):i(a.data,s),function(){if(!a.component)return l;const e=a.component(s);return Promise.resolve(e).then(e=>"default"in e?e.default:e)}()]).then(([e,r])=>(0,t.jsx)(p,{data:e,name:a.name,children:(0,t.jsx)(h.Provider,{value:s,children:(0,t.jsx)(r,{})})}),e=>{if(!a.errorComponent)throw e;return(0,t.jsx)(p,{data:void 0,name:a.name,children:(0,t.jsx)(h.Provider,{value:s,children:(0,t.jsx)(a.errorComponent,{error:e,ctx:s})})})})})).then(e=>e.reverse().reduce((e,r)=>(0,t.jsx)(a,{value:e,children:r})))}var w=(0,e.createContext)(null);function O({router:r,children:o}){const i=(0,e.useRef)((0,n.getCurrentView)(r)),c=(0,e.useCallback)(e=>(0,n.listen)(r,r=>{i.current=r,e()}),[r]),l=(0,e.useCallback)(()=>i.current,[]),d=(0,e.useCallback)(()=>(0,n.getCurrentView)(r),[r]),f=(0,u.useSyncExternalStore)(c,l,d),x=(0,e.useContext)(y),p=null==f&&"pending"===x?.status?function(e,r){const{resolving:o}=e,u=o?(0,n.match)(e,o.pathname):void 0;if(!u)return null;for(let n=u.length-1;n>=0;n--){const e=u[n].route.pendingComponent;if(e)return(0,t.jsx)(e,{},r)}return null}(r,x.key):null;return(0,t.jsx)(w.Provider,{value:r,children:void 0===o?f??p:(0,t.jsx)(a,{value:f,children:(0,t.jsx)(s.Provider,{value:p,children:o})})})}function R(e,r,{resolveView:t=g,...o}={}){return(0,n.create)(e,r,t,o)}function M({routes:r,children:u,...i},a){const[c,s]=(0,o.splitProps)(i,["baseUrl","currentView"]),{baseUrl:l,currentView:d}=c,[f,x]=(0,e.useState)(),p=(0,e.useMemo)(()=>R(r,a(),{...i,onLoadingChange(e){x(e&&{key:(0,o.uniqId)(),status:e})}}),[r,a,l,d]);(0,e.useEffect)(()=>{(0,n.setOptions)(p,{...s,onLoadingChange(e){x(e&&{key:(0,o.uniqId)(),status:e})}})},[p,s]);const h=(0,e.useMemo)(()=>(0,t.jsx)(O,{router:p,children:u}),[p,u]);return(0,t.jsx)(y.Provider,{value:f,children:h})}function S(e){return M(e,r.createBrowserHistory)}function H(e){return M(e,r.createHashHistory)}function V({initialEntries:t,initialIndex:n,...o}){return M(o,(0,e.useMemo)(()=>()=>(0,r.createMemoryHistory)({initialEntries:t,initialIndex:n}),[t,n]))}function q(){const r=(0,e.useContext)(w);if(!r)throw new Error("useRouter() must be used within a <Router> component");return r}var k="_nativeRouterReactSSRData";function E(e,r,o){return(0,n.resolve)(e,r).then(n=>{const u=function(e){return j.get(e)}(n),i=e.history.location.state?.index||0;return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(O,{router:e,children:n}),(0,t.jsx)("script",{...o?.scriptAttributes,suppressHydrationWarning:!0,dangerouslySetInnerHTML:{__html:`window.${o?.hydrateKey||k} = ${a={data:u,location:r,index:i},JSON.stringify(a).replace(/</g,"\\u003c").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")};`}})]});var a})}function I(e,t,{scriptAttributes:u,hydrateKey:i,...a}={}){const c=(0,n.create)(e,(0,r.createMemoryHistory)({initialEntries:[t]}),P,a);return E(c,(0,o.isString)(t)?(0,n.toLocation)(c,t):t,{scriptAttributes:u,hydrateKey:i})}function A(e,t){const{data:o,location:u,index:i=0}=window[t?.hydrateKey||k],a=(0,r.createBrowserHistory)();a.replace((0,r.createPath)(a.location),{index:i});const c=(0,n.create)(e,a,function(e){return(r,t)=>C(r,t,(r,t)=>e[t.index])}(o),t);return(0,n.resolve)(c,u).then(e=>({view:e,router:c}))}Object.defineProperty(exports,"HashRouter",{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,"HistoryRouter",{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,"MemoryRouter",{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,"Router",{enumerable:!0,get:function(){return O}}),Object.defineProperty(exports,"View",{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,"createRouter",{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,"hydrate",{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,"resolveServerView",{enumerable:!0,get:function(){return I}}),Object.defineProperty(exports,"resolveView",{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,"useData",{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,"useLoading",{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,"useMatched",{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,"useNamedData",{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,"useRouter",{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,"useView",{enumerable:!0,get:function(){return c}});
2
- //# sourceMappingURL=ssr-Cow2_ikA.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ssr-Cow2_ikA.cjs","names":[],"sources":["../src/context.tsx","../src/resolve-view.tsx","../src/components/Router.tsx","../src/ssr.tsx"],"sourcesContent":["import {createContext, ReactNode, useContext, useMemo} from 'react';\nimport type {Context, LoadStatus, Route} from './types';\n\nconst ViewContext = createContext<ReactNode>(null);\n\nexport function ViewProvider(props: {children: ReactNode; value: ReactNode}) {\n return <ViewContext.Provider {...props} />;\n}\n\n/**\n * @group Hooks\n * @see {@link View View Component}\n */\nexport function useView() {\n return useContext(ViewContext);\n}\n\n/**\n * Route-level pending skeleton(`pendingComponent` of the nearest matched\n * ancestor), set by the Router only while a navigation is pending with no\n * previous view to retain(cold start, refresh, re-navigation after an\n * error); `null` otherwise, so in-app navigation keeps the previous view.\n * @see {@link Route.pendingComponent}\n */\nexport const PendingContext = createContext<ReactNode>(null);\n\n/**\n * Used for route component to render child route component.\n * It just render the return of {@link useView}, falling back to the\n * route-level pending skeleton when the view slot is empty.\n * @group Components\n */\nexport function View() {\n const view = useView();\n const pending = useContext(PendingContext);\n return view ?? pending;\n}\n\nconst DataContext = createContext<[any, Record<string, any>]>([undefined, {}]);\n\nfunction useDataContext() {\n return useContext(DataContext);\n}\n\n/**\n * Get the named data map of the resolved route levels: an object keyed by\n * each ancestor's `name`, holding its resolved `data`. The current level\n * is included only when it declares a `name`.\n *\n * Give the generic the expected map shape to read values type-safely:\n * `useNamedData<{user: User}>()`.\n * @group Hooks\n */\nexport function useNamedData<T = Record<string, unknown>>() {\n return useDataContext()[1] as T;\n}\n\nexport function DataProvider({\n children,\n name,\n data\n}: {\n children: ReactNode;\n data: any;\n name?: string;\n}) {\n const namedData = useNamedData();\n const value = useMemo(\n () => [data, name ? {...namedData, [name]: data} : namedData] as [any, any],\n [data, name, namedData]\n );\n return <DataContext.Provider value={value}>{children}</DataContext.Provider>;\n}\n\nexport const MatchedContext = createContext<Context<Route> | undefined>(\n undefined\n);\n\n/**\n * @group Hooks\n */\nexport function useMatched() {\n return useContext(MatchedContext)!;\n}\n\n/**\n * Get the resolved `data` of the current route level, or the named data\n * of an ancestor level when `name` is given.\n *\n * Give the generic the expected data type to read it type-safely without\n * a cast: `useData<Article>()` → `Article | undefined`.\n * @group Hooks\n */\nexport function useData<T = unknown>(name?: string): T | undefined {\n const [data, namedData] = useDataContext();\n return (name ? namedData[name] : data) as T | undefined;\n}\n\nexport const LoadingContext = createContext<LoadStatus | undefined>(undefined);\n\n/**\n * @group Hooks\n */\nexport function useLoading() {\n return useContext(LoadingContext);\n}\n","import type {ComponentType, ReactElement} from 'react';\nimport type {Context, ResolveViewContext, Route} from '@@/types';\nimport {\n mergeMatchedParams,\n parseSearch,\n parseSearchInput\n} from '@native-router/core';\nimport type {Matched} from '@native-router/core';\nimport {DataProvider, MatchedContext, View, ViewProvider} from './context';\n\n/**\n * The default implementation of resolve view\n * @param matched the matched result\n * @param viewContext resolved view context\n * @returns the resolve view\n * @see {@link create router->create}\n */\nexport default function resolveView(\n matched: Matched<Route>[],\n ctx: ResolveViewContext<Route>\n) {\n return resolveViewBase(matched, ctx, (data, dataCtx) => data?.(dataCtx));\n}\n\nconst viewDataMap = new WeakMap<ReactElement, any[]>();\n\nexport function resolveViewServer(\n matched: Matched<Route>[],\n ctx: ResolveViewContext<Route>\n) {\n const dataResults = new Array(matched.length);\n return resolveViewBase(matched, ctx, (data, dataCtx) =>\n Promise.resolve(data?.(dataCtx)).then(\n (result) => (dataResults[dataCtx.index] = result)\n )\n ).then((view) => {\n viewDataMap.set(view, dataResults);\n return view;\n });\n}\n\nexport function createHydrateResolveView(data: any[]) {\n return (matched: Matched<Route>[], ctx: ResolveViewContext<Route>) =>\n resolveViewBase(matched, ctx, (_, dataCtx) => data[dataCtx.index]);\n}\n\nexport function getViewData(view: ReactElement) {\n return viewDataMap.get(view);\n}\n\nfunction resolveViewBase(\n matched: Matched<Route>[],\n {router, location, signal}: ResolveViewContext<Route>,\n resolveData: (\n dataFetcher: ((ctx: Context<Route>) => any) | undefined,\n ctx: Context<Route>\n ) => any\n) {\n return Promise.all(\n matched.map(({route}, index) => {\n // `search` starts as the degraded input and is upgraded to the\n // schema output before the data fetcher runs below; schema outputs\n // are user-typed(`Route<P, S>`), so the property stays `any` here.\n const ctx: Context<Route, Record<string, string>, any> = {\n matched: matched!,\n params: mergeMatchedParams(matched, index),\n index,\n router,\n location,\n search: parseSearchInput(location.search),\n // The chain's abort signal(navigation-superseded/cancelled) is\n // forwarded to every level's loader; a hand-rolled resolveView\n // context without one still yields a never-aborting signal.\n signal: signal ?? new AbortController().signal\n };\n function resolveComponent(): ComponentType | Promise<ComponentType> {\n if (!route.component) return View;\n const r = route.component(ctx);\n return Promise.resolve(r).then((m) => ('default' in m ? m.default : m));\n }\n\n // The level's search schema runs before its data fetcher: the parsed\n // output replaces the degraded input in `ctx.search`, and a rejected\n // validation fails the level exactly like a data error.\n const resolveDataWithSearch = () =>\n route.search\n ? parseSearch(route.search, location.search).then((search) => {\n ctx.search = search;\n return resolveData(route.data, ctx);\n })\n : resolveData(route.data, ctx);\n\n // A level that fails to resolve (search, data or component) is\n // replaced by its route-level errorComponent when configured;\n // otherwise the error bubbles up to the global errorHandler as before.\n return Promise.all([resolveDataWithSearch(), resolveComponent()]).then(\n ([data, C]) => (\n <DataProvider data={data} name={route.name}>\n <MatchedContext.Provider value={ctx}>\n <C />\n </MatchedContext.Provider>\n </DataProvider>\n ),\n (error: Error) => {\n if (!route.errorComponent) throw error;\n return (\n <DataProvider data={undefined} name={route.name}>\n <MatchedContext.Provider value={ctx}>\n <route.errorComponent error={error} ctx={ctx} />\n </MatchedContext.Provider>\n </DataProvider>\n );\n }\n );\n })\n ).then((views) =>\n views\n .reverse()\n .reduce((acc, view) => <ViewProvider value={acc}>{view}</ViewProvider>)\n );\n}\n","import {\n ReactNode,\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState\n} from 'react';\nimport {\n History,\n createBrowserHistory,\n createHashHistory,\n createMemoryHistory,\n MemoryHistoryOptions\n} from 'history';\nimport type {LoadStatus, Route} from '@@/types';\nimport {LoadingContext, PendingContext, ViewProvider} from '@@/context';\nimport {\n create,\n getCurrentView,\n listen,\n match,\n setOptions\n} from '@native-router/core';\nimport type {Options, ResolveView, RouterInstance} from '@native-router/core';\nimport {splitProps, uniqId} from '@native-router/core/util';\nimport {useSyncExternalStore} from 'use-sync-external-store/shim';\nimport defaultResolve from '@@/resolve-view';\n\nconst RouterContext = createContext<RouterInstance<Route, ReactNode> | null>(\n null\n);\n\ntype Props = {\n children?: ReactNode;\n routes: Route[] | Route;\n resolveView?: typeof defaultResolve;\n} & Omit<Options<ReactNode>, 'onLoadingChange'>;\n\n/**\n * Base Router Component.\n * @group Components\n */\nexport function Router({\n router,\n children\n}: {\n children?: ReactNode;\n router: RouterInstance<Route, ReactNode>;\n}) {\n const viewRef = useRef<ReactNode>(getCurrentView(router));\n const subscribe = useCallback(\n (onStoreChange: () => void) =>\n listen(router, (view) => {\n viewRef.current = view;\n onStoreChange();\n }),\n [router]\n );\n const getSnapshot = useCallback(() => viewRef.current, []);\n // `getServerSnapshot` is required by the native implementation when the\n // Router is rendered inside server-rendered content(e.g. resolveServerView).\n const getServerSnapshot = useCallback(() => getCurrentView(router), [router]);\n const view = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n // Route-level pending skeleton, only when no previous view is retained\n // (cold start, refresh, re-navigation after an error); in-app navigation\n // keeps the old view by design, the global loading signal already\n // covers that phase. Reading LoadingContext here also re-renders the\n // Router on every loading transition.\n const loading = useContext(LoadingContext);\n const pending =\n view == null && loading?.status === 'pending'\n ? resolvePendingView(router, loading.key)\n : null;\n\n return (\n <RouterContext.Provider value={router}>\n {children === undefined ? (\n (view ?? pending)\n ) : (\n <ViewProvider value={view}>\n <PendingContext.Provider value={pending}>\n {children}\n </PendingContext.Provider>\n </ViewProvider>\n )}\n </RouterContext.Provider>\n );\n}\n\n/**\n * Render the `pendingComponent` of the nearest matched ancestor of the\n * resolving location, walked deepest first(the resolving route's own\n * included). Keyed by the loading episode so a new pending phase remounts\n * the skeleton(stateful shimmer animations restart). Guards may still\n * redirect the resolution away; until then the initially matched chain\n * is the best — and only — answer available.\n */\nfunction resolvePendingView(\n router: RouterInstance<Route, ReactNode>,\n key: number\n) {\n const {resolving} = router;\n const matched = resolving ? match(router, resolving.pathname) : undefined;\n if (!matched) return null;\n for (let i = matched.length - 1; i >= 0; i--) {\n const Pending = matched[i].route.pendingComponent;\n if (Pending) return <Pending key={key} />;\n }\n return null;\n}\n\nexport function createRouter(\n routes: Route | Route[],\n history: History,\n {\n resolveView = defaultResolve,\n ...options\n }: Options<ReactNode> & {resolveView?: ResolveView<Route, ReactNode>} = {}\n): RouterInstance<Route, ReactNode> {\n return create(routes, history, resolveView, options);\n}\n\nfunction useNewRouter(\n {routes, children, ...options}: Props,\n createHistory: () => History\n) {\n const [tracked, rest] = splitProps(options, ['baseUrl', 'currentView']);\n const {baseUrl, currentView} = tracked;\n const [loading, setLoading] = useState<LoadStatus>();\n // Initial options are baked in at creation: the cold-start resolve fires\n // from the subscribe effect(children effects run first) before the\n // setOptions effect below runs, and the default errorHandler would let\n // listen's refresh().catch(noop) swallow a first failure, leaving the\n // view blank forever.\n const router = useMemo(\n () =>\n createRouter(routes, createHistory(), {\n ...options,\n onLoadingChange(status) {\n setLoading(status && {key: uniqId(), status});\n }\n }),\n // Only the tracked options belong to the deps: option updates flow\n // through the setOptions effect below instead of recreating the router.\n [routes, createHistory, baseUrl, currentView]\n );\n\n // Options are refreshed on every commit, so `onLoadingChange` and the\n // callback options always see the latest closure.\n useEffect(() => {\n setOptions(router, {\n ...rest,\n onLoadingChange(status) {\n setLoading(status && {key: uniqId(), status});\n }\n });\n }, [router, rest]);\n\n const r = useMemo(\n () => <Router router={router}>{children}</Router>,\n [router, children]\n );\n\n return <LoadingContext.Provider value={loading}>{r}</LoadingContext.Provider>;\n}\n\n/**\n * History mode Router Component.\n * @group Components\n */\nexport function HistoryRouter(props: Props) {\n return useNewRouter(props, createBrowserHistory);\n}\n\n/**\n * Hash mode Router Component.\n * @group Components\n */\nexport function HashRouter(props: Props) {\n return useNewRouter(props, createHashHistory);\n}\n\n/**\n * Memory mode Router Component.\n * @group Components\n */\nexport function MemoryRouter({\n initialEntries,\n initialIndex,\n ...props\n}: Props & MemoryHistoryOptions) {\n const createHistory = useMemo(\n () => () => createMemoryHistory({initialEntries, initialIndex}),\n [initialEntries, initialIndex]\n );\n return useNewRouter(props, createHistory);\n}\n\n/**\n * Get Router instance.\n * @group Hooks\n * @returns Router Instance\n */\nexport function useRouter() {\n const router = useContext(RouterContext);\n if (!router) {\n throw new Error('useRouter() must be used within a <Router> component');\n }\n return router;\n}\n","import {createBrowserHistory, createMemoryHistory, createPath} from 'history';\nimport {ReactElement, ReactNode} from 'react';\nimport {create, resolve, toLocation} from '@native-router/core';\nimport type {\n HistoryState,\n Location,\n Options,\n RouterInstance\n} from '@native-router/core';\nimport {isString} from '@native-router/core/util';\nimport {Router} from './components/Router';\nimport {\n createHydrateResolveView,\n getViewData,\n resolveViewServer\n} from './resolve-view';\nimport type {Route} from './types';\n\nconst defaultHydrateKey = '_nativeRouterReactSSRData';\n\n/**\n * Serialize the SSR payload for embedding in a script element.\n * `JSON.stringify` does not escape `<`, U+2028 and U+2029,\n * so route data like `</script>` would break out of the script element.\n * @param payload the payload to serialize\n * @returns the escaped JSON string\n */\nfunction serializePayload(payload: {\n data?: any[];\n location: Location;\n index: number;\n}) {\n return JSON.stringify(payload)\n .replace(/</g, '\\\\u003c')\n .replace(/\\u2028/g, '\\\\u2028')\n .replace(/\\u2029/g, '\\\\u2029');\n}\n\nexport function resolveServerViewBase(\n router: RouterInstance<Route, ReactNode>,\n location: Location,\n options?: {\n scriptAttributes?: Record<string, string>;\n hydrateKey?: string;\n }\n) {\n return resolve<Route, ReactNode>(router, location).then((view) => {\n const data = getViewData(view as ReactElement);\n const index =\n (router.history.location.state as HistoryState | undefined)?.index || 0;\n return (\n <>\n <Router router={router}>{view}</Router>\n <script\n {...options?.scriptAttributes}\n suppressHydrationWarning\n // eslint-disable-next-line @eslint-react/dom-no-dangerously-set-innerhtml -- serialized state for hydration\n dangerouslySetInnerHTML={{\n __html: `window.${\n options?.hydrateKey || defaultHydrateKey\n } = ${serializePayload({data, location, index})};`\n }}\n />\n </>\n );\n });\n}\n\nexport function resolveServerView(\n routes: Route | Route[],\n location: Location | string,\n {\n scriptAttributes,\n hydrateKey,\n ...options\n }: Options<ReactElement> & {\n scriptAttributes?: Record<string, string>;\n hydrateKey?: string;\n } = {}\n) {\n const router = create(\n routes,\n createMemoryHistory({initialEntries: [location]}),\n resolveViewServer,\n options\n );\n\n return resolveServerViewBase(\n router,\n isString(location) ? toLocation(router, location) : location,\n {\n scriptAttributes,\n hydrateKey\n }\n );\n}\n\n/**\n * Hydrate the SSR result of {@link resolveServerView} on the client.\n * The router is bound to the browser history(aligned with the index\n * in the SSR payload), so navigation after hydration updates the address bar.\n * @param routes routes config, must match the server side\n * @param options options, `hydrateKey` must match the server side\n * @returns the resolved view and the router instance, for example:\n * `const {view, router} = await hydrate(routes);`\n * `hydrateRoot(root, <Router router={router}>{view}</Router>)`\n * @group Methods\n */\nexport function hydrate(\n routes: Route | Route[],\n options?: Options<ReactElement> & {\n hydrateKey?: string;\n }\n): Promise<{view: ReactNode; router: RouterInstance<Route, ReactNode>}> {\n const {\n data,\n location,\n index = 0\n } = (window as any)[options?.hydrateKey || defaultHydrateKey] as {\n data: any[];\n location: Location;\n index?: number;\n };\n const history = createBrowserHistory();\n history.replace(createPath(history.location), {index});\n const router = create(\n routes,\n history,\n createHydrateResolveView(data),\n options\n );\n return resolve<Route, ReactNode>(router, location).then((view) => ({\n view,\n router\n }));\n}\n"],"mappings":"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"}
@@ -1,8 +0,0 @@
1
- import{createContext as r,useCallback as n,useContext as e,useEffect as t,useMemo as i,useRef as o,useState as a}from"react";import{createBrowserHistory as u,createHashHistory as c,createMemoryHistory as s,createPath as l}from"history";import{Fragment as d,jsx as h,jsxs as f}from"react/jsx-runtime";import{create as v,getCurrentView as m,listen as p,match as g,mergeMatchedParams as y,parseSearch as w,parseSearchInput as x,resolve as P,setOptions as b,toLocation as C}from"@native-router/core";import{isString as A,splitProps as R,uniqId as k}from"@native-router/core/util";import{useSyncExternalStore as E}from"use-sync-external-store/shim";var K=r(null);function S(r){/* @__PURE__ */
2
- return h(K.Provider,{...r})}function I(){return e(K)}var L=r(null);function V(){const r=I(),n=e(L);return r??n}var _=r([void 0,{}]);function H(){return e(_)}function M(){return H()[1]}function U({children:r,name:n,data:e}){const t=M(),o=i(()=>[e,n?{...t,[n]:e}:t],[e,n,t]);/* @__PURE__ */
3
- return h(_.Provider,{value:o,children:r})}var W=r(void 0);function $(){return e(W)}function j(r){const[n,e]=H();return r?e[r]:n}var D=r(void 0);function J(){return e(D)}function N(r,n){return q(r,n,(r,n)=>r?.(n))}var O=/* @__PURE__ */new WeakMap;function T(r,n){const e=new Array(r.length);return q(r,n,(r,n)=>Promise.resolve(r?.(n)).then(r=>e[n.index]=r)).then(r=>(O.set(r,e),r))}function q(r,{router:n,location:e,signal:t},i){return Promise.all(r.map(({route:o},a)=>{const u={matched:r,params:y(r,a),index:a,router:n,location:e,search:x(e.search),signal:t??(new AbortController).signal};return Promise.all([o.search?w(o.search,e.search).then(r=>(u.search=r,i(o.data,u))):i(o.data,u),function(){if(!o.component)return V;const r=o.component(u);return Promise.resolve(r).then(r=>"default"in r?r.default:r)}()]).then(([r,n])=>/* @__PURE__ */h(U,{data:r,name:o.name,children:/* @__PURE__ */h(W.Provider,{value:u,children:/* @__PURE__ */h(n,{})})}),r=>{if(!o.errorComponent)throw r;/* @__PURE__ */
4
- return h(U,{data:void 0,name:o.name,children:/* @__PURE__ */h(W.Provider,{value:u,children:/* @__PURE__ */h(o.errorComponent,{error:r,ctx:u})})})})})).then(r=>r.reverse().reduce((r,n)=>/* @__PURE__ */h(S,{value:r,children:n})))}var z=r(null);function B({router:r,children:t}){const i=o(m(r)),a=n(n=>p(r,r=>{i.current=r,n()}),[r]),u=n(()=>i.current,[]),c=n(()=>m(r),[r]),s=E(a,u,c),l=e(D),d=null==s&&"pending"===l?.status?function(r,n){const{resolving:e}=r,t=e?g(r,e.pathname):void 0;if(!t)return null;for(let i=t.length-1;i>=0;i--){const r=t[i].route.pendingComponent;if(r)/* @__PURE__ */return h(r,{},n)}return null}(r,l.key):null;/* @__PURE__ */
5
- return h(z.Provider,{value:r,children:void 0===t?s??d:/* @__PURE__ */h(S,{value:s,children:/* @__PURE__ */h(L.Provider,{value:d,children:t})})})}function F(r,n,{resolveView:e=N,...t}={}){return v(r,n,e,t)}function G({routes:r,children:n,...e},o){const[u,c]=R(e,["baseUrl","currentView"]),{baseUrl:s,currentView:l}=u,[d,f]=a(),v=i(()=>F(r,o(),{...e,onLoadingChange(r){f(r&&{key:k(),status:r})}}),[r,o,s,l]);t(()=>{b(v,{...c,onLoadingChange(r){f(r&&{key:k(),status:r})}})},[v,c]);const m=i(()=>/* @__PURE__ */h(B,{router:v,children:n}),[v,n]);/* @__PURE__ */
6
- return h(D.Provider,{value:d,children:m})}function Q(r){return G(r,u)}function X(r){return G(r,c)}function Y({initialEntries:r,initialIndex:n,...e}){return G(e,i(()=>()=>s({initialEntries:r,initialIndex:n}),[r,n]))}function Z(){const r=e(z);if(!r)throw new Error("useRouter() must be used within a <Router> component");return r}var rr="_nativeRouterReactSSRData";function nr(r,n,e){return P(r,n).then(t=>{const i=function(r){return O.get(r)}(t),o=r.history.location.state?.index||0;/* @__PURE__ */
7
- return f(d,{children:[/* @__PURE__ */h(B,{router:r,children:t}),/* @__PURE__ */h("script",{...e?.scriptAttributes,suppressHydrationWarning:!0,dangerouslySetInnerHTML:{__html:`window.${e?.hydrateKey||rr} = ${a={data:i,location:n,index:o},JSON.stringify(a).replace(/</g,"\\u003c").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")};`}})]});var a})}function er(r,n,{scriptAttributes:e,hydrateKey:t,...i}={}){const o=v(r,s({initialEntries:[n]}),T,i);return nr(o,A(n)?C(o,n):n,{scriptAttributes:e,hydrateKey:t})}function tr(r,n){const{data:e,location:t,index:i=0}=window[n?.hydrateKey||rr],o=u();o.replace(l(o.location),{index:i});const a=v(r,o,function(r){return(n,e)=>q(n,e,(n,e)=>r[e.index])}(e),n);return P(a,t).then(r=>({view:r,router:a}))}export{Y as a,Z as c,j as d,J as f,I as h,Q as i,N as l,M as m,er as n,B as o,$ as p,X as r,F as s,tr as t,V as u};
8
- //# sourceMappingURL=ssr-j5c5cH-B.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ssr-j5c5cH-B.js","names":[],"sources":["../src/context.tsx","../src/resolve-view.tsx","../src/components/Router.tsx","../src/ssr.tsx"],"sourcesContent":["import {createContext, ReactNode, useContext, useMemo} from 'react';\nimport type {Context, LoadStatus, Route} from './types';\n\nconst ViewContext = createContext<ReactNode>(null);\n\nexport function ViewProvider(props: {children: ReactNode; value: ReactNode}) {\n return <ViewContext.Provider {...props} />;\n}\n\n/**\n * @group Hooks\n * @see {@link View View Component}\n */\nexport function useView() {\n return useContext(ViewContext);\n}\n\n/**\n * Route-level pending skeleton(`pendingComponent` of the nearest matched\n * ancestor), set by the Router only while a navigation is pending with no\n * previous view to retain(cold start, refresh, re-navigation after an\n * error); `null` otherwise, so in-app navigation keeps the previous view.\n * @see {@link Route.pendingComponent}\n */\nexport const PendingContext = createContext<ReactNode>(null);\n\n/**\n * Used for route component to render child route component.\n * It just render the return of {@link useView}, falling back to the\n * route-level pending skeleton when the view slot is empty.\n * @group Components\n */\nexport function View() {\n const view = useView();\n const pending = useContext(PendingContext);\n return view ?? pending;\n}\n\nconst DataContext = createContext<[any, Record<string, any>]>([undefined, {}]);\n\nfunction useDataContext() {\n return useContext(DataContext);\n}\n\n/**\n * Get the named data map of the resolved route levels: an object keyed by\n * each ancestor's `name`, holding its resolved `data`. The current level\n * is included only when it declares a `name`.\n *\n * Give the generic the expected map shape to read values type-safely:\n * `useNamedData<{user: User}>()`.\n * @group Hooks\n */\nexport function useNamedData<T = Record<string, unknown>>() {\n return useDataContext()[1] as T;\n}\n\nexport function DataProvider({\n children,\n name,\n data\n}: {\n children: ReactNode;\n data: any;\n name?: string;\n}) {\n const namedData = useNamedData();\n const value = useMemo(\n () => [data, name ? {...namedData, [name]: data} : namedData] as [any, any],\n [data, name, namedData]\n );\n return <DataContext.Provider value={value}>{children}</DataContext.Provider>;\n}\n\nexport const MatchedContext = createContext<Context<Route> | undefined>(\n undefined\n);\n\n/**\n * @group Hooks\n */\nexport function useMatched() {\n return useContext(MatchedContext)!;\n}\n\n/**\n * Get the resolved `data` of the current route level, or the named data\n * of an ancestor level when `name` is given.\n *\n * Give the generic the expected data type to read it type-safely without\n * a cast: `useData<Article>()` → `Article | undefined`.\n * @group Hooks\n */\nexport function useData<T = unknown>(name?: string): T | undefined {\n const [data, namedData] = useDataContext();\n return (name ? namedData[name] : data) as T | undefined;\n}\n\nexport const LoadingContext = createContext<LoadStatus | undefined>(undefined);\n\n/**\n * @group Hooks\n */\nexport function useLoading() {\n return useContext(LoadingContext);\n}\n","import type {ComponentType, ReactElement} from 'react';\nimport type {Context, ResolveViewContext, Route} from '@@/types';\nimport {\n mergeMatchedParams,\n parseSearch,\n parseSearchInput\n} from '@native-router/core';\nimport type {Matched} from '@native-router/core';\nimport {DataProvider, MatchedContext, View, ViewProvider} from './context';\n\n/**\n * The default implementation of resolve view\n * @param matched the matched result\n * @param viewContext resolved view context\n * @returns the resolve view\n * @see {@link create router->create}\n */\nexport default function resolveView(\n matched: Matched<Route>[],\n ctx: ResolveViewContext<Route>\n) {\n return resolveViewBase(matched, ctx, (data, dataCtx) => data?.(dataCtx));\n}\n\nconst viewDataMap = new WeakMap<ReactElement, any[]>();\n\nexport function resolveViewServer(\n matched: Matched<Route>[],\n ctx: ResolveViewContext<Route>\n) {\n const dataResults = new Array(matched.length);\n return resolveViewBase(matched, ctx, (data, dataCtx) =>\n Promise.resolve(data?.(dataCtx)).then(\n (result) => (dataResults[dataCtx.index] = result)\n )\n ).then((view) => {\n viewDataMap.set(view, dataResults);\n return view;\n });\n}\n\nexport function createHydrateResolveView(data: any[]) {\n return (matched: Matched<Route>[], ctx: ResolveViewContext<Route>) =>\n resolveViewBase(matched, ctx, (_, dataCtx) => data[dataCtx.index]);\n}\n\nexport function getViewData(view: ReactElement) {\n return viewDataMap.get(view);\n}\n\nfunction resolveViewBase(\n matched: Matched<Route>[],\n {router, location, signal}: ResolveViewContext<Route>,\n resolveData: (\n dataFetcher: ((ctx: Context<Route>) => any) | undefined,\n ctx: Context<Route>\n ) => any\n) {\n return Promise.all(\n matched.map(({route}, index) => {\n // `search` starts as the degraded input and is upgraded to the\n // schema output before the data fetcher runs below; schema outputs\n // are user-typed(`Route<P, S>`), so the property stays `any` here.\n const ctx: Context<Route, Record<string, string>, any> = {\n matched: matched!,\n params: mergeMatchedParams(matched, index),\n index,\n router,\n location,\n search: parseSearchInput(location.search),\n // The chain's abort signal(navigation-superseded/cancelled) is\n // forwarded to every level's loader; a hand-rolled resolveView\n // context without one still yields a never-aborting signal.\n signal: signal ?? new AbortController().signal\n };\n function resolveComponent(): ComponentType | Promise<ComponentType> {\n if (!route.component) return View;\n const r = route.component(ctx);\n return Promise.resolve(r).then((m) => ('default' in m ? m.default : m));\n }\n\n // The level's search schema runs before its data fetcher: the parsed\n // output replaces the degraded input in `ctx.search`, and a rejected\n // validation fails the level exactly like a data error.\n const resolveDataWithSearch = () =>\n route.search\n ? parseSearch(route.search, location.search).then((search) => {\n ctx.search = search;\n return resolveData(route.data, ctx);\n })\n : resolveData(route.data, ctx);\n\n // A level that fails to resolve (search, data or component) is\n // replaced by its route-level errorComponent when configured;\n // otherwise the error bubbles up to the global errorHandler as before.\n return Promise.all([resolveDataWithSearch(), resolveComponent()]).then(\n ([data, C]) => (\n <DataProvider data={data} name={route.name}>\n <MatchedContext.Provider value={ctx}>\n <C />\n </MatchedContext.Provider>\n </DataProvider>\n ),\n (error: Error) => {\n if (!route.errorComponent) throw error;\n return (\n <DataProvider data={undefined} name={route.name}>\n <MatchedContext.Provider value={ctx}>\n <route.errorComponent error={error} ctx={ctx} />\n </MatchedContext.Provider>\n </DataProvider>\n );\n }\n );\n })\n ).then((views) =>\n views\n .reverse()\n .reduce((acc, view) => <ViewProvider value={acc}>{view}</ViewProvider>)\n );\n}\n","import {\n ReactNode,\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState\n} from 'react';\nimport {\n History,\n createBrowserHistory,\n createHashHistory,\n createMemoryHistory,\n MemoryHistoryOptions\n} from 'history';\nimport type {LoadStatus, Route} from '@@/types';\nimport {LoadingContext, PendingContext, ViewProvider} from '@@/context';\nimport {\n create,\n getCurrentView,\n listen,\n match,\n setOptions\n} from '@native-router/core';\nimport type {Options, ResolveView, RouterInstance} from '@native-router/core';\nimport {splitProps, uniqId} from '@native-router/core/util';\nimport {useSyncExternalStore} from 'use-sync-external-store/shim';\nimport defaultResolve from '@@/resolve-view';\n\nconst RouterContext = createContext<RouterInstance<Route, ReactNode> | null>(\n null\n);\n\ntype Props = {\n children?: ReactNode;\n routes: Route[] | Route;\n resolveView?: typeof defaultResolve;\n} & Omit<Options<ReactNode>, 'onLoadingChange'>;\n\n/**\n * Base Router Component.\n * @group Components\n */\nexport function Router({\n router,\n children\n}: {\n children?: ReactNode;\n router: RouterInstance<Route, ReactNode>;\n}) {\n const viewRef = useRef<ReactNode>(getCurrentView(router));\n const subscribe = useCallback(\n (onStoreChange: () => void) =>\n listen(router, (view) => {\n viewRef.current = view;\n onStoreChange();\n }),\n [router]\n );\n const getSnapshot = useCallback(() => viewRef.current, []);\n // `getServerSnapshot` is required by the native implementation when the\n // Router is rendered inside server-rendered content(e.g. resolveServerView).\n const getServerSnapshot = useCallback(() => getCurrentView(router), [router]);\n const view = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n // Route-level pending skeleton, only when no previous view is retained\n // (cold start, refresh, re-navigation after an error); in-app navigation\n // keeps the old view by design, the global loading signal already\n // covers that phase. Reading LoadingContext here also re-renders the\n // Router on every loading transition.\n const loading = useContext(LoadingContext);\n const pending =\n view == null && loading?.status === 'pending'\n ? resolvePendingView(router, loading.key)\n : null;\n\n return (\n <RouterContext.Provider value={router}>\n {children === undefined ? (\n (view ?? pending)\n ) : (\n <ViewProvider value={view}>\n <PendingContext.Provider value={pending}>\n {children}\n </PendingContext.Provider>\n </ViewProvider>\n )}\n </RouterContext.Provider>\n );\n}\n\n/**\n * Render the `pendingComponent` of the nearest matched ancestor of the\n * resolving location, walked deepest first(the resolving route's own\n * included). Keyed by the loading episode so a new pending phase remounts\n * the skeleton(stateful shimmer animations restart). Guards may still\n * redirect the resolution away; until then the initially matched chain\n * is the best — and only — answer available.\n */\nfunction resolvePendingView(\n router: RouterInstance<Route, ReactNode>,\n key: number\n) {\n const {resolving} = router;\n const matched = resolving ? match(router, resolving.pathname) : undefined;\n if (!matched) return null;\n for (let i = matched.length - 1; i >= 0; i--) {\n const Pending = matched[i].route.pendingComponent;\n if (Pending) return <Pending key={key} />;\n }\n return null;\n}\n\nexport function createRouter(\n routes: Route | Route[],\n history: History,\n {\n resolveView = defaultResolve,\n ...options\n }: Options<ReactNode> & {resolveView?: ResolveView<Route, ReactNode>} = {}\n): RouterInstance<Route, ReactNode> {\n return create(routes, history, resolveView, options);\n}\n\nfunction useNewRouter(\n {routes, children, ...options}: Props,\n createHistory: () => History\n) {\n const [tracked, rest] = splitProps(options, ['baseUrl', 'currentView']);\n const {baseUrl, currentView} = tracked;\n const [loading, setLoading] = useState<LoadStatus>();\n // Initial options are baked in at creation: the cold-start resolve fires\n // from the subscribe effect(children effects run first) before the\n // setOptions effect below runs, and the default errorHandler would let\n // listen's refresh().catch(noop) swallow a first failure, leaving the\n // view blank forever.\n const router = useMemo(\n () =>\n createRouter(routes, createHistory(), {\n ...options,\n onLoadingChange(status) {\n setLoading(status && {key: uniqId(), status});\n }\n }),\n // Only the tracked options belong to the deps: option updates flow\n // through the setOptions effect below instead of recreating the router.\n [routes, createHistory, baseUrl, currentView]\n );\n\n // Options are refreshed on every commit, so `onLoadingChange` and the\n // callback options always see the latest closure.\n useEffect(() => {\n setOptions(router, {\n ...rest,\n onLoadingChange(status) {\n setLoading(status && {key: uniqId(), status});\n }\n });\n }, [router, rest]);\n\n const r = useMemo(\n () => <Router router={router}>{children}</Router>,\n [router, children]\n );\n\n return <LoadingContext.Provider value={loading}>{r}</LoadingContext.Provider>;\n}\n\n/**\n * History mode Router Component.\n * @group Components\n */\nexport function HistoryRouter(props: Props) {\n return useNewRouter(props, createBrowserHistory);\n}\n\n/**\n * Hash mode Router Component.\n * @group Components\n */\nexport function HashRouter(props: Props) {\n return useNewRouter(props, createHashHistory);\n}\n\n/**\n * Memory mode Router Component.\n * @group Components\n */\nexport function MemoryRouter({\n initialEntries,\n initialIndex,\n ...props\n}: Props & MemoryHistoryOptions) {\n const createHistory = useMemo(\n () => () => createMemoryHistory({initialEntries, initialIndex}),\n [initialEntries, initialIndex]\n );\n return useNewRouter(props, createHistory);\n}\n\n/**\n * Get Router instance.\n * @group Hooks\n * @returns Router Instance\n */\nexport function useRouter() {\n const router = useContext(RouterContext);\n if (!router) {\n throw new Error('useRouter() must be used within a <Router> component');\n }\n return router;\n}\n","import {createBrowserHistory, createMemoryHistory, createPath} from 'history';\nimport {ReactElement, ReactNode} from 'react';\nimport {create, resolve, toLocation} from '@native-router/core';\nimport type {\n HistoryState,\n Location,\n Options,\n RouterInstance\n} from '@native-router/core';\nimport {isString} from '@native-router/core/util';\nimport {Router} from './components/Router';\nimport {\n createHydrateResolveView,\n getViewData,\n resolveViewServer\n} from './resolve-view';\nimport type {Route} from './types';\n\nconst defaultHydrateKey = '_nativeRouterReactSSRData';\n\n/**\n * Serialize the SSR payload for embedding in a script element.\n * `JSON.stringify` does not escape `<`, U+2028 and U+2029,\n * so route data like `</script>` would break out of the script element.\n * @param payload the payload to serialize\n * @returns the escaped JSON string\n */\nfunction serializePayload(payload: {\n data?: any[];\n location: Location;\n index: number;\n}) {\n return JSON.stringify(payload)\n .replace(/</g, '\\\\u003c')\n .replace(/\\u2028/g, '\\\\u2028')\n .replace(/\\u2029/g, '\\\\u2029');\n}\n\nexport function resolveServerViewBase(\n router: RouterInstance<Route, ReactNode>,\n location: Location,\n options?: {\n scriptAttributes?: Record<string, string>;\n hydrateKey?: string;\n }\n) {\n return resolve<Route, ReactNode>(router, location).then((view) => {\n const data = getViewData(view as ReactElement);\n const index =\n (router.history.location.state as HistoryState | undefined)?.index || 0;\n return (\n <>\n <Router router={router}>{view}</Router>\n <script\n {...options?.scriptAttributes}\n suppressHydrationWarning\n // eslint-disable-next-line @eslint-react/dom-no-dangerously-set-innerhtml -- serialized state for hydration\n dangerouslySetInnerHTML={{\n __html: `window.${\n options?.hydrateKey || defaultHydrateKey\n } = ${serializePayload({data, location, index})};`\n }}\n />\n </>\n );\n });\n}\n\nexport function resolveServerView(\n routes: Route | Route[],\n location: Location | string,\n {\n scriptAttributes,\n hydrateKey,\n ...options\n }: Options<ReactElement> & {\n scriptAttributes?: Record<string, string>;\n hydrateKey?: string;\n } = {}\n) {\n const router = create(\n routes,\n createMemoryHistory({initialEntries: [location]}),\n resolveViewServer,\n options\n );\n\n return resolveServerViewBase(\n router,\n isString(location) ? toLocation(router, location) : location,\n {\n scriptAttributes,\n hydrateKey\n }\n );\n}\n\n/**\n * Hydrate the SSR result of {@link resolveServerView} on the client.\n * The router is bound to the browser history(aligned with the index\n * in the SSR payload), so navigation after hydration updates the address bar.\n * @param routes routes config, must match the server side\n * @param options options, `hydrateKey` must match the server side\n * @returns the resolved view and the router instance, for example:\n * `const {view, router} = await hydrate(routes);`\n * `hydrateRoot(root, <Router router={router}>{view}</Router>)`\n * @group Methods\n */\nexport function hydrate(\n routes: Route | Route[],\n options?: Options<ReactElement> & {\n hydrateKey?: string;\n }\n): Promise<{view: ReactNode; router: RouterInstance<Route, ReactNode>}> {\n const {\n data,\n location,\n index = 0\n } = (window as any)[options?.hydrateKey || defaultHydrateKey] as {\n data: any[];\n location: Location;\n index?: number;\n };\n const history = createBrowserHistory();\n history.replace(createPath(history.location), {index});\n const router = create(\n routes,\n history,\n createHydrateResolveView(data),\n options\n );\n return resolve<Route, ReactNode>(router, location).then((view) => ({\n view,\n router\n }));\n}\n"],"mappings":"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"}