@solidjs/web 2.0.0-experimental.8 → 2.0.0-rc.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 (85) hide show
  1. package/README.md +22 -4
  2. package/dist/dev.cjs +1585 -225
  3. package/dist/dev.js +1510 -201
  4. package/dist/server.cjs +2642 -264
  5. package/dist/server.js +2542 -217
  6. package/dist/web.cjs +1523 -218
  7. package/dist/web.js +1448 -194
  8. package/frames/dist/client.cjs +1916 -0
  9. package/frames/dist/client.dev.cjs +1933 -0
  10. package/frames/dist/client.dev.js +1921 -0
  11. package/frames/dist/client.js +1904 -0
  12. package/frames/dist/server.cjs +3667 -0
  13. package/frames/dist/server.js +3654 -0
  14. package/frames/package.json +30 -0
  15. package/package.json +349 -37
  16. package/serialization/decode/package.json +20 -0
  17. package/serialization/dist/decode.cjs +110 -0
  18. package/serialization/dist/decode.js +104 -0
  19. package/serialization/dist/serialization.cjs +232 -0
  20. package/serialization/dist/serialization.js +215 -0
  21. package/serialization/package.json +20 -0
  22. package/serialization/types/index.d.ts +182 -0
  23. package/serialization/types/serializer-decode.d.ts +182 -0
  24. package/serialization/types-cjs/index.d.cts +182 -0
  25. package/serialization/types-cjs/package.json +3 -0
  26. package/serialization/types-cjs/serializer-decode.d.cts +182 -0
  27. package/server-functions/dist/client.cjs +646 -0
  28. package/server-functions/dist/client.js +617 -0
  29. package/server-functions/dist/rich-args.cjs +11 -0
  30. package/server-functions/dist/rich-args.js +9 -0
  31. package/server-functions/dist/server.cjs +1077 -0
  32. package/server-functions/dist/server.dev.cjs +1077 -0
  33. package/server-functions/dist/server.dev.js +1045 -0
  34. package/server-functions/dist/server.js +1045 -0
  35. package/server-functions/package.json +40 -0
  36. package/server-functions/rich-args/package.json +20 -0
  37. package/storage/package.json +8 -3
  38. package/storage/types/index.d.ts +26 -0
  39. package/storage/types-cjs/index.d.cts +28 -0
  40. package/storage/types-cjs/package.json +3 -0
  41. package/types/client.d.ts +290 -27
  42. package/types/cookies.d.ts +93 -0
  43. package/types/core.d.ts +6 -2
  44. package/types/frames/client.d.ts +36 -0
  45. package/types/frames/frame-client.d.ts +338 -0
  46. package/types/frames/frame-sink.d.ts +194 -0
  47. package/types/frames/frame-transport.d.ts +222 -0
  48. package/types/frames/serializer.d.ts +182 -0
  49. package/types/frames/server.d.ts +52 -0
  50. package/types/index.d.ts +209 -24
  51. package/types/jsx-properties.d.ts +93 -0
  52. package/types/jsx.d.ts +4150 -1
  53. package/types/response.d.ts +174 -0
  54. package/types/serializer-decode.d.ts +182 -0
  55. package/types/serializer.d.ts +182 -0
  56. package/types/server-functions/client.d.ts +201 -0
  57. package/types/server-functions/flash.d.ts +38 -0
  58. package/types/server-functions/rich-args.d.ts +10 -0
  59. package/types/server-functions/server.d.ts +588 -0
  60. package/types/server-functions/shared.d.ts +523 -0
  61. package/types/server-mock.d.ts +249 -12
  62. package/types/server.d.ts +424 -51
  63. package/types-cjs/client.d.cts +337 -0
  64. package/types-cjs/cookies.d.cts +93 -0
  65. package/types-cjs/core.d.cts +6 -0
  66. package/types-cjs/frames/client.d.cts +36 -0
  67. package/types-cjs/frames/frame-client.d.cts +338 -0
  68. package/types-cjs/frames/frame-sink.d.cts +194 -0
  69. package/types-cjs/frames/frame-transport.d.cts +222 -0
  70. package/types-cjs/frames/serializer.d.cts +182 -0
  71. package/types-cjs/frames/server.d.cts +52 -0
  72. package/types-cjs/index.d.cts +230 -0
  73. package/types-cjs/jsx-properties.d.cts +93 -0
  74. package/types-cjs/jsx.d.cts +4150 -0
  75. package/types-cjs/package.json +3 -0
  76. package/types-cjs/response.d.cts +174 -0
  77. package/types-cjs/serializer-decode.d.cts +182 -0
  78. package/types-cjs/serializer.d.cts +182 -0
  79. package/types-cjs/server-functions/client.d.cts +201 -0
  80. package/types-cjs/server-functions/flash.d.cts +38 -0
  81. package/types-cjs/server-functions/rich-args.d.cts +10 -0
  82. package/types-cjs/server-functions/server.d.cts +588 -0
  83. package/types-cjs/server-functions/shared.d.cts +523 -0
  84. package/types-cjs/server-mock.d.cts +277 -0
  85. package/types-cjs/server.d.cts +523 -0
@@ -0,0 +1,588 @@
1
+ import { ResponseEnvelope } from "../response.cjs";
2
+ import { JSONCodecOptions } from "../serializer-decode.cjs";
3
+ import { RequestEvent } from "../server.cjs";
4
+
5
+ export {
6
+ ERROR_HEADER,
7
+ FLASH_COOKIE,
8
+ FUNCTION_HEADER,
9
+ INSTANCE_HEADER,
10
+ SINGLE_FLIGHT_HEADER,
11
+ clearFlashCookie,
12
+ decodeErrorHeaderValue,
13
+ decodeResponse,
14
+ decodeResponsePayload,
15
+ encodeErrorHeaderValue,
16
+ getServerFunctionMetadata,
17
+ hasFlashCookie,
18
+ isServerFunction,
19
+ subscribeFlightData,
20
+ withMeta
21
+ } from "./shared.cjs";
22
+ export type {
23
+ FlightDataConsumer,
24
+ FlightDataContext,
25
+ ServerFunction,
26
+ ServerFunctionMetadata,
27
+ SingleFlightPayload
28
+ } from "./shared.cjs";
29
+ export { decodeFlashCookie, encodeFlashCookie } from "./flash.cjs";
30
+ export type { FlashSubmission } from "./flash.cjs";
31
+ import { ServerFunction } from "./shared.cjs";
32
+
33
+ /**
34
+ * The request event a server function call runs under: the base
35
+ * `RequestEvent` (request + locals) with `serverOnly` added, set when the
36
+ * call is an in-process SSR invocation whose result never serializes to a
37
+ * client.
38
+ */
39
+ export interface ServerFunctionEvent extends RequestEvent {
40
+ serverOnly?: boolean;
41
+ }
42
+
43
+ /**
44
+ * What a server function call resolved to, as seen by the single-flight
45
+ * hook — enough context for any data-production strategy without core
46
+ * assuming one.
47
+ */
48
+ export interface ServerFunctionOutcome {
49
+ /** The build-stable id of the function that ran. */
50
+ id: string;
51
+ /**
52
+ * The value the caller will receive: the raw return for plain results,
53
+ * the unwrapped `value` for `ResponseEnvelope`s, `null` for body-less
54
+ * control-flow `Response`s (redirect/reload).
55
+ */
56
+ value: unknown;
57
+ /**
58
+ * The `Response` carrying the result's HTTP metadata, when there is one
59
+ * (from a returned/thrown `Response` or a `ResponseEnvelope`). Read
60
+ * `Location` here for redirect-with-data — the data should describe the
61
+ * destination route — and `X-Revalidate` for the invalidated keys.
62
+ * Undefined for plain values.
63
+ */
64
+ response: Response | undefined;
65
+ /**
66
+ * The original HTTP request, untouched: headers the client integration
67
+ * sent (referrer, custom route context) ride here for the hook to read —
68
+ * core assigns them no meaning.
69
+ */
70
+ request: Request;
71
+ /** Whether the result was thrown rather than returned. */
72
+ thrown: boolean;
73
+ /**
74
+ * The URL the client will show after the mutation — the redirect
75
+ * `Location` when the outcome carries one (resolved against the request
76
+ * URL, as a browser would), the referring page otherwise. Undefined
77
+ * without a usable referer (a non-browser caller has no page to produce
78
+ * data for) and for redirects leaving the app's origin: produce no data
79
+ * when this is undefined.
80
+ */
81
+ targetUrl: string | undefined;
82
+ /**
83
+ * The outcome's `X-Revalidate` keys, split — the invalidation scope the
84
+ * mutation declared. Undefined when the outcome carries none (integrations
85
+ * typically collect everything for the target in that case).
86
+ */
87
+ revalidateKeys: string[] | undefined;
88
+ /**
89
+ * The request headers with the mutation's cookie effects applied: the
90
+ * event response's `Set-Cookie`s (set during the call), then the
91
+ * outcome's own (e.g. `redirect(to, { headers })`), later winning on
92
+ * conflict, deletions honored. Build the data-collection request from
93
+ * these so re-run reads observe post-mutation cookie state.
94
+ */
95
+ foldedHeaders: Headers;
96
+ }
97
+
98
+ /**
99
+ * The single-flight server hook: given the request event and the function's
100
+ * outcome, optionally produce a data payload (possibly async) to fold into
101
+ * the response alongside the return value. Data production is a black box
102
+ * to the protocol — render data-only, run route preloads, query a cache,
103
+ * whatever the integration chooses; the payload just has to be
104
+ * codec-serializable. Return undefined to send the response unchanged
105
+ * (byte-identical to a call without the hook).
106
+ *
107
+ * Runs after `transformResult`, only for scripted calls that sent
108
+ * `SINGLE_FLIGHT_HEADER` on the request, on returned results and thrown
109
+ * `Response`/`ResponseEnvelope` control-flow signals alike (plain thrown
110
+ * errors never collect, and neither do raw body-carrying `Response` values
111
+ * — those are the caller's verbatim payload). The handler owns the
112
+ * enveloping: contributed data ships as `{ value, data }` under the
113
+ * single-flight response header. The generic halves of collection arrive
114
+ * pre-digested on the outcome (`targetUrl`, `revalidateKeys`,
115
+ * `foldedHeaders`); the hook supplies only the data strategy.
116
+ */
117
+ export type CollectFlightDataHook = (
118
+ event: ServerFunctionEvent,
119
+ outcome: ServerFunctionOutcome
120
+ ) => unknown | Promise<unknown>;
121
+
122
+ /**
123
+ * Wraps a server function execution — the per-invocation seam for
124
+ * framework policies (per-function middleware, auth, logging, error
125
+ * mapping). Called inside the call's event scope with the invocation
126
+ * identity already established: `getServerFunctionInvocation()` answers
127
+ * before, during and after `run()`. Must return (or resolve to) `run()`'s
128
+ * result — replacing it replaces the function's result; throwing routes
129
+ * through the handler's normal error encoding.
130
+ *
131
+ * The context carries the call's identity (`id`, parsed `args`), its
132
+ * `event`, and how it arrived: `direct` is `true` for in-process SSR calls
133
+ * (where `request` is absent) and `false` for HTTP dispatch. On the direct
134
+ * path the wrapper must stay transparent for synchronous functions —
135
+ * return `run()`'s value, not an unconditional promise, unless it needs to
136
+ * be async.
137
+ */
138
+ export type WrapInvocationHook = (
139
+ run: () => unknown,
140
+ context: {
141
+ id: string;
142
+ args: unknown[];
143
+ event: ServerFunctionEvent;
144
+ request?: Request;
145
+ direct: boolean;
146
+ }
147
+ ) => unknown;
148
+
149
+ /**
150
+ * Request headers with `setCookies` folded into the `Cookie` header, as the
151
+ * browser would have applied them before its next request. Later entries
152
+ * win on conflict, and deletions are honored (`Max-Age` at or below zero,
153
+ * `Expires` in the past). The input headers are not modified.
154
+ *
155
+ * For work re-run on the server after a mutation — a
156
+ * `CollectFlightDataHook` gathering fresh data, typically. That pass starts
157
+ * from the request that triggered the mutation, whose cookies are
158
+ * pre-mutation by definition, so a read depending on a session the mutation
159
+ * just established would otherwise see the old state. Which responses
160
+ * contribute their `Set-Cookie`s, and in what order, is the caller's
161
+ * decision.
162
+ *
163
+ * @example
164
+ * ```ts
165
+ * const headers = foldSetCookies(event.request.headers, [
166
+ * ...(event.response?.headers?.getSetCookie() ?? []),
167
+ * ...(outcome.response?.headers?.getSetCookie() ?? [])
168
+ * ]);
169
+ * ```
170
+ */
171
+ export function foldSetCookies(headers: Headers, setCookies: readonly string[]): Headers;
172
+
173
+ /** Options for `createNoJSHandler`. */
174
+ export interface NoJSHandlerOptions {
175
+ /** The app's mount path, for resolving a relative redirect `Location`. */
176
+ base?: string;
177
+ }
178
+
179
+ /**
180
+ * Builds the `handleNoJS` implementation for the no-JS form convention: a
181
+ * form posted without the client runtime has no way to receive a value, so
182
+ * the call redirects back to the referring page (or to the result's own
183
+ * `Location`, resolved against `base`) with the outcome riding a one-shot
184
+ * flash cookie. `303 See Other` turns the POST into a GET unless the result
185
+ * names a redirect status of its own. A result that is already a `Response`
186
+ * carries its meaning in its metadata and is not flashed.
187
+ *
188
+ * The render that follows reads the cookie with `decodeFlashCookie` and
189
+ * surfaces the outcome however it likes — that half is the integration's.
190
+ *
191
+ * The handler applies to every call it receives. `handleServerFunctionRequest`
192
+ * already uses it for browser form posts, so wire it explicitly only to set
193
+ * a `base`, or to extend the convention to direct HTTP calls by registering
194
+ * it through `configureServerFunctionsServer`.
195
+ */
196
+ export function createNoJSHandler(
197
+ options?: NoJSHandlerOptions
198
+ ): (result: unknown, request: Request, args: unknown[], thrown?: boolean) => Response;
199
+
200
+ /** Options for `configureServerFunctionsServer`. */
201
+ export interface ServerFunctionsServerConfig {
202
+ /**
203
+ * Establishes the request-event scope for a call — the function passed
204
+ * runs with `event` visible to `getRequestEvent()`. Wire it to
205
+ * `provideRequestEvent` from `@solidjs/web/storage` (or the framework's
206
+ * equivalent). When omitted, falls back to the AsyncLocalStorage instance
207
+ * an established request scope parks on the global.
208
+ */
209
+ provideEvent?: <T>(event: ServerFunctionEvent, fn: () => T) => T;
210
+ /**
211
+ * Wraps every server function execution — HTTP dispatch and direct SSR
212
+ * calls alike — with the invocation identity already established (see
213
+ * `WrapInvocationHook`). The per-invocation seam for framework policies:
214
+ * per-function middleware, auth, logging, error mapping. A per-request
215
+ * option overrides it for HTTP dispatch.
216
+ */
217
+ wrapInvocation?: WrapInvocationHook;
218
+ /**
219
+ * The single-flight hook: produces the data payload folded into
220
+ * responses of calls that opted in (see `CollectFlightDataHook`).
221
+ * Registered once by the integration that owns data production (a
222
+ * router); per-handler `collectFlightData` options override it.
223
+ */
224
+ collectFlightData?: CollectFlightDataHook;
225
+ /**
226
+ * Server-wide default for the handler's `transformResult` (same contract
227
+ * — see `HandleServerFunctionRequestOptions`); a per-request option
228
+ * overrides it. Registering it here makes result policies (e.g. frames'
229
+ * `frameTransformResult`) work through generic dispatchers that call
230
+ * `handleServerFunctionRequest(request)` with no options.
231
+ */
232
+ transformResult?(
233
+ event: ServerFunctionEvent,
234
+ result: unknown,
235
+ context: {
236
+ id: string;
237
+ args: unknown[];
238
+ instance: string | null;
239
+ request: Request;
240
+ thrown?: boolean;
241
+ }
242
+ ): unknown | ResponseEnvelope | Promise<unknown | ResponseEnvelope>;
243
+ /**
244
+ * `transformResult`'s counterpart for the single-flight fold: when a
245
+ * call's flight payload needs a body only a policy knows how to build
246
+ * (frames' `frameTransformFlightResult` — an invalidated entry is
247
+ * markup), this gets first refusal on the `{ value, data }` outcome.
248
+ * Return a `Response` to carry the outcome (call headers and cookies are
249
+ * copied onto it), or `undefined` to decline and keep the plain
250
+ * serialized envelope. A per-request option overrides it.
251
+ */
252
+ transformFlightResult?(
253
+ event: ServerFunctionEvent,
254
+ outcome: { value: unknown; data: unknown },
255
+ context: { id: string; args: unknown[]; instance: string | null; request: Request }
256
+ ): Response | undefined | Promise<Response | undefined>;
257
+ /**
258
+ * The in-process mirror of `transformResult` for direct (same-server)
259
+ * calls during document SSR — e.g. frames' `frameTransformDirectResult`.
260
+ */
261
+ transformDirectResult?(
262
+ value: unknown,
263
+ options: { id: string; args: unknown[]; event: ServerFunctionEvent }
264
+ ): unknown;
265
+ /**
266
+ * Server-wide response builder for calls made without the client runtime
267
+ * (see `handleNoJS` in `HandleServerFunctionRequestOptions`); a
268
+ * per-request option overrides it. Set it to `createNoJSHandler({ base })`
269
+ * to apply the convention to every non-scripted call rather than only to
270
+ * browser form posts, to a handler of your own to replace it, or to
271
+ * `null` to disable the built-in convention and answer form posts with
272
+ * the plain serialized response.
273
+ */
274
+ handleNoJS?:
275
+ | ((
276
+ result: unknown,
277
+ request: Request,
278
+ args: unknown[],
279
+ thrown?: boolean
280
+ ) => Response | Promise<Response>)
281
+ | null;
282
+ /**
283
+ * Endpoint the HTTP handler is mounted on, used for the `url` of SSR'd
284
+ * references (e.g. form actions) — must match the client configuration.
285
+ * Prefix it when the app serves from a base path (e.g.
286
+ * `` `${BASE_URL}_server` ``).
287
+ * @default "/_server"
288
+ */
289
+ endpoint?: string;
290
+ /**
291
+ * Codec options (extra plugins etc.) for decoding arguments and encoding
292
+ * results — must match the client's. Stored in the shared layer, so
293
+ * `decodeResponse` sees them too.
294
+ */
295
+ codec?: JSONCodecOptions;
296
+ }
297
+
298
+ /**
299
+ * Configures the server runtime. Call once at server startup, before
300
+ * handling requests. Only needed when deviating from the defaults (custom
301
+ * endpoint, codec plugins, an explicit event provider, or a single-flight
302
+ * hook).
303
+ */
304
+ export function configureServerFunctionsServer(config?: ServerFunctionsServerConfig): void;
305
+
306
+ /**
307
+ * A registered server function: its build-stable id paired with the
308
+ * original implementation. Returned by `registerServerReference` and
309
+ * consumed by the server-side `createServerReference`.
310
+ *
311
+ * Compiler ABI shape; hand-written code rarely constructs these.
312
+ * @internal
313
+ */
314
+ export interface ServerFunctionReference<T extends any[] = any[], R = any> {
315
+ id: string;
316
+ fn: (...args: T) => R;
317
+ /**
318
+ * The function's source name, emitted by development builds only —
319
+ * `createServerReference` seeds the metadata channel with it.
320
+ * @internal
321
+ */
322
+ name?: string;
323
+ }
324
+
325
+ /**
326
+ * Adds a function to the dispatch registry under an id and returns it
327
+ * unchanged. The low-level registry write for integrations registering
328
+ * functions outside the compiler (e.g. a router registering its own
329
+ * endpoints); compiled output goes through `registerServerReference`
330
+ * instead. Ids must be stable across the client and server builds.
331
+ */
332
+ export function registerServerFunction<T extends any[], R>(
333
+ id: string,
334
+ callback: (...args: T) => R
335
+ ): (...args: T) => R;
336
+
337
+ /**
338
+ * Looks up a registered server function by id; throws for unknown ids.
339
+ * The HTTP handler uses this for dispatch — integrations building custom
340
+ * dispatch (or introspection) can too.
341
+ */
342
+ export function getServerFunction<T extends any[], R>(id: string): (...args: T) => R;
343
+
344
+ /**
345
+ * Compiler ABI — emitted by compiled `"use server"` server output for
346
+ * every server function: registers `fn` for HTTP dispatch under its
347
+ * build-stable id and returns the reference the server-side
348
+ * `createServerReference` consumes. Development builds pass the function's
349
+ * source name as the trailing argument (dev-only metadata; never emitted in
350
+ * production). Not meant for hand-written code.
351
+ * @internal
352
+ */
353
+ export function registerServerReference<T extends any[], R>(
354
+ id: string,
355
+ fn: (...args: T) => R,
356
+ name?: string
357
+ ): ServerFunctionReference<T, R>;
358
+
359
+ /**
360
+ * Compiler ABI — emitted by compiled `"use server"` server output where
361
+ * the function was referenced; produces the server-side callable. Calling
362
+ * it during SSR runs the original function in-process (no HTTP), under a
363
+ * request event derived from the current one — marked `serverOnly` and
364
+ * carrying the function's meta. Not meant for hand-written code.
365
+ * @internal
366
+ */
367
+ export function createServerReference<T extends any[], R>(
368
+ reference: ServerFunctionReference<T, R>
369
+ ): (...args: T) => R;
370
+
371
+ /**
372
+ * Declares a server function callable over HTTP GET. The server half is
373
+ * identity-flavored — SSR calls stay in-process — but it brands the
374
+ * declaration on the reference's metadata channel
375
+ * (`getServerFunctionMetadata(fn)?.method === "GET"`) and records the
376
+ * declared method for the function's id so `handleServerFunctionRequest`
377
+ * honors it: GET-declared functions accept GET requests in addition to the
378
+ * default POST transport (declaring GET grants, it does not revoke);
379
+ * functions that never declared GET answer GET requests with 405.
380
+ *
381
+ * Wrap the reference at its declaration; the compiler round-trips the call
382
+ * in both builds:
383
+ *
384
+ * ```ts
385
+ * export const getUser = GET(async (id: string) => {
386
+ * "use server";
387
+ * return db.users.find(id);
388
+ * });
389
+ * ```
390
+ */
391
+ export function GET<A extends readonly any[], R>(
392
+ fn: (...args: A) => R
393
+ ): ServerFunction<A, Awaited<R>>;
394
+
395
+ /** Identity of the currently executing server function call. */
396
+ export interface ServerFunctionInvocation {
397
+ id: string;
398
+ }
399
+
400
+ /**
401
+ * Reads the in-flight server function invocation (its id) for the current
402
+ * request event — usable inside a server function body, e.g. to key caches
403
+ * or logs by function. Returns undefined outside a server function call.
404
+ * The state lives in a module-private WeakMap keyed by the per-call request
405
+ * event (never in `event.locals`, which derived events share with their
406
+ * outer event). Distinct from `getServerFunctionMetadata(fn)`, which reads
407
+ * a reference's static declaration metadata; this describes the call
408
+ * currently executing.
409
+ */
410
+ export function getServerFunctionInvocation(): ServerFunctionInvocation | undefined;
411
+
412
+ /**
413
+ * The event-keyed half of `getServerFunctionInvocation`, for callers handed
414
+ * an event outside its provideEvent scope (the handler's result transforms
415
+ * run after the scope has exited). Integration plumbing — application code
416
+ * reads the ambient accessor instead.
417
+ * @internal
418
+ */
419
+ export function getEventServerFunctionInvocation(
420
+ event: RequestEvent | undefined
421
+ ): ServerFunctionInvocation | undefined;
422
+
423
+ /**
424
+ * Hooks layering framework policy onto `handleServerFunctionRequest`.
425
+ * All are optional — the bare handler dispatches, scopes events, and
426
+ * encodes results on its own.
427
+ */
428
+ export interface HandleServerFunctionOptions {
429
+ /**
430
+ * Builds the request event a call runs under (default: bare
431
+ * `{ request, locals: {} }`). Integrations supply their richer event
432
+ * (cookies, response helpers, platform handles).
433
+ */
434
+ createEvent?(request: Request): ServerFunctionEvent;
435
+ /**
436
+ * Overrides the configured event provider for this handler — same
437
+ * contract as the `provideEvent` config option.
438
+ */
439
+ provideEvent?<T>(event: ServerFunctionEvent, fn: () => T): T;
440
+ /**
441
+ * Overrides the configured per-invocation wrap for this handler — same
442
+ * contract as the `wrapInvocation` config option (see
443
+ * `WrapInvocationHook`), except it only applies to HTTP dispatch (a
444
+ * per-request option can't see direct SSR calls).
445
+ */
446
+ wrapInvocation?: WrapInvocationHook;
447
+ /**
448
+ * Observes or replaces the function's result before encoding — the
449
+ * extension point for response metadata policies (headers, statuses,
450
+ * substituted results). Runs for returned and thrown results alike
451
+ * (`context.thrown` distinguishes); `context.instance` is null for no-JS
452
+ * calls. The context carries the call's identity — the function `id` and
453
+ * the parsed `args` the implementation was invoked with — matching the
454
+ * direct-call mirror (`transformDirectResult`), so a policy keying state
455
+ * by the call works over either dispatch path. Return the result
456
+ * unchanged to pass through, or a `ResponseEnvelope` (exposed through
457
+ * the core entry) to send HTTP metadata plus a structured payload. Runs
458
+ * before `collectFlightData`, so the flight hook sees the transformed
459
+ * outcome — use `collectFlightData`, not this, to fold data into the
460
+ * response.
461
+ */
462
+ transformResult?(
463
+ event: ServerFunctionEvent,
464
+ result: unknown,
465
+ context: {
466
+ id: string;
467
+ args: unknown[];
468
+ instance: string | null;
469
+ request: Request;
470
+ thrown?: boolean;
471
+ }
472
+ ): unknown | ResponseEnvelope | Promise<unknown | ResponseEnvelope>;
473
+ /**
474
+ * Overrides the configured single-flight hook for this handler — same
475
+ * contract as the `collectFlightData` config option (see
476
+ * `CollectFlightDataHook`).
477
+ */
478
+ collectFlightData?: CollectFlightDataHook;
479
+ /**
480
+ * Overrides the configured single-flight fold policy for this handler —
481
+ * same contract as the `transformFlightResult` config option.
482
+ */
483
+ transformFlightResult?(
484
+ event: ServerFunctionEvent,
485
+ outcome: { value: unknown; data: unknown },
486
+ context: { id: string; args: unknown[]; instance: string | null; request: Request }
487
+ ): Response | undefined | Promise<Response | undefined>;
488
+ /**
489
+ * Builds the response for calls made without the client runtime (no
490
+ * instance header — no-JS form posts, direct HTTP). Receives the
491
+ * (transformed) result, the request, and the decoded arguments; `thrown`
492
+ * is set when the result was thrown rather than returned.
493
+ *
494
+ * Overrides the configured hook, which in turn overrides the built-in
495
+ * `createNoJSHandler()` applied to browser form posts. Other
496
+ * no-instance callers get the normal serialized response.
497
+ */
498
+ handleNoJS?(
499
+ result: unknown,
500
+ request: Request,
501
+ args: unknown[],
502
+ thrown?: boolean
503
+ ): Response | Promise<Response>;
504
+ /** Overrides the configured codec options for this handler. */
505
+ codec?: JSONCodecOptions;
506
+ }
507
+
508
+ /**
509
+ * Web-standard HTTP handler for server function calls: resolves the
510
+ * function id from the request, gates GET dispatch on the declaration (405
511
+ * for a GET request to a function that never declared `GET`; POST is always
512
+ * accepted), decodes arguments, runs the function under a request-event scope,
513
+ * and encodes the result (forwarding redirect/revalidation metadata
514
+ * through headers). Mount it on the endpoint the client transport targets
515
+ * (default `/_server`); platform adapters (h3, express, ...) convert their
516
+ * request shape to a web `Request` around it.
517
+ *
518
+ * When the event carries a `response` head stub (`event.response`, see the
519
+ * server entry's `ResponseStub`), the handler folds it onto every outgoing
520
+ * response as the head freezes — its `Set-Cookie` values (cookies appended
521
+ * during the call) append cookie-by-cookie alongside the result's own,
522
+ * other stub headers fill gaps (the call's response metadata wins; the
523
+ * protocol-owned family — the error/format/single-flight tags, `Location`,
524
+ * `X-Revalidate` — never fills, and neither does `Content-Type`/`Content-
525
+ * Length` onto a bodiless response) — and marks the stub `committed`, so
526
+ * later cookie/header writes report instead of silently missing the wire.
527
+ *
528
+ * ## Thrown-error sanitization (security default)
529
+ *
530
+ * A thrown `Response`/envelope (`redirect`/`reload`/`respond`) is intentional
531
+ * control flow and is forwarded untouched. A *plain* thrown value (a bare
532
+ * `Error`, string, or object) is different: serialized verbatim it would ship
533
+ * its `message` and every own-property to the client — a driver/ORM error's
534
+ * failing query, connection string, or bound parameters included. So outside
535
+ * the dev build a plain thrown value is replaced with a generic `Error`
536
+ * before serialization; the client still receives *an* `Error` (the shape
537
+ * `submission.error` etc. expect), just with no leaked content. The dev
538
+ * build keeps full fidelity (message, stack, own-props) for DX and the dev
539
+ * toolbar inspector. Dev/prod is the BUILD VARIANT, not `NODE_ENV`:
540
+ * `@solidjs/web` publishes a dev copy of this entry behind the
541
+ * `development` export condition (what Vite dev resolves) and the default
542
+ * resolution sanitizes — as does importing the runtime source directly with
543
+ * no bundler signal (fail-safe).
544
+ *
545
+ * Escape hatch: brand the value with `markSafeError` (`Symbol.for(
546
+ * "solid.SafeError")`) to send its content intact in every environment.
547
+ * A `wrapInvocation`/`transformResult` override that maps errors expresses
548
+ * intent the same way — throw a `Response`/envelope, or brand the mapped
549
+ * error safe; an unbranded plain error it lets propagate is sanitized like
550
+ * any other, so a framework onError policy must brand its result to keep a
551
+ * custom client-facing message in production.
552
+ *
553
+ * @example
554
+ * ```ts
555
+ * import { handleServerFunctionRequest } from "@solidjs/web/server-functions";
556
+ * import "virtual:solid-server-function-manifest";
557
+ *
558
+ * // in the server's request handling:
559
+ * if (url.pathname.startsWith("/_server")) {
560
+ * return handleServerFunctionRequest(request);
561
+ * }
562
+ * ```
563
+ */
564
+ export function handleServerFunctionRequest(
565
+ request: Request,
566
+ options?: HandleServerFunctionOptions
567
+ ): Promise<Response>;
568
+
569
+ /** Message a sanitized (production) server error carries on the wire. */
570
+ export const GENERIC_SERVER_ERROR_MESSAGE: string;
571
+
572
+ /**
573
+ * The production error-sanitization policy `handleServerFunctionRequest`
574
+ * applies to a plain thrown value before serialization. Returns `value`
575
+ * unchanged in the dev build or when it is branded safe (`markSafeError`);
576
+ * otherwise returns a generic `Error` carrying `GENERIC_SERVER_ERROR_MESSAGE`.
577
+ * Exposed for frameworks composing their own dispatch around the same policy.
578
+ */
579
+ export function sanitizeServerError(value: unknown): unknown;
580
+
581
+ /**
582
+ * Overrides the build-variant dev flag for this module instance — the seam
583
+ * for test harnesses and hand-rolled bundles whose packaging cannot replace
584
+ * `_DX_DEV_`. Applications never call this; select the dev build through
585
+ * the `development` export condition instead.
586
+ * @internal
587
+ */
588
+ export function setServerFunctionsDev(dev: boolean): void;