fix(ptc-runtime-node): preserve native then-export results
This commit is contained in:
1 parent
c61f117ba0
commit
55cef1caf7
2 files changed
+13
-1
No files matched your search
@@ -1,5 +1,6 @@
|
||||
/** Adapt runner-local import decisions to Node's VM module callbacks. */
|
||||
import * as vm from 'node:vm'
|
||||
import { types } from 'node:util'
|
||||
import type { ImportAttributes } from 'node:module'
|
||||
import type { ProgramImportHandler } from '../evaluators/types.ts'
|
||||
|
||||
@@ -56,7 +57,10 @@ export class VmModuleImportLoader {
|
||||
nativeImport ??= vm.compileFunction('return import(specifier, { with: attributes })', ['specifier', 'attributes'], {
|
||||
filename, importModuleDynamically: vm.constants.USE_MAIN_CONTEXT_DEFAULT_LOADER,
|
||||
}) as NativeImport
|
||||
return nativeImport(specifier, attributes)
|
||||
const value = await nativeImport(specifier, attributes)
|
||||
if (types.isModuleNamespaceObject(value)) return value
|
||||
// A native then export can settle to any value; the VM callback still requires a module.
|
||||
return this.module({ then(resolve: (result: unknown) => void) { resolve(value) } })
|
||||
}
|
||||
// Node accepts namespace objects as well as vm.Module; the Node types declare only vm.Module.
|
||||
return load as vm.DynamicModuleLoader<object>
|
||||
|
||||
@@ -125,6 +125,14 @@ it.each(formats)('preserves JavaScript then-export assimilation in %s', async (f
|
||||
else expect(await e.expression('import("runner:then")')).toBe(42)
|
||||
})
|
||||
|
||||
it.each(['default', 'redirect'] as const)('preserves native then-export results through Script %s loading', async (decision) => {
|
||||
const specifier = 'data:text/javascript,export function then(resolve) { resolve({ answer() { return 42 } }) }'
|
||||
const handler = vi.fn((): ProgramImportResult => decision === 'default' ? { type: 'default' } : { type: 'redirect', specifier })
|
||||
const e = evaluator('script', handler)
|
||||
expect(await e.expression(`(await import(${JSON.stringify(decision === 'default' ? specifier : 'runner:then')})).answer()`)).toBe(42)
|
||||
expect(handler).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('keeps async-function grammar and parameter semantics when imports are intercepted', async () => {
|
||||
const e = evaluator('function-body', () => ({ type: 'default' }))
|
||||
e.globals.answer = 42
|
||||
|
||||
Reference in new issue
Block a user