From e8839a4bef9a04f70714acf307ff8db5bcbb07f8 Mon Sep 17 00:00:00 2001 From: Kris Kowal Date: Thu, 5 Sep 2024 17:18:29 -0700 Subject: [PATCH] feat(module-source): Introduce a shim that composes with lockdown --- packages/module-source/package.json | 1 + packages/module-source/shim.js | 10 ++++++++++ packages/module-source/src/module-source.js | 15 +++++++++++++++ packages/ses/test/module-source.test.js | 8 +++++++- 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 packages/module-source/shim.js diff --git a/packages/module-source/package.json b/packages/module-source/package.json index a40e2ecb77..4599af06b8 100644 --- a/packages/module-source/package.json +++ b/packages/module-source/package.json @@ -23,6 +23,7 @@ "main": "./index.js", "exports": { ".": "./index.js", + "./shim.js": "./shim.js", "./package.json": "./package.json" }, "scripts": { diff --git a/packages/module-source/shim.js b/packages/module-source/shim.js new file mode 100644 index 0000000000..e1d8c5b98e --- /dev/null +++ b/packages/module-source/shim.js @@ -0,0 +1,10 @@ +/* global globalThis */ + +import { ModuleSource } from './index.js'; + +Object.defineProperty(globalThis, 'ModuleSource', { + value: ModuleSource, + enumerable: false, + writable: true, + configurable: true, +}); diff --git a/packages/module-source/src/module-source.js b/packages/module-source/src/module-source.js index d220cb23df..7d32a89a23 100644 --- a/packages/module-source/src/module-source.js +++ b/packages/module-source/src/module-source.js @@ -55,6 +55,19 @@ const analyzeModule = makeModuleAnalyzer(); * @property {SourceMapHook} [sourceMapHook] */ +// https://github.com/tc39/proposal-source-phase-imports?tab=readme-ov-file#js-module-source +function AbstractModuleSource() { + // no-op, safe to super() +} + +// WebAssembly and ModuleSource are both in motion. +// The Source Phase Imports proposal implies an additional AbstractModuleSource +// layer above the existing WebAssembly.Module that would be shared by +// the JavaScript ModuleSource prototype chain. +// At time of writing, no version of WebAssembly provides the shared base class, +// and the shimmed ModuleSource gains nothing from sharing that prototype when +// it comes into being. + // XXX implements import('ses').PrecompiledModuleSource but adding // `@implements` errors that this isn't a class and `@returns` errors that // there's no value returned. @@ -100,3 +113,5 @@ export function ModuleSource(source, opts = {}) { this.__needsImportMeta__ = needsImportMeta; freeze(this); } + +Object.setPrototypeOf(ModuleSource.prototype, AbstractModuleSource.prototype); diff --git a/packages/ses/test/module-source.test.js b/packages/ses/test/module-source.test.js index 4f94584392..dfdd0c2772 100644 --- a/packages/ses/test/module-source.test.js +++ b/packages/ses/test/module-source.test.js @@ -1,6 +1,8 @@ +/// + import test from 'ava'; import '../index.js'; -import { ModuleSource } from '@endo/module-source'; +import '@endo/module-source/shim.js'; lockdown(); @@ -42,3 +44,7 @@ test('module source constructor', t => { 'ModuleSource imports should be frozen', ); }); + +test('ModuleSource is a shared intrinsic', t => { + t.truthy(ModuleSource === new Compartment().globalThis.ModuleSource); +});