@solidjs/start 0.7.1 → 0.7.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.js +4 -4
- package/config/server-components.js +1 -1
- package/dist/client/StartClient.d.ts +3 -0
- package/{client/StartClient.tsx → dist/client/StartClient.jsx} +4 -9
- package/{client/index.tsx → dist/client/index.d.ts} +0 -1
- package/dist/client/index.jsx +4 -0
- package/dist/client/islands.d.ts +3 -0
- package/{client/islands.ts → dist/client/islands.jsx} +1 -1
- package/dist/client/mount.d.ts +3 -0
- package/dist/client/mount.js +85 -0
- package/dist/client/spa/index.d.ts +5 -0
- package/dist/client/spa/index.jsx +6 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.jsx +5 -0
- package/dist/middleware/index.d.ts +18 -0
- package/dist/middleware/index.js +40 -0
- package/dist/router/FileRoutes.d.ts +2 -0
- package/dist/router/FileRoutes.js +25 -0
- package/dist/router/index.jsx +2 -0
- package/dist/router/lazyRoute.d.ts +6 -0
- package/dist/router/lazyRoute.js +48 -0
- package/dist/router/routes.d.ts +25 -0
- package/dist/router/routes.js +51 -0
- package/dist/runtime/server-fns-runtime.d.ts +1 -0
- package/dist/runtime/server-fns-runtime.js +30 -0
- package/dist/runtime/server-handler.d.ts +2 -0
- package/dist/runtime/server-handler.js +242 -0
- package/dist/runtime/server-runtime.d.ts +3 -0
- package/dist/runtime/server-runtime.js +185 -0
- package/dist/server/StartServer.d.ts +5 -0
- package/dist/server/StartServer.jsx +78 -0
- package/dist/server/fetchEvent.d.ts +6 -0
- package/dist/server/fetchEvent.js +88 -0
- package/dist/server/handler.d.ts +3 -0
- package/dist/server/handler.js +98 -0
- package/dist/server/index.jsx +5 -0
- package/dist/server/islands/index.d.ts +19 -0
- package/dist/server/islands/index.jsx +62 -0
- package/dist/server/islands/utils.d.ts +1 -0
- package/dist/server/islands/utils.jsx +85 -0
- package/dist/server/pageEvent.d.ts +2 -0
- package/dist/server/pageEvent.js +43 -0
- package/dist/server/renderAsset.d.ts +2 -0
- package/dist/server/renderAsset.jsx +13 -0
- package/dist/server/serverFunction.d.ts +2 -0
- package/dist/server/serverFunction.jsx +4 -0
- package/dist/server/spa/StartServer.d.ts +5 -0
- package/dist/server/spa/StartServer.jsx +18 -0
- package/dist/server/spa/handler.d.ts +3 -0
- package/dist/server/spa/handler.js +17 -0
- package/{server/spa/index.tsx → dist/server/spa/index.d.ts} +0 -1
- package/dist/server/spa/index.jsx +4 -0
- package/dist/server/types.d.ts +79 -0
- package/dist/server/types.js +1 -0
- package/dist/shared/ErrorBoundary.d.ts +2 -0
- package/dist/shared/ErrorBoundary.jsx +16 -0
- package/dist/shared/GET.d.ts +1 -0
- package/dist/shared/GET.js +5 -0
- package/dist/shared/HttpHeader.d.ts +6 -0
- package/dist/shared/HttpHeader.jsx +32 -0
- package/dist/shared/HttpStatusCode.d.ts +5 -0
- package/dist/shared/HttpStatusCode.jsx +12 -0
- package/dist/shared/clientOnly.d.ts +6 -0
- package/dist/shared/clientOnly.jsx +19 -0
- package/dist/shared/dev-overlay/CodeView.d.ts +7 -0
- package/dist/shared/dev-overlay/CodeView.jsx +71 -0
- package/dist/shared/dev-overlay/DevOverlayDialog.d.ts +9 -0
- package/dist/shared/dev-overlay/DevOverlayDialog.jsx +209 -0
- package/dist/shared/dev-overlay/createStackFrame.d.ts +9 -0
- package/dist/shared/dev-overlay/createStackFrame.js +56 -0
- package/dist/shared/dev-overlay/download.d.ts +1 -0
- package/dist/shared/dev-overlay/download.js +6 -0
- package/dist/shared/dev-overlay/get-source-map.d.ts +2 -0
- package/dist/shared/dev-overlay/get-source-map.js +25 -0
- package/dist/shared/dev-overlay/icons.d.ts +28 -0
- package/{shared/dev-overlay/icons.tsx → dist/shared/dev-overlay/icons.jsx} +35 -173
- package/dist/shared/dev-overlay/index.d.ts +5 -0
- package/dist/shared/dev-overlay/index.jsx +37 -0
- package/package.json +20 -22
- package/client/mount.ts +0 -99
- package/client/spa/index.tsx +0 -10
- package/config/server-fns-runtime.ts +0 -28
- package/config/server-handler.ts +0 -261
- package/config/server-runtime.ts +0 -229
- package/middleware/index.ts +0 -70
- package/router/FileRoutes.ts +0 -35
- package/router/lazyRoute.ts +0 -55
- package/router/routes.ts +0 -87
- package/server/StartServer.tsx +0 -126
- package/server/fetchEvent.ts +0 -113
- package/server/handler.ts +0 -112
- package/server/islands/index.tsx +0 -103
- package/server/islands/utils.tsx +0 -89
- package/server/pageEvent.ts +0 -50
- package/server/renderAsset.tsx +0 -23
- package/server/serverFunction.tsx +0 -6
- package/server/spa/StartServer.tsx +0 -52
- package/server/spa/handler.ts +0 -24
- package/server/types.ts +0 -81
- package/shared/ErrorBoundary.tsx +0 -23
- package/shared/GET.ts +0 -5
- package/shared/HttpHeader.tsx +0 -35
- package/shared/HttpStatusCode.tsx +0 -19
- package/shared/clientOnly.tsx +0 -29
- package/shared/dev-overlay/CodeView.tsx +0 -95
- package/shared/dev-overlay/DevOverlayDialog.tsx +0 -280
- package/shared/dev-overlay/createStackFrame.ts +0 -77
- package/shared/dev-overlay/download.ts +0 -6
- package/shared/dev-overlay/env.d.ts +0 -4
- package/shared/dev-overlay/get-source-map.ts +0 -35
- package/shared/dev-overlay/index.tsx +0 -61
- package/shared/index.ts +0 -5
- /package/{router/index.ts → dist/router/index.d.ts} +0 -0
- /package/{server/index.tsx → dist/server/index.d.ts} +0 -0
- /package/{shared → dist/shared}/dev-overlay/styles.css +0 -0
package/server/fetchEvent.ts
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
H3Event,
|
|
3
|
-
appendResponseHeader,
|
|
4
|
-
getRequestIP,
|
|
5
|
-
getResponseHeader,
|
|
6
|
-
getResponseHeaders,
|
|
7
|
-
getResponseStatus,
|
|
8
|
-
getResponseStatusText,
|
|
9
|
-
getWebRequest,
|
|
10
|
-
removeResponseHeader,
|
|
11
|
-
setHeader,
|
|
12
|
-
setResponseHeader,
|
|
13
|
-
setResponseStatus
|
|
14
|
-
} from "vinxi/http";
|
|
15
|
-
import type { FetchEvent, ResponseStub } from "./types";
|
|
16
|
-
|
|
17
|
-
const fetchEventSymbol = Symbol("fetchEvent");
|
|
18
|
-
|
|
19
|
-
export function createFetchEvent(event: H3Event): FetchEvent {
|
|
20
|
-
return {
|
|
21
|
-
request: getWebRequest(event),
|
|
22
|
-
response: createResponseStub(event),
|
|
23
|
-
clientAddress: getRequestIP(event),
|
|
24
|
-
locals: {},
|
|
25
|
-
nativeEvent: event
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function cloneEvent<T extends FetchEvent>(fetchEvent: T): T {
|
|
30
|
-
return {
|
|
31
|
-
...fetchEvent
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function getFetchEvent(h3Event: H3Event): FetchEvent {
|
|
36
|
-
if (!(h3Event as any)[fetchEventSymbol]) {
|
|
37
|
-
const fetchEvent = createFetchEvent(h3Event);
|
|
38
|
-
(h3Event as any)[fetchEventSymbol] = fetchEvent;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return (h3Event as any)[fetchEventSymbol];
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function mergeResponseHeaders(h3Event: H3Event, headers: Headers) {
|
|
45
|
-
for (const [key, value] of headers.entries()) {
|
|
46
|
-
setHeader(h3Event, key, value);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
class HeaderProxy {
|
|
51
|
-
constructor(private event: H3Event) {}
|
|
52
|
-
get(key: string) {
|
|
53
|
-
const h = getResponseHeader(this.event, key);
|
|
54
|
-
return Array.isArray(h) ? h.join(", ") : (h as string) || null;
|
|
55
|
-
}
|
|
56
|
-
has(key: string) {
|
|
57
|
-
return this.get(key) !== undefined;
|
|
58
|
-
}
|
|
59
|
-
set(key: string, value: string) {
|
|
60
|
-
return setResponseHeader(this.event, key, value);
|
|
61
|
-
}
|
|
62
|
-
delete(key: string) {
|
|
63
|
-
return removeResponseHeader(this.event, key);
|
|
64
|
-
}
|
|
65
|
-
append(key: string, value: string) {
|
|
66
|
-
appendResponseHeader(this.event, key, value);
|
|
67
|
-
}
|
|
68
|
-
getSetCookie() {
|
|
69
|
-
const cookies = getResponseHeader(this.event, "Set-Cookie");
|
|
70
|
-
return Array.isArray(cookies) ? cookies : [cookies as string];
|
|
71
|
-
}
|
|
72
|
-
forEach(fn: (value: string, key: string, object: Headers) => void) {
|
|
73
|
-
return Object.entries(getResponseHeaders(this.event)).forEach(([key, value]) =>
|
|
74
|
-
fn(Array.isArray(value) ? value.join(", ") : (value as string), key, this)
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
entries() {
|
|
78
|
-
return Object.entries(getResponseHeaders(this.event))
|
|
79
|
-
.map(
|
|
80
|
-
([key, value]) => [key, Array.isArray(value) ? value.join(", ") : value] as [string, string]
|
|
81
|
-
)
|
|
82
|
-
[Symbol.iterator]();
|
|
83
|
-
}
|
|
84
|
-
keys() {
|
|
85
|
-
return Object.keys(getResponseHeaders(this.event))[Symbol.iterator]();
|
|
86
|
-
}
|
|
87
|
-
values() {
|
|
88
|
-
return Object.values(getResponseHeaders(this.event))
|
|
89
|
-
.map(value => (Array.isArray(value) ? value.join(", ") : (value as string)))
|
|
90
|
-
[Symbol.iterator]();
|
|
91
|
-
}
|
|
92
|
-
[Symbol.iterator]() {
|
|
93
|
-
return this.entries()[Symbol.iterator]();
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function createResponseStub(event: H3Event): ResponseStub {
|
|
98
|
-
return {
|
|
99
|
-
get status() {
|
|
100
|
-
return getResponseStatus(event);
|
|
101
|
-
},
|
|
102
|
-
set status(v) {
|
|
103
|
-
setResponseStatus(event, v);
|
|
104
|
-
},
|
|
105
|
-
get statusText() {
|
|
106
|
-
return getResponseStatusText(event);
|
|
107
|
-
},
|
|
108
|
-
set statusText(v) {
|
|
109
|
-
setResponseStatus(event, getResponseStatus(), v);
|
|
110
|
-
},
|
|
111
|
-
headers: new HeaderProxy(event)
|
|
112
|
-
};
|
|
113
|
-
}
|
package/server/handler.ts
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { sharedConfig } from "solid-js";
|
|
2
|
-
import { renderToStream, renderToString } from "solid-js/web";
|
|
3
|
-
import { provideRequestEvent } from "solid-js/web/storage";
|
|
4
|
-
import {
|
|
5
|
-
eventHandler,
|
|
6
|
-
sendRedirect,
|
|
7
|
-
setHeader,
|
|
8
|
-
setResponseStatus,
|
|
9
|
-
type HTTPEvent
|
|
10
|
-
} from "vinxi/http";
|
|
11
|
-
import { matchAPIRoute } from "../router/routes";
|
|
12
|
-
import { getFetchEvent } from "./fetchEvent";
|
|
13
|
-
import { createPageEvent } from "./pageEvent";
|
|
14
|
-
import type { APIEvent, FetchEvent, HandlerOptions, PageEvent } from "./types";
|
|
15
|
-
|
|
16
|
-
export function createBaseHandler(
|
|
17
|
-
fn: (context: PageEvent) => unknown,
|
|
18
|
-
createPageEvent: (event: FetchEvent) => Promise<PageEvent>,
|
|
19
|
-
options: HandlerOptions | ((context: PageEvent) => HandlerOptions | Promise<HandlerOptions>) = {}
|
|
20
|
-
) {
|
|
21
|
-
return eventHandler({
|
|
22
|
-
handler: (e: HTTPEvent) => {
|
|
23
|
-
const event = getFetchEvent(e);
|
|
24
|
-
|
|
25
|
-
return provideRequestEvent(event, async () => {
|
|
26
|
-
// api
|
|
27
|
-
const match = matchAPIRoute(new URL(event.request.url).pathname, event.request.method);
|
|
28
|
-
if (match) {
|
|
29
|
-
const mod = await match.handler.import();
|
|
30
|
-
const fn = mod[event.request.method];
|
|
31
|
-
(event as APIEvent).params = match.params || {};
|
|
32
|
-
// @ts-ignore
|
|
33
|
-
sharedConfig.context = { event };
|
|
34
|
-
const res = await fn(event);
|
|
35
|
-
if (res !== undefined) return res;
|
|
36
|
-
if (event.request.method !== "GET") {
|
|
37
|
-
throw new Error(
|
|
38
|
-
`API handler for ${event.request.method} "${event.request.url}" did not return a response.`
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// render
|
|
44
|
-
const context = await createPageEvent(event);
|
|
45
|
-
if (typeof options === "function") options = await options(context);
|
|
46
|
-
const mode = options.mode || "stream";
|
|
47
|
-
// @ts-ignore
|
|
48
|
-
if (options.nonce) context.nonce = options.nonce;
|
|
49
|
-
if (mode === "sync" || !import.meta.env.START_SSR) {
|
|
50
|
-
const html = renderToString(() => {
|
|
51
|
-
(sharedConfig.context as any).event = context;
|
|
52
|
-
return fn(context);
|
|
53
|
-
}, options);
|
|
54
|
-
if (context.response && context.response.headers.get("Location")) {
|
|
55
|
-
return sendRedirect(e, context.response.headers.get("Location")!);
|
|
56
|
-
}
|
|
57
|
-
return html;
|
|
58
|
-
}
|
|
59
|
-
let cloned = { ...options };
|
|
60
|
-
if (cloned.onCompleteAll) {
|
|
61
|
-
const og = cloned.onCompleteAll;
|
|
62
|
-
cloned.onCompleteAll = options => {
|
|
63
|
-
handleStreamCompleteRedirect(context)(options);
|
|
64
|
-
og(options);
|
|
65
|
-
};
|
|
66
|
-
} else cloned.onCompleteAll = handleStreamCompleteRedirect(context);
|
|
67
|
-
if (cloned.onCompleteShell) {
|
|
68
|
-
const og = cloned.onCompleteShell;
|
|
69
|
-
cloned.onCompleteShell = options => {
|
|
70
|
-
handleShellCompleteRedirect(context, e)();
|
|
71
|
-
og(options);
|
|
72
|
-
};
|
|
73
|
-
} else cloned.onCompleteShell = handleShellCompleteRedirect(context, e);
|
|
74
|
-
const stream = renderToStream(() => {
|
|
75
|
-
(sharedConfig.context as any).event = context;
|
|
76
|
-
return fn(context);
|
|
77
|
-
}, cloned);
|
|
78
|
-
if (context.response && context.response.headers.get("Location")) {
|
|
79
|
-
return sendRedirect(e, context.response.headers.get("Location")!);
|
|
80
|
-
}
|
|
81
|
-
if (mode === "async") return stream;
|
|
82
|
-
// fix cloudflare streaming
|
|
83
|
-
const { writable, readable } = new TransformStream();
|
|
84
|
-
stream.pipeTo(writable);
|
|
85
|
-
return readable;
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function handleShellCompleteRedirect(context: PageEvent, e: HTTPEvent) {
|
|
92
|
-
return () => {
|
|
93
|
-
if (context.response && context.response.headers.get("Location")) {
|
|
94
|
-
setResponseStatus(e, 302);
|
|
95
|
-
setHeader(e, "Location", context.response.headers.get("Location")!);
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function handleStreamCompleteRedirect(context: PageEvent) {
|
|
101
|
-
return ({ write }: { write: (html: string) => void }) => {
|
|
102
|
-
const to = context.response && context.response.headers.get("Location");
|
|
103
|
-
to && write(`<script>window.location="${to}"</script>`);
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export function createHandler(
|
|
108
|
-
fn: (context: PageEvent) => unknown,
|
|
109
|
-
options?: HandlerOptions | ((context: PageEvent) => HandlerOptions | Promise<HandlerOptions>)
|
|
110
|
-
) {
|
|
111
|
-
return createBaseHandler(fn, createPageEvent, options);
|
|
112
|
-
}
|
package/server/islands/index.tsx
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
// @refresh skip
|
|
2
|
-
import { lazy, sharedConfig, type Component, type ComponentProps } from "solid-js";
|
|
3
|
-
import { Hydration, NoHydration, getRequestEvent } from "solid-js/web";
|
|
4
|
-
// import { IslandManifest } from "./types";
|
|
5
|
-
import { splitProps } from "./utils";
|
|
6
|
-
|
|
7
|
-
declare module "solid-js" {
|
|
8
|
-
namespace JSX {
|
|
9
|
-
interface IntrinsicElements {
|
|
10
|
-
"solid-island": {
|
|
11
|
-
"data-props": string;
|
|
12
|
-
"data-id": string;
|
|
13
|
-
"data-when": "idle" | "load";
|
|
14
|
-
children: JSX.Element;
|
|
15
|
-
};
|
|
16
|
-
"solid-children": {
|
|
17
|
-
children: JSX.Element;
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function createIslandReference<T extends Component<any>>(
|
|
24
|
-
Comp:
|
|
25
|
-
| T
|
|
26
|
-
| (() => Promise<{
|
|
27
|
-
default: T;
|
|
28
|
-
}>),
|
|
29
|
-
id: string,
|
|
30
|
-
name: string
|
|
31
|
-
): T {
|
|
32
|
-
let Component = Comp as T;
|
|
33
|
-
|
|
34
|
-
if (!import.meta.env.START_ISLANDS) {
|
|
35
|
-
// TODO: have some sane semantics for islands used in non-island mode
|
|
36
|
-
return lazy(Comp as () => Promise<{ default: T }>);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function IslandComponent(props: ComponentProps<T>) {
|
|
40
|
-
return (
|
|
41
|
-
<Component {...props}>
|
|
42
|
-
<NoHydration>{props.children}</NoHydration>
|
|
43
|
-
</Component>
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return ((compProps: ComponentProps<T>) => {
|
|
48
|
-
if (import.meta.env.SSR) {
|
|
49
|
-
const context = getRequestEvent();
|
|
50
|
-
const [, props] = splitProps(compProps, ["children"] as any);
|
|
51
|
-
const [, spreadProps] = splitProps(compProps, [] as any);
|
|
52
|
-
|
|
53
|
-
let fpath: string;
|
|
54
|
-
let styles: string[] = [];
|
|
55
|
-
// if (import.meta.env.PROD) {
|
|
56
|
-
// let x = context.env.manifest?.[path] as IslandManifest;
|
|
57
|
-
// context.$islands.add(path);
|
|
58
|
-
// if (x) {
|
|
59
|
-
// fpath = x.script.href;
|
|
60
|
-
// styles = x.assets.filter(v => v.type == "style").map(v => v.href);
|
|
61
|
-
// }
|
|
62
|
-
// } else {
|
|
63
|
-
fpath = id + "#" + name;
|
|
64
|
-
// }
|
|
65
|
-
|
|
66
|
-
const serialize = (props: ComponentProps<T>) => {
|
|
67
|
-
let offset = 0;
|
|
68
|
-
let el = JSON.stringify(props, (key, value) => {
|
|
69
|
-
if (value && value.t) {
|
|
70
|
-
offset++;
|
|
71
|
-
return undefined;
|
|
72
|
-
}
|
|
73
|
-
return value;
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
return {
|
|
77
|
-
"data-props": el,
|
|
78
|
-
"data-offset": offset
|
|
79
|
-
};
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
// @ts-expect-error
|
|
83
|
-
if (!sharedConfig.context?.noHydrate) {
|
|
84
|
-
return <Component {...compProps} />;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return (
|
|
88
|
-
<Hydration>
|
|
89
|
-
<solid-island
|
|
90
|
-
data-id={fpath!}
|
|
91
|
-
data-when={(props as any)["client:idle"] ? "idle" : "load"}
|
|
92
|
-
data-css={JSON.stringify(styles)}
|
|
93
|
-
{...serialize(props)}
|
|
94
|
-
>
|
|
95
|
-
<IslandComponent {...spreadProps} />
|
|
96
|
-
</solid-island>
|
|
97
|
-
</Hydration>
|
|
98
|
-
);
|
|
99
|
-
} else {
|
|
100
|
-
return <Component {...compProps} />;
|
|
101
|
-
}
|
|
102
|
-
}) as T;
|
|
103
|
-
}
|
package/server/islands/utils.tsx
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
// @refresh skip
|
|
2
|
-
// TODO rename to utils.ts?
|
|
3
|
-
// @ts-nocheck
|
|
4
|
-
import { $PROXY } from "solid-js";
|
|
5
|
-
|
|
6
|
-
function trueFn() {
|
|
7
|
-
return true;
|
|
8
|
-
}
|
|
9
|
-
const propTraps = {
|
|
10
|
-
get(_, property, receiver) {
|
|
11
|
-
if (property === $PROXY) return receiver;
|
|
12
|
-
return _.get(property);
|
|
13
|
-
},
|
|
14
|
-
has(_, property) {
|
|
15
|
-
return _.has(property);
|
|
16
|
-
},
|
|
17
|
-
set: trueFn,
|
|
18
|
-
deleteProperty: trueFn,
|
|
19
|
-
getOwnPropertyDescriptor(_, property) {
|
|
20
|
-
return {
|
|
21
|
-
configurable: true,
|
|
22
|
-
enumerable: true,
|
|
23
|
-
get() {
|
|
24
|
-
return _.get(property);
|
|
25
|
-
},
|
|
26
|
-
set: trueFn,
|
|
27
|
-
deleteProperty: trueFn
|
|
28
|
-
};
|
|
29
|
-
},
|
|
30
|
-
ownKeys(_) {
|
|
31
|
-
return _.keys();
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
export function splitProps<T>(props: T, ...keys: (keyof T)[]): [T, T] {
|
|
35
|
-
const blocked = new Set(keys.flat());
|
|
36
|
-
const descriptors = Object.getOwnPropertyDescriptors(props);
|
|
37
|
-
const isProxy = $PROXY in props;
|
|
38
|
-
if (!isProxy) keys.push(Object.keys(descriptors).filter(k => !blocked.has(k)));
|
|
39
|
-
|
|
40
|
-
const res = keys.map(k => {
|
|
41
|
-
const clone = {};
|
|
42
|
-
for (let i = 0; i < k.length; i++) {
|
|
43
|
-
const key = k[i];
|
|
44
|
-
let cache;
|
|
45
|
-
Object.defineProperty(clone, key, {
|
|
46
|
-
enumerable: descriptors[key]?.enumerable ?? false,
|
|
47
|
-
configurable: true,
|
|
48
|
-
get() {
|
|
49
|
-
if (cache) {
|
|
50
|
-
return cache;
|
|
51
|
-
}
|
|
52
|
-
let val = props[key];
|
|
53
|
-
if (val?.t) {
|
|
54
|
-
val.t = `<solid-children>${val.t}</solid-children>`;
|
|
55
|
-
} else if (Array.isArray(val) && val.every(v => v?.t)) {
|
|
56
|
-
val = {
|
|
57
|
-
t: `<solid-children>${val.map(v => `${v.t}`).join("\n")}</solid-children>`
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
cache = val;
|
|
61
|
-
return val;
|
|
62
|
-
},
|
|
63
|
-
set() {
|
|
64
|
-
return true;
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
return clone;
|
|
69
|
-
});
|
|
70
|
-
if (isProxy) {
|
|
71
|
-
res.push(
|
|
72
|
-
new Proxy(
|
|
73
|
-
{
|
|
74
|
-
get(property) {
|
|
75
|
-
return blocked.has(property) ? undefined : props[property];
|
|
76
|
-
},
|
|
77
|
-
has(property) {
|
|
78
|
-
return blocked.has(property) ? false : property in props;
|
|
79
|
-
},
|
|
80
|
-
keys() {
|
|
81
|
-
return Object.keys(props).filter(k => !blocked.has(k));
|
|
82
|
-
}
|
|
83
|
-
},
|
|
84
|
-
propTraps
|
|
85
|
-
)
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
return res;
|
|
89
|
-
}
|
package/server/pageEvent.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getCookie,
|
|
3
|
-
setCookie
|
|
4
|
-
} from "vinxi/http";
|
|
5
|
-
import { createRoutes } from "../router/FileRoutes";
|
|
6
|
-
import { FetchEvent, PageEvent } from "./types";
|
|
7
|
-
|
|
8
|
-
function initFromFlash(ctx: FetchEvent) {
|
|
9
|
-
const flash = getCookie(ctx.nativeEvent, "flash");
|
|
10
|
-
if (!flash) return;
|
|
11
|
-
let param = JSON.parse(flash);
|
|
12
|
-
if (!param || !param.result) return;
|
|
13
|
-
const input = [...param.input.slice(0, -1), new Map(param.input[param.input.length - 1])];
|
|
14
|
-
setCookie(ctx.nativeEvent, "flash", "", { maxAge: 0 });
|
|
15
|
-
return {
|
|
16
|
-
input,
|
|
17
|
-
url: param.url,
|
|
18
|
-
pending: false,
|
|
19
|
-
result: param.error ? new Error(param.result) : param.result,
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export async function createPageEvent(ctx: FetchEvent) {
|
|
24
|
-
const clientManifest = import.meta.env.MANIFEST["client"]!;
|
|
25
|
-
const serverManifest = import.meta.env.MANIFEST["ssr"]!;
|
|
26
|
-
ctx.response.headers.set("Content-Type", "text/html");
|
|
27
|
-
// const prevPath = ctx.request.headers.get("x-solid-referrer");
|
|
28
|
-
// const mutation = ctx.request.headers.get("x-solid-mutation") === "true";
|
|
29
|
-
const pageEvent: PageEvent = Object.assign(ctx, {
|
|
30
|
-
manifest: await clientManifest.json(),
|
|
31
|
-
assets: [
|
|
32
|
-
...(await clientManifest.inputs[clientManifest.handler]!.assets()),
|
|
33
|
-
...(import.meta.env.START_ISLANDS
|
|
34
|
-
? (await serverManifest.inputs[serverManifest.handler]!.assets()).filter(
|
|
35
|
-
s => (s as any).attrs.rel !== "modulepreload"
|
|
36
|
-
)
|
|
37
|
-
: [])
|
|
38
|
-
],
|
|
39
|
-
router: {
|
|
40
|
-
submission: initFromFlash(ctx) as any
|
|
41
|
-
},
|
|
42
|
-
routes: createRoutes(),
|
|
43
|
-
// prevUrl: prevPath || "",
|
|
44
|
-
// mutation: mutation,
|
|
45
|
-
// $type: FETCH_EVENT,
|
|
46
|
-
$islands: new Set<string>()
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
return pageEvent;
|
|
50
|
-
}
|
package/server/renderAsset.tsx
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
// @refresh skip
|
|
2
|
-
// TODO rename to renderAsset.ts?
|
|
3
|
-
import type { JSX } from "solid-js";
|
|
4
|
-
import type { Asset } from "./types";
|
|
5
|
-
|
|
6
|
-
const assetMap = {
|
|
7
|
-
style: (props: { attrs: JSX.StyleHTMLAttributes<HTMLStyleElement>; children?: JSX.Element }) => (
|
|
8
|
-
<style {...props.attrs}>{props.children}</style>
|
|
9
|
-
),
|
|
10
|
-
link: (props: { attrs: JSX.LinkHTMLAttributes<HTMLLinkElement> }) => <link {...props.attrs} />,
|
|
11
|
-
script: (props: { attrs: JSX.ScriptHTMLAttributes<HTMLScriptElement>; key: string | undefined }) => {
|
|
12
|
-
return props.attrs.src ? (
|
|
13
|
-
<script {...props.attrs} id={props.key}>
|
|
14
|
-
{" "}
|
|
15
|
-
</script>
|
|
16
|
-
) : null;
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export function renderAsset(asset: Asset) {
|
|
21
|
-
let { tag, attrs: { key, ...attrs } = { key: undefined }, children } = asset as any;
|
|
22
|
-
return (assetMap as any)[tag]({ attrs, key, children });
|
|
23
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
// @refresh skip
|
|
2
|
-
// @ts-ignore
|
|
3
|
-
import type { Component } from "solid-js";
|
|
4
|
-
import { NoHydration, getRequestEvent, ssr } from "solid-js/web";
|
|
5
|
-
import { renderAsset } from "../renderAsset";
|
|
6
|
-
import type { DocumentComponentProps, PageEvent } from "../types";
|
|
7
|
-
|
|
8
|
-
const docType = ssr("<!DOCTYPE html>");
|
|
9
|
-
|
|
10
|
-
export function StartServer(props: { document: Component<DocumentComponentProps> }) {
|
|
11
|
-
const context = getRequestEvent() as PageEvent;
|
|
12
|
-
// @ts-ignore
|
|
13
|
-
const nonce = context.nonce;
|
|
14
|
-
return (
|
|
15
|
-
<NoHydration>
|
|
16
|
-
{docType as unknown as any}
|
|
17
|
-
<props.document
|
|
18
|
-
assets={<>{context.assets.map((m: any) => renderAsset(m))}</>}
|
|
19
|
-
scripts={
|
|
20
|
-
nonce ? (
|
|
21
|
-
<>
|
|
22
|
-
<script
|
|
23
|
-
nonce={nonce}
|
|
24
|
-
innerHTML={`window.manifest = ${JSON.stringify(context.manifest)}`}
|
|
25
|
-
/>
|
|
26
|
-
<script
|
|
27
|
-
type="module"
|
|
28
|
-
src={
|
|
29
|
-
import.meta.env.MANIFEST["client"]!.inputs[
|
|
30
|
-
import.meta.env.MANIFEST["client"]!.handler
|
|
31
|
-
]!.output.path
|
|
32
|
-
}
|
|
33
|
-
/>
|
|
34
|
-
</>
|
|
35
|
-
) : (
|
|
36
|
-
<>
|
|
37
|
-
<script innerHTML={`window.manifest = ${JSON.stringify(context.manifest)}`} />
|
|
38
|
-
<script
|
|
39
|
-
type="module"
|
|
40
|
-
src={
|
|
41
|
-
import.meta.env.MANIFEST["client"]!.inputs[
|
|
42
|
-
import.meta.env.MANIFEST["client"]!.handler
|
|
43
|
-
]!.output.path
|
|
44
|
-
}
|
|
45
|
-
/>
|
|
46
|
-
</>
|
|
47
|
-
)
|
|
48
|
-
}
|
|
49
|
-
/>
|
|
50
|
-
</NoHydration>
|
|
51
|
-
);
|
|
52
|
-
}
|
package/server/spa/handler.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { createBaseHandler } from "../handler";
|
|
2
|
-
import { FetchEvent, HandlerOptions, PageEvent } from "../types";
|
|
3
|
-
|
|
4
|
-
export function createHandler(
|
|
5
|
-
fn: (context: PageEvent) => unknown,
|
|
6
|
-
options?: HandlerOptions | ((context: PageEvent) => HandlerOptions)
|
|
7
|
-
) {
|
|
8
|
-
return createBaseHandler(fn, createPageEvent, options);
|
|
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
|
-
}
|
package/server/types.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import type { JSX } from "solid-js";
|
|
2
|
-
import { RequestEvent } from "solid-js/web";
|
|
3
|
-
import { HTTPEvent } from "vinxi/http";
|
|
4
|
-
|
|
5
|
-
// export const FETCH_EVENT = "$FETCH";
|
|
6
|
-
|
|
7
|
-
export type DocumentComponentProps = {
|
|
8
|
-
assets: JSX.Element;
|
|
9
|
-
scripts: JSX.Element;
|
|
10
|
-
children?: JSX.Element;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export type Asset = {
|
|
14
|
-
tag: "style";
|
|
15
|
-
attrs: JSX.StyleHTMLAttributes<HTMLStyleElement> & { key?: string };
|
|
16
|
-
children?: JSX.Element;
|
|
17
|
-
} | {
|
|
18
|
-
tag: "script";
|
|
19
|
-
attrs: JSX.ScriptHTMLAttributes<HTMLScriptElement> & { key?: string };
|
|
20
|
-
} | {
|
|
21
|
-
tag: "link";
|
|
22
|
-
attrs: JSX.LinkHTMLAttributes<HTMLLinkElement> & { key?: string };
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export type HandlerOptions = {
|
|
26
|
-
mode?: "sync" | "async" | "stream";
|
|
27
|
-
nonce?: string;
|
|
28
|
-
renderId?: string;
|
|
29
|
-
onCompleteAll?: (options: { write: (v: any) => void }) => void;
|
|
30
|
-
onCompleteShell?: (options: { write: (v: any) => void }) => void;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export type ContextMatches = {
|
|
34
|
-
originalPath: string;
|
|
35
|
-
pattern: string;
|
|
36
|
-
path: string;
|
|
37
|
-
params: unknown;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export interface ResponseStub {
|
|
41
|
-
status?: number;
|
|
42
|
-
statusText?: string;
|
|
43
|
-
headers: Headers;
|
|
44
|
-
}
|
|
45
|
-
export interface FetchEvent {
|
|
46
|
-
request: Request;
|
|
47
|
-
response: ResponseStub;
|
|
48
|
-
clientAddress?: string;
|
|
49
|
-
locals: RequestEventLocals;
|
|
50
|
-
nativeEvent: HTTPEvent;
|
|
51
|
-
}
|
|
52
|
-
export interface RequestEventLocals {
|
|
53
|
-
[key: string | symbol]: any;
|
|
54
|
-
}
|
|
55
|
-
export interface PageEvent extends RequestEvent {
|
|
56
|
-
manifest: any;
|
|
57
|
-
assets: any;
|
|
58
|
-
routes: any[];
|
|
59
|
-
// prevUrl: string | null;
|
|
60
|
-
// $type: typeof FETCH_EVENT;
|
|
61
|
-
$islands: Set<string>;
|
|
62
|
-
// mutation: boolean;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export interface APIEvent extends FetchEvent {
|
|
66
|
-
params: { [key: string]: string };
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export interface APIHandler {
|
|
70
|
-
(event: APIEvent): Promise<any>;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export interface ServerFunctionMeta {
|
|
74
|
-
id: string;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
declare module "solid-js/web" {
|
|
78
|
-
interface RequestEvent extends FetchEvent {
|
|
79
|
-
serverOnly?: boolean;
|
|
80
|
-
}
|
|
81
|
-
}
|
package/shared/ErrorBoundary.tsx
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
// @refresh skip
|
|
2
|
-
import { ErrorBoundary as DefaultErrorBoundary, type ParentProps } from "solid-js";
|
|
3
|
-
import { isServer } from "solid-js/web";
|
|
4
|
-
import { HttpStatusCode } from "./HttpStatusCode";
|
|
5
|
-
import { DevOverlay } from "./dev-overlay";
|
|
6
|
-
|
|
7
|
-
export const ErrorBoundary = import.meta.env.DEV && import.meta.env.START_DEV_OVERLAY
|
|
8
|
-
? (props: ParentProps) => <DevOverlay>{props.children}</DevOverlay>
|
|
9
|
-
: (props: ParentProps) => {
|
|
10
|
-
const message = isServer ? "500 | Internal Server Error" : "Error | Uncaught Client Exception";
|
|
11
|
-
return (
|
|
12
|
-
<DefaultErrorBoundary
|
|
13
|
-
fallback={
|
|
14
|
-
<>
|
|
15
|
-
<span style="font-size:1.5em;text-align:center;position:fixed;left:0px;bottom:55%;width:100%;">{message}</span>
|
|
16
|
-
<HttpStatusCode code={500} />
|
|
17
|
-
</>
|
|
18
|
-
}
|
|
19
|
-
>
|
|
20
|
-
{props.children}
|
|
21
|
-
</DefaultErrorBoundary>
|
|
22
|
-
)
|
|
23
|
-
};
|