New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More

@masknet/compartment

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@masknet/compartment - npm Package Compare versions

Comparing version

to
0.4.0

@@ -69,8 +69,5 @@ class ModuleSource {

/** @internal */ const opaqueProxy = /*#__PURE__*/ getOpaqueProxy();
/** @internal */ function internalError() {
throw new TypeError('Internal error.');
/** @internal */ function assertFailed(message) {
throw new TypeError('Assertion failed.' + (message ? ' ' : '') + message);
}
/** @internal */ function assertFailed() {
throw new TypeError('Assertion failed.');
}
/** @internal */ function unreachable(val) {

@@ -256,20 +253,23 @@ throw new TypeError('Unreachable');

let imports;
/** @internal */ let setGlobalThis;
/** @internal */ let setParentGlobalThis;
/** @internal */ let setParentImportHook;
/** @internal */ let setParentImportMetaHook;
class Module {
// The constructor is equivalent to ParseModule in SourceTextModuleRecord
// https://tc39.es/ecma262/#sec-parsemodule
constructor(moduleSource, referral, // it actually NOT an optional argument when it is the top-level Module.
importHook = defaultImportHook, importMeta){
constructor(moduleSource, handler){
if (typeof moduleSource !== 'object') throw new TypeError('moduleSource must be an object');
if (typeof referral === 'object' && referral !== null) throw new TypeError('referral must be a primitive');
if (typeof importHook !== 'function') throw new TypeError('importHook must be a function');
let assignedImportMeta;
if (importMeta === undefined) assignedImportMeta = null;
else if (typeof importMeta !== 'object') throw new TypeError('importMeta must be an object');
else assignedImportMeta = importMeta;
// impossible to create a ModuleSource instance
if (moduleSource instanceof ModuleSource) internalError();
if (moduleSource instanceof ModuleSource) assertFailed('ModuleSource instance cannot be created');
const module = normalizeVirtualModuleRecord(moduleSource);
this.#Source = moduleSource;
this.#Referral = referral;
if (handler === null) throw new TypeError('handler must not be null');
let importHook;
let importMetaHook;
if (typeof handler === 'object') {
importHook = handler.importHook;
if (typeof importHook !== 'function' && importHook !== undefined) throw new TypeError('importHook must be a function');
importMetaHook = handler.importMetaHook;
if (typeof importMetaHook !== 'function' && importMetaHook !== undefined) throw new TypeError('importMetaHook must be a function');
}
this.#VirtualModuleSource = moduleSource;
this.#Execute = module.execute;

@@ -279,4 +279,5 @@ this.#NeedsImport = module.needsImport;

this.#HasTLA = !!module.isAsync;
this.#AssignedImportMeta = assignedImportMeta;
this.#ImportHook = importHook;
this.#ImportMetaHook = importMetaHook;
this.#HandlerValue = handler;
const { importEntries , indirectExportEntries , localExportEntries , requestedModules , starExportEntries } = normalizeBindingsToSpecRecord(module.bindings);

@@ -290,3 +291,3 @@ this.#ImportEntries = importEntries;

get source() {
return this.#Source;
return this.#VirtualModuleSource;
}

@@ -299,4 +300,3 @@ //#region ModuleRecord fields https://tc39.es/ecma262/#table-module-record-fields

// *this value* when calling #Execute.
#Referral;
#Source;
#VirtualModuleSource;
#Execute;

@@ -307,5 +307,7 @@ #NeedsImportMeta;

#ImportHook;
#ImportHookCache = new Map();
#AssignedImportMeta;
#ImportMetaHook;
#HandlerValue;
/** the global environment this module binds to */ #GlobalThis = globalThis;
#ParentImportHook = defaultImportHook;
#ParentImportMetaHook;
/** imported module cache */ #ImportEntries;

@@ -328,2 +330,3 @@ #LocalExportEntries;

const module = this;
if (!(module.#Status !== 0)) assertFailed();
if (exportStarSet.includes(module)) return [];

@@ -343,4 +346,2 @@ exportStarSet.push(module);

const requestedModule = Module.#GetImportedModule(module, e2.ModuleRequest);
// TODO: https://github.com/tc39/ecma262/pull/2905/files#r973044508
if (!requestedModule) assertFailed();
const starNames = requestedModule.#GetExportedNames(exportStarSet);

@@ -358,2 +359,3 @@ for (const n of starNames){

const module1 = this;
if (!(module1.#Status !== 0)) assertFailed();
for (const r of resolveSet){

@@ -383,4 +385,2 @@ if (module1 === r.module && exportName === r.exportName) {

const importedModule = Module.#GetImportedModule(module1, e4.ModuleRequest);
// TODO: https://github.com/tc39/ecma262/pull/2905/files#r973044508
if (!importedModule) assertFailed();
if (e4.ImportName === all) {

@@ -407,4 +407,2 @@ // Assert: module does not provide the direct binding for this export.

const importedModule1 = Module.#GetImportedModule(module1, e5.ModuleRequest);
// TODO: https://github.com/tc39/ecma262/pull/2905/files#r973044508
if (!importedModule1) assertFailed();
let resolution = importedModule1.#ResolveExport(exportName, resolveSet);

@@ -430,5 +428,4 @@ if (resolution === ambiguous) return ambiguous;

const state = {
Action: 'graph-loading',
IsLoading: true,
PendingModules: 1,
PendingModulesCount: 1,
Visited: [],

@@ -446,18 +443,16 @@ PromiseCapability: pc,

const requestedModulesCount = module3.#RequestedModules.length;
state1.PendingModules = state1.PendingModules + requestedModulesCount;
state1.PendingModulesCount = state1.PendingModulesCount + requestedModulesCount;
for (const required of module3.#RequestedModules){
if (state1.IsLoading) {
const record = module3.#LoadedModules.get(required);
if (record) {
Module.#InnerModuleLoading(state1, record);
} else {
Module.#HostLoadImportedModule(module3, required, state1.HostDefined, state1);
}
const record = module3.#LoadedModules.get(required);
if (record) {
Module.#InnerModuleLoading(state1, record);
} else {
Module.#LoadImportedModule(module3, required, state1.HostDefined, state1);
}
if (!state1.IsLoading) return;
}
}
if (!state1.IsLoading) return;
if (!(state1.PendingModules >= 1)) assertFailed();
state1.PendingModules = state1.PendingModules - 1;
if (state1.PendingModules === 0) {
if (!(state1.PendingModulesCount >= 1)) assertFailed();
state1.PendingModulesCount = state1.PendingModulesCount - 1;
if (state1.PendingModulesCount === 0) {
state1.IsLoading = false;

@@ -516,3 +511,2 @@ for (const loaded of state1.Visited){

const importedModule2 = Module.#GetImportedModule(module4, i.ModuleRequest);
if (!importedModule2) assertFailed();
// import * as ns from '..'

@@ -572,3 +566,3 @@ if (i.ImportName === namespace) {

// Note: export property should not be enumerable?
// but it will crash Chrome devtools.See: https://bugs.chromium.org/p/chromium/issues/detail?id=1358114
// but it will crash Chrome devtools. See: https://bugs.chromium.org/p/chromium/issues/detail?id=1358114
enumerable: true

@@ -588,17 +582,41 @@ };

/** All call to ExecuteModule must use Task.run to keep the call stack continue */ #ExecuteModule(promise) {
const execute = this.#Execute;
if (!execute) return;
this.#Execute = undefined;
// prepare context
this.#ContextObject.globalThis = this.#GlobalThis;
if (this.#NeedsImportMeta) {
this.#ContextObject.importMeta = Object.assign({}, this.#AssignedImportMeta);
const importMeta = {
__proto__: null
};
if (this.#ImportMetaHook) Reflect.apply(this.#ImportMetaHook, this.#HandlerValue, [
importMeta
]);
else if (this.#ParentImportMetaHook) Reflect.apply(this.#ParentImportMetaHook, undefined, [
importMeta
]);
this.#ContextObject.importMeta = importMeta;
}
if (this.#NeedsImport) {
this.#ContextObject.import = async (specifier, options)=>{
specifier = String(specifier);
const status = {
Action: 'dynamic-import',
PromiseCapability: PromiseCapability(),
HostDefined: createTask(`import("${specifier}")`)
};
Module.#HostLoadImportedModule(this, specifier, status.HostDefined, status);
return status.PromiseCapability.Promise;
const referrer = this;
const promiseCapability = PromiseCapability();
let hasModuleInternalSlot = false;
try {
specifier.#HandlerValue;
hasModuleInternalSlot = true;
} catch {}
if (hasModuleInternalSlot) {
const hostDefined = createTask(`import(<module block>)`);
Module.#ContinueDynamicImport(promiseCapability, NormalCompletion(specifier), hostDefined);
} else {
specifier = String(specifier);
const hostDefined1 = createTask(`import("${specifier}")`);
if (referrer.#LoadedModules.has(specifier)) {
Module.#ContinueDynamicImport(promiseCapability, NormalCompletion(referrer.#LoadedModules.get(specifier)), hostDefined1);
} else {
Module.#LoadImportedModule(referrer, specifier, hostDefined1, promiseCapability);
}
}
return promiseCapability.Promise;
};

@@ -609,19 +627,15 @@ }

if (!this.#HasTLA) {
if (!!promise) assertFailed();
if (this.#Execute) {
Reflect.apply(this.#Execute, this.#Source, [
env1,
this.#ContextObject
]);
}
if (promise) assertFailed();
const result = Reflect.apply(execute, this.#VirtualModuleSource, [
env1,
this.#ContextObject
]);
if (result) throw new TypeError('Due to specification limitations, in order to support Async Modules (modules that use Top Level Await or a Virtual Module that has an execute() function that returns a Promise), the Virtual Module record must be marked with `isAsync: true`. The `isAsync` property is non-standard, and it is being tracked in https://github.com/tc39/proposal-compartments/issues/84.');
} else {
if (!promise) assertFailed();
if (this.#Execute) {
Promise.resolve(Reflect.apply(this.#Execute, this.#Source, [
env1,
this.#ContextObject
])).then(promise.Resolve, promise.Reject);
}
Promise.resolve(Reflect.apply(execute, this.#VirtualModuleSource, [
env1,
this.#ContextObject
])).then(promise.Resolve, promise.Reject);
}
this.#Execute = undefined;
}

@@ -719,3 +733,2 @@ // https://tc39.es/ecma262/#sec-moduledeclarationlinking

const requiredModule = this.#GetImportedModule(module7, required1);
if (!requiredModule) assertFailed();
index = this.#InnerModuleLinking(requiredModule, stack2, index);

@@ -769,3 +782,2 @@ if (![

let requiredModule2 = this.#GetImportedModule(module8, required2);
if (!requiredModule2) assertFailed();
index1 = this.#InnerModuleEvaluation(requiredModule2, stack3, index1, HostDefined2);

@@ -918,3 +930,3 @@ if (![

if (module12.#Namespace) return module12.#Namespace;
if (!(module12.#Status !== 1)) assertFailed();
if (!(module12.#Status !== 0 && module12.#Status !== 1)) assertFailed();
const exportedNames1 = module12.#GetExportedNames();

@@ -975,55 +987,37 @@ const namespaceObject2 = {

static #GetImportedModule(module13, spec) {
return module13.#LoadedModules.get(spec);
const record1 = module13.#LoadedModules.get(spec);
if (!record1) assertFailed();
return record1;
}
static #HostLoadImportedModule(referrer, specifier, hostDefined, payload) {
let promiseCapability = referrer.#ImportHookCache.get(specifier);
function onFulfilled(module) {
promiseCapability?.Resolve(module);
Module.#FinishLoadingImportedModule(referrer, specifier, payload, NormalCompletion(module));
}
function onRejected(reason) {
promiseCapability?.Reject(reason);
Module.#FinishLoadingImportedModule(referrer, specifier, payload, ThrowCompletion(reason));
}
if (promiseCapability) {
if (promiseCapability.Status.Type === 'Fulfilled') {
onFulfilled(promiseCapability.Status.Value);
return;
} else if (promiseCapability.Status.Type === 'Pending') {
promiseCapability.Promise.then(onFulfilled, onRejected);
return;
}
// if error, fallthorugh
}
promiseCapability = PromiseCapability();
referrer.#ImportHookCache.set(specifier, promiseCapability);
static #LoadImportedModule(referrer, specifier, hostDefined, payload) {
try {
const result = referrer.#ImportHook(specifier, referrer.#Referral);
if (result === null) throw new SyntaxError(`Failed to load module ${specifier}.`);
try {
const module14 = result;
module14.#Referral;
onFulfilled(module14);
return;
} catch {}
// treat it as a Promise
Promise.resolve(result).then((result)=>{
if (result === null) onRejected(new SyntaxError(`Failed to load module ${specifier}.`));
const importHookResult = referrer.#ImportHook ? Reflect.apply(referrer.#ImportHook, referrer.#HandlerValue, [
specifier
]) : Reflect.apply(referrer.#ParentImportHook, undefined, [
specifier
]);
const importHookPromise = Promise.resolve(importHookResult);
const onFulfilled = (result)=>{
let completion;
try {
const module = result;
module.#Referral;
onFulfilled(module);
result.#HandlerValue;
completion = NormalCompletion(result);
} catch (error) {
onRejected(new TypeError('importHook must return an instance of Module'));
completion = ThrowCompletion(new TypeError('importHook must return a Module instance'));
}
});
this.#FinishLoadingImportedModule(referrer, specifier, payload, completion, hostDefined);
};
const onRejected = (error)=>{
this.#FinishLoadingImportedModule(referrer, specifier, payload, ThrowCompletion(error), hostDefined);
};
importHookPromise.then(onFulfilled, onRejected);
} catch (error) {
onRejected(error);
this.#FinishLoadingImportedModule(referrer, specifier, payload, ThrowCompletion(error), hostDefined);
}
}
static #FinishLoadingImportedModule(referrer1, specifier1, state3, result1) {
static #FinishLoadingImportedModule(referrer1, specifier1, payload1, result1, hostDefined1) {
if (result1.Type === 'normal') {
const record1 = referrer1.#LoadedModules.get(specifier1);
if (record1) {
if (!(record1 === result1.Value)) assertFailed();
const record2 = referrer1.#LoadedModules.get(specifier1);
if (record2) {
if (!(record2 === result1.Value)) assertFailed();
} else {

@@ -1033,34 +1027,29 @@ referrer1.#LoadedModules.set(specifier1, result1.Value);

}
if (state3.Action === 'graph-loading') {
Module.#ContinueModuleLoading(state3, result1);
if ('Visited' in payload1) {
Module.#ContinueModuleLoading(payload1, result1);
} else {
Module.#ContinueDynamicImport(state3, result1);
Module.#ContinueDynamicImport(payload1, result1, hostDefined1);
}
}
static #ContinueDynamicImport(state4, moduleCompletion1) {
const promiseCapability1 = state4.PromiseCapability;
static #ContinueDynamicImport(promiseCapability, moduleCompletion1, hostDefined2) {
if (moduleCompletion1.Type === 'throw') {
promiseCapability1.Reject(moduleCompletion1.Value);
promiseCapability.Reject(moduleCompletion1.Value);
return;
}
const module15 = moduleCompletion1.Value;
const loadPromise = module15.#LoadRequestedModules(state4.HostDefined);
const module14 = moduleCompletion1.Value;
const loadPromise = module14.#LoadRequestedModules(hostDefined2);
function onRejected1(reason) {
promiseCapability1.Reject(reason);
promiseCapability.Reject(reason);
}
function linkAndEvaluate() {
try {
module15.#Link();
const evaluatePromise = module15.#Evaluate(state4.HostDefined);
module14.#Link();
const evaluatePromise = module14.#Evaluate(hostDefined2);
function onFulfilled() {
try {
const namespace = Module.#GetModuleNamespace(module15);
promiseCapability1.Resolve(namespace);
} catch (error) {
promiseCapability1.Reject(error);
}
const namespace = Module.#GetModuleNamespace(module14);
promiseCapability.Resolve(namespace);
}
evaluatePromise.then(onFulfilled, onRejected1);
} catch (error) {
promiseCapability1.Reject(error);
promiseCapability.Reject(error);
}

@@ -1074,14 +1063,9 @@ }

const promiseCapability = PromiseCapability();
let HostDefinedName = 'Module<...>';
if (typeof module.#Referral === 'symbol') HostDefinedName = `Module<@${module.#Referral.description}>`;
else if (typeof module.#Referral === 'string') HostDefinedName = `"${module.#Referral}"`;
const state = {
Action: 'dynamic-import',
PromiseCapability: promiseCapability,
HostDefined: createTask(`import(${HostDefinedName})`)
};
Module.#ContinueDynamicImport(state, NormalCompletion(module));
const hostDefined = createTask(`import(<module block>)`);
Module.#ContinueDynamicImport(promiseCapability, NormalCompletion(module), hostDefined);
return promiseCapability.Promise;
};
setGlobalThis = (module, global)=>module.#GlobalThis = global;
setParentGlobalThis = (module, global)=>module.#GlobalThis = global;
setParentImportHook = (module, hook)=>module.#ParentImportHook = hook;
setParentImportMetaHook = (module, hook)=>module.#ParentImportMetaHook = hook;
}

@@ -1152,15 +1136,4 @@ }

getOwnPropertyDescriptor: ()=>undefined,
defineProperty () {
// TODO:
internalError();
},
deleteProperty () {
return false;
},
has () {
return false;
},
ownKeys () {
return [];
},
defineProperty: ()=>false,
deleteProperty: ()=>false,
isExtensible: ()=>false,

@@ -1173,39 +1146,59 @@ preventExtensions: ()=>true,

class Evaluators {
constructor(options){
const { globalThis: globalThis1 = realGlobalThis , importHook =defaultImportHook , importMeta =null } = options;
if (typeof globalThis1 !== 'object') throw new TypeError('globalThis must be an object');
if (typeof importHook !== 'function') throw new TypeError('importHook must be a function');
if (typeof importMeta !== 'object') throw new TypeError('importMeta must be an object');
get globalThis() {
return this.#AssignGlobalThis;
}
// We do not support `eval` and `Function`.
eval = eval;
Function = Function;
// implementation
constructor(handler){
const { globalThis: globalThis1 , importHook , importMeta } = handler;
this.#Handler = handler;
if (typeof globalThis1 !== 'object' && globalThis1 !== undefined) throw new TypeError('globalThis must be an object');
if (typeof importHook !== 'function' && importHook !== undefined) throw new TypeError('importHook must be a function');
if (typeof importMeta !== 'object' && importMeta !== undefined && importMeta !== null) throw new TypeError('importMeta must be an object');
const parent = this;
class Evaluators extends TopEvaluators {
constructor(options){
const { globalThis: globalThis1 = parent.#globalThis , importHook =parent.#importHook , importMeta =parent.#importMeta ?? null } = options;
super({
globalThis: globalThis1,
importHook,
importMeta
});
super(options);
this.#ParentEvaluator = parent;
}
}
let Module$1 = class Module extends Module {
constructor(moduleSource, referral, importHook, importMeta){
super(moduleSource, referral, importHook ?? parent.#importHook, importMeta ?? parent.#importMeta);
setGlobalThis(this, parent.#globalThis);
constructor(moduleSource, handler){
super(moduleSource, handler);
setParentGlobalThis(this, parent.#CalculatedGlobalThis ??= parent.#GetGlobalThis());
setParentImportHook(this, parent.#CalculatedImportHook ??= parent.#GetImportHook());
setParentImportMetaHook(this, (meta)=>Object.assign(meta, parent.#CalculatedImportMeta ??= parent.#GetImportMeta()));
}
};
this.#importHook = importHook;
this.#importMeta = importMeta ?? undefined;
this.#globalThis = globalThis1;
this.#AssignedImportHook = importHook;
this.#AssignedImportMeta = importMeta;
this.#AssignGlobalThis = globalThis1;
this.Module = Module$1;
this.Evaluators = Evaluators;
}
get globalThis() {
return this.#globalThis;
#ParentEvaluator;
#AssignGlobalThis;
#AssignedImportHook;
#AssignedImportMeta;
#CalculatedGlobalThis;
#CalculatedImportHook;
#CalculatedImportMeta;
#Handler;
#GetGlobalThis() {
if (this.#AssignGlobalThis) return this.#AssignGlobalThis;
if (this.#ParentEvaluator) return this.#ParentEvaluator.#GetGlobalThis();
return realGlobalThis;
}
// We do not support `eval` and `Function`.
eval = eval;
Function = Function;
#globalThis;
#importHook;
#importMeta;
#GetImportHook() {
if (this.#AssignedImportHook) return this.#AssignedImportHook.bind(this.#Handler);
if (this.#ParentEvaluator) return this.#ParentEvaluator.#GetImportHook();
return defaultImportHook;
}
#GetImportMeta() {
if (this.#AssignedImportMeta) return this.#AssignedImportMeta;
if (this.#ParentEvaluator) return this.#ParentEvaluator.#GetImportMeta();
return null;
}
}

@@ -1215,3 +1208,3 @@ const TopEvaluators = Evaluators;

/** @internal */ function defaultImportHook() {
throw new TypeError(`This evaluator does not have any import resolution.`);
throw new TypeError(`This evaluator does not have any import resolution strategy.`);
}

@@ -1218,0 +1211,0 @@

import { Module } from './Module.js';
import type { ImportHook } from './types.js';
export interface EvaluatorsOptions {
globalThis?: object;
importHook?: ImportHook;
importMeta?: object | null;
globalThis?: object | undefined;
importHook?: ImportHook | undefined;
importMeta?: object | null | undefined;
}
export declare class Evaluators {
#private;
constructor(options: EvaluatorsOptions);
Module: typeof Module;
Evaluators: typeof Evaluators;
get globalThis(): object;
get globalThis(): object | undefined;
eval: typeof eval;
Function: FunctionConstructor;
constructor(handler: EvaluatorsOptions);
}
//# sourceMappingURL=Evaluators.d.ts.map

@@ -1,10 +0,20 @@

import { Module, Module as TopModule, setGlobalThis } from './Module.js';
import { Module, Module as TopModule, setParentGlobalThis, setParentImportHook, setParentImportMetaHook, } from './Module.js';
export class Evaluators {
constructor(options) {
const { globalThis = realGlobalThis, importHook = defaultImportHook, importMeta = null } = options;
if (typeof globalThis !== 'object')
Module;
Evaluators;
get globalThis() {
return this.#AssignGlobalThis;
}
// We do not support `eval` and `Function`.
eval = eval;
Function = Function;
// implementation
constructor(handler) {
const { globalThis, importHook, importMeta } = handler;
this.#Handler = handler;
if (typeof globalThis !== 'object' && globalThis !== undefined)
throw new TypeError('globalThis must be an object');
if (typeof importHook !== 'function')
if (typeof importHook !== 'function' && importHook !== undefined)
throw new TypeError('importHook must be a function');
if (typeof importMeta !== 'object')
if (typeof importMeta !== 'object' && importMeta !== undefined && importMeta !== null)
throw new TypeError('importMeta must be an object');

@@ -14,29 +24,49 @@ const parent = this;

constructor(options) {
const { globalThis = parent.#globalThis, importHook = parent.#importHook, importMeta = parent.#importMeta ?? null, } = options;
super({ globalThis, importHook, importMeta });
super(options);
this.#ParentEvaluator = parent;
}
}
class Module extends TopModule {
constructor(moduleSource, referral, importHook, importMeta) {
super(moduleSource, referral, importHook ?? parent.#importHook, importMeta ?? parent.#importMeta);
setGlobalThis(this, parent.#globalThis);
constructor(moduleSource, handler) {
super(moduleSource, handler);
setParentGlobalThis(this, (parent.#CalculatedGlobalThis ??= parent.#GetGlobalThis()));
setParentImportHook(this, (parent.#CalculatedImportHook ??= parent.#GetImportHook()));
setParentImportMetaHook(this, (meta) => Object.assign(meta, (parent.#CalculatedImportMeta ??= parent.#GetImportMeta())));
}
}
this.#importHook = importHook;
this.#importMeta = importMeta ?? undefined;
this.#globalThis = globalThis;
this.#AssignedImportHook = importHook;
this.#AssignedImportMeta = importMeta;
this.#AssignGlobalThis = globalThis;
this.Module = Module;
this.Evaluators = Evaluators;
}
Module;
Evaluators;
get globalThis() {
return this.#globalThis;
#ParentEvaluator;
#AssignGlobalThis;
#AssignedImportHook;
#AssignedImportMeta;
#CalculatedGlobalThis;
#CalculatedImportHook;
#CalculatedImportMeta;
#Handler;
#GetGlobalThis() {
if (this.#AssignGlobalThis)
return this.#AssignGlobalThis;
if (this.#ParentEvaluator)
return this.#ParentEvaluator.#GetGlobalThis();
return realGlobalThis;
}
// We do not support `eval` and `Function`.
eval = eval;
Function = Function;
#globalThis;
#importHook;
#importMeta;
#GetImportHook() {
if (this.#AssignedImportHook)
return this.#AssignedImportHook.bind(this.#Handler);
if (this.#ParentEvaluator)
return this.#ParentEvaluator.#GetImportHook();
return defaultImportHook;
}
#GetImportMeta() {
if (this.#AssignedImportMeta)
return this.#AssignedImportMeta;
if (this.#ParentEvaluator)
return this.#ParentEvaluator.#GetImportMeta();
return null;
}
}

@@ -47,4 +77,4 @@ const TopEvaluators = Evaluators;

export function defaultImportHook() {
throw new TypeError(`This evaluator does not have any import resolution.`);
throw new TypeError(`This evaluator does not have any import resolution strategy.`);
}
//# sourceMappingURL=Evaluators.js.map

@@ -1,2 +0,2 @@

export type { Binding, ImportBinding, ImportAllBinding, ExportBinding, ExportAllBinding, VirtualModuleRecord, VirtualModuleRecordExecuteContext, ModuleNamespace, ImportHook, Referral, StaticModuleRecordInstance, } from './types.js';
export type { Binding, ImportBinding, ImportAllBinding, ExportBinding, ExportAllBinding, VirtualModuleRecord, VirtualModuleRecordExecuteContext, ModuleNamespace, ImportHook, ImportMetaHook, ModuleHandler, } from './types.js';
export { ModuleSource } from './ModuleSource.js';

@@ -3,0 +3,0 @@ export { Evaluators } from './Evaluators.js';

import { ModuleSource } from './ModuleSource.js';
import type { ImportHook, Referral, VirtualModuleRecord } from './types.js';
export declare let imports: <T extends object = any>(specifier: Module<T>, options?: ImportCallOptions) => Promise<T>;
export declare class Module<T extends object = any> {
import type { ModuleHandler, ModuleNamespace, VirtualModuleRecord } from './types.js';
export declare let imports: <T extends ModuleNamespace = any>(specifier: Module<T>, options?: ImportCallOptions) => Promise<T>;
export declare class Module<T extends ModuleNamespace = any> {
#private;
constructor(moduleSource: ModuleSource<T> | VirtualModuleRecord, referral: Referral, importHook?: ImportHook, importMeta?: object);
constructor(moduleSource: ModuleSource<T> | VirtualModuleRecord, handler: ModuleHandler);
get source(): ModuleSource | VirtualModuleRecord | null;
}
//# sourceMappingURL=Module.d.ts.map
import { ModuleSource } from './ModuleSource.js';
import { all, ambiguous, empty, namespace, NormalCompletion, PromiseCapability, ThrowCompletion, } from './utils/spec.js';
import { normalizeBindingsToSpecRecord, normalizeVirtualModuleRecord } from './utils/normalize.js';
import { assertFailed, internalError, opaqueProxy } from './utils/assert.js';
import { assertFailed, opaqueProxy } from './utils/assert.js';
import { defaultImportHook } from './Evaluators.js';

@@ -9,28 +9,30 @@ import { createTask } from './utils/async-task.js';

/** @internal */
export let setGlobalThis;
export let setParentGlobalThis;
/** @internal */
export let setParentImportHook;
/** @internal */
export let setParentImportMetaHook;
export class Module {
// The constructor is equivalent to ParseModule in SourceTextModuleRecord
// https://tc39.es/ecma262/#sec-parsemodule
constructor(moduleSource, referral,
// it actually NOT an optional argument when it is the top-level Module.
importHook = defaultImportHook, importMeta) {
constructor(moduleSource, handler) {
if (typeof moduleSource !== 'object')
throw new TypeError('moduleSource must be an object');
if (typeof referral === 'object' && referral !== null)
throw new TypeError('referral must be a primitive');
if (typeof importHook !== 'function')
throw new TypeError('importHook must be a function');
let assignedImportMeta;
if (importMeta === undefined)
assignedImportMeta = null;
else if (typeof importMeta !== 'object')
throw new TypeError('importMeta must be an object');
else
assignedImportMeta = importMeta;
// impossible to create a ModuleSource instance
if (moduleSource instanceof ModuleSource)
internalError();
assertFailed('ModuleSource instance cannot be created');
const module = normalizeVirtualModuleRecord(moduleSource);
this.#Source = moduleSource;
this.#Referral = referral;
if (handler === null)
throw new TypeError('handler must not be null');
let importHook;
let importMetaHook;
if (typeof handler === 'object') {
importHook = handler.importHook;
if (typeof importHook !== 'function' && importHook !== undefined)
throw new TypeError('importHook must be a function');
importMetaHook = handler.importMetaHook;
if (typeof importMetaHook !== 'function' && importMetaHook !== undefined)
throw new TypeError('importMetaHook must be a function');
}
this.#VirtualModuleSource = moduleSource;
this.#Execute = module.execute;

@@ -40,4 +42,5 @@ this.#NeedsImport = module.needsImport;

this.#HasTLA = !!module.isAsync;
this.#AssignedImportMeta = assignedImportMeta;
this.#ImportHook = importHook;
this.#ImportMetaHook = importMetaHook;
this.#HandlerValue = handler;
const { importEntries, indirectExportEntries, localExportEntries, requestedModules, starExportEntries } = normalizeBindingsToSpecRecord(module.bindings);

@@ -51,3 +54,3 @@ this.#ImportEntries = importEntries;

get source() {
return this.#Source;
return this.#VirtualModuleSource;
}

@@ -62,4 +65,3 @@ //#region ModuleRecord fields https://tc39.es/ecma262/#table-module-record-fields

// *this value* when calling #Execute.
#Referral;
#Source;
#VirtualModuleSource;
#Execute;

@@ -70,6 +72,8 @@ #NeedsImportMeta;

#ImportHook;
#ImportHookCache = new Map();
#AssignedImportMeta;
#ImportMetaHook;
#HandlerValue;
/** the global environment this module binds to */
#GlobalThis = globalThis;
#ParentImportHook = defaultImportHook;
#ParentImportMetaHook;
/** imported module cache */

@@ -96,2 +100,4 @@ #ImportEntries;

const module = this;
if (!(module.#Status !== ModuleStatus.new))
assertFailed();
if (exportStarSet.includes(module))

@@ -115,5 +121,2 @@ return [];

const requestedModule = Module.#GetImportedModule(module, e.ModuleRequest);
// TODO: https://github.com/tc39/ecma262/pull/2905/files#r973044508
if (!requestedModule)
assertFailed();
const starNames = requestedModule.#GetExportedNames(exportStarSet);

@@ -133,2 +136,4 @@ for (const n of starNames) {

const module = this;
if (!(module.#Status !== ModuleStatus.new))
assertFailed();
for (const r of resolveSet) {

@@ -153,5 +158,2 @@ if (module === r.module && exportName === r.exportName) {

const importedModule = Module.#GetImportedModule(module, e.ModuleRequest);
// TODO: https://github.com/tc39/ecma262/pull/2905/files#r973044508
if (!importedModule)
assertFailed();
if (e.ImportName === all) {

@@ -178,5 +180,2 @@ // Assert: module does not provide the direct binding for this export.

const importedModule = Module.#GetImportedModule(module, e.ModuleRequest);
// TODO: https://github.com/tc39/ecma262/pull/2905/files#r973044508
if (!importedModule)
assertFailed();
let resolution = importedModule.#ResolveExport(exportName, resolveSet);

@@ -209,5 +208,4 @@ if (resolution === ambiguous)

const state = {
Action: 'graph-loading',
IsLoading: true,
PendingModules: 1,
PendingModulesCount: 1,
Visited: [],

@@ -226,21 +224,19 @@ PromiseCapability: pc,

const requestedModulesCount = module.#RequestedModules.length;
state.PendingModules = state.PendingModules + requestedModulesCount;
state.PendingModulesCount = state.PendingModulesCount + requestedModulesCount;
for (const required of module.#RequestedModules) {
if (state.IsLoading) {
const record = module.#LoadedModules.get(required);
if (record) {
Module.#InnerModuleLoading(state, record);
}
else {
Module.#HostLoadImportedModule(module, required, state.HostDefined, state);
}
const record = module.#LoadedModules.get(required);
if (record) {
Module.#InnerModuleLoading(state, record);
}
else {
Module.#LoadImportedModule(module, required, state.HostDefined, state);
}
if (!state.IsLoading)
return;
}
}
if (!state.IsLoading)
return;
if (!(state.PendingModules >= 1))
if (!(state.PendingModulesCount >= 1))
assertFailed();
state.PendingModules = state.PendingModules - 1;
if (state.PendingModules === 0) {
state.PendingModulesCount = state.PendingModulesCount - 1;
if (state.PendingModulesCount === 0) {
state.IsLoading = false;

@@ -301,4 +297,2 @@ for (const loaded of state.Visited) {

const importedModule = Module.#GetImportedModule(module, i.ModuleRequest);
if (!importedModule)
assertFailed();
// import * as ns from '..'

@@ -358,3 +352,3 @@ if (i.ImportName === namespace) {

// Note: export property should not be enumerable?
// but it will crash Chrome devtools.See: https://bugs.chromium.org/p/chromium/issues/detail?id=1358114
// but it will crash Chrome devtools. See: https://bugs.chromium.org/p/chromium/issues/detail?id=1358114
enumerable: true,

@@ -375,17 +369,42 @@ };

#ExecuteModule(promise) {
const execute = this.#Execute;
if (!execute)
return;
this.#Execute = undefined;
// prepare context
this.#ContextObject.globalThis = this.#GlobalThis;
if (this.#NeedsImportMeta) {
this.#ContextObject.importMeta = Object.assign({}, this.#AssignedImportMeta);
const importMeta = { __proto__: null };
if (this.#ImportMetaHook)
Reflect.apply(this.#ImportMetaHook, this.#HandlerValue, [importMeta]);
else if (this.#ParentImportMetaHook)
Reflect.apply(this.#ParentImportMetaHook, undefined, [importMeta]);
this.#ContextObject.importMeta = importMeta;
}
if (this.#NeedsImport) {
this.#ContextObject.import = async (specifier, options) => {
specifier = String(specifier);
const status = {
Action: 'dynamic-import',
PromiseCapability: PromiseCapability(),
HostDefined: createTask(`import("${specifier}")`),
};
Module.#HostLoadImportedModule(this, specifier, status.HostDefined, status);
return status.PromiseCapability.Promise;
const referrer = this;
const promiseCapability = PromiseCapability();
let hasModuleInternalSlot = false;
try {
;
specifier.#HandlerValue;
hasModuleInternalSlot = true;
}
catch { }
if (hasModuleInternalSlot) {
const hostDefined = createTask(`import(<module block>)`);
Module.#ContinueDynamicImport(promiseCapability, NormalCompletion(specifier), hostDefined);
}
else {
specifier = String(specifier);
const hostDefined = createTask(`import("${specifier}")`);
if (referrer.#LoadedModules.has(specifier)) {
Module.#ContinueDynamicImport(promiseCapability, NormalCompletion(referrer.#LoadedModules.get(specifier)), hostDefined);
}
else {
Module.#LoadImportedModule(referrer, specifier, hostDefined, promiseCapability);
}
}
return promiseCapability.Promise;
};

@@ -397,7 +416,7 @@ }

if (!this.#HasTLA) {
if (!!promise)
if (promise)
assertFailed();
if (this.#Execute) {
Reflect.apply(this.#Execute, this.#Source, [env, this.#ContextObject]);
}
const result = Reflect.apply(execute, this.#VirtualModuleSource, [env, this.#ContextObject]);
if (result)
throw new TypeError('Due to specification limitations, in order to support Async Modules (modules that use Top Level Await or a Virtual Module that has an execute() function that returns a Promise), the Virtual Module record must be marked with `isAsync: true`. The `isAsync` property is non-standard, and it is being tracked in https://github.com/tc39/proposal-compartments/issues/84.');
}

@@ -407,7 +426,4 @@ else {

assertFailed();
if (this.#Execute) {
Promise.resolve(Reflect.apply(this.#Execute, this.#Source, [env, this.#ContextObject])).then(promise.Resolve, promise.Reject);
}
Promise.resolve(Reflect.apply(execute, this.#VirtualModuleSource, [env, this.#ContextObject])).then(promise.Resolve, promise.Reject);
}
this.#Execute = undefined;
}

@@ -503,4 +519,2 @@ // https://tc39.es/ecma262/#sec-moduledeclarationlinking

const requiredModule = this.#GetImportedModule(module, required);
if (!requiredModule)
assertFailed();
index = this.#InnerModuleLinking(requiredModule, stack, index);

@@ -561,4 +575,2 @@ if (![

let requiredModule = this.#GetImportedModule(module, required);
if (!requiredModule)
assertFailed();
index = this.#InnerModuleEvaluation(requiredModule, stack, index, HostDefined);

@@ -739,3 +751,3 @@ if (![ModuleStatus.evaluating, ModuleStatus.evaluatingAsync, ModuleStatus.evaluated].includes(requiredModule.#Status))

return module.#Namespace;
if (!(module.#Status !== ModuleStatus.unlinked))
if (!(module.#Status !== ModuleStatus.new && module.#Status !== ModuleStatus.unlinked))
assertFailed();

@@ -793,57 +805,35 @@ const exportedNames = module.#GetExportedNames();

static #GetImportedModule(module, spec) {
return module.#LoadedModules.get(spec);
const record = module.#LoadedModules.get(spec);
if (!record)
assertFailed();
return record;
}
static #HostLoadImportedModule(referrer, specifier, hostDefined, payload) {
let promiseCapability = referrer.#ImportHookCache.get(specifier);
function onFulfilled(module) {
promiseCapability?.Resolve(module);
Module.#FinishLoadingImportedModule(referrer, specifier, payload, NormalCompletion(module));
}
function onRejected(reason) {
promiseCapability?.Reject(reason);
Module.#FinishLoadingImportedModule(referrer, specifier, payload, ThrowCompletion(reason));
}
if (promiseCapability) {
if (promiseCapability.Status.Type === 'Fulfilled') {
onFulfilled(promiseCapability.Status.Value);
return;
}
else if (promiseCapability.Status.Type === 'Pending') {
promiseCapability.Promise.then(onFulfilled, onRejected);
return;
}
// if error, fallthorugh
}
promiseCapability = PromiseCapability();
referrer.#ImportHookCache.set(specifier, promiseCapability);
static #LoadImportedModule(referrer, specifier, hostDefined, payload) {
try {
const result = referrer.#ImportHook(specifier, referrer.#Referral);
if (result === null)
throw new SyntaxError(`Failed to load module ${specifier}.`);
try {
const module = result;
module.#Referral;
onFulfilled(module);
return;
}
catch { }
// treat it as a Promise
Promise.resolve(result).then((result) => {
if (result === null)
onRejected(new SyntaxError(`Failed to load module ${specifier}.`));
const importHookResult = referrer.#ImportHook
? Reflect.apply(referrer.#ImportHook, referrer.#HandlerValue, [specifier])
: Reflect.apply(referrer.#ParentImportHook, undefined, [specifier]);
const importHookPromise = Promise.resolve(importHookResult);
const onFulfilled = (result) => {
let completion;
try {
const module = result;
module.#Referral;
onFulfilled(module);
;
result.#HandlerValue;
completion = NormalCompletion(result);
}
catch (error) {
onRejected(new TypeError('importHook must return an instance of Module'));
completion = ThrowCompletion(new TypeError('importHook must return a Module instance'));
}
});
this.#FinishLoadingImportedModule(referrer, specifier, payload, completion, hostDefined);
};
const onRejected = (error) => {
this.#FinishLoadingImportedModule(referrer, specifier, payload, ThrowCompletion(error), hostDefined);
};
importHookPromise.then(onFulfilled, onRejected);
}
catch (error) {
onRejected(error);
this.#FinishLoadingImportedModule(referrer, specifier, payload, ThrowCompletion(error), hostDefined);
}
}
static #FinishLoadingImportedModule(referrer, specifier, state, result) {
static #FinishLoadingImportedModule(referrer, specifier, payload, result, hostDefined) {
if (result.Type === 'normal') {

@@ -859,11 +849,10 @@ const record = referrer.#LoadedModules.get(specifier);

}
if (state.Action === 'graph-loading') {
Module.#ContinueModuleLoading(state, result);
if ('Visited' in payload) {
Module.#ContinueModuleLoading(payload, result);
}
else {
Module.#ContinueDynamicImport(state, result);
Module.#ContinueDynamicImport(payload, result, hostDefined);
}
}
static #ContinueDynamicImport(state, moduleCompletion) {
const promiseCapability = state.PromiseCapability;
static #ContinueDynamicImport(promiseCapability, moduleCompletion, hostDefined) {
if (moduleCompletion.Type === 'throw') {

@@ -874,3 +863,3 @@ promiseCapability.Reject(moduleCompletion.Value);

const module = moduleCompletion.Value;
const loadPromise = module.#LoadRequestedModules(state.HostDefined);
const loadPromise = module.#LoadRequestedModules(hostDefined);
function onRejected(reason) {

@@ -882,11 +871,6 @@ promiseCapability.Reject(reason);

module.#Link();
const evaluatePromise = module.#Evaluate(state.HostDefined);
const evaluatePromise = module.#Evaluate(hostDefined);
function onFulfilled() {
try {
const namespace = Module.#GetModuleNamespace(module);
promiseCapability.Resolve(namespace);
}
catch (error) {
promiseCapability.Reject(error);
}
const namespace = Module.#GetModuleNamespace(module);
promiseCapability.Resolve(namespace);
}

@@ -906,16 +890,9 @@ evaluatePromise.then(onFulfilled, onRejected);

const promiseCapability = PromiseCapability();
let HostDefinedName = 'Module<...>';
if (typeof module.#Referral === 'symbol')
HostDefinedName = `Module<@${module.#Referral.description}>`;
else if (typeof module.#Referral === 'string')
HostDefinedName = `"${module.#Referral}"`;
const state = {
Action: 'dynamic-import',
PromiseCapability: promiseCapability,
HostDefined: createTask(`import(${HostDefinedName})`),
};
Module.#ContinueDynamicImport(state, NormalCompletion(module));
const hostDefined = createTask(`import(<module block>)`);
Module.#ContinueDynamicImport(promiseCapability, NormalCompletion(module), hostDefined);
return promiseCapability.Promise;
};
setGlobalThis = (module, global) => (module.#GlobalThis = global);
setParentGlobalThis = (module, global) => (module.#GlobalThis = global);
setParentImportHook = (module, hook) => (module.#ParentImportHook = hook);
setParentImportMetaHook = (module, hook) => (module.#ParentImportMetaHook = hook);
}

@@ -981,15 +958,4 @@ }

getOwnPropertyDescriptor: () => undefined,
defineProperty() {
// TODO:
internalError();
},
deleteProperty() {
return false;
},
has() {
return false;
},
ownKeys() {
return [];
},
defineProperty: () => false,
deleteProperty: () => false,
isExtensible: () => false,

@@ -996,0 +962,0 @@ preventExtensions: () => true,

@@ -36,4 +36,4 @@ import type { Module } from './Module.js';

export interface VirtualModuleRecord {
bindings?: Array<Binding>;
execute?(environment: any, context?: VirtualModuleRecordExecuteContext): void | Promise<void>;
bindings?: Array<Binding> | undefined;
execute?(environment: any, context: VirtualModuleRecordExecuteContext): void | Promise<void>;
needsImportMeta?: boolean | undefined;

@@ -46,10 +46,11 @@ needsImport?: boolean | undefined;

importMeta?: object;
import?(spec: string, options?: ImportCallOptions): Promise<ModuleNamespace>;
import?<T extends ModuleNamespace = ModuleNamespace>(spec: string | Module<T>, options?: ImportCallOptions): Promise<T>;
globalThis: typeof globalThis;
}
export interface StaticModuleRecordInstance {
get bindings(): readonly Binding[];
export type ImportHook = (importSpecifier: string) => PromiseLike<Module | null> | Module | null;
export type ImportMetaHook = (importMeta: object) => void;
export interface ModuleHandler {
importHook?: ImportHook | undefined;
importMetaHook?: ImportMetaHook;
}
export type ImportHook = (importSpecifier: string, referrer: Referral) => PromiseLike<Module | null> | Module | null;
export type Referral = symbol | string | number | bigint;
//# sourceMappingURL=types.d.ts.map

@@ -9,10 +9,6 @@ function getOpaqueProxy() {

/** @internal */
export function internalError() {
throw new TypeError('Internal error.');
export function assertFailed(message) {
throw new TypeError('Assertion failed.' + (message ? ' ' : '') + message);
}
/** @internal */
export function assertFailed() {
throw new TypeError('Assertion failed.');
}
/** @internal */
export function unreachable(val) {

@@ -19,0 +15,0 @@ throw new TypeError('Unreachable');

{
"name": "@masknet/compartment",
"version": "0.3.13",
"version": "0.4.0",
"type": "module",

@@ -16,3 +16,3 @@ "main": "./dist/index.js",

"devDependencies": {
"@swc/core": "^1.3.9"
"@swc/core": "^1.3.10"
},

@@ -19,0 +19,0 @@ "files": [

# @masknet/compartment
An eval-free implementation of [Compartment](https://github.com/tc39/proposal-compartments/pull/46/files).
> WARNING: This package currently does not follow the [Semantic Versioning](https://semver.org/) because the original standard is still developing. The minor version might include breaking changes!
This package should be run in the environment described below:
This package implements a user-land [Virtual Module Source][layer-2] evaluator.
- Satisfy the [security assumption](../../README.md#security-assumptions).
- ES2021 syntax available.
This package currently implements the following specs/API explainers:
- [ECMA262 Normative PR: Layering: Add HostLoadImportedModule hook](https://github.com/tc39/ecma262/pull/2905/)
- [Module Block proposal](https://tc39.es/proposal-js-module-blocks/)
- [Compartment proposal: Layer 0: Module and ModuleSource constructor][layer-0]
- [Compartment proposal: Layer 1: ModuleSource reflection][layer-1]
- [Compartment proposal: Layer 2: Virtual Module Source][layer-2]
- [Compartment proposal: Layer 3: Evaluator][layer-3]
## Assumptions and runtime requirements
1. The environment is already `lockdown()` by [ses][ses].
2. Dynamic code execution (`eval` and `Function`) is not possible.
3. Code executed are either trusted or precompiled into a [Virtual Module Source][layer-2] by a compiler like [@masknet/static-module-record-swc](../static-module-record-swc/).
4. ECMAScript 2022 syntax is available.
## APIs
TODOs before first release:
### `ModuleSource` constructor
- Add some tests
- Document APIs and limitations
Implements `ModuleSource` from [layer 0][layer-0] and [layer 1][layer-1] of the compartment proposal.
This constructor always throws like it is in an environment that cannot use eval.
```ts
new ModuleSource()
// EvalError: Refused to evaluate a string as JavaScript.
```
### `Module` constructor
Implements `Module` from [layer 0][layer-0] and [layer-2][layer-2] of the compartment proposal.
```ts
import { Module, imports, type VirtualModuleRecord } from '@masknet/compartment'
const virtualModule: VirtualModuleRecord = {
execute(environment, context) {
console.log('module constructed!')
},
}
const module = new Module(virtualModule, import.meta.url, () => null)
// ^referral ^importHook
const moduleNamespace = await imports(module)
```
### `imports` function
This function is a user-land dynamic import that accepts `Module` instances.
This function does not accept strings as dynamic import does.
### `Evaluators` constructor
This constructor implements `Evaluators` from [layer 3][layer-3] of the compartment proposal.
```ts
import { Evaluators, Module, imports, type VirtualModuleRecord } from '@masknet/compartment'
const globalThis = { answer: 42 }
const evaluators = new Evaluators({ globalThis })
const virtualModule: VirtualModuleRecord = {
bindings: [{ export: 'x' }],
execute(environment, { globalThis }) {
environment.x = globalThis.answer // 42
},
}
const module = new Evaluators.Module(virtualModule, import.meta.url, () => null)
const moduleNamespace = await imports(module)
moduleNamespace.x // 42
```
### `makeGlobalThis` function
This function is a utility function that creates a new object that contains only items from the ECMAScript specification.
Those items are from the **current realm**, therefore sharing them with the Evaluators without [lockdown()](ses) might bring serious problems.
```ts
import { makeGlobalThis } from '@masknet/compartment'
const globalThis = makeGlobalThis()
globalThis.Array // [Function: Array]
```
[ses]: https://github.com/endojs/endo/tree/master/packages/ses
[layer-0]: https://tc39.es/proposal-compartments/0-module-and-module-source.html
[layer-1]: https://github.com/tc39/proposal-compartments/blob/master/1-static-analysis.md
[layer-2]: https://github.com/tc39/proposal-compartments/blob/master/2-virtual-module-source.md
[layer-3]: https://github.com/tc39/proposal-compartments/blob/master/3-evaluator.md

@@ -1,43 +0,58 @@

import { Module, Module as TopModule, setGlobalThis } from './Module.js'
import {
Module,
Module as TopModule,
setParentGlobalThis,
setParentImportHook,
setParentImportMetaHook,
} from './Module.js'
import type { ModuleSource } from './ModuleSource.js'
import type { ImportHook, Referral, VirtualModuleRecord } from './types.js'
import type { ImportHook, ModuleHandler, VirtualModuleRecord } from './types.js'
export interface EvaluatorsOptions {
globalThis?: object
importHook?: ImportHook
importMeta?: object | null
globalThis?: object | undefined
importHook?: ImportHook | undefined
importMeta?: object | null | undefined
}
export class Evaluators {
constructor(options: EvaluatorsOptions) {
const { globalThis = realGlobalThis, importHook = defaultImportHook, importMeta = null } = options
Module: typeof Module
Evaluators: typeof Evaluators
get globalThis() {
return this.#AssignGlobalThis
}
// We do not support `eval` and `Function`.
eval = eval
Function = Function
if (typeof globalThis !== 'object') throw new TypeError('globalThis must be an object')
if (typeof importHook !== 'function') throw new TypeError('importHook must be a function')
if (typeof importMeta !== 'object') throw new TypeError('importMeta must be an object')
// implementation
constructor(handler: EvaluatorsOptions) {
const { globalThis, importHook, importMeta } = handler
this.#Handler = handler
if (typeof globalThis !== 'object' && globalThis !== undefined)
throw new TypeError('globalThis must be an object')
if (typeof importHook !== 'function' && importHook !== undefined)
throw new TypeError('importHook must be a function')
if (typeof importMeta !== 'object' && importMeta !== undefined && importMeta !== null)
throw new TypeError('importMeta must be an object')
const parent = this
class Evaluators extends TopEvaluators {
constructor(options: EvaluatorsOptions) {
const {
globalThis = parent.#globalThis,
importHook = parent.#importHook,
importMeta = parent.#importMeta ?? null,
} = options
super({ globalThis, importHook, importMeta })
super(options)
this.#ParentEvaluator = parent
}
}
class Module extends TopModule {
constructor(
moduleSource: ModuleSource | VirtualModuleRecord,
referral: Referral,
importHook?: ImportHook,
importMeta?: object,
) {
super(moduleSource, referral, importHook ?? parent.#importHook, importMeta ?? parent.#importMeta)
setGlobalThis(this, parent.#globalThis)
constructor(moduleSource: ModuleSource | VirtualModuleRecord, handler: ModuleHandler) {
super(moduleSource, handler)
setParentGlobalThis(this, (parent.#CalculatedGlobalThis ??= parent.#GetGlobalThis()))
setParentImportHook(this, (parent.#CalculatedImportHook ??= parent.#GetImportHook()))
setParentImportMetaHook(this, (meta) =>
Object.assign(meta, (parent.#CalculatedImportMeta ??= parent.#GetImportMeta())),
)
}
}
this.#importHook = importHook
this.#importMeta = importMeta ?? undefined
this.#globalThis = globalThis
this.#AssignedImportHook = importHook
this.#AssignedImportMeta = importMeta
this.#AssignGlobalThis = globalThis

@@ -47,13 +62,26 @@ this.Module = Module

}
Module: typeof Module
Evaluators: typeof Evaluators
get globalThis() {
return this.#globalThis
#ParentEvaluator: Evaluators | undefined
#AssignGlobalThis: object | undefined
#AssignedImportHook: ImportHook | undefined
#AssignedImportMeta: object | undefined | null
#CalculatedGlobalThis: object | undefined
#CalculatedImportHook: ImportHook | undefined
#CalculatedImportMeta: object | undefined | null
#Handler: EvaluatorsOptions
#GetGlobalThis(): object {
if (this.#AssignGlobalThis) return this.#AssignGlobalThis
if (this.#ParentEvaluator) return this.#ParentEvaluator.#GetGlobalThis()
return realGlobalThis
}
// We do not support `eval` and `Function`.
eval = eval
Function = Function
#globalThis: object
#importHook: ImportHook
#importMeta: object | undefined
#GetImportHook(): ImportHook {
if (this.#AssignedImportHook) return this.#AssignedImportHook.bind(this.#Handler)
if (this.#ParentEvaluator) return this.#ParentEvaluator.#GetImportHook()
return defaultImportHook
}
#GetImportMeta(): ImportMeta | null {
if (this.#AssignedImportMeta) return this.#AssignedImportMeta
if (this.#ParentEvaluator) return this.#ParentEvaluator.#GetImportMeta()
return null
}
}

@@ -65,3 +93,3 @@ const TopEvaluators = Evaluators

export function defaultImportHook(): never {
throw new TypeError(`This evaluator does not have any import resolution.`)
throw new TypeError(`This evaluator does not have any import resolution strategy.`)
}

@@ -11,4 +11,4 @@ export type {

ImportHook,
Referral,
StaticModuleRecordInstance,
ImportMetaHook,
ModuleHandler,
} from './types.js'

@@ -15,0 +15,0 @@ export { ModuleSource } from './ModuleSource.js'

import { ModuleSource } from './ModuleSource.js'
import type {
ImportHook,
ImportMetaHook,
ModuleHandler,
ModuleNamespace,
Referral,
VirtualModuleRecord,

@@ -22,35 +23,36 @@ VirtualModuleRecordExecuteContext,

import { normalizeBindingsToSpecRecord, normalizeVirtualModuleRecord } from './utils/normalize.js'
import { assertFailed, internalError, opaqueProxy } from './utils/assert.js'
import { assertFailed, opaqueProxy } from './utils/assert.js'
import { defaultImportHook } from './Evaluators.js'
import { createTask, type Task } from './utils/async-task.js'
export let imports: <T extends object = any>(specifier: Module<T>, options?: ImportCallOptions) => Promise<T>
export let imports: <T extends ModuleNamespace = any>(specifier: Module<T>, options?: ImportCallOptions) => Promise<T>
/** @internal */
export let setGlobalThis: (module: Module, global: object) => void
export let setParentGlobalThis: (module: Module, global: object) => void
/** @internal */
export let setParentImportHook: (module: Module, handler: ImportHook) => void
/** @internal */
export let setParentImportMetaHook: (module: Module, handler: ImportMetaHook) => void
export class Module<T extends object = any> {
export class Module<T extends ModuleNamespace = any> {
// The constructor is equivalent to ParseModule in SourceTextModuleRecord
// https://tc39.es/ecma262/#sec-parsemodule
constructor(
moduleSource: ModuleSource<T> | VirtualModuleRecord,
referral: Referral,
// it actually NOT an optional argument when it is the top-level Module.
importHook: ImportHook = defaultImportHook,
importMeta?: object,
) {
constructor(moduleSource: ModuleSource<T> | VirtualModuleRecord, handler: ModuleHandler) {
if (typeof moduleSource !== 'object') throw new TypeError('moduleSource must be an object')
if (typeof referral === 'object' && referral !== null) throw new TypeError('referral must be a primitive')
if (typeof importHook !== 'function') throw new TypeError('importHook must be a function')
let assignedImportMeta: null | object
if (importMeta === undefined) assignedImportMeta = null
else if (typeof importMeta !== 'object') throw new TypeError('importMeta must be an object')
else assignedImportMeta = importMeta
// impossible to create a ModuleSource instance
if (moduleSource instanceof ModuleSource) internalError()
if (moduleSource instanceof ModuleSource) assertFailed('ModuleSource instance cannot be created')
const module = normalizeVirtualModuleRecord(moduleSource)
this.#Source = moduleSource
this.#Referral = referral
if (handler === null) throw new TypeError('handler must not be null')
let importHook: ImportHook | undefined
let importMetaHook: ImportMetaHook | undefined
if (typeof handler === 'object') {
importHook = handler.importHook
if (typeof importHook !== 'function' && importHook !== undefined)
throw new TypeError('importHook must be a function')
importMetaHook = handler.importMetaHook
if (typeof importMetaHook !== 'function' && importMetaHook !== undefined)
throw new TypeError('importMetaHook must be a function')
}
this.#VirtualModuleSource = moduleSource
this.#Execute = module.execute

@@ -61,4 +63,5 @@ this.#NeedsImport = module.needsImport

this.#AssignedImportMeta = assignedImportMeta
this.#ImportHook = importHook
this.#ImportMetaHook = importMetaHook
this.#HandlerValue = handler

@@ -74,3 +77,3 @@ const { importEntries, indirectExportEntries, localExportEntries, requestedModules, starExportEntries } =

get source(): ModuleSource | VirtualModuleRecord | null {
return this.#Source
return this.#VirtualModuleSource
}

@@ -86,4 +89,3 @@ //#region ModuleRecord fields https://tc39.es/ecma262/#table-module-record-fields

// *this value* when calling #Execute.
#Referral: Referral
#Source: VirtualModuleRecord
#VirtualModuleSource: VirtualModuleRecord
#Execute: VirtualModuleRecord['execute']

@@ -93,7 +95,9 @@ #NeedsImportMeta: boolean | undefined

#ContextObject: VirtualModuleRecordExecuteContext | undefined
#ImportHook: ImportHook
#ImportHookCache = new Map<string, PromiseCapability<Module>>()
#AssignedImportMeta: object | null
#ImportHook: ImportHook | undefined
#ImportMetaHook: ImportMetaHook | undefined
#HandlerValue: ModuleHandler
/** the global environment this module binds to */
#GlobalThis: object = globalThis
#ParentImportHook: ImportHook = defaultImportHook
#ParentImportMetaHook: ImportMetaHook | undefined
/** imported module cache */

@@ -121,2 +125,3 @@ #ImportEntries: ModuleImportEntry[]

const module = this
if (!(module.#Status !== ModuleStatus.new)) assertFailed()
if (exportStarSet.includes(module)) return []

@@ -136,4 +141,2 @@ exportStarSet.push(module)

const requestedModule = Module.#GetImportedModule(module, e.ModuleRequest)
// TODO: https://github.com/tc39/ecma262/pull/2905/files#r973044508
if (!requestedModule) assertFailed()
const starNames = requestedModule.#GetExportedNames(exportStarSet)

@@ -154,2 +157,3 @@ for (const n of starNames) {

const module = this
if (!(module.#Status !== ModuleStatus.new)) assertFailed()
for (const r of resolveSet) {

@@ -173,4 +177,2 @@ if (module === r.module && exportName === r.exportName) {

const importedModule = Module.#GetImportedModule(module, e.ModuleRequest)
// TODO: https://github.com/tc39/ecma262/pull/2905/files#r973044508
if (!importedModule) assertFailed()
if (e.ImportName === all) {

@@ -194,4 +196,2 @@ // Assert: module does not provide the direct binding for this export.

const importedModule = Module.#GetImportedModule(module, e.ModuleRequest)
// TODO: https://github.com/tc39/ecma262/pull/2905/files#r973044508
if (!importedModule) assertFailed()
let resolution = importedModule.#ResolveExport(exportName, resolveSet)

@@ -224,6 +224,5 @@ if (resolution === ambiguous) return ambiguous

const pc = PromiseCapability<void>()
const state: ModuleLoadState_GraphLoading = {
Action: 'graph-loading',
const state: GraphLoadingState = {
IsLoading: true,
PendingModules: 1,
PendingModulesCount: 1,
Visited: [],

@@ -236,3 +235,3 @@ PromiseCapability: pc,

}
static #InnerModuleLoading(state: ModuleLoadState_GraphLoading, module: Module) {
static #InnerModuleLoading(state: GraphLoadingState, module: Module) {
if (!state.IsLoading) assertFailed()

@@ -242,18 +241,16 @@ if (module.#Status === ModuleStatus.new && !state.Visited.includes(module)) {

const requestedModulesCount = module.#RequestedModules.length
state.PendingModules = state.PendingModules + requestedModulesCount
state.PendingModulesCount = state.PendingModulesCount + requestedModulesCount
for (const required of module.#RequestedModules) {
if (state.IsLoading) {
const record = module.#LoadedModules.get(required)
if (record) {
Module.#InnerModuleLoading(state, record)
} else {
Module.#HostLoadImportedModule(module, required, state.HostDefined, state)
}
const record = module.#LoadedModules.get(required)
if (record) {
Module.#InnerModuleLoading(state, record)
} else {
Module.#LoadImportedModule(module, required, state.HostDefined, state)
}
if (!state.IsLoading) return
}
}
if (!state.IsLoading) return
if (!(state.PendingModules >= 1)) assertFailed()
state.PendingModules = state.PendingModules - 1
if (state.PendingModules === 0) {
if (!(state.PendingModulesCount >= 1)) assertFailed()
state.PendingModulesCount = state.PendingModulesCount - 1
if (state.PendingModulesCount === 0) {
state.IsLoading = false

@@ -266,3 +263,3 @@ for (const loaded of state.Visited) {

}
static #ContinueModuleLoading(state: ModuleLoadState_GraphLoading, moduleCompletion: Completion<Module>) {
static #ContinueModuleLoading(state: GraphLoadingState, moduleCompletion: Completion<Module>) {
if (!state.IsLoading) return

@@ -316,3 +313,2 @@ if (moduleCompletion.Type === 'normal') Module.#InnerModuleLoading(state, moduleCompletion.Value)

const importedModule = Module.#GetImportedModule(module, i.ModuleRequest)
if (!importedModule) assertFailed()
// import * as ns from '..'

@@ -370,3 +366,3 @@ if (i.ImportName === namespace) {

// Note: export property should not be enumerable?
// but it will crash Chrome devtools.See: https://bugs.chromium.org/p/chromium/issues/detail?id=1358114
// but it will crash Chrome devtools. See: https://bugs.chromium.org/p/chromium/issues/detail?id=1358114
enumerable: true,

@@ -390,17 +386,45 @@ }

#ExecuteModule(promise?: PromiseCapability<void>) {
const execute = this.#Execute
if (!execute) return
this.#Execute = undefined
// prepare context
this.#ContextObject!.globalThis = this.#GlobalThis as any
if (this.#NeedsImportMeta) {
this.#ContextObject!.importMeta = Object.assign({}, this.#AssignedImportMeta)
const importMeta = { __proto__: null }
if (this.#ImportMetaHook) Reflect.apply(this.#ImportMetaHook, this.#HandlerValue, [importMeta])
else if (this.#ParentImportMetaHook) Reflect.apply(this.#ParentImportMetaHook, undefined, [importMeta])
this.#ContextObject!.importMeta = importMeta
}
if (this.#NeedsImport) {
this.#ContextObject!.import = async (specifier: string, options?: ImportCallOptions) => {
specifier = String(specifier)
const status: ModuleLoadState_DynamicImport = {
Action: 'dynamic-import',
PromiseCapability: PromiseCapability(),
HostDefined: createTask(`import("${specifier}")`),
this.#ContextObject!.import = async (
specifier: string | Module<ModuleNamespace>,
options?: ImportCallOptions,
) => {
const referrer = this
const promiseCapability = PromiseCapability<ModuleNamespace>()
let hasModuleInternalSlot = false
try {
;(specifier as Module).#HandlerValue
hasModuleInternalSlot = true
} catch {}
if (hasModuleInternalSlot) {
const hostDefined = createTask(`import(<module block>)`)
Module.#ContinueDynamicImport(promiseCapability, NormalCompletion(specifier as Module), hostDefined)
} else {
specifier = String(specifier)
const hostDefined = createTask(`import("${specifier}")`)
if (referrer.#LoadedModules.has(specifier)) {
Module.#ContinueDynamicImport(
promiseCapability,
NormalCompletion(referrer.#LoadedModules.get(specifier)!),
hostDefined,
)
} else {
Module.#LoadImportedModule(referrer, specifier, hostDefined, promiseCapability)
}
}
Module.#HostLoadImportedModule(this, specifier, status.HostDefined, status)
return status.PromiseCapability.Promise as any
return promiseCapability.Promise as any
}

@@ -413,16 +437,15 @@ }

if (!this.#HasTLA) {
if (!!promise) assertFailed()
if (this.#Execute) {
Reflect.apply(this.#Execute, this.#Source, [env, this.#ContextObject])
}
if (promise) assertFailed()
const result = Reflect.apply(execute, this.#VirtualModuleSource, [env, this.#ContextObject])
if (result)
throw new TypeError(
'Due to specification limitations, in order to support Async Modules (modules that use Top Level Await or a Virtual Module that has an execute() function that returns a Promise), the Virtual Module record must be marked with `isAsync: true`. The `isAsync` property is non-standard, and it is being tracked in https://github.com/tc39/proposal-compartments/issues/84.',
)
} else {
if (!promise) assertFailed()
if (this.#Execute) {
Promise.resolve(Reflect.apply(this.#Execute, this.#Source, [env, this.#ContextObject])).then(
promise.Resolve,
promise.Reject,
)
}
Promise.resolve(Reflect.apply(execute, this.#VirtualModuleSource, [env, this.#ContextObject])).then(
promise.Resolve,
promise.Reject,
)
}
this.#Execute = undefined!
}

@@ -511,3 +534,2 @@ // https://tc39.es/ecma262/#sec-moduledeclarationlinking

const requiredModule = this.#GetImportedModule(module, required)
if (!requiredModule) assertFailed()
index = this.#InnerModuleLinking(requiredModule, stack, index)

@@ -565,3 +587,2 @@ if (

let requiredModule = this.#GetImportedModule(module, required)
if (!requiredModule) assertFailed()
index = this.#InnerModuleEvaluation(requiredModule, stack, index, HostDefined)

@@ -725,3 +746,3 @@ if (

if (module.#Namespace) return module.#Namespace
if (!(module.#Status !== ModuleStatus.unlinked)) assertFailed()
if (!(module.#Status !== ModuleStatus.new && module.#Status !== ModuleStatus.unlinked)) assertFailed()
const exportedNames = module.#GetExportedNames()

@@ -780,49 +801,33 @@

static #GetImportedModule(module: Module, spec: string) {
return module.#LoadedModules.get(spec)
const record = module.#LoadedModules.get(spec)
if (!record) assertFailed()
return record
}
static #HostLoadImportedModule(referrer: Module, specifier: string, hostDefined: Task, payload: ModuleLoadState) {
let promiseCapability = referrer.#ImportHookCache.get(specifier)
function onFulfilled(module: Module) {
promiseCapability?.Resolve(module)
Module.#FinishLoadingImportedModule(referrer, specifier, payload, NormalCompletion(module))
}
function onRejected(reason: unknown) {
promiseCapability?.Reject(reason)
Module.#FinishLoadingImportedModule(referrer, specifier, payload, ThrowCompletion(reason))
}
if (promiseCapability) {
if (promiseCapability.Status.Type === 'Fulfilled') {
onFulfilled(promiseCapability.Status.Value)
return
} else if (promiseCapability.Status.Type === 'Pending') {
promiseCapability.Promise.then(onFulfilled, onRejected)
return
}
// if error, fallthorugh
}
promiseCapability = PromiseCapability()
referrer.#ImportHookCache.set(specifier, promiseCapability)
static #LoadImportedModule(
referrer: Module,
specifier: string,
hostDefined: Task,
payload: GraphLoadingState | PromiseCapability<ModuleNamespace>,
) {
try {
const result = referrer.#ImportHook(specifier, referrer.#Referral)
if (result === null) throw new SyntaxError(`Failed to load module ${specifier}.`)
try {
const module = result as Module
module.#Referral
onFulfilled(module)
return
} catch {}
// treat it as a Promise
Promise.resolve(result).then((result) => {
if (result === null) onRejected(new SyntaxError(`Failed to load module ${specifier}.`))
const importHookResult = referrer.#ImportHook
? Reflect.apply(referrer.#ImportHook, referrer.#HandlerValue, [specifier])
: Reflect.apply(referrer.#ParentImportHook, undefined, [specifier])
const importHookPromise = Promise.resolve(importHookResult)
const onFulfilled = (result: any) => {
let completion: Completion<Module>
try {
const module = result as Module
module.#Referral
onFulfilled(module)
;(result as Module).#HandlerValue
completion = NormalCompletion(result)
} catch (error) {
onRejected(new TypeError('importHook must return an instance of Module'))
completion = ThrowCompletion(new TypeError('importHook must return a Module instance'))
}
})
this.#FinishLoadingImportedModule(referrer, specifier, payload, completion, hostDefined)
}
const onRejected = (error: any) => {
this.#FinishLoadingImportedModule(referrer, specifier, payload, ThrowCompletion(error), hostDefined)
}
importHookPromise.then(onFulfilled, onRejected)
} catch (error) {
onRejected(error)
this.#FinishLoadingImportedModule(referrer, specifier, payload, ThrowCompletion(error), hostDefined)
}

@@ -834,4 +839,5 @@ }

specifier: string,
state: ModuleLoadState,
payload: GraphLoadingState | PromiseCapability<ModuleNamespace>,
result: Completion<Module>,
hostDefined: Task,
) {

@@ -846,11 +852,14 @@ if (result.Type === 'normal') {

}
if (state.Action === 'graph-loading') {
Module.#ContinueModuleLoading(state, result)
if ('Visited' in payload) {
Module.#ContinueModuleLoading(payload, result)
} else {
Module.#ContinueDynamicImport(state, result)
Module.#ContinueDynamicImport(payload, result, hostDefined)
}
}
static #ContinueDynamicImport(state: ModuleLoadState_DynamicImport, moduleCompletion: Completion<Module>) {
const promiseCapability = state.PromiseCapability
static #ContinueDynamicImport(
promiseCapability: PromiseCapability<ModuleNamespace>,
moduleCompletion: Completion<Module>,
hostDefined: Task,
) {
if (moduleCompletion.Type === 'throw') {

@@ -861,3 +870,3 @@ promiseCapability.Reject(moduleCompletion.Value)

const module = moduleCompletion.Value
const loadPromise = module.#LoadRequestedModules(state.HostDefined)
const loadPromise = module.#LoadRequestedModules(hostDefined)
function onRejected(reason: unknown) {

@@ -869,10 +878,6 @@ promiseCapability.Reject(reason)

module.#Link()
const evaluatePromise = module.#Evaluate(state.HostDefined)
const evaluatePromise = module.#Evaluate(hostDefined)
function onFulfilled() {
try {
const namespace = Module.#GetModuleNamespace(module)
promiseCapability.Resolve(namespace)
} catch (error) {
promiseCapability.Reject(error)
}
const namespace = Module.#GetModuleNamespace(module)
promiseCapability.Resolve(namespace)
}

@@ -892,15 +897,9 @@ evaluatePromise.then(onFulfilled, onRejected)

let HostDefinedName = 'Module<...>'
if (typeof module.#Referral === 'symbol') HostDefinedName = `Module<@${module.#Referral.description}>`
else if (typeof module.#Referral === 'string') HostDefinedName = `"${module.#Referral}"`
const state: ModuleLoadState_DynamicImport = {
Action: 'dynamic-import',
PromiseCapability: promiseCapability,
HostDefined: createTask(`import(${HostDefinedName})`),
}
Module.#ContinueDynamicImport(state, NormalCompletion(module))
const hostDefined = createTask(`import(<module block>)`)
Module.#ContinueDynamicImport(promiseCapability, NormalCompletion(module), hostDefined)
return promiseCapability.Promise as any
}
setGlobalThis = (module, global) => (module.#GlobalThis = global)
setParentGlobalThis = (module, global) => (module.#GlobalThis = global)
setParentImportHook = (module, hook) => (module.#ParentImportHook = hook)
setParentImportMetaHook = (module, hook) => (module.#ParentImportMetaHook = hook)
}

@@ -913,16 +912,9 @@ }

interface ModuleLoadState_GraphLoading {
Action: 'graph-loading'
interface GraphLoadingState {
PromiseCapability: PromiseCapability<void>
IsLoading: boolean
PendingModules: number
PendingModulesCount: number
Visited: Module[]
HostDefined: Task
}
interface ModuleLoadState_DynamicImport {
Action: 'dynamic-import'
PromiseCapability: PromiseCapability<ModuleNamespace>
HostDefined: Task
}
type ModuleLoadState = ModuleLoadState_DynamicImport | ModuleLoadState_GraphLoading

@@ -978,15 +970,4 @@ const enum ModuleStatus {

getOwnPropertyDescriptor: () => undefined,
defineProperty() {
// TODO:
internalError()
},
deleteProperty() {
return false
},
has() {
return false
},
ownKeys() {
return []
},
defineProperty: () => false,
deleteProperty: () => false,
isExtensible: () => false,

@@ -993,0 +974,0 @@ preventExtensions: () => true,

@@ -39,4 +39,4 @@ // https://github.com/tc39/proposal-compartments/blob/775024d93830ee6464363b4b373d9353425a0776/README.md

export interface VirtualModuleRecord {
bindings?: Array<Binding>
execute?(environment: any, context?: VirtualModuleRecordExecuteContext): void | Promise<void>
bindings?: Array<Binding> | undefined
execute?(environment: any, context: VirtualModuleRecordExecuteContext): void | Promise<void>
needsImportMeta?: boolean | undefined

@@ -50,10 +50,14 @@ needsImport?: boolean | undefined

importMeta?: object
import?(spec: string, options?: ImportCallOptions): Promise<ModuleNamespace>
import?<T extends ModuleNamespace = ModuleNamespace>(
spec: string | Module<T>,
options?: ImportCallOptions,
): Promise<T>
globalThis: typeof globalThis
}
export interface StaticModuleRecordInstance {
get bindings(): readonly Binding[]
export type ImportHook = (importSpecifier: string) => PromiseLike<Module | null> | Module | null
export type ImportMetaHook = (importMeta: object) => void
export interface ModuleHandler {
importHook?: ImportHook | undefined
importMetaHook?: ImportMetaHook
}
export type ImportHook = (importSpecifier: string, referrer: Referral) => PromiseLike<Module | null> | Module | null
export type Referral = symbol | string | number | bigint

@@ -10,12 +10,8 @@ function getOpaqueProxy() {

/** @internal */
export function internalError(): never {
throw new TypeError('Internal error.')
export function assertFailed(message?: string): never {
throw new TypeError('Assertion failed.' + (message ? ' ' : '') + message)
}
/** @internal */
export function assertFailed(): never {
throw new TypeError('Assertion failed.')
}
/** @internal */
export function unreachable(val: never): never {
throw new TypeError('Unreachable')
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet