@torpor/build 0.2.0 → 0.3.0

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.
Files changed (157) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/RouteType-g8Ce5gOd.js +107 -0
  3. package/dist/RouteType-g8Ce5gOd.js.map +1 -0
  4. package/dist/Server-CSpY_-Ba.d.ts +78 -0
  5. package/dist/Server-CSpY_-Ba.d.ts.map +1 -0
  6. package/dist/ServerEvent-2-CnAy1W.js +74 -0
  7. package/dist/ServerEvent-2-CnAy1W.js.map +1 -0
  8. package/dist/Site-D4x1l0p5.d.ts +67 -0
  9. package/dist/Site-D4x1l0p5.d.ts.map +1 -0
  10. package/dist/_page-CsdPubw4.js +33 -0
  11. package/dist/_page-CsdPubw4.js.map +1 -0
  12. package/dist/bin/index.d.ts +1 -1
  13. package/dist/bin/index.js +14 -19
  14. package/dist/bin/index.js.map +1 -1
  15. package/dist/connectMiddleware-DbLj0St1.js +252 -0
  16. package/dist/connectMiddleware-DbLj0St1.js.map +1 -0
  17. package/dist/index.d.ts +188 -179
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +109 -145
  20. package/dist/index.js.map +1 -1
  21. package/dist/nav.d.ts +14 -0
  22. package/dist/nav.d.ts.map +1 -0
  23. package/dist/nav.js +184 -0
  24. package/dist/nav.js.map +1 -0
  25. package/dist/pathToRegex-CTgx7hQP.js +11 -0
  26. package/dist/pathToRegex-CTgx7hQP.js.map +1 -0
  27. package/dist/response-D-XpIuMH.js +307 -0
  28. package/dist/response-D-XpIuMH.js.map +1 -0
  29. package/dist/response.d.ts +336 -151
  30. package/dist/response.d.ts.map +1 -0
  31. package/dist/response.js +4 -37
  32. package/dist/run-CNdaKSPR.js +331 -0
  33. package/dist/run-CNdaKSPR.js.map +1 -0
  34. package/dist/run.d.ts +11 -8
  35. package/dist/run.d.ts.map +1 -0
  36. package/dist/run.js +8 -18
  37. package/dist/seeOther-BmehiI4C.js +110 -0
  38. package/dist/seeOther-BmehiI4C.js.map +1 -0
  39. package/dist/server.d.ts +12 -11
  40. package/dist/server.d.ts.map +1 -0
  41. package/dist/server.js +5 -18
  42. package/dist/state.d.ts +14 -10
  43. package/dist/state.d.ts.map +1 -0
  44. package/dist/state.js +3 -7
  45. package/dist/test.d.ts +12 -11
  46. package/dist/test.d.ts.map +1 -0
  47. package/dist/test.js +152 -225
  48. package/dist/test.js.map +1 -1
  49. package/package.json +25 -29
  50. package/src/bin/index.ts +9 -11
  51. package/src/index.ts +3 -0
  52. package/src/nav/load.ts +9 -0
  53. package/src/nav/loadData.ts +121 -0
  54. package/src/nav/navigate.ts +154 -0
  55. package/src/nav/reload.ts +9 -0
  56. package/src/nav.ts +4 -0
  57. package/src/response/badRequest.ts +9 -4
  58. package/src/response/created.ts +10 -3
  59. package/src/response/forbidden.ts +11 -4
  60. package/src/response/found.ts +30 -0
  61. package/src/response/methodNotAllowed.ts +8 -4
  62. package/src/response/movedPermanently.ts +25 -0
  63. package/src/response/notFound.ts +14 -7
  64. package/src/response/notModified.ts +24 -4
  65. package/src/response/ok.ts +19 -10
  66. package/src/response/permanentRedirect.ts +30 -0
  67. package/src/response/seeOther.ts +9 -3
  68. package/src/response/serverError.ts +14 -2
  69. package/src/response/temporaryRedirect.ts +31 -0
  70. package/src/response/unauthorized.ts +11 -4
  71. package/src/response/unprocessable.ts +8 -2
  72. package/src/response.ts +8 -4
  73. package/src/{site → run}/prepareTemplate.ts +1 -1
  74. package/src/{site → run}/run.ts +1 -1
  75. package/src/{site → run}/runBuild.ts +2 -2
  76. package/src/{site → run}/runDev.ts +2 -2
  77. package/src/{site → run}/runPreview.ts +1 -1
  78. package/src/run.ts +4 -4
  79. package/src/server/Routerx.ts +3 -3
  80. package/src/server/Server.ts +3 -3
  81. package/src/server/connect/connectMiddleware.ts +2 -1
  82. package/src/server/connect/nodeMessageToNodeResponse.ts +2 -2
  83. package/src/site/Router.ts +3 -3
  84. package/src/site/clientEntry.ts +11 -269
  85. package/src/site/defaultAdapter.ts +1 -1
  86. package/src/site/serverEntry.ts +67 -44
  87. package/src/state/$page.ts +3 -12
  88. package/src/state/client.ts +6 -0
  89. package/src/state/internal.ts +45 -0
  90. package/src/test/runTest.ts +1 -1
  91. package/src/types/Adapter.ts +2 -4
  92. package/src/types/ClientState.ts +8 -0
  93. package/src/types/InternalState.ts +7 -0
  94. package/src/types/LayoutHandler.ts +2 -4
  95. package/src/types/LayoutPath.ts +10 -0
  96. package/src/types/ManifestRoute.ts +2 -4
  97. package/src/types/PageEndPoint.ts +2 -4
  98. package/src/types/PageLoadEvent.ts +2 -4
  99. package/src/types/PageServerEndPoint.ts +2 -4
  100. package/src/types/PageState.ts +8 -0
  101. package/src/types/RouteHandler.ts +2 -4
  102. package/src/types/RouteLayoutHandler.ts +2 -4
  103. package/src/types/RouteMatchResult.ts +2 -4
  104. package/src/types/ServerHook.ts +3 -7
  105. package/src/types/ServerLoadEvent.ts +2 -4
  106. package/src/{site → utils}/pathToRegex.ts +1 -1
  107. package/{tsup.config.ts → tsdown.config.ts} +3 -4
  108. package/dist/Server-CNZWh5ca.d.cts +0 -71
  109. package/dist/Server-CNZWh5ca.d.ts +0 -71
  110. package/dist/Site-C2020GV_.d.ts +0 -63
  111. package/dist/Site-DQojGpE-.d.cts +0 -63
  112. package/dist/bin/index.cjs +0 -778
  113. package/dist/bin/index.cjs.map +0 -1
  114. package/dist/bin/index.d.cts +0 -1
  115. package/dist/chunk-565UOT3F.js +0 -18
  116. package/dist/chunk-565UOT3F.js.map +0 -1
  117. package/dist/chunk-B2UNTYN5.js +0 -68
  118. package/dist/chunk-B2UNTYN5.js.map +0 -1
  119. package/dist/chunk-CZHJQCPI.js +0 -286
  120. package/dist/chunk-CZHJQCPI.js.map +0 -1
  121. package/dist/chunk-PTVHEJZ5.js +0 -152
  122. package/dist/chunk-PTVHEJZ5.js.map +0 -1
  123. package/dist/chunk-SJVHHGVW.js +0 -13
  124. package/dist/chunk-SJVHHGVW.js.map +0 -1
  125. package/dist/chunk-TDOXEXG6.js +0 -85
  126. package/dist/chunk-TDOXEXG6.js.map +0 -1
  127. package/dist/chunk-WVXAN4IV.js +0 -50
  128. package/dist/chunk-WVXAN4IV.js.map +0 -1
  129. package/dist/chunk-YRBEYKQM.js +0 -372
  130. package/dist/chunk-YRBEYKQM.js.map +0 -1
  131. package/dist/index.cjs +0 -322
  132. package/dist/index.cjs.map +0 -1
  133. package/dist/index.d.cts +0 -199
  134. package/dist/metafile-cjs.json +0 -1
  135. package/dist/metafile-esm.json +0 -1
  136. package/dist/response.cjs +0 -150
  137. package/dist/response.cjs.map +0 -1
  138. package/dist/response.d.cts +0 -166
  139. package/dist/response.js.map +0 -1
  140. package/dist/run.cjs +0 -787
  141. package/dist/run.cjs.map +0 -1
  142. package/dist/run.d.cts +0 -14
  143. package/dist/run.js.map +0 -1
  144. package/dist/server.cjs +0 -398
  145. package/dist/server.cjs.map +0 -1
  146. package/dist/server.d.cts +0 -17
  147. package/dist/server.js.map +0 -1
  148. package/dist/state.cjs +0 -44
  149. package/dist/state.cjs.map +0 -1
  150. package/dist/state.d.cts +0 -11
  151. package/dist/state.js.map +0 -1
  152. package/dist/test.cjs +0 -538
  153. package/dist/test.cjs.map +0 -1
  154. package/dist/test.d.cts +0 -15
  155. package/src/response/moved.ts +0 -16
  156. package/src/response/redirect.ts +0 -17
  157. package/src/state/Page.ts +0 -8
@@ -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,33 +29,6 @@ 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
33
  //const url = new URL(`http://${process.env.HOST ?? "localhost"}${ev.request.url}`);
62
34
  const url = new URL(ev.request.url);
@@ -69,19 +41,18 @@ export async function load(ev: ServerEvent, template: string): Promise<Response>
69
41
  if (!route) {
70
42
  return handleResponse(notFound());
71
43
  }
44
+ const handler = route.handler;
45
+ const params = route.params || {};
72
46
 
73
47
  // Update $page before building the components
74
48
  $page.url = url;
75
49
  if (path.endsWith("/_error")) {
76
50
  $page.status = parseInt(query.get("status") ?? "404");
77
- $page.error.message = query.get("message") ?? "";
51
+ $page.error = { message: query.get("message") ?? "" };
78
52
  } else {
79
53
  $page.status = 200;
80
54
  }
81
55
 
82
- const handler = route.handler;
83
- const params = route.params || {};
84
-
85
56
  // TODO: Hit the server hook out here
86
57
  // We could maybe set data loading up as middleware on a route??????
87
58
 
@@ -92,7 +63,7 @@ export async function load(ev: ServerEvent, template: string): Promise<Response>
92
63
  if (ev.request.method === "GET") {
93
64
  return handleResponse(await loadView(ev, url, handler, params, template));
94
65
  } else if (ev.request.method === "POST") {
95
- return handleResponse(await runAction(ev, url, handler, params, query));
66
+ return handleResponse(await runAction(ev, url, handler, params, query, template), true);
96
67
  }
97
68
  break;
98
69
  }
@@ -121,6 +92,42 @@ export async function load(ev: ServerEvent, template: string): Promise<Response>
121
92
  return notFound();
122
93
  }
123
94
 
95
+ async function handleResponse(response: Response, fromForm = false): Promise<Response> {
96
+ $page.status = response.status;
97
+
98
+ // Success codes and redirect codes are acceptable
99
+ if (response.status >= 200 && response.status <= 399) {
100
+ return response;
101
+ }
102
+
103
+ // 4xx error codes are acceptable from form actions
104
+ if (fromForm && response.status >= 400 && response.status <= 499) {
105
+ return response;
106
+ }
107
+
108
+ // It's an error, so redirect to the error page
109
+ // We're just pushing the status and message in the URL, but maybe there's a
110
+ // more sophisticated way to do this?
111
+ // TODO: Should be returning loadView rather than redirecting
112
+ // TODO: Should be returning the NEAREST error page to this path, including layouts
113
+ let params = new URLSearchParams();
114
+ params.append("status", $page.status.toString());
115
+ let message = await response.text();
116
+ if (response.headers.get("Content-Type")?.includes("application/json")) {
117
+ const data = JSON.parse(message);
118
+ message = data.message ?? message;
119
+ }
120
+ if (message) {
121
+ if ($page.error) {
122
+ $page.error.message = message;
123
+ } else {
124
+ $page.error = { message };
125
+ }
126
+ params.append("message", message);
127
+ }
128
+ return seeOther(`/_error?${params.toString()}`);
129
+ }
130
+
124
131
  async function loadData(
125
132
  ev: ServerEvent,
126
133
  url: URL,
@@ -155,6 +162,8 @@ async function loadView(
155
162
  handler: RouteHandler,
156
163
  params: Record<string, string>,
157
164
  template: string,
165
+ formStatus?: number,
166
+ form?: Record<string, string>,
158
167
  ) {
159
168
  // There must be a client endpoint with a component
160
169
  const clientEndPoint: PageEndPoint | undefined = (await handler.endPoint()).default;
@@ -209,7 +218,7 @@ async function loadView(
209
218
  if (endPointResponse?.ok === false) {
210
219
  return endPointResponse;
211
220
  }
212
- let $props: Record<string, any> = { data };
221
+ let $props: Record<string, any> = { data, form };
213
222
 
214
223
  let styles = "";
215
224
 
@@ -217,7 +226,6 @@ async function loadView(
217
226
  // the default slot of its parent
218
227
  // TODO: Also handle layout server data
219
228
  // TODO: There's probably a nicer way to do this with reducers or something
220
- // TODO: Re-use parent layouts
221
229
  let component = clientEndPoint.component as ServerComponent;
222
230
  let slots: Record<string, ServerSlotRender> | undefined = undefined;
223
231
  if (handler.layouts) {
@@ -250,6 +258,12 @@ async function loadView(
250
258
  let html;
251
259
  try {
252
260
  let { body, head } = component($props, undefined, slots);
261
+
262
+ // Put the form info in a hidden input so that it can be accessed on the client
263
+ if (form) {
264
+ body += `\n<input type="hidden" id="t-form-data" value='${JSON.stringify(form).replaceAll("'", "\\'")}' />`;
265
+ }
266
+
253
267
  styles += head;
254
268
  html = template.replace("%COMPONENT_BODY%", body).replace("%COMPONENT_HEAD%", styles);
255
269
  } catch (error) {
@@ -259,7 +273,7 @@ async function loadView(
259
273
  }
260
274
 
261
275
  return new Response(html, {
262
- status: 200,
276
+ status: formStatus ?? 200,
263
277
  headers: {
264
278
  "Content-Type": "text/html",
265
279
  },
@@ -272,6 +286,7 @@ async function runAction(
272
286
  handler: RouteHandler,
273
287
  params: Record<string, string>,
274
288
  query: URLSearchParams,
289
+ template: string,
275
290
  ) {
276
291
  const actionName = (Array.from(query.keys())[0] || "default").replace(/^\//, "");
277
292
  const serverEndPoint: PageServerEndPoint | undefined =
@@ -279,7 +294,6 @@ async function runAction(
279
294
  if (serverEndPoint?.actions) {
280
295
  const action = serverEndPoint.actions[actionName];
281
296
  if (action) {
282
- // TODO: form.errors etc
283
297
  const serverParams = buildServerParams(ev, url, params);
284
298
 
285
299
  if (handler.serverHook) {
@@ -291,12 +305,21 @@ async function runAction(
291
305
 
292
306
  const result = await action(serverParams);
293
307
 
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
- return result;
308
+ // If no result, ok or 4xx error, re-render the view with the form result
309
+ // If redirect or server error, just return the result to handle it as normal
310
+ // TODO: do not re-run hooks?
311
+ if (
312
+ !result ||
313
+ (result.status >= 200 && result.status <= 299) ||
314
+ (result.status >= 400 && result.status <= 499)
315
+ ) {
316
+ const newUrl = new URL(url.pathname, url);
317
+ const formStatus = result?.status;
318
+ const form = await result?.json();
319
+ $page.form = form;
320
+ return await loadView(ev, newUrl, handler, params, template, formStatus, form);
298
321
  } else {
299
- return seeOther(url.pathname);
322
+ return result;
300
323
  }
301
324
  }
302
325
  }
@@ -1,15 +1,6 @@
1
- import { $watch } from "@torpor/view";
2
- import Page from "./Page";
1
+ import type PageState from "../types/PageState";
2
+ import internal from "./internal";
3
3
 
4
- const $page: Page = $watch(
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,6 @@
1
+ import type ClientState from "../types/ClientState";
2
+ import internal from "./internal";
3
+
4
+ const client: ClientState = internal().client;
5
+
6
+ export default client;
@@ -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: {},
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
+ }
@@ -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,
@@ -1,10 +1,8 @@
1
1
  import Server from "../server/Server";
2
2
  import Site from "../site/Site";
3
3
 
4
- type Adapter = {
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,8 @@
1
+ import Router from "../site/Router";
2
+ import type LayoutPath from "./LayoutPath";
3
+
4
+ export default interface ClientState {
5
+ router: Router;
6
+ layoutStack: LayoutPath[];
7
+ prefetchedData: Record<string, any>;
8
+ }
@@ -0,0 +1,7 @@
1
+ import type ClientState from "./ClientState";
2
+ import type PageState from "./PageState";
3
+
4
+ export default interface InternalState {
5
+ $page: PageState;
6
+ client: ClientState;
7
+ }
@@ -1,7 +1,5 @@
1
- type LayoutHandler = {
1
+ export default interface LayoutHandler {
2
2
  path: string;
3
3
  endPoint: () => Promise<any>;
4
4
  serverEndPoint?: () => Promise<any>;
5
- };
6
-
7
- export default LayoutHandler;
5
+ }
@@ -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
+ }
@@ -1,7 +1,5 @@
1
- type ManifestRoute = {
1
+ export default interface ManifestRoute {
2
2
  path: string;
3
3
  type: number;
4
4
  endPoint: () => Promise<any>;
5
- };
6
-
7
- export default ManifestRoute;
5
+ }
@@ -4,7 +4,7 @@ import type PageLoadEvent from "./PageLoadEvent";
4
4
  /**
5
5
  * For +page.
6
6
  */
7
- type PageEndPoint = {
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
- type PageLoadEvent = {
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
- type PageServerEndPoint = {
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
+ }
@@ -0,0 +1,8 @@
1
+ export default interface PageState {
2
+ status: number;
3
+ url: URL;
4
+ form?: Record<string, string>;
5
+ error?: {
6
+ message: string;
7
+ };
8
+ }
@@ -1,6 +1,6 @@
1
1
  import type RouteLayoutHandler from "./RouteLayoutHandler";
2
2
 
3
- type RouteHandler = {
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,7 +1,5 @@
1
- type RouteLayoutHandler = {
1
+ export default interface RouteLayoutHandler {
2
2
  path: string;
3
3
  endPoint: () => Promise<any>;
4
4
  serverEndPoint?: () => Promise<any>;
5
- };
6
-
7
- export default RouteLayoutHandler;
5
+ }
@@ -1,9 +1,7 @@
1
1
  import type RouteHandler from "./RouteHandler";
2
2
 
3
- type RouteMatchResult = {
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
+ }
@@ -3,13 +3,9 @@ import type ServerLoadEvent from "./ServerLoadEvent";
3
3
  /**
4
4
  * For _hook.server.
5
5
  */
6
- type ServerHook = {
6
+ export default interface ServerHook {
7
7
  /**
8
8
  * Called on each server request.
9
9
  */
10
- handle?: ServerLoad;
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
- type ServerLoadEvent = {
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(/\[([^\/]+?)\]/, "(?<$1>[^\\/]+?)");
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 "tsup";
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: ["esm", "cjs"],
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 };
@@ -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 };