@solidjs/start 1.0.0 → 1.0.2
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/config/index.d.ts +17 -6
- package/dist/client/StartClient.d.ts +4 -0
- package/dist/client/StartClient.jsx +4 -0
- package/dist/client/islands.d.ts +4 -0
- package/dist/client/islands.jsx +4 -0
- package/dist/client/mount.d.ts +4 -0
- package/dist/client/mount.js +8 -2
- package/dist/middleware/index.d.ts +1 -1
- package/dist/router/FileRoutes.d.ts +4 -0
- package/dist/router/FileRoutes.js +8 -3
- package/dist/router/lazyRoute.js +7 -2
- package/dist/runtime/server-handler.js +51 -39
- package/dist/server/StartServer.d.ts +4 -0
- package/dist/server/StartServer.jsx +25 -19
- package/dist/server/fetchEvent.js +1 -1
- package/dist/server/handler.d.ts +4 -0
- package/dist/server/handler.js +4 -0
- package/dist/server/pageEvent.js +3 -1
- package/dist/server/renderAsset.jsx +2 -1
- package/dist/server/serverFunction.d.ts +4 -0
- package/dist/server/serverFunction.jsx +4 -0
- package/dist/server/spa/StartServer.d.ts +4 -0
- package/dist/server/spa/StartServer.jsx +14 -7
- package/dist/server/spa/handler.d.ts +4 -0
- package/dist/server/spa/handler.js +4 -0
- package/dist/shared/ErrorBoundary.d.ts +1 -0
- package/dist/shared/ErrorBoundary.jsx +28 -8
- package/dist/shared/GET.d.ts +4 -0
- package/dist/shared/GET.js +6 -3
- package/dist/shared/HttpHeader.d.ts +4 -0
- package/dist/shared/HttpHeader.jsx +4 -0
- package/dist/shared/HttpStatusCode.d.ts +4 -0
- package/dist/shared/HttpStatusCode.jsx +4 -0
- package/dist/shared/clientOnly.d.ts +4 -0
- package/dist/shared/clientOnly.jsx +4 -0
- package/package.json +7 -3
package/config/index.d.ts
CHANGED
|
@@ -3,10 +3,15 @@ import type { CustomizableConfig } from "vinxi/dist/types/lib/vite-dev";
|
|
|
3
3
|
import { InlineConfig } from "vite";
|
|
4
4
|
import type { Options } from "vite-plugin-solid";
|
|
5
5
|
|
|
6
|
-
//
|
|
6
|
+
// should probably be maintained by Vinxi
|
|
7
|
+
type VinxiViteServerOptions = Omit<
|
|
8
|
+
InlineConfig["server"],
|
|
9
|
+
"port" | "strictPort" | "host" | "middlewareMode" | "open"
|
|
10
|
+
>;
|
|
11
|
+
|
|
7
12
|
type ViteCustomizableConfig = CustomizableConfig & {
|
|
8
|
-
server?:
|
|
9
|
-
}
|
|
13
|
+
server?: VinxiViteServerOptions;
|
|
14
|
+
};
|
|
10
15
|
|
|
11
16
|
type SolidStartInlineConfig = {
|
|
12
17
|
ssr?: boolean;
|
|
@@ -16,13 +21,19 @@ type SolidStartInlineConfig = {
|
|
|
16
21
|
appRoot?: string;
|
|
17
22
|
routeDir?: string;
|
|
18
23
|
middleware?: string;
|
|
19
|
-
devOverlay?:
|
|
24
|
+
devOverlay?: boolean;
|
|
20
25
|
experimental?: {
|
|
21
26
|
islands?: boolean;
|
|
22
|
-
}
|
|
27
|
+
};
|
|
23
28
|
vite?:
|
|
24
29
|
| ViteCustomizableConfig
|
|
25
30
|
| ((options: { router: "server" | "client" | "server-function" }) => ViteCustomizableConfig);
|
|
26
31
|
};
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
/**
|
|
34
|
+
*
|
|
35
|
+
* Read more: https://docs.solidjs.com/solid-start/reference/entrypoints/app-config
|
|
36
|
+
*/
|
|
37
|
+
export declare function defineConfig(
|
|
38
|
+
baseConfig?: SolidStartInlineConfig
|
|
39
|
+
): ReturnType<typeof createApp>;
|
package/dist/client/islands.d.ts
CHANGED
package/dist/client/islands.jsx
CHANGED
package/dist/client/mount.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import type { JSX } from "solid-js";
|
|
2
2
|
import { type MountableElement } from "solid-js/web";
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* Read more: https://docs.solidjs.com/solid-start/reference/client/mount
|
|
6
|
+
*/
|
|
3
7
|
export declare function mount(fn: () => JSX.Element, el: MountableElement): (() => void) | undefined;
|
package/dist/client/mount.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { createStore } from "solid-js/store";
|
|
2
2
|
import { createComponent, getHydrationKey, getOwner, hydrate } from "solid-js/web";
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* Read more: https://docs.solidjs.com/solid-start/reference/client/mount
|
|
6
|
+
*/
|
|
3
7
|
export function mount(fn, el) {
|
|
4
8
|
if (import.meta.env.START_ISLANDS) {
|
|
5
9
|
const map = new WeakMap();
|
|
@@ -17,7 +21,8 @@ export function mount(fn, el) {
|
|
|
17
21
|
}
|
|
18
22
|
let mod = await import(
|
|
19
23
|
/* @vite-ignore */
|
|
20
|
-
import.meta.env.MANIFEST["client"].chunks[el.dataset.id.split("#")[0]].output
|
|
24
|
+
import.meta.env.MANIFEST["client"].chunks[el.dataset.id.split("#")[0]].output
|
|
25
|
+
.path);
|
|
21
26
|
if (!mod || !el.dataset.hk)
|
|
22
27
|
return;
|
|
23
28
|
let Component = mod[el.dataset.id.split("#")[1]];
|
|
@@ -58,7 +63,8 @@ export function mount(fn, el) {
|
|
|
58
63
|
const islands = document.querySelectorAll("solid-island[data-hk]");
|
|
59
64
|
const assets = new Set();
|
|
60
65
|
islands.forEach((el) => el.dataset.id && assets.add(el.dataset.id));
|
|
61
|
-
Promise.all([...assets].map(asset => import(
|
|
66
|
+
Promise.all([...assets].map(asset => import(
|
|
67
|
+
/* @vite-ignore */ import.meta.env.MANIFEST["client"].chunks[asset.split("#")[0]].output.path)))
|
|
62
68
|
.then(() => {
|
|
63
69
|
islands.forEach((el) => {
|
|
64
70
|
if (el.dataset.when === "idle" && "requestIdleCallback" in window) {
|
|
@@ -2,7 +2,7 @@ import type { FetchEvent } from "../server/types";
|
|
|
2
2
|
/** Function responsible for receiving an observable [operation]{@link Operation} and returning a [result]{@link OperationResult}. */
|
|
3
3
|
export type MiddlewareFn = (event: FetchEvent) => Promise<unknown> | unknown;
|
|
4
4
|
/** This composes an array of Exchanges into a single ExchangeIO function */
|
|
5
|
-
export type RequestMiddleware = (event: FetchEvent) => Response | Promise<Response> | void | Promise<void>;
|
|
5
|
+
export type RequestMiddleware = (event: FetchEvent) => Response | Promise<Response> | void | Promise<void> | Promise<void | Response>;
|
|
6
6
|
type EventHandlerResponse<T = any> = T | Promise<T>;
|
|
7
7
|
type ResponseMiddlewareResponseParam = {
|
|
8
8
|
body?: Awaited<EventHandlerResponse>;
|
|
@@ -10,9 +10,10 @@ export function createRoutes() {
|
|
|
10
10
|
...(route.$$route ? route.$$route.require().route.info : {}),
|
|
11
11
|
filesystem: true
|
|
12
12
|
},
|
|
13
|
-
component: route.$component &&
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
component: route.$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"]),
|
|
16
17
|
children: route.children ? route.children.map(createRoute) : undefined
|
|
17
18
|
};
|
|
18
19
|
}
|
|
@@ -20,6 +21,10 @@ export function createRoutes() {
|
|
|
20
21
|
return routes;
|
|
21
22
|
}
|
|
22
23
|
let routes;
|
|
24
|
+
/**
|
|
25
|
+
*
|
|
26
|
+
* Read more: https://docs.solidjs.com/solid-start/reference/routing/file-routes
|
|
27
|
+
*/
|
|
23
28
|
export const FileRoutes = isServer
|
|
24
29
|
? () => getRequestEvent().routes
|
|
25
30
|
: () => routes || (routes = createRoutes());
|
package/dist/router/lazyRoute.js
CHANGED
|
@@ -6,11 +6,16 @@ export default function lazyRoute(component, clientManifest, serverManifest, exp
|
|
|
6
6
|
return lazy(async () => {
|
|
7
7
|
if (import.meta.env.DEV) {
|
|
8
8
|
let manifest = import.meta.env.SSR ? serverManifest : clientManifest;
|
|
9
|
-
|
|
9
|
+
// import() throws if a module doesn't exist, which includes any
|
|
10
|
+
// modules loaded by the route itself, so it's important we catch here
|
|
11
|
+
const mod = await manifest.inputs[component.src].import().catch(() => null);
|
|
12
|
+
// fallback to an empty component as any errors will surface in the vite overlay
|
|
13
|
+
if (!mod)
|
|
14
|
+
return { default: () => [] };
|
|
10
15
|
if (!mod[exported])
|
|
11
16
|
console.error(`Module ${component.src} does not export ${exported}`);
|
|
12
17
|
const Component = mod[exported];
|
|
13
|
-
let assets = await clientManifest.inputs?.[component.src]
|
|
18
|
+
let assets = await clientManifest.inputs?.[component.src]?.assets();
|
|
14
19
|
const styles = assets.filter((asset) => asset.tag === "style");
|
|
15
20
|
if (typeof window !== "undefined" && import.meta.hot) {
|
|
16
21
|
import.meta.hot.on("css-update", data => {
|
|
@@ -8,8 +8,8 @@ import { provideRequestEvent } from "solid-js/web/storage";
|
|
|
8
8
|
import { eventHandler, setHeader, setResponseStatus } from "vinxi/http";
|
|
9
9
|
import invariant from "vinxi/lib/invariant";
|
|
10
10
|
import { cloneEvent, getFetchEvent, mergeResponseHeaders } from "../server/fetchEvent";
|
|
11
|
-
import { createPageEvent } from "../server/pageEvent";
|
|
12
11
|
import { getExpectedRedirectStatus } from "../server/handler";
|
|
12
|
+
import { createPageEvent } from "../server/pageEvent";
|
|
13
13
|
function createChunk(data) {
|
|
14
14
|
const encodeData = new TextEncoder().encode(data);
|
|
15
15
|
const bytes = encodeData.length;
|
|
@@ -139,45 +139,26 @@ async function handleServerFunction(h3Event) {
|
|
|
139
139
|
result = await handleSingleFlight(event, result);
|
|
140
140
|
}
|
|
141
141
|
// handle responses
|
|
142
|
-
if (result instanceof Response
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
result
|
|
142
|
+
if (result instanceof Response) {
|
|
143
|
+
if (result.headers && result.headers.has("X-Content-Raw"))
|
|
144
|
+
return result;
|
|
145
|
+
if (instance) {
|
|
146
|
+
// forward headers
|
|
147
|
+
if (result.headers)
|
|
148
|
+
mergeResponseHeaders(h3Event, result.headers);
|
|
149
|
+
// forward non-redirect statuses
|
|
150
|
+
if (result.status && (result.status < 300 || result.status >= 400))
|
|
151
|
+
setResponseStatus(h3Event, result.status);
|
|
152
|
+
if (result.customBody) {
|
|
153
|
+
result = await result.customBody();
|
|
154
|
+
}
|
|
155
|
+
else if (result.body == undefined)
|
|
156
|
+
result = null;
|
|
151
157
|
}
|
|
152
|
-
else if (result.body == undefined)
|
|
153
|
-
result = null;
|
|
154
158
|
}
|
|
155
159
|
// handle no JS success case
|
|
156
|
-
if (!instance)
|
|
157
|
-
|
|
158
|
-
let redirectUrl = new URL(request.headers.get("referer")).toString();
|
|
159
|
-
let statusCode = 302;
|
|
160
|
-
if (result instanceof Response && result.headers.has("Location")) {
|
|
161
|
-
redirectUrl = new URL(result.headers.get("Location"), new URL(request.url).origin + import.meta.env.SERVER_BASE_URL).toString();
|
|
162
|
-
statusCode = getExpectedRedirectStatus(result);
|
|
163
|
-
}
|
|
164
|
-
return new Response(null, {
|
|
165
|
-
status: statusCode,
|
|
166
|
-
headers: {
|
|
167
|
-
Location: redirectUrl,
|
|
168
|
-
...(result
|
|
169
|
-
? {
|
|
170
|
-
"Set-Cookie": `flash=${JSON.stringify({
|
|
171
|
-
url: url.pathname + encodeURIComponent(url.search),
|
|
172
|
-
result: isError ? result.message : result,
|
|
173
|
-
error: isError,
|
|
174
|
-
input: [...parsed.slice(0, -1), [...parsed[parsed.length - 1].entries()]]
|
|
175
|
-
})}; Secure; HttpOnly;`
|
|
176
|
-
}
|
|
177
|
-
: {})
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
}
|
|
160
|
+
if (!instance)
|
|
161
|
+
return handleNoJS(result, request, parsed);
|
|
181
162
|
setHeader(h3Event, "content-type", "text/javascript");
|
|
182
163
|
return serializeToStream(instance, result);
|
|
183
164
|
}
|
|
@@ -197,10 +178,14 @@ async function handleServerFunction(h3Event) {
|
|
|
197
178
|
}
|
|
198
179
|
else if (x.body == undefined)
|
|
199
180
|
x = null;
|
|
181
|
+
setHeader(h3Event, "X-Error", "true");
|
|
200
182
|
}
|
|
201
|
-
else {
|
|
183
|
+
else if (instance) {
|
|
202
184
|
const error = x instanceof Error ? x.message : typeof x === "string" ? x : "true";
|
|
203
|
-
setHeader(h3Event, "X-Error", error);
|
|
185
|
+
setHeader(h3Event, "X-Error", error.replace(/[\r\n]+/g, ""));
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
x = handleNoJS(x, request, parsed, true);
|
|
204
189
|
}
|
|
205
190
|
if (instance) {
|
|
206
191
|
setHeader(h3Event, "content-type", "text/javascript");
|
|
@@ -209,6 +194,33 @@ async function handleServerFunction(h3Event) {
|
|
|
209
194
|
return x;
|
|
210
195
|
}
|
|
211
196
|
}
|
|
197
|
+
function handleNoJS(result, request, parsed, thrown) {
|
|
198
|
+
const url = new URL(request.url);
|
|
199
|
+
const isError = result instanceof Error;
|
|
200
|
+
let redirectUrl = new URL(request.headers.get("referer")).toString();
|
|
201
|
+
let statusCode = 302;
|
|
202
|
+
if (result instanceof Response && result.headers.has("Location")) {
|
|
203
|
+
redirectUrl = new URL(result.headers.get("Location"), url.origin + import.meta.env.SERVER_BASE_URL).toString();
|
|
204
|
+
statusCode = getExpectedRedirectStatus(result);
|
|
205
|
+
}
|
|
206
|
+
return new Response(null, {
|
|
207
|
+
status: statusCode,
|
|
208
|
+
headers: {
|
|
209
|
+
Location: redirectUrl,
|
|
210
|
+
...(result
|
|
211
|
+
? {
|
|
212
|
+
"Set-Cookie": `flash=${JSON.stringify({
|
|
213
|
+
url: url.pathname + encodeURIComponent(url.search),
|
|
214
|
+
result: isError ? result.message : result,
|
|
215
|
+
thrown: thrown,
|
|
216
|
+
error: isError,
|
|
217
|
+
input: [...parsed.slice(0, -1), [...parsed[parsed.length - 1].entries()]]
|
|
218
|
+
})}; Secure; HttpOnly;`
|
|
219
|
+
}
|
|
220
|
+
: {})
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
}
|
|
212
224
|
let App;
|
|
213
225
|
async function handleSingleFlight(sourceEvent, result) {
|
|
214
226
|
let revalidate;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { Component, JSX } from "solid-js";
|
|
2
2
|
import type { DocumentComponentProps } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* Read more: https://docs.solidjs.com/solid-start/reference/server/start-server
|
|
6
|
+
*/
|
|
3
7
|
export declare function StartServer(props: {
|
|
4
8
|
document: Component<DocumentComponentProps>;
|
|
5
9
|
}): JSX.Element;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// @ts-ignore
|
|
3
3
|
import App from "#start/app";
|
|
4
4
|
import { Hydration, HydrationScript, NoHydration, getRequestEvent, ssr, useAssets } from "solid-js/web";
|
|
5
|
-
import { ErrorBoundary } from "../shared/ErrorBoundary";
|
|
5
|
+
import { ErrorBoundary, TopErrorBoundary } from "../shared/ErrorBoundary";
|
|
6
6
|
import { renderAsset } from "./renderAsset";
|
|
7
7
|
const docType = ssr("<!DOCTYPE html>");
|
|
8
8
|
function matchRoute(matches, routes, matched = []) {
|
|
@@ -22,11 +22,15 @@ function matchRoute(matches, routes, matched = []) {
|
|
|
22
22
|
return next;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
*
|
|
27
|
+
* Read more: https://docs.solidjs.com/solid-start/reference/server/start-server
|
|
28
|
+
*/
|
|
25
29
|
export function StartServer(props) {
|
|
26
30
|
const context = getRequestEvent();
|
|
27
31
|
// @ts-ignore
|
|
28
32
|
const nonce = context.nonce;
|
|
29
|
-
let assets;
|
|
33
|
+
let assets = [];
|
|
30
34
|
Promise.resolve().then(async () => {
|
|
31
35
|
let assetPromises = [];
|
|
32
36
|
// @ts-ignore
|
|
@@ -57,23 +61,25 @@ export function StartServer(props) {
|
|
|
57
61
|
useAssets(() => (assets.length ? assets.map(m => renderAsset(m)) : undefined));
|
|
58
62
|
return (<NoHydration>
|
|
59
63
|
{docType}
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
64
|
+
<TopErrorBoundary>
|
|
65
|
+
<props.document assets={<>
|
|
66
|
+
<HydrationScript />
|
|
67
|
+
{context.assets.map((m) => renderAsset(m, nonce))}
|
|
68
|
+
</>} scripts={nonce ? (<>
|
|
69
|
+
<script nonce={nonce} innerHTML={`window.manifest = ${JSON.stringify(context.manifest)}`}/>
|
|
70
|
+
<script type="module" nonce={nonce} async src={import.meta.env.MANIFEST["client"].inputs[import.meta.env.MANIFEST["client"].handler].output.path}/>
|
|
71
|
+
</>) : (<>
|
|
72
|
+
<script innerHTML={`window.manifest = ${JSON.stringify(context.manifest)}`}/>
|
|
73
|
+
<script type="module" async src={import.meta.env.MANIFEST["client"].inputs[import.meta.env.MANIFEST["client"].handler].output.path}/>
|
|
74
|
+
</>)}>
|
|
75
|
+
{!import.meta.env.START_ISLANDS ? (<Hydration>
|
|
76
|
+
<ErrorBoundary>
|
|
77
|
+
<App />
|
|
78
|
+
</ErrorBoundary>
|
|
79
|
+
</Hydration>) : (<ErrorBoundary>
|
|
72
80
|
<App />
|
|
73
|
-
</ErrorBoundary>
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
</ErrorBoundary>)}
|
|
77
|
-
</props.document>
|
|
81
|
+
</ErrorBoundary>)}
|
|
82
|
+
</props.document>
|
|
83
|
+
</TopErrorBoundary>
|
|
78
84
|
</NoHydration>);
|
|
79
85
|
}
|
|
@@ -81,7 +81,7 @@ function createResponseStub(event) {
|
|
|
81
81
|
return getResponseStatusText(event);
|
|
82
82
|
},
|
|
83
83
|
set statusText(v) {
|
|
84
|
-
setResponseStatus(event, getResponseStatus(), v);
|
|
84
|
+
setResponseStatus(event, getResponseStatus(event), v);
|
|
85
85
|
},
|
|
86
86
|
headers: new HeaderProxy(event)
|
|
87
87
|
};
|
package/dist/server/handler.d.ts
CHANGED
|
@@ -5,4 +5,8 @@ import type { FetchEvent, HandlerOptions, PageEvent, ResponseStub } from "./type
|
|
|
5
5
|
*/
|
|
6
6
|
export declare function getExpectedRedirectStatus(response: ResponseStub): number;
|
|
7
7
|
export declare function createBaseHandler(fn: (context: PageEvent) => unknown, createPageEvent: (event: FetchEvent) => Promise<PageEvent>, options?: HandlerOptions | ((context: PageEvent) => HandlerOptions | Promise<HandlerOptions>)): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* Read more: https://docs.solidjs.com/solid-start/reference/server/create-handler
|
|
11
|
+
*/
|
|
8
12
|
export declare function createHandler(fn: (context: PageEvent) => unknown, options?: HandlerOptions | ((context: PageEvent) => HandlerOptions | Promise<HandlerOptions>)): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
|
package/dist/server/handler.js
CHANGED
|
@@ -108,6 +108,10 @@ function handleStreamCompleteRedirect(context) {
|
|
|
108
108
|
to && write(`<script>window.location="${to}"</script>`);
|
|
109
109
|
};
|
|
110
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
*
|
|
113
|
+
* Read more: https://docs.solidjs.com/solid-start/reference/server/create-handler
|
|
114
|
+
*/
|
|
111
115
|
export function createHandler(fn, options) {
|
|
112
116
|
return createBaseHandler(fn, createPageEvent, options);
|
|
113
117
|
}
|
package/dist/server/pageEvent.js
CHANGED
|
@@ -9,11 +9,13 @@ function initFromFlash(ctx) {
|
|
|
9
9
|
return;
|
|
10
10
|
const input = [...param.input.slice(0, -1), new Map(param.input[param.input.length - 1])];
|
|
11
11
|
setCookie(ctx.nativeEvent, "flash", "", { maxAge: 0 });
|
|
12
|
+
const result = param.error ? new Error(param.result) : param.result;
|
|
12
13
|
return {
|
|
13
14
|
input,
|
|
14
15
|
url: param.url,
|
|
15
16
|
pending: false,
|
|
16
|
-
result: param.
|
|
17
|
+
result: param.thrown ? undefined : result,
|
|
18
|
+
error: param.thrown ? result : undefined,
|
|
17
19
|
};
|
|
18
20
|
}
|
|
19
21
|
export async function createPageEvent(ctx) {
|
|
@@ -5,7 +5,8 @@ const assetMap = {
|
|
|
5
5
|
return props.attrs.src ? (<script {...props.attrs} id={props.key}>
|
|
6
6
|
{" "}
|
|
7
7
|
</script>) : null;
|
|
8
|
-
}
|
|
8
|
+
},
|
|
9
|
+
noscript: (props) => (<noscript {...props.attrs}>{props.children}</noscript>),
|
|
9
10
|
};
|
|
10
11
|
export function renderAsset(asset, nonce) {
|
|
11
12
|
let { tag, attrs: { key, ...attrs } = { key: undefined }, children } = asset;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { Component } from "solid-js";
|
|
2
2
|
import type { DocumentComponentProps } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* Read more: https://docs.solidjs.com/solid-start/reference/server/start-server
|
|
6
|
+
*/
|
|
3
7
|
export declare function StartServer(props: {
|
|
4
8
|
document: Component<DocumentComponentProps>;
|
|
5
9
|
}): import("solid-js").JSX.Element;
|
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
import { NoHydration, getRequestEvent, ssr } from "solid-js/web";
|
|
2
|
+
import { TopErrorBoundary } from "../../shared/ErrorBoundary";
|
|
2
3
|
import { renderAsset } from "../renderAsset";
|
|
3
4
|
const docType = ssr("<!DOCTYPE html>");
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* Read more: https://docs.solidjs.com/solid-start/reference/server/start-server
|
|
8
|
+
*/
|
|
4
9
|
export function StartServer(props) {
|
|
5
10
|
const context = getRequestEvent();
|
|
6
11
|
// @ts-ignore
|
|
7
12
|
const nonce = context.nonce;
|
|
8
13
|
return (<NoHydration>
|
|
9
14
|
{docType}
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
<TopErrorBoundary>
|
|
16
|
+
<props.document assets={<>{context.assets.map((m) => renderAsset(m))}</>} scripts={nonce ? (<>
|
|
17
|
+
<script nonce={nonce} innerHTML={`window.manifest = ${JSON.stringify(context.manifest)}`}/>
|
|
18
|
+
<script type="module" src={import.meta.env.MANIFEST["client"].inputs[import.meta.env.MANIFEST["client"].handler].output.path}/>
|
|
19
|
+
</>) : (<>
|
|
20
|
+
<script innerHTML={`window.manifest = ${JSON.stringify(context.manifest)}`}/>
|
|
21
|
+
<script type="module" src={import.meta.env.MANIFEST["client"].inputs[import.meta.env.MANIFEST["client"].handler].output.path}/>
|
|
22
|
+
</>)}/>
|
|
23
|
+
</TopErrorBoundary>
|
|
17
24
|
</NoHydration>);
|
|
18
25
|
}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import { FetchEvent, HandlerOptions, PageEvent } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* Read more: https://docs.solidjs.com/solid-start/reference/server/create-handler
|
|
5
|
+
*/
|
|
2
6
|
export declare function createHandler(fn: (context: PageEvent) => unknown, options?: HandlerOptions | ((context: PageEvent) => HandlerOptions)): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
|
|
3
7
|
export declare function createPageEvent(ctx: FetchEvent): Promise<PageEvent>;
|
|
@@ -1,16 +1,36 @@
|
|
|
1
1
|
// @refresh skip
|
|
2
|
-
import { ErrorBoundary as DefaultErrorBoundary } from "solid-js";
|
|
2
|
+
import { ErrorBoundary as DefaultErrorBoundary, catchError } from "solid-js";
|
|
3
3
|
import { isServer } from "solid-js/web";
|
|
4
4
|
import { HttpStatusCode } from "./HttpStatusCode";
|
|
5
5
|
import { DevOverlay } from "./dev-overlay";
|
|
6
6
|
export const ErrorBoundary = import.meta.env.DEV && import.meta.env.START_DEV_OVERLAY
|
|
7
7
|
? (props) => <DevOverlay>{props.children}</DevOverlay>
|
|
8
8
|
: (props) => {
|
|
9
|
-
const message = isServer
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
const message = isServer
|
|
10
|
+
? "500 | Internal Server Error"
|
|
11
|
+
: "Error | Uncaught Client Exception";
|
|
12
|
+
return (<DefaultErrorBoundary fallback={error => {
|
|
13
|
+
console.error(error);
|
|
14
|
+
return (<>
|
|
15
|
+
<span style="font-size:1.5em;text-align:center;position:fixed;left:0px;bottom:55%;width:100%;">
|
|
16
|
+
{message}
|
|
17
|
+
</span>
|
|
18
|
+
<HttpStatusCode code={500}/>
|
|
19
|
+
</>);
|
|
20
|
+
}}>
|
|
21
|
+
{props.children}
|
|
22
|
+
</DefaultErrorBoundary>);
|
|
16
23
|
};
|
|
24
|
+
export const TopErrorBoundary = (props) => {
|
|
25
|
+
let isError = false;
|
|
26
|
+
const res = catchError(() => props.children, err => {
|
|
27
|
+
console.error(err);
|
|
28
|
+
isError = !!err;
|
|
29
|
+
});
|
|
30
|
+
return isError ? (<>
|
|
31
|
+
<span style="font-size:1.5em;text-align:center;position:fixed;left:0px;bottom:55%;width:100%;">
|
|
32
|
+
500 | Internal Server Error
|
|
33
|
+
</span>
|
|
34
|
+
<HttpStatusCode code={500}/>
|
|
35
|
+
</>) : (res);
|
|
36
|
+
};
|
package/dist/shared/GET.d.ts
CHANGED
package/dist/shared/GET.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
// @refresh skip
|
|
2
2
|
import { onCleanup } from "solid-js";
|
|
3
3
|
import { getRequestEvent, isServer } from "solid-js/web";
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* Read more: https://docs.solidjs.com/solid-start/reference/server/http-header
|
|
7
|
+
*/
|
|
4
8
|
export const HttpHeader = isServer
|
|
5
9
|
? (props) => {
|
|
6
10
|
const event = getRequestEvent();
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
// @refresh skip
|
|
2
2
|
import { onCleanup } from "solid-js";
|
|
3
3
|
import { getRequestEvent, isServer } from "solid-js/web";
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* Read more: https://docs.solidjs.com/solid-start/reference/server/http-status-code
|
|
7
|
+
*/
|
|
4
8
|
export const HttpStatusCode = isServer
|
|
5
9
|
? (props) => {
|
|
6
10
|
const event = getRequestEvent();
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { Component, ComponentProps, JSX } from "solid-js";
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* Read more: https://docs.solidjs.com/solid-start/reference/client/client-only
|
|
5
|
+
*/
|
|
2
6
|
export default function clientOnly<T extends Component<any>>(fn: () => Promise<{
|
|
3
7
|
default: T;
|
|
4
8
|
}>): (props: ComponentProps<T> & {
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { createMemo, createSignal, onMount, sharedConfig, splitProps, untrack } from "solid-js";
|
|
2
2
|
import { isServer } from "solid-js/web";
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* Read more: https://docs.solidjs.com/solid-start/reference/client/client-only
|
|
6
|
+
*/
|
|
3
7
|
// not using Suspense
|
|
4
8
|
export default function clientOnly(fn) {
|
|
5
9
|
if (isServer)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidjs/start",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": "Ryan Carniato",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,7 +29,11 @@
|
|
|
29
29
|
"./server/spa": "./dist/server/spa/index.jsx",
|
|
30
30
|
"./client": "./dist/client/index.jsx",
|
|
31
31
|
"./client/islands": "./dist/client/islands.jsx",
|
|
32
|
-
"./client/spa": "./dist/client/spa/index.jsx"
|
|
32
|
+
"./client/spa": "./dist/client/spa/index.jsx",
|
|
33
|
+
"./env": {
|
|
34
|
+
"types": "./env.d.ts",
|
|
35
|
+
"import": null
|
|
36
|
+
}
|
|
33
37
|
},
|
|
34
38
|
"typesVersions": {
|
|
35
39
|
"*": {
|
|
@@ -52,7 +56,7 @@
|
|
|
52
56
|
},
|
|
53
57
|
"devDependencies": {
|
|
54
58
|
"solid-js": "^1.8.17",
|
|
55
|
-
"vinxi": "^0.3.
|
|
59
|
+
"vinxi": "^0.3.12",
|
|
56
60
|
"typescript": "^5.4.2"
|
|
57
61
|
},
|
|
58
62
|
"dependencies": {
|