Skip to content

Commit

Permalink
Annotate scripts in _node, _npm, and _jsr
Browse files Browse the repository at this point in the history
  • Loading branch information
Fil committed Oct 21, 2024
1 parent 7c96c68 commit e0bc373
Show file tree
Hide file tree
Showing 25 changed files with 48 additions and 45 deletions.
4 changes: 2 additions & 2 deletions src/javascript/transpile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ function rewriteImportDeclarations(
for (const node of declarations) {
output.delete(node.start, node.end + +(output.input[node.end] === "\n"));
specifiers.push(rewriteImportSpecifiers(node));
imports.push(`import(${JSON.stringify(resolve(getStringLiteralValue(node.source as StringLiteral)))})`);
imports.push(`import(${annotatePath(resolve(getStringLiteralValue(node.source as StringLiteral)))})`);
}
if (declarations.length > 1) {
output.insertLeft(0, `const [${specifiers.join(", ")}] = await Promise.all([${imports.join(", ")}]);\n`);
Expand Down Expand Up @@ -261,6 +261,6 @@ export function rewriteParams(output: Sourcemap, body: Node, params: Params, inp
/**
* Annotate a path to a local import or file so it can be reworked server-side.
*/
function annotatePath(uri: string): string {
export function annotatePath(uri: string): string {
return `${JSON.stringify(uri)}${isPathImport(uri) ? "/* observablehq-file */" : ""}`;
}
3 changes: 2 additions & 1 deletion src/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import esbuild from "rollup-plugin-esbuild";
import {prepareOutput, toOsPath} from "./files.js";
import type {ImportReference} from "./javascript/imports.js";
import {isJavaScript, parseImports} from "./javascript/imports.js";
import {annotatePath} from "./javascript/transpile.js";
import {parseNpmSpecifier, rewriteNpmImports} from "./npm.js";
import {isPathImport, relativePath} from "./path.js";
import {faint} from "./tty.js";
Expand Down Expand Up @@ -86,7 +87,7 @@ function isBadCommonJs(specifier: string): boolean {
}

function shimCommonJs(specifier: string, require: NodeRequire): string {
return `export {${Object.keys(require(specifier))}} from ${JSON.stringify(specifier)};\n`;
return `export {${Object.keys(require(specifier))}} from ${annotatePath(specifier)};\n`;
}

async function bundle(
Expand Down
3 changes: 2 additions & 1 deletion src/npm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {isImportMetaResolve, parseImports} from "./javascript/imports.js";
import {parseProgram} from "./javascript/parse.js";
import type {StringLiteral} from "./javascript/source.js";
import {getStringLiteralValue, isStringLiteral} from "./javascript/source.js";
import {annotatePath} from "./javascript/transpile.js";
import {relativePath} from "./path.js";
import {Sourcemap} from "./sourcemap.js";
import {faint, yellow} from "./tty.js";
Expand Down Expand Up @@ -64,7 +65,7 @@ export function rewriteNpmImports(input: string, resolve: (s: string) => string
const value = getStringLiteralValue(source);
const resolved = resolve(value);
if (resolved === undefined || value === resolved) return;
output.replaceLeft(source.start, source.end, JSON.stringify(resolved));
output.replaceLeft(source.start, source.end, annotatePath(resolved));
}

// TODO Preserve the source map, but download it too.
Expand Down
3 changes: 2 additions & 1 deletion src/rollup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import esbuild from "rollup-plugin-esbuild";
import {getClientPath, getStylePath} from "./files.js";
import type {StringLiteral} from "./javascript/source.js";
import {getStringLiteralValue, isStringLiteral} from "./javascript/source.js";
import {annotatePath} from "./javascript/transpile.js";
import {resolveNpmImport} from "./npm.js";
import {getObservableUiOrigin} from "./observableApiClient.js";
import {isAssetPath, isPathImport, relativePath} from "./path.js";
Expand Down Expand Up @@ -177,7 +178,7 @@ function importMetaResolve(path: string, resolveImport: ImportResolver): Plugin
for (const source of resolves) {
const specifier = getStringLiteralValue(source);
const resolution = await resolveImport(specifier);
if (resolution) output.replaceLeft(source.start, source.end, JSON.stringify(relativePath(path, resolution)));
if (resolution) output.replaceLeft(source.start, source.end, annotatePath(relativePath(path, resolution)));
}

return {code: String(output)};
Expand Down
30 changes: 15 additions & 15 deletions test/npm-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,37 +103,37 @@ describe("fromJsDelivrPath(path)", () => {
// prettier-ignore
describe("rewriteNpmImports(input, resolve)", () => {
it("rewrites /npm/ imports to /_npm/", () => {
assert.strictEqual(rewriteNpmImports('export * from "/npm/[email protected]/dist/d3-array.js";\n', (v) => resolve("/_npm/[email protected]/dist/d3.js", v)), 'export * from "../../[email protected]/dist/d3-array.js";\n');
assert.strictEqual(rewriteNpmImports('export * from "/npm/[email protected]/dist/d3-array.js";\n', (v) => resolve("/_npm/[email protected]/dist/d3.js", v)), 'export * from "../../[email protected]/dist/d3-array.js"/* observablehq-file */;\n');
});
it("rewrites /npm/…+esm imports to _esm.js", () => {
assert.strictEqual(rewriteNpmImports('export * from "/npm/[email protected]/+esm";\n', (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'export * from "../[email protected]/_esm.js";\n');
assert.strictEqual(rewriteNpmImports('export * from "/npm/[email protected]/+esm";\n', (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'export * from "../[email protected]/_esm.js"/* observablehq-file */;\n');
});
it("rewrites /npm/ imports to a relative path", () => {
assert.strictEqual(rewriteNpmImports('import "/npm/[email protected]/dist/d3-array.js";\n', (v) => resolve("/_npm/[email protected]/dist/d3.js", v)), 'import "../../[email protected]/dist/d3-array.js";\n');
assert.strictEqual(rewriteNpmImports('import "/npm/[email protected]/dist/d3-array.js";\n', (v) => resolve("/_npm/[email protected]/d3.js", v)), 'import "../[email protected]/dist/d3-array.js";\n');
assert.strictEqual(rewriteNpmImports('import "/npm/[email protected]/dist/d3-array.js";\n', (v) => resolve("/_npm/[email protected]/dist/d3.js", v)), 'import "../../[email protected]/dist/d3-array.js"/* observablehq-file */;\n');
assert.strictEqual(rewriteNpmImports('import "/npm/[email protected]/dist/d3-array.js";\n', (v) => resolve("/_npm/[email protected]/d3.js", v)), 'import "../[email protected]/dist/d3-array.js"/* observablehq-file */;\n');
});
it("rewrites named imports", () => {
assert.strictEqual(rewriteNpmImports('import {sort} from "/npm/[email protected]/+esm";\n', (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'import {sort} from "../[email protected]/_esm.js";\n');
assert.strictEqual(rewriteNpmImports('import {sort} from "/npm/[email protected]/+esm";\n', (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'import {sort} from "../[email protected]/_esm.js"/* observablehq-file */;\n');
});
it("rewrites empty imports", () => {
assert.strictEqual(rewriteNpmImports('import "/npm/[email protected]/+esm";\n', (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'import "../[email protected]/_esm.js";\n');
assert.strictEqual(rewriteNpmImports('import "/npm/[email protected]/+esm";\n', (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'import "../[email protected]/_esm.js"/* observablehq-file */;\n');
});
it("rewrites default imports", () => {
assert.strictEqual(rewriteNpmImports('import d3 from "/npm/[email protected]/+esm";\n', (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'import d3 from "../[email protected]/_esm.js";\n');
assert.strictEqual(rewriteNpmImports('import d3 from "/npm/[email protected]/+esm";\n', (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'import d3 from "../[email protected]/_esm.js"/* observablehq-file */;\n');
});
it("rewrites namespace imports", () => {
assert.strictEqual(rewriteNpmImports('import * as d3 from "/npm/[email protected]/+esm";\n', (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'import * as d3 from "../[email protected]/_esm.js";\n');
assert.strictEqual(rewriteNpmImports('import * as d3 from "/npm/[email protected]/+esm";\n', (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'import * as d3 from "../[email protected]/_esm.js"/* observablehq-file */;\n');
});
it("rewrites named exports", () => {
assert.strictEqual(rewriteNpmImports('export {sort} from "/npm/[email protected]/+esm";\n', (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'export {sort} from "../[email protected]/_esm.js";\n');
assert.strictEqual(rewriteNpmImports('export {sort} from "/npm/[email protected]/+esm";\n', (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'export {sort} from "../[email protected]/_esm.js"/* observablehq-file */;\n');
});
it("rewrites namespace exports", () => {
assert.strictEqual(rewriteNpmImports('export * from "/npm/[email protected]/+esm";\n', (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'export * from "../[email protected]/_esm.js";\n');
assert.strictEqual(rewriteNpmImports('export * from "/npm/[email protected]/+esm";\n', (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'export * from "../[email protected]/_esm.js"/* observablehq-file */;\n');
});
it("rewrites dynamic imports with static module specifiers", () => {
assert.strictEqual(rewriteNpmImports('import("/npm/[email protected]/+esm");\n', (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'import("../[email protected]/_esm.js");\n');
assert.strictEqual(rewriteNpmImports("import(`/npm/[email protected]/+esm`);\n", (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'import("../[email protected]/_esm.js");\n');
assert.strictEqual(rewriteNpmImports("import('/npm/[email protected]/+esm');\n", (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'import("../[email protected]/_esm.js");\n');
assert.strictEqual(rewriteNpmImports('import("/npm/[email protected]/+esm");\n', (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'import("../[email protected]/_esm.js"/* observablehq-file */);\n');
assert.strictEqual(rewriteNpmImports("import(`/npm/[email protected]/+esm`);\n", (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'import("../[email protected]/_esm.js"/* observablehq-file */);\n');
assert.strictEqual(rewriteNpmImports("import('/npm/[email protected]/+esm');\n", (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'import("../[email protected]/_esm.js"/* observablehq-file */);\n');
});
it("ignores dynamic imports with dynamic module specifiers", () => {
assert.strictEqual(rewriteNpmImports("import(`/npm/d3-array@${version}/+esm`);\n", (v) => resolve("/_npm/[email protected]/_esm.js", v)), "import(`/npm/d3-array@${version}/+esm`);\n");
Expand All @@ -142,8 +142,8 @@ describe("rewriteNpmImports(input, resolve)", () => {
assert.strictEqual(rewriteNpmImports("import(`/npm/d3-array@${version}/+esm`);\n", (v) => resolve("/_npm/[email protected]/_esm.js", v)), "import(`/npm/d3-array@${version}/+esm`);\n");
});
it("strips the sourceMappingURL declaration", () => {
assert.strictEqual(rewriteNpmImports("import(`/npm/[email protected]/+esm`);\n//# sourceMappingURL=index.js.map", (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'import("../[email protected]/_esm.js");\n');
assert.strictEqual(rewriteNpmImports("import(`/npm/[email protected]/+esm`);\n//# sourceMappingURL=index.js.map\n", (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'import("../[email protected]/_esm.js");\n');
assert.strictEqual(rewriteNpmImports("import(`/npm/[email protected]/+esm`);\n//# sourceMappingURL=index.js.map", (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'import("../[email protected]/_esm.js"/* observablehq-file */);\n');
assert.strictEqual(rewriteNpmImports("import(`/npm/[email protected]/+esm`);\n//# sourceMappingURL=index.js.map\n", (v) => resolve("/_npm/[email protected]/_esm.js", v)), 'import("../[email protected]/_esm.js"/* observablehq-file */);\n');
});
});

Expand Down
2 changes: 1 addition & 1 deletion test/output/build/data-loaders/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
registerFile("./test.txt", {"name":"./test.txt","mimeType":"text/plain","path":"./_file/test.f2ca1bb6.txt","lastModified":/* ts */1706742000000,"size":5});

define({id: "05e74070", inputs: ["display"], outputs: ["test"], body: async (display) => {
const {test} = await import("./_import/import-test.e7269c4e.js");
const {test} = await import("./_import/import-test.e7269c4e.js"/* observablehq-file */);

display(await test);
return {test};
Expand Down
2 changes: 1 addition & 1 deletion test/output/build/fetches/foo.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
registerFile("./foo/foo-data.json", {"name":"./foo/foo-data.json","mimeType":"application/json","path":"./_file/foo/foo-data.67358ed8.json","lastModified":/* ts */1706742000000,"size":10});

define({id: "47a695da", inputs: ["display"], outputs: ["fooJsonData","fooCsvData"], body: async (display) => {
const {fooJsonData, fooCsvData} = await import("./_import/foo/foo.666599bc.js");
const {fooJsonData, fooCsvData} = await import("./_import/foo/foo.666599bc.js"/* observablehq-file */);

display(fooJsonData);
display(fooCsvData);
Expand Down
2 changes: 1 addition & 1 deletion test/output/build/fetches/top.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
registerFile("./top-data.json", {"name":"./top-data.json","mimeType":"application/json","path":"./_file/top-data.67358ed8.json","lastModified":/* ts */1706742000000,"size":10});

define({id: "cb908c08", inputs: ["display"], outputs: ["fooCsvData","fooJsonData","topCsvData","topJsonData"], body: async (display) => {
const {fooCsvData, fooJsonData, topCsvData, topJsonData} = await import("./_import/top.c85e149a.js");
const {fooCsvData, fooJsonData, topCsvData, topJsonData} = await import("./_import/top.c85e149a.js"/* observablehq-file */);

display(fooJsonData);
display(fooCsvData);
Expand Down
4 changes: 2 additions & 2 deletions test/output/build/imports/foo/foo.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
registerFile("./hello.txt", {"name":"./hello.txt","mimeType":"text/plain","path":"../_file/foo/hello.5891b5b5.txt","lastModified":/* ts */1706742000000,"size":6});

define({id: "261e010e", inputs: ["display","FileAttachment"], outputs: ["d3","bar","top"], body: async (display,FileAttachment) => {
const [d3, {bar}, {top}] = await Promise.all([import("../_npm/[email protected]/cd372fb8.js"), import("../_import/bar/bar.4460ccc2.js"), import("../_import/top.160847a6.js")]);
const [d3, {bar}, {top}] = await Promise.all([import("../_npm/[email protected]/cd372fb8.js"/* observablehq-file */), import("../_import/bar/bar.4460ccc2.js"/* observablehq-file */), import("../_import/top.160847a6.js"/* observablehq-file */)]);

display(bar);
display(top);
Expand All @@ -38,7 +38,7 @@
}});

define({id: "ec24b17a", inputs: ["display"], outputs: ["foobar"], body: async (display) => {
const {foobar} = await import("./foo%20bar.js");
const {foobar} = await import("./foo%20bar.js"/* observablehq-file */);
display(foobar);
return {foobar};
}});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible.
import { randomBetween } from "./between.2ce008c6.js";
import { randomBetween } from "./between.2ce008c6.js"/* observablehq-file */;
/**
* Generates a random integer between the provided minimum and maximum values.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
* @experimental **UNSTABLE**: New API, yet to be vetted.
*
* @module
*/ export * from "./between.2ce008c6.js";
export * from "./integer_between.4528767d.js";
export * from "./sample.6e7cf133.js";
export * from "./seeded.4e59f274.js";
export * from "./shuffle.0ef8dd95.js";
*/ export * from "./between.2ce008c6.js"/* observablehq-file */;
export * from "./integer_between.4528767d.js"/* observablehq-file */;
export * from "./sample.6e7cf133.js"/* observablehq-file */;
export * from "./seeded.4e59f274.js"/* observablehq-file */;
export * from "./shuffle.0ef8dd95.js"/* observablehq-file */;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible.
import { randomIntegerBetween } from "./integer_between.4528767d.js";
import { randomIntegerBetween } from "./integer_between.4528767d.js"/* observablehq-file */;
/**
* Returns a random element from the given array.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible.
import { fromSeed, nextU32, seedFromU64 } from "./_pcg32.b2f4838f.js";
import { fromSeed, nextU32, seedFromU64 } from "./_pcg32.b2f4838f.js"/* observablehq-file */;
/**
* Creates a pseudo-random number generator that generates random numbers in
* the range `[0, 1)`, based on the given seed. The algorithm used for
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible.
import { randomIntegerBetween } from "./integer_between.4528767d.js";
import { randomIntegerBetween } from "./integer_between.4528767d.js"/* observablehq-file */;
/**
* Shuffles the provided array, returning a copy and without modifying the original array.
*
Expand Down
2 changes: 1 addition & 1 deletion test/output/build/jsr/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import {define} from "./_observablehq/client.00000001.js";

define({id: "0e3025ad", inputs: ["display"], outputs: ["randomIntegerBetween","randomSeeded","prng"], body: async (display) => {
const {randomIntegerBetween, randomSeeded} = await import("./_jsr/@std/[email protected]/mod.e50195f4.js");
const {randomIntegerBetween, randomSeeded} = await import("./_jsr/@std/[email protected]/mod.e50195f4.js"/* observablehq-file */);

const prng = randomSeeded(1n);

Expand Down
2 changes: 1 addition & 1 deletion test/output/build/npm/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import {define} from "./_observablehq/client.00000001.js";

define({id: "0e31b7ef", body: async () => {
const {} = await import("./_import/index.4bdc071f.js");
const {} = await import("./_import/index.4bdc071f.js"/* observablehq-file */);

}});

Expand Down
2 changes: 1 addition & 1 deletion test/output/build/typescript/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
}});

define({id: "5a5e524f", outputs: ["sum"], body: async () => {
const {sum} = await import("./_import/sum.fd55756b.js");
const {sum} = await import("./_import/sum.fd55756b.js"/* observablehq-file */);

return {sum};
}});
Expand Down
2 changes: 1 addition & 1 deletion test/output/imports/alias-import.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
define({id: "0", inputs: ["display"], outputs: ["bar"], body: async (display) => {
const {foo: bar} = await import("./_import/bar.js");
const {foo: bar} = await import("./_import/bar.js"/* observablehq-file */);

display(bar);
return {bar};
Expand Down
2 changes: 1 addition & 1 deletion test/output/imports/empty-import.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
define({id: "0", body: async () => {
const {} = await import("./_import/bar.js");
const {} = await import("./_import/bar.js"/* observablehq-file */);

}});
2 changes: 1 addition & 1 deletion test/output/imports/local-fetch-from-import.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
define({id: "0", inputs: ["display"], outputs: ["data"], body: async (display) => {
const {data} = await import("./_import/baz.js");
const {data} = await import("./_import/baz.js"/* observablehq-file */);

display(data);
return {data};
Expand Down
2 changes: 1 addition & 1 deletion test/output/imports/namespace-import.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
define({id: "0", inputs: ["display"], outputs: ["bar"], body: async (display) => {
const bar = await import("./_import/bar.js");
const bar = await import("./_import/bar.js"/* observablehq-file */);

display(bar);
return {bar};
Expand Down
2 changes: 1 addition & 1 deletion test/output/imports/static-all-import.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
define({id: "0", outputs: ["foo","bar"], body: async () => {
const [{foo}, {bar}] = await Promise.all([import("./_import/foo.js"), import("./_import/bar.js")]);
const [{foo}, {bar}] = await Promise.all([import("./_import/foo.js"/* observablehq-file */), import("./_import/bar.js"/* observablehq-file */)]);

foo() + bar();
return {foo,bar};
Expand Down
2 changes: 1 addition & 1 deletion test/output/imports/static-import.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
define({id: "0", inputs: ["display"], outputs: ["foo"], body: async (display) => {
const {foo} = await import("./_import/bar.js");
const {foo} = await import("./_import/bar.js"/* observablehq-file */);

display(foo);
return {foo};
Expand Down
2 changes: 1 addition & 1 deletion test/output/imports/transitive-static-import.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
define({id: "0", outputs: ["foo"], body: async () => {
const {foo} = await import("./_import/other/foo.js");
const {foo} = await import("./_import/other/foo.js"/* observablehq-file */);

return {foo};
}});
2 changes: 1 addition & 1 deletion test/output/static-import-noent.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
define({id: "0", inputs: ["display"], outputs: ["foo"], body: async (display) => {
const {foo} = await import("./_import/noent.js");
const {foo} = await import("./_import/noent.js"/* observablehq-file */);

display(foo);
return {foo};
Expand Down

0 comments on commit e0bc373

Please sign in to comment.