@masknet/compartment
Advanced tools
Comparing version 0.2.0 to 0.2.1
import type { CompartmentInstance, CompartmentOptions } from './types.js'; | ||
export declare let internalSlot_Compartment_globalThis_get: (compartment: Compartment) => Compartment['globalThis']; | ||
/** @deprecated Need a rewrite based on Module & ExecutionContext. */ | ||
/** @deprecated Need a rewrite based on Module & Evaluators. */ | ||
export declare class Compartment implements CompartmentInstance { | ||
@@ -5,0 +5,0 @@ #private; |
@@ -1,6 +0,5 @@ | ||
import { ExecutionContext } from './ExecutionContext.js'; | ||
import { makeBorrowedGlobalThis, makeGlobalThis } from './utils/makeGlobalThis.js'; | ||
import { StaticModuleRecord } from './StaticModuleRecord.js'; | ||
import { normalizeModuleDescriptor } from './utils/normalize.js'; | ||
import { internalError } from './utils/opaqueProxy.js'; | ||
import { internalError, unreachable } from './utils/assert.js'; | ||
import { hasFromField, isExportAllBinding, isExportBinding, isImportAllBinding, isImportBinding, isModuleDescriptor_FullSpecReference, isModuleDescriptor_ModuleInstance, isModuleDescriptor_Source, isModuleDescriptor_StaticModuleRecord, isReExportBinding, } from './utils/shapeCheck.js'; | ||
@@ -13,3 +12,3 @@ import { SystemJS } from './utils/system.js'; | ||
export let internalSlot_Compartment_globalThis_get; | ||
/** @deprecated Need a rewrite based on Module & ExecutionContext. */ | ||
/** @deprecated Need a rewrite based on Module & Evaluators. */ | ||
export class Compartment { | ||
@@ -74,6 +73,9 @@ get globalThis() { | ||
: makeGlobalThis(Object.prototype, { | ||
Compartment: Subcompartment, | ||
ExecutionContext: ExecutionContext, | ||
createModule: createModuleSubclass, | ||
}, normalizedOptions.globals); | ||
Object.defineProperty(this.#globalThis, 'Compartment', { | ||
configurable: true, | ||
writable: true, | ||
value: Subcompartment, | ||
}); | ||
} | ||
@@ -150,6 +152,4 @@ this.#opts = normalizedOptions; | ||
} | ||
else { | ||
const _ = desc; | ||
internalError(); | ||
} | ||
else | ||
unreachable(desc); | ||
} | ||
@@ -184,3 +184,3 @@ async #instantiate(url, parentUrl) { | ||
return { | ||
execute: () => initialize(moduleEnvironmentProxy, _context), | ||
execute: () => initialize?.(moduleEnvironmentProxy, _context), | ||
setters, | ||
@@ -191,6 +191,4 @@ }; | ||
} | ||
else { | ||
let _ = module; | ||
internalError(); | ||
} | ||
else | ||
unreachable(module); | ||
} | ||
@@ -249,6 +247,4 @@ } | ||
} | ||
else { | ||
let _ = binding; | ||
internalError(); | ||
} | ||
else | ||
unreachable(binding); | ||
}) | ||
@@ -255,0 +251,0 @@ .filter(Boolean))); |
@@ -5,3 +5,3 @@ export type { Binding, ImportBinding, ExportBinding, CompartmentOptions, ModuleDescriptor, ModuleDescriptor_Source, ModuleDescriptor_ModuleInstance, ModuleDescriptor_FullSpecReference, ModuleDescriptor_StaticModuleRecord, ModuleNamespace, SyntheticModuleRecord, SyntheticModuleRecordInitializeContext, } from './types.js'; | ||
export { ModuleSource } from './ModuleSource.js'; | ||
export { ExecutionContext, type ExecutionContextConstructor } from './ExecutionContext.js'; | ||
export { Evaluators } from './Evaluators.js'; | ||
export { Module, type ImportHook, imports } from './Module.js'; | ||
@@ -11,2 +11,3 @@ export { createModuleCache } from './utils/createModuleCache.js'; | ||
export { URLResolveHook } from './utils/resolver.js'; | ||
export { makeGlobalThisPublic as makeGlobalThis } from './utils/makeGlobalThis.js'; | ||
//# sourceMappingURL=index.d.ts.map |
export { Compartment } from './compartment.js'; | ||
export { StaticModuleRecord } from './StaticModuleRecord.js'; | ||
export { ModuleSource } from './ModuleSource.js'; | ||
export { ExecutionContext } from './ExecutionContext.js'; | ||
export { Evaluators } from './Evaluators.js'; | ||
export { Module, imports } from './Module.js'; | ||
@@ -9,2 +9,3 @@ export { createModuleCache } from './utils/createModuleCache.js'; | ||
export { URLResolveHook } from './utils/resolver.js'; | ||
export { makeGlobalThisPublic as makeGlobalThis } from './utils/makeGlobalThis.js'; | ||
//# sourceMappingURL=index.js.map |
@@ -1,5 +0,4 @@ | ||
import { all, allButDefault, ambiguous, empty, namespace, PromiseCapability } from './utils/spec.js'; | ||
import { normalizeSyntheticModuleRecord } from './utils/normalize.js'; | ||
import { assert, internalError, opaqueProxy } from './utils/opaqueProxy.js'; | ||
import { isImportBinding, isImportAllBinding, isExportAllBinding, isExportBinding, hasFromField, } from './utils/shapeCheck.js'; | ||
import { all, ambiguous, empty, namespace, PromiseCapability, } from './utils/spec.js'; | ||
import { normalizeBindingsToSpecRecord, normalizeSyntheticModuleRecord } from './utils/normalize.js'; | ||
import { assert, internalError, opaqueProxy } from './utils/assert.js'; | ||
export let imports; | ||
@@ -19,2 +18,3 @@ /** @internal */ | ||
const module = normalizeSyntheticModuleRecord(source); | ||
this.#InitializeThisValue = source; | ||
this.#Initialize = module.initialize; | ||
@@ -26,86 +26,8 @@ this.#NeedsImport = module.needsImport; | ||
this.#ImportHook = importHook; | ||
const requestedModules = []; | ||
const importsEntries = (this.#ImportEntries = []); | ||
for (const binding of module.bindings || []) { | ||
if (isImportBinding(binding)) { | ||
requestedModules.push(binding.from); | ||
importsEntries.push({ | ||
ImportName: binding.import, | ||
LocalName: binding.as ?? binding.import, | ||
ModuleRequest: binding.from, | ||
}); | ||
} | ||
else if (isImportAllBinding(binding)) { | ||
requestedModules.push(binding.importAllFrom); | ||
importsEntries.push({ | ||
ImportName: namespace, | ||
LocalName: binding.as, | ||
ModuleRequest: binding.importAllFrom, | ||
}); | ||
} | ||
} | ||
const importedBoundNames = importsEntries.map((x) => x.LocalName); | ||
const indirectExportEntries = (this.#IndirectExportEntries = []); | ||
const localExportEntries = (this.#LocalExportEntries = []); | ||
const starExportEntries = (this.#StarExportEntries = []); | ||
for (const binding of module.bindings || []) { | ||
if (isExportBinding(binding)) { | ||
if (hasFromField(binding)) { | ||
requestedModules.push(binding.from); | ||
indirectExportEntries.push({ | ||
ExportName: binding.as ?? binding.export, | ||
ImportName: binding.export, | ||
// LocalName: null, | ||
ModuleRequest: binding.from, | ||
}); | ||
} | ||
else { | ||
const ee = { | ||
ExportName: binding.as ?? binding.export, | ||
// LocalName: binding.export, | ||
ImportName: null, | ||
ModuleRequest: null, | ||
}; | ||
if (!importedBoundNames.includes(binding.export)) { | ||
localExportEntries.push(ee); | ||
} | ||
else { | ||
const ie = importsEntries.find((x) => x.LocalName === binding.export); | ||
if (ie.ImportName === namespace) { | ||
localExportEntries.push(ee); | ||
} | ||
else { | ||
indirectExportEntries.push({ | ||
ModuleRequest: ie.ModuleRequest, | ||
ImportName: ie.ImportName, | ||
ExportName: ee.ExportName, | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
else if (isExportAllBinding(binding)) { | ||
requestedModules.push(binding.exportAllFrom); | ||
if (typeof binding.as === 'string') { | ||
// export * as name from 'mod' | ||
starExportEntries.push({ | ||
// LocalName: binding.as, | ||
ExportName: binding.as, | ||
ImportName: all, | ||
ModuleRequest: binding.exportAllFrom, | ||
}); | ||
} | ||
else { | ||
// export * from 'mod' | ||
starExportEntries.push({ | ||
// LocalName: null, | ||
ExportName: null, | ||
ImportName: allButDefault, | ||
ModuleRequest: binding.exportAllFrom, | ||
}); | ||
} | ||
} | ||
} | ||
// Set is ordered. | ||
this.#RequestedModules = [...new Set(requestedModules)]; | ||
const { importEntries, indirectExportEntries, localExportEntries, requestedModules, starExportEntries } = normalizeBindingsToSpecRecord(module.bindings); | ||
this.#ImportEntries = importEntries; | ||
this.#IndirectExportEntries = indirectExportEntries; | ||
this.#LocalExportEntries = localExportEntries; | ||
this.#RequestedModules = requestedModules; | ||
this.#StarExportEntries = starExportEntries; | ||
} | ||
@@ -121,2 +43,4 @@ //#region ModuleRecord fields https://tc39.es/ecma262/#table-module-record-fields | ||
// #region SyntheticModuleRecord fields | ||
// *this value* when calling #Initialize. | ||
#InitializeThisValue; | ||
#Initialize; | ||
@@ -341,3 +265,2 @@ #NeedsImportMeta; | ||
} | ||
const init = this.#Initialize; | ||
assert(this.#Environment); | ||
@@ -347,9 +270,14 @@ const env = new Proxy(this.#Environment, moduleEnvExoticMethods); | ||
assert(!promise); | ||
init(env, this.#ContextObjectProxy); | ||
if (this.#Initialize) { | ||
Reflect.apply(this.#Initialize, this.#InitializeThisValue, [env, this.#ContextObjectProxy]); | ||
} | ||
} | ||
else { | ||
assert(promise); | ||
Promise.resolve(init(env, this.#ContextObjectProxy)).then(promise.Resolve, promise.Reject); | ||
if (this.#Initialize) { | ||
Promise.resolve(Reflect.apply(this.#Initialize, this.#InitializeThisValue, [env, this.#ContextObjectProxy])).then(promise.Resolve, promise.Reject); | ||
} | ||
} | ||
this.#Initialize = undefined; | ||
this.#InitializeThisValue = undefined; | ||
} | ||
@@ -718,7 +646,7 @@ // https://tc39.es/ecma262/#sec-moduledeclarationlinking | ||
}; | ||
createModuleSubclass = (globalThis) => { | ||
createModuleSubclass = (globalThis, upper_importHook, upper_importMeta) => { | ||
const Parent = Module; | ||
const SubModule = class Module extends Parent { | ||
constructor(source, importHook, importMeta) { | ||
super(source, importHook, importMeta); | ||
super(source, importHook ?? upper_importHook, importMeta ?? upper_importMeta); | ||
this.#GlobalThis = globalThis; | ||
@@ -725,0 +653,0 @@ } |
@@ -1,2 +0,2 @@ | ||
import { internalError } from './utils/opaqueProxy.js'; | ||
import { internalError } from './utils/assert.js'; | ||
export class StaticModuleRecord { | ||
@@ -3,0 +3,0 @@ #bindings; |
@@ -38,3 +38,3 @@ import type { Compartment } from './compartment.js'; | ||
bindings?: Array<Binding>; | ||
initialize(environment: object, context?: SyntheticModuleRecordInitializeContext): void | Promise<void>; | ||
initialize?(environment: object, context?: SyntheticModuleRecordInitializeContext): void | Promise<void>; | ||
needsImportMeta?: boolean | undefined; | ||
@@ -41,0 +41,0 @@ needsImport?: boolean | undefined; |
@@ -1,2 +0,2 @@ | ||
export {}; | ||
export declare function makeGlobalThisPublic(): typeof globalThis; | ||
//# sourceMappingURL=makeGlobalThis.d.ts.map |
@@ -0,1 +1,3 @@ | ||
import { Evaluators } from '../Evaluators.js'; | ||
import { createModuleSubclass } from '../Module.js'; | ||
import { ModuleSource } from '../ModuleSource.js'; | ||
@@ -11,4 +13,3 @@ /** @internal */ | ||
globalThis: { writable: true, configurable: true, value: global }, | ||
Compartment: { writable: true, configurable: true, value: evaluators.Compartment }, | ||
ExecutionContext: { writable: true, configurable: true, value: evaluators.ExecutionContext }, | ||
Evaluators: { writable: true, configurable: true, value: Evaluators }, | ||
ModuleSource: { writable: true, configurable: true, value: ModuleSource }, | ||
@@ -21,2 +22,5 @@ Module: { writable: true, configurable: true, value: evaluators.createModule(global) }, | ||
} | ||
export function makeGlobalThisPublic() { | ||
return makeGlobalThis(Object.prototype, { createModule: createModuleSubclass }, {}); | ||
} | ||
/** | ||
@@ -23,0 +27,0 @@ * @internal |
import { brandCheck_Compartment } from '../compartment.js'; | ||
import { StaticModuleRecord } from '../StaticModuleRecord.js'; | ||
import { isExportBinding, isImportAllBinding, isImportBinding, isModuleDescriptor_FullSpecReference, isModuleDescriptor_ModuleInstance, isModuleDescriptor_Source, isModuleDescriptor_StaticModuleRecord, } from './shapeCheck.js'; | ||
import { unreachable } from './assert.js'; | ||
import { hasFromField, isExportAllBinding, isExportBinding, isImportAllBinding, isImportBinding, isModuleDescriptor_FullSpecReference, isModuleDescriptor_ModuleInstance, isModuleDescriptor_Source, isModuleDescriptor_StaticModuleRecord, } from './shapeCheck.js'; | ||
import { all, allButDefault, namespace } from './spec.js'; | ||
/** @internal */ | ||
@@ -56,3 +58,3 @@ export function normalizeModuleDescriptor(desc) { | ||
const { initialize, bindings, needsImport, needsImportMeta, isAsync } = module; | ||
if (typeof initialize !== 'function') { | ||
if (initialize !== undefined && initialize !== null && typeof initialize !== 'function') { | ||
throw new TypeError('SyntheticModuleRecord.initialize must be a function'); | ||
@@ -148,2 +150,110 @@ } | ||
} | ||
/** @internal */ | ||
export function normalizeBindingsToSpecRecord(bindings) { | ||
// bindings = normalizeBindings(bindings) || [] | ||
bindings ??= []; | ||
const requestedModules = []; | ||
for (const binding of bindings) { | ||
if (isImportBinding(binding)) | ||
requestedModules.push(binding.from); | ||
else if (isImportAllBinding(binding)) | ||
requestedModules.push(binding.importAllFrom); | ||
else if (isExportBinding(binding)) { | ||
if (hasFromField(binding)) | ||
requestedModules.push(binding.from); | ||
} | ||
else if (isExportAllBinding(binding)) | ||
requestedModules.push(binding.exportAllFrom); | ||
else | ||
unreachable(binding); | ||
} | ||
const importEntries = []; | ||
for (const binding of bindings) { | ||
if (isImportBinding(binding)) { | ||
requestedModules.push(binding.from); | ||
importEntries.push({ | ||
ImportName: binding.import, | ||
LocalName: binding.as ?? binding.import, | ||
ModuleRequest: binding.from, | ||
}); | ||
} | ||
else if (isImportAllBinding(binding)) { | ||
requestedModules.push(binding.importAllFrom); | ||
importEntries.push({ | ||
ImportName: namespace, | ||
LocalName: binding.as, | ||
ModuleRequest: binding.importAllFrom, | ||
}); | ||
} | ||
} | ||
const importedBoundNames = importEntries.map((x) => x.LocalName); | ||
const indirectExportEntries = []; | ||
const localExportEntries = []; | ||
const starExportEntries = []; | ||
for (const binding of bindings) { | ||
if (isExportBinding(binding)) { | ||
if (hasFromField(binding)) { | ||
requestedModules.push(binding.from); | ||
indirectExportEntries.push({ | ||
ExportName: binding.as ?? binding.export, | ||
ImportName: binding.export, | ||
// LocalName: null, | ||
ModuleRequest: binding.from, | ||
}); | ||
} | ||
else { | ||
const ee = { | ||
ExportName: binding.as ?? binding.export, | ||
// LocalName: binding.export, | ||
ImportName: null, | ||
ModuleRequest: null, | ||
}; | ||
if (!importedBoundNames.includes(binding.export)) { | ||
localExportEntries.push(ee); | ||
} | ||
else { | ||
const ie = importEntries.find((x) => x.LocalName === binding.export); | ||
if (ie.ImportName === namespace) { | ||
localExportEntries.push(ee); | ||
} | ||
else { | ||
indirectExportEntries.push({ | ||
ModuleRequest: ie.ModuleRequest, | ||
ImportName: ie.ImportName, | ||
ExportName: ee.ExportName, | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
else if (isExportAllBinding(binding)) { | ||
requestedModules.push(binding.exportAllFrom); | ||
if (typeof binding.as === 'string') { | ||
// export * as name from 'mod' | ||
starExportEntries.push({ | ||
// LocalName: binding.as, | ||
ExportName: binding.as, | ||
ImportName: all, | ||
ModuleRequest: binding.exportAllFrom, | ||
}); | ||
} | ||
else { | ||
// export * from 'mod' | ||
starExportEntries.push({ | ||
// LocalName: null, | ||
ExportName: null, | ||
ImportName: allButDefault, | ||
ModuleRequest: binding.exportAllFrom, | ||
}); | ||
} | ||
} | ||
} | ||
return { | ||
requestedModules: [...new Set(requestedModules)], | ||
importEntries, | ||
indirectExportEntries, | ||
localExportEntries, | ||
starExportEntries, | ||
}; | ||
} | ||
function normalizeString(x) { | ||
@@ -150,0 +260,0 @@ return `${x}`; |
{ | ||
"name": "@masknet/compartment", | ||
"version": "0.2.0", | ||
"version": "0.2.1", | ||
"type": "module", | ||
@@ -5,0 +5,0 @@ "main": "./dist/index.js", |
@@ -1,2 +0,1 @@ | ||
import { ExecutionContext } from './ExecutionContext.js' | ||
import { makeBorrowedGlobalThis, makeGlobalThis } from './utils/makeGlobalThis.js' | ||
@@ -13,3 +12,3 @@ import { StaticModuleRecord } from './StaticModuleRecord.js' | ||
import { normalizeModuleDescriptor } from './utils/normalize.js' | ||
import { internalError } from './utils/opaqueProxy.js' | ||
import { internalError, unreachable } from './utils/assert.js' | ||
import { | ||
@@ -35,3 +34,3 @@ hasFromField, | ||
/** @deprecated Need a rewrite based on Module & ExecutionContext. */ | ||
/** @deprecated Need a rewrite based on Module & Evaluators. */ | ||
export class Compartment implements CompartmentInstance { | ||
@@ -102,4 +101,2 @@ get globalThis() { | ||
{ | ||
Compartment: Subcompartment, | ||
ExecutionContext: ExecutionContext, | ||
createModule: createModuleSubclass, | ||
@@ -109,2 +106,7 @@ }, | ||
) | ||
Object.defineProperty(this.#globalThis, 'Compartment', { | ||
configurable: true, | ||
writable: true, | ||
value: Subcompartment, | ||
}) | ||
} | ||
@@ -172,6 +174,3 @@ | ||
} | ||
} else { | ||
const _: never = desc | ||
internalError() | ||
} | ||
} else unreachable(desc) | ||
} | ||
@@ -210,3 +209,3 @@ async #instantiate(url: string, parentUrl: string | undefined): Promise<SystemJS.RegisterArray> { | ||
return { | ||
execute: () => initialize(moduleEnvironmentProxy, _context), | ||
execute: () => initialize?.(moduleEnvironmentProxy, _context), | ||
setters, | ||
@@ -216,6 +215,3 @@ } | ||
] | ||
} else { | ||
let _: never = module | ||
internalError() | ||
} | ||
} else unreachable(module) | ||
} | ||
@@ -273,6 +269,3 @@ } | ||
] | ||
} else { | ||
let _: never = binding | ||
internalError() | ||
} | ||
} else unreachable(binding) | ||
}) | ||
@@ -279,0 +272,0 @@ .filter(Boolean), |
@@ -18,3 +18,3 @@ export type { | ||
export { ModuleSource } from './ModuleSource.js' | ||
export { ExecutionContext, type ExecutionContextConstructor } from './ExecutionContext.js' | ||
export { Evaluators } from './Evaluators.js' | ||
export { Module, type ImportHook, imports } from './Module.js' | ||
@@ -25,1 +25,2 @@ | ||
export { URLResolveHook } from './utils/resolver.js' | ||
export { makeGlobalThisPublic as makeGlobalThis } from './utils/makeGlobalThis.js' |
import type { ModuleSource } from './ModuleSource.js' | ||
import type { ModuleNamespace, SyntheticModuleRecord, SyntheticModuleRecordInitializeContext } from './types.js' | ||
import { all, allButDefault, ambiguous, empty, namespace, PromiseCapability } from './utils/spec.js' | ||
import { normalizeSyntheticModuleRecord } from './utils/normalize.js' | ||
import { assert, internalError, opaqueProxy } from './utils/opaqueProxy.js' | ||
import { | ||
isImportBinding, | ||
isImportAllBinding, | ||
isExportAllBinding, | ||
isExportBinding, | ||
hasFromField, | ||
} from './utils/shapeCheck.js' | ||
all, | ||
ambiguous, | ||
empty, | ||
namespace, | ||
PromiseCapability, | ||
type ModuleExportEntry, | ||
type ModuleImportEntry, | ||
} from './utils/spec.js' | ||
import { normalizeBindingsToSpecRecord, normalizeSyntheticModuleRecord } from './utils/normalize.js' | ||
import { assert, internalError, opaqueProxy } from './utils/assert.js' | ||
@@ -17,3 +18,3 @@ export type ImportHook = (importSpecifier: string, importMeta: object) => PromiseLike<Module | null> | ||
/** @internal */ | ||
export let createModuleSubclass: (globalThis: object) => typeof Module | ||
export let createModuleSubclass: (globalThis: object, importHook?: ImportHook, importMeta?: ImportMeta) => typeof Module | ||
export class Module { | ||
@@ -29,2 +30,3 @@ // The constructor is equivalent to ParseModule in SourceTextModuleRecord | ||
const module = normalizeSyntheticModuleRecord(source) | ||
this.#InitializeThisValue = source | ||
this.#Initialize = module.initialize | ||
@@ -38,83 +40,9 @@ this.#NeedsImport = module.needsImport | ||
const requestedModules: string[] = [] | ||
const importsEntries: ModuleImportEntry[] = (this.#ImportEntries = []) | ||
for (const binding of module.bindings || []) { | ||
if (isImportBinding(binding)) { | ||
requestedModules.push(binding.from) | ||
importsEntries.push({ | ||
ImportName: binding.import, | ||
LocalName: binding.as ?? binding.import, | ||
ModuleRequest: binding.from, | ||
}) | ||
} else if (isImportAllBinding(binding)) { | ||
requestedModules.push(binding.importAllFrom) | ||
importsEntries.push({ | ||
ImportName: namespace, | ||
LocalName: binding.as, | ||
ModuleRequest: binding.importAllFrom, | ||
}) | ||
} | ||
} | ||
const importedBoundNames = importsEntries.map((x) => x.LocalName) | ||
const indirectExportEntries: ModuleExportEntry[] = (this.#IndirectExportEntries = []) | ||
const localExportEntries: ModuleExportEntry[] = (this.#LocalExportEntries = []) | ||
const starExportEntries: ModuleExportEntry[] = (this.#StarExportEntries = []) | ||
for (const binding of module.bindings || []) { | ||
if (isExportBinding(binding)) { | ||
if (hasFromField(binding)) { | ||
requestedModules.push(binding.from) | ||
indirectExportEntries.push({ | ||
ExportName: binding.as ?? binding.export, | ||
ImportName: binding.export, | ||
// LocalName: null, | ||
ModuleRequest: binding.from, | ||
}) | ||
} else { | ||
const ee: ModuleExportEntry = { | ||
ExportName: binding.as ?? binding.export, | ||
// LocalName: binding.export, | ||
ImportName: null, | ||
ModuleRequest: null, | ||
} | ||
if (!importedBoundNames.includes(binding.export)) { | ||
localExportEntries.push(ee) | ||
} else { | ||
const ie = importsEntries.find((x) => x.LocalName === binding.export)! | ||
if (ie.ImportName === namespace) { | ||
localExportEntries.push(ee) | ||
} else { | ||
indirectExportEntries.push({ | ||
ModuleRequest: ie.ModuleRequest, | ||
ImportName: ie.ImportName, | ||
ExportName: ee.ExportName, | ||
}) | ||
} | ||
} | ||
} | ||
} else if (isExportAllBinding(binding)) { | ||
requestedModules.push(binding.exportAllFrom) | ||
if (typeof binding.as === 'string') { | ||
// export * as name from 'mod' | ||
starExportEntries.push({ | ||
// LocalName: binding.as, | ||
ExportName: binding.as, | ||
ImportName: all, | ||
ModuleRequest: binding.exportAllFrom, | ||
}) | ||
} else { | ||
// export * from 'mod' | ||
starExportEntries.push({ | ||
// LocalName: null, | ||
ExportName: null, | ||
ImportName: allButDefault, | ||
ModuleRequest: binding.exportAllFrom, | ||
}) | ||
} | ||
} | ||
} | ||
// Set is ordered. | ||
this.#RequestedModules = [...new Set(requestedModules)] | ||
const { importEntries, indirectExportEntries, localExportEntries, requestedModules, starExportEntries } = | ||
normalizeBindingsToSpecRecord(module.bindings) | ||
this.#ImportEntries = importEntries | ||
this.#IndirectExportEntries = indirectExportEntries | ||
this.#LocalExportEntries = localExportEntries | ||
this.#RequestedModules = requestedModules | ||
this.#StarExportEntries = starExportEntries | ||
} | ||
@@ -131,2 +59,4 @@ //#region ModuleRecord fields https://tc39.es/ecma262/#table-module-record-fields | ||
// #region SyntheticModuleRecord fields | ||
// *this value* when calling #Initialize. | ||
#InitializeThisValue: unknown | ||
#Initialize: SyntheticModuleRecord['initialize'] | ||
@@ -359,13 +289,21 @@ #NeedsImportMeta: boolean | undefined | ||
} | ||
const init = this.#Initialize | ||
assert(this.#Environment) | ||
const env = new Proxy(this.#Environment, moduleEnvExoticMethods) | ||
if (!this.#HasTLA) { | ||
assert(!promise) | ||
init(env, this.#ContextObjectProxy) | ||
if (this.#Initialize) { | ||
Reflect.apply(this.#Initialize, this.#InitializeThisValue, [env, this.#ContextObjectProxy]) | ||
} | ||
} else { | ||
assert(promise) | ||
Promise.resolve(init(env, this.#ContextObjectProxy)).then(promise.Resolve, promise.Reject) | ||
if (this.#Initialize) { | ||
Promise.resolve( | ||
Reflect.apply(this.#Initialize, this.#InitializeThisValue, [env, this.#ContextObjectProxy]), | ||
).then(promise.Resolve, promise.Reject) | ||
} | ||
} | ||
this.#Initialize = undefined! | ||
this.#InitializeThisValue = undefined | ||
} | ||
@@ -749,7 +687,7 @@ // https://tc39.es/ecma262/#sec-moduledeclarationlinking | ||
} | ||
createModuleSubclass = (globalThis) => { | ||
createModuleSubclass = (globalThis, upper_importHook, upper_importMeta) => { | ||
const Parent = Module | ||
const SubModule = class Module extends Parent { | ||
constructor(source: ModuleSource | SyntheticModuleRecord, importHook: ImportHook, importMeta: object) { | ||
super(source, importHook, importMeta) | ||
super(source, importHook ?? upper_importHook, importMeta ?? upper_importMeta) | ||
this.#GlobalThis = globalThis | ||
@@ -763,14 +701,2 @@ } | ||
interface ModuleImportEntry { | ||
ModuleRequest: string | ||
ImportName: string | typeof namespace | ||
LocalName: string | ||
} | ||
interface ModuleExportEntry { | ||
ExportName: string | null | ||
ModuleRequest: string | null | ||
ImportName: string | typeof all | typeof allButDefault | null | ||
// LocalName: string | null | ||
} | ||
const enum ModuleStatus { | ||
@@ -777,0 +703,0 @@ unlinked, |
import type { Binding } from './index.js' | ||
import { internalError } from './utils/opaqueProxy.js' | ||
import { internalError } from './utils/assert.js' | ||
@@ -4,0 +4,0 @@ export class StaticModuleRecord { |
@@ -40,3 +40,3 @@ // https://github.com/tc39/proposal-compartments/blob/775024d93830ee6464363b4b373d9353425a0776/README.md | ||
bindings?: Array<Binding> | ||
initialize(environment: object, context?: SyntheticModuleRecordInitializeContext): void | Promise<void> | ||
initialize?(environment: object, context?: SyntheticModuleRecordInitializeContext): void | Promise<void> | ||
needsImportMeta?: boolean | undefined | ||
@@ -43,0 +43,0 @@ needsImport?: boolean | undefined |
import type { Compartment } from '../compartment.js' | ||
import type { ExecutionContext } from '../ExecutionContext.js' | ||
import type { Module } from '../Module.js' | ||
import { Evaluators } from '../Evaluators.js' | ||
import { createModuleSubclass, type Module } from '../Module.js' | ||
import { ModuleSource } from '../ModuleSource.js' | ||
/** @internal */ | ||
export interface Evaluators { | ||
Compartment: typeof Compartment | ||
ExecutionContext: typeof ExecutionContext | ||
export interface Evaluator { | ||
createModule: (globalThis: object) => typeof Module | ||
@@ -15,3 +13,3 @@ } | ||
prototype: object | null, | ||
evaluators: Evaluators, | ||
evaluators: Evaluator, | ||
globals: object | undefined | null, | ||
@@ -31,4 +29,3 @@ ): typeof globalThis { | ||
globalThis: { writable: true, configurable: true, value: global }, | ||
Compartment: { writable: true, configurable: true, value: evaluators.Compartment }, | ||
ExecutionContext: { writable: true, configurable: true, value: evaluators.ExecutionContext }, | ||
Evaluators: { writable: true, configurable: true, value: Evaluators }, | ||
ModuleSource: { writable: true, configurable: true, value: ModuleSource }, | ||
@@ -43,2 +40,6 @@ Module: { writable: true, configurable: true, value: evaluators.createModule(global) }, | ||
export function makeGlobalThisPublic() { | ||
return makeGlobalThis(Object.prototype, { createModule: createModuleSubclass }, {}) | ||
} | ||
/** | ||
@@ -45,0 +46,0 @@ * @internal |
@@ -13,3 +13,6 @@ import { brandCheck_Compartment } from '../compartment.js' | ||
} from '../types.js' | ||
import { unreachable } from './assert.js' | ||
import { | ||
hasFromField, | ||
isExportAllBinding, | ||
isExportBinding, | ||
@@ -23,2 +26,3 @@ isImportAllBinding, | ||
} from './shapeCheck.js' | ||
import { all, allButDefault, namespace, type ModuleExportEntry, type ModuleImportEntry } from './spec.js' | ||
@@ -70,3 +74,3 @@ /** @internal */ | ||
const { initialize, bindings, needsImport, needsImportMeta, isAsync } = module | ||
if (typeof initialize !== 'function') { | ||
if (initialize !== undefined && initialize !== null && typeof initialize !== 'function') { | ||
throw new TypeError('SyntheticModuleRecord.initialize must be a function') | ||
@@ -158,2 +162,102 @@ } | ||
/** @internal */ | ||
export function normalizeBindingsToSpecRecord(bindings: Binding[] | undefined) { | ||
// bindings = normalizeBindings(bindings) || [] | ||
bindings ??= [] | ||
const requestedModules: string[] = [] | ||
for (const binding of bindings) { | ||
if (isImportBinding(binding)) requestedModules.push(binding.from) | ||
else if (isImportAllBinding(binding)) requestedModules.push(binding.importAllFrom) | ||
else if (isExportBinding(binding)) { | ||
if (hasFromField(binding)) requestedModules.push(binding.from) | ||
} else if (isExportAllBinding(binding)) requestedModules.push(binding.exportAllFrom) | ||
else unreachable(binding) | ||
} | ||
const importEntries: ModuleImportEntry[] = [] | ||
for (const binding of bindings) { | ||
if (isImportBinding(binding)) { | ||
requestedModules.push(binding.from) | ||
importEntries.push({ | ||
ImportName: binding.import, | ||
LocalName: binding.as ?? binding.import, | ||
ModuleRequest: binding.from, | ||
}) | ||
} else if (isImportAllBinding(binding)) { | ||
requestedModules.push(binding.importAllFrom) | ||
importEntries.push({ | ||
ImportName: namespace, | ||
LocalName: binding.as, | ||
ModuleRequest: binding.importAllFrom, | ||
}) | ||
} | ||
} | ||
const importedBoundNames = importEntries.map((x) => x.LocalName) | ||
const indirectExportEntries: ModuleExportEntry[] = [] | ||
const localExportEntries: ModuleExportEntry[] = [] | ||
const starExportEntries: ModuleExportEntry[] = [] | ||
for (const binding of bindings) { | ||
if (isExportBinding(binding)) { | ||
if (hasFromField(binding)) { | ||
requestedModules.push(binding.from) | ||
indirectExportEntries.push({ | ||
ExportName: binding.as ?? binding.export, | ||
ImportName: binding.export, | ||
// LocalName: null, | ||
ModuleRequest: binding.from, | ||
}) | ||
} else { | ||
const ee: ModuleExportEntry = { | ||
ExportName: binding.as ?? binding.export, | ||
// LocalName: binding.export, | ||
ImportName: null, | ||
ModuleRequest: null, | ||
} | ||
if (!importedBoundNames.includes(binding.export)) { | ||
localExportEntries.push(ee) | ||
} else { | ||
const ie = importEntries.find((x) => x.LocalName === binding.export)! | ||
if (ie.ImportName === namespace) { | ||
localExportEntries.push(ee) | ||
} else { | ||
indirectExportEntries.push({ | ||
ModuleRequest: ie.ModuleRequest, | ||
ImportName: ie.ImportName, | ||
ExportName: ee.ExportName, | ||
}) | ||
} | ||
} | ||
} | ||
} else if (isExportAllBinding(binding)) { | ||
requestedModules.push(binding.exportAllFrom) | ||
if (typeof binding.as === 'string') { | ||
// export * as name from 'mod' | ||
starExportEntries.push({ | ||
// LocalName: binding.as, | ||
ExportName: binding.as, | ||
ImportName: all, | ||
ModuleRequest: binding.exportAllFrom, | ||
}) | ||
} else { | ||
// export * from 'mod' | ||
starExportEntries.push({ | ||
// LocalName: null, | ||
ExportName: null, | ||
ImportName: allButDefault, | ||
ModuleRequest: binding.exportAllFrom, | ||
}) | ||
} | ||
} | ||
} | ||
return { | ||
requestedModules: [...new Set(requestedModules)], | ||
importEntries, | ||
indirectExportEntries, | ||
localExportEntries, | ||
starExportEntries, | ||
} | ||
} | ||
function normalizeString(x: any) { | ||
@@ -160,0 +264,0 @@ return `${x}` |
@@ -45,1 +45,14 @@ /** @internal */ | ||
} | ||
/** @internal */ | ||
export interface ModuleImportEntry { | ||
ModuleRequest: string | ||
ImportName: string | typeof namespace | ||
LocalName: string | ||
} | ||
/** @internal */ | ||
export interface ModuleExportEntry { | ||
ExportName: string | null | ||
ModuleRequest: string | null | ||
ImportName: string | typeof all | typeof allButDefault | null | ||
// LocalName: string | null | ||
} |
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
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
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
291488
4833
5