| 461 | * ``` |
| 462 | */ |
| 463 | export function createStartHandler<TRegister = Register>( |
| 464 | cbOrOptions: HandlerCallback<AnyRouter> | CreateStartHandlerOptions, |
| 465 | ): RequestHandler<TRegister> { |
| 466 | const handlerOptions: FinalManifestOptions = |
| 467 | typeof cbOrOptions === 'function' ? {} : cbOrOptions |
| 468 | const cb: HandlerCallback<AnyRouter> = |
| 469 | typeof cbOrOptions === 'function' ? cbOrOptions : cbOrOptions.handler |
| 470 | const finalManifestResolver = createFinalManifestResolver({ |
| 471 | ...handlerOptions, |
| 472 | cacheCreateTransform: process.env.TSS_DEV_SERVER !== 'true', |
| 473 | }) |
| 474 | const resolveManifestForRequest = |
| 475 | process.env.TSS_DEV_SERVER === 'true' |
| 476 | ? finalManifestResolver.resolveUncached |
| 477 | : finalManifestResolver.resolveCached |
| 478 | |
| 479 | if (process.env.TSS_DEV_SERVER !== 'true') { |
| 480 | finalManifestResolver.warmup({ |
| 481 | getBaseManifest: () => getBaseManifest(undefined), |
| 482 | }) |
| 483 | } |
| 484 | |
| 485 | const startRequestResolver: RequestHandler<Register> = async ( |
| 486 | request, |
| 487 | requestOpts, |
| 488 | ) => { |
| 489 | let router: AnyRouter | null = null as AnyRouter | null |
| 490 | let responseOwnsCleanup = false as boolean |
| 491 | |
| 492 | try { |
| 493 | request.signal.throwIfAborted() |
| 494 | // normalizing and sanitizing the pathname here for server, so we always deal with the same format during SSR. |
| 495 | // during normalization paths like '//posts' are flattened to '/posts'. |
| 496 | // in these cases we would prefer to redirect to the new path |
| 497 | const { url, handledProtocolRelativeURL } = getNormalizedURL(request.url) |
| 498 | const href = url.pathname + url.search + url.hash |
| 499 | const origin = getOrigin(request) |
| 500 | |
| 501 | if (handledProtocolRelativeURL) { |
| 502 | return Response.redirect(url, 308) |
| 503 | } |
| 504 | |
| 505 | const entries = await waitForRequest(getEntries(), request.signal) |
| 506 | const hasStartInstance = !!entries.startEntry.startInstance |
| 507 | const startOptions: AnyStartInstanceOptions = |
| 508 | (await waitForRequest( |
| 509 | entries.startEntry.startInstance?.getOptions(), |
| 510 | request.signal, |
| 511 | )) || ({} as AnyStartInstanceOptions) |
| 512 | |
| 513 | const { hasPluginAdapters, pluginSerializationAdapters } = |
| 514 | entries.pluginAdapters |
| 515 | |
| 516 | const serializationAdapters = [ |
| 517 | ...(startOptions.serializationAdapters || []), |
| 518 | ...(hasPluginAdapters ? pluginSerializationAdapters : []), |
| 519 | ServerFunctionSerializationAdapter, |
| 520 | ] |