@torpor/build 0.0.5 → 0.1.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 (106) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +1 -1
  3. package/dist/Server-CB99REgs.d.cts +74 -0
  4. package/dist/Server-CB99REgs.d.ts +74 -0
  5. package/dist/Site-CgoeDt8k.d.cts +29 -0
  6. package/dist/Site-D95nwrAg.d.ts +29 -0
  7. package/dist/adapters/cloudflare/index.cjs +125 -0
  8. package/dist/adapters/cloudflare/index.cjs.map +1 -0
  9. package/dist/adapters/cloudflare/index.d.cts +13 -0
  10. package/dist/adapters/cloudflare/index.d.ts +13 -0
  11. package/dist/adapters/cloudflare/index.js +80 -0
  12. package/dist/adapters/cloudflare/index.js.map +1 -0
  13. package/dist/adapters/node/index.cjs +152 -0
  14. package/dist/adapters/node/index.cjs.map +1 -0
  15. package/dist/adapters/node/index.d.cts +8 -0
  16. package/dist/adapters/node/index.d.ts +8 -0
  17. package/dist/adapters/node/index.js +8 -0
  18. package/dist/adapters/node/index.js.map +1 -0
  19. package/dist/bin/index.cjs +541 -93
  20. package/dist/bin/index.cjs.map +1 -1
  21. package/dist/bin/index.js +511 -22
  22. package/dist/bin/index.js.map +1 -1
  23. package/dist/chunk-5X4T3PZN.js +23 -0
  24. package/dist/chunk-5X4T3PZN.js.map +1 -0
  25. package/dist/chunk-ALHFYD7U.js +113 -0
  26. package/dist/chunk-ALHFYD7U.js.map +1 -0
  27. package/dist/chunk-V4XTDQEV.js +19 -0
  28. package/dist/chunk-V4XTDQEV.js.map +1 -0
  29. package/dist/chunk-VAGHGWM5.js +110 -0
  30. package/dist/chunk-VAGHGWM5.js.map +1 -0
  31. package/dist/index.cjs +200 -97
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +33 -36
  34. package/dist/index.d.ts +33 -36
  35. package/dist/index.js +85 -17
  36. package/dist/index.js.map +1 -1
  37. package/dist/metafile-cjs.json +1 -1
  38. package/dist/metafile-esm.json +1 -1
  39. package/dist/response.js +17 -91
  40. package/dist/response.js.map +1 -1
  41. package/package.json +26 -9
  42. package/src/adapters/cloudflare/_worker.ts +38 -0
  43. package/src/adapters/cloudflare/index.ts +98 -0
  44. package/src/adapters/node/constants.ts +1 -0
  45. package/src/adapters/node/createFetchHandler.ts +29 -0
  46. package/src/adapters/node/createMiddlewareHandler.ts +79 -0
  47. package/src/adapters/node/createNodeServer.ts +8 -0
  48. package/src/adapters/node/flattenHeaders.ts +44 -0
  49. package/src/adapters/node/index.ts +18 -0
  50. package/src/adapters/node/nodeMessageToNodeResponse.ts +89 -0
  51. package/src/adapters/node/nodeMessageToRequest.ts +43 -0
  52. package/src/adapters/node/readableToBuffer.ts +16 -0
  53. package/src/adapters/node/requestToNodeMessage.ts +26 -0
  54. package/src/adapters/node/responseToNodeResponse.ts +44 -0
  55. package/src/bin/index.ts +43 -36
  56. package/src/index.ts +6 -14
  57. package/src/server/CookieHelper.ts +36 -0
  58. package/src/server/HeaderHelper.ts +25 -0
  59. package/src/server/Server.ts +119 -0
  60. package/src/server/ServerEvent.ts +33 -0
  61. package/src/server/ServerFunction.ts +5 -0
  62. package/src/server/contentType.ts +85 -0
  63. package/src/site/Router.ts +136 -0
  64. package/src/site/Routerx.ts +67 -0
  65. package/src/site/Site.ts +114 -0
  66. package/src/site/clientEntry.ts +22 -20
  67. package/src/site/manifest.ts +49 -0
  68. package/src/site/pathToRegex.ts +10 -0
  69. package/src/site/prepareTemplate.ts +20 -0
  70. package/src/site/runBuild.ts +92 -0
  71. package/src/site/runDev.ts +84 -0
  72. package/src/site/runPreview.ts +83 -0
  73. package/src/site/serverEntry.ts +113 -200
  74. package/src/types/Adapter.ts +10 -0
  75. package/src/types/HttpMethod.ts +12 -0
  76. package/src/types/LayoutHandler.ts +7 -0
  77. package/src/types/ManifestRoute.ts +8 -0
  78. package/src/types/MiddlewareFunction.ts +8 -0
  79. package/src/types/PageEndPoint.ts +4 -3
  80. package/src/types/{PageEvent.ts → PageLoadEvent.ts} +3 -2
  81. package/src/types/PageServerAction.ts +5 -2
  82. package/src/types/PageServerEndPoint.ts +1 -0
  83. package/src/types/PageServerLoad.ts +5 -2
  84. package/src/types/RouteHandler.ts +6 -5
  85. package/src/types/RouteHandlerCollection.ts +1 -0
  86. package/src/types/RouteLayoutHandler.ts +3 -2
  87. package/src/types/RouteMatchResult.ts +3 -2
  88. package/src/types/RouteType.ts +7 -0
  89. package/src/types/ServerEndPoint.ts +1 -0
  90. package/src/types/ServerHook.ts +3 -2
  91. package/src/types/{ServerEvent.ts → ServerLoadEvent.ts} +13 -6
  92. package/src/types/ServerRequest.ts +5 -2
  93. package/src/types/manifest.d.ts +7 -0
  94. package/test/app.test.ts +47 -0
  95. package/tsconfig.json +1 -1
  96. package/tsup.config.ts +11 -1
  97. package/vitest.config.ts +3 -0
  98. package/dist/chunk-L7GOYKUG.js +0 -93
  99. package/dist/chunk-L7GOYKUG.js.map +0 -1
  100. package/src/site/FileSystemRouter.ts +0 -25
  101. package/src/site/buildRoutePath.ts +0 -25
  102. package/src/site/defineConfig.ts +0 -75
  103. package/src/site/lazyRoute.ts +0 -72
  104. package/src/site/routeHandlers.ts +0 -126
  105. package/src/types/CookieHelper.ts +0 -8
  106. package/src/types/UserConfig.ts +0 -4
@@ -1,7 +1,7 @@
1
- import { ServerResponse } from "node:http";
2
- import CookieHelper from "./CookieHelper";
1
+ import CookieHelper from "../server/CookieHelper";
2
+ import HeaderHelper from "../server/HeaderHelper";
3
3
 
4
- type ServerEvent = {
4
+ type ServerLoadEvent = {
5
5
  /**
6
6
  * The URL for the server function.
7
7
  */
@@ -17,12 +17,19 @@ type ServerEvent = {
17
17
  * and pages. It flows down in that order.
18
18
  */
19
19
  appData: Record<string, any>;
20
- // TODO: Would be nicer if these were Request/Response?
20
+ /**
21
+ * The server request.
22
+ */
21
23
  request: Request;
22
- response: ServerResponse;
24
+ //response: ServerResponse;
23
25
  /**
24
26
  * A helper for getting and setting cookie data.
25
27
  */
26
28
  cookies: CookieHelper;
29
+ /**
30
+ * A helper for getting and setting headers.
31
+ */
32
+ headers: HeaderHelper;
27
33
  };
28
- export default ServerEvent;
34
+
35
+ export default ServerLoadEvent;
@@ -1,4 +1,7 @@
1
- import type ServerEvent from "./ServerEvent";
1
+ import type ServerLoadEvent from "./ServerLoadEvent";
2
+
3
+ type ServerRequest = (
4
+ event: ServerLoadEvent,
5
+ ) => Response | Promise<Response | undefined> | Promise<void> | void;
2
6
 
3
- type ServerRequest = (event: ServerEvent) => Response | Promise<Response | undefined> | void;
4
7
  export default ServerRequest;
@@ -0,0 +1,7 @@
1
+ import type ManifestRoute from "./ManifestRoute";
2
+
3
+ declare const manifest: {
4
+ routes: ManifestRoute[];
5
+ };
6
+
7
+ export default manifest;
@@ -0,0 +1,47 @@
1
+ import { expect, test } from "vitest";
2
+ import Server from "../src/server/Server";
3
+
4
+ test("app router methods", () => {
5
+ let app = new Server();
6
+ expect(app).not.toBeUndefined();
7
+ /*
8
+ app.add("GET", "/blah", () => "hi there");
9
+ expect(app.match("GET", "/blah")).not.toBeUndefined();
10
+ expect(app.match("POST", "/blah")).toBeUndefined();
11
+
12
+ app.get("/", () => "hi there");
13
+ app.head("/", () => "hi there");
14
+ app.patch("/", () => "hi there");
15
+ app.post("/", () => "hi there");
16
+ app.put("/", () => "hi there");
17
+ app.delete("/", () => "hi there");
18
+ app.options("/", () => "hi there");
19
+ app.connect("/", () => "hi there");
20
+ app.trace("/", () => "hi there");
21
+
22
+ expect(app.match("GET", "/")).not.toBeUndefined();
23
+ expect(app.match("HEAD", "/")).not.toBeUndefined();
24
+ expect(app.match("PATCH", "/")).not.toBeUndefined();
25
+ expect(app.match("POST", "/")).not.toBeUndefined();
26
+ expect(app.match("PUT", "/")).not.toBeUndefined();
27
+ expect(app.match("DELETE", "/")).not.toBeUndefined();
28
+ expect(app.match("OPTIONS", "/")).not.toBeUndefined();
29
+ expect(app.match("CONNECT", "/")).not.toBeUndefined();
30
+ expect(app.match("TRACE", "/")).not.toBeUndefined();
31
+ */
32
+ });
33
+
34
+ test("app router params", () => {
35
+ let app = new Server();
36
+ expect(app).not.toBeUndefined();
37
+ /*
38
+ app.add("GET", "/posts/[id]", () => "hi there");
39
+
40
+ let route = app.match("GET", "/posts/5");
41
+
42
+ expect(route).not.toBeUndefined();
43
+ expect(route!.handler).not.toBeUndefined();
44
+ expect(route!.params).not.toBeUndefined();
45
+ expect(route!.params!.id).toBe("5");
46
+ */
47
+ });
package/tsconfig.json CHANGED
@@ -5,5 +5,5 @@
5
5
  "skipLibCheck": true,
6
6
  "verbatimModuleSyntax": false
7
7
  },
8
- "include": ["src"]
8
+ "include": ["src", "src/site/app"]
9
9
  }
package/tsup.config.ts CHANGED
@@ -1,10 +1,20 @@
1
1
  import { defineConfig } from "tsup";
2
2
 
3
3
  export default defineConfig({
4
- entry: ["src/index.ts", "src/state.ts", "src/response.ts", "src/bin/index.ts"],
4
+ entry: [
5
+ "src/index.ts",
6
+ "src/state.ts",
7
+ "src/response.ts",
8
+ "src/bin/index.ts",
9
+ "src/adapters/node/index.ts",
10
+ "src/adapters/cloudflare/index.ts",
11
+ ],
5
12
  format: ["esm", "cjs"],
6
13
  dts: true,
7
14
  clean: true,
8
15
  metafile: true,
9
16
  sourcemap: true,
17
+ // Put this in here to stop issues with bundling Vite from bin/index.ts
18
+ // I'm not sure if this will cause further issues down the line?
19
+ external: ["vite"],
10
20
  });
@@ -0,0 +1,3 @@
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ export default defineConfig(() => ({}));
@@ -1,93 +0,0 @@
1
- // src/site/defineConfig.ts
2
- import torpor from "@torpor/unplugin/vite";
3
- import path from "node:path";
4
- import { createApp } from "vinxi";
5
- import { config } from "vinxi/plugins/config";
6
-
7
- // src/site/FileSystemRouter.ts
8
- import { BaseFileSystemRouter, cleanPath } from "vinxi/fs-router";
9
- var FileSystemRouter = class extends BaseFileSystemRouter {
10
- toPath(src) {
11
- let routePath = cleanPath(src, this.config).replace(/^\//, "").replace(/_hook.server$/, "_hook/~server").replace(/_layout.server$/, "_layout/~server").replace(/\+page.server$/, "~server").replace(/\+page$/, "").replace(/\+server$/, "").replace(/\/$/, "");
12
- return routePath?.length > 0 ? `/${routePath}` : "/";
13
- }
14
- toRoute(filePath) {
15
- return {
16
- path: this.toPath(filePath),
17
- $handler: {
18
- src: filePath,
19
- pick: ["default"]
20
- }
21
- };
22
- }
23
- };
24
-
25
- // src/site/defineConfig.ts
26
- function defineConfig(options) {
27
- process.env.PORT = (options?.port || 7059).toString();
28
- return createApp({
29
- name: "torpor",
30
- routers: [
31
- {
32
- name: "assets",
33
- type: "static",
34
- dir: "./src/assets"
35
- },
36
- // Doesn't look like we can have two server routes?
37
- // Have to put api in /routes
38
- // Maybe we can support having /routes/api and routes/site and stripping /site from the start?
39
- //{
40
- // name: "api",
41
- // type: "http",
42
- // target: "server",
43
- // // TODO: change this when published
44
- // handler: "node_modules/@torpor/build/src/site/serverEntry.ts",
45
- // routes: apiRoutes,
46
- // plugins: () => [config("custom", viteOptions())],
47
- //},
48
- {
49
- name: "server",
50
- type: "http",
51
- target: "server",
52
- // TODO: change this when published
53
- handler: "./node_modules/@torpor/build/src/site/serverEntry.ts",
54
- routes,
55
- plugins: () => [config("custom", viteOptions()), torpor({ server: true })]
56
- },
57
- {
58
- name: "client",
59
- type: "client",
60
- target: "browser",
61
- // TODO: change this when published
62
- handler: "./node_modules/@torpor/build/src/site/clientEntry.ts",
63
- base: "/_build",
64
- routes,
65
- plugins: () => [config("custom", viteOptions()), torpor()]
66
- }
67
- ]
68
- });
69
- }
70
- function routes(router, app) {
71
- return new FileSystemRouter(
72
- {
73
- dir: path.resolve("src/routes"),
74
- extensions: ["js", "ts"]
75
- },
76
- router,
77
- app
78
- );
79
- }
80
- function viteOptions() {
81
- return {
82
- resolve: {
83
- alias: {
84
- "@": path.resolve("src")
85
- }
86
- }
87
- };
88
- }
89
-
90
- export {
91
- defineConfig
92
- };
93
- //# sourceMappingURL=chunk-L7GOYKUG.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/site/defineConfig.ts","../src/site/FileSystemRouter.ts"],"sourcesContent":["import torpor from \"@torpor/unplugin/vite\";\nimport path from \"node:path\";\nimport { type AppOptions, type RouterSchemaInput, createApp } from \"vinxi\";\nimport { config } from \"vinxi/plugins/config\";\nimport { type UserConfig } from \"../types/UserConfig\";\nimport FileSystemRouter from \"./FileSystemRouter\";\n\nexport default function defineConfig(options?: UserConfig) {\n\t// Set the port\n\tprocess.env.PORT = (options?.port || 7059).toString();\n\n\t// Get Vinxi to create and serve the app\n\treturn createApp({\n\t\tname: \"torpor\",\n\t\trouters: [\n\t\t\t{\n\t\t\t\tname: \"assets\",\n\t\t\t\ttype: \"static\",\n\t\t\t\tdir: \"./src/assets\",\n\t\t\t},\n\t\t\t// Doesn't look like we can have two server routes?\n\t\t\t// Have to put api in /routes\n\t\t\t// Maybe we can support having /routes/api and routes/site and stripping /site from the start?\n\t\t\t//{\n\t\t\t//\tname: \"api\",\n\t\t\t//\ttype: \"http\",\n\t\t\t//\ttarget: \"server\",\n\t\t\t//\t// TODO: change this when published\n\t\t\t//\thandler: \"node_modules/@torpor/build/src/site/serverEntry.ts\",\n\t\t\t//\troutes: apiRoutes,\n\t\t\t//\tplugins: () => [config(\"custom\", viteOptions())],\n\t\t\t//},\n\t\t\t{\n\t\t\t\tname: \"server\",\n\t\t\t\ttype: \"http\",\n\t\t\t\ttarget: \"server\",\n\t\t\t\t// TODO: change this when published\n\t\t\t\thandler: \"./node_modules/@torpor/build/src/site/serverEntry.ts\",\n\t\t\t\troutes,\n\t\t\t\tplugins: () => [config(\"custom\", viteOptions()), torpor({ server: true })],\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"client\",\n\t\t\t\ttype: \"client\",\n\t\t\t\ttarget: \"browser\",\n\t\t\t\t// TODO: change this when published\n\t\t\t\thandler: \"./node_modules/@torpor/build/src/site/clientEntry.ts\",\n\t\t\t\tbase: \"/_build\",\n\t\t\t\troutes,\n\t\t\t\tplugins: () => [config(\"custom\", viteOptions()), torpor()],\n\t\t\t},\n\t\t],\n\t});\n}\n\nfunction routes(router: RouterSchemaInput, app: AppOptions) {\n\treturn new FileSystemRouter(\n\t\t{\n\t\t\tdir: path.resolve(\"src/routes\"),\n\t\t\textensions: [\"js\", \"ts\"],\n\t\t},\n\t\trouter,\n\t\tapp,\n\t);\n}\n\nfunction viteOptions() {\n\treturn {\n\t\tresolve: {\n\t\t\talias: {\n\t\t\t\t\"@\": path.resolve(\"src\"),\n\t\t\t},\n\t\t},\n\t};\n}\n","import { BaseFileSystemRouter, cleanPath } from \"vinxi/fs-router\";\n\nexport default class FileSystemRouter extends BaseFileSystemRouter {\n\ttoPath(src: string) {\n\t\tlet routePath = cleanPath(src, this.config)\n\t\t\t.replace(/^\\//, \"\")\n\t\t\t.replace(/_hook.server$/, \"_hook/~server\")\n\t\t\t.replace(/_layout.server$/, \"_layout/~server\")\n\t\t\t.replace(/\\+page.server$/, \"~server\")\n\t\t\t.replace(/\\+page$/, \"\")\n\t\t\t.replace(/\\+server$/, \"\")\n\t\t\t.replace(/\\/$/, \"\");\n\t\treturn routePath?.length > 0 ? `/${routePath}` : \"/\";\n\t}\n\n\ttoRoute(filePath: string) {\n\t\treturn {\n\t\t\tpath: this.toPath(filePath),\n\t\t\t$handler: {\n\t\t\t\tsrc: filePath,\n\t\t\t\tpick: [\"default\"],\n\t\t\t},\n\t\t};\n\t}\n}\n"],"mappings":";AAAA,OAAO,YAAY;AACnB,OAAO,UAAU;AACjB,SAAkD,iBAAiB;AACnE,SAAS,cAAc;;;ACHvB,SAAS,sBAAsB,iBAAiB;AAEhD,IAAqB,mBAArB,cAA8C,qBAAqB;AAAA,EAClE,OAAO,KAAa;AACnB,QAAI,YAAY,UAAU,KAAK,KAAK,MAAM,EACxC,QAAQ,OAAO,EAAE,EACjB,QAAQ,iBAAiB,eAAe,EACxC,QAAQ,mBAAmB,iBAAiB,EAC5C,QAAQ,kBAAkB,SAAS,EACnC,QAAQ,WAAW,EAAE,EACrB,QAAQ,aAAa,EAAE,EACvB,QAAQ,OAAO,EAAE;AACnB,WAAO,WAAW,SAAS,IAAI,IAAI,SAAS,KAAK;AAAA,EAClD;AAAA,EAEA,QAAQ,UAAkB;AACzB,WAAO;AAAA,MACN,MAAM,KAAK,OAAO,QAAQ;AAAA,MAC1B,UAAU;AAAA,QACT,KAAK;AAAA,QACL,MAAM,CAAC,SAAS;AAAA,MACjB;AAAA,IACD;AAAA,EACD;AACD;;;ADjBe,SAAR,aAA8B,SAAsB;AAE1D,UAAQ,IAAI,QAAQ,SAAS,QAAQ,MAAM,SAAS;AAGpD,SAAO,UAAU;AAAA,IAChB,MAAM;AAAA,IACN,SAAS;AAAA,MACR;AAAA,QACC,MAAM;AAAA,QACN,MAAM;AAAA,QACN,KAAK;AAAA,MACN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAaA;AAAA,QACC,MAAM;AAAA,QACN,MAAM;AAAA,QACN,QAAQ;AAAA;AAAA,QAER,SAAS;AAAA,QACT;AAAA,QACA,SAAS,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,GAAG,OAAO,EAAE,QAAQ,KAAK,CAAC,CAAC;AAAA,MAC1E;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,MAAM;AAAA,QACN,QAAQ;AAAA;AAAA,QAER,SAAS;AAAA,QACT,MAAM;AAAA,QACN;AAAA,QACA,SAAS,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,GAAG,OAAO,CAAC;AAAA,MAC1D;AAAA,IACD;AAAA,EACD,CAAC;AACF;AAEA,SAAS,OAAO,QAA2B,KAAiB;AAC3D,SAAO,IAAI;AAAA,IACV;AAAA,MACC,KAAK,KAAK,QAAQ,YAAY;AAAA,MAC9B,YAAY,CAAC,MAAM,IAAI;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;AAEA,SAAS,cAAc;AACtB,SAAO;AAAA,IACN,SAAS;AAAA,MACR,OAAO;AAAA,QACN,KAAK,KAAK,QAAQ,KAAK;AAAA,MACxB;AAAA,IACD;AAAA,EACD;AACD;","names":[]}
@@ -1,25 +0,0 @@
1
- import { BaseFileSystemRouter, cleanPath } from "vinxi/fs-router";
2
-
3
- export default class FileSystemRouter extends BaseFileSystemRouter {
4
- toPath(src: string) {
5
- let routePath = cleanPath(src, this.config)
6
- .replace(/^\//, "")
7
- .replace(/_hook.server$/, "_hook/~server")
8
- .replace(/_layout.server$/, "_layout/~server")
9
- .replace(/\+page.server$/, "~server")
10
- .replace(/\+page$/, "")
11
- .replace(/\+server$/, "")
12
- .replace(/\/$/, "");
13
- return routePath?.length > 0 ? `/${routePath}` : "/";
14
- }
15
-
16
- toRoute(filePath: string) {
17
- return {
18
- path: this.toPath(filePath),
19
- $handler: {
20
- src: filePath,
21
- pick: ["default"],
22
- },
23
- };
24
- }
25
- }
@@ -1,25 +0,0 @@
1
- type ParamsType = Record<PropertyKey, any>;
2
-
3
- export default function buildRoutePath<RP extends ParamsType, UP extends ParamsType>(
4
- path: string,
5
- routeParams: RP,
6
- urlParams?: UP,
7
- ) {
8
- for (let [key, value] of Object.entries(routeParams)) {
9
- path = path.replace(`[${key}]`, value);
10
- }
11
- if (urlParams) {
12
- // TODO: More sophisticated url params serialization
13
- let params = Object.entries(urlParams)
14
- .map(([key, value]) => {
15
- if (value != null) {
16
- return `${key}=${value}`;
17
- }
18
- })
19
- .filter(Boolean);
20
- if (params.length) {
21
- path += `?${params.join("&")}`;
22
- }
23
- }
24
- return path;
25
- }
@@ -1,75 +0,0 @@
1
- import torpor from "@torpor/unplugin/vite";
2
- import path from "node:path";
3
- import { type AppOptions, type RouterSchemaInput, createApp } from "vinxi";
4
- import { config } from "vinxi/plugins/config";
5
- import type UserConfig from "../types/UserConfig";
6
- import FileSystemRouter from "./FileSystemRouter";
7
-
8
- export default function defineConfig(options?: UserConfig) {
9
- // Set the port
10
- process.env.PORT = (options?.port || 7059).toString();
11
-
12
- // Get Vinxi to create and serve the app
13
- return createApp({
14
- name: "torpor",
15
- routers: [
16
- {
17
- name: "assets",
18
- type: "static",
19
- dir: "./src/assets",
20
- },
21
- // Doesn't look like we can have two server routes?
22
- // Have to put api in /routes
23
- // Maybe we can support having /routes/api and routes/site and stripping /site from the start?
24
- //{
25
- // name: "api",
26
- // type: "http",
27
- // target: "server",
28
- // // TODO: change this when published
29
- // handler: "node_modules/@torpor/build/src/site/serverEntry.ts",
30
- // routes: apiRoutes,
31
- // plugins: () => [config("custom", viteOptions())],
32
- //},
33
- {
34
- name: "server",
35
- type: "http",
36
- target: "server",
37
- // TODO: change this when published
38
- handler: "./node_modules/@torpor/build/src/site/serverEntry.ts",
39
- routes,
40
- plugins: () => [config("custom", viteOptions()), torpor({ server: true })],
41
- },
42
- {
43
- name: "client",
44
- type: "client",
45
- target: "browser",
46
- // TODO: change this when published
47
- handler: "./node_modules/@torpor/build/src/site/clientEntry.ts",
48
- base: "/_build",
49
- routes,
50
- plugins: () => [config("custom", viteOptions()), torpor()],
51
- },
52
- ],
53
- });
54
- }
55
-
56
- function routes(router: RouterSchemaInput, app: AppOptions) {
57
- return new FileSystemRouter(
58
- {
59
- dir: path.resolve("src/routes"),
60
- extensions: ["js", "ts"],
61
- },
62
- router,
63
- app,
64
- );
65
- }
66
-
67
- function viteOptions() {
68
- return {
69
- resolve: {
70
- alias: {
71
- "@": path.resolve("src"),
72
- },
73
- },
74
- };
75
- }
@@ -1,72 +0,0 @@
1
- export default async function lazyRoute(
2
- component: { src: string; import(): Promise<any> },
3
- clientManifest: any,
4
- serverManifest: any,
5
- //exported = "default",
6
- ) {
7
- if (import.meta.env.DEV) {
8
- const manifest = import.meta.env.SSR ? serverManifest : clientManifest;
9
- const mod = await manifest.inputs[component.src].import();
10
- return mod;
11
- } else {
12
- const mod = await component.import();
13
- return mod;
14
- }
15
- /*
16
- return lazy(async () => {
17
- if (import.meta.env.DEV) {
18
- let manifest = import.meta.env.SSR ? serverManifest : clientManifest;
19
-
20
- const mod = await manifest.inputs[component.src].import();
21
- invariant(mod[exported], `Module ${component.src} does not export ${exported}`);
22
- const Component = mod[exported];
23
- let assets = await clientManifest.inputs?.[component.src].assets();
24
- const styles = assets.filter((asset) => asset.tag === "style");
25
-
26
- if (typeof window !== "undefined" && import.meta.hot) {
27
- import.meta.hot.on("css-update", (data) => {
28
- updateStyles(styles, data);
29
- });
30
- }
31
-
32
- const Comp = forwardRef((props, ref) => {
33
- if (typeof window !== "undefined") {
34
- useLayoutEffect(() => {
35
- return () => {
36
- // remove style tags added by vite when a CSS file is imported
37
- cleanupStyles(styles);
38
- };
39
- }, []);
40
- }
41
- return createElement(
42
- Fragment,
43
- null,
44
- ...assets.map((asset) => renderAsset(asset)),
45
- createElement(Component, { ...props, ref: ref }),
46
- );
47
- });
48
- return { default: Comp };
49
- } else {
50
- const mod = await component.import();
51
-
52
- const Component = mod[exported];
53
- let assets = await clientManifest.inputs?.[component.src].assets();
54
-
55
- if (typeof window !== "undefined") {
56
- const styles = assets.filter((asset) => asset.attrs.rel === "stylesheet");
57
- preloadStyles(styles);
58
- }
59
-
60
- const Comp = forwardRef((props, ref) => {
61
- return createElement(
62
- Fragment,
63
- null,
64
- ...assets.map((asset) => renderAsset(asset)),
65
- createElement(Component, { ...props, ref: ref }),
66
- );
67
- });
68
- return { default: Comp };
69
- }
70
- });
71
- */
72
- }
@@ -1,126 +0,0 @@
1
- import { getManifest } from "vinxi/manifest";
2
- import fileRoutes, { type RouteModule } from "vinxi/routes";
3
- import type RouteHandler from "../types/RouteHandler";
4
- import type RouteHandlerCollection from "../types/RouteHandlerCollection";
5
- import type RouteLayoutHandler from "../types/RouteLayoutHandler";
6
- import lazyRoute from "./lazyRoute";
7
-
8
- const clientManifest = getManifest("client");
9
- const serverManifest = getManifest("server");
10
-
11
- const routeHandlers: RouteHandlerCollection = {
12
- handlers: fileRoutes
13
- // HACK: Is there a better way to filter? glob in the config?
14
- .filter((route) => !route.path.startsWith("_"))
15
- .map((route) => {
16
- return {
17
- ...route,
18
- regex: pathToRegExp(route.path),
19
- // TODO: Implement the rest of the lazyRoute stuff from vinxi/react or vinxi/solid
20
- endPoint: lazyRoute(route.$handler, clientManifest, serverManifest),
21
- loaded: false,
22
- };
23
- })
24
- .sort((a, b) => {
25
- // Sort [param]s after paths
26
- // There might be a quicker/easier way to do this
27
- for (let i = 0; i < Math.min(a.path.length, b.path.length); i++) {
28
- if (a.path[i] === "[" && b.path[i] !== "[") {
29
- return 1;
30
- } else if (b.path[i] === "[" && a.path[i] !== "[") {
31
- return -1;
32
- } else if (a.path[i] === b.path[i]) {
33
- // Keep going...
34
- } else {
35
- return a.path[i].localeCompare(b.path[i]);
36
- }
37
- }
38
- return a.path.length - b.path.length;
39
- }),
40
- match(path, urlParams) {
41
- // TODO: Lots of testing etc
42
- for (let handler of (this as RouteHandlerCollection).handlers) {
43
- let match = path.match(handler.regex);
44
- if (match) {
45
- console.log(`matching ${path}, found ${handler.path}`);
46
-
47
- // Lazy load server endpoints and layouts
48
- // Partly because it makes sense to do it here, but also because
49
- // it doesn't work if we try to do it upfront for some reason
50
- if (!handler.loaded) {
51
- loadHandler(handler);
52
- handler.loaded = true;
53
- }
54
- return {
55
- handler,
56
- routeParams: match.groups,
57
- urlParams: urlParams ? Object.fromEntries(urlParams) : undefined,
58
- };
59
- }
60
- }
61
-
62
- console.log(`matching ${path}, not found`);
63
- },
64
- };
65
-
66
- function pathToRegExp(path: string): RegExp {
67
- const pattern = path
68
- .split("/")
69
- .map((p) => {
70
- return p.replace(/\[([^\/]+?)\]/, "(?<$1>[^\\/]+?)");
71
- })
72
- .join("\\/");
73
- return new RegExp(`^${pattern}$`);
74
- }
75
-
76
- function loadHandler(handler: RouteHandler) {
77
- handler.layouts = findLayouts(handler.path, fileRoutes);
78
- handler.serverEndPoint = findServer(handler.path, fileRoutes);
79
- handler.serverHook = findServerHook(handler.path, fileRoutes);
80
- }
81
-
82
- function findLayouts(path: string, fileRoutes: RouteModule[]): RouteLayoutHandler[] | undefined {
83
- let layouts: RouteLayoutHandler[] = [];
84
- let parts = path
85
- // Strip the trailing`~/server` (so we don't look for `~/server/_layout`
86
- // which will never exist)
87
- .replace(/\/~server$/, "")
88
- // The path will always start with / so splitting e.g. `/first/second`
89
- // will result in ['', 'first', 'second'] and checks for `/_layout`,
90
- // `/first/_layout` and `/second/_layout`
91
- .split("/");
92
- let basePath = "";
93
- for (let i = 0; i < parts.length; i++) {
94
- if (i > 0) {
95
- basePath += "/" + parts[i];
96
- }
97
- const layoutPath = basePath + "/_layout";
98
- const layoutRoute = fileRoutes.find((r) => r.path === layoutPath);
99
- if (layoutRoute) {
100
- layouts.push({
101
- path: layoutPath,
102
- endPoint: lazyRoute(layoutRoute.$handler, clientManifest, serverManifest),
103
- serverEndPoint: findServer(layoutPath, fileRoutes),
104
- });
105
- }
106
- }
107
- return layouts.length ? layouts : undefined;
108
- }
109
-
110
- function findServer(path: string, fileRoutes: RouteModule[]): Promise<any> | undefined {
111
- const serverPath = path.replace(/\/$/, "") + "/~server";
112
- const serverRoute = fileRoutes.find((r) => r.path === serverPath);
113
- return serverRoute && lazyRoute(serverRoute.$handler, clientManifest, serverManifest);
114
- }
115
-
116
- function findServerHook(path: string, fileRoutes: RouteModule[]): Promise<any> | undefined {
117
- // TODO: Should this be a collection, like layouts?
118
- let hookPath = "/_hook/~server";
119
- if (path.startsWith("/api/")) {
120
- hookPath = "/api" + hookPath;
121
- }
122
- const hookRoute = fileRoutes.find((r) => r.path === hookPath);
123
- return hookRoute && lazyRoute(hookRoute.$handler, clientManifest, serverManifest);
124
- }
125
-
126
- export default routeHandlers;
@@ -1,8 +0,0 @@
1
- import { type CookieSerializeOptions } from "vinxi/http";
2
-
3
- type CookieHelper = {
4
- get: (name: string) => string | undefined;
5
- set: (name: string, value: string, options?: CookieSerializeOptions) => void;
6
- delete: (name: string, options?: CookieSerializeOptions) => void;
7
- };
8
- export default CookieHelper;
@@ -1,4 +0,0 @@
1
- type UserConfig = {
2
- port?: number;
3
- };
4
- export default UserConfig;