Skip to content

Commit

Permalink
Support tranforming import source for wasm to fetch
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Aug 16, 2023
1 parent 8b22e06 commit 3a6e81e
Show file tree
Hide file tree
Showing 29 changed files with 355 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Makefile.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions Makefile.source.mjs
Expand Up @@ -447,14 +447,14 @@ target["bootstrap-flow"] = function () {

target["new-version-checklist"] = function () {
// eslint-disable-next-line no-constant-condition
if (0) {
if (1) {
console.log(
`
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!! !!!!!!
!!!!!! Write any important message here, and change the !!!!!!
!!!!!! if (0) above to if (1) !!!!!!
!!!!!! Set the minimum required core version in the !!!!!!
!!!!!! import source transform to the new minor. !!!!!!
!!!!!! !!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Expand Down
@@ -0,0 +1,3 @@
src
test
*.log
@@ -0,0 +1,19 @@
# @babel/plugin-proposal-import-wasm-source-to-fetch

> Transform source phase imports (`import source ... from '...'`) to `fetch` calls, assuming that the imported source is a WebAssembly module.
See our website [@babel/plugin-proposal-import-wasm-source-to-fetch](https://babeljs.io/docs/babel-plugin-proposal-import-wasm-source-to-fetch) for more information.

## Install

Using npm:

```sh
npm install --save-dev @babel/plugin-proposal-import-wasm-source-to-fetch
```

or using yarn:

```sh
yarn add @babel/plugin-proposal-import-wasm-source-to-fetch --dev
```
@@ -0,0 +1,63 @@
{
"name": "@babel/plugin-proposal-import-wasm-source-to-fetch",
"version": "7.22.5",
"description": "Transform source phase imports (`import source ... from '...'`) to `fetch` calls, assuming that the imported source is a WebAssembly module.",
"repository": {
"type": "git",
"url": "https://github.com/babel/babel.git",
"directory": "packages/babel-plugin-proposal-import-wasm-source-to-fetch"
},
"homepage": "https://babel.dev/docs/en/next/babel-plugin-proposal-import-wasm-source-to-fetch",
"license": "MIT",
"publishConfig": {
"access": "public"
},
"main": "./lib/index.js",
"exports": {
".": "./lib/index.js",
"./package.json": "./package.json"
},
"keywords": [
"babel-plugin",
"import",
"source",
"phase",
"wasm",
"WebAssembly",
"assertions",
"proposal",
"stage-3"
],
"dependencies": {
"@babel/helper-plugin-utils": "workspace:^",
"@babel/plugin-syntax-import-source-phase": "workspace:^"
},
"peerDependencies": {
"@babel/core": "^7.22.0"
},
"devDependencies": {
"@babel/core": "workspace:^",
"@babel/helper-plugin-test-runner": "workspace:^"
},
"engines": {
"node": ">=6.9.0"
},
"author": "The Babel Team (https://babel.dev/team)",
"type": "commonjs",
"conditions": {
"USE_ESM": [
{
"type": "module"
},
null
],
"BABEL_8_BREAKING": [
{
"engines": {
"node": "^16.20.0 || ^18.16.0 || >=20.0.0"
}
},
{}
]
}
}
@@ -0,0 +1,101 @@
import { declare } from "@babel/helper-plugin-utils";
import type { NodePath } from "@babel/traverse";
import type { types as t } from "@babel/core";
import syntaxImportSourcePhase from "@babel/plugin-syntax-import-source-phase";

export default declare(({ assertVersion, types: t, template }) => {
assertVersion(7);

function buildFetch(
path: NodePath<t.ImportDeclaration | t.ImportExpression>,
) {
let specifier = path.node.source;
let specifierRef: t.Expression;
if (t.isStringLiteral(specifier)) {
specifierRef = specifier;
} else {
specifierRef = path.scope.generateDeclaredUidIdentifier("specifier");
specifier = t.assignmentExpression(
"=",
t.cloneNode(specifierRef),
specifier,
);
}

return template.expression.ast`
WebAssembly.compileStreaming(fetch(
import.meta.resolve?.(${specifier}) ??
new URL(${t.cloneNode(specifierRef)}, import.meta.url)
))
`;
}

return {
name: "proposal-import-wasm-source-to-fetch",

inherits: syntaxImportSourcePhase,

visitor: {
Program(path) {
if (path.node.sourceType !== "module") return;

// TS reports that 'Assertions require every name in the call target to be
// declared with an explicit type annotation.' if we just call
// t.assertImportDefaultSpecifier, so we _explicitly_ annotate `t` as
// having type `typeof t`. Unfortunately this is a design limitation of
// the TS type checker, so we need to manually help it:
// https://github.com/microsoft/TypeScript/issues/36931
const t2: typeof t = t;

const ids: t.Identifier[] = [];
const fetches: t.Expression[] = [];
for (const decl of path.get("body")) {
if (!decl.isImportDeclaration({ phase: "source" })) continue;

if (decl.node.attributes?.length || decl.node.assertions?.length) {
throw path.buildCodeFrameError(
"`import source` with import attributes cannot be compiled.",
);
}

const specifier = decl.node.specifiers[0];
t2.assertImportDefaultSpecifier(specifier);
ids.push(specifier.local);
fetches.push(buildFetch(decl));
decl.remove();
}
if (ids.length === 0) return;

let lhs: t.LVal, rhs: t.Expression;
if (ids.length === 1) {
lhs = ids[0];
rhs = fetches[0];
} else {
lhs = t.arrayPattern(ids);
rhs = template.expression.ast`
Promise.all(${t.arrayExpression(fetches)})
`;
}

path.unshiftContainer(
"body",
t.variableDeclaration("const", [
t.variableDeclarator(lhs, t.awaitExpression(rhs)),
]),
);
},

ImportExpression(path) {
if (path.node.phase !== "source") return;

if (path.node.options) {
throw path.buildCodeFrameError(
"`import.source` with an options bag cannot be compiled.",
);
}

path.replaceWith(buildFetch(path));
},
},
};
});
@@ -0,0 +1,3 @@
import source s from "./x.wasm";
someBody;
import source s2 from "./x2.wasm";
@@ -0,0 +1,2 @@
const [s, s2] = await Promise.all([WebAssembly.compileStreaming(fetch(import.meta.resolve?.("./x.wasm") ?? new URL("./x.wasm", import.meta.url))), WebAssembly.compileStreaming(fetch(import.meta.resolve?.("./x2.wasm") ?? new URL("./x2.wasm", import.meta.url)))]);
someBody;
@@ -0,0 +1 @@
import source s from "./x.wasm" assert { some: "attr" };
@@ -0,0 +1,8 @@
{
"sourceType": "module",
"plugins": [
"proposal-import-wasm-source-to-fetch",
"syntax-import-assertions"
],
"throws": "`import source` with import attributes cannot be compiled."
}
@@ -0,0 +1 @@
import source s from "./x.wasm" with { some: "attr" };
@@ -0,0 +1,8 @@
{
"sourceType": "module",
"plugins": [
"proposal-import-wasm-source-to-fetch",
"syntax-import-attributes"
],
"throws": "`import source` with import attributes cannot be compiled."
}
@@ -0,0 +1 @@
import source s from "./x.wasm";
@@ -0,0 +1 @@
const s = await WebAssembly.compileStreaming(fetch(import.meta.resolve?.("./x.wasm") ?? new URL("./x.wasm", import.meta.url)));
@@ -0,0 +1 @@
let promise = import.source(getSpecifier());
@@ -0,0 +1,2 @@
var _specifier;
let promise = WebAssembly.compileStreaming(fetch(import.meta.resolve?.(_specifier = getSpecifier()) ?? new URL(_specifier, import.meta.url)));
@@ -0,0 +1 @@
let promise = import.source("./x.wasm", { with: { some: "attr" }});
@@ -0,0 +1,8 @@
{
"sourceType": "module",
"plugins": [
"proposal-import-wasm-source-to-fetch",
"syntax-import-attributes"
],
"throws": "`import.source` with an options bag cannot be compiled."
}
@@ -0,0 +1 @@
let promise = import.source("./x.wasm");
@@ -0,0 +1 @@
let promise = WebAssembly.compileStreaming(fetch(import.meta.resolve?.("./x.wasm") ?? new URL("./x.wasm", import.meta.url)));
@@ -0,0 +1,4 @@
{
"sourceType": "module",
"plugins": ["proposal-import-wasm-source-to-fetch"]
}
@@ -0,0 +1,3 @@
import runner from "@babel/helper-plugin-test-runner";

runner(import.meta.url);
@@ -0,0 +1 @@
{ "type": "module" }
2 changes: 2 additions & 0 deletions packages/babel-plugin-syntax-import-source-phase/.npmignore
@@ -0,0 +1,2 @@
src
test
19 changes: 19 additions & 0 deletions packages/babel-plugin-syntax-import-source-phase/README.md
@@ -0,0 +1,19 @@
# @babel/plugin-syntax-import-source-phase

> Allow parsing of the `import source` proposal.
See our website [@babel/plugin-syntax-import-source-phase](https://babeljs.io/docs/babel-plugin-syntax-import-source-phase) for more information.

## Install

Using npm:

```sh
npm install --save-dev @babel/plugin-syntax-import-source-phase
```

or using yarn:

```sh
yarn add @babel/plugin-syntax-import-source-phase --dev
```
52 changes: 52 additions & 0 deletions packages/babel-plugin-syntax-import-source-phase/package.json
@@ -0,0 +1,52 @@
{
"name": "@babel/plugin-syntax-import-source-phase",
"version": "7.22.5",
"description": "Allow parsing of the `import source` proposal.",
"repository": {
"type": "git",
"url": "https://github.com/babel/babel.git",
"directory": "packages/babel-plugin-syntax-import-source-phase"
},
"license": "MIT",
"publishConfig": {
"access": "public"
},
"main": "./lib/index.js",
"keywords": [
"babel-plugin"
],
"dependencies": {
"@babel/helper-plugin-utils": "workspace:^"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
},
"devDependencies": {
"@babel/core": "workspace:^"
},
"engines": {
"node": ">=6.9.0"
},
"author": "The Babel Team (https://babel.dev/team)",
"conditions": {
"USE_ESM": [
{
"type": "module"
},
null
],
"BABEL_8_BREAKING": [
{
"engines": {
"node": "^16.20.0 || ^18.16.0 || >=20.0.0"
}
},
{}
]
},
"exports": {
".": "./lib/index.js",
"./package.json": "./package.json"
},
"type": "commonjs"
}
13 changes: 13 additions & 0 deletions packages/babel-plugin-syntax-import-source-phase/src/index.ts
@@ -0,0 +1,13 @@
import { declare } from "@babel/helper-plugin-utils";
export default declare(api => {
api.assertVersion("^7.22.0");

return {
name: "syntax-import-source-phase",

manipulateOptions({ parserOpts }) {
parserOpts.plugins.push("sourcePhaseImports");
parserOpts.createImportExpressions = true;
},
};
});
8 changes: 8 additions & 0 deletions tsconfig.json
Expand Up @@ -51,6 +51,7 @@
"./packages/babel-plugin-proposal-function-bind/src/**/*.ts",
"./packages/babel-plugin-proposal-function-sent/src/**/*.ts",
"./packages/babel-plugin-proposal-import-attributes-to-assertions/src/**/*.ts",
"./packages/babel-plugin-proposal-import-wasm-source-to-fetch/src/**/*.ts",
"./packages/babel-plugin-proposal-partial-application/src/**/*.ts",
"./packages/babel-plugin-proposal-pipeline-operator/src/**/*.ts",
"./packages/babel-plugin-proposal-record-and-tuple/src/**/*.ts",
Expand All @@ -69,6 +70,7 @@
"./packages/babel-plugin-syntax-import-assertions/src/**/*.ts",
"./packages/babel-plugin-syntax-import-attributes/src/**/*.ts",
"./packages/babel-plugin-syntax-import-reflection/src/**/*.ts",
"./packages/babel-plugin-syntax-import-source-phase/src/**/*.ts",
"./packages/babel-plugin-syntax-jsx/src/**/*.ts",
"./packages/babel-plugin-syntax-module-blocks/src/**/*.ts",
"./packages/babel-plugin-syntax-partial-application/src/**/*.ts",
Expand Down Expand Up @@ -323,6 +325,9 @@
"@babel/plugin-proposal-import-attributes-to-assertions": [
"./packages/babel-plugin-proposal-import-attributes-to-assertions/src"
],
"@babel/plugin-proposal-import-wasm-source-to-fetch": [
"./packages/babel-plugin-proposal-import-wasm-source-to-fetch/src"
],
"@babel/plugin-proposal-partial-application": [
"./packages/babel-plugin-proposal-partial-application/src"
],
Expand Down Expand Up @@ -377,6 +382,9 @@
"@babel/plugin-syntax-import-reflection": [
"./packages/babel-plugin-syntax-import-reflection/src"
],
"@babel/plugin-syntax-import-source-phase": [
"./packages/babel-plugin-syntax-import-source-phase/src"
],
"@babel/plugin-syntax-jsx": [
"./packages/babel-plugin-syntax-jsx/src"
],
Expand Down

0 comments on commit 3a6e81e

Please sign in to comment.