Vladimir 9be01ba594
feat!: use module-runner instead of vite-node (#8208)
Co-authored-by: Ari Perkkiö <ari.perkkio@gmail.com>
2025-07-28 13:43:53 +02:00

94 lines
2.8 KiB
TypeScript

import type { WorkerGlobalState } from 'vitest'
import type { CloneOption } from './types'
import ponyfillStructuredClone from '@ungap/structured-clone'
import createDebug from 'debug'
export const debug: createDebug.Debugger = createDebug('vitest:web-worker')
export function getWorkerState(): WorkerGlobalState {
// @ts-expect-error untyped global
return globalThis.__vitest_worker__
}
export function assertGlobalExists(name: string): void {
if (!(name in globalThis)) {
throw new Error(
`[@vitest/web-worker] Cannot initiate a custom Web Worker. "${name}" is not supported in this environment. Please, consider using jsdom or happy-dom environment.`,
)
}
}
function createClonedMessageEvent(
data: any,
transferOrOptions: StructuredSerializeOptions | Transferable[] | undefined,
clone: CloneOption,
) {
const transfer = Array.isArray(transferOrOptions)
? transferOrOptions
: transferOrOptions?.transfer
debug('clone worker message %o', data)
const origin = typeof location === 'undefined' ? undefined : location.origin
if (typeof structuredClone === 'function' && clone === 'native') {
debug('create message event, using native structured clone')
return new MessageEvent('message', {
data: structuredClone(data, { transfer }),
origin,
})
}
if (clone !== 'none') {
debug('create message event, using polyfilled structured clone')
if (transfer?.length) {
console.warn(
'[@vitest/web-worker] `structuredClone` is not supported in this environment. '
+ 'Falling back to polyfill, your transferable options will be lost. '
+ 'Set `VITEST_WEB_WORKER_CLONE` environmental variable to "none", if you don\'t want to loose it,'
+ 'or update to Node 17+.',
)
}
return new MessageEvent('message', {
data: ponyfillStructuredClone(data, { lossy: true } as any),
origin,
})
}
debug('create message event without cloning an object')
return new MessageEvent('message', {
data,
origin,
})
}
export function createMessageEvent(
data: any,
transferOrOptions: StructuredSerializeOptions | Transferable[] | undefined,
clone: CloneOption,
): MessageEvent {
try {
return createClonedMessageEvent(data, transferOrOptions, clone)
}
catch (error) {
debug('failed to clone message, dispatch "messageerror" event: %o', error)
return new MessageEvent('messageerror', {
data: error,
})
}
}
function stripProtocol(url: string | URL) {
return url.toString().replace(/^file:\/+/, '/')
}
export function getFileIdFromUrl(url: URL | string): string {
if (typeof self === 'undefined') {
return stripProtocol(url)
}
if (!(url instanceof URL)) {
url = new URL(url, self.location.origin)
}
if (url.protocol === 'http:' || url.protocol === 'https:') {
return url.pathname
}
return stripProtocol(url)
}