@solidjs/start 1.0.11 → 1.1.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.
@@ -58,7 +58,7 @@ export class SolidStartClientFileRouter extends BaseFileSystemRouter {
58
58
  }
59
59
  }
60
60
 
61
- const HTTP_METHODS = ["HEAD", "GET", "POST", "PUT", "DELETE", "PATCH"];
61
+ const HTTP_METHODS = ["HEAD", "GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"];
62
62
  function createHTTPHandlers(src, exports) {
63
63
  const handlers = {};
64
64
  for (const exp of exports) {
package/config/index.js CHANGED
@@ -1,5 +1,4 @@
1
- import { serverFunctions } from "@vinxi/server-functions/plugin";
2
- import { server as serverFunctionServer, serverTransform } from "@vinxi/server-functions/server";
1
+ import { createTanStackServerFnPlugin } from "@tanstack/server-functions-plugin";
3
2
  import defu from "defu";
4
3
  import { existsSync } from "node:fs";
5
4
  import { join } from "node:path";
@@ -38,6 +37,36 @@ function solidStartServerFsRouter(config) {
38
37
  );
39
38
  }
40
39
 
40
+ const SolidStartServerFnsPlugin = createTanStackServerFnPlugin({
41
+ // This is the ID that will be available to look up and import
42
+ // our server function manifest and resolve its module
43
+ manifestVirtualImportId: "solidstart:server-fn-manifest",
44
+ client: {
45
+ getRuntimeCode: () =>
46
+ `import { createServerReference } from "${normalize(
47
+ fileURLToPath(new URL("../dist/runtime/server-runtime.js", import.meta.url))
48
+ )}"`,
49
+ replacer: opts =>
50
+ `createServerReference(${() => {}}, '${opts.functionId}', '${opts.extractedFilename}')`
51
+ },
52
+ ssr: {
53
+ getRuntimeCode: () =>
54
+ `import { createServerReference } from '${normalize(
55
+ fileURLToPath(new URL("../dist/runtime/server-fns-runtime.js", import.meta.url))
56
+ )}'`,
57
+ replacer: opts =>
58
+ `createServerReference(${opts.fn}, '${opts.functionId}', '${opts.extractedFilename}')`
59
+ },
60
+ server: {
61
+ getRuntimeCode: () =>
62
+ `import { createServerReference } from '${normalize(
63
+ fileURLToPath(new URL("../dist/runtime/server-fns-runtime.js", import.meta.url))
64
+ )}'`,
65
+ replacer: opts =>
66
+ `createServerReference(${opts.fn}, '${opts.functionId}', '${opts.extractedFilename}')`
67
+ }
68
+ });
69
+
41
70
  export function defineConfig(baseConfig = {}) {
42
71
  let { vite = {}, ...start } = baseConfig;
43
72
  const extensions = [...DEFAULT_EXTENSIONS, ...(start.extensions || [])];
@@ -112,11 +141,7 @@ export function defineConfig(baseConfig = {}) {
112
141
  }
113
142
  }),
114
143
  ...plugins,
115
- serverTransform({
116
- runtime: normalize(
117
- fileURLToPath(new URL("../dist/runtime/server-fns-runtime.js", import.meta.url))
118
- )
119
- }),
144
+ SolidStartServerFnsPlugin.ssr,
120
145
  start.experimental.islands ? serverComponents.server() : null,
121
146
  solid({ ...start.solid, ssr: true, extensions: extensions.map(ext => `.${ext}`) }),
122
147
  config("app-server", {
@@ -177,11 +202,7 @@ export function defineConfig(baseConfig = {}) {
177
202
  }
178
203
  }),
179
204
  ...plugins,
180
- serverFunctions.client({
181
- runtime: normalize(
182
- fileURLToPath(new URL("../dist/runtime/server-runtime.js", import.meta.url))
183
- )
184
- }),
205
+ SolidStartServerFnsPlugin.client,
185
206
  start.experimental.islands ? serverComponents.client() : null,
186
207
  solid({ ...start.solid, ssr: start.ssr, extensions: extensions.map(ext => `.${ext}`) }),
187
208
  config("app-client", {
@@ -247,11 +268,7 @@ export function defineConfig(baseConfig = {}) {
247
268
  cacheDir: "node_modules/.vinxi/server-fns"
248
269
  }),
249
270
  ...plugins,
250
- serverFunctionServer({
251
- runtime: normalize(
252
- fileURLToPath(new URL("../dist/runtime/server-fns-runtime.js", import.meta.url))
253
- )
254
- }),
271
+ SolidStartServerFnsPlugin.server,
255
272
  start.experimental.islands ? serverComponents.server() : null,
256
273
  solid({ ...start.solid, ssr: true, extensions: extensions.map(ext => `.${ext}`) }),
257
274
  config("app-server", {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
+ export { default as clientOnly } from "./shared/clientOnly";
1
2
  export { GET } from "./shared/GET";
2
3
  export { HttpHeader } from "./shared/HttpHeader";
3
4
  export { HttpStatusCode } from "./shared/HttpStatusCode";
4
- export { default as clientOnly } from "./shared/clientOnly";
5
+ export { getServerFunctionMeta } from "./shared/serverFunction";
package/dist/index.jsx CHANGED
@@ -1,5 +1,6 @@
1
1
  // @refresh skip
2
+ export { default as clientOnly } from "./shared/clientOnly";
2
3
  export { GET } from "./shared/GET";
3
4
  export { HttpHeader } from "./shared/HttpHeader";
4
5
  export { HttpStatusCode } from "./shared/HttpStatusCode";
5
- export { default as clientOnly } from "./shared/clientOnly";
6
+ export { getServerFunctionMeta } from "./shared/serverFunction";
@@ -5,11 +5,8 @@ function wrapRequestMiddleware(onRequest) {
5
5
  return async (h3Event) => {
6
6
  const fetchEvent = getFetchEvent(h3Event);
7
7
  const response = await onRequest(fetchEvent);
8
- if (!response) {
9
- return;
10
- }
11
- else {
12
- sendWebResponse(h3Event, response);
8
+ if (response) {
9
+ await sendWebResponse(h3Event, response);
13
10
  }
14
11
  };
15
12
  }
@@ -17,11 +14,8 @@ function wrapResponseMiddleware(onBeforeResponse) {
17
14
  return async (h3Event, response) => {
18
15
  const fetchEvent = getFetchEvent(h3Event);
19
16
  const mwResponse = await onBeforeResponse(fetchEvent, response);
20
- if (!mwResponse) {
21
- return;
22
- }
23
- else {
24
- sendWebResponse(h3Event, mwResponse);
17
+ if (mwResponse) {
18
+ await sendWebResponse(h3Event, mwResponse);
25
19
  }
26
20
  };
27
21
  }
@@ -7,7 +7,11 @@ function defineRoutes(fileRoutes) {
7
7
  return id.startsWith(o.id + "/");
8
8
  });
9
9
  if (!parentRoute) {
10
- routes.push({ ...route, id, path: id.replace(/\/\([^)/]+\)/g, "").replace(/\([^)/]+\)/g, "") });
10
+ routes.push({
11
+ ...route,
12
+ id,
13
+ path: id.replace(/\/\([^)/]+\)/g, "").replace(/\([^)/]+\)/g, "")
14
+ });
11
15
  return routes;
12
16
  }
13
17
  processRoute(parentRoute.children || (parentRoute.children = []), route, id.slice(parentRoute.id.length), full);
@@ -32,13 +36,24 @@ export function matchAPIRoute(path, method) {
32
36
  }
33
37
  }
34
38
  function containsHTTP(route) {
35
- return route["$HEAD"] || route["$GET"] || route["$POST"] || route["$PUT"] || route["$PATCH"] || route["$DELETE"];
39
+ return (route["$HEAD"] ||
40
+ route["$GET"] ||
41
+ route["$POST"] ||
42
+ route["$PUT"] ||
43
+ route["$PATCH"] ||
44
+ route["$DELETE"]);
36
45
  }
37
46
  const router = createRouter({
38
47
  routes: fileRoutes.reduce((memo, route) => {
39
48
  if (!containsHTTP(route))
40
49
  return memo;
41
- let path = route.path.replace(/\/\([^)/]+\)/g, "").replace(/\([^)/]+\)/g, "").replace(/\*([^/]*)/g, (_, m) => `**:${m}`).split('/').map(s => (s.startsWith(':') || s.startsWith('*')) ? s : encodeURIComponent(s)).join('/');
50
+ let path = route.path
51
+ .replace(/\/\([^)/]+\)/g, "")
52
+ .replace(/\([^)/]+\)/g, "")
53
+ .replace(/\*([^/]*)/g, (_, m) => `**:${m}`)
54
+ .split("/")
55
+ .map(s => (s.startsWith(":") || s.startsWith("*") ? s : encodeURIComponent(s)))
56
+ .join("/");
42
57
  if (/:[^/]*\?/g.test(path)) {
43
58
  throw new Error(`Optional parameters are not supported in API routes: ${path}`);
44
59
  }
@@ -10,6 +10,8 @@ import invariant from "vinxi/lib/invariant";
10
10
  import { cloneEvent, getFetchEvent, mergeResponseHeaders } from "../server/fetchEvent";
11
11
  import { getExpectedRedirectStatus } from "../server/handler";
12
12
  import { createPageEvent } from "../server/pageEvent";
13
+ // @ts-ignore
14
+ import serverFnManifest from "solidstart:server-fn-manifest";
13
15
  function createChunk(data) {
14
16
  const encodeData = new TextEncoder().encode(data);
15
17
  const bytes = encodeData.length;
@@ -58,18 +60,40 @@ async function handleServerFunction(h3Event) {
58
60
  const instance = request.headers.get("X-Server-Instance");
59
61
  const singleFlight = request.headers.has("X-Single-Flight");
60
62
  const url = new URL(request.url);
61
- let filepath, name;
63
+ let functionId, name;
62
64
  if (serverReference) {
63
65
  invariant(typeof serverReference === "string", "Invalid server function");
64
- [filepath, name] = serverReference.split("#");
66
+ [functionId, name] = serverReference.split("#");
65
67
  }
66
68
  else {
67
- filepath = url.searchParams.get("id");
69
+ functionId = url.searchParams.get("id");
68
70
  name = url.searchParams.get("name");
69
- if (!filepath || !name)
70
- throw new Error("Invalid request");
71
+ if (!functionId || !name) {
72
+ return process.env.NODE_ENV === "development"
73
+ ? new Response("Server function not found", { status: 404 })
74
+ : new Response(null, { status: 404 });
75
+ }
76
+ }
77
+ const serverFnInfo = serverFnManifest[functionId];
78
+ let fnModule;
79
+ if (!serverFnInfo) {
80
+ return process.env.NODE_ENV === "development"
81
+ ? new Response("Server function not found", { status: 404 })
82
+ : new Response(null, { status: 404 });
83
+ }
84
+ if (process.env.NODE_ENV === "development") {
85
+ // In dev, we use Vinxi to get the "server" server-side router
86
+ // Then we use that router's devServer.ssrLoadModule to get the serverFn
87
+ // This code comes from:
88
+ // https://github.com/TanStack/router/blob/266f5cc863cd1a99809d1af2669e58b6b6db9a67/packages/start-server-functions-handler/src/index.tsx#L83-L87
89
+ fnModule = await globalThis.app
90
+ .getRouter("server-fns")
91
+ .internals.devServer.ssrLoadModule(serverFnInfo.extractedFilename);
92
+ }
93
+ else {
94
+ fnModule = await serverFnInfo.importer();
71
95
  }
72
- const serverFunction = (await import.meta.env.MANIFEST[import.meta.env.ROUTER_NAME].chunks[filepath].import())[name];
96
+ const serverFunction = fnModule[serverFnInfo.functionName];
73
97
  let parsed = [];
74
98
  // grab bound arguments from url when no JS
75
99
  if (!instance || h3Event.method === "GET") {
@@ -101,7 +125,8 @@ async function handleServerFunction(h3Event) {
101
125
  // But the new azure-functions preset for some reason uses a ReadableStream in node.req (#1521)
102
126
  const isReadableStream = h3Request instanceof ReadableStream;
103
127
  const hasReadableStream = h3Request.body instanceof ReadableStream;
104
- const isH3EventBodyStreamLocked = (isReadableStream && h3Request.locked) || (hasReadableStream && h3Request.body.locked);
128
+ const isH3EventBodyStreamLocked = (isReadableStream && h3Request.locked) ||
129
+ (hasReadableStream && h3Request.body.locked);
105
130
  const requestBody = isReadableStream ? h3Request : h3Request.body;
106
131
  if (contentType?.startsWith("multipart/form-data") ||
107
132
  contentType?.startsWith("application/x-www-form-urlencoded")) {
@@ -142,7 +167,7 @@ async function handleServerFunction(h3Event) {
142
167
  /* @ts-ignore */
143
168
  sharedConfig.context = { event };
144
169
  event.locals.serverFunctionMeta = {
145
- id: filepath + "#" + name
170
+ id: functionId + "#" + name
146
171
  };
147
172
  return serverFunction(...parsed);
148
173
  });
@@ -247,7 +272,7 @@ function createSingleFlightHeaders(sourceEvent) {
247
272
  useH3Internals = true;
248
273
  sourceEvent.nativeEvent.node.req.headers.cookie = "";
249
274
  }
250
- SetCookies.forEach((cookie) => {
275
+ SetCookies.forEach(cookie => {
251
276
  if (!cookie)
252
277
  return;
253
278
  const keyValue = cookie.split(";")[0];
@@ -1,4 +1,6 @@
1
- export { StartServer } from "./StartServer";
2
1
  export { createHandler } from "./handler";
3
- export { getServerFunctionMeta } from "./serverFunction";
4
- export type { DocumentComponentProps, Asset, HandlerOptions, ContextMatches, ResponseStub, FetchEvent, RequestEventLocals, PageEvent, APIEvent, APIHandler, ServerFunctionMeta } from "./types";
2
+ export { StartServer } from "./StartServer";
3
+ export type { APIEvent, APIHandler, Asset, ContextMatches, DocumentComponentProps, FetchEvent, HandlerOptions, PageEvent, ResponseStub, ServerFunctionMeta } from "./types";
4
+ import { getServerFunctionMeta as getServerFunctionMeta_ } from "../shared/serverFunction";
5
+ /** @deprecated */
6
+ export declare const getServerFunctionMeta: typeof getServerFunctionMeta_;
@@ -1,4 +1,6 @@
1
1
  // @refresh skip
2
- export { StartServer } from "./StartServer";
3
2
  export { createHandler } from "./handler";
4
- export { getServerFunctionMeta } from "./serverFunction";
3
+ export { StartServer } from "./StartServer";
4
+ import { getServerFunctionMeta as getServerFunctionMeta_ } from "../shared/serverFunction";
5
+ /** @deprecated */
6
+ export const getServerFunctionMeta = getServerFunctionMeta_;
@@ -49,12 +49,9 @@ export interface FetchEvent {
49
49
  request: Request;
50
50
  response: ResponseStub;
51
51
  clientAddress?: string;
52
- locals: RequestEventLocals;
52
+ locals: App.RequestEventLocals;
53
53
  nativeEvent: HTTPEvent;
54
54
  }
55
- export interface RequestEventLocals {
56
- [key: string | symbol]: any;
57
- }
58
55
  export interface PageEvent extends RequestEvent {
59
56
  manifest: any;
60
57
  assets: any;
@@ -1,16 +1,18 @@
1
- import { getHighlighterCore, loadWasm } from 'shikiji/core';
1
+ // @refresh skip
2
+ import { getSingletonHighlighter } from 'shiki';
3
+ import { loadWasm } from 'shiki/engine/oniguruma';
2
4
  import { createEffect, createResource } from 'solid-js';
3
- import url from 'shikiji/onig.wasm?url';
4
- import langJS from 'shikiji/langs/javascript.mjs';
5
- import langJSX from 'shikiji/langs/jsx.mjs';
6
- import langTSX from 'shikiji/langs/tsx.mjs';
7
- import langTS from 'shikiji/langs/typescript.mjs';
8
- import darkPlus from 'shikiji/themes/dark-plus.mjs';
5
+ import url from 'shiki/onig.wasm?url';
6
+ import langJS from 'shiki/langs/javascript.mjs';
7
+ import langJSX from 'shiki/langs/jsx.mjs';
8
+ import langTSX from 'shiki/langs/tsx.mjs';
9
+ import langTS from 'shiki/langs/typescript.mjs';
10
+ import darkPlus from 'shiki/themes/dark-plus.mjs';
9
11
  let HIGHLIGHTER;
10
12
  async function loadHighlighter() {
11
13
  if (!HIGHLIGHTER) {
12
14
  await loadWasm(await fetch(url));
13
- HIGHLIGHTER = await getHighlighterCore({
15
+ HIGHLIGHTER = await getSingletonHighlighter({
14
16
  themes: [
15
17
  darkPlus,
16
18
  ],
@@ -1,4 +1,4 @@
1
- import type { ServerFunctionMeta } from "./types";
1
+ import type { ServerFunctionMeta } from "../server/types";
2
2
  /**
3
3
  *
4
4
  * Read more: https://docs.solidjs.com/solid-start/reference/server/get-server-function-meta
package/env.d.ts CHANGED
@@ -4,6 +4,12 @@
4
4
 
5
5
  /* eslint-disable @typescript-eslint/consistent-type-imports */
6
6
 
7
+ declare namespace App {
8
+ export interface RequestEventLocals {
9
+ [key: string | symbol]: any;
10
+ }
11
+ }
12
+
7
13
  interface ImportMetaEnv extends Record<`VITE_${string}`, any>, SolidStartMetaEnv {
8
14
  BASE_URL: string;
9
15
  MODE: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidjs/start",
3
- "version": "1.0.11",
3
+ "version": "1.1.1",
4
4
  "type": "module",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",
@@ -55,25 +55,27 @@
55
55
  }
56
56
  },
57
57
  "devDependencies": {
58
- "solid-js": "^1.9.2",
59
- "vinxi": "^0.4.3",
60
- "typescript": "^5.4.2"
58
+ "solid-js": "^1.9.4",
59
+ "vinxi": "^0.5.3"
61
60
  },
62
61
  "dependencies": {
63
- "@vinxi/plugin-directives": "^0.4.3",
64
- "@vinxi/server-components": "^0.4.3",
65
- "@vinxi/server-functions": "^0.4.3",
62
+ "@vinxi/plugin-directives": "^0.5.0",
63
+ "@vinxi/server-components": "^0.5.0",
64
+ "@tanstack/server-functions-plugin": "^1.103.1",
66
65
  "defu": "^6.1.2",
67
66
  "error-stack-parser": "^2.1.4",
68
67
  "html-to-image": "^1.11.11",
69
68
  "radix3": "^1.1.0",
70
69
  "seroval": "^1.0.2",
71
70
  "seroval-plugins": "^1.0.2",
72
- "shikiji": "^0.9.12",
71
+ "shiki": "^1.26.1",
73
72
  "source-map-js": "^1.0.2",
74
73
  "terracotta": "^1.0.4",
75
74
  "tinyglobby": "^0.2.2",
76
- "vite-plugin-solid": "^2.11.0"
75
+ "vite-plugin-solid": "^2.11.1"
76
+ },
77
+ "peerDependencies": {
78
+ "vinxi": "^0.5.3"
77
79
  },
78
80
  "scripts": {
79
81
  "typecheck": "tsc --noEmit",
File without changes