diff options
-rw-r--r-- | cli/js/compiler_api_test.ts | 4 | ||||
-rw-r--r-- | cli/js/compiler_bundler.ts | 13 | ||||
-rw-r--r-- | cli/tests/bundle.test.out | 5 | ||||
-rw-r--r-- | deno_typescript/system_loader.js | 72 |
4 files changed, 58 insertions, 36 deletions
diff --git a/cli/js/compiler_api_test.ts b/cli/js/compiler_api_test.ts index a6baecbf5..82f72cdef 100644 --- a/cli/js/compiler_api_test.ts +++ b/cli/js/compiler_api_test.ts @@ -94,14 +94,14 @@ test(async function bundleApiSources() { "/bar.ts": `export const bar = "bar";\n` }); assert(diagnostics == null); - assert(actual.includes(`__inst("foo")`)); + assert(actual.includes(`__inst_s("foo")`)); assert(actual.includes(`__exp["bar"]`)); }); test(async function bundleApiNoSources() { const [diagnostics, actual] = await bundle("./cli/tests/subdir/mod1.ts"); assert(diagnostics == null); - assert(actual.includes(`__inst("mod1")`)); + assert(actual.includes(`__inst_s("mod1")`)); assert(actual.includes(`__exp["printHello3"]`)); }); diff --git a/cli/js/compiler_bundler.ts b/cli/js/compiler_bundler.ts index b9893620a..f8f0b48e8 100644 --- a/cli/js/compiler_bundler.ts +++ b/cli/js/compiler_bundler.ts @@ -42,9 +42,16 @@ export function buildBundle( rootName = normalizeUrl(rootName) .replace(sharedPath, "") .replace(/\.\w+$/i, ""); + // If one of the modules requires support for top-level-await, TypeScript will + // emit the execute function as an async function. When this is the case we + // need to bubble up the TLA to the instantiation, otherwise we instantiate + // synchronously. + const hasTla = data.match(/execute:\sasync\sfunction\s/); let instantiate: string; if (rootExports && rootExports.length) { - instantiate = `const __exp = await __inst("${rootName}");\n`; + instantiate = hasTla + ? `const __exp = await __inst("${rootName}");\n` + : `const __exp = __inst_s("${rootName}");\n`; for (const rootExport of rootExports) { if (rootExport === "default") { instantiate += `export default __exp["${rootExport}"];\n`; @@ -53,7 +60,9 @@ export function buildBundle( } } } else { - instantiate = `await __inst("${rootName}");\n`; + instantiate = hasTla + ? `await __inst("${rootName}");\n` + : `__inst_s("${rootName}");\n`; } return `${SYSTEM_LOADER}\n${data}\n${instantiate}`; } diff --git a/cli/tests/bundle.test.out b/cli/tests/bundle.test.out index 1379eb7e5..778754c34 100644 --- a/cli/tests/bundle.test.out +++ b/cli/tests/bundle.test.out @@ -1,6 +1,5 @@ [WILDCARD] -let System; -let __inst; +let System, __inst, __inst_s; [WILDCARD] (() => { [WILDCARD] @@ -16,7 +15,7 @@ System.register("mod1", ["subdir2/mod2"], function (exports_3, context_3) { [WILDCARD] }); -const __exp = await __inst("mod1"); +const __exp = __inst_s("mod1"); export const returnsHi = __exp["returnsHi"]; export const returnsFoo2 = __exp["returnsFoo2"]; export const printHello3 = __exp["printHello3"]; diff --git a/deno_typescript/system_loader.js b/deno_typescript/system_loader.js index c1365f6c8..18a08107e 100644 --- a/deno_typescript/system_loader.js +++ b/deno_typescript/system_loader.js @@ -2,20 +2,16 @@ // This is a specialised implementation of a System module loader. -// eslint-disable-next-line @typescript-eslint/no-unused-vars -let System; -let __inst; +// @ts-nocheck +/* eslint-disable */ + +let System, __inst, __inst_s; (() => { const mMap = new Map(); System = { - register(id, deps, f) { - mMap.set(id, { - id, - deps, - f, - exp: {} - }); + register(id, d, f) { + mMap.set(id, { id, d, f, exp: {} }); } }; @@ -28,11 +24,10 @@ let __inst; }; }; - const gE = data => { - const { exp } = data; - return (id, value) => { - const values = typeof id === "string" ? { [id]: value } : id; - for (const [id, value] of Object.entries(values)) { + const gE = ({ exp }) => { + return (id, v) => { + const vs = typeof id === "string" ? { [id]: v } : id; + for (const [id, value] of Object.entries(vs)) { Object.defineProperty(exp, id, { value, writable: true, @@ -47,39 +42,58 @@ let __inst; const enq = ids => { for (const id of ids) { if (!iQ.includes(id)) { - const { deps } = mMap.get(id); + const { d } = mMap.get(id); iQ.push(id); - enq(deps); + enq(d); } } }; - const dr = async main => { + const gRQ = main => { const rQ = []; let id; while ((id = iQ.pop())) { - const m = mMap.get(id); - const { f } = m; - if (!f) { - return; - } - rQ.push([m.deps, f(gE(m), gC(m, id === main))]); - m.f = undefined; + const m = mMap.get(id), + { f } = m; + if (!f) return; + rQ.push([m.d, f(gE(m), gC(m, id === main))]); + delete m.f; } + return rQ; + }; + + const dr = async main => { + const rQ = gRQ(main); let r; while ((r = rQ.shift())) { - const [deps, { execute, setters }] = r; - for (let i = 0; i < deps.length; i++) setters[i](mMap.get(deps[i])?.exp); + const [d, { execute, setters }] = r; + for (let i = 0; i < d.length; i++) setters[i](mMap.get(d[i])?.exp); const e = execute(); if (e) await e; } }; + const dr_s = main => { + const rQ = gRQ(main); + let r; + while ((r = rQ.shift())) { + const [d, { execute, setters }] = r; + for (let i = 0; i < d.length; i++) setters[i](mMap.get(d[i])?.exp); + execute(); + } + }; + __inst = async id => { - System = undefined; - __inst = undefined; + System = __inst = __inst_s = undefined; enq([id]); await dr(id); return mMap.get(id)?.exp; }; + + __inst_s = id => { + System = __inst = __inst_s = undefined; + enq([id]); + dr_s(id); + return mMap.get(id)?.exp; + }; })(); |