Skip to content
Open
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
68 changes: 68 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,18 @@ jobs:
if: matrix.build_playground
run: yarn workspace playground test

- name: Stage dev playground compiler bundle
if: ${{ matrix.build_playground && github.event_name == 'push' && github.ref == 'refs/heads/master' }}
run: yarn workspace dev-playground stage-master-bundle

- name: "Upload artifacts: dev playground compiler bundle"
if: ${{ matrix.build_playground && github.event_name == 'push' && github.ref == 'refs/heads/master' }}
uses: actions/upload-artifact@v7
with:
name: dev-playground-master-bundle
path: packages/dev-playground/public/playground-bundles/master
if-no-files-found: error

- name: Setup Rclone
if: ${{ matrix.build_playground && startsWith(github.ref, 'refs/tags/v') }}
uses: cometkim/rclone-actions/setup-rclone@main
Expand Down Expand Up @@ -430,6 +442,62 @@ jobs:
name: api
path: scripts/res/apiDocs/

dev-playground:
needs:
- build-compiler
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
runs-on: ubuntu-24.04
permissions:
contents: read
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}dev-playground/
env:
VITE_DEFAULT_COMPILER_VERSION: master
VITE_COMPILER_VERSIONS: '[{"id":"master","label":"master"}]'
GITHUB_PAGES_PATH: dev-playground
PLAYGROUND_BUNDLE_ID: master
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Use Node.js
uses: actions/setup-node@v6
with:
cache: yarn
node-version-file: .nvmrc

- name: Install npm packages
run: yarn install

- name: Download dev playground compiler bundle
uses: actions/download-artifact@v8
with:
name: dev-playground-master-bundle
path: packages/dev-playground/public/playground-bundles/master

- name: Configure GitHub Pages
id: pages
uses: actions/configure-pages@v6

- name: Build dev playground Pages site
env:
VITE_BASE: ${{ steps.pages.outputs.base_path }}/dev-playground/
run: |
yarn workspace dev-playground build
yarn workspace dev-playground prepare-pages-site

- name: Upload GitHub Pages artifact
uses: actions/upload-pages-artifact@v5
with:
path: packages/dev-playground/pages-site

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v5

pkg-pr-new:
needs:
- build-compiler
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ playground/*.cmj
playground/*.cmi
playground/.netrc
playground/compiler.*js
packages/dev-playground/dist/
packages/dev-playground/pages-site/
packages/dev-playground/lib/
packages/dev-playground/src/*.res.mjs
packages/dev-playground/public/playground-bundles/*
!packages/dev-playground/public/playground-bundles/.gitignore

rewatch/target/
rewatch/rewatch
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#### :house: Internal

- Remove `Primitive_option.toUndefined`; use `valFromOption` for optional ffi args. https://github.com/rescript-lang/rescript/pull/8380
- Add a developer playground for testing the current compiler bundle locally and deploy the latest `master` build to GitHub Pages. https://github.com/rescript-lang/rescript/pull/8435
- Expand `super_errors` fixture coverage for warnings and errors. https://github.com/rescript-lang/rescript/pull/8429
- Run `super_errors` fixtures in parallel (~2.4× faster locally). https://github.com/rescript-lang/rescript/pull/8430
- Expand `super_errors` fixture coverage for the remaining reachable single-file error variants. https://github.com/rescript-lang/rescript/pull/8432
Expand Down
9 changes: 9 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,15 @@ $(PLAYGROUND_CMI_BUILD_STAMP): $(RUNTIME_BUILD_STAMP)
playground-test: playground
yarn workspace playground test

dev-playground-stage: playground
yarn workspace dev-playground stage-local-bundle

dev-playground: dev-playground-stage
yarn workspace dev-playground dev

dev-playground-build: dev-playground-stage
yarn workspace dev-playground build

# Builds the playground, runs some e2e tests and releases the playground to the
# Cloudflare R2 (requires Rclone `rescript:` remote)
playground-release: playground-test
Expand Down
40 changes: 35 additions & 5 deletions compiler/jsoo/jsoo_playground_main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@
* modules in the playground.
* v5: Removed .ml support.
* v6: Added `config.experimental_features` and `config.jsx_preserve_mode` to the BundleConfig.
* v7: Added debug dump output APIs for developer playground tooling.
* *)
let api_version = "6"
let api_version = "7"

module Js = Js_of_ocaml.Js

Expand Down Expand Up @@ -298,6 +299,8 @@ let rescript_parse ~filename src =
structure

module Printer = struct
let to_string printer value = Format.asprintf "%a@." printer value

let print_expr typ =
Printtyp.reset_names ();
Printtyp.reset_and_mark_loops typ;
Expand Down Expand Up @@ -472,7 +475,8 @@ module Compile = struct
List.iter Iter.iter_structure_item structure.str_items;
Js.array (!acc |> Array.of_list)

let implementation ~(config : BundleConfig.t) ~lang str =
let implementation ?(include_debug_outputs = false) ~(config : BundleConfig.t)
~lang str =
let {
BundleConfig.module_system;
warn_flags;
Expand Down Expand Up @@ -525,8 +529,8 @@ module Compile = struct
in
let v = Buffer.contents buffer in
let type_hints = collect_type_hints typed_tree in
Js.Unsafe.(
obj
let attrs =
Js.Unsafe.
[|
("js_code", inject @@ Js.string v);
( "warnings",
Expand All @@ -536,7 +540,28 @@ module Compile = struct
|> Js.array |> inject) );
("type_hints", inject @@ type_hints);
("type", inject @@ Js.string "success");
|])
|]
in
if include_debug_outputs then
let export_ident_sets = Set_ident.of_list exports in
let lam, _ = Lam_convert.convert export_ident_sets lambda in
let parsetree = Printer.to_string Printast.implementation ast in
let typedtree =
Printer.to_string Printtyped.implementation_with_coercion typed_tree
in
let lambda = Printer.to_string Printlambda.lambda lambda in
let lam = Lam_print.lambda_to_string lam in
let debug_attrs =
Js.Unsafe.
[|
("parsetree", inject @@ Js.string parsetree);
("typedtree", inject @@ Js.string typedtree);
("lambda", inject @@ Js.string lambda);
("lam", inject @@ Js.string lam);
|]
in
Js.Unsafe.obj (Array.append attrs debug_attrs)
else Js.Unsafe.obj attrs
with e -> (
match e with
| Arg.Bad msg -> ErrorRet.make_warning_flag_error ~warn_flags msg
Expand Down Expand Up @@ -582,6 +607,11 @@ module Export = struct
inject
@@ Js.wrap_meth_callback (fun _ code ->
Compile.implementation ~config ~lang (Js.to_string code)) );
( "compileWithDebug",
inject
@@ Js.wrap_meth_callback (fun _ code ->
Compile.implementation ~include_debug_outputs:true ~config
~lang (Js.to_string code)) );
("version", inject @@ Js.string Bs_version.version);
|]
in
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
"typescript": "6.0.3"
},
"workspaces": [
"packages/dev-playground",
"packages/playground",
"packages/@rescript/*",
"tests/dependencies/**",
Expand Down
13 changes: 13 additions & 0 deletions packages/dev-playground/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ReScript Developer Playground</title>
<link rel="stylesheet" href="/src/styles.css" />
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/Main.res.mjs"></script>
</body>
</html>
22 changes: 22 additions & 0 deletions packages/dev-playground/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"private": true,
"name": "dev-playground",
"version": "0.1.0",
"type": "module",
"scripts": {
"stage-local-bundle": "node scripts/stage-local-bundle.mjs",
"stage-master-bundle": "node scripts/stage-local-bundle.mjs master --clear-other-bundles",
"prepare-pages-site": "node scripts/prepare-pages-site.mjs",
"res:build": "rescript",
"res:watch": "rescript -w",
"dev": "vite --host 127.0.0.1",
"build": "rescript && vite build",
"preview": "vite preview --host 127.0.0.1"
},
"dependencies": {
"@rescript/runtime": "12.3.0",
"rescript": "12.3.0",
"vite": "^7.3.2",
"xote": "6.1.1"
}
}
2 changes: 2 additions & 0 deletions packages/dev-playground/public/playground-bundles/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
26 changes: 26 additions & 0 deletions packages/dev-playground/rescript.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "dev-playground",
"sources": [
{
"dir": "src",
"subdirs": true
}
],
"package-specs": {
"module": "esmodule",
"in-source": true
},
"suffix": ".res.mjs",
"dependencies": ["xote"],
"jsx": {
"version": 4,
"module": "XoteJSX"
},
"experimental-features": {
"LetUnwrap": true
},
"compiler-flags": ["-open Xote", "-open Bindings"],
"warnings": {
"error": "+8"
}
}
85 changes: 85 additions & 0 deletions packages/dev-playground/scripts/prepare-pages-site.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#!/usr/bin/env node

import * as fs from "node:fs/promises";
import * as path from "node:path";

const devPlaygroundDir = path.join(import.meta.dirname, "..");
const distDir = path.join(devPlaygroundDir, "dist");
const siteDir = path.join(devPlaygroundDir, "pages-site");
const sitePath = process.env.GITHUB_PAGES_PATH ?? "dev-playground";
const bundleId = process.env.PLAYGROUND_BUNDLE_ID ?? "master";
const commitSha = process.env.GITHUB_SHA ?? "unknown";
const targetDir = path.join(siteDir, sitePath);

async function assertExists(filePath, message) {
try {
await fs.stat(filePath);
} catch {
throw new Error(`${message}: ${filePath}`);
}
}

await assertExists(
distDir,
"Missing dev playground build. Run `yarn workspace dev-playground build` first",
);

await fs.rm(siteDir, { recursive: true, force: true });
await fs.mkdir(targetDir, { recursive: true });
await fs.cp(distDir, targetDir, { recursive: true });

const catalog = {
generatedAt: new Date().toISOString(),
defaultBundle: bundleId,
bundles: [
{
id: bundleId,
label: bundleId,
channel: bundleId,
commit: commitSha,
root: `playground-bundles/${bundleId}`,
},
],
};

await fs.writeFile(
path.join(targetDir, "catalog.json"),
`${JSON.stringify(catalog, null, 2)}\n`,
);

await fs.writeFile(
path.join(siteDir, "index.html"),
`<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="refresh" content="0; url=./${sitePath}/" />
<title>ReScript Developer Playground</title>
</head>
<body>
<a href="./${sitePath}/">Open ReScript Developer Playground</a>
</body>
</html>
`,
);

await assertExists(
path.join(targetDir, "index.html"),
"Missing deployed dev playground index",
);
await assertExists(
path.join(targetDir, "playground-bundles", bundleId, "compiler.js"),
"Missing deployed playground compiler bundle",
);
await assertExists(
path.join(
targetDir,
"playground-bundles",
bundleId,
"compiler-builtins",
"cmij.js",
),
"Missing deployed compiler-builtins cmij bundle",
);

console.log(`Prepared GitHub Pages site at ${siteDir}`);
Loading
Loading