@torpor/build 0.2.0 → 0.3.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 +42 -0
- package/dist/RouteType-g8Ce5gOd.js +107 -0
- package/dist/RouteType-g8Ce5gOd.js.map +1 -0
- package/dist/Server-CSpY_-Ba.d.ts +78 -0
- package/dist/Server-CSpY_-Ba.d.ts.map +1 -0
- package/dist/ServerEvent-2-CnAy1W.js +74 -0
- package/dist/ServerEvent-2-CnAy1W.js.map +1 -0
- package/dist/Site-D4x1l0p5.d.ts +67 -0
- package/dist/Site-D4x1l0p5.d.ts.map +1 -0
- package/dist/_page-Cv6YWocY.js +33 -0
- package/dist/_page-Cv6YWocY.js.map +1 -0
- package/dist/bin/index.d.ts +1 -1
- package/dist/bin/index.js +14 -19
- package/dist/bin/index.js.map +1 -1
- package/dist/connectMiddleware-DbLj0St1.js +252 -0
- package/dist/connectMiddleware-DbLj0St1.js.map +1 -0
- package/dist/index.d.ts +188 -179
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +109 -145
- package/dist/index.js.map +1 -1
- package/dist/nav.d.ts +14 -0
- package/dist/nav.d.ts.map +1 -0
- package/dist/nav.js +206 -0
- package/dist/nav.js.map +1 -0
- package/dist/pathToRegex-CTgx7hQP.js +11 -0
- package/dist/pathToRegex-CTgx7hQP.js.map +1 -0
- package/dist/response-D-XpIuMH.js +307 -0
- package/dist/response-D-XpIuMH.js.map +1 -0
- package/dist/response.d.ts +336 -151
- package/dist/response.d.ts.map +1 -0
- package/dist/response.js +4 -37
- package/dist/run-CVKpO0HO.js +331 -0
- package/dist/run-CVKpO0HO.js.map +1 -0
- package/dist/run.d.ts +11 -8
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +8 -18
- package/dist/seeOther-BmehiI4C.js +110 -0
- package/dist/seeOther-BmehiI4C.js.map +1 -0
- package/dist/server.d.ts +12 -11
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +5 -18
- package/dist/state.d.ts +14 -10
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +3 -7
- package/dist/test.d.ts +12 -11
- package/dist/test.d.ts.map +1 -0
- package/dist/test.js +152 -225
- package/dist/test.js.map +1 -1
- package/package.json +25 -29
- package/src/bin/index.ts +9 -11
- package/src/index.ts +3 -0
- package/src/nav/formSubmit.ts +48 -0
- package/src/nav/load.ts +9 -0
- package/src/nav/loadData.ts +121 -0
- package/src/nav/navigate.ts +163 -0
- package/src/nav/reload.ts +9 -0
- package/src/nav.ts +4 -0
- package/src/response/badRequest.ts +9 -4
- package/src/response/created.ts +10 -3
- package/src/response/forbidden.ts +11 -4
- package/src/response/found.ts +30 -0
- package/src/response/methodNotAllowed.ts +8 -4
- package/src/response/movedPermanently.ts +25 -0
- package/src/response/notFound.ts +14 -7
- package/src/response/notModified.ts +24 -4
- package/src/response/ok.ts +19 -10
- package/src/response/permanentRedirect.ts +30 -0
- package/src/response/seeOther.ts +9 -3
- package/src/response/serverError.ts +14 -2
- package/src/response/temporaryRedirect.ts +31 -0
- package/src/response/unauthorized.ts +11 -4
- package/src/response/unprocessable.ts +8 -2
- package/src/response.ts +8 -4
- package/src/{site → run}/prepareTemplate.ts +1 -1
- package/src/{site → run}/run.ts +1 -1
- package/src/{site → run}/runBuild.ts +2 -2
- package/src/{site → run}/runDev.ts +2 -2
- package/src/{site → run}/runPreview.ts +1 -1
- package/src/run.ts +4 -4
- package/src/server/Routerx.ts +3 -3
- package/src/server/Server.ts +3 -3
- package/src/server/connect/connectMiddleware.ts +2 -1
- package/src/server/connect/nodeMessageToNodeResponse.ts +2 -2
- package/src/site/Router.ts +3 -3
- package/src/site/clientEntry.ts +16 -269
- package/src/site/defaultAdapter.ts +1 -1
- package/src/site/serverEntry.ts +86 -45
- package/src/state/$page.ts +3 -12
- package/src/state/client.ts +6 -0
- package/src/state/internal.ts +45 -0
- package/src/test/runTest.ts +1 -1
- package/src/types/Adapter.ts +2 -4
- package/src/types/ClientState.ts +8 -0
- package/src/types/InternalState.ts +7 -0
- package/src/types/LayoutHandler.ts +2 -4
- package/src/types/LayoutPath.ts +10 -0
- package/src/types/ManifestRoute.ts +2 -4
- package/src/types/PageEndPoint.ts +2 -4
- package/src/types/PageLoadEvent.ts +2 -4
- package/src/types/PageServerEndPoint.ts +2 -4
- package/src/types/PageState.ts +8 -0
- package/src/types/RouteHandler.ts +2 -4
- package/src/types/RouteLayoutHandler.ts +2 -4
- package/src/types/RouteMatchResult.ts +2 -4
- package/src/types/ServerHook.ts +3 -7
- package/src/types/ServerLoadEvent.ts +2 -4
- package/src/{site → utils}/pathToRegex.ts +1 -1
- package/{tsup.config.ts → tsdown.config.ts} +3 -4
- package/dist/Server-CNZWh5ca.d.cts +0 -71
- package/dist/Server-CNZWh5ca.d.ts +0 -71
- package/dist/Site-C2020GV_.d.ts +0 -63
- package/dist/Site-DQojGpE-.d.cts +0 -63
- package/dist/bin/index.cjs +0 -778
- package/dist/bin/index.cjs.map +0 -1
- package/dist/bin/index.d.cts +0 -1
- package/dist/chunk-565UOT3F.js +0 -18
- package/dist/chunk-565UOT3F.js.map +0 -1
- package/dist/chunk-B2UNTYN5.js +0 -68
- package/dist/chunk-B2UNTYN5.js.map +0 -1
- package/dist/chunk-CZHJQCPI.js +0 -286
- package/dist/chunk-CZHJQCPI.js.map +0 -1
- package/dist/chunk-PTVHEJZ5.js +0 -152
- package/dist/chunk-PTVHEJZ5.js.map +0 -1
- package/dist/chunk-SJVHHGVW.js +0 -13
- package/dist/chunk-SJVHHGVW.js.map +0 -1
- package/dist/chunk-TDOXEXG6.js +0 -85
- package/dist/chunk-TDOXEXG6.js.map +0 -1
- package/dist/chunk-WVXAN4IV.js +0 -50
- package/dist/chunk-WVXAN4IV.js.map +0 -1
- package/dist/chunk-YRBEYKQM.js +0 -372
- package/dist/chunk-YRBEYKQM.js.map +0 -1
- package/dist/index.cjs +0 -322
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -199
- package/dist/metafile-cjs.json +0 -1
- package/dist/metafile-esm.json +0 -1
- package/dist/response.cjs +0 -150
- package/dist/response.cjs.map +0 -1
- package/dist/response.d.cts +0 -166
- package/dist/response.js.map +0 -1
- package/dist/run.cjs +0 -787
- package/dist/run.cjs.map +0 -1
- package/dist/run.d.cts +0 -14
- package/dist/run.js.map +0 -1
- package/dist/server.cjs +0 -398
- package/dist/server.cjs.map +0 -1
- package/dist/server.d.cts +0 -17
- package/dist/server.js.map +0 -1
- package/dist/state.cjs +0 -44
- package/dist/state.cjs.map +0 -1
- package/dist/state.d.cts +0 -11
- package/dist/state.js.map +0 -1
- package/dist/test.cjs +0 -538
- package/dist/test.cjs.map +0 -1
- package/dist/test.d.cts +0 -15
- package/src/response/moved.ts +0 -16
- package/src/response/redirect.ts +0 -17
- package/src/state/Page.ts +0 -8
package/src/site/serverEntry.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import manifest from "@torpor/build/manifest";
|
|
2
|
-
// @ts-ignore This errors in the Cloudflare build?
|
|
3
|
-
import { $page } from "@torpor/build/state";
|
|
4
2
|
import { type ServerComponent, type ServerSlotRender } from "@torpor/view";
|
|
5
3
|
import notFound from "../response/notFound.ts";
|
|
6
4
|
import ok from "../response/ok.ts";
|
|
7
5
|
import seeOther from "../response/seeOther.ts";
|
|
8
6
|
import ServerEvent from "../server/ServerEvent.ts";
|
|
7
|
+
import $page from "../state/$page";
|
|
9
8
|
import type PageEndPoint from "../types/PageEndPoint.ts";
|
|
10
9
|
import type PageServerEndPoint from "../types/PageServerEndPoint.ts";
|
|
11
|
-
import RouteHandler from "../types/RouteHandler.ts";
|
|
10
|
+
import type RouteHandler from "../types/RouteHandler.ts";
|
|
12
11
|
import {
|
|
13
12
|
ERROR_ROUTE,
|
|
14
13
|
HOOK_ROUTE,
|
|
@@ -30,35 +29,7 @@ router.addPages(manifest.routes);
|
|
|
30
29
|
|
|
31
30
|
//console.log(`routes:\n ${router.routes.map((r) => r.path).join("\n ")}`);
|
|
32
31
|
|
|
33
|
-
async function handleResponse(response: Response): Promise<Response> {
|
|
34
|
-
$page.status = response.status;
|
|
35
|
-
|
|
36
|
-
// Success codes and redirect codes are acceptable
|
|
37
|
-
if (response.status >= 200 && response.status <= 399) {
|
|
38
|
-
return response;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// It's an error, so redirect to the error page
|
|
42
|
-
// We're just pushing the status and message in the URL, but maybe there's a
|
|
43
|
-
// more sophisticated way to do this?
|
|
44
|
-
// TODO: Should be returning loadView rather than redirecting
|
|
45
|
-
// TODO: Should be returning the NEAREST error page to this path, including layouts
|
|
46
|
-
let params = new URLSearchParams();
|
|
47
|
-
params.append("status", $page.status.toString());
|
|
48
|
-
let message = await response.text();
|
|
49
|
-
if (response.headers.get("Content-Type")?.includes("application/json")) {
|
|
50
|
-
const data = JSON.parse(message);
|
|
51
|
-
message = data.message ?? message;
|
|
52
|
-
}
|
|
53
|
-
if (message) {
|
|
54
|
-
$page.error.message = message;
|
|
55
|
-
params.append("message", message);
|
|
56
|
-
}
|
|
57
|
-
return seeOther(`/_error?${params.toString()}`);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
32
|
export async function load(ev: ServerEvent, template: string): Promise<Response> {
|
|
61
|
-
//const url = new URL(`http://${process.env.HOST ?? "localhost"}${ev.request.url}`);
|
|
62
33
|
const url = new URL(ev.request.url);
|
|
63
34
|
const path = url.pathname;
|
|
64
35
|
const query = url.searchParams;
|
|
@@ -69,19 +40,18 @@ export async function load(ev: ServerEvent, template: string): Promise<Response>
|
|
|
69
40
|
if (!route) {
|
|
70
41
|
return handleResponse(notFound());
|
|
71
42
|
}
|
|
43
|
+
const handler = route.handler;
|
|
44
|
+
const params = route.params || {};
|
|
72
45
|
|
|
73
46
|
// Update $page before building the components
|
|
74
47
|
$page.url = url;
|
|
75
48
|
if (path.endsWith("/_error")) {
|
|
76
49
|
$page.status = parseInt(query.get("status") ?? "404");
|
|
77
|
-
$page.error
|
|
50
|
+
$page.error = { message: query.get("message") ?? "" };
|
|
78
51
|
} else {
|
|
79
52
|
$page.status = 200;
|
|
80
53
|
}
|
|
81
54
|
|
|
82
|
-
const handler = route.handler;
|
|
83
|
-
const params = route.params || {};
|
|
84
|
-
|
|
85
55
|
// TODO: Hit the server hook out here
|
|
86
56
|
// We could maybe set data loading up as middleware on a route??????
|
|
87
57
|
|
|
@@ -92,7 +62,7 @@ export async function load(ev: ServerEvent, template: string): Promise<Response>
|
|
|
92
62
|
if (ev.request.method === "GET") {
|
|
93
63
|
return handleResponse(await loadView(ev, url, handler, params, template));
|
|
94
64
|
} else if (ev.request.method === "POST") {
|
|
95
|
-
return handleResponse(await runAction(ev, url, handler, params, query));
|
|
65
|
+
return handleResponse(await runAction(ev, url, handler, params, query, template), true);
|
|
96
66
|
}
|
|
97
67
|
break;
|
|
98
68
|
}
|
|
@@ -121,6 +91,42 @@ export async function load(ev: ServerEvent, template: string): Promise<Response>
|
|
|
121
91
|
return notFound();
|
|
122
92
|
}
|
|
123
93
|
|
|
94
|
+
async function handleResponse(response: Response, fromForm = false): Promise<Response> {
|
|
95
|
+
$page.status = response.status;
|
|
96
|
+
|
|
97
|
+
// Success codes and redirect codes are acceptable
|
|
98
|
+
if (response.status >= 200 && response.status <= 399) {
|
|
99
|
+
return response;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// 4xx error codes are acceptable from form actions
|
|
103
|
+
if (fromForm && response.status >= 400 && response.status <= 499) {
|
|
104
|
+
return response;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// It's an error, so redirect to the error page
|
|
108
|
+
// We're just pushing the status and message in the URL, but maybe there's a
|
|
109
|
+
// more sophisticated way to do this?
|
|
110
|
+
// TODO: Should be returning loadView rather than redirecting
|
|
111
|
+
// TODO: Should be returning the NEAREST error page to this path, including layouts
|
|
112
|
+
let params = new URLSearchParams();
|
|
113
|
+
params.append("status", $page.status.toString());
|
|
114
|
+
let message = await response.text();
|
|
115
|
+
if (response.headers.get("Content-Type")?.includes("application/json")) {
|
|
116
|
+
const data = JSON.parse(message);
|
|
117
|
+
message = data.message ?? message;
|
|
118
|
+
}
|
|
119
|
+
if (message) {
|
|
120
|
+
if ($page.error) {
|
|
121
|
+
$page.error.message = message;
|
|
122
|
+
} else {
|
|
123
|
+
$page.error = { message };
|
|
124
|
+
}
|
|
125
|
+
params.append("message", message);
|
|
126
|
+
}
|
|
127
|
+
return seeOther(`/_error?${params.toString()}`);
|
|
128
|
+
}
|
|
129
|
+
|
|
124
130
|
async function loadData(
|
|
125
131
|
ev: ServerEvent,
|
|
126
132
|
url: URL,
|
|
@@ -155,6 +161,8 @@ async function loadView(
|
|
|
155
161
|
handler: RouteHandler,
|
|
156
162
|
params: Record<string, string>,
|
|
157
163
|
template: string,
|
|
164
|
+
formStatus?: number,
|
|
165
|
+
form?: Record<string, string>,
|
|
158
166
|
) {
|
|
159
167
|
// There must be a client endpoint with a component
|
|
160
168
|
const clientEndPoint: PageEndPoint | undefined = (await handler.endPoint()).default;
|
|
@@ -209,7 +217,7 @@ async function loadView(
|
|
|
209
217
|
if (endPointResponse?.ok === false) {
|
|
210
218
|
return endPointResponse;
|
|
211
219
|
}
|
|
212
|
-
let $props: Record<string, any> = { data };
|
|
220
|
+
let $props: Record<string, any> = { data, form };
|
|
213
221
|
|
|
214
222
|
let styles = "";
|
|
215
223
|
|
|
@@ -217,7 +225,6 @@ async function loadView(
|
|
|
217
225
|
// the default slot of its parent
|
|
218
226
|
// TODO: Also handle layout server data
|
|
219
227
|
// TODO: There's probably a nicer way to do this with reducers or something
|
|
220
|
-
// TODO: Re-use parent layouts
|
|
221
228
|
let component = clientEndPoint.component as ServerComponent;
|
|
222
229
|
let slots: Record<string, ServerSlotRender> | undefined = undefined;
|
|
223
230
|
if (handler.layouts) {
|
|
@@ -250,6 +257,12 @@ async function loadView(
|
|
|
250
257
|
let html;
|
|
251
258
|
try {
|
|
252
259
|
let { body, head } = component($props, undefined, slots);
|
|
260
|
+
|
|
261
|
+
// Put the form info in a hidden input so that it can be accessed on the client
|
|
262
|
+
if (form) {
|
|
263
|
+
body += `\n<input type="hidden" id="t-form-data" value='${JSON.stringify(form).replaceAll("'", "\\'")}' />`;
|
|
264
|
+
}
|
|
265
|
+
|
|
253
266
|
styles += head;
|
|
254
267
|
html = template.replace("%COMPONENT_BODY%", body).replace("%COMPONENT_HEAD%", styles);
|
|
255
268
|
} catch (error) {
|
|
@@ -259,7 +272,7 @@ async function loadView(
|
|
|
259
272
|
}
|
|
260
273
|
|
|
261
274
|
return new Response(html, {
|
|
262
|
-
status: 200,
|
|
275
|
+
status: formStatus ?? 200,
|
|
263
276
|
headers: {
|
|
264
277
|
"Content-Type": "text/html",
|
|
265
278
|
},
|
|
@@ -272,6 +285,7 @@ async function runAction(
|
|
|
272
285
|
handler: RouteHandler,
|
|
273
286
|
params: Record<string, string>,
|
|
274
287
|
query: URLSearchParams,
|
|
288
|
+
template: string,
|
|
275
289
|
) {
|
|
276
290
|
const actionName = (Array.from(query.keys())[0] || "default").replace(/^\//, "");
|
|
277
291
|
const serverEndPoint: PageServerEndPoint | undefined =
|
|
@@ -279,7 +293,6 @@ async function runAction(
|
|
|
279
293
|
if (serverEndPoint?.actions) {
|
|
280
294
|
const action = serverEndPoint.actions[actionName];
|
|
281
295
|
if (action) {
|
|
282
|
-
// TODO: form.errors etc
|
|
283
296
|
const serverParams = buildServerParams(ev, url, params);
|
|
284
297
|
|
|
285
298
|
if (handler.serverHook) {
|
|
@@ -289,14 +302,42 @@ async function runAction(
|
|
|
289
302
|
}
|
|
290
303
|
}
|
|
291
304
|
|
|
292
|
-
|
|
305
|
+
let result = await action(serverParams);
|
|
306
|
+
|
|
307
|
+
if (ev.request.headers.has("x-torpor-form-submit")) {
|
|
308
|
+
// If the form was submitted from javascript, just return the
|
|
309
|
+
// response and it will be handled on the client
|
|
310
|
+
// TODO: Should we make the user return a response??
|
|
311
|
+
result ??= ok();
|
|
312
|
+
|
|
313
|
+
// If it's a redirect, we need to stop the browser handling it
|
|
314
|
+
if (result.status >= 300 && result.status <= 399) {
|
|
315
|
+
const location = result.headers.get("location") ?? "";
|
|
316
|
+
result = ok();
|
|
317
|
+
result.headers.set("x-torpor-form-redirect", "");
|
|
318
|
+
result.headers.set("location", location);
|
|
319
|
+
}
|
|
293
320
|
|
|
294
|
-
// Return the response if it was not ok (i.e. errors or a redirect)
|
|
295
|
-
// Otherwise, reload the page by redirecting
|
|
296
|
-
if (result && !result.ok) {
|
|
297
321
|
return result;
|
|
322
|
+
} else if (
|
|
323
|
+
!result ||
|
|
324
|
+
(result.status >= 200 && result.status <= 299) ||
|
|
325
|
+
(result.status >= 400 && result.status <= 499)
|
|
326
|
+
) {
|
|
327
|
+
// If the form was submitted without javascript, and there was
|
|
328
|
+
// no result, an ok result, or a 4xx error, re-render the view
|
|
329
|
+
// with the form result
|
|
330
|
+
// TODO: do not re-run hooks?
|
|
331
|
+
const newUrl = new URL(url.pathname, url);
|
|
332
|
+
const formStatus = result?.status;
|
|
333
|
+
const form = await result?.json();
|
|
334
|
+
$page.form = form;
|
|
335
|
+
return await loadView(ev, newUrl, handler, params, template, formStatus, form);
|
|
298
336
|
} else {
|
|
299
|
-
|
|
337
|
+
// If the form was submitted without javascript and there was a
|
|
338
|
+
// redirect or server error, just return the result to handle it
|
|
339
|
+
// as normal
|
|
340
|
+
return result;
|
|
300
341
|
}
|
|
301
342
|
}
|
|
302
343
|
}
|
package/src/state/$page.ts
CHANGED
|
@@ -1,15 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import type PageState from "../types/PageState";
|
|
2
|
+
import internal from "./internal";
|
|
3
3
|
|
|
4
|
-
const $page:
|
|
5
|
-
{
|
|
6
|
-
status: 404,
|
|
7
|
-
url: new URL("http://localhost"),
|
|
8
|
-
error: {
|
|
9
|
-
message: "",
|
|
10
|
-
},
|
|
11
|
-
},
|
|
12
|
-
{ shallow: true },
|
|
13
|
-
);
|
|
4
|
+
const $page: PageState = internal().$page;
|
|
14
5
|
|
|
15
6
|
export default $page;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { $watch } from "@torpor/view";
|
|
2
|
+
import type ClientState from "../types/ClientState";
|
|
3
|
+
import type InternalState from "../types/InternalState";
|
|
4
|
+
import type PageState from "../types/PageState";
|
|
5
|
+
|
|
6
|
+
// Do a weird little dance to ensure that everyone has the same $page and
|
|
7
|
+
// client, regardless of if they are entering via serverEntry/clientEntry or the
|
|
8
|
+
// built library. There may be an easier way to do this!
|
|
9
|
+
|
|
10
|
+
const INTERNAL_GLOBAL: unique symbol = Symbol.for("torpor-internal");
|
|
11
|
+
|
|
12
|
+
export default function internal(): InternalState {
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
if (globalThis[INTERNAL_GLOBAL] === undefined) {
|
|
15
|
+
// TODO: Should use the SSR $watch if entering via serverEntry
|
|
16
|
+
const $page: PageState = $watch(
|
|
17
|
+
{
|
|
18
|
+
status: 404,
|
|
19
|
+
url: new URL("http://localhost"),
|
|
20
|
+
form: undefined,
|
|
21
|
+
error: {
|
|
22
|
+
message: "",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
shallow: true,
|
|
27
|
+
},
|
|
28
|
+
);
|
|
29
|
+
const client: ClientState = {
|
|
30
|
+
// @ts-ignore This will definitely, 100% get set
|
|
31
|
+
router: null,
|
|
32
|
+
layoutStack: [],
|
|
33
|
+
// TODO: Probably expire after 30 seconds or something?
|
|
34
|
+
prefetchedData: {},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// @ts-ignore
|
|
38
|
+
globalThis[INTERNAL_GLOBAL] = {
|
|
39
|
+
$page,
|
|
40
|
+
client,
|
|
41
|
+
} satisfies InternalState;
|
|
42
|
+
}
|
|
43
|
+
// @ts-ignore
|
|
44
|
+
return globalThis[INTERNAL_GLOBAL] as InternalState;
|
|
45
|
+
}
|
package/src/test/runTest.ts
CHANGED
|
@@ -9,7 +9,7 @@ import Site from "../site/Site";
|
|
|
9
9
|
import $page from "../state/$page.ts";
|
|
10
10
|
import type PageEndPoint from "../types/PageEndPoint.ts";
|
|
11
11
|
import type PageServerEndPoint from "../types/PageServerEndPoint.ts";
|
|
12
|
-
import RouteHandler from "../types/RouteHandler.ts";
|
|
12
|
+
import type RouteHandler from "../types/RouteHandler.ts";
|
|
13
13
|
import {
|
|
14
14
|
HOOK_ROUTE,
|
|
15
15
|
HOOK_SERVER_ROUTE,
|
package/src/types/Adapter.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import Server from "../server/Server";
|
|
2
2
|
import Site from "../site/Site";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
export default interface Adapter {
|
|
5
5
|
prebuild?: (site: Site) => Promise<void> | void;
|
|
6
6
|
postbuild?: (site: Site) => Promise<void> | void;
|
|
7
7
|
serve: (server: Server, site: Site) => void;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export default Adapter;
|
|
8
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Store the current layout stack, so that we can re-use parts of it as necessary
|
|
2
|
+
export default interface LayoutPath {
|
|
3
|
+
path: string;
|
|
4
|
+
/** Whether to re-use this layout */
|
|
5
|
+
reuse: boolean;
|
|
6
|
+
/** Data loaded from endpoints that should be re-used */
|
|
7
|
+
data: any;
|
|
8
|
+
/** The range of the UI in this layout's slot */
|
|
9
|
+
slotRange: any;
|
|
10
|
+
}
|
|
@@ -4,7 +4,7 @@ import type PageLoadEvent from "./PageLoadEvent";
|
|
|
4
4
|
/**
|
|
5
5
|
* For +page.
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
export default interface PageEndPoint {
|
|
8
8
|
/**
|
|
9
9
|
* Builds the route path for the page in a type-safe manner.
|
|
10
10
|
* TODO: Not sure this is actually the best way to do it...
|
|
@@ -25,9 +25,7 @@ type PageEndPoint = {
|
|
|
25
25
|
* The head element data for the page, which may include a <title> and <meta> elements.
|
|
26
26
|
*/
|
|
27
27
|
head?: HeadElement[] | ((event: PageLoadEvent) => HeadElement[]);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export default PageEndPoint;
|
|
28
|
+
}
|
|
31
29
|
|
|
32
30
|
type HeadElement = TitleElement | MetaElement;
|
|
33
31
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
export default interface PageLoadEvent {
|
|
2
2
|
/**
|
|
3
3
|
* The URL for the server function.
|
|
4
4
|
*/
|
|
@@ -11,6 +11,4 @@ type PageLoadEvent = {
|
|
|
11
11
|
* Data that is (optionally) loaded from the load function and passed into the page as $props.data.
|
|
12
12
|
*/
|
|
13
13
|
data: Record<string, any>;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export default PageLoadEvent;
|
|
14
|
+
}
|
|
@@ -4,7 +4,7 @@ import type PageServerLoad from "./PageServerLoad";
|
|
|
4
4
|
/**
|
|
5
5
|
* For +page.server.
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
export default interface PageServerEndPoint {
|
|
8
8
|
/**
|
|
9
9
|
* Loads data from the server for a page.
|
|
10
10
|
*/
|
|
@@ -13,6 +13,4 @@ type PageServerEndPoint = {
|
|
|
13
13
|
* A map of actions that can be performed on the server for a page, generally from a form submit.
|
|
14
14
|
*/
|
|
15
15
|
actions?: Record<string, PageServerAction>;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export default PageServerEndPoint;
|
|
16
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type RouteLayoutHandler from "./RouteLayoutHandler";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
export default interface RouteHandler {
|
|
4
4
|
path: string;
|
|
5
5
|
type: number;
|
|
6
6
|
endPoint: () => Promise<any>;
|
|
@@ -9,6 +9,4 @@ type RouteHandler = {
|
|
|
9
9
|
layouts?: RouteLayoutHandler[];
|
|
10
10
|
serverEndPoint?: () => Promise<any>;
|
|
11
11
|
serverHook?: () => Promise<any>;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export default RouteHandler;
|
|
12
|
+
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import type RouteHandler from "./RouteHandler";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
export default interface RouteMatchResult {
|
|
4
4
|
handler: RouteHandler;
|
|
5
5
|
params?: Record<string, string>;
|
|
6
6
|
query?: Record<string, string>;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export default RouteMatchResult;
|
|
7
|
+
}
|
package/src/types/ServerHook.ts
CHANGED
|
@@ -3,13 +3,9 @@ import type ServerLoadEvent from "./ServerLoadEvent";
|
|
|
3
3
|
/**
|
|
4
4
|
* For _hook.server.
|
|
5
5
|
*/
|
|
6
|
-
|
|
6
|
+
export default interface ServerHook {
|
|
7
7
|
/**
|
|
8
8
|
* Called on each server request.
|
|
9
9
|
*/
|
|
10
|
-
handle?:
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export default ServerHook;
|
|
14
|
-
|
|
15
|
-
type ServerLoad = (event: ServerLoadEvent) => Promise<void> | void;
|
|
10
|
+
handle?: (event: ServerLoadEvent) => Promise<void> | void;
|
|
11
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import CookieHelper from "../server/CookieHelper";
|
|
2
2
|
import HeaderHelper from "../server/HeaderHelper";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
export default interface ServerLoadEvent {
|
|
5
5
|
/**
|
|
6
6
|
* The URL for the server function.
|
|
7
7
|
*/
|
|
@@ -34,6 +34,4 @@ type ServerLoadEvent = {
|
|
|
34
34
|
* An optional adapter object, containing adapter-specific functionality.
|
|
35
35
|
*/
|
|
36
36
|
adapter: Record<PropertyKey, any>;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export default ServerLoadEvent;
|
|
37
|
+
}
|
|
@@ -4,7 +4,7 @@ export default function pathToRegex(path: string): RegExp {
|
|
|
4
4
|
.split("/")
|
|
5
5
|
// Replace `[slug]` with a grouped match so we can pull out params
|
|
6
6
|
.map((p) => {
|
|
7
|
-
return p.replace(/\[([
|
|
7
|
+
return p.replace(/\[([^/]+?)\]/, "(?<$1>[^\\/]+?)");
|
|
8
8
|
})
|
|
9
9
|
.join("\\/")
|
|
10
10
|
// Replace globs with regex syntax
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Options, defineConfig } from "
|
|
1
|
+
import { type Options, defineConfig } from "tsdown";
|
|
2
2
|
|
|
3
3
|
type Config =
|
|
4
4
|
| Options
|
|
@@ -8,6 +8,7 @@ type Config =
|
|
|
8
8
|
export default defineConfig({
|
|
9
9
|
entry: [
|
|
10
10
|
"src/index.ts",
|
|
11
|
+
"src/nav.ts",
|
|
11
12
|
"src/response.ts",
|
|
12
13
|
"src/run.ts",
|
|
13
14
|
"src/server.ts",
|
|
@@ -15,10 +16,8 @@ export default defineConfig({
|
|
|
15
16
|
"src/test.ts",
|
|
16
17
|
"src/bin/index.ts",
|
|
17
18
|
],
|
|
18
|
-
format:
|
|
19
|
+
format: "esm",
|
|
19
20
|
dts: true,
|
|
20
|
-
clean: true,
|
|
21
|
-
metafile: true,
|
|
22
21
|
sourcemap: true,
|
|
23
22
|
// Put this in here to stop issues with bundling Vite from bin/index.ts
|
|
24
23
|
// I'm not sure if this will cause further issues down the line?
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { SerializeOptions } from 'cookie';
|
|
2
|
-
|
|
3
|
-
declare class CookieHelper {
|
|
4
|
-
request: Request;
|
|
5
|
-
cookies: Map<string, string>;
|
|
6
|
-
constructor(request: Request);
|
|
7
|
-
get(name: string): string | undefined;
|
|
8
|
-
set(name: string, value: string, options?: SerializeOptions): void;
|
|
9
|
-
delete(name: string, options?: SerializeOptions): void;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
declare class HeaderHelper {
|
|
13
|
-
request: Request;
|
|
14
|
-
headers: Map<string, string>;
|
|
15
|
-
constructor(request: Request);
|
|
16
|
-
get(name: string): string | undefined;
|
|
17
|
-
set(name: string, value: string): void;
|
|
18
|
-
delete(name: string): void;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
declare class ServerEvent {
|
|
22
|
-
request: Request;
|
|
23
|
-
response: Response | undefined | void;
|
|
24
|
-
params?: Record<string, string>;
|
|
25
|
-
adapter: any;
|
|
26
|
-
cookies: CookieHelper;
|
|
27
|
-
headers: HeaderHelper;
|
|
28
|
-
constructor(request: Request, params?: Record<string, string>);
|
|
29
|
-
addHeaders(): void;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
type MiddlewareFunction = (ev: ServerEvent, next: () => void | Promise<void>) => void | Promise<void>;
|
|
33
|
-
|
|
34
|
-
type ServerFunction = (e: ServerEvent) => Response | undefined | void | Promise<Response | undefined | void>;
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* A Fetch API Request/Response server.
|
|
38
|
-
*/
|
|
39
|
-
declare class Server {
|
|
40
|
-
#private;
|
|
41
|
-
routes: RouteHandler[];
|
|
42
|
-
middleware: MiddlewareFunction[];
|
|
43
|
-
constructor();
|
|
44
|
-
/**
|
|
45
|
-
* The standard Fetch API method that should work in any runtime (including
|
|
46
|
-
* Node with polyfills).
|
|
47
|
-
* @returns
|
|
48
|
-
*/
|
|
49
|
-
fetch: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
50
|
-
/**
|
|
51
|
-
* Adds a server function at a route path.
|
|
52
|
-
* @param path The route path pattern.
|
|
53
|
-
* @param fn The function to call when the pattern is matched.
|
|
54
|
-
* @returns
|
|
55
|
-
*/
|
|
56
|
-
add(path: string, fn: ServerFunction): Server;
|
|
57
|
-
match(path: string): Match | undefined;
|
|
58
|
-
use(...fn: MiddlewareFunction[]): Server;
|
|
59
|
-
}
|
|
60
|
-
declare class RouteHandler {
|
|
61
|
-
path: string;
|
|
62
|
-
regex: RegExp;
|
|
63
|
-
fn: ServerFunction;
|
|
64
|
-
constructor(path: string, fn: ServerFunction);
|
|
65
|
-
}
|
|
66
|
-
type Match = {
|
|
67
|
-
fn: ServerFunction;
|
|
68
|
-
params?: Record<string, string>;
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
export { CookieHelper as C, HeaderHelper as H, type MiddlewareFunction as M, Server as S, ServerEvent as a };
|