@solidjs/start 0.4.5 → 0.4.7
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.js +3 -1
- package/config/server-fns-runtime.jsx +2 -1
- package/config/server-runtime.jsx +3 -2
- package/package.json +7 -3
- package/server/StartServer.tsx +23 -7
- package/server/index.tsx +0 -10
- package/server/spa/index.tsx +0 -1
- package/server/handler.tsx +0 -99
- package/server/spa/handler.tsx +0 -24
package/config/index.js
CHANGED
|
@@ -104,7 +104,8 @@ export function defineConfig(baseConfig = {}) {
|
|
|
104
104
|
"~": join(process.cwd(), start.appRoot),
|
|
105
105
|
...(!start.ssr
|
|
106
106
|
? {
|
|
107
|
-
"@solidjs/start/server": "@solidjs/start/server/spa"
|
|
107
|
+
"@solidjs/start/server": "@solidjs/start/server/spa",
|
|
108
|
+
"@solidjs/start/entry": "@solidjs/start/entry/spa"
|
|
108
109
|
}
|
|
109
110
|
: {}),
|
|
110
111
|
...userConfig.resolve?.alias
|
|
@@ -170,6 +171,7 @@ export function defineConfig(baseConfig = {}) {
|
|
|
170
171
|
"import.meta.env.START_ISLANDS": JSON.stringify(start.islands),
|
|
171
172
|
"import.meta.env.SSR": JSON.stringify(false),
|
|
172
173
|
"import.meta.env.START_SSR": JSON.stringify(start.ssr),
|
|
174
|
+
"import.meta.env.SERVER_BASE_URL": JSON.stringify(server?.baseURL ?? ""),
|
|
173
175
|
...userConfig.define
|
|
174
176
|
}
|
|
175
177
|
})
|
|
@@ -3,10 +3,11 @@ import { provideRequestEvent } from "solid-js/web/storage";
|
|
|
3
3
|
import { cloneEvent } from "../server/middleware";
|
|
4
4
|
|
|
5
5
|
export function createServerReference(fn, id, name) {
|
|
6
|
+
const baseURL = import.meta.env.SERVER_BASE_URL;
|
|
6
7
|
return new Proxy(fn, {
|
|
7
8
|
get(target, prop, receiver) {
|
|
8
9
|
if (prop === "url") {
|
|
9
|
-
return
|
|
10
|
+
return `${baseURL}/_server?id=${encodeURIComponent(id)}&name=${encodeURIComponent(name)}`;
|
|
10
11
|
}
|
|
11
12
|
},
|
|
12
13
|
apply(target, thisArg, args) {
|
|
@@ -120,14 +120,15 @@ async function fetchServerFunction(base, id, args) {
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
export function createServerReference(fn, id, name) {
|
|
123
|
+
const baseURL = import.meta.env.SERVER_BASE_URL;
|
|
123
124
|
return new Proxy(fn, {
|
|
124
125
|
get(target, prop, receiver) {
|
|
125
126
|
if (prop === "url") {
|
|
126
|
-
return
|
|
127
|
+
return `${baseURL}/_server?id=${encodeURIComponent(id)}&name=${encodeURIComponent(name)}`;
|
|
127
128
|
}
|
|
128
129
|
},
|
|
129
130
|
apply(target, thisArg, args) {
|
|
130
|
-
return fetchServerFunction(
|
|
131
|
+
return fetchServerFunction(`${baseURL}/_server`, `${id}#${name}`, args);
|
|
131
132
|
}
|
|
132
133
|
});
|
|
133
134
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidjs/start",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": "Ryan Carniato",
|
|
6
6
|
"publishConfig": {
|
|
@@ -17,11 +17,12 @@
|
|
|
17
17
|
"exports": {
|
|
18
18
|
".": "./shared/index.tsx",
|
|
19
19
|
"./config": "./config/index.js",
|
|
20
|
+
"./entry": "./entry/index.ts",
|
|
21
|
+
"./entry/spa": "./entry/spa/index.ts",
|
|
20
22
|
"./server": "./server/index.tsx",
|
|
21
23
|
"./server/spa": "./server/spa/index.tsx",
|
|
22
24
|
"./client": "./client/index.tsx",
|
|
23
25
|
"./client/islands": "./client/islands.tsx",
|
|
24
|
-
"./middleware": "./server/middleware.ts",
|
|
25
26
|
"./client/spa": "./client/spa/index.tsx"
|
|
26
27
|
},
|
|
27
28
|
"typesVersions": {
|
|
@@ -29,6 +30,9 @@
|
|
|
29
30
|
".": [
|
|
30
31
|
"./shared/index.tsx"
|
|
31
32
|
],
|
|
33
|
+
"./entry": [
|
|
34
|
+
"./entry/index.ts"
|
|
35
|
+
],
|
|
32
36
|
"./server": [
|
|
33
37
|
"./server/index.tsx"
|
|
34
38
|
],
|
|
@@ -38,7 +42,7 @@
|
|
|
38
42
|
}
|
|
39
43
|
},
|
|
40
44
|
"devDependencies": {
|
|
41
|
-
"solid-js": "^1.8.
|
|
45
|
+
"solid-js": "^1.8.10",
|
|
42
46
|
"vinxi": "0.1.1"
|
|
43
47
|
},
|
|
44
48
|
"dependencies": {
|
package/server/StartServer.tsx
CHANGED
|
@@ -15,24 +15,40 @@ import type { DocumentComponentProps } from "./types";
|
|
|
15
15
|
|
|
16
16
|
const docType = ssr("<!DOCTYPE html>");
|
|
17
17
|
|
|
18
|
+
function matchRoute(matches, routes, matched = []) {
|
|
19
|
+
for (let i = 0; i < routes.length; i++) {
|
|
20
|
+
const segment = routes[i];
|
|
21
|
+
if (segment.path !== matches[0].path) continue;
|
|
22
|
+
let next = [...matched, segment];
|
|
23
|
+
if (segment.children) {
|
|
24
|
+
const nextMatches = matches.slice(1);
|
|
25
|
+
if (nextMatches.length === 0) continue;
|
|
26
|
+
next = matchRoute(nextMatches, segment.children, next);
|
|
27
|
+
if (!next) continue;
|
|
28
|
+
}
|
|
29
|
+
return next;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
18
33
|
export function StartServer(props: { document: Component<DocumentComponentProps> }) {
|
|
19
34
|
const context = getRequestEvent() as any;
|
|
20
35
|
|
|
21
36
|
let assets = [];
|
|
22
37
|
Promise.resolve().then(async () => {
|
|
23
|
-
let current = context.routes;
|
|
24
38
|
if (context.routerMatches && context.routerMatches[0]) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
39
|
+
const matches = [...context.routerMatches[0]];
|
|
40
|
+
while (matches.length && (!matches[0].metadata || !matches[0].metadata.filesystem))
|
|
41
|
+
matches.shift();
|
|
42
|
+
const matched = matches.length && matchRoute(matches, context.routes);
|
|
43
|
+
if (matched) {
|
|
44
|
+
for (let i = 0; i < matched.length; i++) {
|
|
45
|
+
const segment = matched[i];
|
|
29
46
|
const part = import.meta.env.MANIFEST[import.meta.env.START_ISLANDS ? "ssr" : "client"]
|
|
30
47
|
.inputs[segment["$component"].src];
|
|
31
48
|
const asset = await part.assets();
|
|
32
49
|
assets.push.apply(assets, asset);
|
|
33
|
-
current = segment.children;
|
|
34
50
|
}
|
|
35
|
-
}
|
|
51
|
+
} else console.warn("No route matched for preloading js assets");
|
|
36
52
|
}
|
|
37
53
|
// dedupe assets
|
|
38
54
|
assets = [...new Map(assets.map(item => [item.attrs.key, item])).values()].filter(asset =>
|
package/server/index.tsx
CHANGED
|
@@ -2,13 +2,3 @@ export * from "vinxi/server";
|
|
|
2
2
|
export { StartServer } from "./StartServer";
|
|
3
3
|
export * from "./middleware";
|
|
4
4
|
export * from "./types";
|
|
5
|
-
import { createHandler as createBaseHandler } from "./handler";
|
|
6
|
-
import { createPageEvent } from "./page-event";
|
|
7
|
-
import type { PageEvent } from "./types";
|
|
8
|
-
|
|
9
|
-
export function createHandler(
|
|
10
|
-
fn: (context: PageEvent) => unknown,
|
|
11
|
-
options: Parameters<typeof createBaseHandler>[1] = {}
|
|
12
|
-
) {
|
|
13
|
-
return createBaseHandler(fn, { ...options, createPageEvent });
|
|
14
|
-
}
|
package/server/spa/index.tsx
CHANGED
package/server/handler.tsx
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { sharedConfig } from "solid-js";
|
|
2
|
-
import { renderToStream } from "solid-js/web";
|
|
3
|
-
/* @ts-ignore */
|
|
4
|
-
import { provideRequestEvent } from "solid-js/web/storage";
|
|
5
|
-
import {
|
|
6
|
-
EventHandlerObject,
|
|
7
|
-
EventHandlerRequest,
|
|
8
|
-
H3Event,
|
|
9
|
-
HTTPMethod,
|
|
10
|
-
eventHandler,
|
|
11
|
-
sendRedirect,
|
|
12
|
-
setHeader,
|
|
13
|
-
setResponseStatus
|
|
14
|
-
} from "vinxi/server";
|
|
15
|
-
import { matchAPIRoute } from "../shared/routes";
|
|
16
|
-
import { getFetchEvent } from "./middleware";
|
|
17
|
-
import { createPageEvent } from "./page-event";
|
|
18
|
-
import { APIEvent, FetchEvent, PageEvent } from "./types";
|
|
19
|
-
|
|
20
|
-
export function createHandler(
|
|
21
|
-
fn: (context: PageEvent) => unknown,
|
|
22
|
-
options: {
|
|
23
|
-
nonce?: string;
|
|
24
|
-
renderId?: string;
|
|
25
|
-
timeoutMs?: number;
|
|
26
|
-
onCompleteAll?: (options: { write: (v: any) => void }) => void;
|
|
27
|
-
onCompleteShell?: (options: { write: (v: any) => void }) => void;
|
|
28
|
-
createPageEvent?: (event: FetchEvent) => Promise<PageEvent>;
|
|
29
|
-
onRequest?: EventHandlerObject["onRequest"];
|
|
30
|
-
onBeforeResponse?: EventHandlerObject["onBeforeResponse"];
|
|
31
|
-
} = {}
|
|
32
|
-
) {
|
|
33
|
-
return eventHandler({
|
|
34
|
-
onRequest: options.onRequest,
|
|
35
|
-
onBeforeResponse: options.onBeforeResponse,
|
|
36
|
-
handler: (e: H3Event<EventHandlerRequest> & { startEvent: FetchEvent }) => {
|
|
37
|
-
const event = getFetchEvent(e);
|
|
38
|
-
|
|
39
|
-
return provideRequestEvent(event, async () => {
|
|
40
|
-
// api
|
|
41
|
-
const match = matchAPIRoute(new URL(event.request.url).pathname, event.request.method as HTTPMethod)
|
|
42
|
-
if (match) {
|
|
43
|
-
const mod = await match.handler.import();
|
|
44
|
-
const fn = mod[event.request.method];
|
|
45
|
-
(event as APIEvent).params = match.params;
|
|
46
|
-
sharedConfig.context = { event } as any;
|
|
47
|
-
return await fn(event);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// render stream
|
|
51
|
-
const doAsync = import.meta.env.START_SSR === "async";
|
|
52
|
-
const context = await createPageEvent(event);
|
|
53
|
-
let cloned = { ...options };
|
|
54
|
-
if (cloned.onCompleteAll) {
|
|
55
|
-
const og = cloned.onCompleteAll;
|
|
56
|
-
cloned.onCompleteAll = options => {
|
|
57
|
-
handleStreamCompleteRedirect(context)(options);
|
|
58
|
-
og(options);
|
|
59
|
-
};
|
|
60
|
-
} else cloned.onCompleteAll = handleStreamCompleteRedirect(context);
|
|
61
|
-
if (cloned.onCompleteShell) {
|
|
62
|
-
const og = cloned.onCompleteShell;
|
|
63
|
-
cloned.onCompleteShell = options => {
|
|
64
|
-
handleShellCompleteRedirect(context, e)();
|
|
65
|
-
og(options);
|
|
66
|
-
};
|
|
67
|
-
} else cloned.onCompleteShell = handleShellCompleteRedirect(context, e);
|
|
68
|
-
const stream = renderToStream(() => {
|
|
69
|
-
(sharedConfig.context as any).event = context;
|
|
70
|
-
return fn(context)
|
|
71
|
-
}, cloned);
|
|
72
|
-
if (context.response && context.response.headers.get("Location")) {
|
|
73
|
-
return sendRedirect(event, context.response.headers.get("Location"));
|
|
74
|
-
}
|
|
75
|
-
if (doAsync) return stream;
|
|
76
|
-
// fix cloudflare streaming
|
|
77
|
-
const { writable, readable } = new TransformStream();
|
|
78
|
-
stream.pipeTo(writable);
|
|
79
|
-
return readable;
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function handleShellCompleteRedirect(context: PageEvent, e: H3Event<EventHandlerRequest>) {
|
|
86
|
-
return () => {
|
|
87
|
-
if (context.response && context.response.headers.get("Location")) {
|
|
88
|
-
setResponseStatus(e, 302);
|
|
89
|
-
setHeader(e, "Location", context.response.headers.get("Location"));
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function handleStreamCompleteRedirect(context: PageEvent) {
|
|
95
|
-
return ({ write }: { write: (html: string) => void }) => {
|
|
96
|
-
const to = context.response && context.response.headers.get("Location");
|
|
97
|
-
to && write(`<script>window.location="${to}"</script>`);
|
|
98
|
-
};
|
|
99
|
-
}
|
package/server/spa/handler.tsx
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { createHandler as createBaseHandler } from "../handler";
|
|
2
|
-
import { FetchEvent, PageEvent } from "../types";
|
|
3
|
-
|
|
4
|
-
export function createHandler(
|
|
5
|
-
fn: (context: PageEvent) => unknown,
|
|
6
|
-
options?: { nonce?: string; renderId?: string; timeoutMs?: number }
|
|
7
|
-
) {
|
|
8
|
-
return createBaseHandler(fn, { ...options, createPageEvent });
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export async function createPageEvent(ctx: FetchEvent) {
|
|
12
|
-
const clientManifest = import.meta.env.MANIFEST["client"];
|
|
13
|
-
const pageEvent: PageEvent = Object.assign(ctx, {
|
|
14
|
-
manifest: await clientManifest.json(),
|
|
15
|
-
assets: [...(await clientManifest.inputs[clientManifest.handler].assets())],
|
|
16
|
-
routes: [],
|
|
17
|
-
// prevUrl: "",
|
|
18
|
-
// mutation: false,
|
|
19
|
-
// $type: FETCH_EVENT,
|
|
20
|
-
$islands: new Set<string>()
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
return pageEvent;
|
|
24
|
-
}
|