Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions src/runtime/bake/bake.private.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,3 @@ declare module "react-dom/server.node" {
options: RenderToPipeableStreamOptions,
): PipeableStream<Uint8Array>;
}

declare module "bun:wrap" {
export const __name: unique symbol;
export const __legacyDecorateClassTS: unique symbol;
export const __legacyDecorateParamTS: unique symbol;
export const __legacyMetadataTS: unique symbol;
export const __using: unique symbol;
export const __callDispose: unique symbol;
export const __MEMO_CACHE_SENTINEL: unique symbol;
export const __EARLY_RETURN_SENTINEL: unique symbol;
}
22 changes: 2 additions & 20 deletions src/runtime/bake/hmr-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,7 @@
// Some build failures from the bundler surface as runtime errors here, such as
// `require` on a module with transitive top-level await, or a missing export.
// This was done to make incremental updates as isolated as possible.
import {
__callDispose,
__EARLY_RETURN_SENTINEL,
__legacyDecorateClassTS,
__legacyDecorateParamTS,
__legacyMetadataTS,
__MEMO_CACHE_SENTINEL,
__name,
__using,
} from "../../runtime.bun";
import * as runtimeHelpers from "../../runtime.bun";
// This import is different based on client vs server side.
// On the server, remapping is done automatically.
import { type SourceMapURL, derefMapping } from "#stack-trace";
Expand Down Expand Up @@ -946,16 +937,7 @@ declare global {

// bun:bake/server, bun:bake/client, and bun:wrap are
// provided by this file instead of the bundler
registerSynthetic("bun:wrap", {
__name,
__legacyDecorateClassTS,
__legacyDecorateParamTS,
__legacyMetadataTS,
__using,
__callDispose,
__MEMO_CACHE_SENTINEL,
__EARLY_RETURN_SENTINEL,
});
registerSynthetic("bun:wrap", runtimeHelpers);

if (side === "server") {
registerSynthetic("bun:bake/server", {
Expand Down
67 changes: 66 additions & 1 deletion test/bake/dev-and-prod.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Tests which apply to both dev and prod. They are run twice.
import { writeFileSync } from "node:fs";
import { devAndProductionTest, devTest, emptyHtmlFile, WAIT_MULTIPLIER } from "./bake-harness";
import { devAndProductionTest, devTest, emptyHtmlFile, minimalFramework, WAIT_MULTIPLIER } from "./bake-harness";

const hmrSelfAcceptingModule = (label: string) => `
console.log(${JSON.stringify(label)});
Expand Down Expand Up @@ -202,6 +202,71 @@ devTest("using runtime import", {
);
},
});
// Standard (TC39) decorators, `accessor` fields, and the `#private` members of a
// decorated class are lowered into calls to helpers imported from "bun:wrap"
// (__decoratorStart, __decorateElement, __runInitializers, __decoratorMetadata,
// __privateAdd, __privateGet, __privateSet, __privateIn, __privateMethod). The
// dev server does not bundle runtime.js; its HMR runtime provides "bun:wrap"
// itself, so it has to export everything the production runtime does. This
// class imports all nine helpers.
const standardDecoratorsSource = `
const applied: string[] = [];
function dec(_value: unknown, ctx: DecoratorContext) {
applied.push(ctx.kind + ":" + String(ctx.name));
}
@dec
class Foo {
@dec static s = 1;
@dec #p = 2;
@dec accessor x = 3;
@dec m() {}
@dec get g() { return this.#p; }
@dec #pm() { return 5; }
accessor y = 4;
has(o: object) { return #p in o; }
pm() { return this.#pm(); }
}
const foo = new Foo();
foo.x += 10;
foo.y += 10;
export const decorated = applied.sort().join(",");
export const values = [Foo.s, foo.x, foo.y, foo.g, foo.pm(), foo.has(foo), foo.has({})].join(",");
`;
const expectedDecorated = "accessor:x,class:Foo,field:#p,field:s,getter:g,method:#pm,method:m";
const expectedValues = "1,13,14,2,5,true,false";
devAndProductionTest("standard decorators runtime import", {
files: {
"index.html": emptyHtmlFile({
styles: [],
scripts: ["index.ts"],
}),
"index.ts": `
import { decorated, values } from "./decorated";
console.log(decorated);
console.log(values);
`,
"decorated.ts": standardDecoratorsSource,
},
async test(dev) {
await using c = await dev.client("/");
await c.expectMessage(expectedDecorated, expectedValues);
},
});
devTest("standard decorators runtime import on the server", {
framework: minimalFramework,
files: {
"decorated.ts": standardDecoratorsSource,
"routes/index.ts": `
import { decorated, values } from "../decorated";
export default function (req, meta) {
return new Response(decorated + "\\n" + values);
}
`,
},
async test(dev) {
await dev.fetch("/").equals(expectedDecorated + "\n" + expectedValues);
},
});
devTest("hmr handles rapid consecutive edits", {
files: {
"index.html": emptyHtmlFile({
Expand Down