mirror of https://github.com/vuejs/vitepress
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
2.4 KiB
74 lines
2.4 KiB
import type { ModuleRunnerTransport } from 'vite/module-runner'
|
|
import { SsrModuleArtifactReader } from './ssrModuleStore'
|
|
import type { SerializedSsrBuiltin } from './ssrWorkerProtocol'
|
|
|
|
interface ViteInvokePayload {
|
|
type: 'custom'
|
|
event: 'vite:invoke'
|
|
data: {
|
|
name: 'fetchModule' | 'getBuiltins'
|
|
data: unknown[]
|
|
}
|
|
}
|
|
|
|
/** Read-only transport for a page graph compiled before workers start. */
|
|
export class SsrModuleArtifactTransport implements ModuleRunnerTransport {
|
|
readonly #reader: SsrModuleArtifactReader
|
|
|
|
constructor(
|
|
private readonly moduleStorePath: string,
|
|
private readonly builtins: SerializedSsrBuiltin[],
|
|
moduleSnapshotPath?: string
|
|
) {
|
|
this.#reader = new SsrModuleArtifactReader(
|
|
moduleStorePath,
|
|
moduleSnapshotPath
|
|
)
|
|
}
|
|
|
|
async invoke(payload: unknown): Promise<{ result: unknown }> {
|
|
if (!isViteInvokePayload(payload)) {
|
|
throw new Error('SSR worker received an invalid Vite invoke payload.')
|
|
}
|
|
if (payload.data.name === 'getBuiltins') {
|
|
return { result: this.builtins }
|
|
}
|
|
|
|
const [id, rawImporter, rawOptions] = payload.data.data
|
|
if (typeof id !== 'string') {
|
|
throw new TypeError('SSR module artifact request id must be a string.')
|
|
}
|
|
const importer = typeof rawImporter === 'string' ? rawImporter : undefined
|
|
const options =
|
|
rawOptions && typeof rawOptions === 'object'
|
|
? (rawOptions as { cached?: boolean })
|
|
: undefined
|
|
if (options?.cached) {
|
|
return { result: { cache: true } }
|
|
}
|
|
|
|
const artifact = await this.#reader.read(id, importer)
|
|
if (!artifact) {
|
|
throw new Error(
|
|
`Missing precompiled SSR module ${JSON.stringify(id)}` +
|
|
(importer ? ` imported by ${JSON.stringify(importer)}` : '') +
|
|
`. The coordinator did not materialize the complete page graph at ${this.moduleStorePath}.`
|
|
)
|
|
}
|
|
return { result: artifact.result }
|
|
}
|
|
}
|
|
|
|
function isViteInvokePayload(value: unknown): value is ViteInvokePayload {
|
|
if (!value || typeof value !== 'object') return false
|
|
const payload = value as Partial<ViteInvokePayload>
|
|
const data = payload.data as Partial<ViteInvokePayload['data']> | undefined
|
|
return (
|
|
payload.type === 'custom' &&
|
|
payload.event === 'vite:invoke' &&
|
|
!!data &&
|
|
(data.name === 'fetchModule' || data.name === 'getBuiltins') &&
|
|
Array.isArray(data.data)
|
|
)
|
|
}
|