@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,187 @@
|
|
|
1
|
+
import { DataProtocolError } from "@modern-js/renderer-core/data";
|
|
2
|
+
import { RouteDataError, loadFileSystemRoute, matchApplicationRouteIds, matchApplicationRoutes, nativeRoutePath, resolveRouteData, selectApplicationDataRoute, splitFileSystemRoutes, untilAborted } from "@modern-js/renderer-core/router";
|
|
3
|
+
import { createApplicationRouter, createRouteCompletionScope, registerRouteCompletionScope } from "./route-completion.js";
|
|
4
|
+
import { restoreRouteDataError } from "./route-data-error.js";
|
|
5
|
+
import { Outlet, createRootRoute, createRoute, isNotFound, isRedirect, notFound, preparePublicContextData, preparePublicLoaderData, preparePublicMatchError, redirect } from "./router-binding/index.js";
|
|
6
|
+
export * from "./router-binding/index.js";
|
|
7
|
+
function isPublicRecord(value) {
|
|
8
|
+
if (!value || "object" != typeof value) return false;
|
|
9
|
+
const prototype = Object.getPrototypeOf(value);
|
|
10
|
+
return prototype === Object.prototype || null === prototype;
|
|
11
|
+
}
|
|
12
|
+
function resolveApplicationRedirect(router) {
|
|
13
|
+
const result = router._serverResult;
|
|
14
|
+
const value = result?.type === "redirect" ? result.redirect : void 0;
|
|
15
|
+
return isRedirect(value) ? router.resolveRedirect(value) : void 0;
|
|
16
|
+
}
|
|
17
|
+
function getApplicationStatus(router) {
|
|
18
|
+
const result = router._serverResult;
|
|
19
|
+
if (!result) throw new Error("Load the native Solid router before resolving HTTP status");
|
|
20
|
+
return "render" === result.type ? result.status : result.redirect.status;
|
|
21
|
+
}
|
|
22
|
+
function router_resolveRouteData(routeId, outcome, project) {
|
|
23
|
+
return resolveRouteData({
|
|
24
|
+
redirect: redirect,
|
|
25
|
+
notFound: notFound
|
|
26
|
+
}, routeId, outcome, project);
|
|
27
|
+
}
|
|
28
|
+
function createFileSystemRouteTree(routes, modules, options = {}) {
|
|
29
|
+
const { root: rootDescriptor, children } = splitFileSystemRoutes(routes);
|
|
30
|
+
const privateRoots = options.context && ("object" == typeof options.context || "function" == typeof options.context) ? [
|
|
31
|
+
options.context
|
|
32
|
+
] : [];
|
|
33
|
+
const completionScope = createRouteCompletionScope(privateRoots, options.session);
|
|
34
|
+
const moduleFields = new Set([
|
|
35
|
+
"component",
|
|
36
|
+
"pendingComponent",
|
|
37
|
+
"errorComponent",
|
|
38
|
+
"notFoundComponent",
|
|
39
|
+
"head",
|
|
40
|
+
"beforeLoad",
|
|
41
|
+
"context",
|
|
42
|
+
"validateSearch"
|
|
43
|
+
]);
|
|
44
|
+
function projectModuleContext(authored, source) {
|
|
45
|
+
try {
|
|
46
|
+
const value = preparePublicContextData(authored, options.session ?? completionScope.hydrationOwner, [
|
|
47
|
+
options.context
|
|
48
|
+
]);
|
|
49
|
+
if ("context" === source && void 0 !== value && !isPublicRecord(value)) throw new DataProtocolError("Native Solid route context must return a synchronous public record");
|
|
50
|
+
if ("search" === source && !isPublicRecord(value)) throw new DataProtocolError("Native Solid search validation must return a public record");
|
|
51
|
+
return value;
|
|
52
|
+
} catch (error) {
|
|
53
|
+
options.session?.fail(error);
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function routeModuleOptions(id) {
|
|
58
|
+
const module = modules[id] ?? {};
|
|
59
|
+
const prototype = Object.getPrototypeOf(module);
|
|
60
|
+
if (prototype !== Object.prototype && null !== prototype) throw new DataProtocolError("Native Solid filesystem route modules require plain option records");
|
|
61
|
+
for (const key of Reflect.ownKeys(module)){
|
|
62
|
+
const descriptor = Object.getOwnPropertyDescriptor(module, key);
|
|
63
|
+
if ("string" != typeof key || !moduleFields.has(key) || descriptor.get || descriptor.set) throw new DataProtocolError("Unsupported native Solid filesystem route option; use the declared public route module contract");
|
|
64
|
+
}
|
|
65
|
+
const beforeLoad = module.beforeLoad;
|
|
66
|
+
const validateSearch = module.validateSearch;
|
|
67
|
+
const context = module.context;
|
|
68
|
+
const contextOptions = context ? {
|
|
69
|
+
context (...args) {
|
|
70
|
+
return projectModuleContext(context(...args), "context");
|
|
71
|
+
}
|
|
72
|
+
} : {};
|
|
73
|
+
const searchOptions = validateSearch ? {
|
|
74
|
+
validateSearch (search) {
|
|
75
|
+
return projectModuleContext(validateSearch(search), "search");
|
|
76
|
+
}
|
|
77
|
+
} : {};
|
|
78
|
+
if (!beforeLoad) return {
|
|
79
|
+
...module,
|
|
80
|
+
...searchOptions,
|
|
81
|
+
...contextOptions
|
|
82
|
+
};
|
|
83
|
+
return {
|
|
84
|
+
...module,
|
|
85
|
+
...searchOptions,
|
|
86
|
+
...contextOptions,
|
|
87
|
+
beforeLoad: async (...args)=>{
|
|
88
|
+
const signal = args[0]?.abortController?.signal;
|
|
89
|
+
let value;
|
|
90
|
+
try {
|
|
91
|
+
value = await (signal ? untilAborted(beforeLoad(...args), signal) : beforeLoad(...args));
|
|
92
|
+
} catch (error) {
|
|
93
|
+
if (signal?.aborted) throw error;
|
|
94
|
+
if (isRedirect(error)) throw error;
|
|
95
|
+
let projected;
|
|
96
|
+
try {
|
|
97
|
+
projected = isNotFound(error) ? preparePublicContextData(error, options.session, [
|
|
98
|
+
options.context
|
|
99
|
+
]) : preparePublicMatchError(error, options.session, [
|
|
100
|
+
options.context
|
|
101
|
+
]);
|
|
102
|
+
} catch (invalid) {
|
|
103
|
+
options.session?.fail(invalid);
|
|
104
|
+
throw invalid;
|
|
105
|
+
}
|
|
106
|
+
if (isNotFound(projected)) throw projected;
|
|
107
|
+
if (projected && "object" == typeof projected && Object.getOwnPropertyDescriptor(projected, "kind")?.value === "ultramodern-route-data-error") throw Object.freeze(restoreRouteDataError(projected));
|
|
108
|
+
const message = projected && "object" == typeof projected ? Object.getOwnPropertyDescriptor(projected, "message")?.value : void 0;
|
|
109
|
+
const name = projected && "object" == typeof projected ? Object.getOwnPropertyDescriptor(projected, "name")?.value : void 0;
|
|
110
|
+
const diagnostic = new Error("string" == typeof message ? message : "Unexpected Server Error");
|
|
111
|
+
diagnostic.name = "string" == typeof name ? name : "Error";
|
|
112
|
+
if (projected && "object" == typeof projected) for (const key of [
|
|
113
|
+
"cause",
|
|
114
|
+
"stack"
|
|
115
|
+
]){
|
|
116
|
+
const descriptor = Object.getOwnPropertyDescriptor(projected, key);
|
|
117
|
+
if (descriptor && !descriptor.get && !descriptor.set) Object.defineProperty(diagnostic, key, {
|
|
118
|
+
value: descriptor.value,
|
|
119
|
+
configurable: true,
|
|
120
|
+
writable: true
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
throw Object.freeze(diagnostic);
|
|
124
|
+
}
|
|
125
|
+
return projectModuleContext(value, "beforeLoad");
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function loaderOptions(route) {
|
|
130
|
+
const loadRoute = options.loadRoute;
|
|
131
|
+
if (!(route.modules?.data || route.modules?.clientData) || !loadRoute) return {};
|
|
132
|
+
return {
|
|
133
|
+
loader: async (match)=>{
|
|
134
|
+
const { outcome, request, signal } = await loadFileSystemRoute(route, loadRoute, options, match);
|
|
135
|
+
options.onOutcome?.(route.id, outcome);
|
|
136
|
+
const generation = completionScope.begin(signal, ()=>match.abortController.abort());
|
|
137
|
+
const owner = options.session ?? generation.owner;
|
|
138
|
+
const project = (value)=>{
|
|
139
|
+
try {
|
|
140
|
+
return preparePublicLoaderData(value, owner, [
|
|
141
|
+
options.context,
|
|
142
|
+
request
|
|
143
|
+
]);
|
|
144
|
+
} catch (error) {
|
|
145
|
+
owner.fail(error);
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
const value = router_resolveRouteData(route.id, outcome, project);
|
|
150
|
+
generation.publish(value, "completion" in outcome ? outcome.completion : void 0);
|
|
151
|
+
return value;
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
const root = createRootRoute({
|
|
156
|
+
...routeModuleOptions(rootDescriptor?.id ?? ""),
|
|
157
|
+
component: completionScope.component(modules[rootDescriptor?.id ?? ""]?.component ?? Outlet),
|
|
158
|
+
staticData: {
|
|
159
|
+
ultramodernRouteId: rootDescriptor?.id
|
|
160
|
+
},
|
|
161
|
+
...rootDescriptor ? loaderOptions(rootDescriptor) : {}
|
|
162
|
+
});
|
|
163
|
+
function bind(route, parent, inheritedErrorComponent) {
|
|
164
|
+
const errorComponent = modules[route.id]?.errorComponent ?? inheritedErrorComponent;
|
|
165
|
+
const native = createRoute({
|
|
166
|
+
getParentRoute: ()=>parent,
|
|
167
|
+
...nativeRoutePath(route),
|
|
168
|
+
...routeModuleOptions(route.id),
|
|
169
|
+
...errorComponent ? {
|
|
170
|
+
errorComponent
|
|
171
|
+
} : {},
|
|
172
|
+
component: completionScope.component(modules[route.id]?.component ?? Outlet),
|
|
173
|
+
staticData: {
|
|
174
|
+
ultramodernRouteId: route.id
|
|
175
|
+
},
|
|
176
|
+
...loaderOptions(route)
|
|
177
|
+
});
|
|
178
|
+
return native.addChildren(route.children.map((child)=>bind(child, native, errorComponent)));
|
|
179
|
+
}
|
|
180
|
+
const rootErrorComponent = modules[rootDescriptor?.id ?? ""]?.errorComponent;
|
|
181
|
+
const tree = root.addChildren(children.map((route)=>bind(route, root, rootErrorComponent)));
|
|
182
|
+
registerRouteCompletionScope(tree, completionScope);
|
|
183
|
+
return tree;
|
|
184
|
+
}
|
|
185
|
+
export { ActionForm, RouteActionError, createRouteAction, useRouteAction } from "./actions.js";
|
|
186
|
+
export { ApplicationRouter } from "./application-router.js";
|
|
187
|
+
export { RouteDataError, createApplicationRouter, createFileSystemRouteTree, getApplicationStatus, matchApplicationRouteIds, matchApplicationRoutes, resolveApplicationRedirect, router_resolveRouteData as resolveRouteData, selectApplicationDataRoute };
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
import { prepareDocument } from "@modern-js/renderer-core/document";
|
|
2
|
+
import { policyHeaders, responseHeaders, restrictDocumentCache, untilAborted } from "@modern-js/renderer-core/session";
|
|
3
|
+
import { commitEventResponse, createRequestEvent, generateHydrationScript, isServer, renderToStream, ssr } from "@solidjs/web";
|
|
4
|
+
import { provideRequestEvent } from "@solidjs/web/storage";
|
|
5
|
+
import { Hydration, NoHydration, createComponent, createRoot, runWithOwner } from "solid-js";
|
|
6
|
+
import { createFederationScope, provideFederation } from "./federation-context.js";
|
|
7
|
+
import { withFederatedAssets } from "./federation-ssr.js";
|
|
8
|
+
import { nativePromiseSerializationPlugin } from "./native-promise-serialization.js";
|
|
9
|
+
const CSP_HEADERS = new Set([
|
|
10
|
+
"content-security-policy",
|
|
11
|
+
"content-security-policy-report-only",
|
|
12
|
+
"link"
|
|
13
|
+
]);
|
|
14
|
+
const requestEvents = new WeakMap();
|
|
15
|
+
const nativeHeads = new WeakMap();
|
|
16
|
+
function applicationRequestEvent(session) {
|
|
17
|
+
if ("solid" !== session.identity.renderer) throw new Error("The Solid adapter requires a Solid renderer identity.");
|
|
18
|
+
if ("node" !== session.platform.kind && "worker" !== session.platform.kind) throw new Error("Solid request context requires a Node or worker request platform.");
|
|
19
|
+
if (!isServer) throw new Error("The Solid server adapter must resolve @solidjs/web with a server (node or worker) condition.");
|
|
20
|
+
let event = requestEvents.get(session);
|
|
21
|
+
if (!event) {
|
|
22
|
+
event = createRequestEvent(session.request, {
|
|
23
|
+
locals: {
|
|
24
|
+
session,
|
|
25
|
+
bindings: session.platform.bindings
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
requestEvents.set(session, event);
|
|
29
|
+
nativeHeads.set(event, {
|
|
30
|
+
response: event.response,
|
|
31
|
+
headers: event.response.headers
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return event;
|
|
35
|
+
}
|
|
36
|
+
async function runApplicationRequest(session, callback) {
|
|
37
|
+
let event;
|
|
38
|
+
try {
|
|
39
|
+
event = applicationRequestEvent(session);
|
|
40
|
+
} catch (error) {
|
|
41
|
+
session.fail(error);
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
return await provideRequestEvent(event, async ()=>{
|
|
45
|
+
try {
|
|
46
|
+
return await untilAborted(callback(), session.signal);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
session.fail(error);
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function ownData(object, key) {
|
|
54
|
+
const descriptor = Object.getOwnPropertyDescriptor(object, key);
|
|
55
|
+
if (!descriptor || !("value" in descriptor)) throw new TypeError("Solid response metadata must contain own data fields.");
|
|
56
|
+
return descriptor.value;
|
|
57
|
+
}
|
|
58
|
+
function readNativeHead(event) {
|
|
59
|
+
const native = nativeHeads.get(event);
|
|
60
|
+
if (!native || ownData(event, "response") !== native.response) throw new TypeError("The native Solid response stub cannot be replaced.");
|
|
61
|
+
const response = native.response;
|
|
62
|
+
const status = ownData(response, "status");
|
|
63
|
+
const statusText = ownData(response, "statusText");
|
|
64
|
+
if (void 0 !== status && ("number" != typeof status || !Number.isInteger(status) || status < 200 || status > 599)) throw new TypeError("A Solid response status must be an integer from 200 to 599.");
|
|
65
|
+
if (void 0 !== statusText && "string" != typeof statusText) throw new TypeError("A Solid response statusText must be a string.");
|
|
66
|
+
if (false !== ownData(response, "committed")) throw new Error("The native Solid response head is already committed.");
|
|
67
|
+
if (ownData(response, "headers") !== native.headers || Object.getPrototypeOf(native.headers) !== Headers.prototype) throw new TypeError("The native Solid response Headers cannot be replaced.");
|
|
68
|
+
for (const key of [
|
|
69
|
+
"append",
|
|
70
|
+
"delete",
|
|
71
|
+
"entries",
|
|
72
|
+
"forEach",
|
|
73
|
+
"get",
|
|
74
|
+
"getSetCookie",
|
|
75
|
+
"has",
|
|
76
|
+
"set",
|
|
77
|
+
Symbol.iterator
|
|
78
|
+
])if (Object.getOwnPropertyDescriptor(native.headers, key)) throw new TypeError("The native Solid response Headers methods cannot be replaced.");
|
|
79
|
+
return {
|
|
80
|
+
status,
|
|
81
|
+
statusText,
|
|
82
|
+
headers: native.headers
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function respondApplicationBody(session, body, hasSuppliedBody = false) {
|
|
86
|
+
return provideRequestEvent(applicationRequestEvent(session), ()=>{
|
|
87
|
+
try {
|
|
88
|
+
const event = applicationRequestEvent(session);
|
|
89
|
+
const policy = session.responsePolicy;
|
|
90
|
+
if (!policy || session.committedPolicy) throw new Error("Resolve an uncommitted Solid HTTP outcome before responding.");
|
|
91
|
+
const native = readNativeHead(event);
|
|
92
|
+
const original = policyHeaders(policy.headers);
|
|
93
|
+
const outgoing = policyHeaders(policy.headers);
|
|
94
|
+
let status = policy.status;
|
|
95
|
+
let statusText = policy.statusText;
|
|
96
|
+
let kind = policy.kind;
|
|
97
|
+
let bodyless = [
|
|
98
|
+
204,
|
|
99
|
+
205,
|
|
100
|
+
304
|
|
101
|
+
].includes(status);
|
|
102
|
+
if ("document" === kind) {
|
|
103
|
+
status = native.status ?? status;
|
|
104
|
+
statusText = native.statusText ?? statusText;
|
|
105
|
+
native.headers.forEach((value, name)=>{
|
|
106
|
+
if (CSP_HEADERS.has(name)) outgoing.append(name, value);
|
|
107
|
+
else if ("set-cookie" !== name && "server-timing" !== name && "vary" !== name) outgoing.set(name, value);
|
|
108
|
+
});
|
|
109
|
+
const vary = [
|
|
110
|
+
original.get("vary"),
|
|
111
|
+
native.headers.get("vary")
|
|
112
|
+
].flatMap((value)=>value?.split(",").map((part)=>part.trim()).filter(Boolean) ?? []);
|
|
113
|
+
if (vary.length) outgoing.set("vary", [
|
|
114
|
+
...new Set(vary)
|
|
115
|
+
].join(", "));
|
|
116
|
+
for (const name of [
|
|
117
|
+
"content-length",
|
|
118
|
+
"content-encoding",
|
|
119
|
+
"transfer-encoding"
|
|
120
|
+
])outgoing.delete(name);
|
|
121
|
+
if (outgoing.has("location")) {
|
|
122
|
+
status = [
|
|
123
|
+
301,
|
|
124
|
+
302,
|
|
125
|
+
303,
|
|
126
|
+
307,
|
|
127
|
+
308
|
|
128
|
+
].includes(status) ? status : 302;
|
|
129
|
+
bodyless = true;
|
|
130
|
+
} else bodyless = [
|
|
131
|
+
204,
|
|
132
|
+
205,
|
|
133
|
+
304
|
|
134
|
+
].includes(status);
|
|
135
|
+
if (bodyless) {
|
|
136
|
+
kind = "terminal";
|
|
137
|
+
outgoing.delete("content-type");
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (bodyless && hasSuppliedBody) throw new TypeError("A terminal Solid HTTP outcome cannot consume a document body.");
|
|
141
|
+
const cache = restrictDocumentCache({
|
|
142
|
+
...policy,
|
|
143
|
+
kind,
|
|
144
|
+
status
|
|
145
|
+
}, [
|
|
146
|
+
native.headers
|
|
147
|
+
], outgoing);
|
|
148
|
+
session.resolveResponse({
|
|
149
|
+
kind,
|
|
150
|
+
status,
|
|
151
|
+
statusText,
|
|
152
|
+
headers: responseHeaders(outgoing),
|
|
153
|
+
cache
|
|
154
|
+
});
|
|
155
|
+
const preview = commitEventResponse(new Response(bodyless ? null : body(), {
|
|
156
|
+
status,
|
|
157
|
+
statusText,
|
|
158
|
+
headers: outgoing
|
|
159
|
+
}), event);
|
|
160
|
+
const committedHeaders = preview.headers;
|
|
161
|
+
const finalCache = restrictDocumentCache({
|
|
162
|
+
...policy,
|
|
163
|
+
kind,
|
|
164
|
+
status
|
|
165
|
+
}, [
|
|
166
|
+
native.headers
|
|
167
|
+
], committedHeaders);
|
|
168
|
+
session.resolveResponse({
|
|
169
|
+
kind,
|
|
170
|
+
status,
|
|
171
|
+
statusText,
|
|
172
|
+
headers: responseHeaders(committedHeaders),
|
|
173
|
+
cache: finalCache
|
|
174
|
+
});
|
|
175
|
+
return session.respond(preview.body);
|
|
176
|
+
} catch (error) {
|
|
177
|
+
session.fail(error);
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
function respondApplication(session, body) {
|
|
183
|
+
try {
|
|
184
|
+
return respondApplicationBody(session, ()=>body, null !== body);
|
|
185
|
+
} catch (error) {
|
|
186
|
+
session.fail(error);
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function respondApplicationResponse(session, response) {
|
|
191
|
+
try {
|
|
192
|
+
session.resolveResponse({
|
|
193
|
+
kind: "terminal",
|
|
194
|
+
status: response.status,
|
|
195
|
+
statusText: response.statusText,
|
|
196
|
+
headers: responseHeaders(response.headers),
|
|
197
|
+
cache: {
|
|
198
|
+
mode: "no-store"
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
return respondApplication(session, response.body);
|
|
202
|
+
} catch (error) {
|
|
203
|
+
session.fail(error);
|
|
204
|
+
throw error;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function getDocumentNonce(nonce, destination) {
|
|
208
|
+
const value = "string" == typeof nonce ? nonce : nonce?.[destination];
|
|
209
|
+
return false === value ? void 0 : value;
|
|
210
|
+
}
|
|
211
|
+
async function renderApplication(options) {
|
|
212
|
+
let federation;
|
|
213
|
+
try {
|
|
214
|
+
federation = createFederationScope(options.federation);
|
|
215
|
+
} catch (error) {
|
|
216
|
+
options.session.fail(error);
|
|
217
|
+
throw error;
|
|
218
|
+
}
|
|
219
|
+
return renderNativeApplication({
|
|
220
|
+
...options,
|
|
221
|
+
view: provideFederation(federation, options.view)
|
|
222
|
+
}, federation);
|
|
223
|
+
}
|
|
224
|
+
async function renderNativeApplication(options, federation) {
|
|
225
|
+
const { session } = options;
|
|
226
|
+
let readable;
|
|
227
|
+
let consumed = false;
|
|
228
|
+
try {
|
|
229
|
+
const event = applicationRequestEvent(session);
|
|
230
|
+
if (session.responsePolicy?.kind !== "document" || [
|
|
231
|
+
204,
|
|
232
|
+
205,
|
|
233
|
+
304
|
|
234
|
+
].includes(session.responsePolicy.status)) throw new Error("Resolve a document HTTP outcome before invoking the Solid renderer; terminal responses bypass rendering.");
|
|
235
|
+
session.startRendering();
|
|
236
|
+
let renderFailure;
|
|
237
|
+
const { promise: shell, resolve, reject } = Promise.withResolvers();
|
|
238
|
+
shell.catch(()=>{});
|
|
239
|
+
const failBeforeShell = ()=>reject(renderFailure ? renderFailure.error : session.signal.reason);
|
|
240
|
+
if (session.signal.aborted) failBeforeShell();
|
|
241
|
+
else session.signal.addEventListener("abort", failBeforeShell, {
|
|
242
|
+
once: true
|
|
243
|
+
});
|
|
244
|
+
readable = provideRequestEvent(event, ()=>runWithOwner(null, ()=>createRoot((dispose)=>{
|
|
245
|
+
const nativeAbort = new AbortController();
|
|
246
|
+
const abortNative = ()=>provideRequestEvent(event, ()=>{
|
|
247
|
+
nativeAbort.abort(session.signal.reason);
|
|
248
|
+
});
|
|
249
|
+
session.signal.addEventListener("abort", abortNative, {
|
|
250
|
+
once: true
|
|
251
|
+
});
|
|
252
|
+
session.registerCleanup(()=>provideRequestEvent(event, ()=>{
|
|
253
|
+
session.signal.removeEventListener("abort", abortNative);
|
|
254
|
+
if (session.committedPolicy?.kind === "terminal") nativeAbort.abort(new DOMException("The request resolved without a document body.", "AbortError"));
|
|
255
|
+
dispose();
|
|
256
|
+
}));
|
|
257
|
+
if (session.signal.aborted) abortNative();
|
|
258
|
+
const native = renderToStream(options.view, {
|
|
259
|
+
...options.document,
|
|
260
|
+
manifest: withFederatedAssets(options.document?.manifest, federation),
|
|
261
|
+
plugins: [
|
|
262
|
+
nativePromiseSerializationPlugin
|
|
263
|
+
],
|
|
264
|
+
signal: nativeAbort.signal,
|
|
265
|
+
onCompleteShell () {
|
|
266
|
+
session.signal.removeEventListener("abort", failBeforeShell);
|
|
267
|
+
try {
|
|
268
|
+
resolve(respondApplicationBody(session, ()=>{
|
|
269
|
+
consumed = true;
|
|
270
|
+
return native.readable;
|
|
271
|
+
}));
|
|
272
|
+
} catch (error) {
|
|
273
|
+
reject(error);
|
|
274
|
+
throw error;
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
onError (error, context) {
|
|
278
|
+
if ("failed" === context.handling) {
|
|
279
|
+
renderFailure ??= {
|
|
280
|
+
error
|
|
281
|
+
};
|
|
282
|
+
session.fail(error);
|
|
283
|
+
} else if ("completed" !== session.state && "failed" !== session.state && "aborted" !== session.state) session.markFallback();
|
|
284
|
+
return options.onError?.(error, context);
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
if (renderFailure) throw renderFailure.error;
|
|
288
|
+
return native.readable;
|
|
289
|
+
}, {
|
|
290
|
+
transparent: true
|
|
291
|
+
})));
|
|
292
|
+
return await shell;
|
|
293
|
+
} catch (error) {
|
|
294
|
+
session.fail(error);
|
|
295
|
+
throw error;
|
|
296
|
+
} finally{
|
|
297
|
+
if (readable && !consumed) readable.cancel().catch(()=>{});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function createDocumentParts(options, hydrating) {
|
|
301
|
+
const { session } = options;
|
|
302
|
+
const document = options.document ?? {};
|
|
303
|
+
const renderId = document.renderId ?? `${[
|
|
304
|
+
session.identity.appId,
|
|
305
|
+
session.identity.entryName,
|
|
306
|
+
session.identity.buildId
|
|
307
|
+
].map((value)=>encodeURIComponent(value).replaceAll("'", "%27")).join(":")}:`;
|
|
308
|
+
if ("string" != typeof renderId || /[\s"'`=<>&]/u.test(renderId)) throw new TypeError("A Solid renderId cannot contain whitespace, quotes or HTML syntax.");
|
|
309
|
+
const script = getDocumentNonce(document.nonce, "script");
|
|
310
|
+
const style = getDocumentNonce(document.nonce, "style");
|
|
311
|
+
const parts = prepareDocument({
|
|
312
|
+
identity: session.identity,
|
|
313
|
+
documentId: renderId,
|
|
314
|
+
hydrating
|
|
315
|
+
}, {
|
|
316
|
+
rootId: document.rootId,
|
|
317
|
+
lang: document.lang,
|
|
318
|
+
nonce: {
|
|
319
|
+
script,
|
|
320
|
+
style
|
|
321
|
+
},
|
|
322
|
+
assets: document.assets,
|
|
323
|
+
inlineData: document.inlineData
|
|
324
|
+
});
|
|
325
|
+
return {
|
|
326
|
+
renderId,
|
|
327
|
+
lang: ` lang="${parts.lang}"`,
|
|
328
|
+
root: ` id="${parts.rootId}"`,
|
|
329
|
+
head: parts.headAssets + parts.bootstrap + (hydrating ? generateHydrationScript({
|
|
330
|
+
nonce: script
|
|
331
|
+
}) : ""),
|
|
332
|
+
modules: parts.entryScripts
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
async function renderDocumentApplication(options) {
|
|
336
|
+
try {
|
|
337
|
+
const parts = createDocumentParts(options, true);
|
|
338
|
+
const federation = createFederationScope(options.federation);
|
|
339
|
+
const view = provideFederation(federation, options.view);
|
|
340
|
+
return await renderNativeApplication({
|
|
341
|
+
session: options.session,
|
|
342
|
+
document: {
|
|
343
|
+
renderId: parts.renderId,
|
|
344
|
+
nonce: options.document?.nonce,
|
|
345
|
+
manifest: options.document?.manifest,
|
|
346
|
+
onHead: options.document?.onHead
|
|
347
|
+
},
|
|
348
|
+
onError: options.onError,
|
|
349
|
+
view: ()=>createComponent(NoHydration, {
|
|
350
|
+
get children () {
|
|
351
|
+
return ssr([
|
|
352
|
+
"<!doctype html><html",
|
|
353
|
+
"><head>",
|
|
354
|
+
"</head><body><div",
|
|
355
|
+
">",
|
|
356
|
+
"</div>",
|
|
357
|
+
"</body></html>"
|
|
358
|
+
], parts.lang, ssr(parts.head), parts.root, createComponent(Hydration, {
|
|
359
|
+
id: parts.renderId,
|
|
360
|
+
get children () {
|
|
361
|
+
return view();
|
|
362
|
+
}
|
|
363
|
+
}), ssr(parts.modules));
|
|
364
|
+
}
|
|
365
|
+
})
|
|
366
|
+
}, federation);
|
|
367
|
+
} catch (error) {
|
|
368
|
+
options.session.fail(error);
|
|
369
|
+
throw error;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
function renderCSRDocument(options) {
|
|
373
|
+
const { session } = options;
|
|
374
|
+
try {
|
|
375
|
+
if ("solid" !== session.identity.renderer || "node" !== session.platform.kind && "worker" !== session.platform.kind) throw new Error("The Solid CSR document requires a Solid Node or worker request session.");
|
|
376
|
+
if (session.responsePolicy?.kind !== "document" || [
|
|
377
|
+
204,
|
|
378
|
+
205,
|
|
379
|
+
304
|
|
380
|
+
].includes(session.responsePolicy.status)) throw new Error("Terminal HTTP outcomes bypass the Solid CSR document.");
|
|
381
|
+
const parts = createDocumentParts(options, false);
|
|
382
|
+
const html = `<!doctype html><html${parts.lang}><head>${parts.head}</head><body><div${parts.root}></div>${parts.modules}</body></html>`;
|
|
383
|
+
return respondApplication(session, new ReadableStream({
|
|
384
|
+
start (controller) {
|
|
385
|
+
controller.enqueue(new TextEncoder().encode(html));
|
|
386
|
+
controller.close();
|
|
387
|
+
}
|
|
388
|
+
}, {
|
|
389
|
+
highWaterMark: 0
|
|
390
|
+
}));
|
|
391
|
+
} catch (error) {
|
|
392
|
+
session.fail(error);
|
|
393
|
+
throw error;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
export { renderApplication, renderCSRDocument, renderDocumentApplication, respondApplication, respondApplicationResponse, runApplicationRequest };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { DecodedDataOutcome } from '@modern-js/renderer-core/data';
|
|
2
|
+
import type { RendererIdentity } from '@modern-js/renderer-core/identity';
|
|
3
|
+
import type { JSX } from '@solidjs/web';
|
|
4
|
+
import type { Accessor } from 'solid-js';
|
|
5
|
+
import type { AnyRouter } from './router-binding/index.js';
|
|
6
|
+
export interface RouteActionOptions {
|
|
7
|
+
router: AnyRouter;
|
|
8
|
+
routeId: string;
|
|
9
|
+
rendererIdentity: RendererIdentity;
|
|
10
|
+
url?: string | URL;
|
|
11
|
+
fetch?: typeof globalThis.fetch;
|
|
12
|
+
}
|
|
13
|
+
export interface RouteAction {
|
|
14
|
+
readonly routeId: string;
|
|
15
|
+
readonly pending: Accessor<boolean>;
|
|
16
|
+
readonly outcome: Accessor<DecodedDataOutcome | undefined>;
|
|
17
|
+
readonly error: Accessor<Error | undefined>;
|
|
18
|
+
readonly url: Accessor<string>;
|
|
19
|
+
/** Cancellation and superseded submissions resolve without publishing stale data. */
|
|
20
|
+
submit(request: Request): Promise<DecodedDataOutcome | undefined>;
|
|
21
|
+
submitForm(form: HTMLFormElement, submitter?: HTMLElement | null): Promise<DecodedDataOutcome | undefined>;
|
|
22
|
+
cancel(): void;
|
|
23
|
+
dispose(): void;
|
|
24
|
+
}
|
|
25
|
+
/** An asynchronous action exposes its public failure to the form's owner. */
|
|
26
|
+
export declare class RouteActionError extends Error {
|
|
27
|
+
readonly routeId: string;
|
|
28
|
+
readonly status: number;
|
|
29
|
+
readonly data: unknown;
|
|
30
|
+
readonly outcome: Extract<DecodedDataOutcome, {
|
|
31
|
+
kind: 'error' | 'not-found';
|
|
32
|
+
}>;
|
|
33
|
+
constructor(routeId: string, outcome: Extract<DecodedDataOutcome, {
|
|
34
|
+
kind: 'error' | 'not-found';
|
|
35
|
+
}>);
|
|
36
|
+
}
|
|
37
|
+
export declare function createRouteAction(options: RouteActionOptions): RouteAction;
|
|
38
|
+
/** Bind a form to the closest native route without a second route-ID authority. */
|
|
39
|
+
export declare function useRouteAction(): RouteAction;
|
|
40
|
+
export type ActionFormProps = Omit<JSX.FormHTMLAttributes<HTMLFormElement>, 'action' | 'method' | 'onSubmit' | 'onSubmitCapture'> & {
|
|
41
|
+
action: RouteAction;
|
|
42
|
+
children?: JSX.Element;
|
|
43
|
+
};
|
|
44
|
+
/** Native controls produce the request body; the renderer owns data transport. */
|
|
45
|
+
export declare function ActionForm(props: ActionFormProps): JSX.Element;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type JSX } from '@solidjs/web';
|
|
2
|
+
import type { AnyRouter, RegisteredRouter } from '@tanstack/router-core';
|
|
3
|
+
import { type RouterProps } from './router-binding/RouterProvider.js';
|
|
4
|
+
/** Native routing and head hooks share the same request/application provider. */
|
|
5
|
+
export declare function ApplicationRouter<TRouter extends AnyRouter = RegisteredRouter, TDehydrated extends Record<string, unknown> = Record<string, unknown>>(props: Omit<RouterProps<TRouter, TDehydrated>, 'context'>): JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type DocumentBootstrap } from '@modern-js/renderer-core/document';
|
|
2
|
+
import type { NativeFederationBinding } from '@modern-js/renderer-core/federation';
|
|
3
|
+
import type { RendererIdentity } from '@modern-js/renderer-core/identity';
|
|
4
|
+
import type { JSX } from '@solidjs/web';
|
|
5
|
+
import { hydrate } from '@solidjs/web';
|
|
6
|
+
type NativeMountOptions = NonNullable<Parameters<typeof hydrate>[2]>;
|
|
7
|
+
export type ApplicationMountElement = Parameters<typeof hydrate>[1];
|
|
8
|
+
export type SolidDocumentBootstrap = DocumentBootstrap;
|
|
9
|
+
/** Read the server's exact identity before creating a native router or owner. */
|
|
10
|
+
export declare function readSolidDocumentBootstrap(document: Document, expectedIdentity: RendererIdentity): SolidDocumentBootstrap;
|
|
11
|
+
/** The generated entry passes its bundler's native HMR disposal callback. */
|
|
12
|
+
export interface ApplicationMountOptions {
|
|
13
|
+
renderId?: NativeMountOptions['renderId'];
|
|
14
|
+
onError?: NativeMountOptions['onError'];
|
|
15
|
+
hot?: {
|
|
16
|
+
dispose(callback: () => void): void;
|
|
17
|
+
};
|
|
18
|
+
/** This browser compilation's native Module Federation runtime. */
|
|
19
|
+
federation?: NativeFederationBinding;
|
|
20
|
+
}
|
|
21
|
+
export declare function mountApplication(view: () => JSX.Element, element: ApplicationMountElement, options?: ApplicationMountOptions): () => void;
|
|
22
|
+
export declare function hydrateApplication(view: () => JSX.Element, element: ApplicationMountElement, options?: ApplicationMountOptions): () => void;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { LocalisedUrlsOption } from '@modern-js/i18n-runtime-extensions/paths';
|
|
2
|
+
import type { NativeI18nView } from '@modern-js/renderer-core/entry-client';
|
|
3
|
+
import type { NativeRouterFactory } from '@modern-js/renderer-core/router';
|
|
4
|
+
import type { JSX } from '@solidjs/web';
|
|
5
|
+
import { type AnyRoute, type AnyRouter } from './router-binding/index.js';
|
|
6
|
+
export type SolidI18nView = NativeI18nView<unknown, LocalisedUrlsOption>;
|
|
7
|
+
/** The Solid route tree and router of a generated entry. */
|
|
8
|
+
export declare const solidRouterFactory: NativeRouterFactory<AnyRoute, AnyRouter>;
|
|
9
|
+
export declare function componentView(component: unknown, i18n?: SolidI18nView): () => JSX.Element;
|
|
10
|
+
export declare function routerView(router: AnyRouter, i18n?: SolidI18nView): () => JSX.Element;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { LocalisedUrlsOption } from '@modern-js/i18n-runtime-extensions/paths';
|
|
2
|
+
import { type NativeClientEntryOptions, type NativeI18nInstance } from '@modern-js/renderer-core/entry-client';
|
|
3
|
+
export type SolidClientEntryOptions = NativeClientEntryOptions<NativeI18nInstance, LocalisedUrlsOption>;
|
|
4
|
+
/** Start a generated Solid browser entry: mount, or hydrate the server document. */
|
|
5
|
+
export declare function startNativeClient(options: SolidClientEntryOptions): void;
|