@bleedingdev/modern-js-renderer-solid 0.0.0-stage → 3.9.3-ultramodern.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/dist/esm/actions.js +283 -0
- package/dist/esm/application-router.js +25 -0
- package/dist/esm/client.js +49 -0
- package/dist/esm/entry-application.js +60 -0
- package/dist/esm/entry-client.js +23 -0
- package/dist/esm/federation-context.js +25 -0
- package/dist/esm/federation-ssr.js +84 -0
- package/dist/esm/federation.js +83 -0
- package/dist/esm/i18n/I18nProvider.js +33 -0
- package/dist/esm/i18n/LocalizedLink.js +74 -0
- package/dist/esm/i18n/context.js +3 -0
- package/dist/esm/i18n/index.js +8 -0
- package/dist/esm/i18n/languageSync.js +50 -0
- package/dist/esm/i18n/types.js +0 -0
- package/dist/esm/i18n/useI18n.js +74 -0
- package/dist/esm/index.js +58 -0
- package/dist/esm/manifest.js +150 -0
- package/dist/esm/route-completion.js +150 -0
- package/dist/esm/route-data-error.js +108 -0
- package/dist/esm/router-binding/Asset.js +201 -0
- package/dist/esm/router-binding/CatchBoundary.js +94 -0
- package/dist/esm/router-binding/ClientOnly.js +26 -0
- package/dist/esm/router-binding/HeadContent.js +8 -0
- package/dist/esm/router-binding/LICENSE +21 -0
- package/dist/esm/router-binding/Match.js +319 -0
- package/dist/esm/router-binding/Matches.js +117 -0
- package/dist/esm/router-binding/PROVENANCE.json +94 -0
- package/dist/esm/router-binding/RouterProvider.js +51 -0
- package/dist/esm/router-binding/SafeFragment.js +5 -0
- package/dist/esm/router-binding/ScriptOnce.js +15 -0
- package/dist/esm/router-binding/Scripts.js +30 -0
- package/dist/esm/router-binding/ScrollRestoration.js +16 -0
- package/dist/esm/router-binding/Transitioner.js +103 -0
- package/dist/esm/router-binding/awaited.js +48 -0
- package/dist/esm/router-binding/fileRoute.js +83 -0
- package/dist/esm/router-binding/flightData.js +23 -0
- package/dist/esm/router-binding/headContentUtils.js +162 -0
- package/dist/esm/router-binding/history.js +0 -0
- package/dist/esm/router-binding/index.js +35 -0
- package/dist/esm/router-binding/lazyRouteComponent.js +30 -0
- package/dist/esm/router-binding/link.js +389 -0
- package/dist/esm/router-binding/matchContext.js +7 -0
- package/dist/esm/router-binding/nonRouteComponentContext.js +13 -0
- package/dist/esm/router-binding/not-found.js +35 -0
- package/dist/esm/router-binding/publicMatchData.js +447 -0
- package/dist/esm/router-binding/registryTransfer.js +210 -0
- package/dist/esm/router-binding/renderRouteNotFound.js +23 -0
- package/dist/esm/router-binding/route.js +143 -0
- package/dist/esm/router-binding/router.js +13 -0
- package/dist/esm/router-binding/routerContext.js +3 -0
- package/dist/esm/router-binding/routerStores.js +50 -0
- package/dist/esm/router-binding/scroll-restoration.js +13 -0
- package/dist/esm/router-binding/typePrimitives.js +0 -0
- package/dist/esm/router-binding/useBlocker.js +152 -0
- package/dist/esm/router-binding/useCanGoBack.js +7 -0
- package/dist/esm/router-binding/useLoaderData.js +9 -0
- package/dist/esm/router-binding/useLoaderDeps.js +8 -0
- package/dist/esm/router-binding/useLocation.js +14 -0
- package/dist/esm/router-binding/useMatch.js +28 -0
- package/dist/esm/router-binding/useNavigate.js +19 -0
- package/dist/esm/router-binding/useParams.js +13 -0
- package/dist/esm/router-binding/useRouteContext.js +8 -0
- package/dist/esm/router-binding/useRouter.js +10 -0
- package/dist/esm/router-binding/useRouterState.js +19 -0
- package/dist/esm/router-binding/useSearch.js +13 -0
- package/dist/esm/router-binding/utils.js +23 -0
- package/dist/esm/router.js +187 -0
- package/dist/esm-node/actions.js +263 -0
- package/dist/esm-node/application-router.js +25 -0
- package/dist/esm-node/client.js +49 -0
- package/dist/esm-node/entry-application.js +110 -0
- package/dist/esm-node/entry-client.js +23 -0
- package/dist/esm-node/entry-server.js +47 -0
- package/dist/esm-node/federation-context.js +25 -0
- package/dist/esm-node/federation-ssr.js +84 -0
- package/dist/esm-node/federation.js +83 -0
- package/dist/esm-node/i18n/I18nProvider.js +42 -0
- package/dist/esm-node/i18n/LocalizedLink.js +142 -0
- package/dist/esm-node/i18n/context.js +3 -0
- package/dist/esm-node/i18n/index.js +8 -0
- package/dist/esm-node/i18n/languageSync.js +50 -0
- package/dist/esm-node/i18n/types.js +1 -0
- package/dist/esm-node/i18n/useI18n.js +74 -0
- package/dist/esm-node/index.js +58 -0
- package/dist/esm-node/manifest.js +150 -0
- package/dist/esm-node/native-promise-serialization.js +113 -0
- package/dist/esm-node/plugin/compiler.js +209 -0
- package/dist/esm-node/plugin/create.js +235 -0
- package/dist/esm-node/plugin/index.js +73 -0
- package/dist/esm-node/plugin/profile.js +52 -0
- package/dist/esm-node/route-completion.js +160 -0
- package/dist/esm-node/route-data-error.js +108 -0
- package/dist/esm-node/router-binding/Asset.js +171 -0
- package/dist/esm-node/router-binding/CatchBoundary.js +136 -0
- package/dist/esm-node/router-binding/ClientOnly.js +46 -0
- package/dist/esm-node/router-binding/HeadContent.js +8 -0
- package/dist/esm-node/router-binding/LICENSE +21 -0
- package/dist/esm-node/router-binding/Match.js +660 -0
- package/dist/esm-node/router-binding/Matches.js +161 -0
- package/dist/esm-node/router-binding/PROVENANCE.json +94 -0
- package/dist/esm-node/router-binding/RouterProvider.js +87 -0
- package/dist/esm-node/router-binding/SafeFragment.js +5 -0
- package/dist/esm-node/router-binding/ScriptOnce.js +16 -0
- package/dist/esm-node/router-binding/Scripts.js +49 -0
- package/dist/esm-node/router-binding/ScrollRestoration.js +16 -0
- package/dist/esm-node/router-binding/Transitioner.js +103 -0
- package/dist/esm-node/router-binding/awaited.js +75 -0
- package/dist/esm-node/router-binding/fileRoute.js +83 -0
- package/dist/esm-node/router-binding/flightData.js +23 -0
- package/dist/esm-node/router-binding/headContentUtils.js +162 -0
- package/dist/esm-node/router-binding/history.js +1 -0
- package/dist/esm-node/router-binding/index.js +35 -0
- package/dist/esm-node/router-binding/lazyRouteComponent.js +30 -0
- package/dist/esm-node/router-binding/link.js +399 -0
- package/dist/esm-node/router-binding/matchContext.js +7 -0
- package/dist/esm-node/router-binding/nonRouteComponentContext.js +22 -0
- package/dist/esm-node/router-binding/not-found.js +49 -0
- package/dist/esm-node/router-binding/publicMatchData.js +447 -0
- package/dist/esm-node/router-binding/registryTransfer.js +210 -0
- package/dist/esm-node/router-binding/renderRouteNotFound.js +22 -0
- package/dist/esm-node/router-binding/route.js +162 -0
- package/dist/esm-node/router-binding/router.js +13 -0
- package/dist/esm-node/router-binding/routerContext.js +3 -0
- package/dist/esm-node/router-binding/routerStores.js +50 -0
- package/dist/esm-node/router-binding/scroll-restoration.js +12 -0
- package/dist/esm-node/router-binding/typePrimitives.js +1 -0
- package/dist/esm-node/router-binding/useBlocker.js +152 -0
- package/dist/esm-node/router-binding/useCanGoBack.js +7 -0
- package/dist/esm-node/router-binding/useLoaderData.js +9 -0
- package/dist/esm-node/router-binding/useLoaderDeps.js +8 -0
- package/dist/esm-node/router-binding/useLocation.js +14 -0
- package/dist/esm-node/router-binding/useMatch.js +28 -0
- package/dist/esm-node/router-binding/useNavigate.js +19 -0
- package/dist/esm-node/router-binding/useParams.js +13 -0
- package/dist/esm-node/router-binding/useRouteContext.js +8 -0
- package/dist/esm-node/router-binding/useRouter.js +10 -0
- package/dist/esm-node/router-binding/useRouterState.js +19 -0
- package/dist/esm-node/router-binding/useSearch.js +13 -0
- package/dist/esm-node/router-binding/utils.js +23 -0
- package/dist/esm-node/router.js +187 -0
- package/dist/esm-node/server.js +396 -0
- package/dist/types/actions.d.ts +45 -0
- package/dist/types/application-router.d.ts +5 -0
- package/dist/types/client.d.ts +23 -0
- package/dist/types/entry-application.d.ts +10 -0
- package/dist/types/entry-client.d.ts +5 -0
- package/dist/types/entry-server.d.ts +5 -0
- package/dist/types/federation-context.d.ts +16 -0
- package/dist/types/federation-ssr.d.ts +21 -0
- package/dist/types/federation.d.ts +30 -0
- package/dist/types/i18n/I18nProvider.d.ts +21 -0
- package/dist/types/i18n/LocalizedLink.d.ts +43 -0
- package/dist/types/i18n/context.d.ts +11 -0
- package/dist/types/i18n/index.d.ts +9 -0
- package/dist/types/i18n/languageSync.d.ts +31 -0
- package/dist/types/i18n/types.d.ts +33 -0
- package/dist/types/i18n/useI18n.d.ts +24 -0
- package/dist/types/index.d.ts +41 -0
- package/dist/types/manifest.d.ts +55 -0
- package/dist/types/native-promise-serialization.d.ts +9 -0
- package/dist/types/plugin/compiler.d.ts +6 -0
- package/dist/types/plugin/create.d.ts +21 -0
- package/dist/types/plugin/index.d.ts +3 -0
- package/dist/types/plugin/lazy-modules.d.cts +15 -0
- package/dist/types/plugin/preserve-import-loader.d.cts +3 -0
- package/dist/types/plugin/profile.d.ts +2 -0
- package/dist/types/plugin/solid-loader.d.cts +2 -0
- package/dist/types/plugin/svg-component-template.d.cts +6 -0
- package/dist/types/route-completion.d.ts +21 -0
- package/dist/types/route-data-error.d.ts +17 -0
- package/dist/types/router-binding/Asset.d.ts +3 -0
- package/dist/types/router-binding/CatchBoundary.d.ts +13 -0
- package/dist/types/router-binding/ClientOnly.d.ts +31 -0
- package/dist/types/router-binding/HeadContent.d.ts +13 -0
- package/dist/types/router-binding/Match.d.ts +6 -0
- package/dist/types/router-binding/Matches.d.ts +26 -0
- package/dist/types/router-binding/RouterProvider.d.ts +10 -0
- package/dist/types/router-binding/SafeFragment.d.ts +2 -0
- package/dist/types/router-binding/ScriptOnce.d.ts +6 -0
- package/dist/types/router-binding/Scripts.d.ts +2 -0
- package/dist/types/router-binding/ScrollRestoration.d.ts +14 -0
- package/dist/types/router-binding/Transitioner.d.ts +2 -0
- package/dist/types/router-binding/awaited.d.ts +11 -0
- package/dist/types/router-binding/fileRoute.d.ts +54 -0
- package/dist/types/router-binding/flightData.d.ts +38 -0
- package/dist/types/router-binding/headContentUtils.d.ts +15 -0
- package/dist/types/router-binding/history.d.ts +8 -0
- package/dist/types/router-binding/index.d.ts +45 -0
- package/dist/types/router-binding/lazyRouteComponent.d.ts +2 -0
- package/dist/types/router-binding/link.d.ts +43 -0
- package/dist/types/router-binding/matchContext.d.ts +7 -0
- package/dist/types/router-binding/nonRouteComponentContext.d.ts +5 -0
- package/dist/types/router-binding/not-found.d.ts +11 -0
- package/dist/types/router-binding/publicMatchData.d.ts +19 -0
- package/dist/types/router-binding/registryTransfer.d.ts +47 -0
- package/dist/types/router-binding/renderRouteNotFound.d.ts +11 -0
- package/dist/types/router-binding/route.d.ts +105 -0
- package/dist/types/router-binding/router.d.ts +70 -0
- package/dist/types/router-binding/routerContext.d.ts +3 -0
- package/dist/types/router-binding/routerStores.d.ts +2 -0
- package/dist/types/router-binding/scroll-restoration.d.ts +2 -0
- package/dist/types/router-binding/typePrimitives.d.ts +10 -0
- package/dist/types/router-binding/useBlocker.d.ts +70 -0
- package/dist/types/router-binding/useCanGoBack.d.ts +2 -0
- package/dist/types/router-binding/useLoaderData.d.ts +8 -0
- package/dist/types/router-binding/useLoaderDeps.d.ts +8 -0
- package/dist/types/router-binding/useLocation.d.ts +7 -0
- package/dist/types/router-binding/useMatch.d.ts +10 -0
- package/dist/types/router-binding/useNavigate.d.ts +5 -0
- package/dist/types/router-binding/useParams.d.ts +9 -0
- package/dist/types/router-binding/useRouteContext.d.ts +4 -0
- package/dist/types/router-binding/useRouter.d.ts +4 -0
- package/dist/types/router-binding/useRouterState.d.ts +8 -0
- package/dist/types/router-binding/useSearch.d.ts +9 -0
- package/dist/types/router-binding/utils.d.ts +25 -0
- package/dist/types/router.d.ts +31 -0
- package/dist/types/server.d.ts +47 -0
- package/package.json +123 -4
- package/src/actions.tsx +437 -0
- package/src/application-router.tsx +41 -0
- package/src/client.ts +106 -0
- package/src/entry-application.tsx +73 -0
- package/src/entry-client.tsx +48 -0
- package/src/entry-server.tsx +85 -0
- package/src/federation-context.ts +47 -0
- package/src/federation-ssr.ts +117 -0
- package/src/federation.tsx +193 -0
- package/src/i18n/I18nProvider.tsx +54 -0
- package/src/i18n/LocalizedLink.tsx +122 -0
- package/src/i18n/context.ts +13 -0
- package/src/i18n/index.ts +35 -0
- package/src/i18n/languageSync.ts +113 -0
- package/src/i18n/types.ts +35 -0
- package/src/i18n/useI18n.ts +121 -0
- package/src/index.ts +41 -0
- package/src/manifest.ts +337 -0
- package/src/native-promise-serialization.ts +167 -0
- package/src/plugin/compiler.ts +320 -0
- package/src/plugin/create.ts +270 -0
- package/src/plugin/index.ts +72 -0
- package/src/plugin/lazy-modules.cjs +146 -0
- package/src/plugin/preserve-import-loader.cjs +46 -0
- package/src/plugin/profile.ts +42 -0
- package/src/plugin/solid-loader.cjs +83 -0
- package/src/plugin/svg-component-template.cjs +19 -0
- package/src/route-completion.tsx +222 -0
- package/src/route-data-error.ts +175 -0
- package/src/router-binding/Asset.tsx +283 -0
- package/src/router-binding/CatchBoundary.tsx +130 -0
- package/src/router-binding/ClientOnly.tsx +76 -0
- package/src/router-binding/HeadContent.tsx +23 -0
- package/src/router-binding/LICENSE +21 -0
- package/src/router-binding/Match.tsx +397 -0
- package/src/router-binding/Matches.tsx +242 -0
- package/src/router-binding/PROVENANCE.json +94 -0
- package/src/router-binding/RouterProvider.tsx +129 -0
- package/src/router-binding/SafeFragment.tsx +5 -0
- package/src/router-binding/ScriptOnce.tsx +23 -0
- package/src/router-binding/Scripts.tsx +44 -0
- package/src/router-binding/ScrollRestoration.tsx +49 -0
- package/src/router-binding/Transitioner.tsx +172 -0
- package/src/router-binding/awaited.tsx +71 -0
- package/src/router-binding/fileRoute.ts +268 -0
- package/src/router-binding/flightData.ts +90 -0
- package/src/router-binding/headContentUtils.tsx +290 -0
- package/src/router-binding/history.ts +9 -0
- package/src/router-binding/index.tsx +318 -0
- package/src/router-binding/lazyRouteComponent.tsx +70 -0
- package/src/router-binding/link.tsx +865 -0
- package/src/router-binding/matchContext.tsx +15 -0
- package/src/router-binding/nonRouteComponentContext.tsx +23 -0
- package/src/router-binding/not-found.tsx +65 -0
- package/src/router-binding/publicMatchData.ts +674 -0
- package/src/router-binding/registryTransfer.ts +383 -0
- package/src/router-binding/renderRouteNotFound.tsx +53 -0
- package/src/router-binding/route.tsx +665 -0
- package/src/router-binding/router.ts +121 -0
- package/src/router-binding/routerContext.tsx +6 -0
- package/src/router-binding/routerStores.ts +85 -0
- package/src/router-binding/scroll-restoration.tsx +15 -0
- package/src/router-binding/typePrimitives.ts +74 -0
- package/src/router-binding/useBlocker.tsx +359 -0
- package/src/router-binding/useCanGoBack.ts +9 -0
- package/src/router-binding/useLoaderData.tsx +50 -0
- package/src/router-binding/useLoaderDeps.tsx +46 -0
- package/src/router-binding/useLocation.tsx +43 -0
- package/src/router-binding/useMatch.tsx +111 -0
- package/src/router-binding/useNavigate.tsx +43 -0
- package/src/router-binding/useParams.tsx +72 -0
- package/src/router-binding/useRouteContext.ts +30 -0
- package/src/router-binding/useRouter.tsx +17 -0
- package/src/router-binding/useRouterState.tsx +50 -0
- package/src/router-binding/useSearch.tsx +72 -0
- package/src/router-binding/utils.ts +59 -0
- package/src/router.ts +376 -0
- package/src/server.ts +645 -0
- package/README.md +0 -3
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type { JSX } from '@solidjs/web';
|
|
2
|
+
import { Dynamic } from '@solidjs/web';
|
|
3
|
+
import * as Solid from 'solid-js';
|
|
4
|
+
import { renderInNonRouteComponentContext } from './nonRouteComponentContext';
|
|
5
|
+
import type { ErrorRouteComponent } from './route';
|
|
6
|
+
|
|
7
|
+
export function CatchBoundary(
|
|
8
|
+
props: {
|
|
9
|
+
getResetKey: () => unknown;
|
|
10
|
+
children?: JSX.Element;
|
|
11
|
+
render?: () => JSX.Element;
|
|
12
|
+
errorComponent?: ErrorRouteComponent;
|
|
13
|
+
onCatch?: (error: Error) => void;
|
|
14
|
+
} & Solid.ParentProps,
|
|
15
|
+
) {
|
|
16
|
+
const [retryKey, setRetryKey] = Solid.createSignal<object>({});
|
|
17
|
+
let resetBoundary: (() => void) | undefined;
|
|
18
|
+
let initialized = false;
|
|
19
|
+
let previousKey: unknown;
|
|
20
|
+
|
|
21
|
+
Solid.onCleanup(() => {
|
|
22
|
+
resetBoundary = undefined;
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
Solid.createEffect(props.getResetKey, key => {
|
|
26
|
+
if (!initialized) {
|
|
27
|
+
initialized = true;
|
|
28
|
+
previousKey = key;
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// The effect re-runs on every recompute of the key function, not only
|
|
33
|
+
// on value changes — gate on the value so an unchanged key can't
|
|
34
|
+
// recreate the retried subtree while it settles.
|
|
35
|
+
if (key === previousKey) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
previousKey = key;
|
|
39
|
+
|
|
40
|
+
const reset = resetBoundary;
|
|
41
|
+
if (reset) {
|
|
42
|
+
queueMicrotask(() => {
|
|
43
|
+
if (resetBoundary !== reset) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
setRetryKey({});
|
|
47
|
+
reset();
|
|
48
|
+
Solid.flush();
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<Solid.Errored
|
|
55
|
+
fallback={(error, reset) => {
|
|
56
|
+
const resolvedError = Solid.untrack(() => error() as Error);
|
|
57
|
+
|
|
58
|
+
props.onCatch?.(resolvedError);
|
|
59
|
+
resetBoundary = reset;
|
|
60
|
+
|
|
61
|
+
return process.env.NODE_ENV !== 'production' ? (
|
|
62
|
+
renderInNonRouteComponentContext(
|
|
63
|
+
() => (
|
|
64
|
+
<Dynamic
|
|
65
|
+
component={props.errorComponent ?? ErrorComponent}
|
|
66
|
+
error={resolvedError}
|
|
67
|
+
reset={reset}
|
|
68
|
+
/>
|
|
69
|
+
),
|
|
70
|
+
'errorComponent',
|
|
71
|
+
)
|
|
72
|
+
) : (
|
|
73
|
+
<Dynamic
|
|
74
|
+
component={props.errorComponent ?? ErrorComponent}
|
|
75
|
+
error={resolvedError}
|
|
76
|
+
reset={reset}
|
|
77
|
+
/>
|
|
78
|
+
);
|
|
79
|
+
}}
|
|
80
|
+
>
|
|
81
|
+
<Solid.Show when={retryKey()} keyed>
|
|
82
|
+
{_retryKey => props.render?.() ?? props.children}
|
|
83
|
+
</Solid.Show>
|
|
84
|
+
</Solid.Errored>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function ErrorComponent({ error }: { error: any }) {
|
|
89
|
+
const [show, setShow] = Solid.createSignal(
|
|
90
|
+
process.env.NODE_ENV !== 'production',
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<div style={{ padding: '.5rem', 'max-width': '100%' }}>
|
|
95
|
+
<div style={{ display: 'flex', 'align-items': 'center', gap: '.5rem' }}>
|
|
96
|
+
<strong style={{ 'font-size': '1rem' }}>Something went wrong!</strong>
|
|
97
|
+
<button
|
|
98
|
+
style={{
|
|
99
|
+
appearance: 'none',
|
|
100
|
+
'font-size': '.6em',
|
|
101
|
+
border: '1px solid currentColor',
|
|
102
|
+
padding: '.1rem .2rem',
|
|
103
|
+
'font-weight': 'bold',
|
|
104
|
+
'border-radius': '.25rem',
|
|
105
|
+
}}
|
|
106
|
+
onClick={() => setShow(d => !d)}
|
|
107
|
+
>
|
|
108
|
+
{show() ? 'Hide Error' : 'Show Error'}
|
|
109
|
+
</button>
|
|
110
|
+
</div>
|
|
111
|
+
<div style={{ height: '.25rem' }} />
|
|
112
|
+
{show() ? (
|
|
113
|
+
<div>
|
|
114
|
+
<pre
|
|
115
|
+
style={{
|
|
116
|
+
'font-size': '.7em',
|
|
117
|
+
border: '1px solid red',
|
|
118
|
+
'border-radius': '.25rem',
|
|
119
|
+
padding: '.3rem',
|
|
120
|
+
color: 'red',
|
|
121
|
+
overflow: 'auto',
|
|
122
|
+
}}
|
|
123
|
+
>
|
|
124
|
+
{error.message ? <code>{error.message}</code> : null}
|
|
125
|
+
</pre>
|
|
126
|
+
</div>
|
|
127
|
+
) : null}
|
|
128
|
+
</div>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { JSX } from '@solidjs/web';
|
|
2
|
+
import * as Solid from 'solid-js';
|
|
3
|
+
|
|
4
|
+
export interface ClientOnlyProps {
|
|
5
|
+
/**
|
|
6
|
+
* The children to render when the JS is loaded.
|
|
7
|
+
*/
|
|
8
|
+
children: JSX.Element;
|
|
9
|
+
/**
|
|
10
|
+
* The fallback component to render if the JS is not yet loaded.
|
|
11
|
+
*/
|
|
12
|
+
fallback?: JSX.Element;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Render the children only after the JS has loaded client-side. Use an optional
|
|
17
|
+
* fallback component if the JS is not yet loaded.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* Render a Chart component if JS loads, renders a simple FakeChart
|
|
21
|
+
* component server-side or if there is no JS. The FakeChart can have only the
|
|
22
|
+
* UI without the behavior or be a loading spinner or skeleton.
|
|
23
|
+
*
|
|
24
|
+
* ```tsx
|
|
25
|
+
* return (
|
|
26
|
+
* <ClientOnly fallback={<FakeChart />}>
|
|
27
|
+
* <Chart />
|
|
28
|
+
* </ClientOnly>
|
|
29
|
+
* )
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function ClientOnly(props: ClientOnlyProps) {
|
|
33
|
+
const hydrated = useHydrated();
|
|
34
|
+
return (
|
|
35
|
+
<Solid.Show when={hydrated()} fallback={props.fallback ?? null}>
|
|
36
|
+
{props.children}
|
|
37
|
+
</Solid.Show>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Return a boolean indicating if the JS has been hydrated already.
|
|
43
|
+
* When doing Server-Side Rendering, the result will always be false.
|
|
44
|
+
* When doing Client-Side Rendering, the result will always be false on the
|
|
45
|
+
* first render and true from then on. Even if a new component renders it will
|
|
46
|
+
* always start with true.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```tsx
|
|
50
|
+
* // Disable a button that needs JS to work.
|
|
51
|
+
* const hydrated = useHydrated()
|
|
52
|
+
* return (
|
|
53
|
+
* <button type="button" disabled={!hydrated()} onClick={doSomethingCustom}>
|
|
54
|
+
* Click me
|
|
55
|
+
* </button>
|
|
56
|
+
* )
|
|
57
|
+
* ```
|
|
58
|
+
* @returns True if the JS has been hydrated already, false otherwise.
|
|
59
|
+
*/
|
|
60
|
+
let globalHydrated = false;
|
|
61
|
+
|
|
62
|
+
export function useHydrated(): Solid.Accessor<boolean> {
|
|
63
|
+
const [hydrated, setHydrated] = Solid.createSignal(
|
|
64
|
+
globalHydrated && !Solid.isHydrating(),
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
Solid.createEffect(
|
|
68
|
+
() => true,
|
|
69
|
+
() => {
|
|
70
|
+
globalHydrated = true;
|
|
71
|
+
setHydrated(true);
|
|
72
|
+
},
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
return hydrated;
|
|
76
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { JSX } from '@solidjs/web';
|
|
2
|
+
import { HydrationScript, useHead } from '@solidjs/web';
|
|
3
|
+
import type { AssetCrossOriginConfig } from '@tanstack/router-core';
|
|
4
|
+
import { toHeadTags, useTags } from './headContentUtils';
|
|
5
|
+
|
|
6
|
+
export interface HeadContentProps {
|
|
7
|
+
assetCrossOrigin?: AssetCrossOriginConfig;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @description The `HeadContent` component registers the current route's meta
|
|
12
|
+
* tags, links, and scripts with Solid's head registry, which owns emission
|
|
13
|
+
* into `<head>` (SSR splicing/streaming and client-side patching alike). It
|
|
14
|
+
* can be rendered anywhere in the tree, though placing it inside the `<head>`
|
|
15
|
+
* of your document keeps the hydration script in the right place.
|
|
16
|
+
*/
|
|
17
|
+
export function HeadContent(props: HeadContentProps): JSX.Element {
|
|
18
|
+
const tags = useTags(props.assetCrossOrigin);
|
|
19
|
+
|
|
20
|
+
useHead(() => toHeadTags(tags()));
|
|
21
|
+
|
|
22
|
+
return <HydrationScript />;
|
|
23
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021-present Tanner Linsley
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
import type { JSX } from '@solidjs/web';
|
|
2
|
+
import { Dynamic } from '@solidjs/web';
|
|
3
|
+
import type {
|
|
4
|
+
AnyRoute,
|
|
5
|
+
AnyRouter,
|
|
6
|
+
RootRouteOptions,
|
|
7
|
+
} from '@tanstack/router-core';
|
|
8
|
+
import { rootRouteId } from '@tanstack/router-core';
|
|
9
|
+
import { isServer } from '@tanstack/router-core/isServer';
|
|
10
|
+
import * as Solid from 'solid-js';
|
|
11
|
+
import { CatchBoundary, ErrorComponent } from './CatchBoundary';
|
|
12
|
+
import { ClientOnly } from './ClientOnly';
|
|
13
|
+
import { nearestMatchContext } from './matchContext';
|
|
14
|
+
import {
|
|
15
|
+
nonRouteComponentContext,
|
|
16
|
+
renderInNonRouteComponentContext,
|
|
17
|
+
} from './nonRouteComponentContext';
|
|
18
|
+
import { CatchNotFound, getNotFound } from './not-found';
|
|
19
|
+
import { renderRouteNotFound } from './renderRouteNotFound';
|
|
20
|
+
import { SafeFragment } from './SafeFragment';
|
|
21
|
+
import { ScrollRestoration } from './scroll-restoration';
|
|
22
|
+
import { useRouter } from './useRouter';
|
|
23
|
+
|
|
24
|
+
const NearestMatchContext = nearestMatchContext as unknown as Solid.Component<{
|
|
25
|
+
value: any;
|
|
26
|
+
children?: any;
|
|
27
|
+
}>;
|
|
28
|
+
|
|
29
|
+
// Keep the client constant undefined so the server-only script can be dropped.
|
|
30
|
+
const renderScrollRestoration =
|
|
31
|
+
isServer === false
|
|
32
|
+
? undefined
|
|
33
|
+
: (router: AnyRouter, route: AnyRoute) =>
|
|
34
|
+
(isServer ?? router.isServer) &&
|
|
35
|
+
route.parentRoute?.id === rootRouteId &&
|
|
36
|
+
router.options.scrollRestoration ? (
|
|
37
|
+
<ScrollRestoration />
|
|
38
|
+
) : null;
|
|
39
|
+
|
|
40
|
+
export const Match = (props: { routeId: string }): JSX.Element => {
|
|
41
|
+
const router = useRouter();
|
|
42
|
+
const currentMatch = Solid.createMemo(() =>
|
|
43
|
+
router.stores.getMatchStore(props.routeId).get(),
|
|
44
|
+
);
|
|
45
|
+
const matchState = Solid.createMemo(() => {
|
|
46
|
+
const match = currentMatch();
|
|
47
|
+
if (!match) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
routeId: match.routeId,
|
|
53
|
+
ssr: match.ssr,
|
|
54
|
+
status: match.status,
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
const nearestMatch = [() => props.routeId, currentMatch] as const;
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<Solid.Show when={matchState()}>
|
|
61
|
+
{currentMatchState => {
|
|
62
|
+
const route = router.routesById[props.routeId] as AnyRoute;
|
|
63
|
+
const routeOptions = () => {
|
|
64
|
+
// Lazy route options become observable with the next publication.
|
|
65
|
+
currentMatchState();
|
|
66
|
+
return route.options;
|
|
67
|
+
};
|
|
68
|
+
const resolvePendingComponent = Solid.createMemo(
|
|
69
|
+
() =>
|
|
70
|
+
routeOptions().pendingComponent ??
|
|
71
|
+
router.options.defaultPendingComponent,
|
|
72
|
+
);
|
|
73
|
+
const routeErrorComponent = Solid.createMemo(
|
|
74
|
+
() =>
|
|
75
|
+
routeOptions().errorComponent ??
|
|
76
|
+
router.options.defaultErrorComponent,
|
|
77
|
+
);
|
|
78
|
+
const routeNotFoundComponent = Solid.createMemo(() =>
|
|
79
|
+
route.isRoot
|
|
80
|
+
? (routeOptions().notFoundComponent ??
|
|
81
|
+
router.options.notFoundRoute?.options.component ??
|
|
82
|
+
router.options.defaultNotFoundComponent)
|
|
83
|
+
: (routeOptions().notFoundComponent ??
|
|
84
|
+
router.options.defaultNotFoundComponent),
|
|
85
|
+
);
|
|
86
|
+
const resolvedNoSsr = Solid.createMemo(
|
|
87
|
+
() =>
|
|
88
|
+
currentMatchState().ssr === false ||
|
|
89
|
+
currentMatchState().ssr === 'data-only',
|
|
90
|
+
);
|
|
91
|
+
const ResolvedNotFoundBoundary = Solid.createMemo(() =>
|
|
92
|
+
routeNotFoundComponent() ? CatchNotFound : SafeFragment,
|
|
93
|
+
);
|
|
94
|
+
const ShellComponent = Solid.createMemo(() =>
|
|
95
|
+
route.isRoot
|
|
96
|
+
? ((route.options as RootRouteOptions).shellComponent ??
|
|
97
|
+
SafeFragment)
|
|
98
|
+
: SafeFragment,
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
const MatchContent = () => (
|
|
102
|
+
<Solid.Show
|
|
103
|
+
when={currentMatchState().status !== 'pending'}
|
|
104
|
+
fallback={(() => {
|
|
105
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
106
|
+
return renderInNonRouteComponentContext(
|
|
107
|
+
() => <Dynamic component={resolvePendingComponent()} />,
|
|
108
|
+
'pendingComponent',
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
return <Dynamic component={resolvePendingComponent()} />;
|
|
112
|
+
})()}
|
|
113
|
+
>
|
|
114
|
+
<MatchInner />
|
|
115
|
+
</Solid.Show>
|
|
116
|
+
);
|
|
117
|
+
const RouteContent = () => (
|
|
118
|
+
<Dynamic
|
|
119
|
+
component={ResolvedNotFoundBoundary()}
|
|
120
|
+
fallback={(error: any) => {
|
|
121
|
+
const notFoundError = getNotFound(error) ?? error;
|
|
122
|
+
notFoundError.routeId ??= currentMatchState().routeId;
|
|
123
|
+
|
|
124
|
+
if (notFoundError.routeId !== currentMatchState().routeId) {
|
|
125
|
+
throw notFoundError;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return process.env.NODE_ENV !== 'production' ? (
|
|
129
|
+
renderInNonRouteComponentContext(
|
|
130
|
+
() => (
|
|
131
|
+
<Dynamic
|
|
132
|
+
component={routeNotFoundComponent()}
|
|
133
|
+
{...notFoundError}
|
|
134
|
+
/>
|
|
135
|
+
),
|
|
136
|
+
'notFoundComponent',
|
|
137
|
+
)
|
|
138
|
+
) : (
|
|
139
|
+
<Dynamic
|
|
140
|
+
component={routeNotFoundComponent()}
|
|
141
|
+
{...notFoundError}
|
|
142
|
+
/>
|
|
143
|
+
);
|
|
144
|
+
}}
|
|
145
|
+
>
|
|
146
|
+
<Solid.Switch>
|
|
147
|
+
<Solid.Match when={resolvedNoSsr()}>
|
|
148
|
+
<ClientOnly
|
|
149
|
+
fallback={(() => {
|
|
150
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
151
|
+
return renderInNonRouteComponentContext(
|
|
152
|
+
() => <Dynamic component={resolvePendingComponent()} />,
|
|
153
|
+
'pendingComponent',
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
return <Dynamic component={resolvePendingComponent()} />;
|
|
157
|
+
})()}
|
|
158
|
+
>
|
|
159
|
+
<MatchContent />
|
|
160
|
+
</ClientOnly>
|
|
161
|
+
</Solid.Match>
|
|
162
|
+
<Solid.Match when={!resolvedNoSsr()}>
|
|
163
|
+
<MatchContent />
|
|
164
|
+
</Solid.Match>
|
|
165
|
+
</Solid.Switch>
|
|
166
|
+
</Dynamic>
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
return (
|
|
170
|
+
<Dynamic component={ShellComponent()}>
|
|
171
|
+
<NearestMatchContext value={nearestMatch}>
|
|
172
|
+
<Solid.Show
|
|
173
|
+
when={routeErrorComponent()}
|
|
174
|
+
fallback={<RouteContent />}
|
|
175
|
+
>
|
|
176
|
+
{errorComponent => (
|
|
177
|
+
<CatchBoundary
|
|
178
|
+
// Scope the reset key to this match and its
|
|
179
|
+
// descendants (whose errors bubble here when they
|
|
180
|
+
// have no errorComponent of their own): resetting on
|
|
181
|
+
// unrelated matches' transitions just re-throws the
|
|
182
|
+
// still-stale error and recreates the retried
|
|
183
|
+
// subtree mid-settle.
|
|
184
|
+
getResetKey={() => {
|
|
185
|
+
const matches = router.stores.matches.get();
|
|
186
|
+
const index = matches.findIndex(
|
|
187
|
+
match => match.routeId === props.routeId,
|
|
188
|
+
);
|
|
189
|
+
if (index === -1) {
|
|
190
|
+
return '';
|
|
191
|
+
}
|
|
192
|
+
let key = '';
|
|
193
|
+
for (let i = index; i < matches.length; i++) {
|
|
194
|
+
const match = matches[i]!;
|
|
195
|
+
key += `${match.status}|${match.updatedAt},`;
|
|
196
|
+
}
|
|
197
|
+
return key;
|
|
198
|
+
}}
|
|
199
|
+
errorComponent={errorComponent() as any}
|
|
200
|
+
onCatch={(error: Error) => {
|
|
201
|
+
const notFoundError = getNotFound(error);
|
|
202
|
+
if (notFoundError) {
|
|
203
|
+
notFoundError.routeId ??= currentMatchState().routeId;
|
|
204
|
+
throw notFoundError;
|
|
205
|
+
}
|
|
206
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
207
|
+
console.warn(
|
|
208
|
+
`Warning: Error in route match: ${currentMatchState().routeId}`,
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
(
|
|
212
|
+
routeOptions().onCatch ?? router.options.defaultOnCatch
|
|
213
|
+
)?.(error);
|
|
214
|
+
}}
|
|
215
|
+
render={RouteContent}
|
|
216
|
+
/>
|
|
217
|
+
)}
|
|
218
|
+
</Solid.Show>
|
|
219
|
+
</NearestMatchContext>
|
|
220
|
+
|
|
221
|
+
{renderScrollRestoration?.(router, route)}
|
|
222
|
+
</Dynamic>
|
|
223
|
+
);
|
|
224
|
+
}}
|
|
225
|
+
</Solid.Show>
|
|
226
|
+
);
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
export const MatchInner = (): any => {
|
|
230
|
+
const router = useRouter();
|
|
231
|
+
const nearestMatch = Solid.useContext(nearestMatchContext);
|
|
232
|
+
const match = nearestMatch[1 /* match */];
|
|
233
|
+
const routeId = nearestMatch[0 /* route id */];
|
|
234
|
+
|
|
235
|
+
const matchState = Solid.createMemo(() => {
|
|
236
|
+
const currentMatch = match();
|
|
237
|
+
const currentRouteId = routeId();
|
|
238
|
+
if (!currentMatch || !currentRouteId) {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const route = router.routesById[currentRouteId] as AnyRoute;
|
|
243
|
+
const remount =
|
|
244
|
+
route.options.remountDeps ?? router.options.defaultRemountDeps;
|
|
245
|
+
let componentKey: string;
|
|
246
|
+
if (!remount) {
|
|
247
|
+
componentKey = currentRouteId;
|
|
248
|
+
} else {
|
|
249
|
+
const deps = remount({
|
|
250
|
+
routeId: currentRouteId,
|
|
251
|
+
loaderDeps: currentMatch.loaderDeps,
|
|
252
|
+
params: currentMatch._strictParams,
|
|
253
|
+
search: currentMatch._strictSearch,
|
|
254
|
+
});
|
|
255
|
+
componentKey = JSON.stringify(deps) ?? currentRouteId;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return {
|
|
259
|
+
route,
|
|
260
|
+
routeId: currentRouteId,
|
|
261
|
+
match: {
|
|
262
|
+
id: currentMatch.id,
|
|
263
|
+
status: currentMatch.status,
|
|
264
|
+
error: currentMatch.error,
|
|
265
|
+
},
|
|
266
|
+
componentKey,
|
|
267
|
+
};
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
return (
|
|
271
|
+
<Solid.Show when={matchState()}>
|
|
272
|
+
{currentMatchState => {
|
|
273
|
+
const route = Solid.createMemo(() => currentMatchState().route);
|
|
274
|
+
const currentMatch = Solid.createMemo(() => currentMatchState().match);
|
|
275
|
+
const componentKey = Solid.createMemo(
|
|
276
|
+
() => currentMatchState().componentKey,
|
|
277
|
+
);
|
|
278
|
+
const OutComponent = Solid.createMemo(
|
|
279
|
+
() =>
|
|
280
|
+
route().options.component ??
|
|
281
|
+
router.options.defaultComponent ??
|
|
282
|
+
Outlet,
|
|
283
|
+
);
|
|
284
|
+
const keyedOut = () => (
|
|
285
|
+
<Solid.Show when={componentKey()} keyed>
|
|
286
|
+
{_key => <Dynamic component={OutComponent()} />}
|
|
287
|
+
</Solid.Show>
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
return (
|
|
291
|
+
<Solid.Switch>
|
|
292
|
+
<Solid.Match when={currentMatch().status === 'notFound'}>
|
|
293
|
+
{_ =>
|
|
294
|
+
Solid.untrack(() =>
|
|
295
|
+
renderRouteNotFound(router, route(), currentMatch().error),
|
|
296
|
+
)
|
|
297
|
+
}
|
|
298
|
+
</Solid.Match>
|
|
299
|
+
<Solid.Match when={currentMatch().status === 'error'}>
|
|
300
|
+
{_ => {
|
|
301
|
+
const matchError = Solid.untrack(
|
|
302
|
+
() => currentMatch().error,
|
|
303
|
+
) as Error;
|
|
304
|
+
if (isServer ?? router.isServer) {
|
|
305
|
+
const RouteErrorComponent =
|
|
306
|
+
(route().options.errorComponent ??
|
|
307
|
+
router.options.defaultErrorComponent) ||
|
|
308
|
+
ErrorComponent;
|
|
309
|
+
|
|
310
|
+
return process.env.NODE_ENV !== 'production' ? (
|
|
311
|
+
renderInNonRouteComponentContext(
|
|
312
|
+
() => (
|
|
313
|
+
<RouteErrorComponent
|
|
314
|
+
error={matchError}
|
|
315
|
+
reset={undefined as any}
|
|
316
|
+
info={{ componentStack: '' }}
|
|
317
|
+
/>
|
|
318
|
+
),
|
|
319
|
+
'errorComponent',
|
|
320
|
+
)
|
|
321
|
+
) : (
|
|
322
|
+
<RouteErrorComponent
|
|
323
|
+
error={matchError}
|
|
324
|
+
reset={undefined as any}
|
|
325
|
+
info={{ componentStack: '' }}
|
|
326
|
+
/>
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
throw matchError;
|
|
331
|
+
}}
|
|
332
|
+
</Solid.Match>
|
|
333
|
+
<Solid.Match when={currentMatch().status === 'success'}>
|
|
334
|
+
{keyedOut()}
|
|
335
|
+
</Solid.Match>
|
|
336
|
+
</Solid.Switch>
|
|
337
|
+
);
|
|
338
|
+
}}
|
|
339
|
+
</Solid.Show>
|
|
340
|
+
);
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
export const Outlet = (): JSX.Element => {
|
|
344
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
345
|
+
const nonRouteComponent = Solid.useContext(nonRouteComponentContext!);
|
|
346
|
+
if (nonRouteComponent) {
|
|
347
|
+
console.warn(
|
|
348
|
+
`Warning: An <Outlet /> was rendered inside a ${nonRouteComponent}. <Outlet /> should only be rendered inside a route component.`,
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
const router = useRouter();
|
|
354
|
+
const nearestParentMatch = Solid.useContext(nearestMatchContext);
|
|
355
|
+
const parentMatch = nearestParentMatch[1 /* match */];
|
|
356
|
+
const routeId = nearestParentMatch[0 /* route id */];
|
|
357
|
+
const route = Solid.createMemo(() => {
|
|
358
|
+
const currentRouteId = routeId();
|
|
359
|
+
return currentRouteId
|
|
360
|
+
? (router.routesById[currentRouteId] as AnyRoute)
|
|
361
|
+
: undefined;
|
|
362
|
+
});
|
|
363
|
+
const parentNotFound = Solid.createMemo(() => parentMatch()?._notFound);
|
|
364
|
+
const parentNotFoundError = Solid.createMemo(() => parentMatch()?.error);
|
|
365
|
+
const childRouteId = Solid.createMemo(() => {
|
|
366
|
+
if (parentNotFound()) {
|
|
367
|
+
return undefined;
|
|
368
|
+
}
|
|
369
|
+
const currentRouteId = routeId();
|
|
370
|
+
if (!currentRouteId) {
|
|
371
|
+
return undefined;
|
|
372
|
+
}
|
|
373
|
+
const ids = router.stores.ids.get();
|
|
374
|
+
return ids[ids.indexOf(currentRouteId) + 1];
|
|
375
|
+
});
|
|
376
|
+
return (
|
|
377
|
+
<Solid.Show
|
|
378
|
+
when={childRouteId()}
|
|
379
|
+
keyed
|
|
380
|
+
fallback={
|
|
381
|
+
<Solid.Show when={parentNotFound() && route()}>
|
|
382
|
+
{resolvedRoute =>
|
|
383
|
+
Solid.untrack(() =>
|
|
384
|
+
renderRouteNotFound(
|
|
385
|
+
router,
|
|
386
|
+
resolvedRoute(),
|
|
387
|
+
parentNotFoundError(),
|
|
388
|
+
),
|
|
389
|
+
)
|
|
390
|
+
}
|
|
391
|
+
</Solid.Show>
|
|
392
|
+
}
|
|
393
|
+
>
|
|
394
|
+
{currentChildRouteId => <Match routeId={currentChildRouteId} />}
|
|
395
|
+
</Solid.Show>
|
|
396
|
+
);
|
|
397
|
+
};
|