Skip to content

Instantly share code, notes, and snippets.

@dherman
Last active February 7, 2017 16:06
Show Gist options
  • Save dherman/1555894a09ca188d4d3ca0c96fb44311 to your computer and use it in GitHub Desktop.
Save dherman/1555894a09ca188d4d3ca0c96fb44311 to your computer and use it in GitHub Desktop.
a tiny userland loader, using a "parse" and "link" primitive
import {b} from "./b.js";
import $ from "jquery";
export function a() {
// ...
}
import {a} from "./a.js";
import $ from "jquery";
export function b() {
// ...
}
import Dict from "dict";
class TinyLittleLoader {
constructor(realm, jquery) {
this.#realm = realm;
this.#jquery = jquery;
this.#registry = new Dict();
}
load(specifier) {
if (specifier === 'jquery') {
return Promise.resolve(this.#jquery);
}
let name = specifier.replace(/^\.\//, "")
.replace(/\.js$/, "");
if (!this.#registry.has(name)) {
let module = fetch(specifier).then(source => this.#realm.parseModule(source));
let complete = module.then(module => {
let specifiers = module.requestedNames();
return Promise.all(specifiers.map(specifier => {
let entry = this.load(specifier);
return entry.complete.then(() => entry.module.then(dependency => {
module.add(specifier, dependency);
return dependency;
}));
}));
});
let linked = module.then(module => complete.then(() => {
module.link();
return module;
}));
this.#registry.set(name, {
module,
complete,
linked
});
}
return this.#registry.get(name);
}
}
import * as jquery from "jquery";
class TinyLittleRealm extends Realm {
constructor() {
super();
this.#loader = new TinyLittleLoader(this, jquery);
}
async [Realm.import](name, referrer) {
let module = await this.#loader.load(name).linked;
module.ensureEvaluated();
return module;
}
}
let realm = new TinyLittleRealm();
realm.eval("import('./a.js')").then(m => m.a());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment