| | import type { NextServer, RequestHandler, UpgradeHandler } from '../next' |
| | import type { DevBundlerService } from './dev-bundler-service' |
| | import type { PropagateToWorkersField } from './router-utils/types' |
| |
|
| | import next from '../next' |
| | import type { Span } from '../../trace' |
| | import type { ServerResponse } from 'http' |
| | import type { OnCacheEntryHandler } from '../request-meta' |
| | import { interopDefault } from '../../lib/interop-default' |
| | import { formatDynamicImportPath } from '../../lib/format-dynamic-import-path' |
| | import type { ConfiguredExperimentalFeature } from '../config' |
| |
|
| | export type ServerInitResult = { |
| | requestHandler: RequestHandler |
| | upgradeHandler: UpgradeHandler |
| | server: NextServer |
| | |
| | closeUpgraded: () => void |
| | |
| | distDir: string |
| | |
| | experimentalFeatures: ConfiguredExperimentalFeature[] |
| | |
| | cacheComponents: boolean |
| | } |
| |
|
| | let initializations: Record<string, Promise<ServerInitResult> | undefined> = {} |
| |
|
| | let sandboxContext: undefined | typeof import('../web/sandbox/context') |
| |
|
| | if (process.env.NODE_ENV !== 'production') { |
| | sandboxContext = |
| | require('../web/sandbox/context') as typeof import('../web/sandbox/context') |
| | } |
| |
|
| | export function clearAllModuleContexts() { |
| | return sandboxContext?.clearAllModuleContexts() |
| | } |
| |
|
| | export function clearModuleContext(target: string) { |
| | return sandboxContext?.clearModuleContext(target) |
| | } |
| |
|
| | export async function getServerField( |
| | dir: string, |
| | field: PropagateToWorkersField |
| | ) { |
| | const initialization = await initializations[dir] |
| | if (!initialization) { |
| | throw new Error('Invariant cant propagate server field, no app initialized') |
| | } |
| | const { server } = initialization |
| | let wrappedServer = server['server']! |
| | return wrappedServer[field as keyof typeof wrappedServer] |
| | } |
| |
|
| | export async function propagateServerField( |
| | dir: string, |
| | field: PropagateToWorkersField, |
| | value: any |
| | ) { |
| | const initialization = await initializations[dir] |
| | if (!initialization) { |
| | throw new Error('Invariant cant propagate server field, no app initialized') |
| | } |
| | const { server } = initialization |
| | let wrappedServer = server['server'] |
| | const _field = field as keyof NonNullable<typeof wrappedServer> |
| |
|
| | if (wrappedServer) { |
| | if (typeof wrappedServer[_field] === 'function') { |
| | |
| | await wrappedServer[_field].apply( |
| | wrappedServer, |
| | Array.isArray(value) ? value : [] |
| | ) |
| | } else { |
| | |
| | wrappedServer[_field] = value |
| | } |
| | } |
| | } |
| |
|
| | async function initializeImpl(opts: { |
| | dir: string |
| | port: number |
| | dev: boolean |
| | minimalMode?: boolean |
| | hostname?: string |
| | keepAliveTimeout?: number |
| | serverFields?: any |
| | server?: any |
| | experimentalTestProxy: boolean |
| | experimentalHttpsServer: boolean |
| | _ipcPort?: string |
| | _ipcKey?: string |
| | bundlerService: DevBundlerService | undefined |
| | startServerSpan: Span | undefined |
| | quiet?: boolean |
| | onDevServerCleanup: ((listener: () => Promise<void>) => void) | undefined |
| | distDir: string |
| | experimentalFeatures: ConfiguredExperimentalFeature[] |
| | cacheComponents: boolean |
| | }): Promise<ServerInitResult> { |
| | const type = process.env.__NEXT_PRIVATE_RENDER_WORKER |
| | if (type) { |
| | process.title = 'next-render-worker-' + type |
| | } |
| |
|
| | let requestHandler: RequestHandler |
| | let upgradeHandler: UpgradeHandler |
| |
|
| | const server = next({ |
| | ...opts, |
| | hostname: opts.hostname || 'localhost', |
| | customServer: false, |
| | httpServer: opts.server, |
| | port: opts.port, |
| | }) as NextServer |
| |
|
| | |
| | |
| | if ( |
| | process.env.__NEXT_TEST_MODE && |
| | process.env.NEXT_PRIVATE_DEBUG_CACHE_ENTRY_HANDLERS |
| | ) { |
| | |
| | |
| | const createOnCacheEntryHandlers = interopDefault( |
| | await import( |
| | formatDynamicImportPath( |
| | opts.dir, |
| | process.env.NEXT_PRIVATE_DEBUG_CACHE_ENTRY_HANDLERS |
| | ) |
| | ) |
| | ) as (res: ServerResponse) => { |
| | |
| | onCacheEntry: OnCacheEntryHandler |
| | onCacheEntryV2: OnCacheEntryHandler |
| | } |
| |
|
| | |
| | |
| | requestHandler = async (req, res, parsedUrl) => { |
| | |
| | |
| | const { |
| | |
| | onCacheEntry, |
| | onCacheEntryV2, |
| | } = createOnCacheEntryHandlers(res) |
| |
|
| | |
| | |
| | const handler = server.getRequestHandlerWithMetadata({ |
| | |
| | onCacheEntry, |
| | onCacheEntryV2, |
| | }) |
| |
|
| | return handler(req, res, parsedUrl) |
| | } |
| |
|
| | upgradeHandler = server.getUpgradeHandler() |
| | } else { |
| | requestHandler = server.getRequestHandler() |
| | upgradeHandler = server.getUpgradeHandler() |
| | } |
| |
|
| | await server.prepare(opts.serverFields) |
| |
|
| | return { |
| | requestHandler, |
| | upgradeHandler, |
| | server, |
| | closeUpgraded() { |
| | opts.bundlerService?.close() |
| | }, |
| | distDir: opts.distDir, |
| | experimentalFeatures: opts.experimentalFeatures, |
| | cacheComponents: opts.cacheComponents, |
| | } |
| | } |
| |
|
| | export async function initialize( |
| | opts: Parameters<typeof initializeImpl>[0] |
| | ): Promise<ServerInitResult> { |
| | |
| | |
| | if (initializations[opts.dir]) { |
| | return initializations[opts.dir]! |
| | } |
| | return (initializations[opts.dir] = initializeImpl(opts)) |
| | } |
| |
|