summaryrefslogtreecommitdiff
path: root/amd.ts
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2018-05-15 04:39:03 -0400
committerRyan Dahl <ry@tinyclouds.org>2018-05-15 04:50:45 -0400
commit5117a8f8a289101723bc74d4e9c45581d5b99172 (patch)
tree99e63aede656212711c40475a797419d639b7acd /amd.ts
parent03af2c711818d616f8de82a5bc731a8ec2dbc723 (diff)
Compile cache and relative imports working.
Diffstat (limited to 'amd.ts')
-rw-r--r--amd.ts80
1 files changed, 80 insertions, 0 deletions
diff --git a/amd.ts b/amd.ts
new file mode 100644
index 000000000..29cee123b
--- /dev/null
+++ b/amd.ts
@@ -0,0 +1,80 @@
+import * as path from "path";
+import { assert, log } from "./util";
+
+namespace ModuleExportsCache {
+ const cache = new Map<string, object>();
+ export function set(fileName: string, moduleExports: object) {
+ fileName = normalizeModuleName(fileName);
+ assert(
+ fileName.startsWith("/"),
+ `Normalized modules should start with /\n${fileName}`
+ );
+ log("ModuleExportsCache set", fileName);
+ cache.set(fileName, moduleExports);
+ }
+ export function get(fileName: string): object {
+ fileName = normalizeModuleName(fileName);
+ log("ModuleExportsCache get", fileName);
+ let moduleExports = cache.get(fileName);
+ if (moduleExports == null) {
+ moduleExports = {};
+ set(fileName, moduleExports);
+ }
+ return moduleExports;
+ }
+}
+
+function normalizeModuleName(fileName: string): string {
+ // Remove the extension.
+ return fileName.replace(/\.\w+$/, "");
+}
+
+function normalizeRelativeModuleName(contextFn: string, depFn: string): string {
+ if (depFn.startsWith("/")) {
+ return depFn;
+ } else {
+ return path.resolve(path.dirname(contextFn), depFn);
+ }
+}
+
+const executeQueue: Array<() => void> = [];
+
+export function executeQueueDrain(): void {
+ let fn;
+ while ((fn = executeQueue.shift())) {
+ fn();
+ }
+}
+
+// tslint:disable-next-line:no-any
+type AmdFactory = (...args: any[]) => undefined | object;
+type AmdDefine = (deps: string[], factory: AmdFactory) => void;
+
+export function makeDefine(fileName: string): AmdDefine {
+ const localDefine = (deps: string[], factory: AmdFactory): void => {
+ const localRequire = (x: string) => {
+ log("localRequire", x);
+ };
+ const localExports = ModuleExportsCache.get(fileName);
+ log("localDefine", fileName, deps, localExports);
+ const args = deps.map(dep => {
+ if (dep === "require") {
+ return localRequire;
+ } else if (dep === "exports") {
+ return localExports;
+ } else {
+ dep = normalizeRelativeModuleName(fileName, dep);
+ return ModuleExportsCache.get(dep);
+ }
+ });
+ executeQueue.push(() => {
+ log("execute", fileName);
+ const r = factory(...args);
+ if (r != null) {
+ ModuleExportsCache.set(fileName, r);
+ throw Error("x");
+ }
+ });
+ };
+ return localDefine;
+}