@solidjs/start 0.4.0-alpha.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.
- package/LICENSE +21 -0
- package/client/StartClient.tsx +17 -0
- package/client/index.tsx +3 -0
- package/client/islands.tsx +5 -0
- package/client/mount.ts +98 -0
- package/client/spa/index.tsx +8 -0
- package/config/fs-router.js +137 -0
- package/config/index.js +178 -0
- package/config/server-components.js +106 -0
- package/config/server-runtime.jsx +44 -0
- package/package.json +52 -0
- package/server/StartServer.tsx +42 -0
- package/server/handler.tsx +72 -0
- package/server/index.tsx +4 -0
- package/server/islands/index.tsx +102 -0
- package/server/islands/utils.tsx +87 -0
- package/server/middleware.ts +129 -0
- package/server/renderAsset.tsx +16 -0
- package/server/spa/StartServer.tsx +30 -0
- package/server/spa/handler.tsx +24 -0
- package/server/spa/index.tsx +4 -0
- package/server/types.ts +58 -0
- package/shared/ErrorBoundary.tsx +48 -0
- package/shared/FileRoutes.tsx +28 -0
- package/shared/HttpHeader.tsx +30 -0
- package/shared/HttpStatusCode.tsx +13 -0
- package/shared/clientOnly.tsx +28 -0
- package/shared/index.tsx +6 -0
- package/shared/lazyRoute.tsx +59 -0
- package/shared/routes.ts +44 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { onCleanup } from "solid-js";
|
|
2
|
+
import { getRequestEvent, isServer } from "solid-js/web";
|
|
3
|
+
|
|
4
|
+
export function HttpStatusCode(props: { code: number, text?: string }) {
|
|
5
|
+
if (isServer) {
|
|
6
|
+
const context = getRequestEvent();
|
|
7
|
+
context!.setResponseStatus(props.code, props.text);
|
|
8
|
+
onCleanup(() => {
|
|
9
|
+
context!.setResponseStatus(200);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Component, ComponentProps, JSX } from "solid-js";
|
|
2
|
+
import { createMemo, createSignal, onMount, sharedConfig, splitProps, untrack } from "solid-js";
|
|
3
|
+
import { isServer } from "solid-js/web";
|
|
4
|
+
|
|
5
|
+
// not using Suspense
|
|
6
|
+
export default function clientOnly<T extends Component<any>>(
|
|
7
|
+
fn: () => Promise<{
|
|
8
|
+
default: T;
|
|
9
|
+
}>
|
|
10
|
+
) {
|
|
11
|
+
if (isServer) return (props: ComponentProps<T> & { fallback?: JSX.Element }) => props.fallback;
|
|
12
|
+
|
|
13
|
+
const [comp, setComp] = createSignal<T>();
|
|
14
|
+
fn().then(m => setComp(() => m.default));
|
|
15
|
+
return (props: ComponentProps<T>) => {
|
|
16
|
+
let Comp: T | undefined;
|
|
17
|
+
let m: boolean;
|
|
18
|
+
const [, rest] = splitProps(props, ["fallback"]);
|
|
19
|
+
if ((Comp = comp()) && !sharedConfig.context) return Comp(rest);
|
|
20
|
+
const [mounted, setMounted] = createSignal(!sharedConfig.context);
|
|
21
|
+
onMount(() => setMounted(true));
|
|
22
|
+
return createMemo(
|
|
23
|
+
() => (
|
|
24
|
+
(Comp = comp()), (m = mounted()), untrack(() => (Comp && m ? Comp(rest) : props.fallback))
|
|
25
|
+
)
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
}
|
package/shared/index.tsx
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { default as clientOnly } from "./clientOnly";
|
|
2
|
+
export { ErrorBoundary as DefaultErrorBoundary } from "./ErrorBoundary";
|
|
3
|
+
export { FileRoutes } from "./FileRoutes";
|
|
4
|
+
export { HttpHeader } from "./HttpHeader";
|
|
5
|
+
export { HttpStatusCode } from "./HttpStatusCode";
|
|
6
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/// <reference types="vinxi/types/client" />
|
|
2
|
+
import { createComponent, lazy, onCleanup } from "solid-js";
|
|
3
|
+
import { appendStyles, cleanupStyles, updateStyles } from "vinxi/css";
|
|
4
|
+
|
|
5
|
+
import { renderAsset } from "../server/renderAsset";
|
|
6
|
+
|
|
7
|
+
export default function lazyRoute(
|
|
8
|
+
component,
|
|
9
|
+
clientManifest,
|
|
10
|
+
serverManifest,
|
|
11
|
+
exported = "default",
|
|
12
|
+
) {
|
|
13
|
+
return lazy(async () => {
|
|
14
|
+
if (import.meta.env.DEV) {
|
|
15
|
+
let manifest = import.meta.env.SSR ? serverManifest : clientManifest;
|
|
16
|
+
|
|
17
|
+
const mod = await manifest.inputs[component.src].import();
|
|
18
|
+
if (!mod[exported]) console.error(`Module ${component.src} does not export ${exported}`)
|
|
19
|
+
const Component = mod[exported];
|
|
20
|
+
let assets = await clientManifest.inputs?.[component.src].assets();
|
|
21
|
+
const styles = assets.filter((asset) => asset.tag === "style");
|
|
22
|
+
|
|
23
|
+
if (typeof window !== "undefined" && import.meta.hot) {
|
|
24
|
+
import.meta.hot.on("css-update", (data) => {
|
|
25
|
+
updateStyles(styles, data);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const Comp = (props) => {
|
|
30
|
+
if (typeof window !== "undefined") {
|
|
31
|
+
appendStyles(styles);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
onCleanup(() => {
|
|
35
|
+
if (typeof window !== "undefined") {
|
|
36
|
+
// remove style tags added by vite when a CSS file is imported
|
|
37
|
+
cleanupStyles(styles);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return [
|
|
41
|
+
...assets.map((asset) => renderAsset(asset)),
|
|
42
|
+
createComponent(Component, props),
|
|
43
|
+
];
|
|
44
|
+
};
|
|
45
|
+
return { default: Comp };
|
|
46
|
+
} else {
|
|
47
|
+
const mod = await component.import();
|
|
48
|
+
const Component = mod[exported];
|
|
49
|
+
let assets = await clientManifest.inputs?.[component.src].assets();
|
|
50
|
+
const Comp = (props) => {
|
|
51
|
+
return [
|
|
52
|
+
...assets.map((asset) => renderAsset(asset)),
|
|
53
|
+
createComponent(Component, props),
|
|
54
|
+
];
|
|
55
|
+
};
|
|
56
|
+
return { default: Comp };
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
package/shared/routes.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import fileRoutes, { Route } from "vinxi/routes";
|
|
2
|
+
|
|
3
|
+
declare module "vinxi/routes" {
|
|
4
|
+
export interface Register {
|
|
5
|
+
route: {
|
|
6
|
+
path: string;
|
|
7
|
+
type: "api" | "page";
|
|
8
|
+
children?: Route[];
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const defineRoutes = (fileRoutes: Route[]) => {
|
|
14
|
+
function processRoute(routes: Route[], route: Route, id: string, full: string) {
|
|
15
|
+
const parentRoute = Object.values(routes).find(o => {
|
|
16
|
+
// if (o.id.endsWith("/index")) {
|
|
17
|
+
// return false;
|
|
18
|
+
// }
|
|
19
|
+
return id.startsWith(o.path + "/");
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (!parentRoute) {
|
|
23
|
+
routes.push({ ...route, path: id });
|
|
24
|
+
return routes;
|
|
25
|
+
}
|
|
26
|
+
processRoute(
|
|
27
|
+
parentRoute.children || (parentRoute.children = []),
|
|
28
|
+
route,
|
|
29
|
+
id.slice(parentRoute.path.length),
|
|
30
|
+
full
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
return routes;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return fileRoutes
|
|
37
|
+
.sort((a, b) => a.path.length - b.path.length)
|
|
38
|
+
.reduce((prevRoutes, route) => {
|
|
39
|
+
return processRoute(prevRoutes, route, route.path, route.path);
|
|
40
|
+
}, []);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const pageRoutes = defineRoutes(fileRoutes.filter(o => o.type === "page"));
|
|
44
|
+
export const apiRoutes = fileRoutes.filter(o => o.type === "api");
|