From 2b939e26e7600631fc114b11d3a195cbf8c4b3f2 Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Wed, 3 Sep 2025 21:25:49 +0900 Subject: [PATCH 1/4] add a script to serve playground bundle locally --- packages/playground/package.json | 4 ++- packages/playground/serve-bundle.mjs | 36 ++++++++++++++++++++ yarn.lock | 50 ++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 packages/playground/serve-bundle.mjs diff --git a/packages/playground/package.json b/packages/playground/package.json index d8053f9db8..c058463871 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -6,7 +6,8 @@ "clean": "rescript clean", "test": "node ./playground_test.cjs", "build": "rescript clean && rescript legacy build && node scripts/generate_cmijs.mjs && rollup -c", - "upload-bundle": "node scripts/upload_bundle.mjs" + "upload-bundle": "node scripts/upload_bundle.mjs", + "serve-bundle": "node serve-bundle.mjs" }, "dependencies": { "@rescript/react": "^0.13.1", @@ -15,6 +16,7 @@ "devDependencies": { "@rollup/plugin-node-resolve": "^16.0.0", "glob": "^11.0.1", + "h3": "2.0.0-beta.4", "rollup": "^4.32.0" } } diff --git a/packages/playground/serve-bundle.mjs b/packages/playground/serve-bundle.mjs new file mode 100644 index 0000000000..86677ee64c --- /dev/null +++ b/packages/playground/serve-bundle.mjs @@ -0,0 +1,36 @@ +import { stat, readFile } from "node:fs/promises"; +import * as path from "node:path"; +import { H3, serve, serveStatic } from "h3"; + +import { rescript_compiler } from "./compiler.js"; + +const compilerVersion = rescript_compiler.version; + +const app = new H3() + .get("/versions.json", () => { + return [`${compilerVersion}-local`]; + }) + .use("**", event => { + return serveStatic(event, { + getContents: id => { + const basePath = id === "/compiler.js" + ? import.meta.dirname + : path.join(import.meta.dirname, "packages"); + return readFile(path.join(basePath, id)); + }, + getMeta: async id => { + const basePath = id === "/compiler.js" + ? import.meta.dirname + : path.join(import.meta.dirname, "packages"); + const stats = await stat(path.join(basePath, id)).catch(() => {}); + if (stats?.isFile()) { + return { + size: stats.size, + mtime: stats.mtimeMs, + }; + } + }, + }); + }); + +serve(app, { port: 8888 }); diff --git a/yarn.lock b/yarn.lock index 939f34baac..44840efa72 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1117,6 +1117,13 @@ __metadata: languageName: node linkType: hard +"cookie-es@npm:^2.0.0": + version: 2.0.0 + resolution: "cookie-es@npm:2.0.0" + checksum: 10c0/3b2459030a5ad2bc715aeb27a32f274340670bfc5031ac29e1fba804212517411bb617880d3fe66ace2b64dfb28f3049e2d1ff40d4bec342154ccdd124deaeaa + languageName: node + linkType: hard + "cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" @@ -1280,6 +1287,13 @@ __metadata: languageName: node linkType: hard +"fetchdts@npm:^0.1.6": + version: 0.1.7 + resolution: "fetchdts@npm:0.1.7" + checksum: 10c0/7497671ee28b3e7cc49d037a7c11e6f98e53e6e2abd85f26e8fac3fae4142c3c0d91352dc46198530f73b16480585605c63e3d112c34210ff2c75be1199668a0 + languageName: node + linkType: hard + "fill-range@npm:^7.1.1": version: 7.1.1 resolution: "fill-range@npm:7.1.1" @@ -1501,6 +1515,23 @@ __metadata: languageName: node linkType: hard +"h3@npm:2.0.0-beta.4": + version: 2.0.0-beta.4 + resolution: "h3@npm:2.0.0-beta.4" + dependencies: + cookie-es: "npm:^2.0.0" + fetchdts: "npm:^0.1.6" + rou3: "npm:^0.7.3" + srvx: "npm:^0.8.7" + peerDependencies: + crossws: ^0.4.1 + peerDependenciesMeta: + crossws: + optional: true + checksum: 10c0/ac40213784bab18a96509048d82338763484dddab303763ab549c1fc2e41c8c83a00013154fd9861042b9016f91dc0be3e6c12e553e7450910dc692c17e59403 + languageName: node + linkType: hard + "has-flag@npm:^4.0.0": version: 4.0.0 resolution: "has-flag@npm:4.0.0" @@ -2412,6 +2443,7 @@ __metadata: "@rescript/react": "npm:^0.13.1" "@rollup/plugin-node-resolve": "npm:^16.0.0" glob: "npm:^11.0.1" + h3: "npm:2.0.0-beta.4" rescript: "workspace:^" rollup: "npm:^4.32.0" languageName: unknown @@ -2680,6 +2712,13 @@ __metadata: languageName: node linkType: hard +"rou3@npm:^0.7.3": + version: 0.7.3 + resolution: "rou3@npm:0.7.3" + checksum: 10c0/f20224a724838c8a0cbdd8b37462ad684b59f87a8314aa7e6a1a892f96d806bcf504bcb9108f9d812cdb6194e1a347adc15f2c379238bfbc3b723e33dc71ca46 + languageName: node + linkType: hard + "safe-buffer@npm:^5.1.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" @@ -2839,6 +2878,17 @@ __metadata: languageName: node linkType: hard +"srvx@npm:^0.8.7": + version: 0.8.7 + resolution: "srvx@npm:0.8.7" + dependencies: + cookie-es: "npm:^2.0.0" + bin: + srvx: bin/srvx.mjs + checksum: 10c0/67b0b0acbb660df966dd0486e93eba456535190b38a8817f45afbfc4a8892146d69bf8183cdc270bfbbc360169df26f4b636d29ca6b28a4c5eec20d3432ab317 + languageName: node + linkType: hard + "ssri@npm:^12.0.0": version: 12.0.0 resolution: "ssri@npm:12.0.0" From 8d50a779d2e8e16f3bb95dd8c92c442e0ecc670b Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Wed, 3 Sep 2025 21:59:21 +0900 Subject: [PATCH 2/4] fix routing --- packages/playground/serve-bundle.mjs | 37 +++++++++++++++++++++------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/packages/playground/serve-bundle.mjs b/packages/playground/serve-bundle.mjs index 86677ee64c..e41ef985a9 100644 --- a/packages/playground/serve-bundle.mjs +++ b/packages/playground/serve-bundle.mjs @@ -5,24 +5,43 @@ import { H3, serve, serveStatic } from "h3"; import { rescript_compiler } from "./compiler.js"; const compilerVersion = rescript_compiler.version; +const localVersion = `${compilerVersion}-local`; + +/** + * @param {string} id + */ +function toLocalPath(id) { + if (id === "/compiler.js") { + return path.join(import.meta.dirname, id); + } + if (id.startsWith(`/${localVersion}`)) { + return path.join( + import.meta.dirname, + id.replace(`/${localVersion}`, "/packages"), + ); + } + return undefined; +} const app = new H3() .get("/versions.json", () => { - return [`${compilerVersion}-local`]; + return [localVersion]; }) + // Supported paths + // - /compiler.js + // - /{compilerVersion}-local/{library}/cmij.js .use("**", event => { return serveStatic(event, { getContents: id => { - const basePath = id === "/compiler.js" - ? import.meta.dirname - : path.join(import.meta.dirname, "packages"); - return readFile(path.join(basePath, id)); + const localPath = toLocalPath(id); + return localPath && readFile(path.join(basePath, id)); }, getMeta: async id => { - const basePath = id === "/compiler.js" - ? import.meta.dirname - : path.join(import.meta.dirname, "packages"); - const stats = await stat(path.join(basePath, id)).catch(() => {}); + const localPath = toLocalPath(id); + if (!localPath) { + return undefined; + } + const stats = await stat(localPath).catch(() => {}); if (stats?.isFile()) { return { size: stats.size, From 5a94c29b4b70b9c237a4bb58c2e46d06bd53b33b Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Thu, 4 Sep 2025 02:07:58 +0900 Subject: [PATCH 3/4] fix, tested --- packages/playground/serve-bundle.mjs | 43 ++++++++++++---------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/packages/playground/serve-bundle.mjs b/packages/playground/serve-bundle.mjs index e41ef985a9..413013cb52 100644 --- a/packages/playground/serve-bundle.mjs +++ b/packages/playground/serve-bundle.mjs @@ -2,45 +2,34 @@ import { stat, readFile } from "node:fs/promises"; import * as path from "node:path"; import { H3, serve, serveStatic } from "h3"; -import { rescript_compiler } from "./compiler.js"; - -const compilerVersion = rescript_compiler.version; -const localVersion = `${compilerVersion}-local`; +import compilerBundle from "./compiler.js"; +const compilerVersion = compilerBundle.rescript_compiler.version; +const localVersion = "v" + compilerVersion.toString(); /** * @param {string} id */ function toLocalPath(id) { - if (id === "/compiler.js") { - return path.join(import.meta.dirname, id); - } - if (id.startsWith(`/${localVersion}`)) { - return path.join( - import.meta.dirname, - id.replace(`/${localVersion}`, "/packages"), - ); + const originalId = id.slice(localVersion.length + 1); + if (originalId === "/compiler.js") { + return path.join(import.meta.dirname, originalId); } - return undefined; + return path.join( + import.meta.dirname, + "packages", + originalId, + ); } -const app = new H3() - .get("/versions.json", () => { - return [localVersion]; - }) - // Supported paths - // - /compiler.js - // - /{compilerVersion}-local/{library}/cmij.js - .use("**", event => { +const versionContent = new H3() + .get("/**", event => { return serveStatic(event, { getContents: id => { const localPath = toLocalPath(id); - return localPath && readFile(path.join(basePath, id)); + return localPath && readFile(localPath); }, getMeta: async id => { const localPath = toLocalPath(id); - if (!localPath) { - return undefined; - } const stats = await stat(localPath).catch(() => {}); if (stats?.isFile()) { return { @@ -52,4 +41,8 @@ const app = new H3() }); }); +const app = new H3() + .get("/playground-bundles/versions.json", () => [localVersion]) + .mount(`/${localVersion}`, versionContent); + serve(app, { port: 8888 }); From 7b61dbf778da426e821a6fd614ca094774be1558 Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Thu, 4 Sep 2025 02:19:29 +0900 Subject: [PATCH 4/4] add a manual --- CONTRIBUTING.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6d72684cc3..1410115c48 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -286,6 +286,17 @@ $ node Run `yarn workspace playground test` for a quick sanity check to see if all the build artifacts are working together correctly. When releasing the playground bundle, the test will always be executed before publishing to catch regressions. +You can test the bundle within the playground by running a web server and playground locally. + +```sh +# Serve playground bundles locally +yarn workspace playground serve-bundle + +# And run the website with "PLAYGROUND_BUNDLE_ENDPOINT" +cd path/to/rescript-lang.org +PLAYGROUND_BUNDLE_ENDPOINT=http://localhost:8888 npm run dev +``` + ### Working on the Playground JS API Whenever you are modifying any files in the ReScript compiler, or in the `jsoo_playground_main.ml` file, you'll need to rebuild the source and recreate the JS bundle.