@solidjs/start 2.0.0-alpha.0 → 2.0.0-alpha.1
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/CHANGELOG.md +14 -0
- package/dist/client/mount.d.ts +1 -7
- package/dist/client/mount.js +1 -99
- package/dist/config/constants.js +2 -2
- package/dist/config/fs-router.js +10 -22
- package/dist/config/fs-routes/fs-watcher.js +4 -4
- package/dist/config/fs-routes/index.js +4 -6
- package/dist/config/fs-routes/router.js +5 -5
- package/dist/config/fs-routes/tree-shake.js +12 -21
- package/dist/config/index.js +33 -36
- package/dist/config/lazy.js +9 -9
- package/dist/config/manifest.js +1 -1
- package/dist/http/index.d.ts +1 -4
- package/dist/http/index.js +3 -5
- package/dist/index.d.ts +0 -1
- package/dist/router.jsx +2 -2
- package/dist/server/assets/index.js +1 -1
- package/dist/server/assets/render.jsx +2 -2
- package/dist/server/fetchEvent.spec.js +1 -1
- package/dist/server/handler.js +29 -15
- package/dist/server/index.d.ts +1 -0
- package/dist/server/manifest/dev-client-manifest.js +1 -1
- package/dist/server/manifest/dev-ssr-manifest.js +1 -1
- package/dist/server/manifest/prod-ssr-manifest.js +7 -12
- package/dist/server/routes.js +3 -3
- package/dist/server/server-fns-runtime.js +2 -2
- package/dist/server/server-functions-handler.js +6 -11
- package/dist/server/server-runtime.js +8 -8
- package/dist/shared/dev-overlay/CodeView.d.ts +1 -1
- package/dist/shared/dev-overlay/CodeView.jsx +23 -34
- package/dist/shared/dev-overlay/DevOverlayDialog.jsx +4 -4
- package/dist/shared/dev-overlay/get-source-map.d.ts +1 -1
- package/dist/shared/dev-overlay/get-source-map.js +5 -5
- package/dist/shared/dev-overlay/icons.d.ts +10 -10
- package/dist/shared/dev-overlay/icons.jsx +91 -91
- package/dist/shared/dev-overlay/index.jsx +1 -1
- package/dist/shared/lazy.js +4 -2
- package/env.d.ts +9 -0
- package/package.json +5 -4
- package/scripts/build.js +3 -3
- package/scripts/validate-imports.js +8 -8
- package/src/client/mount.ts +1 -114
- package/src/config/constants.ts +3 -3
- package/src/config/dev-server.ts +95 -99
- package/src/config/fs-router.ts +140 -155
- package/src/config/fs-routes/fs-watcher.ts +57 -61
- package/src/config/fs-routes/index.ts +117 -119
- package/src/config/fs-routes/router.ts +7 -7
- package/src/config/fs-routes/tree-shake.ts +342 -363
- package/src/config/index.ts +36 -39
- package/src/config/lazy.ts +13 -13
- package/src/config/manifest.ts +5 -5
- package/src/config/vite-utils.ts +2 -6
- package/src/env.d.ts +10 -28
- package/src/http/index.ts +105 -142
- package/src/index.tsx +0 -12
- package/src/internal.d.ts +1 -1
- package/src/middleware/index.ts +39 -49
- package/src/router.tsx +4 -3
- package/src/server/StartServer.tsx +1 -7
- package/src/server/assets/index.ts +1 -1
- package/src/server/assets/render.tsx +6 -2
- package/src/server/collect-styles.ts +63 -70
- package/src/server/fetchEvent.spec.ts +71 -75
- package/src/server/fetchEvent.ts +17 -17
- package/src/server/handler.ts +136 -129
- package/src/server/index.tsx +13 -0
- package/src/server/manifest/client-manifest.ts +1 -1
- package/src/server/manifest/dev-client-manifest.ts +7 -5
- package/src/server/manifest/dev-ssr-manifest.ts +8 -6
- package/src/server/manifest/prod-client-manifest.ts +7 -4
- package/src/server/manifest/prod-ssr-manifest.ts +78 -94
- package/src/server/manifest/ssr-manifest.ts +4 -2
- package/src/server/routes.ts +96 -108
- package/src/server/server-fns-runtime.ts +3 -3
- package/src/server/server-functions-handler.ts +294 -319
- package/src/server/server-runtime.ts +13 -13
- package/src/server/spa/handler.ts +12 -12
- package/src/server/types.ts +46 -46
- package/src/server/util.ts +4 -4
- package/src/shared/ErrorBoundary.tsx +1 -1
- package/src/shared/HttpHeader.tsx +20 -20
- package/src/shared/HttpStatusCode.ts +14 -14
- package/src/shared/clientOnly.ts +3 -3
- package/src/shared/dev-overlay/CodeView.tsx +43 -46
- package/src/shared/dev-overlay/DevOverlayDialog.tsx +4 -4
- package/src/shared/dev-overlay/createStackFrame.ts +59 -62
- package/src/shared/dev-overlay/env.d.ts +2 -2
- package/src/shared/dev-overlay/get-source-map.ts +5 -7
- package/src/shared/dev-overlay/icons.tsx +289 -121
- package/src/shared/dev-overlay/index.tsx +1 -1
- package/src/shared/lazy.ts +4 -3
- package/src/shared/serverFunction.ts +1 -1
- package/src/virtual.d.ts +10 -10
- package/tsconfig.json +2 -2
- package/vitest.config.ts +2 -2
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
import { getServerFnById } from "solidstart:server-fn-manifest";
|
|
2
2
|
import { parseSetCookie } from "cookie-es";
|
|
3
3
|
import { type H3Event, parseCookies } from "h3";
|
|
4
|
+
import { crossSerializeStream, fromJSON, getCrossReferenceHeader } from "seroval";
|
|
4
5
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
ReadableStreamPlugin,
|
|
16
|
-
RequestPlugin,
|
|
17
|
-
ResponsePlugin,
|
|
18
|
-
URLPlugin,
|
|
19
|
-
URLSearchParamsPlugin,
|
|
6
|
+
CustomEventPlugin,
|
|
7
|
+
DOMExceptionPlugin,
|
|
8
|
+
EventPlugin,
|
|
9
|
+
FormDataPlugin,
|
|
10
|
+
HeadersPlugin,
|
|
11
|
+
ReadableStreamPlugin,
|
|
12
|
+
RequestPlugin,
|
|
13
|
+
ResponsePlugin,
|
|
14
|
+
URLPlugin,
|
|
15
|
+
URLSearchParamsPlugin,
|
|
20
16
|
} from "seroval-plugins/web";
|
|
21
17
|
import { sharedConfig } from "solid-js";
|
|
22
18
|
import { renderToString } from "solid-js/web";
|
|
@@ -28,337 +24,316 @@ import type { FetchEvent, PageEvent } from "./types.ts";
|
|
|
28
24
|
import { getExpectedRedirectStatus } from "./util.ts";
|
|
29
25
|
|
|
30
26
|
function createChunk(data: string) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
const encodeData = new TextEncoder().encode(data);
|
|
28
|
+
const bytes = encodeData.length;
|
|
29
|
+
const baseHex = bytes.toString(16);
|
|
30
|
+
const totalHex = "00000000".substring(0, 8 - baseHex.length) + baseHex; // 32-bit
|
|
31
|
+
const head = new TextEncoder().encode(`;0x${totalHex};`);
|
|
36
32
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
const chunk = new Uint8Array(12 + bytes);
|
|
34
|
+
chunk.set(head);
|
|
35
|
+
chunk.set(encodeData, 12);
|
|
36
|
+
return chunk;
|
|
41
37
|
}
|
|
42
38
|
|
|
43
39
|
function serializeToStream(id: string, value: any) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
},
|
|
75
|
-
});
|
|
40
|
+
return new ReadableStream({
|
|
41
|
+
start(controller) {
|
|
42
|
+
crossSerializeStream(value, {
|
|
43
|
+
scopeId: id,
|
|
44
|
+
plugins: [
|
|
45
|
+
CustomEventPlugin,
|
|
46
|
+
DOMExceptionPlugin,
|
|
47
|
+
EventPlugin,
|
|
48
|
+
FormDataPlugin,
|
|
49
|
+
HeadersPlugin,
|
|
50
|
+
ReadableStreamPlugin,
|
|
51
|
+
RequestPlugin,
|
|
52
|
+
ResponsePlugin,
|
|
53
|
+
URLSearchParamsPlugin,
|
|
54
|
+
URLPlugin,
|
|
55
|
+
],
|
|
56
|
+
onSerialize(data: string, initial: boolean) {
|
|
57
|
+
controller.enqueue(
|
|
58
|
+
createChunk(initial ? `(${getCrossReferenceHeader(id)},${data})` : data),
|
|
59
|
+
);
|
|
60
|
+
},
|
|
61
|
+
onDone() {
|
|
62
|
+
controller.close();
|
|
63
|
+
},
|
|
64
|
+
onError(error: any) {
|
|
65
|
+
controller.error(error);
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
});
|
|
76
70
|
}
|
|
77
71
|
|
|
78
72
|
export async function handleServerFunction(h3Event: H3Event) {
|
|
79
|
-
|
|
80
|
-
|
|
73
|
+
const event = getFetchEvent(h3Event);
|
|
74
|
+
const request = event.request;
|
|
81
75
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
76
|
+
const serverReference = request.headers.get("X-Server-Id");
|
|
77
|
+
const instance = request.headers.get("X-Server-Instance");
|
|
78
|
+
const singleFlight = request.headers.has("X-Single-Flight");
|
|
79
|
+
const url = new URL(request.url);
|
|
80
|
+
let functionId: string | undefined | null;
|
|
81
|
+
if (serverReference) {
|
|
82
|
+
// invariant(typeof serverReference === "string", "Invalid server function");
|
|
83
|
+
[functionId] = serverReference.split("#");
|
|
84
|
+
} else {
|
|
85
|
+
functionId = url.searchParams.get("id");
|
|
92
86
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
87
|
+
if (!functionId) {
|
|
88
|
+
return process.env.NODE_ENV === "development"
|
|
89
|
+
? new Response("Server function not found", { status: 404 })
|
|
90
|
+
: new Response(null, { status: 404 });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
99
93
|
|
|
100
|
-
|
|
94
|
+
const serverFunction = await getServerFnById(functionId!);
|
|
101
95
|
|
|
102
|
-
|
|
96
|
+
let parsed: any[] = [];
|
|
103
97
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
98
|
+
// grab bound arguments from url when no JS
|
|
99
|
+
if (!instance || h3Event.method === "GET") {
|
|
100
|
+
const args = url.searchParams.get("args");
|
|
101
|
+
if (args) {
|
|
102
|
+
const json = JSON.parse(args);
|
|
103
|
+
(json.t
|
|
104
|
+
? (fromJSON(json, {
|
|
105
|
+
plugins: [
|
|
106
|
+
CustomEventPlugin,
|
|
107
|
+
DOMExceptionPlugin,
|
|
108
|
+
EventPlugin,
|
|
109
|
+
FormDataPlugin,
|
|
110
|
+
HeadersPlugin,
|
|
111
|
+
ReadableStreamPlugin,
|
|
112
|
+
RequestPlugin,
|
|
113
|
+
ResponsePlugin,
|
|
114
|
+
URLSearchParamsPlugin,
|
|
115
|
+
URLPlugin,
|
|
116
|
+
],
|
|
117
|
+
}) as any)
|
|
118
|
+
: json
|
|
119
|
+
).forEach((arg: any) => {
|
|
120
|
+
parsed.push(arg);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (h3Event.method === "POST") {
|
|
125
|
+
const contentType = request.headers.get("content-type");
|
|
132
126
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
127
|
+
if (
|
|
128
|
+
contentType?.startsWith("multipart/form-data") ||
|
|
129
|
+
contentType?.startsWith("application/x-www-form-urlencoded")
|
|
130
|
+
) {
|
|
131
|
+
parsed.push(await event.request.formData());
|
|
132
|
+
} else if (contentType?.startsWith("application/json")) {
|
|
133
|
+
parsed = fromJSON(await event.request.json(), {
|
|
134
|
+
plugins: [
|
|
135
|
+
CustomEventPlugin,
|
|
136
|
+
DOMExceptionPlugin,
|
|
137
|
+
EventPlugin,
|
|
138
|
+
FormDataPlugin,
|
|
139
|
+
HeadersPlugin,
|
|
140
|
+
ReadableStreamPlugin,
|
|
141
|
+
RequestPlugin,
|
|
142
|
+
ResponsePlugin,
|
|
143
|
+
URLSearchParamsPlugin,
|
|
144
|
+
URLPlugin,
|
|
145
|
+
],
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
let result = await provideRequestEvent(event, async () => {
|
|
151
|
+
/* @ts-expect-error */
|
|
152
|
+
sharedConfig.context = { event };
|
|
153
|
+
event.locals.serverFunctionMeta = {
|
|
154
|
+
id: functionId,
|
|
155
|
+
};
|
|
156
|
+
return serverFunction(...parsed);
|
|
157
|
+
});
|
|
164
158
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
159
|
+
if (singleFlight && instance) {
|
|
160
|
+
result = await handleSingleFlight(event, result);
|
|
161
|
+
}
|
|
168
162
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
163
|
+
// handle responses
|
|
164
|
+
if (result instanceof Response) {
|
|
165
|
+
if (result.headers && result.headers.has("X-Content-Raw")) return result;
|
|
166
|
+
if (instance) {
|
|
167
|
+
// forward headers
|
|
168
|
+
if (result.headers) mergeResponseHeaders(h3Event, result.headers);
|
|
169
|
+
// forward non-redirect statuses
|
|
170
|
+
if (result.status && (result.status < 300 || result.status >= 400))
|
|
171
|
+
h3Event.res.status = result.status;
|
|
172
|
+
if ((result as any).customBody) {
|
|
173
|
+
result = await (result as any).customBody();
|
|
174
|
+
} else if (result.body == undefined) result = null;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
183
177
|
|
|
184
|
-
|
|
185
|
-
|
|
178
|
+
// handle no JS success case
|
|
179
|
+
if (!instance) return handleNoJS(result, request, parsed);
|
|
186
180
|
|
|
187
|
-
|
|
181
|
+
h3Event.res.headers.set("content-type", "text/javascript");
|
|
188
182
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
h3Event.res.headers.set("X-Error", "true");
|
|
207
|
-
} else if (instance) {
|
|
208
|
-
const error =
|
|
209
|
-
x instanceof Error ? x.message : typeof x === "string" ? x : "true";
|
|
183
|
+
return serializeToStream(instance, result);
|
|
184
|
+
} catch (x) {
|
|
185
|
+
if (x instanceof Response) {
|
|
186
|
+
if (singleFlight && instance) {
|
|
187
|
+
x = await handleSingleFlight(event, x);
|
|
188
|
+
}
|
|
189
|
+
// forward headers
|
|
190
|
+
if ((x as any).headers) mergeResponseHeaders(h3Event, (x as any).headers);
|
|
191
|
+
// forward non-redirect statuses
|
|
192
|
+
if ((x as any).status && (!instance || (x as any).status < 300 || (x as any).status >= 400))
|
|
193
|
+
h3Event.res.status = (x as any).status;
|
|
194
|
+
if ((x as any).customBody) {
|
|
195
|
+
x = (x as any).customBody();
|
|
196
|
+
} else if ((x as any).body === undefined) x = null;
|
|
197
|
+
h3Event.res.headers.set("X-Error", "true");
|
|
198
|
+
} else if (instance) {
|
|
199
|
+
const error = x instanceof Error ? x.message : typeof x === "string" ? x : "true";
|
|
210
200
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
201
|
+
h3Event.res.headers.set("X-Error", error.replace(/[\r\n]+/g, ""));
|
|
202
|
+
} else {
|
|
203
|
+
x = handleNoJS(x, request, parsed, true);
|
|
204
|
+
}
|
|
205
|
+
if (instance) {
|
|
206
|
+
h3Event.res.headers.set("content-type", "text/javascript");
|
|
207
|
+
return serializeToStream(instance, x);
|
|
208
|
+
}
|
|
209
|
+
return x;
|
|
210
|
+
}
|
|
221
211
|
}
|
|
222
212
|
|
|
223
|
-
function handleNoJS(
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
...parsed.slice(0, -1),
|
|
260
|
-
[...parsed[parsed.length - 1].entries()],
|
|
261
|
-
],
|
|
262
|
-
}),
|
|
263
|
-
)}; Secure; HttpOnly;`,
|
|
264
|
-
);
|
|
265
|
-
}
|
|
266
|
-
return new Response(null, {
|
|
267
|
-
status: statusCode,
|
|
268
|
-
headers,
|
|
269
|
-
});
|
|
213
|
+
function handleNoJS(result: any, request: Request, parsed: any[], thrown?: boolean) {
|
|
214
|
+
const url = new URL(request.url);
|
|
215
|
+
const isError = result instanceof Error;
|
|
216
|
+
let statusCode = 302;
|
|
217
|
+
let headers: Headers;
|
|
218
|
+
if (result instanceof Response) {
|
|
219
|
+
headers = new Headers(result.headers);
|
|
220
|
+
if (result.headers.has("Location")) {
|
|
221
|
+
headers.set(
|
|
222
|
+
`Location`,
|
|
223
|
+
new URL(result.headers.get("Location")!, url.origin + import.meta.env.BASE_URL).toString(),
|
|
224
|
+
);
|
|
225
|
+
statusCode = getExpectedRedirectStatus(result);
|
|
226
|
+
}
|
|
227
|
+
} else
|
|
228
|
+
headers = new Headers({
|
|
229
|
+
Location: new URL(request.headers.get("referer")!).toString(),
|
|
230
|
+
});
|
|
231
|
+
if (result) {
|
|
232
|
+
headers.append(
|
|
233
|
+
"Set-Cookie",
|
|
234
|
+
`flash=${encodeURIComponent(
|
|
235
|
+
JSON.stringify({
|
|
236
|
+
url: url.pathname + url.search,
|
|
237
|
+
result: isError ? result.message : result,
|
|
238
|
+
thrown: thrown,
|
|
239
|
+
error: isError,
|
|
240
|
+
input: [...parsed.slice(0, -1), [...parsed[parsed.length - 1].entries()]],
|
|
241
|
+
}),
|
|
242
|
+
)}; Secure; HttpOnly;`,
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
return new Response(null, {
|
|
246
|
+
status: statusCode,
|
|
247
|
+
headers,
|
|
248
|
+
});
|
|
270
249
|
}
|
|
271
250
|
|
|
272
251
|
let App: any;
|
|
273
252
|
function createSingleFlightHeaders(sourceEvent: FetchEvent) {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
253
|
+
// cookie handling logic is pretty simplistic so this might be imperfect
|
|
254
|
+
// unclear if h3 internals are available on all platforms but we need a way to
|
|
255
|
+
// update request headers on the underlying H3 event.
|
|
277
256
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
257
|
+
const headers = sourceEvent.request.headers;
|
|
258
|
+
const cookies = parseCookies(sourceEvent.nativeEvent);
|
|
259
|
+
const SetCookies = sourceEvent.response.headers.getSetCookie();
|
|
260
|
+
headers.delete("cookie");
|
|
261
|
+
// let useH3Internals = false;
|
|
262
|
+
// if (sourceEvent.nativeEvent.node?.req) {
|
|
263
|
+
// useH3Internals = true;
|
|
264
|
+
// sourceEvent.nativeEvent.node.req.headers.cookie = "";
|
|
265
|
+
// }
|
|
266
|
+
SetCookies.forEach(cookie => {
|
|
267
|
+
if (!cookie) return;
|
|
268
|
+
const { maxAge, expires, name, value } = parseSetCookie(cookie);
|
|
269
|
+
if (maxAge != null && maxAge <= 0) {
|
|
270
|
+
delete cookies[name];
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
if (expires != null && expires.getTime() <= Date.now()) {
|
|
274
|
+
delete cookies[name];
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
cookies[name] = value;
|
|
278
|
+
});
|
|
279
|
+
Object.entries(cookies).forEach(([key, value]) => {
|
|
280
|
+
headers.append("cookie", `${key}=${value}`);
|
|
281
|
+
// useH3Internals &&
|
|
282
|
+
// (sourceEvent.nativeEvent.node.req.headers.cookie += `${key}=${value};`);
|
|
283
|
+
});
|
|
305
284
|
|
|
306
|
-
|
|
285
|
+
return headers;
|
|
307
286
|
}
|
|
308
|
-
async function handleSingleFlight(
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
});
|
|
341
|
-
} catch (e) {
|
|
342
|
-
console.log(e);
|
|
343
|
-
}
|
|
287
|
+
async function handleSingleFlight(sourceEvent: FetchEvent, result: any): Promise<Response> {
|
|
288
|
+
let revalidate: string[];
|
|
289
|
+
let url = new URL(sourceEvent.request.headers.get("referer")!).toString();
|
|
290
|
+
if (result instanceof Response) {
|
|
291
|
+
if (result.headers.has("X-Revalidate"))
|
|
292
|
+
revalidate = result.headers.get("X-Revalidate")!.split(",");
|
|
293
|
+
if (result.headers.has("Location"))
|
|
294
|
+
url = new URL(
|
|
295
|
+
result.headers.get("Location")!,
|
|
296
|
+
new URL(sourceEvent.request.url).origin + import.meta.env.BASE_URL,
|
|
297
|
+
).toString();
|
|
298
|
+
}
|
|
299
|
+
const event = { ...sourceEvent } as PageEvent;
|
|
300
|
+
event.request = new Request(url, {
|
|
301
|
+
headers: createSingleFlightHeaders(sourceEvent),
|
|
302
|
+
});
|
|
303
|
+
return await provideRequestEvent(event, async () => {
|
|
304
|
+
await createPageEvent(event);
|
|
305
|
+
App || (App = (await import("solid-start:app")).default);
|
|
306
|
+
/* @ts-expect-error */
|
|
307
|
+
event.router.dataOnly = revalidate || true;
|
|
308
|
+
/* @ts-expect-error */
|
|
309
|
+
event.router.previousUrl = sourceEvent.request.headers.get("referer");
|
|
310
|
+
try {
|
|
311
|
+
renderToString(() => {
|
|
312
|
+
/* @ts-expect-error */
|
|
313
|
+
sharedConfig.context.event = event;
|
|
314
|
+
App();
|
|
315
|
+
});
|
|
316
|
+
} catch (e) {
|
|
317
|
+
console.log(e);
|
|
318
|
+
}
|
|
344
319
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
320
|
+
/* @ts-expect-error */
|
|
321
|
+
const body = event.router.data;
|
|
322
|
+
if (!body) return result;
|
|
323
|
+
let containsKey = false;
|
|
324
|
+
for (const key in body) {
|
|
325
|
+
if (body[key] === undefined) delete body[key];
|
|
326
|
+
else containsKey = true;
|
|
327
|
+
}
|
|
328
|
+
if (!containsKey) return result;
|
|
329
|
+
if (!(result instanceof Response)) {
|
|
330
|
+
body["_$value"] = result;
|
|
331
|
+
result = new Response(null, { status: 200 });
|
|
332
|
+
} else if ((result as any).customBody) {
|
|
333
|
+
body["_$value"] = (result as any).customBody();
|
|
334
|
+
}
|
|
335
|
+
result.customBody = () => body;
|
|
336
|
+
result.headers.set("X-Single-Flight", "true");
|
|
337
|
+
return result;
|
|
338
|
+
});
|
|
364
339
|
}
|