@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
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// @refresh skip
|
|
2
|
+
import { ErrorBoundary, Show, createEffect, createSignal, onCleanup, resetErrorBoundaries } from "solid-js";
|
|
3
|
+
import { HttpStatusCode } from "../HttpStatusCode";
|
|
4
|
+
import clientOnly from "../clientOnly";
|
|
5
|
+
const DevOverlayDialog = /* #__PURE__ */ clientOnly(() => import("./DevOverlayDialog"));
|
|
6
|
+
export function DevOverlay(props) {
|
|
7
|
+
const [errors, setErrors] = createSignal([]);
|
|
8
|
+
function resetError() {
|
|
9
|
+
setErrors([]);
|
|
10
|
+
resetErrorBoundaries();
|
|
11
|
+
}
|
|
12
|
+
function pushError(error) {
|
|
13
|
+
console.error(error);
|
|
14
|
+
setErrors(current => [error, ...current]);
|
|
15
|
+
}
|
|
16
|
+
createEffect(() => {
|
|
17
|
+
const onErrorEvent = (error) => {
|
|
18
|
+
pushError(error.error);
|
|
19
|
+
};
|
|
20
|
+
window.addEventListener("error", onErrorEvent);
|
|
21
|
+
onCleanup(() => {
|
|
22
|
+
window.removeEventListener("error", onErrorEvent);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
return (<>
|
|
26
|
+
<ErrorBoundary fallback={error => {
|
|
27
|
+
pushError(error);
|
|
28
|
+
return <HttpStatusCode code={500}/>;
|
|
29
|
+
}}>
|
|
30
|
+
{props.children}
|
|
31
|
+
</ErrorBoundary>
|
|
32
|
+
<Show when={errors().length}>
|
|
33
|
+
<HttpStatusCode code={500}/>
|
|
34
|
+
<DevOverlayDialog errors={errors()} resetError={resetError}/>
|
|
35
|
+
</Show>
|
|
36
|
+
</>);
|
|
37
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidjs/start",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": "Ryan Carniato",
|
|
6
6
|
"license": "MIT",
|
|
@@ -8,42 +8,38 @@
|
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
|
-
"client",
|
|
12
11
|
"config",
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"server",
|
|
16
|
-
"shared",
|
|
17
|
-
"*.d.ts"
|
|
12
|
+
"dist",
|
|
13
|
+
"env.d.ts"
|
|
18
14
|
],
|
|
19
|
-
"types": "./
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
20
16
|
"exports": {
|
|
21
|
-
".": "./
|
|
17
|
+
".": "./dist/index.jsx",
|
|
22
18
|
"./config": "./config/index.js",
|
|
23
|
-
"./middleware": "./middleware/index.
|
|
24
|
-
"./router": "./router/index.
|
|
25
|
-
"./server": "./server/index.
|
|
26
|
-
"./server/spa": "./server/spa/index.
|
|
27
|
-
"./client": "./client/index.
|
|
28
|
-
"./client/islands": "./client/islands.
|
|
29
|
-
"./client/spa": "./client/spa/index.
|
|
19
|
+
"./middleware": "./dist/middleware/index.js",
|
|
20
|
+
"./router": "./dist/router/index.jsx",
|
|
21
|
+
"./server": "./dist/server/index.jsx",
|
|
22
|
+
"./server/spa": "./dist/server/spa/index.jsx",
|
|
23
|
+
"./client": "./dist/client/index.jsx",
|
|
24
|
+
"./client/islands": "./dist/client/islands.jsx",
|
|
25
|
+
"./client/spa": "./dist/client/spa/index.jsx"
|
|
30
26
|
},
|
|
31
27
|
"typesVersions": {
|
|
32
28
|
"*": {
|
|
33
29
|
".": [
|
|
34
|
-
"./
|
|
30
|
+
"./dist/index.d.ts"
|
|
35
31
|
],
|
|
36
32
|
"middleware": [
|
|
37
|
-
"./middleware/index.ts"
|
|
33
|
+
"./dist/middleware/index.d.ts"
|
|
38
34
|
],
|
|
39
35
|
"router": [
|
|
40
|
-
"./router/index.ts"
|
|
36
|
+
"./dist/router/index.d.ts"
|
|
41
37
|
],
|
|
42
38
|
"server": [
|
|
43
|
-
"./server/index.
|
|
39
|
+
"./dist/server/index.d.ts"
|
|
44
40
|
],
|
|
45
41
|
"client": [
|
|
46
|
-
"./client/index.
|
|
42
|
+
"./dist/client/index.d.ts"
|
|
47
43
|
]
|
|
48
44
|
}
|
|
49
45
|
},
|
|
@@ -57,6 +53,7 @@
|
|
|
57
53
|
"@vinxi/server-functions": "^0.3.2",
|
|
58
54
|
"defu": "^6.1.2",
|
|
59
55
|
"error-stack-parser": "^2.1.4",
|
|
56
|
+
"glob": "^10.3.10",
|
|
60
57
|
"html-to-image": "^1.11.11",
|
|
61
58
|
"radix3": "^1.1.0",
|
|
62
59
|
"seroval": "^1.0.2",
|
|
@@ -68,6 +65,7 @@
|
|
|
68
65
|
"vite-plugin-solid": "~2.9.1"
|
|
69
66
|
},
|
|
70
67
|
"scripts": {
|
|
71
|
-
"typecheck": "tsc --noEmit
|
|
68
|
+
"typecheck": "tsc --noEmit",
|
|
69
|
+
"build": "node build && pnpm tsc"
|
|
72
70
|
}
|
|
73
71
|
}
|
package/client/mount.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import type { JSX } from "solid-js";
|
|
2
|
-
import { createStore } from "solid-js/store";
|
|
3
|
-
import { createComponent, getHydrationKey, getOwner, hydrate, type MountableElement } from "solid-js/web";
|
|
4
|
-
|
|
5
|
-
export function mount(fn: () => JSX.Element, el: MountableElement) {
|
|
6
|
-
if (import.meta.env.START_ISLANDS) {
|
|
7
|
-
const map = new WeakMap();
|
|
8
|
-
async function mountIsland(el: HTMLElement) {
|
|
9
|
-
if (el.dataset.css) {
|
|
10
|
-
let css = JSON.parse(el.dataset.css);
|
|
11
|
-
for (let href of css) {
|
|
12
|
-
if (!document.querySelector(`link[href="${href}"]`)) {
|
|
13
|
-
let link = document.createElement("link");
|
|
14
|
-
link.rel = "stylesheet";
|
|
15
|
-
link.href = href;
|
|
16
|
-
document.head.appendChild(link);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
let mod = await import(
|
|
22
|
-
/* @vite-ignore */
|
|
23
|
-
import.meta.env.MANIFEST["client"]!.chunks[el.dataset.id!.split("#")[0] as string]!.output.path
|
|
24
|
-
);
|
|
25
|
-
if (!mod || !el.dataset.hk) return;
|
|
26
|
-
|
|
27
|
-
let Component = mod[el.dataset.id!.split("#")[1] as string];
|
|
28
|
-
let hk = el.dataset.hk;
|
|
29
|
-
// _$DEBUG("hydrating island", el.dataset.island, hk.slice(0, hk.length - 1) + `1-`, el);
|
|
30
|
-
|
|
31
|
-
let props = createStore({
|
|
32
|
-
...JSON.parse(el.dataset.props!),
|
|
33
|
-
get children() {
|
|
34
|
-
const p = el.getElementsByTagName("solid-children");
|
|
35
|
-
getHydrationKey();
|
|
36
|
-
[...p].forEach(a => {
|
|
37
|
-
(a as any).__$owner = getOwner();
|
|
38
|
-
});
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
map.set(el, props);
|
|
44
|
-
|
|
45
|
-
hydrate(() => createComponent(Component, props[0]), el, {
|
|
46
|
-
renderId: hk.slice(0, hk.length - 1) + `${1 + Number(el.dataset.offset)}-`,
|
|
47
|
-
owner: lookupOwner(el)
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
delete el.dataset.hk;
|
|
51
|
-
el.dataset.hkk = hk;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
let queue: HTMLElement[] = [];
|
|
55
|
-
let queued = false;
|
|
56
|
-
function runTaskQueue(info: any) {
|
|
57
|
-
while (info.timeRemaining() > 0 && queue.length) {
|
|
58
|
-
mountIsland(queue.shift()!);
|
|
59
|
-
}
|
|
60
|
-
if (queue.length) {
|
|
61
|
-
requestIdleCallback(runTaskQueue);
|
|
62
|
-
} else queued = false;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const hydrateIslands = () => {
|
|
66
|
-
const islands: NodeListOf<HTMLElement> = document.querySelectorAll("solid-island[data-hk]");
|
|
67
|
-
const assets = new Set<string>();
|
|
68
|
-
islands.forEach((el: HTMLElement) => el.dataset.id && assets.add(el.dataset.id));
|
|
69
|
-
Promise.all(
|
|
70
|
-
[...assets].map(
|
|
71
|
-
asset =>
|
|
72
|
-
import(/* @vite-ignore */import.meta.env.MANIFEST["client"]!.chunks[asset.split("#")[0] as string]!.output.path)
|
|
73
|
-
)
|
|
74
|
-
)
|
|
75
|
-
.then(() => {
|
|
76
|
-
islands.forEach((el: HTMLElement) => {
|
|
77
|
-
if (el.dataset.when === "idle" && "requestIdleCallback" in window) {
|
|
78
|
-
if (!queued) {
|
|
79
|
-
queued = true;
|
|
80
|
-
requestIdleCallback(runTaskQueue);
|
|
81
|
-
}
|
|
82
|
-
queue.push(el);
|
|
83
|
-
} else mountIsland(el as HTMLElement);
|
|
84
|
-
});
|
|
85
|
-
})
|
|
86
|
-
.catch(e => console.error(e));
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
function lookupOwner(el: HTMLElement) {
|
|
90
|
-
const parent = el.closest("solid-children");
|
|
91
|
-
return parent && (parent as any).__$owner;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
hydrateIslands();
|
|
95
|
-
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
return hydrate(fn, el);
|
|
99
|
-
}
|
package/client/spa/index.tsx
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// @refresh skip
|
|
2
|
-
import type { JSX } from "solid-js";
|
|
3
|
-
import { render, type MountableElement } from "solid-js/web";
|
|
4
|
-
import "vinxi/client";
|
|
5
|
-
|
|
6
|
-
export function mount(fn: () => JSX.Element, el: MountableElement) {
|
|
7
|
-
render(fn, el);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export { StartClient } from "../StartClient";
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { getRequestEvent } from "solid-js/web";
|
|
2
|
-
import { provideRequestEvent } from "solid-js/web/storage";
|
|
3
|
-
import { cloneEvent } from "../server/fetchEvent";
|
|
4
|
-
|
|
5
|
-
export function createServerReference(fn: Function, id: string, name: string) {
|
|
6
|
-
if (typeof fn !== "function") throw new Error("Export from a 'use server' module must be a function");
|
|
7
|
-
const baseURL = import.meta.env.SERVER_BASE_URL;
|
|
8
|
-
return new Proxy(fn, {
|
|
9
|
-
get(target, prop, receiver) {
|
|
10
|
-
if (prop === "url") {
|
|
11
|
-
return `${baseURL}/_server?id=${encodeURIComponent(id)}&name=${encodeURIComponent(name)}`;
|
|
12
|
-
}
|
|
13
|
-
if (prop === "GET") return receiver;
|
|
14
|
-
},
|
|
15
|
-
apply(target, thisArg, args) {
|
|
16
|
-
const ogEvt = getRequestEvent();
|
|
17
|
-
if (!ogEvt) throw new Error("Cannot call server function outside of a request");
|
|
18
|
-
const evt = cloneEvent(ogEvt);
|
|
19
|
-
evt.locals.serverFunctionMeta = {
|
|
20
|
-
id: id + "#" + name,
|
|
21
|
-
};
|
|
22
|
-
evt.serverOnly = true;
|
|
23
|
-
return provideRequestEvent(evt, () => {
|
|
24
|
-
return fn.apply(thisArg, args);
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
}
|
package/config/server-handler.ts
DELETED
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
/// <reference types="vinxi/types/server" />
|
|
2
|
-
import { crossSerializeStream, fromJSON, getCrossReferenceHeader } from "seroval";
|
|
3
|
-
// @ts-ignore
|
|
4
|
-
import {
|
|
5
|
-
CustomEventPlugin,
|
|
6
|
-
DOMExceptionPlugin,
|
|
7
|
-
EventPlugin,
|
|
8
|
-
FormDataPlugin,
|
|
9
|
-
HeadersPlugin,
|
|
10
|
-
ReadableStreamPlugin,
|
|
11
|
-
RequestPlugin,
|
|
12
|
-
ResponsePlugin,
|
|
13
|
-
URLPlugin,
|
|
14
|
-
URLSearchParamsPlugin
|
|
15
|
-
} from "seroval-plugins/web";
|
|
16
|
-
import { sharedConfig } from "solid-js";
|
|
17
|
-
import { renderToString } from "solid-js/web";
|
|
18
|
-
import { provideRequestEvent } from "solid-js/web/storage";
|
|
19
|
-
import { eventHandler, setHeader, setResponseStatus, type HTTPEvent } from "vinxi/http";
|
|
20
|
-
import invariant from "vinxi/lib/invariant";
|
|
21
|
-
import { cloneEvent, getFetchEvent, mergeResponseHeaders } from "../server/fetchEvent";
|
|
22
|
-
import { createPageEvent } from "../server/pageEvent";
|
|
23
|
-
// @ts-ignore
|
|
24
|
-
import { FetchEvent, PageEvent } from "../server";
|
|
25
|
-
|
|
26
|
-
function createChunk(data: string) {
|
|
27
|
-
const bytes = data.length;
|
|
28
|
-
const baseHex = bytes.toString(16);
|
|
29
|
-
const totalHex = "00000000".substring(0, 8 - baseHex.length) + baseHex; // 32-bit
|
|
30
|
-
return new TextEncoder().encode(`;0x${totalHex};${data}`);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function serializeToStream(id: string, value: any) {
|
|
34
|
-
return new ReadableStream({
|
|
35
|
-
start(controller) {
|
|
36
|
-
crossSerializeStream(value, {
|
|
37
|
-
scopeId: id,
|
|
38
|
-
plugins: [
|
|
39
|
-
CustomEventPlugin,
|
|
40
|
-
DOMExceptionPlugin,
|
|
41
|
-
EventPlugin,
|
|
42
|
-
FormDataPlugin,
|
|
43
|
-
HeadersPlugin,
|
|
44
|
-
ReadableStreamPlugin,
|
|
45
|
-
RequestPlugin,
|
|
46
|
-
ResponsePlugin,
|
|
47
|
-
URLSearchParamsPlugin,
|
|
48
|
-
URLPlugin
|
|
49
|
-
],
|
|
50
|
-
onSerialize(data, initial) {
|
|
51
|
-
controller.enqueue(
|
|
52
|
-
createChunk(initial ? `(${getCrossReferenceHeader(id)},${data})` : data)
|
|
53
|
-
);
|
|
54
|
-
},
|
|
55
|
-
onDone() {
|
|
56
|
-
controller.close();
|
|
57
|
-
},
|
|
58
|
-
onError(error) {
|
|
59
|
-
controller.error(error);
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async function handleServerFunction(h3Event: HTTPEvent) {
|
|
67
|
-
const event = getFetchEvent(h3Event);
|
|
68
|
-
const request = event.request;
|
|
69
|
-
|
|
70
|
-
const serverReference = request.headers.get("X-Server-Id");
|
|
71
|
-
const instance = request.headers.get("X-Server-Instance");
|
|
72
|
-
const singleFlight = request.headers.has("X-Single-Flight");
|
|
73
|
-
const url = new URL(request.url);
|
|
74
|
-
let filepath: string | undefined | null, name: string | undefined | null;
|
|
75
|
-
if (serverReference) {
|
|
76
|
-
invariant(typeof serverReference === "string", "Invalid server function");
|
|
77
|
-
[filepath, name] = serverReference.split("#");
|
|
78
|
-
} else {
|
|
79
|
-
filepath = url.searchParams.get("id");
|
|
80
|
-
name = url.searchParams.get("name");
|
|
81
|
-
if (!filepath || !name) throw new Error("Invalid request");
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const serverFunction = (
|
|
85
|
-
await import.meta.env.MANIFEST[import.meta.env.ROUTER_NAME]!.chunks[filepath!]!.import()
|
|
86
|
-
)[name!];
|
|
87
|
-
let parsed: any[] = [];
|
|
88
|
-
|
|
89
|
-
// grab bound arguments from url when no JS
|
|
90
|
-
if (!instance || h3Event.method === "GET") {
|
|
91
|
-
const args = url.searchParams.get("args");
|
|
92
|
-
if (args) JSON.parse(args).forEach((arg: any) => parsed.push(arg));
|
|
93
|
-
}
|
|
94
|
-
if (h3Event.method === "POST") {
|
|
95
|
-
const contentType = request.headers.get("content-type");
|
|
96
|
-
if (
|
|
97
|
-
contentType?.startsWith("multipart/form-data") ||
|
|
98
|
-
contentType?.startsWith("application/x-www-form-urlencoded")
|
|
99
|
-
) {
|
|
100
|
-
// workaround for https://github.com/unjs/nitro/issues/1721
|
|
101
|
-
// (issue only in edge runtimes)
|
|
102
|
-
parsed.push(
|
|
103
|
-
await new Request(request, { ...request, body: (h3Event.node.req as any).body }).formData()
|
|
104
|
-
);
|
|
105
|
-
// what should work when #1721 is fixed
|
|
106
|
-
// parsed.push(await request.formData);
|
|
107
|
-
} else if (contentType?.startsWith("application/json")) {
|
|
108
|
-
// workaround for https://github.com/unjs/nitro/issues/1721
|
|
109
|
-
// (issue only in edge runtimes)
|
|
110
|
-
const tmpReq = new Request(request, { ...request, body: (h3Event.node.req as any).body });
|
|
111
|
-
// what should work when #1721 is fixed
|
|
112
|
-
// just use request.json() here
|
|
113
|
-
parsed = fromJSON(await tmpReq.json(), {
|
|
114
|
-
plugins: [
|
|
115
|
-
CustomEventPlugin,
|
|
116
|
-
DOMExceptionPlugin,
|
|
117
|
-
EventPlugin,
|
|
118
|
-
FormDataPlugin,
|
|
119
|
-
HeadersPlugin,
|
|
120
|
-
ReadableStreamPlugin,
|
|
121
|
-
RequestPlugin,
|
|
122
|
-
ResponsePlugin,
|
|
123
|
-
URLSearchParamsPlugin,
|
|
124
|
-
URLPlugin
|
|
125
|
-
]
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
try {
|
|
130
|
-
let result = await provideRequestEvent(event, async () => {
|
|
131
|
-
/* @ts-ignore */
|
|
132
|
-
sharedConfig.context = { event };
|
|
133
|
-
event.locals.serverFunctionMeta = {
|
|
134
|
-
id: filepath + "#" + name,
|
|
135
|
-
};
|
|
136
|
-
return serverFunction(...parsed);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
if (singleFlight && instance) {
|
|
140
|
-
result = await handleSingleFlight(event, result);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// handle responses
|
|
144
|
-
if (result instanceof Response && instance) {
|
|
145
|
-
// forward headers
|
|
146
|
-
if (result.headers) mergeResponseHeaders(h3Event, result.headers);
|
|
147
|
-
// forward non-redirect statuses
|
|
148
|
-
if (result.status && (result.status < 300 || result.status >= 400)) setResponseStatus(h3Event, result.status);
|
|
149
|
-
if ((result as any).customBody) {
|
|
150
|
-
result = await (result as any).customBody();
|
|
151
|
-
} else if (result.body == undefined) result = null;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// handle no JS success case
|
|
155
|
-
if (!instance) {
|
|
156
|
-
const isError = result instanceof Error;
|
|
157
|
-
let redirectUrl = new URL(request.headers.get("referer")!).toString();
|
|
158
|
-
if (result instanceof Response && result.headers.has("Location")) {
|
|
159
|
-
redirectUrl = new URL(
|
|
160
|
-
result.headers.get("Location")!,
|
|
161
|
-
new URL(request.url).origin + import.meta.env.SERVER_BASE_URL
|
|
162
|
-
).toString();
|
|
163
|
-
}
|
|
164
|
-
return new Response(null, {
|
|
165
|
-
status: 302,
|
|
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
|
-
}
|
|
181
|
-
setHeader(h3Event, "content-type", "text/javascript");
|
|
182
|
-
return serializeToStream(instance, result);
|
|
183
|
-
} catch (x) {
|
|
184
|
-
if (x instanceof Response) {
|
|
185
|
-
if (singleFlight && instance) {
|
|
186
|
-
x = await handleSingleFlight(event, x);
|
|
187
|
-
}
|
|
188
|
-
// forward headers
|
|
189
|
-
if ((x as any).headers) mergeResponseHeaders(h3Event, (x as any).headers);
|
|
190
|
-
// forward non-redirect statuses
|
|
191
|
-
if ((x as any).status && (!instance || (x as any).status < 300 || (x as any).status >= 400)) setResponseStatus(h3Event, (x as any).status);
|
|
192
|
-
if ((x as any).customBody) {
|
|
193
|
-
x = (x as any).customBody();
|
|
194
|
-
} else if ((x as any).body == undefined) x = null;
|
|
195
|
-
} else {
|
|
196
|
-
const error = x instanceof Error ? x.message : typeof x === "string" ? x : "true";
|
|
197
|
-
setHeader(h3Event, "X-Error", error);
|
|
198
|
-
}
|
|
199
|
-
if (instance) {
|
|
200
|
-
setHeader(h3Event, "content-type", "text/javascript");
|
|
201
|
-
return serializeToStream(instance, x);
|
|
202
|
-
}
|
|
203
|
-
return x;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
let App: any;
|
|
208
|
-
async function handleSingleFlight(sourceEvent: FetchEvent, result: any): Promise<Response> {
|
|
209
|
-
let revalidate: string[];
|
|
210
|
-
let url = new URL(sourceEvent.request.headers.get("referer")!).toString();
|
|
211
|
-
if (result instanceof Response) {
|
|
212
|
-
if (result.headers.has("X-Revalidate"))
|
|
213
|
-
revalidate = result.headers.get("X-Revalidate")!.split(",");
|
|
214
|
-
if (result.headers.has("Location"))
|
|
215
|
-
url = new URL(
|
|
216
|
-
result.headers.get("Location")!,
|
|
217
|
-
new URL(sourceEvent.request.url).origin + import.meta.env.SERVER_BASE_URL
|
|
218
|
-
).toString();
|
|
219
|
-
}
|
|
220
|
-
const event = cloneEvent(sourceEvent) as PageEvent;
|
|
221
|
-
event.request = new Request(url);
|
|
222
|
-
return await provideRequestEvent(event, async () => {
|
|
223
|
-
await createPageEvent(event);
|
|
224
|
-
/* @ts-ignore */
|
|
225
|
-
App || (App = (await import("#start/app")).default);
|
|
226
|
-
/* @ts-ignore */
|
|
227
|
-
event.router.dataOnly = revalidate || true;
|
|
228
|
-
/* @ts-ignore */
|
|
229
|
-
event.router.previousUrl = sourceEvent.request.headers.get("referer");
|
|
230
|
-
try {
|
|
231
|
-
renderToString(() => {
|
|
232
|
-
/* @ts-ignore */
|
|
233
|
-
sharedConfig.context.event = event;
|
|
234
|
-
App();
|
|
235
|
-
});
|
|
236
|
-
} catch (e) {
|
|
237
|
-
console.log(e);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/* @ts-ignore */
|
|
241
|
-
const body = event.router.data;
|
|
242
|
-
if (!body) return result;
|
|
243
|
-
let containsKey = false;
|
|
244
|
-
for (const key in body) {
|
|
245
|
-
if (body[key] === undefined) delete body[key];
|
|
246
|
-
else containsKey = true;
|
|
247
|
-
}
|
|
248
|
-
if (!containsKey) return result;
|
|
249
|
-
if (!(result instanceof Response)) {
|
|
250
|
-
body["_$value"] = result;
|
|
251
|
-
result = new Response(null, { status: 200 });
|
|
252
|
-
} else if ((result as any).customBody) {
|
|
253
|
-
body["_$value"] = (result as any).customBody();
|
|
254
|
-
}
|
|
255
|
-
result.customBody = () => body;
|
|
256
|
-
result.headers.set("X-Single-Flight", "true");
|
|
257
|
-
return result;
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
export default eventHandler(handleServerFunction);
|