@solidjs/start 1.1.7 → 2.0.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/README.md +88 -8
- package/dist/client/StartClient.d.ts +0 -1
- package/dist/client/StartClient.jsx +2 -4
- package/dist/client/index.d.ts +2 -3
- package/dist/client/index.jsx +2 -4
- package/dist/client/mount.js +10 -2
- package/dist/client/spa/index.d.ts +1 -2
- package/dist/client/spa/index.jsx +1 -2
- package/dist/config/constants.d.ts +16 -0
- package/dist/config/constants.js +16 -0
- package/dist/config/dev-server.d.ts +2 -0
- package/dist/config/dev-server.js +108 -0
- package/dist/config/fs-router.d.ts +37 -0
- package/dist/config/fs-router.js +153 -0
- package/dist/config/fs-routes/fs-watcher.d.ts +3 -0
- package/dist/config/fs-routes/fs-watcher.js +49 -0
- package/dist/config/fs-routes/index.d.ts +7 -0
- package/dist/config/fs-routes/index.js +109 -0
- package/dist/config/fs-routes/router.d.ts +37 -0
- package/dist/config/fs-routes/router.js +136 -0
- package/dist/config/fs-routes/tree-shake.d.ts +2 -0
- package/dist/config/fs-routes/tree-shake.js +357 -0
- package/dist/config/index.d.ts +10 -0
- package/dist/config/index.js +217 -0
- package/dist/config/lazy.d.ts +3 -0
- package/dist/config/lazy.js +82 -0
- package/dist/config/manifest.d.ts +3 -0
- package/dist/config/manifest.js +74 -0
- package/dist/config/utils.d.ts +4 -0
- package/dist/config/utils.js +6 -0
- package/dist/config/vite-utils.d.ts +16 -0
- package/dist/config/vite-utils.js +81 -0
- package/dist/http/index.d.ts +84 -0
- package/dist/http/index.js +131 -0
- package/dist/index.d.ts +6 -5
- package/dist/index.jsx +5 -5
- package/dist/middleware/index.d.ts +6 -6
- package/dist/middleware/index.js +39 -0
- package/dist/{router/FileRoutes.js → router.jsx} +5 -6
- package/dist/server/StartServer.d.ts +3 -3
- package/dist/server/StartServer.jsx +9 -63
- package/dist/server/assets/index.d.ts +2 -0
- package/dist/server/assets/index.js +52 -0
- package/dist/server/assets/render.d.ts +19 -0
- package/dist/server/{renderAsset.jsx → assets/render.jsx} +1 -1
- package/dist/server/collect-styles.d.ts +3 -0
- package/dist/server/collect-styles.js +69 -0
- package/dist/server/fetchEvent.d.ts +4 -3
- package/dist/server/fetchEvent.js +12 -74
- package/dist/server/fetchEvent.spec.d.ts +1 -0
- package/dist/server/fetchEvent.spec.js +65 -0
- package/dist/server/handler.d.ts +6 -12
- package/dist/server/handler.js +180 -95
- package/dist/server/index.d.ts +8 -6
- package/dist/server/index.jsx +14 -6
- package/dist/server/manifest/client-manifest.d.ts +9 -0
- package/dist/server/manifest/client-manifest.js +6 -0
- package/dist/server/manifest/dev-client-manifest.d.ts +4 -0
- package/dist/server/manifest/dev-client-manifest.js +24 -0
- package/dist/server/manifest/dev-ssr-manifest.d.ts +5 -0
- package/dist/server/manifest/dev-ssr-manifest.js +23 -0
- package/dist/server/manifest/prod-client-manifest.d.ts +5 -0
- package/dist/server/manifest/prod-client-manifest.js +26 -0
- package/dist/server/manifest/prod-ssr-manifest.d.ts +6 -0
- package/dist/server/manifest/prod-ssr-manifest.js +90 -0
- package/dist/server/manifest/ssr-manifest.d.ts +4 -0
- package/dist/server/manifest/ssr-manifest.js +6 -0
- package/dist/{router → server}/routes.d.ts +6 -10
- package/dist/{router → server}/routes.js +35 -27
- package/dist/{runtime → server}/server-fns-runtime.d.ts +1 -1
- package/dist/{runtime → server}/server-fns-runtime.js +7 -6
- package/dist/server/server-functions-handler.d.ts +2 -0
- package/dist/{runtime/server-handler.js → server/server-functions-handler.js} +76 -103
- package/dist/server/server-runtime.d.ts +3 -0
- package/dist/{runtime → server}/server-runtime.js +9 -16
- package/dist/server/spa/StartServer.d.ts +1 -1
- package/dist/server/spa/StartServer.jsx +7 -9
- package/dist/server/spa/handler.d.ts +3 -3
- package/dist/server/spa/handler.js +9 -11
- package/dist/server/spa/index.d.ts +4 -3
- package/dist/server/spa/index.jsx +4 -3
- package/dist/server/types.d.ts +7 -9
- package/dist/server/util.d.ts +2 -0
- package/dist/server/util.js +8 -0
- package/dist/shared/ErrorBoundary.jsx +2 -2
- package/dist/shared/HttpHeader.jsx +4 -2
- package/dist/shared/{HttpStatusCode.jsx → HttpStatusCode.js} +3 -1
- package/dist/shared/dev-overlay/DevOverlayDialog.d.ts +2 -2
- package/dist/shared/dev-overlay/DevOverlayDialog.jsx +75 -66
- package/dist/shared/dev-overlay/createStackFrame.js +3 -3
- package/dist/shared/dev-overlay/index.jsx +5 -8
- package/dist/shared/lazy.d.ts +3 -0
- package/dist/shared/lazy.js +40 -0
- package/dist/shared/serverFunction.d.ts +1 -1
- package/package.json +47 -65
- package/scripts/build.js +15 -0
- package/scripts/validate-imports.js +316 -0
- package/src/client/StartClient.tsx +34 -0
- package/src/client/index.tsx +2 -0
- package/src/client/mount.ts +114 -0
- package/src/client/spa/index.tsx +9 -0
- package/src/config/constants.ts +19 -0
- package/src/config/dev-server.ts +149 -0
- package/src/config/fs-router.ts +177 -0
- package/src/config/fs-routes/fs-watcher.ts +81 -0
- package/src/config/fs-routes/index.ts +138 -0
- package/src/config/fs-routes/router.ts +169 -0
- package/src/config/fs-routes/tree-shake.ts +392 -0
- package/src/config/index.ts +236 -0
- package/src/config/lazy.ts +100 -0
- package/src/config/manifest.ts +84 -0
- package/src/config/utils.ts +5 -0
- package/src/config/vite-utils.ts +113 -0
- package/src/env.d.ts +35 -0
- package/src/http/index.ts +253 -0
- package/src/index.tsx +19 -0
- package/src/internal.d.ts +14 -0
- package/src/middleware/index.ts +82 -0
- package/src/router.tsx +36 -0
- package/src/server/StartServer.tsx +62 -0
- package/src/server/assets/index.ts +70 -0
- package/src/server/assets/render.tsx +42 -0
- package/src/server/collect-styles.ts +94 -0
- package/src/server/fetchEvent.spec.ts +89 -0
- package/src/server/fetchEvent.ts +36 -0
- package/src/server/handler.ts +250 -0
- package/src/server/index.tsx +16 -0
- package/src/server/manifest/client-manifest.ts +8 -0
- package/src/server/manifest/dev-client-manifest.ts +19 -0
- package/src/server/manifest/dev-ssr-manifest.ts +21 -0
- package/src/server/manifest/prod-client-manifest.ts +18 -0
- package/src/server/manifest/prod-ssr-manifest.ts +125 -0
- package/src/server/manifest/ssr-manifest.ts +8 -0
- package/src/server/routes.ts +138 -0
- package/src/server/server-fns-runtime.ts +31 -0
- package/src/server/server-functions-handler.ts +364 -0
- package/src/server/server-runtime.ts +240 -0
- package/src/server/spa/StartServer.tsx +40 -0
- package/src/server/spa/handler.ts +29 -0
- package/src/server/spa/index.tsx +5 -0
- package/src/server/types.ts +82 -0
- package/src/server/util.ts +12 -0
- package/src/shared/ErrorBoundary.tsx +52 -0
- package/src/shared/GET.ts +8 -0
- package/src/shared/HttpHeader.tsx +42 -0
- package/src/shared/HttpStatusCode.ts +27 -0
- package/src/shared/clientOnly.ts +44 -0
- package/src/shared/dev-overlay/CodeView.tsx +95 -0
- package/src/shared/dev-overlay/DevOverlayDialog.tsx +316 -0
- package/src/shared/dev-overlay/createStackFrame.ts +77 -0
- package/src/shared/dev-overlay/download.ts +6 -0
- package/src/shared/dev-overlay/env.d.ts +4 -0
- package/src/shared/dev-overlay/get-source-map.ts +35 -0
- package/src/shared/dev-overlay/icons.tsx +288 -0
- package/src/shared/dev-overlay/index.tsx +63 -0
- package/src/shared/dev-overlay/styles.css +292 -0
- package/src/shared/lazy.ts +51 -0
- package/src/shared/serverFunction.ts +10 -0
- package/src/virtual.d.ts +27 -0
- package/tsconfig.json +23 -0
- package/vitest.config.ts +9 -0
- package/config/fs-router.js +0 -142
- package/config/index.d.ts +0 -39
- package/config/index.js +0 -303
- package/config/server-components.js +0 -106
- package/dist/client/islands.d.ts +0 -7
- package/dist/client/islands.jsx +0 -10
- package/dist/middleware/index.jsx +0 -35
- package/dist/router/index.d.ts +0 -1
- package/dist/router/index.jsx +0 -2
- package/dist/router/lazyRoute.d.ts +0 -6
- package/dist/router/lazyRoute.js +0 -53
- package/dist/runtime/server-handler.d.ts +0 -2
- package/dist/runtime/server-runtime.d.ts +0 -3
- package/dist/server/islands/index.d.ts +0 -19
- package/dist/server/islands/index.jsx +0 -62
- package/dist/server/islands/utils.d.ts +0 -1
- package/dist/server/islands/utils.jsx +0 -85
- package/dist/server/pageEvent.d.ts +0 -2
- package/dist/server/pageEvent.js +0 -56
- package/dist/server/renderAsset.d.ts +0 -2
- package/env.d.ts +0 -26
- /package/dist/{router/FileRoutes.d.ts → router.d.ts} +0 -0
- /package/dist/shared/{clientOnly.jsx → clientOnly.js} +0 -0
- /package/dist/shared/{serverFunction.jsx → serverFunction.js} +0 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import * as h3 from "h3";
|
|
2
|
+
import { getRequestEvent } from "solid-js/web";
|
|
3
|
+
function _setContext(event, key, value) {
|
|
4
|
+
event.context[key] = value;
|
|
5
|
+
}
|
|
6
|
+
function _getContext(event, key) {
|
|
7
|
+
return event.context[key];
|
|
8
|
+
}
|
|
9
|
+
function getEvent() {
|
|
10
|
+
return getRequestEvent().nativeEvent;
|
|
11
|
+
}
|
|
12
|
+
export function getWebRequest() {
|
|
13
|
+
return getEvent().req;
|
|
14
|
+
}
|
|
15
|
+
export const HTTPEventSymbol = Symbol("$HTTPEvent");
|
|
16
|
+
export function isEvent(obj) {
|
|
17
|
+
return (typeof obj === "object" &&
|
|
18
|
+
(obj instanceof h3.H3Event ||
|
|
19
|
+
obj?.[HTTPEventSymbol] instanceof h3.H3Event ||
|
|
20
|
+
obj?.__is_event__ === true));
|
|
21
|
+
// Implement logic to check if obj is an H3Event
|
|
22
|
+
}
|
|
23
|
+
function createWrapperFunction(h3Function) {
|
|
24
|
+
return ((...args) => {
|
|
25
|
+
const event = args[0];
|
|
26
|
+
if (!isEvent(event)) {
|
|
27
|
+
args.unshift(getEvent());
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
args[0] =
|
|
31
|
+
event instanceof h3.H3Event || event.__is_event__
|
|
32
|
+
? event
|
|
33
|
+
: event[HTTPEventSymbol];
|
|
34
|
+
}
|
|
35
|
+
return h3Function(...args);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
export const readBody = createWrapperFunction(h3.readBody);
|
|
39
|
+
export const getQuery = createWrapperFunction(h3.getQuery);
|
|
40
|
+
export const isMethod = createWrapperFunction(h3.isMethod);
|
|
41
|
+
export const isPreflightRequest = createWrapperFunction(h3.isPreflightRequest);
|
|
42
|
+
export const getValidatedQuery = createWrapperFunction(h3.getValidatedQuery);
|
|
43
|
+
export const getRouterParams = createWrapperFunction(h3.getRouterParams);
|
|
44
|
+
export const getRouterParam = createWrapperFunction(h3.getRouterParam);
|
|
45
|
+
export const getValidatedRouterParams = createWrapperFunction(h3.getValidatedRouterParams);
|
|
46
|
+
export const assertMethod = createWrapperFunction(h3.assertMethod);
|
|
47
|
+
export const getRequestHeaders = createWrapperFunction(h3.getRequestHeaders);
|
|
48
|
+
export const getRequestHeader = createWrapperFunction(h3.getRequestHeader);
|
|
49
|
+
export const getRequestURL = createWrapperFunction(h3.getRequestURL);
|
|
50
|
+
export const getRequestHost = createWrapperFunction(h3.getRequestHost);
|
|
51
|
+
export const getRequestProtocol = createWrapperFunction(h3.getRequestProtocol);
|
|
52
|
+
export const getRequestIP = createWrapperFunction(h3.getRequestIP);
|
|
53
|
+
export const setResponseStatus = (code, text) => {
|
|
54
|
+
const e = getEvent();
|
|
55
|
+
if (e.res.status !== undefined)
|
|
56
|
+
e.res.status = code;
|
|
57
|
+
if (e.res.statusText !== undefined)
|
|
58
|
+
e.res.statusText = text;
|
|
59
|
+
};
|
|
60
|
+
export const getResponseStatus = () => getEvent().res.status;
|
|
61
|
+
export const getResponseStatusText = () => getEvent().res.statusText;
|
|
62
|
+
export const getResponseHeaders = () => Object.fromEntries(getEvent().res.headers.entries());
|
|
63
|
+
export const getResponseHeader = (name) => getEvent().res.headers.get(name);
|
|
64
|
+
export const setResponseHeaders = (values) => {
|
|
65
|
+
const headers = getEvent().res.headers;
|
|
66
|
+
for (const [name, value] of Object.entries(values)) {
|
|
67
|
+
headers.set(name, value);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
export const setResponseHeader = (name, value) => {
|
|
71
|
+
const headers = getEvent().res.headers;
|
|
72
|
+
(Array.isArray(value) ? value : [value]).forEach((value) => {
|
|
73
|
+
headers.set(name, value);
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
export const appendResponseHeaders = (values) => {
|
|
77
|
+
const headers = getEvent().res.headers;
|
|
78
|
+
for (const [name, value] of Object.entries(values)) {
|
|
79
|
+
headers.append(name, value);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
export const appendResponseHeader = (name, value) => {
|
|
83
|
+
const headers = getEvent().res.headers;
|
|
84
|
+
(Array.isArray(value) ? value : [value]).forEach((value) => {
|
|
85
|
+
headers.append(name, value);
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
export const defaultContentType = (type) => getEvent().res.headers.set("content-type", type);
|
|
89
|
+
export const proxyRequest = createWrapperFunction(h3.proxyRequest);
|
|
90
|
+
export const fetchWithEvent = createWrapperFunction(h3.fetchWithEvent);
|
|
91
|
+
export const getProxyRequestHeaders = createWrapperFunction(h3.getProxyRequestHeaders);
|
|
92
|
+
export const parseCookies = createWrapperFunction(h3.parseCookies);
|
|
93
|
+
export const getCookie = createWrapperFunction(h3.getCookie);
|
|
94
|
+
export const setCookie = createWrapperFunction(h3.setCookie);
|
|
95
|
+
export const deleteCookie = createWrapperFunction(h3.deleteCookie);
|
|
96
|
+
export const useSession = createWrapperFunction(h3.useSession);
|
|
97
|
+
export const getSession = createWrapperFunction(h3.getSession);
|
|
98
|
+
export const updateSession = createWrapperFunction(h3.updateSession);
|
|
99
|
+
export const sealSession = createWrapperFunction(h3.sealSession);
|
|
100
|
+
export const unsealSession = createWrapperFunction(h3.unsealSession);
|
|
101
|
+
export const clearSession = createWrapperFunction(h3.clearSession);
|
|
102
|
+
export const handleCacheHeaders = createWrapperFunction(h3.handleCacheHeaders);
|
|
103
|
+
export const handleCors = createWrapperFunction(h3.handleCors);
|
|
104
|
+
export const appendCorsHeaders = createWrapperFunction(h3.appendCorsHeaders);
|
|
105
|
+
export const appendCorsPreflightHeaders = createWrapperFunction(h3.appendCorsPreflightHeaders);
|
|
106
|
+
export const appendHeader = appendResponseHeader;
|
|
107
|
+
export const appendHeaders = appendResponseHeaders;
|
|
108
|
+
export const setHeader = setResponseHeader;
|
|
109
|
+
export const setHeaders = setResponseHeaders;
|
|
110
|
+
export const getHeader = getRequestHeader;
|
|
111
|
+
export const getHeaders = getRequestHeaders;
|
|
112
|
+
export const getRequestFingerprint = createWrapperFunction(h3.getRequestFingerprint);
|
|
113
|
+
export const getRequestWebStream = () => getEvent().req.body;
|
|
114
|
+
export const readFormData = () => getEvent().req.formData();
|
|
115
|
+
export const readValidatedBody = createWrapperFunction(h3.readValidatedBody);
|
|
116
|
+
export const getContext = createWrapperFunction(_getContext);
|
|
117
|
+
export const setContext = createWrapperFunction(_setContext);
|
|
118
|
+
export const removeResponseHeader = (name) => getEvent().res.headers.delete(name);
|
|
119
|
+
export const clearResponseHeaders = (headerNames) => {
|
|
120
|
+
const headers = getEvent().res.headers;
|
|
121
|
+
if (headerNames && headerNames.length > 0) {
|
|
122
|
+
for (const name of headerNames) {
|
|
123
|
+
headers.delete(name);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
for (const name of headers.keys()) {
|
|
128
|
+
headers.delete(name);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
1
|
+
export type { APIEvent, APIHandler, Asset, ContextMatches, DocumentComponentProps, FetchEvent, HandlerOptions, PageEvent, ResponseStub, ServerFunctionMeta } from "./server/types.ts";
|
|
2
|
+
export { default as clientOnly } from "./shared/clientOnly.ts";
|
|
3
|
+
export { GET } from "./shared/GET.ts";
|
|
4
|
+
export { HttpHeader } from "./shared/HttpHeader.tsx";
|
|
5
|
+
export { HttpStatusCode } from "./shared/HttpStatusCode.ts";
|
|
6
|
+
export { getServerFunctionMeta } from "./shared/serverFunction.ts";
|
package/dist/index.jsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @refresh skip
|
|
2
|
-
export { default as clientOnly } from "./shared/clientOnly";
|
|
3
|
-
export { GET } from "./shared/GET";
|
|
4
|
-
export { HttpHeader } from "./shared/HttpHeader";
|
|
5
|
-
export { HttpStatusCode } from "./shared/HttpStatusCode";
|
|
6
|
-
export { getServerFunctionMeta } from "./shared/serverFunction";
|
|
2
|
+
export { default as clientOnly } from "./shared/clientOnly.js";
|
|
3
|
+
export { GET } from "./shared/GET.js";
|
|
4
|
+
export { HttpHeader } from "./shared/HttpHeader.jsx";
|
|
5
|
+
export { HttpStatusCode } from "./shared/HttpStatusCode.js";
|
|
6
|
+
export { getServerFunctionMeta } from "./shared/serverFunction.js";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Middleware } from "h3";
|
|
2
|
+
import type { FetchEvent } from "../server/types.ts";
|
|
2
3
|
/** Function responsible for receiving an observable [operation]{@link Operation} and returning a [result]{@link OperationResult}. */
|
|
3
4
|
export type MiddlewareFn = (event: FetchEvent) => Promise<unknown> | unknown;
|
|
4
5
|
/** This composes an array of Exchanges into a single ExchangeIO function */
|
|
@@ -8,11 +9,10 @@ type ResponseMiddlewareResponseParam = {
|
|
|
8
9
|
body?: Awaited<EventHandlerResponse>;
|
|
9
10
|
};
|
|
10
11
|
export type ResponseMiddleware = (event: FetchEvent, response: ResponseMiddlewareResponseParam) => Response | Promise<Response> | void | Promise<void>;
|
|
11
|
-
export declare function createMiddleware(
|
|
12
|
+
export declare function createMiddleware(args: {
|
|
13
|
+
/** @deprecated Use H3 `Middleware` */
|
|
12
14
|
onRequest?: RequestMiddleware | RequestMiddleware[] | undefined;
|
|
15
|
+
/** @deprecated Use H3 `Middleware` */
|
|
13
16
|
onBeforeResponse?: ResponseMiddleware | ResponseMiddleware[] | undefined;
|
|
14
|
-
}):
|
|
15
|
-
onRequest?: import("h3")._RequestMiddleware | import("h3")._RequestMiddleware[] | undefined;
|
|
16
|
-
onBeforeResponse?: import("h3")._ResponseMiddleware | import("h3")._ResponseMiddleware[] | undefined;
|
|
17
|
-
};
|
|
17
|
+
} | Middleware[]): Middleware[];
|
|
18
18
|
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// @refresh skip
|
|
2
|
+
import { getFetchEvent } from "../server/fetchEvent.js";
|
|
3
|
+
function wrapRequestMiddleware(onRequest) {
|
|
4
|
+
return async (h3Event) => {
|
|
5
|
+
const fetchEvent = getFetchEvent(h3Event);
|
|
6
|
+
const response = await onRequest(fetchEvent);
|
|
7
|
+
if (response)
|
|
8
|
+
return response;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function wrapResponseMiddleware(onBeforeResponse) {
|
|
12
|
+
return async (h3Event, next) => {
|
|
13
|
+
const resp = await next();
|
|
14
|
+
const fetchEvent = getFetchEvent(h3Event);
|
|
15
|
+
const mwResponse = await onBeforeResponse(fetchEvent, {
|
|
16
|
+
body: resp?.body,
|
|
17
|
+
});
|
|
18
|
+
if (mwResponse)
|
|
19
|
+
return mwResponse;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function createMiddleware(args) {
|
|
23
|
+
if (Array.isArray(args))
|
|
24
|
+
return args;
|
|
25
|
+
const mw = [];
|
|
26
|
+
if (typeof args.onRequest === "function") {
|
|
27
|
+
mw.push(wrapRequestMiddleware(args.onRequest));
|
|
28
|
+
}
|
|
29
|
+
else if (Array.isArray(args.onRequest)) {
|
|
30
|
+
mw.push(...args.onRequest.map(wrapRequestMiddleware));
|
|
31
|
+
}
|
|
32
|
+
if (typeof args.onBeforeResponse === "function") {
|
|
33
|
+
mw.push(wrapResponseMiddleware(args.onBeforeResponse));
|
|
34
|
+
}
|
|
35
|
+
else if (Array.isArray(args.onBeforeResponse)) {
|
|
36
|
+
mw.push(...args.onBeforeResponse.map(wrapResponseMiddleware));
|
|
37
|
+
}
|
|
38
|
+
return mw;
|
|
39
|
+
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { lazy } from "solid-js";
|
|
1
2
|
import { getRequestEvent, isServer } from "solid-js/web";
|
|
2
|
-
import
|
|
3
|
-
|
|
3
|
+
import { pageRoutes as routeConfigs } from "./server/routes.js";
|
|
4
|
+
const components = {};
|
|
4
5
|
export function createRoutes() {
|
|
5
6
|
function createRoute(route) {
|
|
7
|
+
const component = route.$component && (components[route.$component.src] ??= lazy(route.$component.import));
|
|
6
8
|
return {
|
|
7
9
|
...route,
|
|
8
10
|
...(route.$$route ? route.$$route.require().route : undefined),
|
|
@@ -10,10 +12,7 @@ export function createRoutes() {
|
|
|
10
12
|
...(route.$$route ? route.$$route.require().route.info : {}),
|
|
11
13
|
filesystem: true
|
|
12
14
|
},
|
|
13
|
-
component
|
|
14
|
-
lazyRoute(route.$component, import.meta.env.START_ISLANDS
|
|
15
|
-
? import.meta.env.MANIFEST["ssr"]
|
|
16
|
-
: import.meta.env.MANIFEST["client"], import.meta.env.MANIFEST["ssr"]),
|
|
15
|
+
component,
|
|
17
16
|
children: route.children ? route.children.map(createRoute) : undefined
|
|
18
17
|
};
|
|
19
18
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { Component
|
|
2
|
-
import type { DocumentComponentProps } from "./types";
|
|
1
|
+
import type { Component } from "solid-js";
|
|
2
|
+
import type { DocumentComponentProps } from "./types.ts";
|
|
3
3
|
/**
|
|
4
4
|
*
|
|
5
5
|
* Read more: https://docs.solidjs.com/solid-start/reference/server/start-server
|
|
6
6
|
*/
|
|
7
7
|
export declare function StartServer(props: {
|
|
8
8
|
document: Component<DocumentComponentProps>;
|
|
9
|
-
}): JSX.Element;
|
|
9
|
+
}): import("solid-js").JSX.Element;
|
|
@@ -1,27 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { renderAsset } from "./renderAsset";
|
|
1
|
+
import { Hydration, HydrationScript, NoHydration, getRequestEvent, ssr } from "solid-js/web";
|
|
2
|
+
import App from "solid-start:app";
|
|
3
|
+
import { ErrorBoundary, TopErrorBoundary } from "../shared/ErrorBoundary.jsx";
|
|
4
|
+
import { useAssets } from "./assets/index.js";
|
|
5
|
+
import { getSsrManifest } from "./manifest/ssr-manifest.js";
|
|
7
6
|
const docType = ssr("<!DOCTYPE html>");
|
|
8
|
-
function matchRoute(matches, routes, matched = []) {
|
|
9
|
-
for (let i = 0; i < routes.length; i++) {
|
|
10
|
-
const segment = routes[i];
|
|
11
|
-
if (segment.path !== matches[0].path)
|
|
12
|
-
continue;
|
|
13
|
-
let next = [...matched, segment];
|
|
14
|
-
if (segment.children) {
|
|
15
|
-
const nextMatches = matches.slice(1);
|
|
16
|
-
if (nextMatches.length === 0)
|
|
17
|
-
continue;
|
|
18
|
-
next = matchRoute(nextMatches, segment.children, next);
|
|
19
|
-
if (!next)
|
|
20
|
-
continue;
|
|
21
|
-
}
|
|
22
|
-
return next;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
7
|
/**
|
|
26
8
|
*
|
|
27
9
|
* Read more: https://docs.solidjs.com/solid-start/reference/server/start-server
|
|
@@ -30,49 +12,13 @@ export function StartServer(props) {
|
|
|
30
12
|
const context = getRequestEvent();
|
|
31
13
|
// @ts-ignore
|
|
32
14
|
const nonce = context.nonce;
|
|
33
|
-
|
|
34
|
-
Promise.resolve().then(async () => {
|
|
35
|
-
let assetPromises = [];
|
|
36
|
-
// @ts-ignore
|
|
37
|
-
if (context.router && context.router.matches) {
|
|
38
|
-
// @ts-ignore
|
|
39
|
-
const matches = [...context.router.matches];
|
|
40
|
-
while (matches.length && (!matches[0].info || !matches[0].info.filesystem))
|
|
41
|
-
matches.shift();
|
|
42
|
-
const matched = matches.length && matchRoute(matches, context.routes);
|
|
43
|
-
if (matched) {
|
|
44
|
-
const inputs = import.meta.env.MANIFEST[import.meta.env.START_ISLANDS ? "ssr" : "client"]
|
|
45
|
-
.inputs;
|
|
46
|
-
for (let i = 0; i < matched.length; i++) {
|
|
47
|
-
const segment = matched[i];
|
|
48
|
-
const part = inputs[segment["$component"].src];
|
|
49
|
-
assetPromises.push(part.assets());
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
else if (import.meta.env.DEV)
|
|
53
|
-
console.warn("No route matched for preloading js assets");
|
|
54
|
-
}
|
|
55
|
-
assets = await Promise.all(assetPromises).then(a =>
|
|
56
|
-
// dedupe assets
|
|
57
|
-
[...new Map(a.flat().map(item => [item.attrs.key, item])).values()].filter(asset => import.meta.env.START_ISLANDS
|
|
58
|
-
? false
|
|
59
|
-
: asset.attrs.rel === "modulepreload" &&
|
|
60
|
-
!context.assets.find((a) => a.attrs.key === asset.attrs.key)));
|
|
61
|
-
});
|
|
62
|
-
useAssets(() => (assets.length ? assets.map(m => renderAsset(m)) : undefined));
|
|
15
|
+
useAssets(context.assets, nonce);
|
|
63
16
|
return (<NoHydration>
|
|
64
17
|
{docType}
|
|
65
18
|
<TopErrorBoundary>
|
|
66
|
-
<props.document assets={<>
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
</>} scripts={nonce ? (<>
|
|
70
|
-
<script nonce={nonce} innerHTML={`window.manifest = ${JSON.stringify(context.manifest)}`}/>
|
|
71
|
-
<script type="module" nonce={nonce} async src={import.meta.env.MANIFEST["client"].inputs[import.meta.env.MANIFEST["client"].handler].output.path}/>
|
|
72
|
-
</>) : (<>
|
|
73
|
-
<script innerHTML={`window.manifest = ${JSON.stringify(context.manifest)}`}/>
|
|
74
|
-
<script type="module" async src={import.meta.env.MANIFEST["client"].inputs[import.meta.env.MANIFEST["client"].handler].output.path}/>
|
|
75
|
-
</>)}>
|
|
19
|
+
<props.document assets={<HydrationScript />} scripts={<>
|
|
20
|
+
<script type="module" nonce={nonce} async src={getSsrManifest("client").path(import.meta.env.START_CLIENT_ENTRY)}/>
|
|
21
|
+
</>}>
|
|
76
22
|
{!import.meta.env.START_ISLANDS ? (<Hydration>
|
|
77
23
|
<ErrorBoundary>
|
|
78
24
|
<App />
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { onCleanup, sharedConfig } from "solid-js";
|
|
2
|
+
import { getRequestEvent, useAssets as useAssets_ } from "solid-js/web";
|
|
3
|
+
import { renderAsset } from "./render.jsx";
|
|
4
|
+
const REGISTRY = Symbol("assetRegistry");
|
|
5
|
+
const NOOP = () => "";
|
|
6
|
+
const keyAttrs = ["href", "rel", "data-vite-dev-id"];
|
|
7
|
+
const getEntity = (registry, asset) => {
|
|
8
|
+
let key = asset.tag;
|
|
9
|
+
for (const k of keyAttrs) {
|
|
10
|
+
if (!(k in asset.attrs))
|
|
11
|
+
continue;
|
|
12
|
+
key += `[${k}='${asset.attrs[k]}']`;
|
|
13
|
+
}
|
|
14
|
+
const entity = (registry[key] ??= {
|
|
15
|
+
key,
|
|
16
|
+
consumers: 0
|
|
17
|
+
});
|
|
18
|
+
return entity;
|
|
19
|
+
};
|
|
20
|
+
export const useAssets = (assets, nonce) => {
|
|
21
|
+
if (!assets.length)
|
|
22
|
+
return;
|
|
23
|
+
const registry = (getRequestEvent().locals[REGISTRY] ??= {});
|
|
24
|
+
const ssrRequestAssets = sharedConfig.context?.assets;
|
|
25
|
+
const cssKeys = [];
|
|
26
|
+
for (const asset of assets) {
|
|
27
|
+
const entity = getEntity(registry, asset);
|
|
28
|
+
const isCSSLink = asset.tag === "link" && asset.attrs.rel === "stylesheet";
|
|
29
|
+
const isCSS = isCSSLink || asset.tag === "style";
|
|
30
|
+
if (isCSS) {
|
|
31
|
+
cssKeys.push(entity.key);
|
|
32
|
+
}
|
|
33
|
+
entity.consumers++;
|
|
34
|
+
if (entity.consumers > 1)
|
|
35
|
+
continue;
|
|
36
|
+
// Mounting logic
|
|
37
|
+
useAssets_(() => renderAsset(asset, nonce));
|
|
38
|
+
entity.ssrIdx = ssrRequestAssets.length - 1;
|
|
39
|
+
}
|
|
40
|
+
onCleanup(() => {
|
|
41
|
+
for (const key of cssKeys) {
|
|
42
|
+
const entity = registry[key];
|
|
43
|
+
entity.consumers--;
|
|
44
|
+
if (entity.consumers != 0) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
// Ideally this logic should be implemented directly in dom-expressions
|
|
48
|
+
ssrRequestAssets.splice(entity.ssrIdx, 1, NOOP);
|
|
49
|
+
delete registry[key];
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { JSX } from "solid-js";
|
|
2
|
+
export declare function renderAsset(asset: Asset, nonce?: string): any;
|
|
3
|
+
export type Asset = {
|
|
4
|
+
tag: "style";
|
|
5
|
+
attrs: JSX.StyleHTMLAttributes<HTMLStyleElement> & {
|
|
6
|
+
key?: string;
|
|
7
|
+
};
|
|
8
|
+
children?: JSX.Element;
|
|
9
|
+
} | {
|
|
10
|
+
tag: "script";
|
|
11
|
+
attrs: JSX.ScriptHTMLAttributes<HTMLScriptElement> & {
|
|
12
|
+
key?: string;
|
|
13
|
+
};
|
|
14
|
+
} | {
|
|
15
|
+
tag: "link";
|
|
16
|
+
attrs: JSX.LinkHTMLAttributes<HTMLLinkElement> & {
|
|
17
|
+
key?: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
@@ -6,7 +6,7 @@ const assetMap = {
|
|
|
6
6
|
{" "}
|
|
7
7
|
</script>) : null;
|
|
8
8
|
},
|
|
9
|
-
noscript: (props) => (<noscript {...props.attrs}>{props.children}</noscript>)
|
|
9
|
+
noscript: (props) => (<noscript {...props.attrs}>{props.children}</noscript>)
|
|
10
10
|
};
|
|
11
11
|
export function renderAsset(asset, nonce) {
|
|
12
12
|
let { tag, attrs: { key, ...attrs } = { key: undefined }, children } = asset;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { resolve } from "pathe";
|
|
3
|
+
async function getViteModuleNode(vite, file) {
|
|
4
|
+
let nodePath = file;
|
|
5
|
+
let node = vite.moduleGraph.getModuleById(file);
|
|
6
|
+
if (!node) {
|
|
7
|
+
const resolvedId = await vite.pluginContainer.resolveId(file, undefined);
|
|
8
|
+
if (!resolvedId)
|
|
9
|
+
return;
|
|
10
|
+
nodePath = resolvedId.id;
|
|
11
|
+
node = vite.moduleGraph.getModuleById(file);
|
|
12
|
+
}
|
|
13
|
+
if (!node) {
|
|
14
|
+
nodePath = resolve(nodePath);
|
|
15
|
+
node = await vite.moduleGraph.getModuleByUrl(file);
|
|
16
|
+
}
|
|
17
|
+
if (!node) {
|
|
18
|
+
await vite.moduleGraph.ensureEntryFromUrl(nodePath, false);
|
|
19
|
+
node = vite.moduleGraph.getModuleById(nodePath);
|
|
20
|
+
}
|
|
21
|
+
return node;
|
|
22
|
+
}
|
|
23
|
+
async function findModuleDependencies(vite, file, deps, crawledFiles = new Set()) {
|
|
24
|
+
crawledFiles.add(file);
|
|
25
|
+
const module = await getViteModuleNode(vite, file);
|
|
26
|
+
if (!module?.id || deps.has(module))
|
|
27
|
+
return;
|
|
28
|
+
deps.add(module);
|
|
29
|
+
if (module.url.endsWith(".css") || module.url.includes("node_modules"))
|
|
30
|
+
return;
|
|
31
|
+
if (!module.transformResult) {
|
|
32
|
+
await vite.transformRequest(module.id).catch(() => { });
|
|
33
|
+
}
|
|
34
|
+
if (!module.transformResult?.deps)
|
|
35
|
+
return;
|
|
36
|
+
// Relying on module.transformResult.deps instead of module.importedModules because:
|
|
37
|
+
// transformResult properly separates imports into deps and dynamicDeps, importedModules doesn't
|
|
38
|
+
// Style crawling has to skip dynamic imports as such modules load their styles themselves
|
|
39
|
+
for (const dep of module.transformResult.deps) {
|
|
40
|
+
if (crawledFiles.has(dep)) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
await findModuleDependencies(vite, dep, deps, crawledFiles);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Vite doesn't expose these so we just copy the list for now
|
|
47
|
+
// https://github.com/vitejs/vite/blob/d6bde8b03d433778aaed62afc2be0630c8131908/packages/vite/src/node/constants.ts#L49C23-L50
|
|
48
|
+
const cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)$/;
|
|
49
|
+
// https://github.com/vitejs/vite/blob/d6bde8b03d433778aaed62afc2be0630c8131908/packages/vite/src/node/plugins/css.ts#L160
|
|
50
|
+
const cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
|
|
51
|
+
const isCssFile = (file) => cssFileRegExp.test(file);
|
|
52
|
+
export const isCssModulesFile = (file) => cssModulesRegExp.test(file);
|
|
53
|
+
export async function findStylesInModuleGraph(vite, id) {
|
|
54
|
+
const absolute = path.resolve(process.cwd(), id);
|
|
55
|
+
const dependencies = new Set();
|
|
56
|
+
try {
|
|
57
|
+
await findModuleDependencies(vite, absolute, dependencies);
|
|
58
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
console.error(e);
|
|
61
|
+
}
|
|
62
|
+
const styles = {};
|
|
63
|
+
for (const dep of dependencies) {
|
|
64
|
+
if (dep.id && isCssFile(dep.url)) {
|
|
65
|
+
styles[dep.id] = dep.url;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return styles;
|
|
69
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { H3Event } from "
|
|
2
|
-
import type { FetchEvent } from "./types";
|
|
1
|
+
import { type EventHandler, type H3Event, type Middleware } from "h3";
|
|
2
|
+
import type { FetchEvent } from "./types.ts";
|
|
3
3
|
export declare function createFetchEvent(event: H3Event): FetchEvent;
|
|
4
|
-
export declare function cloneEvent<T extends FetchEvent>(fetchEvent: T): T;
|
|
5
4
|
export declare function getFetchEvent(h3Event: H3Event): FetchEvent;
|
|
6
5
|
export declare function mergeResponseHeaders(h3Event: H3Event, headers: Headers): void;
|
|
6
|
+
export declare const decorateHandler: <T extends EventHandler>(fn: T) => T;
|
|
7
|
+
export declare const decorateMiddleware: <T extends Middleware>(fn: T) => T;
|
|
@@ -1,88 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { getRequestIP } from "h3";
|
|
2
|
+
import { provideRequestEvent } from "solid-js/web/storage";
|
|
3
|
+
const FETCH_EVENT_CONTEXT = "solidFetchEvent";
|
|
3
4
|
export function createFetchEvent(event) {
|
|
4
5
|
return {
|
|
5
|
-
request:
|
|
6
|
-
response:
|
|
6
|
+
request: event.req,
|
|
7
|
+
response: event.res,
|
|
7
8
|
clientAddress: getRequestIP(event),
|
|
8
9
|
locals: {},
|
|
9
|
-
nativeEvent: event
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
export function cloneEvent(fetchEvent) {
|
|
13
|
-
return {
|
|
14
|
-
...fetchEvent
|
|
10
|
+
nativeEvent: event,
|
|
15
11
|
};
|
|
16
12
|
}
|
|
17
13
|
export function getFetchEvent(h3Event) {
|
|
18
|
-
if (!h3Event.context[
|
|
14
|
+
if (!h3Event.context[FETCH_EVENT_CONTEXT]) {
|
|
19
15
|
const fetchEvent = createFetchEvent(h3Event);
|
|
20
|
-
h3Event.context[
|
|
16
|
+
h3Event.context[FETCH_EVENT_CONTEXT] = fetchEvent;
|
|
21
17
|
}
|
|
22
|
-
return h3Event.context[
|
|
18
|
+
return h3Event.context[FETCH_EVENT_CONTEXT];
|
|
23
19
|
}
|
|
24
20
|
export function mergeResponseHeaders(h3Event, headers) {
|
|
25
21
|
for (const [key, value] of headers.entries()) {
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
class HeaderProxy {
|
|
30
|
-
event;
|
|
31
|
-
constructor(event) {
|
|
32
|
-
this.event = event;
|
|
33
|
-
}
|
|
34
|
-
get(key) {
|
|
35
|
-
const h = getResponseHeader(this.event, key);
|
|
36
|
-
return Array.isArray(h) ? h.join(", ") : h || null;
|
|
37
|
-
}
|
|
38
|
-
has(key) {
|
|
39
|
-
return this.get(key) !== undefined;
|
|
40
|
-
}
|
|
41
|
-
set(key, value) {
|
|
42
|
-
return setResponseHeader(this.event, key, value);
|
|
43
|
-
}
|
|
44
|
-
delete(key) {
|
|
45
|
-
return removeResponseHeader(this.event, key);
|
|
46
|
-
}
|
|
47
|
-
append(key, value) {
|
|
48
|
-
appendResponseHeader(this.event, key, value);
|
|
22
|
+
h3Event.res.headers.append(key, value);
|
|
49
23
|
}
|
|
50
|
-
getSetCookie() {
|
|
51
|
-
const cookies = getResponseHeader(this.event, "Set-Cookie");
|
|
52
|
-
return Array.isArray(cookies) ? cookies : [cookies];
|
|
53
|
-
}
|
|
54
|
-
forEach(fn) {
|
|
55
|
-
return Object.entries(getResponseHeaders(this.event)).forEach(([key, value]) => fn(Array.isArray(value) ? value.join(", ") : value, key, this));
|
|
56
|
-
}
|
|
57
|
-
entries() {
|
|
58
|
-
return Object.entries(getResponseHeaders(this.event))
|
|
59
|
-
.map(([key, value]) => [key, Array.isArray(value) ? value.join(", ") : value])[Symbol.iterator]();
|
|
60
|
-
}
|
|
61
|
-
keys() {
|
|
62
|
-
return Object.keys(getResponseHeaders(this.event))[Symbol.iterator]();
|
|
63
|
-
}
|
|
64
|
-
values() {
|
|
65
|
-
return Object.values(getResponseHeaders(this.event))
|
|
66
|
-
.map(value => (Array.isArray(value) ? value.join(", ") : value))[Symbol.iterator]();
|
|
67
|
-
}
|
|
68
|
-
[Symbol.iterator]() {
|
|
69
|
-
return this.entries()[Symbol.iterator]();
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
function createResponseStub(event) {
|
|
73
|
-
return {
|
|
74
|
-
get status() {
|
|
75
|
-
return getResponseStatus(event);
|
|
76
|
-
},
|
|
77
|
-
set status(v) {
|
|
78
|
-
setResponseStatus(event, v);
|
|
79
|
-
},
|
|
80
|
-
get statusText() {
|
|
81
|
-
return getResponseStatusText(event);
|
|
82
|
-
},
|
|
83
|
-
set statusText(v) {
|
|
84
|
-
setResponseStatus(event, getResponseStatus(event), v);
|
|
85
|
-
},
|
|
86
|
-
headers: new HeaderProxy(event)
|
|
87
|
-
};
|
|
88
24
|
}
|
|
25
|
+
export const decorateHandler = (fn) => (event => provideRequestEvent(getFetchEvent(event), () => fn(event)));
|
|
26
|
+
export const decorateMiddleware = (fn) => ((event, next) => provideRequestEvent(getFetchEvent(event), () => fn(event, next)));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|