diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2018-05-15 04:39:03 -0400 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2018-05-15 04:50:45 -0400 |
commit | 5117a8f8a289101723bc74d4e9c45581d5b99172 (patch) | |
tree | 99e63aede656212711c40475a797419d639b7acd /amd.ts | |
parent | 03af2c711818d616f8de82a5bc731a8ec2dbc723 (diff) |
Compile cache and relative imports working.
Diffstat (limited to 'amd.ts')
-rw-r--r-- | amd.ts | 80 |
1 files changed, 80 insertions, 0 deletions
@@ -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; +} |