summaryrefslogtreecommitdiff
path: root/deno_typescript
diff options
context:
space:
mode:
authorKitson Kelly <me@kitsonkelly.com>2020-02-13 08:41:51 +1100
committerGitHub <noreply@github.com>2020-02-12 16:41:51 -0500
commit6bd846a780bec8a60d0a251ed1fb43e3add81be5 (patch)
tree315452f40fc2b92c1f9f8ab9b860d4747fb4e0e0 /deno_typescript
parent3563ab4c53689480ac47871fe928ae7c78a2fcc3 (diff)
Improvements to bundling. (#3965)
Moves to using a minimal System loader for bundles generated by Deno. TypeScript in 3.8 will be able to output TLA for modules, and the loader is written to take advantage of that as soon as we update Deno to TS 3.8. System also allows us to support `import.meta` and provide more ESM aligned assignment of exports, as well as there is better handling of circular imports. The loader is also very terse versus to try to save overhead. Also, fixed an issue where abstract classes were not being re-exported. Fixes #2553 Fixes #3559 Fixes #3751 Fixes #3825 Refs #3301
Diffstat (limited to 'deno_typescript')
-rw-r--r--deno_typescript/lib.rs2
-rw-r--r--deno_typescript/system_loader.js85
2 files changed, 86 insertions, 1 deletions
diff --git a/deno_typescript/lib.rs b/deno_typescript/lib.rs
index 7977b7cfe..9056fd903 100644
--- a/deno_typescript/lib.rs
+++ b/deno_typescript/lib.rs
@@ -245,7 +245,7 @@ pub fn get_asset(name: &str) -> Option<&'static str> {
};
}
match name {
- "bundle_loader.js" => Some(include_str!("bundle_loader.js")),
+ "system_loader.js" => Some(include_str!("system_loader.js")),
"bootstrap.ts" => Some("console.log(\"hello deno\");"),
"typescript.d.ts" => inc!("typescript.d.ts"),
"lib.esnext.d.ts" => inc!("lib.esnext.d.ts"),
diff --git a/deno_typescript/system_loader.js b/deno_typescript/system_loader.js
new file mode 100644
index 000000000..c1365f6c8
--- /dev/null
+++ b/deno_typescript/system_loader.js
@@ -0,0 +1,85 @@
+// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+
+// This is a specialised implementation of a System module loader.
+
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+let System;
+let __inst;
+
+(() => {
+ const mMap = new Map();
+ System = {
+ register(id, deps, f) {
+ mMap.set(id, {
+ id,
+ deps,
+ f,
+ exp: {}
+ });
+ }
+ };
+
+ const gC = (data, main) => {
+ const { id } = data;
+ return {
+ id,
+ import: async id => mMap.get(id)?.exp,
+ meta: { url: id, main }
+ };
+ };
+
+ 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)) {
+ Object.defineProperty(exp, id, {
+ value,
+ writable: true,
+ enumerable: true
+ });
+ }
+ };
+ };
+
+ const iQ = [];
+
+ const enq = ids => {
+ for (const id of ids) {
+ if (!iQ.includes(id)) {
+ const { deps } = mMap.get(id);
+ iQ.push(id);
+ enq(deps);
+ }
+ }
+ };
+
+ const dr = async 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;
+ }
+ 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 e = execute();
+ if (e) await e;
+ }
+ };
+
+ __inst = async id => {
+ System = undefined;
+ __inst = undefined;
+ enq([id]);
+ await dr(id);
+ return mMap.get(id)?.exp;
+ };
+})();