@solidjs/start 2.0.0-rc.5 → 2.0.0-rc.6
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 +13 -0
- package/dist/config/constants.d.ts +1 -0
- package/dist/config/constants.js +1 -0
- package/dist/config/index.d.ts +18 -1
- package/dist/config/manifest.js +8 -0
- package/dist/fns/client.js +2 -3
- package/dist/fns/error-handler.d.ts +3 -0
- package/dist/fns/error-handler.js +5 -0
- package/dist/fns/handler.d.ts +1 -1
- package/dist/fns/handler.js +10 -2
- package/dist/server/index.d.ts +1 -0
- package/dist/shared/dev-toolbar/index.jsx +0 -1
- package/package.json +7 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @solidjs/start
|
|
2
2
|
|
|
3
|
+
## 2.0.0-rc.6
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- bac24b2: Add a `serverFunctions.onError` option naming a module that observes and replaces what a server function threw, before it is serialized into the response
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 27c2877: Remove leftover debug `console.log` calls from the server functions inspector, which logged on every server function request in dev.
|
|
12
|
+
- f15724b: Declare `@solidjs/router` as an optional peer dependency constrained to `>=0.16.0 <2.0.0-0`. Router v2 is expected to target Solid v2, so installing it alongside `@solidjs/start` v2 now surfaces a peer warning instead of silently producing an incompatible pairing. The peer is marked optional, so apps that do not use the router are unaffected.
|
|
13
|
+
- 5c8612f: Apply cookies set on a returned or thrown response during single flight mutations. `redirect(to, { headers: { "Set-Cookie": ... } })` previously only reached the browser: the single flight re-render of the redirect target still ran with the old request cookies, so queries reading that cookie saw stale values. Those cookies are now merged into the request the re-render sees, matching what a browser round trip would have sent.
|
|
14
|
+
- 83122ed: Reject server function calls when the response is a 5xx without an X-Error header, instead of resolving with the parsed error body
|
|
15
|
+
|
|
3
16
|
## 2.0.0-rc.5
|
|
4
17
|
|
|
5
18
|
### Minor Changes
|
|
@@ -7,6 +7,7 @@ export declare const VIRTUAL_MODULES: {
|
|
|
7
7
|
readonly middleware: "solid-start:middleware";
|
|
8
8
|
readonly serovalPlugins: "solid-start:seroval-plugins";
|
|
9
9
|
readonly serverFnManifest: "solid-start:server-fn-manifest";
|
|
10
|
+
readonly serverFnErrorHandler: "solid-start:server-fn-error-handler";
|
|
10
11
|
readonly clientEntry: "solid-start:client-entry";
|
|
11
12
|
readonly serverEntry: "solid-start:server-entry";
|
|
12
13
|
readonly app: "solid-start:app";
|
package/dist/config/constants.js
CHANGED
|
@@ -7,6 +7,7 @@ export const VIRTUAL_MODULES = {
|
|
|
7
7
|
middleware: "solid-start:middleware",
|
|
8
8
|
serovalPlugins: "solid-start:seroval-plugins",
|
|
9
9
|
serverFnManifest: "solid-start:server-fn-manifest",
|
|
10
|
+
serverFnErrorHandler: "solid-start:server-fn-error-handler",
|
|
10
11
|
clientEntry: "solid-start:client-entry",
|
|
11
12
|
serverEntry: "solid-start:server-entry",
|
|
12
13
|
app: "solid-start:app",
|
package/dist/config/index.d.ts
CHANGED
|
@@ -118,6 +118,23 @@ export interface SolidStartOptions {
|
|
|
118
118
|
* Options controlling which files are processed as server functions
|
|
119
119
|
* (inclusion / exclusion filters for the `"use server"` transform).
|
|
120
120
|
*/
|
|
121
|
-
serverFunctions?: Pick<ServerFunctionsOptions, "filter"
|
|
121
|
+
serverFunctions?: Pick<ServerFunctionsOptions, "filter"> & {
|
|
122
|
+
/**
|
|
123
|
+
* Path to a module whose default export is called with whatever a server
|
|
124
|
+
* function threw, before it is serialized into the response. Return a
|
|
125
|
+
* value to send it in place of what was thrown, or `undefined` to send the
|
|
126
|
+
* original.
|
|
127
|
+
*
|
|
128
|
+
* Naming the module here rather than registering a handler at runtime
|
|
129
|
+
* keeps the app in sole control of it: no dependency can reach into the
|
|
130
|
+
* running server and take over reporting.
|
|
131
|
+
*
|
|
132
|
+
* The module is bundled into the server only, so it may import server-only
|
|
133
|
+
* code such as a monitoring SDK.
|
|
134
|
+
*
|
|
135
|
+
* @example "src/server-fn-error.ts"
|
|
136
|
+
*/
|
|
137
|
+
onError?: string;
|
|
138
|
+
};
|
|
122
139
|
}
|
|
123
140
|
export declare function solidStart(options?: SolidStartOptions): Array<PluginOption>;
|
package/dist/config/manifest.js
CHANGED
|
@@ -34,6 +34,12 @@ export function manifest(start) {
|
|
|
34
34
|
return await this.resolve(plugins);
|
|
35
35
|
return `\0${VIRTUAL_MODULES.serovalPlugins}`;
|
|
36
36
|
}
|
|
37
|
+
if (id === VIRTUAL_MODULES.serverFnErrorHandler) {
|
|
38
|
+
const onError = start.serverFunctions?.onError;
|
|
39
|
+
if (onError)
|
|
40
|
+
return await this.resolve(onError);
|
|
41
|
+
return `\0${VIRTUAL_MODULES.serverFnErrorHandler}`;
|
|
42
|
+
}
|
|
37
43
|
},
|
|
38
44
|
async load(id) {
|
|
39
45
|
if (id === `\0${VIRTUAL_MODULES.clientViteManifest}`) {
|
|
@@ -84,6 +90,8 @@ export function manifest(start) {
|
|
|
84
90
|
return "export default {};";
|
|
85
91
|
else if (id === `\0${VIRTUAL_MODULES.serovalPlugins}`)
|
|
86
92
|
return "export default [];";
|
|
93
|
+
else if (id === `\0${VIRTUAL_MODULES.serverFnErrorHandler}`)
|
|
94
|
+
return "export default undefined;";
|
|
87
95
|
else if (id.startsWith("/@manifest")) {
|
|
88
96
|
if (this.environment.mode !== "dev")
|
|
89
97
|
throw new Error("@manifest queries are only allowed in dev");
|
package/dist/fns/client.js
CHANGED
|
@@ -15,7 +15,6 @@ async function createRequest(base, id, instance, options) {
|
|
|
15
15
|
},
|
|
16
16
|
});
|
|
17
17
|
if (import.meta.env.DEV) {
|
|
18
|
-
console.log(pushRequest);
|
|
19
18
|
pushRequest(id, instance, request.clone());
|
|
20
19
|
}
|
|
21
20
|
const response = await fetch(request);
|
|
@@ -73,8 +72,8 @@ async function fetchServerFunction(base, id, options, args) {
|
|
|
73
72
|
return response;
|
|
74
73
|
}
|
|
75
74
|
const result = await extractBody(instance, true, response.clone());
|
|
76
|
-
if (response.headers.has("X-Error")) {
|
|
77
|
-
throw result;
|
|
75
|
+
if (response.headers.has("X-Error") || response.status >= 500) {
|
|
76
|
+
throw result ?? new Error(`Server function call failed with status ${response.status}`);
|
|
78
77
|
}
|
|
79
78
|
return result;
|
|
80
79
|
}
|
package/dist/fns/handler.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ import { type H3Event } from "h3";
|
|
|
2
2
|
import "solid-start:server-fn-manifest";
|
|
3
3
|
import type { FetchEvent } from "../server/types.ts";
|
|
4
4
|
export declare function handleServerFunction(h3Event: H3Event): Promise<unknown>;
|
|
5
|
-
export declare function createSingleFlightHeaders(sourceEvent: FetchEvent): Headers;
|
|
5
|
+
export declare function createSingleFlightHeaders(sourceEvent: FetchEvent, result?: unknown): Headers;
|
package/dist/fns/handler.js
CHANGED
|
@@ -17,6 +17,7 @@ import { deserializeFromJSONString, serializeToJSONStream, serializeToJSStream,
|
|
|
17
17
|
import { BODY_FORMAT_KEY, BodyFormat, extractBody, getHeadersAndBody } from "./shared.js";
|
|
18
18
|
import "solid-start:server-fn-manifest";
|
|
19
19
|
import { getServerFunction, hasServerFunction } from "./registration.js";
|
|
20
|
+
import { applyServerFunctionErrorHandler } from "./error-handler.js";
|
|
20
21
|
import { getExpectedRedirectStatus } from "../server/util.js";
|
|
21
22
|
export async function handleServerFunction(h3Event) {
|
|
22
23
|
const event = getFetchEvent(h3Event);
|
|
@@ -124,6 +125,7 @@ export async function handleServerFunction(h3Event) {
|
|
|
124
125
|
return serializeToJSONStream(result);
|
|
125
126
|
}
|
|
126
127
|
catch (x) {
|
|
128
|
+
x = applyServerFunctionErrorHandler(x);
|
|
127
129
|
if (x instanceof Response) {
|
|
128
130
|
if (singleFlight && instance) {
|
|
129
131
|
x = await handleSingleFlight(event, x);
|
|
@@ -236,13 +238,19 @@ async function handleNoJS(result, request, parsed, thrown) {
|
|
|
236
238
|
});
|
|
237
239
|
}
|
|
238
240
|
let App;
|
|
239
|
-
export function createSingleFlightHeaders(sourceEvent) {
|
|
241
|
+
export function createSingleFlightHeaders(sourceEvent, result) {
|
|
240
242
|
// cookie handling logic is pretty simplistic so this might be imperfect
|
|
241
243
|
// unclear if h3 internals are available on all platforms but we need a way to
|
|
242
244
|
// update request headers on the underlying H3 event.
|
|
243
245
|
const headers = new Headers(sourceEvent.request.headers);
|
|
244
246
|
const cookies = parseCookies(sourceEvent.nativeEvent);
|
|
245
247
|
const SetCookies = sourceEvent.response.headers.getSetCookie();
|
|
248
|
+
// cookies attached to the returned/thrown response (eg. `redirect(to, { headers })`)
|
|
249
|
+
// haven't been merged onto the event response yet, but a browser round trip would
|
|
250
|
+
// have sent them back with the next request, so apply them here too. They come after
|
|
251
|
+
// the ones on the event response, so they win on conflict.
|
|
252
|
+
if (result instanceof Response)
|
|
253
|
+
SetCookies.push(...result.headers.getSetCookie());
|
|
246
254
|
headers.delete("cookie");
|
|
247
255
|
// let useH3Internals = false;
|
|
248
256
|
// if (sourceEvent.nativeEvent.node?.req) {
|
|
@@ -286,7 +294,7 @@ async function handleSingleFlight(sourceEvent, result) {
|
|
|
286
294
|
}
|
|
287
295
|
const event = { ...sourceEvent };
|
|
288
296
|
event.request = new Request(url, {
|
|
289
|
-
headers: createSingleFlightHeaders(sourceEvent),
|
|
297
|
+
headers: createSingleFlightHeaders(sourceEvent, result),
|
|
290
298
|
});
|
|
291
299
|
return await provideRequestEvent(event, async () => {
|
|
292
300
|
await createPageEvent(event);
|
package/dist/server/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export { getServerFunctionMeta } from "../shared/serverFunction.ts";
|
|
|
3
3
|
export { StartServer } from "./StartServer.tsx";
|
|
4
4
|
export { decorateHandler, decorateMiddleware } from "./fetchEvent.ts";
|
|
5
5
|
export { createHandler } from "./handler.ts";
|
|
6
|
+
export type { ServerFunctionErrorHandler } from "../fns/error-handler.ts";
|
|
6
7
|
export type { APIEvent, APIHandler, Asset, ContextMatches, DocumentComponentProps, FetchEvent, HandlerOptions, PageEvent, ResponseStub, ServerFunctionMeta, StartHandler, } from "./types.ts";
|
|
7
8
|
/**
|
|
8
9
|
* Checks if user has set a redirect status in the response.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidjs/start",
|
|
3
|
-
"version": "2.0.0-rc.
|
|
3
|
+
"version": "2.0.0-rc.6",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/solidjs/solid-start.git",
|
|
@@ -64,8 +64,14 @@
|
|
|
64
64
|
"vitest": "^4.1.10"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
|
+
"@solidjs/router": ">=0.16.0 <2.0.0-0",
|
|
67
68
|
"vite": "^8 || ^9"
|
|
68
69
|
},
|
|
70
|
+
"peerDependenciesMeta": {
|
|
71
|
+
"@solidjs/router": {
|
|
72
|
+
"optional": true
|
|
73
|
+
}
|
|
74
|
+
},
|
|
69
75
|
"engines": {
|
|
70
76
|
"node": ">=24"
|
|
71
77
|
},
|