diff --git a/.eslintrc.js b/.eslintrc.js index 1b86de1dfb..2f5dadc521 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -92,10 +92,12 @@ module.exports = { "bin/*" ], rules: { - // Node's support for ESM is still not great, but this rule is likely - // to become activated once compatibility doesn't suck anymore. + // We are testing both ESM and UMD, so don't limit us. "@typescript-eslint/no-var-requires": "off", + // This rule does not behave well in JS files. + "@typescript-eslint/explicit-module-boundary-types": "off", + // Enforcing to remove function parameters on stubs makes code less // maintainable, so we instead allow unused function parameters. "no-unused-vars": [ diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e4fcbf64ba..ad09b0cc7b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -33,6 +33,7 @@ jobs: node node_modules/semantic-release/bin/semantic-release.js --unstable cd lib/loader if [ $(node -pe "require('./package.json').version") != "0.0.0" ]; then + npm run build npm config set "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" npm publish --access public fi diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1b494574a8..79a33151ed 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -53,21 +53,11 @@ jobs: - name: Check sources run: npm run check - name: Test sources - run: | - if [[ `node bin/asc --version` != *"-dev" ]]; then - echo "ERROR: Not testing sources" - exit 1 - fi - npm test + run: npm test - name: Build distribution files run: npm run build - name: Test distribution - run: | - if [[ `node bin/asc --version` == *"-dev" ]]; then - echo "ERROR: Not testing distribution" - exit 1 - fi - npm test + run: npm test - name: Test browser build run: node tests/browser-asc test-windows: diff --git a/cli/asc.js b/cli/asc.js index 65a095c66e..93f6270257 100644 --- a/cli/asc.js +++ b/cli/asc.js @@ -22,7 +22,7 @@ * * Uses the low-level API exported from src/index.ts so it works with the compiler compiled to * JavaScript as well as the compiler compiled to WebAssembly (eventually). Runs the sources - * directly through ts-node if distribution files are not present (indicated by a `-dev` version). + * directly through ts-node if distribution files are not present. * * Can also be packaged as a bundle suitable for in-browser use with the standard library injected * in the build step. See dist/asc.js for the bundle and webpack.config.js for building details. @@ -75,15 +75,16 @@ if (process.removeAllListeners) process.removeAllListeners("uncaughtException"); // Use distribution files if present, otherwise run the sources directly. var assemblyscript; -var isDev = false; (function loadAssemblyScript() { try { + // note that this case will always trigger in recent node.js versions for typical installs + // see: https://nodejs.org/api/packages.html#packages_self_referencing_a_package_using_its_name assemblyscript = require("assemblyscript"); } catch (e) { - try { // `asc` on the command line + try { // `asc` on the command line (unnecessary in recent node) assemblyscript = dynrequire("../dist/assemblyscript.js"); } catch (e) { - try { // `asc` on the command line without dist files + try { // `asc` on the command line without dist files (unnecessary in recent node) dynrequire("ts-node").register({ project: path.join(__dirname, "..", "src", "tsconfig.json"), skipIgnore: true, @@ -91,7 +92,6 @@ var isDev = false; }); dynrequire("../src/glue/js"); assemblyscript = dynrequire("../src"); - isDev = true; } catch (e_ts) { try { // `require("dist/asc.js")` in explicit browser tests assemblyscript = dynrequire("./assemblyscript"); @@ -106,9 +106,6 @@ var isDev = false; /** Whether this is a webpack bundle or not. */ exports.isBundle = typeof BUNDLE_VERSION === "string"; -/** Whether asc runs the sources directly or not. */ -exports.isDev = isDev; - /** AssemblyScript version. */ exports.version = exports.isBundle ? BUNDLE_VERSION : dynrequire("../package.json").version; @@ -241,7 +238,7 @@ exports.main = function main(argv, options, callback) { // Just print the version if requested if (opts.version) { - stdout.write("Version " + exports.version + (isDev ? "-dev" : "") + EOL); + stdout.write("Version " + exports.version + EOL); return callback(null); } diff --git a/lib/loader/index.js b/lib/loader/index.js index d49733c39a..22ab72d155 100644 --- a/lib/loader/index.js +++ b/lib/loader/index.js @@ -1,5 +1,3 @@ -"use strict"; - // Runtime header offsets const ID_OFFSET = -8; const SIZE_OFFSET = -4; @@ -297,7 +295,7 @@ function isModule(src) { } /** Asynchronously instantiates an AssemblyScript module from anything that can be instantiated. */ -async function instantiate(source, imports = {}) { +export async function instantiate(source, imports = {}) { if (isResponse(source = await source)) return instantiateStreaming(source, imports); const module = isModule(source) ? source : await WebAssembly.compile(source); const extended = preInstantiate(imports); @@ -306,10 +304,8 @@ async function instantiate(source, imports = {}) { return { module, instance, exports }; } -exports.instantiate = instantiate; - /** Synchronously instantiates an AssemblyScript module from a WebAssembly.Module or binary buffer. */ -function instantiateSync(source, imports = {}) { +export function instantiateSync(source, imports = {}) { const module = isModule(source) ? source : new WebAssembly.Module(source); const extended = preInstantiate(imports); const instance = new WebAssembly.Instance(module, imports); @@ -317,10 +313,8 @@ function instantiateSync(source, imports = {}) { return { module, instance, exports }; } -exports.instantiateSync = instantiateSync; - /** Asynchronously instantiates an AssemblyScript module from a response, i.e. as obtained by `fetch`. */ -async function instantiateStreaming(source, imports = {}) { +export async function instantiateStreaming(source, imports = {}) { if (!WebAssembly.instantiateStreaming) { return instantiate( isResponse(source = await source) @@ -335,10 +329,8 @@ async function instantiateStreaming(source, imports = {}) { return { ...result, exports }; } -exports.instantiateStreaming = instantiateStreaming; - /** Demangles an AssemblyScript module's exports to a friendly object structure. */ -function demangle(exports, extendedExports = {}) { +export function demangle(exports, extendedExports = {}) { extendedExports = Object.create(extendedExports); const setArgumentsLength = exports["__argumentsLength"] ? length => { exports["__argumentsLength"].value = length; } @@ -420,4 +412,9 @@ function demangle(exports, extendedExports = {}) { return extendedExports; } -exports.demangle = demangle; +export default { + instantiate, + instantiateSync, + instantiateStreaming, + demangle +}; diff --git a/lib/loader/package.json b/lib/loader/package.json index 09449c325d..41c29ba5fa 100644 --- a/lib/loader/package.json +++ b/lib/loader/package.json @@ -21,18 +21,27 @@ "bugs": { "url": "https://github.com/AssemblyScript/assemblyscript/issues" }, + "type": "module", "main": "index.js", "types": "index.d.ts", + "exports": { + "import": "./index.js", + "require": "./umd/index.js" + }, "scripts": { "asbuild": "npm run asbuild:default && npm run asbuild:legacy", "asbuild:default": "node ../../bin/asc tests/assembly/index.ts -b tests/build/default.wasm", "asbuild:legacy": "node ../../bin/asc tests/assembly/index.ts --disable mutable-globals -b tests/build/legacy.wasm", - "test": "node tests" + "build": "npx esm2umd loader index.js > umd/index.js", + "test": "node tests && node tests/umd" }, "files": [ "index.d.ts", "index.js", "package.json", + "umd/index.d.ts", + "umd/index.js", + "umd/package.json", "README.md" ] } \ No newline at end of file diff --git a/lib/loader/tests/index.js b/lib/loader/tests/index.js index 5ed603e28a..4164fab2a7 100644 --- a/lib/loader/tests/index.js +++ b/lib/loader/tests/index.js @@ -1,8 +1,12 @@ -var fs = require("fs"); -var assert = require("assert"); -var inspect = require("util").inspect; - -var loader = require(".."); +import fs from "fs"; +import assert from "assert"; +import { inspect } from "util"; +import loader from "../index.js"; +import { dirname } from "path"; +import { fileURLToPath } from "url"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); test("default.wasm"); test("legacy.wasm"); diff --git a/lib/loader/tests/umd/index.js b/lib/loader/tests/umd/index.js new file mode 100644 index 0000000000..accb854ec3 --- /dev/null +++ b/lib/loader/tests/umd/index.js @@ -0,0 +1,4 @@ +const assert = require("assert"); +const loader = require("../../umd"); + +assert(typeof loader.instantiate === "function"); diff --git a/lib/loader/tests/umd/package.json b/lib/loader/tests/umd/package.json new file mode 100644 index 0000000000..5bbefffbab --- /dev/null +++ b/lib/loader/tests/umd/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/lib/loader/umd/index.d.ts b/lib/loader/umd/index.d.ts new file mode 100644 index 0000000000..a940eccbc8 --- /dev/null +++ b/lib/loader/umd/index.d.ts @@ -0,0 +1 @@ +export * from ".."; diff --git a/lib/loader/umd/index.js b/lib/loader/umd/index.js new file mode 100644 index 0000000000..27b42fe9ab --- /dev/null +++ b/lib/loader/umd/index.js @@ -0,0 +1,492 @@ +// GENERATED FILE. DO NOT EDIT. +var loader = (function(exports) { + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.instantiate = instantiate; + exports.instantiateSync = instantiateSync; + exports.instantiateStreaming = instantiateStreaming; + exports.demangle = demangle; + exports.default = void 0; + // Runtime header offsets + const ID_OFFSET = -8; + const SIZE_OFFSET = -4; // Runtime ids + + const ARRAYBUFFER_ID = 0; + const STRING_ID = 1; // const ARRAYBUFFERVIEW_ID = 2; + // Runtime type information + + const ARRAYBUFFERVIEW = 1 << 0; + const ARRAY = 1 << 1; + const STATICARRAY = 1 << 2; // const SET = 1 << 3; + // const MAP = 1 << 4; + + const VAL_ALIGN_OFFSET = 6; // const VAL_ALIGN = 1 << VAL_ALIGN_OFFSET; + + const VAL_SIGNED = 1 << 11; + const VAL_FLOAT = 1 << 12; // const VAL_NULLABLE = 1 << 13; + + const VAL_MANAGED = 1 << 14; // const KEY_ALIGN_OFFSET = 15; + // const KEY_ALIGN = 1 << KEY_ALIGN_OFFSET; + // const KEY_SIGNED = 1 << 20; + // const KEY_FLOAT = 1 << 21; + // const KEY_NULLABLE = 1 << 22; + // const KEY_MANAGED = 1 << 23; + // Array(BufferView) layout + + const ARRAYBUFFERVIEW_BUFFER_OFFSET = 0; + const ARRAYBUFFERVIEW_DATASTART_OFFSET = 4; + const ARRAYBUFFERVIEW_DATALENGTH_OFFSET = 8; + const ARRAYBUFFERVIEW_SIZE = 12; + const ARRAY_LENGTH_OFFSET = 12; + const ARRAY_SIZE = 16; + const BIGINT = typeof BigUint64Array !== "undefined"; + const THIS = Symbol(); + const STRING_DECODE_THRESHOLD = 32; + const decoder = new TextDecoder("utf-16le"); + /** Gets a string from an U32 and an U16 view on a memory. */ + + function getStringImpl(buffer, ptr) { + const len = new Uint32Array(buffer)[ptr + SIZE_OFFSET >>> 2] >>> 1; + const arr = new Uint16Array(buffer, ptr, len); + + if (len <= STRING_DECODE_THRESHOLD) { + return String.fromCharCode.apply(String, arr); + } + + return decoder.decode(arr); + } + /** Prepares the base module prior to instantiation. */ + + + function preInstantiate(imports) { + const extendedExports = {}; + + function getString(memory, ptr) { + if (!memory) return ""; + return getStringImpl(memory.buffer, ptr); + } // add common imports used by stdlib for convenience + + + const env = imports.env = imports.env || {}; + + env.abort = env.abort || function abort(msg, file, line, colm) { + const memory = extendedExports.memory || env.memory; // prefer exported, otherwise try imported + + throw Error(`abort: ${getString(memory, msg)} at ${getString(memory, file)}:${line}:${colm}`); + }; + + env.trace = env.trace || function trace(msg, n, ...args) { + const memory = extendedExports.memory || env.memory; + console.log(`trace: ${getString(memory, msg)}${n ? " " : ""}${args.slice(0, n).join(", ")}`); + }; + + env.seed = env.seed || Date.now; + imports.Math = imports.Math || Math; + imports.Date = imports.Date || Date; + return extendedExports; + } + /** Prepares the final module once instantiation is complete. */ + + + function postInstantiate(extendedExports, instance) { + const exports = instance.exports; + const memory = exports.memory; + const table = exports.table; + const alloc = exports["__alloc"]; + const retain = exports["__retain"]; + const rttiBase = exports["__rtti_base"] || ~0; // oob if not present + + /** Gets the runtime type info for the given id. */ + + function getInfo(id) { + const U32 = new Uint32Array(memory.buffer); + const count = U32[rttiBase >>> 2]; + if ((id >>>= 0) >= count) throw Error(`invalid id: ${id}`); + return U32[(rttiBase + 4 >>> 2) + id * 2]; + } + /** Gets and validate runtime type info for the given id for array like objects */ + + + function getArrayInfo(id) { + const info = getInfo(id); + if (!(info & (ARRAYBUFFERVIEW | ARRAY | STATICARRAY))) throw Error(`not an array: ${id}, flags=${info}`); + return info; + } + /** Gets the runtime base id for the given id. */ + + + function getBase(id) { + const U32 = new Uint32Array(memory.buffer); + const count = U32[rttiBase >>> 2]; + if ((id >>>= 0) >= count) throw Error(`invalid id: ${id}`); + return U32[(rttiBase + 4 >>> 2) + id * 2 + 1]; + } + /** Gets the runtime alignment of a collection's values. */ + + + function getValueAlign(info) { + return 31 - Math.clz32(info >>> VAL_ALIGN_OFFSET & 31); // -1 if none + } + /** Gets the runtime alignment of a collection's keys. */ + // function getKeyAlign(info) { + // return 31 - Math.clz32((info >>> KEY_ALIGN_OFFSET) & 31); // -1 if none + // } + + /** Allocates a new string in the module's memory and returns its retained pointer. */ + + + function __allocString(str) { + const length = str.length; + const ptr = alloc(length << 1, STRING_ID); + const U16 = new Uint16Array(memory.buffer); + + for (var i = 0, p = ptr >>> 1; i < length; ++i) U16[p + i] = str.charCodeAt(i); + + return ptr; + } + + extendedExports.__allocString = __allocString; + /** Reads a string from the module's memory by its pointer. */ + + function __getString(ptr) { + const buffer = memory.buffer; + const id = new Uint32Array(buffer)[ptr + ID_OFFSET >>> 2]; + if (id !== STRING_ID) throw Error(`not a string: ${ptr}`); + return getStringImpl(buffer, ptr); + } + + extendedExports.__getString = __getString; + /** Gets the view matching the specified alignment, signedness and floatness. */ + + function getView(alignLog2, signed, float) { + const buffer = memory.buffer; + + if (float) { + switch (alignLog2) { + case 2: + return new Float32Array(buffer); + + case 3: + return new Float64Array(buffer); + } + } else { + switch (alignLog2) { + case 0: + return new (signed ? Int8Array : Uint8Array)(buffer); + + case 1: + return new (signed ? Int16Array : Uint16Array)(buffer); + + case 2: + return new (signed ? Int32Array : Uint32Array)(buffer); + + case 3: + return new (signed ? BigInt64Array : BigUint64Array)(buffer); + } + } + + throw Error(`unsupported align: ${alignLog2}`); + } + /** Allocates a new array in the module's memory and returns its retained pointer. */ + + + function __allocArray(id, values) { + const info = getArrayInfo(id); + const align = getValueAlign(info); + const length = values.length; + const buf = alloc(length << align, info & STATICARRAY ? id : ARRAYBUFFER_ID); + let result; + + if (info & STATICARRAY) { + result = buf; + } else { + const arr = alloc(info & ARRAY ? ARRAY_SIZE : ARRAYBUFFERVIEW_SIZE, id); + const U32 = new Uint32Array(memory.buffer); + U32[arr + ARRAYBUFFERVIEW_BUFFER_OFFSET >>> 2] = retain(buf); + U32[arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2] = buf; + U32[arr + ARRAYBUFFERVIEW_DATALENGTH_OFFSET >>> 2] = length << align; + if (info & ARRAY) U32[arr + ARRAY_LENGTH_OFFSET >>> 2] = length; + result = arr; + } + + const view = getView(align, info & VAL_SIGNED, info & VAL_FLOAT); + + if (info & VAL_MANAGED) { + for (let i = 0; i < length; ++i) view[(buf >>> align) + i] = retain(values[i]); + } else { + view.set(values, buf >>> align); + } + + return result; + } + + extendedExports.__allocArray = __allocArray; + /** Gets a live view on an array's values in the module's memory. Infers the array type from RTTI. */ + + function __getArrayView(arr) { + const U32 = new Uint32Array(memory.buffer); + const id = U32[arr + ID_OFFSET >>> 2]; + const info = getArrayInfo(id); + const align = getValueAlign(info); + let buf = info & STATICARRAY ? arr : U32[arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2]; + const length = info & ARRAY ? U32[arr + ARRAY_LENGTH_OFFSET >>> 2] : U32[buf + SIZE_OFFSET >>> 2] >>> align; + return getView(align, info & VAL_SIGNED, info & VAL_FLOAT).subarray(buf >>>= align, buf + length); + } + + extendedExports.__getArrayView = __getArrayView; + /** Copies an array's values from the module's memory. Infers the array type from RTTI. */ + + function __getArray(arr) { + const input = __getArrayView(arr); + + const len = input.length; + const out = new Array(len); + + for (let i = 0; i < len; i++) out[i] = input[i]; + + return out; + } + + extendedExports.__getArray = __getArray; + /** Copies an ArrayBuffer's value from the module's memory. */ + + function __getArrayBuffer(ptr) { + const buffer = memory.buffer; + const length = new Uint32Array(buffer)[ptr + SIZE_OFFSET >>> 2]; + return buffer.slice(ptr, ptr + length); + } + + extendedExports.__getArrayBuffer = __getArrayBuffer; + /** Copies a typed array's values from the module's memory. */ + + function getTypedArray(Type, alignLog2, ptr) { + return new Type(getTypedArrayView(Type, alignLog2, ptr)); + } + /** Gets a live view on a typed array's values in the module's memory. */ + + + function getTypedArrayView(Type, alignLog2, ptr) { + const buffer = memory.buffer; + const U32 = new Uint32Array(buffer); + const bufPtr = U32[ptr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2]; + return new Type(buffer, bufPtr, U32[bufPtr + SIZE_OFFSET >>> 2] >>> alignLog2); + } + /** Attach a set of get TypedArray and View functions to the exports. */ + + + function attachTypedArrayFunctions(ctor, name, align) { + extendedExports[`__get${name}`] = getTypedArray.bind(null, ctor, align); + extendedExports[`__get${name}View`] = getTypedArrayView.bind(null, ctor, align); + } + + [Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array].forEach(ctor => { + attachTypedArrayFunctions(ctor, ctor.name, 31 - Math.clz32(ctor.BYTES_PER_ELEMENT)); + }); + + if (BIGINT) { + [BigUint64Array, BigInt64Array].forEach(ctor => { + attachTypedArrayFunctions(ctor, ctor.name.slice(3), 3); + }); + } + /** Tests whether an object is an instance of the class represented by the specified base id. */ + + + function __instanceof(ptr, baseId) { + const U32 = new Uint32Array(memory.buffer); + let id = U32[ptr + ID_OFFSET >>> 2]; + + if (id <= U32[rttiBase >>> 2]) { + do { + if (id == baseId) return true; + id = getBase(id); + } while (id); + } + + return false; + } + + extendedExports.__instanceof = __instanceof; // Pull basic exports to extendedExports so code in preInstantiate can use them + + extendedExports.memory = extendedExports.memory || memory; + extendedExports.table = extendedExports.table || table; // Demangle exports and provide the usual utility on the prototype + + return demangle(exports, extendedExports); + } + + function isResponse(src) { + return typeof Response !== "undefined" && src instanceof Response; + } + + function isModule(src) { + return src instanceof WebAssembly.Module; + } + /** Asynchronously instantiates an AssemblyScript module from anything that can be instantiated. */ + + + async function instantiate(source, imports = {}) { + if (isResponse(source = await source)) return instantiateStreaming(source, imports); + const module = isModule(source) ? source : await WebAssembly.compile(source); + const extended = preInstantiate(imports); + const instance = await WebAssembly.instantiate(module, imports); + const exports = postInstantiate(extended, instance); + return { + module, + instance, + exports + }; + } + /** Synchronously instantiates an AssemblyScript module from a WebAssembly.Module or binary buffer. */ + + + function instantiateSync(source, imports = {}) { + const module = isModule(source) ? source : new WebAssembly.Module(source); + const extended = preInstantiate(imports); + const instance = new WebAssembly.Instance(module, imports); + const exports = postInstantiate(extended, instance); + return { + module, + instance, + exports + }; + } + /** Asynchronously instantiates an AssemblyScript module from a response, i.e. as obtained by `fetch`. */ + + + async function instantiateStreaming(source, imports = {}) { + if (!WebAssembly.instantiateStreaming) { + return instantiate(isResponse(source = await source) ? source.arrayBuffer() : source, imports); + } + + const extended = preInstantiate(imports); + const result = await WebAssembly.instantiateStreaming(source, imports); + const exports = postInstantiate(extended, result.instance); + return { ...result, + exports + }; + } + /** Demangles an AssemblyScript module's exports to a friendly object structure. */ + + + function demangle(exports, extendedExports = {}) { + extendedExports = Object.create(extendedExports); + const setArgumentsLength = exports["__argumentsLength"] ? length => { + exports["__argumentsLength"].value = length; + } : exports["__setArgumentsLength"] || exports["__setargc"] || (() => { + /* nop */ + }); + + for (let internalName in exports) { + if (!Object.prototype.hasOwnProperty.call(exports, internalName)) continue; + const elem = exports[internalName]; + let parts = internalName.split("."); + let curr = extendedExports; + + while (parts.length > 1) { + let part = parts.shift(); + if (!Object.prototype.hasOwnProperty.call(curr, part)) curr[part] = {}; + curr = curr[part]; + } + + let name = parts[0]; + let hash = name.indexOf("#"); + + if (hash >= 0) { + const className = name.substring(0, hash); + const classElem = curr[className]; + + if (typeof classElem === "undefined" || !classElem.prototype) { + const ctor = function (...args) { + return ctor.wrap(ctor.prototype.constructor(0, ...args)); + }; + + ctor.prototype = { + valueOf() { + return this[THIS]; + } + + }; + + ctor.wrap = function (thisValue) { + return Object.create(ctor.prototype, { + [THIS]: { + value: thisValue, + writable: false + } + }); + }; + + if (classElem) Object.getOwnPropertyNames(classElem).forEach(name => Object.defineProperty(ctor, name, Object.getOwnPropertyDescriptor(classElem, name))); + curr[className] = ctor; + } + + name = name.substring(hash + 1); + curr = curr[className].prototype; + + if (/^(get|set):/.test(name)) { + if (!Object.prototype.hasOwnProperty.call(curr, name = name.substring(4))) { + let getter = exports[internalName.replace("set:", "get:")]; + let setter = exports[internalName.replace("get:", "set:")]; + Object.defineProperty(curr, name, { + get() { + return getter(this[THIS]); + }, + + set(value) { + setter(this[THIS], value); + }, + + enumerable: true + }); + } + } else { + if (name === 'constructor') { + (curr[name] = (...args) => { + setArgumentsLength(args.length); + return elem(...args); + }).original = elem; + } else { + // instance method + (curr[name] = function (...args) { + // ! + setArgumentsLength(args.length); + return elem(this[THIS], ...args); + }).original = elem; + } + } + } else { + if (/^(get|set):/.test(name)) { + if (!Object.prototype.hasOwnProperty.call(curr, name = name.substring(4))) { + Object.defineProperty(curr, name, { + get: exports[internalName.replace("set:", "get:")], + set: exports[internalName.replace("get:", "set:")], + enumerable: true + }); + } + } else if (typeof elem === "function" && elem !== setArgumentsLength) { + (curr[name] = (...args) => { + setArgumentsLength(args.length); + return elem(...args); + }).original = elem; + } else { + curr[name] = elem; + } + } + } + + return extendedExports; + } + + var _default = { + instantiate, + instantiateSync, + instantiateStreaming, + demangle + }; + exports.default = _default; + return exports; +})({}); +if (typeof define === 'function' && define.amd) define([], function() { return loader; }); +else if (typeof module === 'object' && typeof exports==='object') module.exports = loader; diff --git a/lib/loader/umd/package.json b/lib/loader/umd/package.json new file mode 100644 index 0000000000..0fef86e339 --- /dev/null +++ b/lib/loader/umd/package.json @@ -0,0 +1,4 @@ +{ + "private": true, + "type": "commonjs" +} diff --git a/package.json b/package.json index 725a064f26..8b67b28e37 100644 --- a/package.json +++ b/package.json @@ -42,8 +42,16 @@ "webpack": "^4.44.1", "webpack-cli": "^3.3.12" }, + "type": "commonjs", "main": "index.js", "types": "index.d.ts", + "exports": { + ".": "./index.js", + "./lib/loader": { + "import": "./lib/loader/index.js", + "require": "./lib/loader/umd/index.js" + } + }, "bin": { "asc": "bin/asc", "asinit": "bin/asinit" @@ -83,6 +91,10 @@ "lib/rtrace/package.json", "lib/loader/index.d.ts", "lib/loader/index.js", + "lib/loader/package.json", + "lib/loader/umd/index.d.ts", + "lib/loader/umd/index.js", + "lib/loader/umd/package.json", "lib/loader/README.md", "bin/", "cli/", diff --git a/tests/asconfig/index.js b/tests/asconfig/index.js index 6b491ec5ee..b323e34b96 100644 --- a/tests/asconfig/index.js +++ b/tests/asconfig/index.js @@ -1,5 +1,5 @@ const asc = require("../../cli/asc"); -const loader = require("../../lib/loader"); +const loader = require("../../lib/loader/umd"); const args = process.argv.slice(2); const path = require('path'); const fs = require("fs"); diff --git a/tests/bootstrap/index.ts b/tests/bootstrap/index.ts index d0f23f8acb..c5c0070f20 100644 --- a/tests/bootstrap/index.ts +++ b/tests/bootstrap/index.ts @@ -2,7 +2,7 @@ import * as fs from "fs"; import * as path from "path"; import * as v8 from "v8"; import * as binaryen from "binaryen"; -import * as loader from "../../lib/loader"; +import * as loader from "../../lib/loader/umd"; import { Rtrace } from "../../lib/rtrace"; import * as find from "../../cli/util/find"; import AssemblyScript from "../../out/assemblyscript"; diff --git a/tests/bootstrap/package.json b/tests/bootstrap/package.json new file mode 100644 index 0000000000..31f6a4909a --- /dev/null +++ b/tests/bootstrap/package.json @@ -0,0 +1,4 @@ +{ + "private": true, + "type": "commonjs" +} \ No newline at end of file