@masknet/compartment
Advanced tools
Comparing version 0.2.3 to 0.3.0
@@ -1,10 +0,13 @@ | ||
import { Module, type ImportHook } from './Module.js'; | ||
import { Module } from './Module.js'; | ||
import type { ImportHook } from './types.js'; | ||
export interface EvaluatorsOptions { | ||
globalThis?: object; | ||
importHook?: ImportHook; | ||
importMeta?: object | null; | ||
} | ||
export declare class Evaluators { | ||
#private; | ||
constructor(options: { | ||
globalThis?: object; | ||
importHook?: ImportHook; | ||
importMeta?: object; | ||
}); | ||
constructor(options: EvaluatorsOptions); | ||
Module: typeof Module; | ||
Evaluators: typeof Evaluators; | ||
get globalThis(): object; | ||
@@ -11,0 +14,0 @@ eval: typeof eval; |
@@ -1,19 +0,32 @@ | ||
import { createModuleSubclass, Module } from './Module.js'; | ||
import { Module, Module as TopModule, setGlobalThis } from './Module.js'; | ||
export class Evaluators { | ||
constructor(options) { | ||
const { globalThis, importHook, importMeta } = options; | ||
if (globalThis !== null && globalThis !== undefined && typeof globalThis !== 'object') { | ||
const { globalThis = realGlobalThis, importHook = defaultImportHook, importMeta = null } = options; | ||
if (typeof globalThis !== 'object') | ||
throw new TypeError('globalThis must be an object'); | ||
} | ||
if (importHook !== null && importHook !== undefined && typeof importHook !== 'function') { | ||
if (typeof importHook !== 'function') | ||
throw new TypeError('importHook must be a function'); | ||
} | ||
if (importMeta !== null && importMeta !== undefined && typeof importMeta !== 'object') { | ||
if (typeof importMeta !== 'object') | ||
throw new TypeError('importMeta must be an object'); | ||
const parent = this; | ||
class Evaluators extends TopEvaluators { | ||
constructor(options) { | ||
const { globalThis = parent.#globalThis, importHook = parent.#importHook, importMeta = parent.#importMeta ?? null, } = options; | ||
super({ globalThis, importHook, importMeta }); | ||
} | ||
} | ||
this.#globalThis = globalThis ?? { __proto__: null }; | ||
this.Module = createModuleSubclass(this.#globalThis, importHook, importMeta); | ||
class Module extends TopModule { | ||
constructor(moduleSource, referral, importHook, importMeta) { | ||
super(moduleSource, referral, importHook ?? parent.#importHook, importMeta ?? parent.#importMeta); | ||
setGlobalThis(this, parent.#globalThis); | ||
} | ||
} | ||
this.#importHook = importHook; | ||
this.#importMeta = importMeta ?? undefined; | ||
this.#globalThis = globalThis; | ||
this.Module = Module; | ||
this.Evaluators = Evaluators; | ||
} | ||
#globalThis; | ||
Module; | ||
Evaluators; | ||
get globalThis() { | ||
@@ -25,3 +38,12 @@ return this.#globalThis; | ||
Function = Function; | ||
#globalThis; | ||
#importHook; | ||
#importMeta; | ||
} | ||
const TopEvaluators = Evaluators; | ||
const realGlobalThis = globalThis; | ||
/** @internal */ | ||
export function defaultImportHook() { | ||
throw new TypeError(`This evaluator does not have any import resolution.`); | ||
} | ||
//# sourceMappingURL=Evaluators.js.map |
@@ -1,10 +0,6 @@ | ||
export type { Binding, ImportBinding, ExportBinding, CompartmentOptions, ModuleDescriptor, ModuleDescriptor_Source, ModuleDescriptor_ModuleInstance, ModuleDescriptor_FullSpecReference, ModuleDescriptor_StaticModuleRecord, ModuleNamespace, VirtualModuleRecord, VirtualModuleRecordExecuteContext, } from './types.js'; | ||
export { Compartment } from './compartment.js'; | ||
export type { Binding, ImportBinding, ImportAllBinding, ExportBinding, ExportAllBinding, VirtualModuleRecord, VirtualModuleRecordExecuteContext, ModuleNamespace, ImportHook, Referral, StaticModuleRecordInstance, } from './types.js'; | ||
export { ModuleSource } from './ModuleSource.js'; | ||
export { Evaluators } from './Evaluators.js'; | ||
export { Module, type ImportHook, imports } from './Module.js'; | ||
export { createModuleCache } from './utils/createModuleCache.js'; | ||
export { createWebImportMeta } from './utils/importMeta.js'; | ||
export { URLResolveHook } from './utils/resolver.js'; | ||
export { makeGlobalThisPublic as makeGlobalThis } from './utils/makeGlobalThis.js'; | ||
export { Module, imports } from './Module.js'; | ||
export { makeGlobalThis } from './utils/makeGlobalThis.js'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -1,9 +0,5 @@ | ||
export { Compartment } from './compartment.js'; | ||
export { ModuleSource } from './ModuleSource.js'; | ||
export { Evaluators } from './Evaluators.js'; | ||
export { Module, imports } from './Module.js'; | ||
export { createModuleCache } from './utils/createModuleCache.js'; | ||
export { createWebImportMeta } from './utils/importMeta.js'; | ||
export { URLResolveHook } from './utils/resolver.js'; | ||
export { makeGlobalThisPublic as makeGlobalThis } from './utils/makeGlobalThis.js'; | ||
export { makeGlobalThis } from './utils/makeGlobalThis.js'; | ||
//# sourceMappingURL=index.js.map |
import type { ModuleSource } from './ModuleSource.js'; | ||
import type { VirtualModuleRecord } from './types.js'; | ||
export declare type ImportHook = (importSpecifier: string, importMeta: object) => PromiseLike<Module | null> | Module | null; | ||
import type { ImportHook, Referral, VirtualModuleRecord } from './types.js'; | ||
export declare let imports: <T extends object = any>(specifier: Module<T>, options?: ImportCallOptions) => Promise<T>; | ||
export interface ModuleConstructorOptions { | ||
importHook?: ImportHook | undefined; | ||
importMeta?: object | undefined; | ||
} | ||
export declare class Module<T extends object = any> { | ||
#private; | ||
constructor(source: ModuleSource<T> | VirtualModuleRecord, options?: ModuleConstructorOptions); | ||
constructor(moduleSource: ModuleSource<T> | VirtualModuleRecord, referral: Referral, importHook?: ImportHook, importMeta?: object); | ||
get source(): ModuleSource | VirtualModuleRecord | null; | ||
} | ||
//# sourceMappingURL=Module.d.ts.map |
import { all, ambiguous, empty, namespace, PromiseCapability, } from './utils/spec.js'; | ||
import { normalizeBindingsToSpecRecord, normalizeVirtualModuleRecord } from './utils/normalize.js'; | ||
import { assert, internalError, opaqueProxy } from './utils/assert.js'; | ||
import { defaultImportHook } from './Evaluators.js'; | ||
export let imports; | ||
/** @internal */ | ||
export let createModuleSubclass; | ||
export let setGlobalThis; | ||
export class Module { | ||
// The constructor is equivalent to ParseModule in SourceTextModuleRecord | ||
// https://tc39.es/ecma262/#sec-parsemodule | ||
constructor(source, options = {}) { | ||
const { importHook, importMeta } = options; | ||
constructor(moduleSource, referral, | ||
// it actually NOT an optional argument when it is the top-level Module. | ||
importHook = defaultImportHook, importMeta) { | ||
if (typeof moduleSource !== 'object') | ||
throw new TypeError('moduleSource must be an object'); | ||
if (typeof importHook !== 'function') | ||
throw new TypeError('importHook must be a function'); | ||
if (typeof importMeta !== 'object') | ||
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 | ||
source = source; | ||
const module = normalizeVirtualModuleRecord(source); | ||
this.#Source = source; | ||
const module = normalizeVirtualModuleRecord(moduleSource); | ||
this.#Source = moduleSource; | ||
this.#Referral = referral; | ||
this.#Execute = module.execute; | ||
@@ -24,3 +33,3 @@ this.#NeedsImport = module.needsImport; | ||
this.#HasTLA = !!module.isAsync; | ||
this.#AssignedImportMeta = importMeta; | ||
this.#AssignedImportMeta = importMeta ?? null; | ||
this.#ImportHook = importHook; | ||
@@ -47,2 +56,3 @@ const { importEntries, indirectExportEntries, localExportEntries, requestedModules, starExportEntries } = normalizeBindingsToSpecRecord(module.bindings); | ||
// *this value* when calling #Execute. | ||
#Referral; | ||
#Source; | ||
@@ -610,3 +620,3 @@ #Execute; | ||
module.#ResolvedModules.set(spec, capability); | ||
Promise.resolve(module.#ImportHook(spec, module.#AssignedImportMeta)) | ||
Promise.resolve(module.#ImportHook(spec, module.#Referral)) | ||
.then(async (module) => { | ||
@@ -646,24 +656,9 @@ if (module === null || module === undefined) | ||
//#endregion | ||
// Safari: static init block | ||
/** @internal */ | ||
static _ = (() => { | ||
static { | ||
imports = async (module, options) => { | ||
return Module.#DynamicImportModule(module); | ||
}; | ||
createModuleSubclass = (globalThis, upper_importHook, upper_importMeta) => { | ||
const Parent = Module; | ||
const SubModule = class Module extends Parent { | ||
constructor(source, options = {}) { | ||
const { importHook, importMeta } = options; | ||
super(source, { | ||
importHook: importHook ?? upper_importHook, | ||
importMeta: importMeta ?? upper_importMeta, | ||
}); | ||
this.#GlobalThis = globalThis; | ||
} | ||
}; | ||
Reflect.defineProperty(SubModule.prototype, Symbol.toStringTag, { configurable: true, value: 'Module' }); | ||
return SubModule; | ||
}; | ||
})(); | ||
setGlobalThis = (module, global) => (module.#GlobalThis = global); | ||
} | ||
} | ||
@@ -674,3 +669,2 @@ Reflect.defineProperty(Module.prototype, Symbol.toStringTag, { | ||
}); | ||
delete Module._; | ||
var ModuleStatus; | ||
@@ -677,0 +671,0 @@ (function (ModuleStatus) { |
@@ -1,3 +0,2 @@ | ||
import type { Compartment } from './compartment.js'; | ||
import type { ModuleSource } from './ModuleSource.js'; | ||
import type { Module } from './Module.js'; | ||
export declare type Binding = ImportBinding | ExportBinding | ImportAllBinding | ExportAllBinding; | ||
@@ -52,34 +51,4 @@ /** | ||
} | ||
export declare type ModuleDescriptor = ModuleDescriptor_Source | ModuleDescriptor_StaticModuleRecord | ModuleDescriptor_FullSpecReference | ModuleDescriptor_ModuleInstance; | ||
export interface ModuleDescriptor_Source { | ||
source: string; | ||
importMeta?: object | undefined; | ||
} | ||
export interface ModuleDescriptor_StaticModuleRecord { | ||
record: ModuleSource | VirtualModuleRecord | string; | ||
importMeta?: object | undefined; | ||
} | ||
export interface ModuleDescriptor_FullSpecReference { | ||
instance: string; | ||
compartment?: Compartment | undefined; | ||
} | ||
export interface ModuleDescriptor_ModuleInstance { | ||
namespace: object; | ||
} | ||
export interface CompartmentOptions { | ||
borrowGlobals?: boolean; | ||
globals?: object | undefined; | ||
resolveHook(importSpec: string, referrerSpec: string): string; | ||
moduleMap?: Record<string, ModuleDescriptor> | undefined; | ||
loadHook?(fullSpec: string): Promise<ModuleDescriptor | undefined>; | ||
importMetaHook?(fullSpec: string, importMeta: object): void; | ||
} | ||
export interface CompartmentInstance { | ||
get globalThis(): object; | ||
evaluate(source: string): unknown; | ||
load(fullSpec: string): Promise<void>; | ||
import(fullSpec: string): Promise<object>; | ||
importNow?(fullSpec: string): object; | ||
loadNow?(fullSpec: string): void; | ||
} | ||
export declare type ImportHook = (importSpecifier: string, referrer: Referral) => PromiseLike<Module | null> | Module | null; | ||
export declare type Referral = symbol | string | number | bigint; | ||
//# sourceMappingURL=types.d.ts.map |
@@ -0,2 +1,3 @@ | ||
// https://github.com/tc39/proposal-compartments/blob/775024d93830ee6464363b4b373d9353425a0776/README.md | ||
export {}; | ||
//# sourceMappingURL=types.js.map |
@@ -1,5 +0,8 @@ | ||
const proxy = Proxy.revocable({}, {}); | ||
proxy.revoke(); | ||
function getOpaqueProxy() { | ||
const x = Proxy.revocable({}, {}); | ||
x.revoke(); | ||
return x.proxy; | ||
} | ||
/** @internal */ | ||
export const opaqueProxy = proxy.proxy; | ||
export const opaqueProxy = /*#__PURE__*/ getOpaqueProxy(); | ||
/** @internal */ | ||
@@ -6,0 +9,0 @@ export function internalError() { |
@@ -1,2 +0,2 @@ | ||
export declare function makeGlobalThisPublic(): typeof globalThis; | ||
export declare function makeGlobalThis(prototype: object | null): typeof globalThis; | ||
//# sourceMappingURL=makeGlobalThis.d.ts.map |
import { Evaluators } from '../Evaluators.js'; | ||
import { createModuleSubclass } from '../Module.js'; | ||
import { ModuleSource } from '../ModuleSource.js'; | ||
/** @internal */ | ||
export function makeGlobalThis(prototype, evaluators, globals) { | ||
export function makeGlobalThis(prototype) { | ||
const global = Object.create(null); | ||
@@ -15,25 +13,6 @@ Object.defineProperties(global, intrinsic.reduce((previous, name) => { | ||
ModuleSource: { writable: true, configurable: true, value: ModuleSource }, | ||
Module: { writable: true, configurable: true, value: evaluators.createModule(global) }, | ||
Module: { writable: true, configurable: true, value: new Evaluators({ globalThis: global }) }, | ||
}); | ||
if (globals) | ||
Object.assign(global, globals); | ||
return Object.setPrototypeOf(global, prototype); | ||
} | ||
export function makeGlobalThisPublic() { | ||
return makeGlobalThis(Object.prototype, { createModule: createModuleSubclass }, {}); | ||
} | ||
/** | ||
* @internal | ||
* @deprecated | ||
*/ | ||
export function makeBorrowedGlobalThis(compartment, globalThis) { | ||
const global = Object.create(null); | ||
Object.defineProperty(global, 'Compartment', { | ||
value: compartment, | ||
configurable: true, | ||
writable: true, | ||
}); | ||
Object.setPrototypeOf(global, globalThis); | ||
return global; | ||
} | ||
// https://tc39.es/ecma262/multipage/global-object.html#sec-global-object | ||
@@ -40,0 +19,0 @@ const intrinsic = [ |
@@ -1,56 +0,5 @@ | ||
import { brandCheck_Compartment } from '../compartment.js'; | ||
import { ModuleSource } from '../ModuleSource.js'; | ||
import { unreachable } from './assert.js'; | ||
import { hasFromField, isExportAllBinding, isExportBinding, isImportAllBinding, isImportBinding, isModuleDescriptor_FullSpecReference, isModuleDescriptor_ModuleInstance, isModuleDescriptor_Source, isModuleDescriptor_StaticModuleRecord, } from './shapeCheck.js'; | ||
import { hasFromField, isExportAllBinding, isExportBinding, isImportAllBinding, isImportBinding } from './shapeCheck.js'; | ||
import { all, allButDefault, namespace } from './spec.js'; | ||
/** @internal */ | ||
export function normalizeModuleDescriptor(desc) { | ||
if (!desc) | ||
return undefined; | ||
if (isModuleDescriptor_Source(desc)) { | ||
const { source, importMeta } = desc; | ||
const copy = { | ||
source: normalizeString(source), | ||
importMeta: normalizeImportMeta(importMeta), | ||
}; | ||
return copy; | ||
} | ||
else if (isModuleDescriptor_StaticModuleRecord(desc)) { | ||
const { record, importMeta } = desc; | ||
let normalizedRecord; | ||
if (typeof record === 'string') { | ||
normalizedRecord = record; | ||
} | ||
else if (typeof record !== 'object' || record === null) { | ||
throw new TypeError('ModuleDescriptor must be either a string, StaticModuleRecord or VirtualModuleRecord'); | ||
} | ||
else if (record instanceof ModuleSource) { | ||
throw new TypeError('ModuleSource is not supported'); | ||
} | ||
else { | ||
normalizedRecord = normalizeVirtualModuleRecord(record); | ||
} | ||
const copy = { | ||
record: normalizedRecord, | ||
importMeta: normalizeImportMeta(importMeta), | ||
}; | ||
return copy; | ||
} | ||
else if (isModuleDescriptor_FullSpecReference(desc)) { | ||
const { instance, compartment } = desc; | ||
if (compartment && !brandCheck_Compartment(compartment)) { | ||
throw new TypeError('moduleDescriptor.compartment is not a Compartment'); | ||
} | ||
const copy = { instance: `${instance}`, compartment }; | ||
return copy; | ||
} | ||
else if (isModuleDescriptor_ModuleInstance(desc)) { | ||
const copy = { namespace: Object.assign({ __proto__: null }, desc.namespace) }; | ||
return copy; | ||
} | ||
else { | ||
throw new TypeError('moduleDescriptor is not a valid descriptor.'); | ||
} | ||
} | ||
/** @internal */ | ||
export function normalizeVirtualModuleRecord(module) { | ||
@@ -57,0 +6,0 @@ const { execute, bindings, needsImport, needsImportMeta, isAsync } = module; |
/** @internal */ | ||
export function isModuleDescriptor_FullSpecReference(descriptor) { | ||
return 'instance' in descriptor; | ||
} | ||
/** @internal */ | ||
export function isModuleDescriptor_Source(descriptor) { | ||
return 'source' in descriptor; | ||
} | ||
/** @internal */ | ||
export function isModuleDescriptor_StaticModuleRecord(descriptor) { | ||
return 'record' in descriptor; | ||
} | ||
/** @internal */ | ||
export function isModuleDescriptor_ModuleInstance(descriptor) { | ||
return 'namespace' in descriptor; | ||
} | ||
/** @internal */ | ||
export function isImportBinding(binding) { | ||
@@ -19,0 +3,0 @@ return 'import' in binding; |
/** @internal */ | ||
export const empty = Symbol('empty'); | ||
export const empty = /*#__PURE__*/ Symbol('empty'); | ||
/** @internal */ | ||
export const namespace = Symbol('namespace'); | ||
export const namespace = /*#__PURE__*/ Symbol('namespace'); | ||
/** @internal */ | ||
export const ambiguous = Symbol('ambiguous'); | ||
export const ambiguous = /*#__PURE__*/ Symbol('ambiguous'); | ||
/** @internal */ | ||
export const all = Symbol('all'); | ||
export const all = /*#__PURE__*/ Symbol('all'); | ||
/** @internal */ | ||
export const allButDefault = Symbol('all-but-default'); | ||
export const allButDefault = /*#__PURE__*/ Symbol('all-but-default'); | ||
/** @internal */ | ||
@@ -12,0 +12,0 @@ export function PromiseCapability() { |
{ | ||
"name": "@masknet/compartment", | ||
"version": "0.2.3", | ||
"version": "0.3.0", | ||
"type": "module", | ||
@@ -10,3 +10,3 @@ "main": "./dist/index.js", | ||
"devDependencies": { | ||
"@swc/core": "^1.2.222" | ||
"@swc/core": "^1.2.223" | ||
}, | ||
@@ -13,0 +13,0 @@ "files": [ |
@@ -1,20 +0,49 @@ | ||
import { createModuleSubclass, Module, type ImportHook } from './Module.js' | ||
import { Module, Module as TopModule, setGlobalThis } from './Module.js' | ||
import type { ModuleSource } from './ModuleSource.js' | ||
import type { ImportHook, Referral, VirtualModuleRecord } from './types.js' | ||
export interface EvaluatorsOptions { | ||
globalThis?: object | ||
importHook?: ImportHook | ||
importMeta?: object | null | ||
} | ||
export class Evaluators { | ||
constructor(options: { globalThis?: object; importHook?: ImportHook; importMeta?: object }) { | ||
const { globalThis, importHook, importMeta } = options | ||
if (globalThis !== null && globalThis !== undefined && typeof globalThis !== 'object') { | ||
throw new TypeError('globalThis must be an object') | ||
constructor(options: EvaluatorsOptions) { | ||
const { globalThis = realGlobalThis, importHook = defaultImportHook, importMeta = null } = options | ||
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') | ||
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 }) | ||
} | ||
} | ||
if (importHook !== null && importHook !== undefined && typeof importHook !== 'function') { | ||
throw new TypeError('importHook must be a function') | ||
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) | ||
} | ||
} | ||
if (importMeta !== null && importMeta !== undefined && typeof importMeta !== 'object') { | ||
throw new TypeError('importMeta must be an object') | ||
} | ||
this.#globalThis = globalThis ?? { __proto__: null } | ||
this.Module = createModuleSubclass(this.#globalThis, importHook, importMeta) | ||
this.#importHook = importHook | ||
this.#importMeta = importMeta ?? undefined | ||
this.#globalThis = globalThis | ||
this.Module = Module | ||
this.Evaluators = Evaluators | ||
} | ||
#globalThis: object | ||
Module: typeof Module | ||
Evaluators: typeof Evaluators | ||
get globalThis() { | ||
@@ -26,2 +55,12 @@ return this.#globalThis | ||
Function = Function | ||
#globalThis: object | ||
#importHook: ImportHook | ||
#importMeta: object | undefined | ||
} | ||
const TopEvaluators = Evaluators | ||
const realGlobalThis = globalThis | ||
/** @internal */ | ||
export function defaultImportHook(): never { | ||
throw new TypeError(`This evaluator does not have any import resolution.`) | ||
} |
export type { | ||
Binding, | ||
ImportBinding, | ||
ImportAllBinding, | ||
ExportBinding, | ||
CompartmentOptions, | ||
ModuleDescriptor, | ||
ModuleDescriptor_Source, | ||
ModuleDescriptor_ModuleInstance, | ||
ModuleDescriptor_FullSpecReference, | ||
ModuleDescriptor_StaticModuleRecord, | ||
ModuleNamespace, | ||
ExportAllBinding, | ||
VirtualModuleRecord, | ||
VirtualModuleRecordExecuteContext, | ||
ModuleNamespace, | ||
ImportHook, | ||
Referral, | ||
StaticModuleRecordInstance, | ||
} from './types.js' | ||
export { Compartment } from './compartment.js' | ||
export { ModuleSource } from './ModuleSource.js' | ||
export { Evaluators } from './Evaluators.js' | ||
export { Module, type ImportHook, imports } from './Module.js' | ||
export { Module, imports } from './Module.js' | ||
export { createModuleCache } from './utils/createModuleCache.js' | ||
export { createWebImportMeta } from './utils/importMeta.js' | ||
export { URLResolveHook } from './utils/resolver.js' | ||
export { makeGlobalThisPublic as makeGlobalThis } from './utils/makeGlobalThis.js' | ||
export { makeGlobalThis } from './utils/makeGlobalThis.js' |
import type { ModuleSource } from './ModuleSource.js' | ||
import type { ModuleNamespace, VirtualModuleRecord, VirtualModuleRecordExecuteContext } from './types.js' | ||
import type { | ||
ImportHook, | ||
ModuleNamespace, | ||
Referral, | ||
VirtualModuleRecord, | ||
VirtualModuleRecordExecuteContext, | ||
} from './types.js' | ||
import { | ||
@@ -14,23 +20,31 @@ all, | ||
import { assert, internalError, opaqueProxy } from './utils/assert.js' | ||
import { defaultImportHook } from './Evaluators.js' | ||
export type ImportHook = (importSpecifier: string, importMeta: object) => PromiseLike<Module | null> | Module | null | ||
export let imports: <T extends object = any>(specifier: Module<T>, options?: ImportCallOptions) => Promise<T> | ||
/** @internal */ | ||
export let createModuleSubclass: (globalThis: object, importHook?: ImportHook, importMeta?: ImportMeta) => typeof Module | ||
export interface ModuleConstructorOptions { | ||
importHook?: ImportHook | undefined | ||
importMeta?: object | undefined | ||
} | ||
export let setGlobalThis: (module: Module, global: object) => void | ||
export class Module<T extends object = any> { | ||
// The constructor is equivalent to ParseModule in SourceTextModuleRecord | ||
// https://tc39.es/ecma262/#sec-parsemodule | ||
constructor(source: ModuleSource<T> | VirtualModuleRecord, options: ModuleConstructorOptions = {}) { | ||
const { importHook, importMeta } = options | ||
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, | ||
) { | ||
if (typeof moduleSource !== 'object') throw new TypeError('moduleSource 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') | ||
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 | ||
source = source as VirtualModuleRecord | ||
const module = normalizeVirtualModuleRecord(moduleSource as VirtualModuleRecord) | ||
const module = normalizeVirtualModuleRecord(source) | ||
this.#Source = source | ||
this.#Source = moduleSource | ||
this.#Referral = referral | ||
this.#Execute = module.execute | ||
@@ -41,3 +55,3 @@ this.#NeedsImport = module.needsImport | ||
this.#AssignedImportMeta = importMeta | ||
this.#AssignedImportMeta = importMeta ?? null | ||
this.#ImportHook = importHook | ||
@@ -67,2 +81,3 @@ | ||
// *this value* when calling #Execute. | ||
#Referral: Referral | ||
#Source: VirtualModuleRecord | ||
@@ -74,3 +89,3 @@ #Execute: VirtualModuleRecord['execute'] | ||
#ImportHook: ImportHook | ||
#AssignedImportMeta: object | ||
#AssignedImportMeta: object | null | ||
/** the global environment this module binds to */ | ||
@@ -657,3 +672,3 @@ #GlobalThis: object = globalThis | ||
module.#ResolvedModules.set(spec, capability) | ||
Promise.resolve(module.#ImportHook(spec, module.#AssignedImportMeta)) | ||
Promise.resolve(module.#ImportHook(spec, module.#Referral)) | ||
.then( | ||
@@ -693,24 +708,9 @@ async (module) => { | ||
//#endregion | ||
// Safari: static init block | ||
/** @internal */ | ||
static _: any = (() => { | ||
static { | ||
imports = async (module, options) => { | ||
return Module.#DynamicImportModule(module) as any | ||
} | ||
createModuleSubclass = (globalThis, upper_importHook, upper_importMeta) => { | ||
const Parent = Module | ||
const SubModule = class Module<T extends object = any> extends Parent<T> { | ||
constructor(source: ModuleSource<T> | VirtualModuleRecord, options: ModuleConstructorOptions = {}) { | ||
const { importHook, importMeta } = options | ||
super(source, { | ||
importHook: importHook ?? upper_importHook, | ||
importMeta: importMeta ?? upper_importMeta, | ||
}) | ||
this.#GlobalThis = globalThis | ||
} | ||
} | ||
Reflect.defineProperty(SubModule.prototype, Symbol.toStringTag, { configurable: true, value: 'Module' }) | ||
return SubModule | ||
} | ||
})() | ||
setGlobalThis = (module, global) => (module.#GlobalThis = global) | ||
} | ||
} | ||
@@ -721,3 +721,2 @@ Reflect.defineProperty(Module.prototype, Symbol.toStringTag, { | ||
}) | ||
delete Module._ | ||
@@ -724,0 +723,0 @@ const enum ModuleStatus { |
@@ -13,2 +13,3 @@ import type { Binding } from './types.js' | ||
} | ||
Reflect.defineProperty(ModuleSource.prototype, Symbol.toStringTag, { | ||
@@ -15,0 +16,0 @@ configurable: true, |
// https://github.com/tc39/proposal-compartments/blob/775024d93830ee6464363b4b373d9353425a0776/README.md | ||
import type { Compartment } from './compartment.js' | ||
import type { ModuleSource } from './ModuleSource.js' | ||
import type { Module } from './Module.js' | ||
export type Binding = ImportBinding | ExportBinding | ImportAllBinding | ExportAllBinding | ||
@@ -56,50 +56,3 @@ /** | ||
} | ||
export type ModuleDescriptor = | ||
| ModuleDescriptor_Source | ||
| ModuleDescriptor_StaticModuleRecord | ||
| ModuleDescriptor_FullSpecReference | ||
| ModuleDescriptor_ModuleInstance | ||
export interface ModuleDescriptor_Source { | ||
source: string | ||
importMeta?: object | undefined | ||
} | ||
export interface ModuleDescriptor_StaticModuleRecord { | ||
record: ModuleSource | VirtualModuleRecord | string | ||
importMeta?: object | undefined | ||
} | ||
export interface ModuleDescriptor_FullSpecReference { | ||
instance: string | ||
compartment?: Compartment | undefined | ||
} | ||
export interface ModuleDescriptor_ModuleInstance { | ||
namespace: object | ||
} | ||
export interface CompartmentOptions { | ||
borrowGlobals?: boolean | ||
globals?: object | undefined | ||
resolveHook(importSpec: string, referrerSpec: string): string | ||
moduleMap?: Record<string, ModuleDescriptor> | undefined | ||
loadHook?(fullSpec: string): Promise<ModuleDescriptor | undefined> | ||
importMetaHook?(fullSpec: string, importMeta: object): void | ||
} | ||
export interface CompartmentInstance { | ||
get globalThis(): object | ||
// Unsupported: CSP | ||
evaluate(source: string): unknown | ||
load(fullSpec: string): Promise<void> | ||
import(fullSpec: string): Promise<object> | ||
// Normative optional | ||
importNow?(fullSpec: string): object | ||
// Normative optional | ||
loadNow?(fullSpec: string): void | ||
} | ||
// Internal implementation | ||
/** @internal */ | ||
export type ModuleCacheItem = | ||
| { type: 'instance'; moduleInstance: ModuleNamespace } | ||
| { type: 'record'; module: VirtualModuleRecord; extraImportMeta: object | null | undefined } | ||
export type ImportHook = (importSpecifier: string, referrer: Referral) => PromiseLike<Module | null> | Module | null | ||
export type Referral = symbol | string | number | bigint |
@@ -1,5 +0,9 @@ | ||
const proxy = Proxy.revocable({}, {}) | ||
proxy.revoke() | ||
function getOpaqueProxy() { | ||
const x = Proxy.revocable({}, {}) | ||
x.revoke() | ||
return x.proxy | ||
} | ||
/** @internal */ | ||
export const opaqueProxy = proxy.proxy | ||
export const opaqueProxy = /*#__PURE__*/ getOpaqueProxy() | ||
/** @internal */ | ||
@@ -6,0 +10,0 @@ export function internalError(): never { |
@@ -1,16 +0,5 @@ | ||
import type { Compartment } from '../compartment.js' | ||
import { Evaluators } from '../Evaluators.js' | ||
import { createModuleSubclass, type Module } from '../Module.js' | ||
import { ModuleSource } from '../ModuleSource.js' | ||
/** @internal */ | ||
export interface Evaluator { | ||
createModule: (globalThis: object) => typeof Module | ||
} | ||
/** @internal */ | ||
export function makeGlobalThis( | ||
prototype: object | null, | ||
evaluators: Evaluator, | ||
globals: object | undefined | null, | ||
): typeof globalThis { | ||
export function makeGlobalThis(prototype: object | null): typeof globalThis { | ||
const global = Object.create(null) | ||
@@ -30,31 +19,8 @@ | ||
ModuleSource: { writable: true, configurable: true, value: ModuleSource }, | ||
Module: { writable: true, configurable: true, value: evaluators.createModule(global) }, | ||
Module: { writable: true, configurable: true, value: new Evaluators({ globalThis: global }) }, | ||
}) | ||
if (globals) Object.assign(global, globals) | ||
return Object.setPrototypeOf(global, prototype) | ||
} | ||
export function makeGlobalThisPublic() { | ||
return makeGlobalThis(Object.prototype, { createModule: createModuleSubclass }, {}) | ||
} | ||
/** | ||
* @internal | ||
* @deprecated | ||
*/ | ||
export function makeBorrowedGlobalThis(compartment: typeof Compartment, globalThis: object) { | ||
const global = Object.create(null) | ||
Object.defineProperty(global, 'Compartment', { | ||
value: compartment, | ||
configurable: true, | ||
writable: true, | ||
}) | ||
Object.setPrototypeOf(global, globalThis) | ||
return global | ||
} | ||
// https://tc39.es/ecma262/multipage/global-object.html#sec-global-object | ||
@@ -61,0 +27,0 @@ const intrinsic = [ |
@@ -1,70 +0,7 @@ | ||
import { brandCheck_Compartment } from '../compartment.js' | ||
import { ModuleSource } from '../ModuleSource.js' | ||
import type { | ||
ModuleDescriptor, | ||
ModuleDescriptor_Source, | ||
ModuleDescriptor_StaticModuleRecord, | ||
VirtualModuleRecord, | ||
ModuleDescriptor_ModuleInstance, | ||
Binding, | ||
ExportAllBinding, | ||
ImportBinding, | ||
} from '../types.js' | ||
import type { VirtualModuleRecord, Binding, ExportAllBinding, ImportBinding } from '../types.js' | ||
import { unreachable } from './assert.js' | ||
import { | ||
hasFromField, | ||
isExportAllBinding, | ||
isExportBinding, | ||
isImportAllBinding, | ||
isImportBinding, | ||
isModuleDescriptor_FullSpecReference, | ||
isModuleDescriptor_ModuleInstance, | ||
isModuleDescriptor_Source, | ||
isModuleDescriptor_StaticModuleRecord, | ||
} from './shapeCheck.js' | ||
import { hasFromField, isExportAllBinding, isExportBinding, isImportAllBinding, isImportBinding } from './shapeCheck.js' | ||
import { all, allButDefault, namespace, type ModuleExportEntry, type ModuleImportEntry } from './spec.js' | ||
/** @internal */ | ||
export function normalizeModuleDescriptor(desc: ModuleDescriptor | undefined | null): ModuleDescriptor | undefined { | ||
if (!desc) return undefined | ||
if (isModuleDescriptor_Source(desc)) { | ||
const { source, importMeta } = desc | ||
const copy: ModuleDescriptor_Source = { | ||
source: normalizeString(source), | ||
importMeta: normalizeImportMeta(importMeta), | ||
} | ||
return copy | ||
} else if (isModuleDescriptor_StaticModuleRecord(desc)) { | ||
const { record, importMeta } = desc | ||
let normalizedRecord: ModuleDescriptor_StaticModuleRecord['record'] | ||
if (typeof record === 'string') { | ||
normalizedRecord = record | ||
} else if (typeof record !== 'object' || record === null) { | ||
throw new TypeError('ModuleDescriptor must be either a string, StaticModuleRecord or VirtualModuleRecord') | ||
} else if (record instanceof ModuleSource) { | ||
throw new TypeError('ModuleSource is not supported') | ||
} else { | ||
normalizedRecord = normalizeVirtualModuleRecord(record) | ||
} | ||
const copy: ModuleDescriptor_StaticModuleRecord = { | ||
record: normalizedRecord, | ||
importMeta: normalizeImportMeta(importMeta), | ||
} | ||
return copy | ||
} else if (isModuleDescriptor_FullSpecReference(desc)) { | ||
const { instance, compartment } = desc | ||
if (compartment && !brandCheck_Compartment(compartment)) { | ||
throw new TypeError('moduleDescriptor.compartment is not a Compartment') | ||
} | ||
const copy: ModuleDescriptor = { instance: `${instance}`, compartment } | ||
return copy | ||
} else if (isModuleDescriptor_ModuleInstance(desc)) { | ||
const copy: ModuleDescriptor_ModuleInstance = { namespace: Object.assign({ __proto__: null }, desc.namespace) } | ||
return copy | ||
} else { | ||
throw new TypeError('moduleDescriptor is not a valid descriptor.') | ||
} | ||
} | ||
/** @internal */ | ||
export function normalizeVirtualModuleRecord(module: VirtualModuleRecord): VirtualModuleRecord { | ||
@@ -71,0 +8,0 @@ const { execute, bindings, needsImport, needsImportMeta, isAsync } = module |
@@ -1,41 +0,4 @@ | ||
import type { | ||
ModuleDescriptor_FullSpecReference, | ||
ModuleDescriptor_Source, | ||
ModuleDescriptor_ModuleInstance, | ||
ModuleDescriptor_StaticModuleRecord, | ||
ModuleDescriptor, | ||
Binding, | ||
ImportBinding, | ||
ExportBinding, | ||
ImportAllBinding, | ||
ExportAllBinding, | ||
} from '../types.js' | ||
import type { Binding, ImportBinding, ExportBinding, ImportAllBinding, ExportAllBinding } from '../types.js' | ||
/** @internal */ | ||
export function isModuleDescriptor_FullSpecReference( | ||
descriptor: ModuleDescriptor, | ||
): descriptor is ModuleDescriptor_FullSpecReference { | ||
return 'instance' in descriptor | ||
} | ||
/** @internal */ | ||
export function isModuleDescriptor_Source(descriptor: ModuleDescriptor): descriptor is ModuleDescriptor_Source { | ||
return 'source' in descriptor | ||
} | ||
/** @internal */ | ||
export function isModuleDescriptor_StaticModuleRecord( | ||
descriptor: ModuleDescriptor, | ||
): descriptor is ModuleDescriptor_StaticModuleRecord { | ||
return 'record' in descriptor | ||
} | ||
/** @internal */ | ||
export function isModuleDescriptor_ModuleInstance( | ||
descriptor: ModuleDescriptor, | ||
): descriptor is ModuleDescriptor_ModuleInstance { | ||
return 'namespace' in descriptor | ||
} | ||
/** @internal */ | ||
export function isImportBinding(binding: Binding): binding is ImportBinding { | ||
@@ -42,0 +5,0 @@ return 'import' in binding |
/** @internal */ | ||
export const empty = Symbol('empty') | ||
export const empty = /*#__PURE__*/ Symbol('empty') | ||
/** @internal */ | ||
export type empty = typeof empty | ||
/** @internal */ | ||
export const namespace = Symbol('namespace') | ||
export const namespace = /*#__PURE__*/ Symbol('namespace') | ||
/** @internal */ | ||
export const ambiguous = Symbol('ambiguous') | ||
export const ambiguous = /*#__PURE__*/ Symbol('ambiguous') | ||
/** @internal */ | ||
export const all = Symbol('all') | ||
export const all = /*#__PURE__*/ Symbol('all') | ||
/** @internal */ | ||
export const allButDefault = Symbol('all-but-default') | ||
export const allButDefault = /*#__PURE__*/ Symbol('all-but-default') | ||
/** @internal */ | ||
export type PromiseCapability<T> = { | ||
export interface PromiseCapability<T> { | ||
readonly Promise: Promise<T> | ||
@@ -17,0 +17,0 @@ readonly Reject: (reason: unknown) => void |
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
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
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
1
161059
53
2523