Skip to content

Commit

Permalink
Reify ModuleInstance
Browse files Browse the repository at this point in the history
  • Loading branch information
kriskowal committed Jun 9, 2022
1 parent 59438f2 commit 5f6a07e
Showing 1 changed file with 50 additions and 4 deletions.
54 changes: 50 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ type Binding =
// imported or exported names.
// The bindings correspond to the equivalent `import` and `export` declarations
// of an ECMAScript module.
type ThirdPartyStaticModuleRecord = {
type SyntheticStaticModuleRecord = {
bindings?: Array<Binding>,
// Initializes the module if it is imported.
// Initialize may return a promise, indicating that the module uses
Expand All @@ -205,8 +205,8 @@ type ThirdPartyStaticModuleRecord = {
needsImportMeta: boolean,
};

// Static module records are an opaque token representing the compilation
// of a module that can be reused across multiple loaders.
// Static module records represent the compilation of a module that can be
// reused across multiple loaders.
interface StaticModuleRecord {
// Static module records can be constructed from source.
// XS allows third-party module records and source descriptors to
Expand All @@ -216,6 +216,13 @@ interface StaticModuleRecord {
// Static module records reflect their bindings for information only.
// Loaders use internal slots for the compiled code and bindings.
bindings: Array<Binding>;

// Indicates that initialize needs to receive a dynamic import function that
// closes over the referrer module specifier.
needsImport: boolean;

// Indicates that initialize needs to receive an importMeta.
needsImportMeta: boolean;
}

// A ModuleDescriptor captures a static module record and per-loader metadata.
Expand Down Expand Up @@ -276,7 +283,7 @@ type ModuleDescriptor =
// where the behavior if the initialize function is async is analogous to
// top-level-await for a module compiled from source.
| {
record: ThirdPartyStaticModuleRecord,
record: SyntheticStaticModuleRecord,

// Properties to copy to the `import.meta` of the resulting module instance,
// if the `record` has a `true` `needsImportMeta` property.
Expand Down Expand Up @@ -434,6 +441,45 @@ interface Loader {

loadNow(fullSpecifier: string): void;
}

// ModuleInstance reifies an entangled pair of module environment record
// and module exports namespace from a particular array of bindings
// that correspond to the `import` and `export` declarations of a
// module.
interface ModuleInstance {
// Creates a module instance for either a static module record
// or a synthetic static module record.
// Creates a module environment record that defers to the
// global environment record of the designated loader.
// If the static module record needs a dynamic import behavior,
// creates a function that resolves import specifiers relative
// to its own referrer specifier and delegates to the
// attached loader.
constructor(
specifier: string,
record: StaticModuleRecord | SyntheticStaticModuleRecord,
loader: Loader,
importMeta?: Object,
);

// Links the module instance with another module instance
// for one of the importSpecifiers declared in the constructed
// bindings.
link(importSpecifier: string, instance: ModuleInstance);

// Initializes a module instance.
// Throws an error if any of its invariants are not satisfied.
// The module instances for the given module environment record
// and their transitive module instance dependencies must be fully linked.
// Defers to the initialize function of a synthetic static module record,
// reifying its own module environment record.
// TODO must all instances be bound in the same global environment record?
// Returns a promise if the static module record uses top-level-await
// or if the synthatic static module record initializer returns a promise.
initialize(): void | Promise<void>;

get namespace(): ModuleExportsNamespace;
}
```

## Motivating Examples and Design Rationales
Expand Down

0 comments on commit 5f6a07e

Please sign in to comment.