@tanstack/start-server-core 1.120.3 → 1.120.4-alpha.10

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 (62) hide show
  1. package/README.md +6 -27
  2. package/dist/cjs/createRequestHandler.cjs +1 -3
  3. package/dist/cjs/createRequestHandler.cjs.map +1 -1
  4. package/dist/cjs/createStartHandler.cjs +235 -30
  5. package/dist/cjs/createStartHandler.cjs.map +1 -1
  6. package/dist/cjs/createStartHandler.d.cts +8 -6
  7. package/dist/cjs/h3.cjs +30 -73
  8. package/dist/cjs/h3.cjs.map +1 -1
  9. package/dist/cjs/h3.d.cts +11 -7
  10. package/dist/cjs/handlerCallback.cjs.map +1 -1
  11. package/dist/cjs/handlerCallback.d.cts +3 -4
  12. package/dist/cjs/index.cjs +20 -14
  13. package/dist/cjs/index.cjs.map +1 -1
  14. package/dist/cjs/index.d.cts +7 -1
  15. package/dist/cjs/router-manifest.cjs +44 -0
  16. package/dist/cjs/router-manifest.cjs.map +1 -0
  17. package/dist/cjs/router-manifest.d.cts +17 -0
  18. package/dist/cjs/server-functions-handler.cjs +154 -0
  19. package/dist/cjs/server-functions-handler.cjs.map +1 -0
  20. package/dist/cjs/server-functions-handler.d.cts +4 -0
  21. package/dist/cjs/serverRoute.cjs +100 -0
  22. package/dist/cjs/serverRoute.cjs.map +1 -0
  23. package/dist/cjs/serverRoute.d.cts +115 -0
  24. package/dist/cjs/undici.cjs +14 -0
  25. package/dist/cjs/undici.cjs.map +1 -0
  26. package/dist/cjs/undici.d.cts +43 -0
  27. package/dist/esm/createRequestHandler.js +1 -3
  28. package/dist/esm/createRequestHandler.js.map +1 -1
  29. package/dist/esm/createStartHandler.d.ts +8 -6
  30. package/dist/esm/createStartHandler.js +215 -32
  31. package/dist/esm/createStartHandler.js.map +1 -1
  32. package/dist/esm/h3.d.ts +11 -7
  33. package/dist/esm/h3.js +26 -63
  34. package/dist/esm/h3.js.map +1 -1
  35. package/dist/esm/handlerCallback.d.ts +3 -4
  36. package/dist/esm/handlerCallback.js.map +1 -1
  37. package/dist/esm/index.d.ts +7 -1
  38. package/dist/esm/index.js +17 -5
  39. package/dist/esm/index.js.map +1 -1
  40. package/dist/esm/router-manifest.d.ts +17 -0
  41. package/dist/esm/router-manifest.js +44 -0
  42. package/dist/esm/router-manifest.js.map +1 -0
  43. package/dist/esm/server-functions-handler.d.ts +4 -0
  44. package/dist/esm/server-functions-handler.js +154 -0
  45. package/dist/esm/server-functions-handler.js.map +1 -0
  46. package/dist/esm/serverRoute.d.ts +115 -0
  47. package/dist/esm/serverRoute.js +100 -0
  48. package/dist/esm/serverRoute.js.map +1 -0
  49. package/dist/esm/undici.d.ts +43 -0
  50. package/dist/esm/undici.js +14 -0
  51. package/dist/esm/undici.js.map +1 -0
  52. package/package.json +9 -6
  53. package/src/createRequestHandler.ts +1 -3
  54. package/src/createStartHandler.ts +325 -48
  55. package/src/h3.ts +71 -78
  56. package/src/handlerCallback.ts +5 -12
  57. package/src/index.tsx +13 -1
  58. package/src/router-manifest.ts +79 -0
  59. package/src/server-functions-handler.ts +273 -0
  60. package/src/serverRoute.ts +661 -0
  61. package/src/tanstack-start.d.ts +5 -0
  62. package/src/undici.ts +60 -0
@@ -1,82 +1,359 @@
1
1
  import { createMemoryHistory } from '@tanstack/history'
2
- import { mergeHeaders } from '@tanstack/start-client-core'
3
- import { eventHandler, getResponseHeaders, toWebRequest } from 'h3'
2
+ import {
3
+ flattenMiddlewares,
4
+ json,
5
+ mergeHeaders,
6
+ } from '@tanstack/start-client-core'
7
+ import {
8
+ getMatchedRoutes,
9
+ isRedirect,
10
+ joinPaths,
11
+ processRouteTree,
12
+ rootRouteId,
13
+ trimPath,
14
+ tsrRedirectHeaderKey,
15
+ } from '@tanstack/router-core'
16
+ import { getResponseHeaders, requestHandler } from './h3'
4
17
  import { attachRouterServerSsrUtils, dehydrateRouter } from './ssr-server'
18
+ import { getStartManifest } from './router-manifest'
19
+ import { handleServerAction } from './server-functions-handler'
20
+ import type { AnyServerRoute, AnyServerRouteWithTypes } from './serverRoute'
21
+ import type { RequestHandler } from './h3'
22
+ import type { AnyRouter } from '@tanstack/router-core'
5
23
  import type { HandlerCallback } from './handlerCallback'
6
- import type { EventHandlerResponse, H3Event } from 'h3'
7
- import type { AnyRouter, Manifest } from '@tanstack/router-core'
8
-
9
- export type CustomizeStartHandler<
10
- TRouter extends AnyRouter,
11
- TResponse extends EventHandlerResponse = EventHandlerResponse,
12
- > = (cb: HandlerCallback<TRouter, TResponse>) => ReturnType<typeof eventHandler>
13
-
14
- export function createStartHandler<
15
- TRouter extends AnyRouter,
16
- TResponse extends EventHandlerResponse = EventHandlerResponse,
17
- >({
24
+
25
+ type TODO = any
26
+
27
+ export type CustomizeStartHandler<TRouter extends AnyRouter> = (
28
+ cb: HandlerCallback<TRouter>,
29
+ ) => RequestHandler
30
+
31
+ export function getStartResponseHeaders(opts: { router: AnyRouter }) {
32
+ let headers = mergeHeaders(
33
+ getResponseHeaders(),
34
+ {
35
+ 'Content-Type': 'text/html; charset=UTF-8',
36
+ },
37
+ ...opts.router.state.matches.map((match) => {
38
+ return match.headers
39
+ }),
40
+ )
41
+ // Handle Redirects
42
+ const { redirect } = opts.router.state
43
+
44
+ if (redirect) {
45
+ headers = mergeHeaders(headers, redirect.headers)
46
+ }
47
+ return headers
48
+ }
49
+
50
+ export function createStartHandler<TRouter extends AnyRouter>({
18
51
  createRouter,
19
- getRouterManifest,
20
52
  }: {
21
53
  createRouter: () => TRouter
22
- getRouterManifest?: () => Manifest | Promise<Manifest>
23
- }): CustomizeStartHandler<TRouter, TResponse> {
54
+ }): CustomizeStartHandler<TRouter> {
24
55
  return (cb) => {
25
- return eventHandler(async (event) => {
26
- const request = toWebRequest(event)
27
-
56
+ return requestHandler(async ({ request }) => {
28
57
  const url = new URL(request.url)
29
58
  const href = url.href.replace(url.origin, '')
30
59
 
31
- // Create a history for the router
60
+ // Create a history for the client-side router
32
61
  const history = createMemoryHistory({
33
62
  initialEntries: [href],
34
63
  })
35
64
 
65
+ // Create the client-side router
36
66
  const router = createRouter()
37
67
 
38
- attachRouterServerSsrUtils(router, await getRouterManifest?.())
68
+ // Attach the server-side SSR utils to the client-side router
69
+ attachRouterServerSsrUtils(router, getStartManifest())
39
70
 
40
- // Update the router with the history and context
71
+ // Update the client-side router with the history and context
41
72
  router.update({
42
73
  history,
43
74
  })
44
75
 
45
- await router.load()
76
+ const response = await (async () => {
77
+ try {
78
+ if (!process.env.TSS_SERVER_FN_BASE) {
79
+ throw new Error(
80
+ 'tanstack/start-server-core: TSS_SERVER_FN_BASE must be defined in your environment for createStartHandler()',
81
+ )
82
+ }
46
83
 
47
- dehydrateRouter(router)
84
+ // First, let's attempt to handle server functions
85
+ // Add trailing slash to sanitise user defined TSS_SERVER_FN_BASE
86
+ const serverFnBase = joinPaths([
87
+ '/',
88
+ trimPath(process.env.TSS_SERVER_FN_BASE),
89
+ '/',
90
+ ])
91
+ if (href.startsWith(serverFnBase)) {
92
+ return await handleServerAction({ request })
93
+ }
48
94
 
49
- const responseHeaders = getStartResponseHeaders({ event, router })
50
- const response = await cb({
51
- request,
52
- router,
53
- responseHeaders,
54
- })
95
+ // Then move on to attempting to load server routes
96
+ const serverRouteTreeModule = await (async () => {
97
+ try {
98
+ // @ts-expect-error
99
+ return (await import('tanstack:server-routes')) as {
100
+ routeTree: AnyServerRoute
101
+ }
102
+ } catch (e) {
103
+ console.log(e)
104
+ return undefined
105
+ }
106
+ })()
55
107
 
56
- return response
108
+ // If we have a server route tree, then we try matching to see if we have a
109
+ // server route that matches the request.
110
+ if (serverRouteTreeModule) {
111
+ const [_matchedRoutes, response] = await handleServerRoutes({
112
+ routeTree: serverRouteTreeModule.routeTree,
113
+ request,
114
+ })
115
+
116
+ if (response) return response
117
+ }
118
+
119
+ const requestAcceptHeader = request.headers.get('Accept') || '*/*'
120
+ const splitRequestAcceptHeader = requestAcceptHeader.split(',')
121
+
122
+ const supportedMimeTypes = ['*/*', 'text/html']
123
+ const isRouterAcceptSupported = supportedMimeTypes.some((mimeType) =>
124
+ splitRequestAcceptHeader.some((acceptedMimeType) =>
125
+ acceptedMimeType.trim().startsWith(mimeType),
126
+ ),
127
+ )
128
+
129
+ if (!isRouterAcceptSupported) {
130
+ return json(
131
+ {
132
+ error: 'Only HTML requests are supported here',
133
+ },
134
+ {
135
+ status: 500,
136
+ },
137
+ )
138
+ }
139
+
140
+ // If no Server Routes were found, so fallback to normal SSR matching using
141
+ // the router
142
+
143
+ await router.load()
144
+
145
+ // If there was a redirect, skip rendering the page at all
146
+ if (router.state.redirect) return router.state.redirect
147
+
148
+ dehydrateRouter(router)
149
+
150
+ const responseHeaders = getStartResponseHeaders({ router })
151
+ const response = await cb({
152
+ request,
153
+ router,
154
+ responseHeaders,
155
+ })
156
+
157
+ return response
158
+ } catch (err) {
159
+ if (err instanceof Response) {
160
+ return err
161
+ }
162
+
163
+ throw err
164
+ }
165
+ })()
166
+
167
+ if (isRedirect(response)) {
168
+ if (
169
+ response.options.to &&
170
+ typeof response.options.to === 'string' &&
171
+ !response.options.to.startsWith('/')
172
+ ) {
173
+ throw new Error(
174
+ `Server side redirects must use absolute paths via the 'href' or 'to' options. Received: ${JSON.stringify(response.options)}`,
175
+ )
176
+ }
177
+
178
+ if (
179
+ ['params', 'search', 'hash'].some(
180
+ (d) => typeof (response.options as any)[d] === 'function',
181
+ )
182
+ ) {
183
+ throw new Error(
184
+ `Server side redirects must use static search, params, and hash values and do not support functional values. Received functional values for: ${Object.keys(
185
+ response.options,
186
+ )
187
+ .filter((d) => typeof (response.options as any)[d] === 'function')
188
+ .map((d) => `"${d}"`)
189
+ .join(', ')}`,
190
+ )
191
+ }
192
+
193
+ const redirect = router.resolveRedirect(response)
194
+
195
+ if (request.headers.get('x-tsr-redirect') === 'manual') {
196
+ return json(
197
+ {
198
+ ...response.options,
199
+ isSerializedRedirect: true,
200
+ },
201
+ {
202
+ headers: redirect.headers,
203
+ },
204
+ )
205
+ }
206
+
207
+ return redirect
208
+ }
209
+
210
+ // Add Access-Control-Expose-Headers
211
+ // With HTTPs the response/header objects are immutable, therefore we must clone them
212
+ const body =
213
+ response.status === 204 ? null : await response.clone().blob()
214
+ const headers = new Headers(response.headers)
215
+ headers.append('Access-Control-Expose-Headers', tsrRedirectHeaderKey)
216
+
217
+ return new Response(body, {
218
+ status: response.status,
219
+ statusText: response.statusText,
220
+ headers,
221
+ })
57
222
  })
58
223
  }
59
224
  }
60
225
 
61
- function getStartResponseHeaders(opts: { event: H3Event; router: AnyRouter }) {
62
- let headers = mergeHeaders(
63
- getResponseHeaders(opts.event),
64
- (opts.event as any).___ssrRpcResponseHeaders,
65
- {
66
- 'Content-Type': 'text/html; charset=UTF-8',
226
+ async function handleServerRoutes({
227
+ routeTree,
228
+ request,
229
+ }: {
230
+ routeTree: AnyServerRouteWithTypes
231
+ request: Request
232
+ }) {
233
+ const { flatRoutes, routesById, routesByPath } = processRouteTree({
234
+ routeTree,
235
+ initRoute: (route, i) => {
236
+ route.init({
237
+ originalIndex: i,
238
+ })
67
239
  },
68
- ...opts.router.state.matches.map((match) => {
69
- return match.headers
70
- }),
71
- )
240
+ })
72
241
 
73
- // Handle Redirects
74
- const { redirect } = opts.router.state
242
+ const url = new URL(request.url)
243
+ const pathname = url.pathname
75
244
 
76
- if (redirect) {
77
- headers = mergeHeaders(headers, redirect.headers, {
78
- Location: redirect.href,
245
+ const history = createMemoryHistory({
246
+ initialEntries: [pathname],
247
+ })
248
+
249
+ const { matchedRoutes, foundRoute, routeParams } =
250
+ getMatchedRoutes<AnyServerRouteWithTypes>({
251
+ pathname: history.location.pathname,
252
+ basepath: '/',
253
+ caseSensitive: true,
254
+ routesByPath,
255
+ routesById,
256
+ flatRoutes,
257
+ })
258
+
259
+ let response: Response | undefined
260
+
261
+ if (foundRoute && foundRoute.id !== rootRouteId) {
262
+ // We've found a server route that matches the request, so we can call it.
263
+ // TODO: Get the input type-signature correct
264
+ // TODO: Perform the middlewares?
265
+ // TODO: Error handling? What happens when its `throw redirect()` vs `throw new Error()`?
266
+
267
+ const method = Object.keys(foundRoute.options.methods).find(
268
+ (method) => method.toLowerCase() === request.method.toLowerCase(),
269
+ )
270
+
271
+ if (method) {
272
+ const handler = foundRoute.options.methods[method]
273
+
274
+ if (handler) {
275
+ const middlewares = flattenMiddlewares(
276
+ matchedRoutes.flatMap((r) => r.options.middleware).filter(Boolean),
277
+ ).map((d) => d.options.server)
278
+
279
+ middlewares.push(handlerToMiddleware(handler) as TODO)
280
+
281
+ // TODO: This is starting to feel too much like a server function
282
+ // Do generalize the existing middleware execution? Or do we need to
283
+ // build a new middleware execution system for server routes?
284
+ const ctx = await executeMiddleware(middlewares, {
285
+ request,
286
+ context: {},
287
+ params: routeParams,
288
+ pathname: history.location.pathname,
289
+ })
290
+
291
+ response = ctx.response
292
+ }
293
+ }
294
+ }
295
+
296
+ // We return the matched routes too so if
297
+ // the app router happens to match the same path,
298
+ // it can use any request middleware from server routes
299
+ return [matchedRoutes, response] as const
300
+ }
301
+
302
+ function handlerToMiddleware(
303
+ handler: AnyServerRouteWithTypes['options']['methods'][string],
304
+ ) {
305
+ return async ({ next, ...rest }: TODO) => ({
306
+ response: await handler(rest),
307
+ })
308
+ }
309
+
310
+ function executeMiddleware(middlewares: TODO, ctx: TODO) {
311
+ let index = -1
312
+
313
+ const next = async (ctx: TODO) => {
314
+ index++
315
+ const middleware = middlewares[index]
316
+ if (!middleware) return ctx
317
+
318
+ const result = await middleware({
319
+ ...ctx,
320
+ // Allow the middleware to call the next middleware in the chain
321
+ next: async (nextCtx: TODO) => {
322
+ // Allow the caller to extend the context for the next middleware
323
+ const nextResult = await next({ ...ctx, ...nextCtx })
324
+
325
+ // Merge the result into the context\
326
+ return Object.assign(ctx, handleCtxResult(nextResult))
327
+ },
328
+ // Allow the middleware result to extend the return context
329
+ }).catch((err: TODO) => {
330
+ if (isSpecialResponse(err)) {
331
+ return {
332
+ response: err,
333
+ }
334
+ }
335
+
336
+ throw err
79
337
  })
338
+
339
+ // Merge the middleware result into the context, just in case it
340
+ // returns a partial context
341
+ return Object.assign(ctx, handleCtxResult(result))
80
342
  }
81
- return headers
343
+
344
+ return handleCtxResult(next(ctx))
345
+ }
346
+
347
+ function handleCtxResult(result: TODO) {
348
+ if (isSpecialResponse(result)) {
349
+ return {
350
+ response: result,
351
+ }
352
+ }
353
+
354
+ return result
355
+ }
356
+
357
+ function isSpecialResponse(err: TODO) {
358
+ return err instanceof Response || isRedirect(err)
82
359
  }
package/src/h3.ts CHANGED
@@ -11,7 +11,9 @@ import {
11
11
  clearResponseHeaders as _clearResponseHeaders,
12
12
  clearSession as _clearSession,
13
13
  defaultContentType as _defaultContentType,
14
+ defineEventHandler as _defineEventHandler,
14
15
  deleteCookie as _deleteCookie,
16
+ eventHandler as _eventHandler,
15
17
  fetchWithEvent as _fetchWithEvent,
16
18
  getCookie as _getCookie,
17
19
  getHeader as _getHeader,
@@ -61,20 +63,24 @@ import {
61
63
  setResponseHeader as _setResponseHeader,
62
64
  setResponseHeaders as _setResponseHeaders,
63
65
  setResponseStatus as _setResponseStatus,
66
+ toWebRequest as _toWebRequest,
64
67
  unsealSession as _unsealSession,
65
68
  updateSession as _updateSession,
66
69
  useSession as _useSession,
67
70
  writeEarlyHints as _writeEarlyHints,
68
71
  } from 'h3'
69
- import { getContext as getUnctxContext } from 'unctx'
72
+
70
73
  import type {
71
74
  Encoding,
75
+ EventHandler,
72
76
  HTTPHeaderName,
73
77
  InferEventInput,
74
78
  _RequestMiddleware,
75
79
  _ResponseMiddleware,
76
80
  } from 'h3'
77
81
 
82
+ const eventStorage = new AsyncLocalStorage()
83
+
78
84
  function _setContext(event: H3Event, key: string, value: any) {
79
85
  event.context[key] = value
80
86
  }
@@ -90,46 +96,38 @@ export function defineMiddleware(options: {
90
96
  return options
91
97
  }
92
98
 
93
- function toWebRequestH3(event: H3Event) {
94
- /**
95
- * @type {ReadableStream | undefined}
96
- */
97
- let readableStream: ReadableStream | undefined
99
+ // function toWebRequestH3(event: H3Event) {
100
+ // /**
101
+ // * @type {ReadableStream | undefined}
102
+ // */
103
+ // let readableStream: ReadableStream | undefined
98
104
 
99
- const url = getRequestURL(event)
100
- const base = {
101
- // @ts-ignore Undici option
102
- duplex: 'half',
103
- method: event.method,
104
- headers: event.headers,
105
- }
106
-
107
- if ((event.node.req as any).body instanceof ArrayBuffer) {
108
- return new Request(url, {
109
- ...base,
110
- body: (event.node.req as any).body,
111
- })
112
- }
105
+ // const url = _getRequestURL(event)
106
+ // const base = {
107
+ // // @ts-ignore Undici option
108
+ // duplex: 'half',
109
+ // method: event.method,
110
+ // headers: event.headers,
111
+ // }
113
112
 
114
- return new Request(url, {
115
- ...base,
116
- get body() {
117
- if (readableStream) {
118
- return readableStream
119
- }
120
- readableStream = getRequestWebStream(event)
121
- return readableStream
122
- },
123
- })
124
- }
113
+ // if ((event.node.req as any).body instanceof ArrayBuffer) {
114
+ // return new Request(url, {
115
+ // ...base,
116
+ // body: (event.node.req as any).body,
117
+ // })
118
+ // }
125
119
 
126
- export function toWebRequest(event: H3Event) {
127
- event.web ??= {
128
- request: toWebRequestH3(event),
129
- url: getRequestURL(event),
130
- }
131
- return event.web.request
132
- }
120
+ // return new Request(url, {
121
+ // ...base,
122
+ // get body() {
123
+ // if (readableStream) {
124
+ // return readableStream
125
+ // }
126
+ // readableStream = _getRequestWebStream(event)
127
+ // return readableStream
128
+ // },
129
+ // })
130
+ // }
133
131
 
134
132
  export {
135
133
  H3Error,
@@ -140,7 +138,6 @@ export {
140
138
  createAppEventHandler,
141
139
  createEvent,
142
140
  createRouter,
143
- defineEventHandler,
144
141
  defineLazyEventHandler,
145
142
  defineNodeListener,
146
143
  defineNodeMiddleware,
@@ -148,7 +145,6 @@ export {
148
145
  defineResponseMiddleware,
149
146
  dynamicEventHandler,
150
147
  defineWebSocket,
151
- eventHandler,
152
148
  splitCookiesString,
153
149
  fromNodeMiddleware,
154
150
  fromPlainHandler,
@@ -163,6 +159,7 @@ export {
163
159
  toNodeListener,
164
160
  toPlainHandler,
165
161
  toWebHandler,
162
+ toWebRequest,
166
163
  isCorsOriginAllowed,
167
164
  isStream,
168
165
  createError,
@@ -221,8 +218,33 @@ export {
221
218
  type _ResponseMiddleware,
222
219
  } from 'h3'
223
220
 
224
- function getHTTPEvent() {
225
- return getEvent()
221
+ export function defineEventHandler(handler: EventHandler) {
222
+ return _defineEventHandler((event) => {
223
+ return runWithEvent(event, () => handler(event))
224
+ })
225
+ }
226
+
227
+ export function eventHandler(handler: EventHandler) {
228
+ return _eventHandler((event) => {
229
+ return runWithEvent(event, () => handler(event))
230
+ })
231
+ }
232
+
233
+ export async function runWithEvent<T>(
234
+ event: H3Event,
235
+ fn: () => T | Promise<T>,
236
+ ): Promise<T> {
237
+ return eventStorage.run(event, fn)
238
+ }
239
+
240
+ export function getEvent() {
241
+ const event = eventStorage.getStore() as H3Event | undefined
242
+ if (!event) {
243
+ throw new Error(
244
+ `No HTTPEvent found in AsyncLocalStorage. Make sure you are using the function within the server runtime.`,
245
+ )
246
+ }
247
+ return event
226
248
  }
227
249
 
228
250
  export const HTTPEventSymbol = Symbol('$HTTPEvent')
@@ -262,12 +284,7 @@ function createWrapperFunction<TFn extends (...args: Array<any>) => any>(
262
284
  return function (...args: Array<any>) {
263
285
  const event = args[0]
264
286
  if (!isEvent(event)) {
265
- if (!(globalThis as any).app.config.server.experimental?.asyncContext) {
266
- throw new Error(
267
- 'AsyncLocalStorage was not enabled. Use the `server.experimental.asyncContext: true` option in your app configuration to enable it. Or, pass the instance of HTTPEvent that you have as the first argument to the function.',
268
- )
269
- }
270
- args.unshift(getHTTPEvent())
287
+ args.unshift(getEvent())
271
288
  } else {
272
289
  args[0] =
273
290
  event instanceof H3Event || (event as any).__is_event__
@@ -463,37 +480,13 @@ export const readValidatedBody: PrependOverload<
463
480
  export const removeResponseHeader = createWrapperFunction(_removeResponseHeader)
464
481
  export const getContext = createWrapperFunction(_getContext)
465
482
  export const setContext = createWrapperFunction(_setContext)
466
-
467
483
  export const clearResponseHeaders = createWrapperFunction(_clearResponseHeaders)
484
+ export const getWebRequest = createWrapperFunction(_toWebRequest)
468
485
 
469
- export const getWebRequest = createWrapperFunction(toWebRequest)
470
-
471
- export { createApp as createServer } from 'h3'
472
-
473
- function getNitroAsyncContext() {
474
- const nitroAsyncContext = getUnctxContext('nitro-app', {
475
- asyncContext: (globalThis as any).app.config.server.experimental
476
- ?.asyncContext
477
- ? true
478
- : false,
479
- AsyncLocalStorage,
480
- })
481
-
482
- return nitroAsyncContext
483
- }
484
-
485
- export function getEvent() {
486
- const event = (getNitroAsyncContext().use() as any).event as
487
- | H3Event
488
- | undefined
489
- if (!event) {
490
- throw new Error(
491
- `No HTTPEvent found in AsyncLocalStorage. Make sure you are using the function within the server runtime.`,
492
- )
493
- }
494
- return event
495
- }
486
+ export type RequestHandler = (ctx: {
487
+ request: Request
488
+ }) => Promise<Response> | Response
496
489
 
497
- export async function handleHTTPEvent(event: H3Event) {
498
- return await (globalThis as any).$handle(event)
490
+ export function requestHandler(handler: RequestHandler) {
491
+ return handler
499
492
  }
@@ -1,22 +1,15 @@
1
- import type { EventHandlerResponse } from 'h3'
2
1
  import type { AnyRouter } from '@tanstack/router-core'
3
2
 
4
- export interface HandlerCallback<
5
- TRouter extends AnyRouter,
6
- TResponse extends EventHandlerResponse = EventHandlerResponse,
7
- > {
3
+ export interface HandlerCallback<TRouter extends AnyRouter> {
8
4
  (ctx: {
9
5
  request: Request
10
6
  router: TRouter
11
7
  responseHeaders: Headers
12
- }): TResponse
8
+ }): Response | Promise<Response>
13
9
  }
14
10
 
15
- export function defineHandlerCallback<
16
- TRouter extends AnyRouter,
17
- TResponse = EventHandlerResponse,
18
- >(
19
- handler: HandlerCallback<TRouter, TResponse>,
20
- ): HandlerCallback<TRouter, TResponse> {
11
+ export function defineHandlerCallback<TRouter extends AnyRouter>(
12
+ handler: HandlerCallback<TRouter>,
13
+ ): HandlerCallback<TRouter> {
21
14
  return handler
22
15
  }
package/src/index.tsx CHANGED
@@ -3,10 +3,22 @@ export {
3
3
  transformPipeableStreamWithRouter,
4
4
  } from './transformStreamWithRouter'
5
5
 
6
- export { createStartHandler } from './createStartHandler'
6
+ export {
7
+ getStartResponseHeaders,
8
+ createStartHandler,
9
+ } from './createStartHandler'
10
+ export type { CustomizeStartHandler } from './createStartHandler'
7
11
  export { createRequestHandler } from './createRequestHandler'
8
12
 
9
13
  export { defineHandlerCallback } from './handlerCallback'
10
14
  export type { HandlerCallback } from './handlerCallback'
11
15
 
16
+ export { attachRouterServerSsrUtils, dehydrateRouter } from './ssr-server'
17
+ export { handleServerAction } from './server-functions-handler'
18
+
12
19
  export * from './h3'
20
+
21
+ export { createServerRoute, createServerFileRoute } from './serverRoute'
22
+ export type { CreateServerFileRoute } from './serverRoute'
23
+
24
+ export { __getAbsoluteUrl, __setGlobalOrigin } from './undici'