diff --git a/.gitattributes b/.gitattributes index 291b72280..b17d448d5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,4 @@ *.res linguist-language=ReScript *.resi linguist-language=ReScript + +/public/playground-bundles/** binary linguist-vendored diff --git a/.gitignore b/.gitignore index d364e12a7..26659b043 100644 --- a/.gitignore +++ b/.gitignore @@ -26,9 +26,12 @@ lib/ .vercel src/**/*.mjs -scripts/**/*.mjs +scripts/gendocs.mjs +scripts/generate_*.mjs # Generated via generate-llms script public/llms/manual/**/llm*.txt public/llms/react/**/llm*.txt pages/docs/**/**/llms.mdx + +public/playground-bundles/ diff --git a/next.config.mjs b/next.config.mjs index eb31e01f3..b13f7fccd 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -21,6 +21,7 @@ const config = { ENV: process.env.NODE_ENV, VERSION_LATEST: process.env.VERSION_LATEST, VERSION_NEXT: process.env.VERSION_NEXT, + VERCEL: process.env.VERCEL, }, swcMinify: false, webpack: (config, options) => { diff --git a/package.json b/package.json index 7da48878d..4e49846d2 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "test": "node scripts/test-examples.mjs && node scripts/test-hrefs.mjs", "reanalyze": "reanalyze -all-cmt .", "update-index": "npm run generate-llms && node scripts/extract-indices.mjs && node scripts/extract-tocs.mjs && node scripts/extract-syntax.mjs && node scripts/generate_feed.mjs > public/blog/feed.xml", + "sync-bundles": "node scripts/sync-playground-bundles.mjs", "generate-llms": "node scripts/generate_llms.mjs", "generate-resources": "node scripts/generate_resources.mjs" }, diff --git a/scripts/sync-playground-bundles.mjs b/scripts/sync-playground-bundles.mjs new file mode 100644 index 000000000..bbc3821b4 --- /dev/null +++ b/scripts/sync-playground-bundles.mjs @@ -0,0 +1,43 @@ +import * as path from "node:path"; +import * as fs from "node:fs"; +import * as childProcess from "node:child_process"; +import { Readable } from "node:stream"; +import * as stream from "node:stream/promises"; + +const bucketUrl = new URL("https://cdn.rescript-lang.org"); + +const bundlesDir = path.join(import.meta.dirname, "../public/playground-bundles"); +const versions = await fetch(new URL("/playground-bundles/versions.json", bucketUrl)) + .then(res => res.json()); + +for (const version of versions) { + const versionDir = path.join(bundlesDir, version); + const compilerFile = path.join(versionDir, "compiler.js"); + if (fs.existsSync(compilerFile)) { + console.log(`%s has already been synced.`, version); + continue; + } + + console.group(`Syncing %s...`, version); + { + console.log(`Downloading archive file...`); + const res = await fetch(new URL(`/playground-bundles/${version}.tar.zst`, bucketUrl)); + if (!res.ok) { + console.error(await res.text()); + continue; + } + + const archiveFile = path.join(bundlesDir, `${version}.tar.zst`); + const fileStream = fs.createWriteStream(archiveFile); + await stream.finished(Readable.fromWeb(res.body).pipe(fileStream)); + + console.log("Extracting archive..."); + fs.mkdirSync(versionDir, { recursive: true }); + childProcess.execSync(`tar --zstd -xf "${archiveFile}" -C "${versionDir}"`); + + console.log("Cleaning up..."); + fs.unlinkSync(archiveFile); + + console.groupEnd(); + } +} diff --git a/src/Try.res b/src/Try.res index 96257dd04..ad7cdc160 100644 --- a/src/Try.res +++ b/src/Try.res @@ -33,22 +33,14 @@ let default = props => { let getStaticProps: Next.GetStaticProps.t = async _ => { let versions = { - let response = await Webapi.Fetch.fetch("https://cdn.rescript-lang.org/") - let text = await Webapi.Fetch.Response.text(response) - text - ->String.split("\n") - ->Array.filterMap(line => { - switch line->String.startsWith(" - // Adapted from https://semver.org/ - let semverRe = /v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?/ - switch RegExp.exec(semverRe, line) { - | Some(result) => RegExp.Result.fullMatch(result)->Some - | None => None - } - | false => None - } - }) + let response = await Webapi.Fetch.fetch( + "https://cdn.rescript-lang.org/playground-bundles/versions.json", + ) + let json = await Webapi.Fetch.Response.json(response) + json + ->JSON.Decode.array + ->Option.getExn + ->Array.map(json => json->JSON.Decode.string->Option.getExn) } {"props": {versions: versions}} diff --git a/src/common/CompilerManagerHook.res b/src/common/CompilerManagerHook.res index 39c0e214e..99a1a97c7 100644 --- a/src/common/CompilerManagerHook.res +++ b/src/common/CompilerManagerHook.res @@ -35,14 +35,18 @@ module LoadScript = { } module CdnMeta = { - let getCompilerUrl = (version): string => - `https://cdn.rescript-lang.org/${Semver.toString(version)}/compiler.js` + let baseUrl = switch Node.Process.env->Dict.get("VERCEL") { + | Some(_) => "https://cdn.rescript-lang.org" + | None => "/playground-bundles" + } + + let getCompilerUrl = (version): string => `${baseUrl}/${Semver.toString(version)}/compiler.js` let getLibraryCmijUrl = (version, libraryName: string): string => - `https://cdn.rescript-lang.org/${Semver.toString(version)}/${libraryName}/cmij.js` + `${baseUrl}/${Semver.toString(version)}/${libraryName}/cmij.js` let getStdlibRuntimeUrl = (version, filename) => - `https://cdn.rescript-lang.org/${Semver.toString(version)}/compiler-builtins/stdlib/${filename}` + `${baseUrl}/${Semver.toString(version)}/compiler-builtins/stdlib/${filename}` } module FinalResult = {