diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 76ac9c5fc..000000000 --- a/.babelrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presets": [ - "next/babel" - ], - "plugins": [ - ] -} diff --git a/.env b/.env new file mode 100644 index 000000000..431fdc073 --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +VERSION_LATEST="v11.0.0" +VERSION_NEXT="v12.0.0" \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..b17d448d5 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +*.res linguist-language=ReScript +*.resi linguist-language=ReScript + +/public/playground-bundles/** binary linguist-vendored diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..2931b7fef --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,20 @@ +blank_issues_enabled: false +contact_links: + - name: 🚀 rescript-compiler + url: https://github.com/rescript-lang/rescript/issues + about: Please report problems about the ReScript compiler, build system and tools here. + - name: 💻 rescript-vscode + url: https://github.com/rescript-lang/rescript-vscode/issues + about: VSCode language support, LSP + - name: 📦 create-rescript-app + url: https://github.com/rescript-lang/create-rescript-app/issues + about: ReScript's project generator + - name: ⚛️ rescript-react + url: https://github.com/rescript-lang/rescript-react/issues + about: ReScript bindings to React.js + - name: 🌐 rescript-core + url: https://github.com/rescript-lang/rescript-core/issues + about: New ReScript standard library + - name: 💬 ReScript Forum + url: https://forum.rescript-lang.org/ + about: For discussions about ReScript, please visit the official ReScript forum. diff --git a/.github/ISSUE_TEMPLATE/documentation_issue.md b/.github/ISSUE_TEMPLATE/documentation_issue.md new file mode 100644 index 000000000..95cb9bae2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation_issue.md @@ -0,0 +1,7 @@ +--- +name: 🚨 Documentation issue +about: Create an issue to help us improve the rescript-lang.org documentation website +title: "" +labels: "" +assignees: "" +--- diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 9ca8d15b3..ecd03a074 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -4,13 +4,15 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: - node-version: 14.x + node-version: 20 + cache: npm - run: npm ci - run: npx rescript - run: npm test + - run: npm run ci:format - name: Format check run: npx rescript format -check -all diff --git a/.gitignore b/.gitignore index b56aab4f3..31b182d6e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ public/blog/feed.xml node_modules/ .next/ +out/ index_data/*.json # Generated via test examples script @@ -15,14 +16,23 @@ _tempFile.cmj _tempFile.cmt # these docs are checked in, but we consider them frozen. -pages/docs/manual/v8.0.0/ -pages/docs/manual/v9.0.0/ +# pages/docs/manual/v8.0.0/ +# pages/docs/manual/v9.0.0/ .bsb.lock .merlin lib/ -.vscode/ .vercel src/**/*.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/ +public/_redirects diff --git a/.node-version b/.node-version new file mode 100644 index 000000000..7af24b7dd --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +22.11.0 diff --git a/.nowignore b/.nowignore deleted file mode 100644 index 5b3ad333e..000000000 --- a/.nowignore +++ /dev/null @@ -1,2 +0,0 @@ -.next/ -node_modules/ diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..35fb054b6 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +data/api/**/*.json diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..564d6bf5a --- /dev/null +++ b/.prettierrc @@ -0,0 +1,2 @@ +plugins: + - "@prettier/plugin-oxc" diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..241f2c935 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["esbenp.prettier-vscode", "chenglou92.rescript-vscode"] +} diff --git a/CHANGELOG.md b/CHANGELOG.md index b84fef4c6..a46ed2ce6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,5 @@ # Changelog - This changelog documents significant changes that caused a new version in the manual, or other related resources. We don't create a version fork for every minor release, and try to make docs "append only" as much as possible. Usually when we introduce a new feature we add a `since 9.0` annotation to a specific section, and be done with it. @@ -13,8 +12,7 @@ Here are the notes on major changes we did, and how the version corresponds to s ### latest -- 9.1 related - - +- ## 9.1 related ### v9.0 (v8.3 - v9.0) @@ -34,5 +32,3 @@ Here are the notes on major changes we did, and how the version corresponds to s ### v8.0.0 (v6 - v8.3) - Docs with Reason / OCaml syntax before the new syntax - - diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fb223a8fc..d80d2ea86 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,8 +6,8 @@ Please make sure to check out our [Code of Conduct](CODE_OF_CONDUCT.md) and make ## Ways to contribute -- Writing docs for the manual (Check for issues that are marked with a [`manual`](https://github.com/reason-association/rescript-lang.org/issues?q=is%3Aissue+is%3Aopen+label%3A"manual") and [`help wanted`](https://github.com/reason-association/rescript-lang.org/issues?q=is%3Aissue+is%3Aopen+label%3A"help+wanted") tag) -- Joining in discussions on our [issue tracker](https://github.com/reason-association/rescript-lang.org/issues) +- Writing docs for the manual (Check for issues that are marked with a [`manual`](https://github.com/rescript-lang/rescript-lang.org/issues?q=is%3Aissue+is%3Aopen+label%3A"manual") and [`help wanted`](https://github.com/rescript-lang/rescript-lang.org/issues?q=is%3Aissue+is%3Aopen+label%3A"help+wanted") tag) +- Joining in discussions on our [issue tracker](https://github.com/rescript-lang/rescript-lang.org/issues) - Give feedback for improvements (incomplete / missing docs, bad wording, search user experience / design, etc.) - Advanced: Help building platform features (design system, automatic testing, markdown parsing, etc.) @@ -16,7 +16,7 @@ Please make sure to check out our [Code of Conduct](CODE_OF_CONDUCT.md) and make ### Find an issue -Before you start any work or submit any PRs, make sure to check our [issue tracker](https://github.com/reason-association/rescript-lang.org/issues) for any issues or discussions on the topic. +Before you start any work or submit any PRs, make sure to check our [issue tracker](https://github.com/rescript-lang/rescript-lang.org/issues) for any issues or discussions on the topic. If you can't find any relevant issues, feel free to create a new one to start a discussion. We usually assign issues to a responsible person to prevent confusion and duplicate work, so always double check if an issue is currently being worked on, or talk to the current assignee to take over the task. @@ -24,15 +24,15 @@ If you can't find any relevant issues, feel free to create a new one to start a The project follows very specific goals and tries to deliver the highest value with the least amount of resources. Please help us focus on the tasks at hand and don't submit any code / bigger refactorings without any proper discussion on the issue tracker. Otherwise your PR might not be accepted! -If you need inspiration on what to work on, you can check out issues tagged with [`good first issue`](https://github.com/reason-association/rescript-lang.org/issues?q=is%3Aissue+is%3Aopen+label%3A"good+first+issue") or [`help wanted`](https://github.com/reason-association/rescript-lang.org/issues?q=is%3Aissue+is%3Aopen+label%3A"help+wanted"). +If you need inspiration on what to work on, you can check out issues tagged with [`good first issue`](https://github.com/rescript-lang/rescript-lang.org/issues?q=is%3Aissue+is%3Aopen+label%3A"good+first+issue") or [`help wanted`](https://github.com/rescript-lang/rescript-lang.org/issues?q=is%3Aissue+is%3Aopen+label%3A"help+wanted"). ### Discuss an issue We really appreciate all input from users, community members and potential contributors. Please make sure to consider the other person's opinion and don't assume any common knowledge. -**Most importantly: Keep it professional and be nice to each other** +**Most importantly: Keep it professional and be nice to eachother** -There might be situations where others don't understand a proposed feature or have different opinions on certain writing styles. That's fine, discussions are always welcome! Communicate in clear actionables, make your plans clear and always stick to the original topic. +There might be situations where others don't understand a proposed feature or have different opinions on certain writing styles. That's fine, discussions are always welcome! Communicate in clear actionables, make your plans clear and always to stick to the original topic. If other contributors disagree with certain proposals and don't change their mind after longer discussions, please don't get discouraged when an issue gets closed / postponed. Everyone tries their best to make the platform better, and to look at it in another perspective: Closed issues are also a highly valuable resource for others to understand technical decisions later on. @@ -40,11 +40,11 @@ If other contributors disagree with certain proposals and don't change their min Open Source development can be a challenge to coordinate, so please make sure to block enough time to work on your tasks and show commitment when taking on some work. Let other contributors know if your time schedule changes significantly, and also let others know if you can't finish a task. -We value your voluntary work, and of course it's fine to step back from a ticket for any reason (we can also help you if you are getting stuck). Please talk to us in any case, otherwise we might re-assign the ticket to other contributors. +We value your voluntary work, and of course it's fine to step back from a ticket for any reasons (we can also help you if you are getting stuck). Please talk to us in any case, otherwise we might re-assign the ticket to other contributors. ### Communication Channels -- [Issue Tracker](https://github.com/reason-association/rescript-lang.org/issues) +- [Issue Tracker](https://github.com/rescript-lang/rescript-lang.org/issues) - [ReScript Discourse (General / mostly unrelated discussions)](http://forum.rescript-lang.org) ## Working on the rescript-lang.org @@ -55,7 +55,7 @@ We try to keep our contribution guidelines to a minimum. Please keep following r The less code we write, the better. If there's a way to do rendering on the server, or enhance existing markdown files, we prefer that over client-side rendering and external loading. -We also try to keep our third-party dependencies to a minimum. We use specific frameworks to make things work (`unified`, `remark`, `mdx`, `bs-platform`, etc). Please try to keep a small JS footprint, especially for client side code (to keep the bundle size small). +We also try to keep our third-party dependencies to a minimum. We use specific frameworks to make things work (`unified`, `remark`, `mdx`, `bs-platform`, etc). Please try to keep a small JS footprint, especially for client side code (to keep the bundle size small). ### Think about the target audience & UX @@ -66,13 +66,13 @@ Always check if there are any designs for certain UI components and think about ### Technical Writing (Documentation) - Think and write in a JS friendly mindset when explaining concepts / showing examples. -- No `foo` examples if somewhat possible. Try to establish practical context in your showcase examples. +- No `foo` examples if somewhat possible. Try to establish practical context in your show case examples. - No references to `OCaml`. ReScript is its own language, and we don't rely on external resources of our host language. - If possible, no references to `Reason` examples / external resources. Our goal is to migrate everything to ReScript syntax. ### Tailwind for CSS Development -We use [TailwindCSS](https://tailwindcss.com) for our component styling. Check out the [tailwind.config.js](tailwind.config.js) file for configured tailwind features, colors, border-radius values etc.. If you are not familiar with Tailwind, check out existing components for inspiration. +We use [TailwindCSS](https://tailwindcss.com) for our component styling. Check out the [tailwind.config.js](tailwind.config.js) file for configured tailwind features, colors, border-radius values etc.. If you are not familiar with Tailwind, check out existing components for inspiration. We sometimes also need to fall back to common css (with tailwind `@apply` directives to enforce our style system). You can find the CSS main entrypoint in [styles/main.css](styles/main.css). diff --git a/README.md b/README.md index 60b62b0c2..7837c53ad 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,21 @@ -[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v1.4%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md) - - - # rescript-lang.org +[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v1.4%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md) + This is the official documentation platform for the [ReScript](https://rescript-lang.org) programming language. -**Please report any technical issues with ReScript to the [compiler repository](https://github.com/rescript-lang/rescript-compiler).** +**Please report any technical issues with ReScript to the [compiler repository](https://github.com/rescript-lang/rescript).** **In case you are missing some specific documentation:** + - Some language / compiler feature may not be documented yet - Create an issue to let us know what you are missing - In case you want to contribute missing docs, please refer to our [Contribution section](#contributing) ## System Requirements -- `node@16.x` or higher (for ES6 module compat) -- `npm@7` or higher (package-lock v2) +- `node@20` or higher +- `npm@10` or higher ## Setup @@ -27,10 +26,7 @@ npm i # Initial build npx rescript -# Only needed for initial clone (or content H2 changes) -npm run update-index - -# Build the index data +# Build the index data. Only needed for initial clone (or content H2 changes) npm run update-index # In a new tab @@ -42,7 +38,7 @@ open localhost:3000 In case you want to run ReScript in watchmode: ```sh -npx rescript build -w +npx rescript -w ``` ## Build Index Data @@ -82,9 +78,10 @@ build specific pages (file `index_data/x.json` not found). ### Markdown Codeblock Tests We check the validity of our code examples marked with: -- `` ```res example `` (ReScript code snippet) -- `` ```res sig `` (signature) -- `` ```res prelude `` (ReScript code snippet available for all subsequent code snippets) + +- ` ```res example ` (ReScript code snippet) +- ` ```res sig ` (signature) +- ` ```res prelude ` (ReScript code snippet available for all subsequent code snippets) Run the checks with: diff --git a/_blogposts/2020-08-10-bucklescript-is-rebranding.mdx b/_blogposts/2020-08-10-bucklescript-is-rebranding.mdx index f924b55eb..fb0d54ca7 100644 --- a/_blogposts/2020-08-10-bucklescript-is-rebranding.mdx +++ b/_blogposts/2020-08-10-bucklescript-is-rebranding.mdx @@ -21,6 +21,7 @@ We're pleased to announce that BuckleScript is getting a brand new name: **ReScr ## Community Situation BuckleScript started with the idea that **JavaScript programmers deserved a great typed language with a fast and lean toolchain**. This idea took root and, over the years, we've gradually accomplished feats such as: + - a state of the art compiled JavaScript output that rivals hand-written JS, - a fast & reliable toolchain much needed in front-end and Node development, - various JS interop features that spawned an ecosystem of well typed libraries, @@ -28,6 +29,7 @@ BuckleScript started with the idea that **JavaScript programmers deserved a grea - [and recently](/blog/bucklescript-8-1-new-syntax), a fresh syntax made by a major contributor of Reason's old syntax. These developments have attracted many people into our community. But one bigger challenge persisted: newcomers dropped out at the sheer amount of extra incongruent tools and learning overhead from having to understand OCaml concepts, Reason concepts, and BuckleScript's concepts. Take, for example, what's required to make a React app using BuckleScript: + - Knowledge of React. - Knowledge of JS. - Knowledge of BuckleScript's specific bindings to React (that we've tried hard to keep to a minimum). @@ -43,6 +45,7 @@ The adoption barrier is real, and it's about time we finally solve it. ## The Rebranding Today, we'll start to truly unify the various BuckleScript-related projects under the ReScript umbrella. This includes: + - The compiler, build system and the new syntax unified under a single installation. - Doubling down on editor tooling for ReScript usage. - A single documentation site (this one), which unifies all the docs and greatly trims down on redundant and stale info. @@ -61,7 +64,7 @@ There's no dedicated name for the syntax anymore. It's simply called the ReScrip **Will there be a migration script to gradually convert our code to the new syntax?** -Yes. See our [migration page](/docs/manual/latest/migrate-from-bucklescript-reason). You can mix and match old and new code for a smoother transition. +Yes. See our [migration page](/docs/manual/v10.0.0/migrate-from-bucklescript-reason). You can mix and match old and new code for a smoother transition. **Will BuckleScript (now ReScript) break my existing code?** @@ -99,7 +102,7 @@ The ReScript community will comprise of the majority of the old Reason community **The new changes make me worried about the future support I'm going to receive from the team.** -_Retrospective edit, in 2021_: suffice to day that we've been doing well =). +_Retrospective edit, in 2021_: suffice to say that we've been doing well =). ## Conclusion diff --git a/_blogposts/2020-08-28-new-rescript-logo.mdx b/_blogposts/2020-08-28-new-rescript-logo.mdx index 0d40e3903..1e4c275fb 100644 --- a/_blogposts/2020-08-28-new-rescript-logo.mdx +++ b/_blogposts/2020-08-28-new-rescript-logo.mdx @@ -15,11 +15,14 @@ ReScript is the evolution and fusion of Reason and BuckleScript. As we're a desi Here it is! - - - + The old Reason and BuckleScript logo had many limitations: + - The icons didn't really work well on round Social Media profile images (or round shapes at all). - There's no guideline on how the logo works inverted, or on colored background. - The large red rectangle makes it difficult to balance the logo with other elements. @@ -27,15 +30,21 @@ The old Reason and BuckleScript logo had many limitations: The new logo addresses all these and more: - + ## Creating Meaning Through Simple Shapes A minimal logo design is achieved by putting aside all distractions while focusing on legibility, meaning and small details like clear lines, interesting perspective and depth. - - - + **The letter "r"**, composed of two shapes, is inspired by Albers, a german-born American Bauhaus artist and typographer. An object should be simple, beautiful, functional and accessible for everyone - a statement which applies to ReScript's principles perfectly. @@ -43,7 +52,7 @@ A minimal logo design is achieved by putting aside all distractions while focusi **The red app-shaped background** references the vibrant, playful applications our developers are empowered to create with ReScript. -**The Logotype** ("rescript") complements the brand mark with its clean look and its embrace of technology while retaining a functional look. +**The Logotype** ("rescript") complements the brand mark with its clean look and its embrace of technology while retaining a functional look. We'd like to position ReScript to be a community of product-first developers who care about the fit & finish of their work, while keeping an eye on the quality of their engineering. This interplay of design and engineering is a hard-to-achieve but beautifully worthwhile sweet spot that's frequently been missing in the programmer community; our vibrant logo is our renewed symbolic step toward this mission. Come along with us on our journey! diff --git a/_blogposts/2020-09-25-release-8-3-2.mdx b/_blogposts/2020-09-25-release-8-3-2.mdx index b092f53d4..2ad89accb 100644 --- a/_blogposts/2020-09-25-release-8-3-2.mdx +++ b/_blogposts/2020-09-25-release-8-3-2.mdx @@ -74,7 +74,7 @@ To get the build output, instead of communicating through IPC, we adopted a simp This makes the editor integration build-system agnostic, it does not need talk to the build system directly. It also makes our build tool work with other watchers including Facebook's [watchman](https://facebook.github.io/watchman/). -Watchman is a more scalable watcher tool for some specific platforms and less memory hungry, however, we still need a watchman-client to get the output of triggered job. +Watchman is a more scalable watcher tool for some specific platforms and less memory hungry, however, we still need a watchman-client to get the output of triggered job. We write the output to `.compiler.log` per each build, allowing clients to read compiler diagnostics when they want. ## A better algorithm for removing stale outputs @@ -86,12 +86,12 @@ There are two ways of removing staled artifacts, the second one is introduced in - Based on live analysis and prebuilt-in knowledge -We scan `lib/bs` directory and check some dangling cm{i,t,j,ti} files, if it does not exist in +We scan `lib/bs` directory and check some dangling `cm{i,t,j,ti}` files, if it does not exist in the current build set, it is considered stale artifacts. If it is `cmt` file, it would trigger some hooks of `genType`, notably -cmt-rm. - Based on previous build logs -We store previous compilation stats. If a file is in the previous compiler output, but no longer in the output of the new build, it is considered stale and can be removed. -it is considered stale output which can be removed. + We store previous compilation stats. If a file is in the previous compiler output, but no longer in the output of the new build, it is considered stale and can be removed. + it is considered stale output which can be removed. In general, strategy two is more reliable and efficient. @@ -100,11 +100,9 @@ In general, strategy two is more reliable and efficient. However, strategy one is easier for tooling like `genType`. Not every tool has knowledge of the build system. - Sometimes a combination of both strategies is needed. -- When removing .cm* files, we use the first strategy. -- When removing generated javascript, we use strategy two, - +- When removing .cm\* files, we use the first strategy. +- When removing generated javascript, we use strategy two, Happy Hacking! diff --git a/_blogposts/2020-09-25-release-8-3.mdx b/_blogposts/2020-09-25-release-8-3.mdx index a3a629be9..71874227f 100644 --- a/_blogposts/2020-09-25-release-8-3.mdx +++ b/_blogposts/2020-09-25-release-8-3.mdx @@ -17,9 +17,7 @@ It's focused on type safety, performance and JS interop. It used to be called Bu npm i bs-platform@8.3.0 ``` -The changes are listed [here](https://github.com/rescript-lang/rescript-compiler/blob/master/Changes.md#83), this is a large release, and we will go through some highlighted changes. - - +The changes are listed [here](https://github.com/rescript-lang/rescript/blob/master/Changes.md#83), this is a large release, and we will go through some highlighted changes. ## Lightweight FFI attributes without `bs.` prefix @@ -27,18 +25,19 @@ In this release, we make the `bs.` prefix optional, this will make the FFI less For example, the old externals for `readFileAsUtf8Sync` used to be written like this - ```res @bs.val @bs.module("fs") external readFileAsUtf8Sync: (string, @bs.as("utf8") _) => string = "readFileSync" ``` + ```reason [@bs.val] [@bs.module "fs"] external readFileAsUtf8Sync: (string, [@bs.as "utf8"] _) => string = "readFileSync"; ``` + ```ocaml external readFileAsUtf8Sync : string -> (_[@bs.as "utf8"]) -> string = "readFileSync" [@@bs.val] [@@bs.module "fs"] ``` @@ -52,11 +51,13 @@ It can now be simplified as ```res @val @module("fs") external readFileAsUtf8Sync: (string, @as("utf8") _) => string = "readFileSync" ``` + ```reason [@val] [@module "fs"] external readFileAsUtf8Sync: (string, [@as "utf8"] _) => string = "readFileSync"; ``` + ```ocaml external readFileAsUtf8Sync : string -> (_[@as "utf8"]) -> string = "readFileSync" [@@val] [@@module "fs"] @@ -70,8 +71,7 @@ with the exception of the following two that don't have abbreviations: - `bs.send.pipe` : this attribute was deprecated in favor of `bs.send`; you can still use the existing one for backward compatibility. - `bs.splice` : this attribute was deprecated in favor of `bs.variadic`; you can still use the existing one for -backward compatibility. - + backward compatibility. ## default import in Es6 support @@ -84,11 +84,13 @@ If you use es6 module output, the default bindings will be compiled properly now let a = input("hello") ``` + ```reason [@module "hello"] external input: string => string = "default"; let a = input("hello"); ``` + ```ocaml external input : string -> string = "default" [@@module "hello"] @@ -104,7 +106,6 @@ import Hello from "hello"; var a = Hello("hello"); ``` - ## Customized js file extension support Now user can pick up their js file extension support per module format: @@ -122,12 +123,10 @@ Now user can pick up their js file extension support per module format: ## More flexible filename support -To have better integration with other [JS infrastructures](https://github.com/rescript-lang/rescript-compiler/issues/4624), +To have better integration with other [JS infrastructures](https://github.com/rescript-lang/rescript/issues/4624), for example, Next.js/React Native, we allow file names like `404.res`, `Button.Android.res` so that it can just be picked up by those tools - - ## Better type based inference for pattern `let {a,b,c} = value` Previously, for code like this: @@ -144,6 +143,7 @@ let f = (u: N.t) => { x + 1 } /* type error */ ``` + ```reason module N = { type t = {x: int}; @@ -154,6 +154,7 @@ let f = (u: N.t) => { x + 1; }; /* type error */ ``` + ```ocaml module N = struct type t = { diff --git a/_blogposts/2020-11-17-editor-support-custom-operators-and-more.mdx b/_blogposts/2020-11-17-editor-support-custom-operators-and-more.mdx index 661b6ea36..43b21fe30 100644 --- a/_blogposts/2020-11-17-editor-support-custom-operators-and-more.mdx +++ b/_blogposts/2020-11-17-editor-support-custom-operators-and-more.mdx @@ -8,7 +8,7 @@ description: | Update on what we're doing around the end of 2020 and early next year. --- -import Video from "src/components/Video" +import Video from "src/components/Video"; ## Upcoming Improvements @@ -28,7 +28,7 @@ Hongbo continues to improve the compiler experience in monorepo-like setups. Exp ## Docs -Patrick is [rearranging the React documentation](https://github.com/reason-association/rescript-lang.org/pull/96), and continues to improve the main documentation site with Cheng Lou. +Patrick is [rearranging the React documentation](https://github.com/rescript-lang/rescript-lang.org/pull/96), and continues to improve the main documentation site with Cheng Lou. ## Syntax diff --git a/_blogposts/2020-11-26-editor-support-release-1-0.mdx b/_blogposts/2020-11-26-editor-support-release-1-0.mdx index 090f101b6..08ae79ed0 100644 --- a/_blogposts/2020-11-26-editor-support-release-1-0.mdx +++ b/_blogposts/2020-11-26-editor-support-release-1-0.mdx @@ -9,12 +9,12 @@ description: | Type hints, jump to definition, error diagnostics, and more. --- - ## Editor Integration Has Finally Landed Thank you so much for the wait! **Here are all the features:** + - Highlighting - Formatting - Diagnostics @@ -32,4 +32,8 @@ We'll keep on iterating on the polish of the plugins, and release better [Sublim Happy thanksgiving! - + diff --git a/_blogposts/2020-12-07-release-8-4.mdx b/_blogposts/2020-12-07-release-8-4.mdx index a51a0dfe0..bc7484feb 100644 --- a/_blogposts/2020-12-07-release-8-4.mdx +++ b/_blogposts/2020-12-07-release-8-4.mdx @@ -19,7 +19,7 @@ It's focused on type safety, performance and JS interop. It used to be called Bu npm i bs-platform@8.4.2 ``` -The changes are listed [here](https://github.com/rescript-lang/rescript-compiler/blob/master/Changes.md#841). +The changes are listed [here](https://github.com/rescript-lang/rescript/blob/master/Changes.md#841). We will go through some highlighted changes. @@ -33,11 +33,10 @@ In this release, we fix the integrity of `bsb -make-world` which allows user to The fix is well implemented that people who don't do such modifications will not pay for it. This is one of the highest desired feature request based on the -[user feedback](https://github.com/rescript-lang/rescript-compiler/issues/4361#issuecomment-739538789), so we will expand a bit here why it is tricky -to implement it without compromising performance. +[user feedback](https://github.com/rescript-lang/rescript/issues/4361#issuecomment-739538789), so we will expand a bit here why it is tricky to implement it without compromising performance. In ReScript compilation scheme, dependencies as packages are treated as a black box, -changes of dependencies should be *transitive*. The is due to that we have cross module +changes of dependencies should be _transitive_. The is due to that we have cross module optimizations and the binary interface itself is a hash of its dependencies. So for a package dependency chain: A -> B -> C, if A changes and B does not change, C still needs get rebuilt. Because the intermediate output of B may still change due to the change of A. @@ -68,6 +67,6 @@ of such stale outptu, such stale `List.cmi` file will break the integrity of the In this release, we introduced a more robust algorithm that will always remove stale output before the build so that such integrity is not broken. -Last but not the least, we continue improving the readability, debuggability of the [generated output](https://github.com/rescript-lang/rescript-compiler/pull/4858) : ) +Last but not the least, we continue improving the readability, debuggability of the [generated output](https://github.com/rescript-lang/rescript/pull/4858) : ) Happy Hacking! -- Hongbo Zhang diff --git a/_blogposts/2021-02-09-release-9-0.mdx b/_blogposts/2021-02-09-release-9-0.mdx index a1221f18b..1238d0788 100644 --- a/_blogposts/2021-02-09-release-9-0.mdx +++ b/_blogposts/2021-02-09-release-9-0.mdx @@ -16,25 +16,24 @@ ReScript is a robustly typed language that compiles to efficient and human-reada Use `npm` to install the newest [9.0.1 release](https://www.npmjs.com/package/bs-platform/v/9.0.1) with the following command: -``` +```sh npm install bs-platform@9.0.1 ``` You can also try our new release in the [Online Playground](/try). -In this post we will highlight the most notable changes. The full changelog for this release can be found [here](https://github.com/rescript-lang/rescript-compiler/blob/master/Changes.md#90). +In this post we will highlight the most notable changes. The full changelog for this release can be found [here](https://github.com/rescript-lang/rescript/blob/master/Changes.md#90). ## Compiler Improvements ### New External Stdlib Configuration -This is a long-awaited [feature request](https://github.com/rescript-lang/rescript-compiler/pull/2171). +This is a long-awaited [feature request](https://github.com/rescript-lang/rescript/pull/2171). Our compiler comes with a set of stdlib modules (such as `Belt`, `Pervasives`, etc.) for core functionality. Compiled ReScript code relies on the JS runtime version of these stdlib modules. In previous versions, users couldn't ship their compiled JS code without defining a `package.json` dependency on `bs-platform`. Whenever a ReScript developer wanted to publish a package just for pure JS consumption / lean container deployment, they were required to use a bundler to bundle up their library / stdlib code, which made things way more complex and harder to understand. - To fix this problem, we introduced an `external-stdlib` configuration that allows specifying a pre-compiled stdlib npm package (`@rescript/std`). More details on how to use that feature can be found in our [External Stdlib](/docs/manual/latest/build-external-stdlib) documentation. ### Less Bundle Bloat when Adding ReScript @@ -47,7 +46,7 @@ We made a small [demo repo](https://github.com/bobzhang/zero-cost-rescript) and ### Improved Code Generation for Pattern Matching -We fine-tuned our pattern matching engine to optimize the JS output even more. Here is an example of a pretty substantial optimization, based on [this issue](https://github.com/rescript-lang/rescript-compiler/issues/4924): +We fine-tuned our pattern matching engine to optimize the JS output even more. Here is an example of a pretty substantial optimization, based on [this issue](https://github.com/rescript-lang/rescript/issues/4924): ```res type test = @@ -67,8 +66,8 @@ The snippet above will compile to the following JS output: ```js -function test(x){ - return x === 0 +function test(x) { + return x === 0; } ``` @@ -82,12 +81,11 @@ function test(x) { } ``` - As you can see, the 9.0 compiler removes all the unnecessary `typeof` checks! -This is possible because our optimizer will try to analyze several predicates and get rid of redundant ones. More diffs can be found [here](https://github.com/rescript-lang/rescript-compiler/pull/4927/files?file-filters%5B%5D=.js). +This is possible because our optimizer will try to analyze several predicates and get rid of redundant ones. More diffs can be found [here](https://github.com/rescript-lang/rescript/pull/4927/files?file-filters%5B%5D=.js). Another important improvement is that we fixed the pattern match offset issue, which lead to the consequence that magic numbers will not be generated for complex pattern matches anymore. @@ -153,7 +151,6 @@ type animation = [ #\"ease-in" | #\"ease-out" ] We introduced this change to allow easier interop with existing JS string enums. In pure ReScript code, we'd still recommend our users to stick with valid identifier names instead (e.g. `easeIn` instead of `ease-in`). - ## Breaking Changes This release comes with a minor breaking change that shouldn't have much impact on the upgrade of existing codebases. @@ -209,5 +206,4 @@ For example, we are tinkering with the idea on using WASM to replace Camlp4, and We will discuss these topics in a separate development post, but we are already excited about the new possibilities this will bring within the compiler toolchain. - Happy Hacking! diff --git a/_blogposts/2021-03-03-rescript-association-rebranding.mdx b/_blogposts/2021-03-03-rescript-association-rebranding.mdx index b330f4be9..e216cb619 100644 --- a/_blogposts/2021-03-03-rescript-association-rebranding.mdx +++ b/_blogposts/2021-03-03-rescript-association-rebranding.mdx @@ -25,7 +25,7 @@ Founded in 2018, the ReScript Association provides a legal and financial foundat - [rescript-lang.org](https://rescript-lang.org). - [Community forum](https://forum.rescript-lang.org) & server. - ReScript related domains and [analytics data](https://simpleanalytics.com/rescript-lang.org). -- [genType’s](https://github.com/rescript-association/genType) release automation. +- [genType’s](https://github.com/rescript-lang/genType) release automation. - Help maintaining editor related tools such as [rescript-vscode](https://github.com/rescript-lang/rescript-vscode), [vim-rescript](https://github.com/rescript-lang/vim-rescript) and the underlying [editor-support](https://github.com/rescript-lang/rescript-editor-support). - Design & logo assets (together with our designer) for all of ReScript. - Helping out on upcoming [ocaml.org](https://ocaml.org) work. @@ -48,6 +48,7 @@ High quality, long-term Open Source work doesn’t come from some good words and If your company relies on the ReScript platform for building commercial products, please consider supporting our efforts by [sending a donation](https://rescript-association.org/donate). It’s the best way to future proof your product’s foundation. Alternatively, you can sponsor individual members like [ryyppy](https://github.com/sponsors/ryyppy/) on GitHub Sponsors. We want to take this opportunity to thank our previous and active sponsors: + - [Tezos Foundation](https://tezos.foundation) (2020-21) - [Ahrefs](https://ahrefs.com) (2019) - [OCaml Software Foundation](https://ocaml-sf.org) (2018-19) diff --git a/_blogposts/2021-05-07-release-9-1.mdx b/_blogposts/2021-05-07-release-9-1.mdx index e5573cf00..56b4e8b15 100644 --- a/_blogposts/2021-05-07-release-9-1.mdx +++ b/_blogposts/2021-05-07-release-9-1.mdx @@ -10,7 +10,7 @@ description: | ## Exciting Improvements in ReScript 9.1 -Our recent few releases of ReScript contains [lots of improvements](https://github.com/rescript-lang/rescript-compiler/blob/3134392a364b70c9c172aa6c1dbaa1ac6580265d/Changes.md#91), among which are a few standout features we'd like to further promote. Hope you're as excited as we are about these! It goes without saying, our [updated editor plugin](https://forum.rescript-lang.org/t/ann-rescript-vscode-1-1-1-released/1542/3) works with the new releases. +Our recent few releases of ReScript contains [lots of improvements](https://github.com/rescript-lang/rescript/blob/3134392a364b70c9c172aa6c1dbaa1ac6580265d/Changes.md#91), among which are a few standout features we'd like to further promote. Hope you're as excited as we are about these! It goes without saying, our [updated editor plugin](https://forum.rescript-lang.org/t/ann-rescript-vscode-1-1-1-released/1542/3) works with the new releases. ### New NPM Package @@ -41,6 +41,7 @@ The default `rescript` is equivalent to `rescript build` subcommand ``` Here's a table of translation, if you're upgrading your script that is currently using `bsc` and `bsb`: + - `bsc -format myFile.res`: `rescript format myFile.res` - `bsb`: `rescript build` \* - `bsb -make-world`: `rescript build -with-deps` \* @@ -53,7 +54,8 @@ This means that you can ditch your old `-make-world` (now the explicit `-with-de ### Polymorphic Variants for Numbers and Strings -*Drumrolls* +_Drumrolls_ + - Poly variants like `#1`, `#42` compile to JavaScript numbers. - Poly variants like `#hello`, `#world` compile to JavaScript Strings. @@ -159,6 +161,6 @@ let helloUnicode = (x) =>{ ## Conclusion -Don't miss our various other improvements in [our changelog](https://github.com/rescript-lang/rescript-compiler/blob/3134392a364b70c9c172aa6c1dbaa1ac6580265d/Changes.md#91). As always we try to keep our changes performant, lean and robust. We hope you'll enjoy these. +Don't miss our various other improvements in [our changelog](https://github.com/rescript-lang/rescript/blob/3134392a364b70c9c172aa6c1dbaa1ac6580265d/Changes.md#91). As always we try to keep our changes performant, lean and robust. We hope you'll enjoy these. See you next time! diff --git a/_blogposts/2021-06-25-roadmap-2021-and-new-landing-page.mdx b/_blogposts/2021-06-25-roadmap-2021-and-new-landing-page.mdx index 543106c1d..013f411a5 100644 --- a/_blogposts/2021-06-25-roadmap-2021-and-new-landing-page.mdx +++ b/_blogposts/2021-06-25-roadmap-2021-and-new-landing-page.mdx @@ -7,7 +7,7 @@ description: | Announcing our roadmap for 2021 / 2022, release cycle plans and new landing page. --- -import Image from "src/components/Image.mjs" +import Image from "src/components/Image.mjs"; ## Team Update @@ -21,7 +21,7 @@ It has almost been a year since we originally [launched our new ReScript brand]( - Accessible object system (no need for `Js.t`) - The release of our new `rescript` npm package and cli to replace `bs-platform` - Making every part of ReScript fully community owned -- etc. +- etc. Stay tuned, this is just the beginning! @@ -30,6 +30,7 @@ Stay tuned, this is just the beginning! We had some thorough discussions about the future of the project and outlined the most important milestones for the next upcoming releases. **Here's the gist:** + - Two release channels: `stable` and `experimental` - More predictable release dates and better migration steps - Better communication and discussion for breaking changes @@ -41,7 +42,11 @@ The detailed roadmap with all our planned changes (and definition of our release After several iterations, we are happy to announce our new [landing page](/). - + This is an incredible milestone for the documentation, and will act as a foundation for some cool new future improvements, such as: @@ -49,7 +54,6 @@ This is an incredible milestone for the documentation, and will act as a foundat - An interactive playground widget for the headline code examples - New starter templates and guides - -Furthermore, in case you are a **production user of ReScript** and you want to see your company logo highlighted on the landing page, please [open an issue](https://github.com/rescript-association/rescript-lang.org/issues) and let us know! +Furthermore, in case you are a **production user of ReScript** and you want to see your company logo highlighted on the landing page, please [open an issue](https://github.com/rescript-lang/rescript-lang.org/issues) and let us know! Happy hacking. diff --git a/_blogposts/2022-08-25-release-10-0-0.mdx b/_blogposts/2022-08-25-release-10-0-0.mdx index 0cd4ef112..9413fa21d 100644 --- a/_blogposts/2022-08-25-release-10-0-0.mdx +++ b/_blogposts/2022-08-25-release-10-0-0.mdx @@ -14,27 +14,33 @@ ReScript version 10 is available! Version 10 is a culmination of over a year's w npm install rescript@10 ``` -All changes are listed [here](https://github.com/rescript-lang/rescript-compiler/blob/10.0_release/CHANGELOG.md). Let's take a tour of a few of the features we're extra excited about. +All changes are listed [here](https://github.com/rescript-lang/rescript/blob/10.0_release/CHANGELOG.md). Let's take a tour of a few of the features we're extra excited about. ## Faster builds with native M1 support + Users with M1 chips should see a notable speedup, as the new ReScript version has full native support for M1. ## Better ergonomics with Unicode support in regular strings + You can now use Unicode characters directly in regular strings. This will now produce what you'd expect: + ```res let str = "Σ" ``` You can also pattern match on Unicode characters: + ```res -switch someCharacter { - | 'Σ' => "what a fine Unicode char" - | _ => "Unicode is fun" +switch someCharacter { + | 'Σ' => "what a fine Unicode char" + | _ => "Unicode is fun" } ``` ## Experimental optional record fields + Previously, a record would always have to define all its optional fields: + ```res type user = { name: string, @@ -51,6 +57,7 @@ let userWithAge = { age: Some(34), } ``` + For small records like the one above, this is typically fine. But for records with many fields, the friction of having to always set all optional fields explicitly adds up. This release has a new experimental feature called optional record fields, allowing you to rewrite the above to this instead: ```res @@ -79,7 +86,7 @@ Version 10 brings the building blocks needed for a number of exciting new featur ## Upgrade guide -Please see the detailed [changelog](https://github.com/rescript-lang/rescript-compiler/blob/10.0_release/CHANGELOG.md) for a list of breaking changes. +Please see the detailed [changelog](https://github.com/rescript-lang/rescript/blob/10.0_release/CHANGELOG.md) for a list of breaking changes. Each breaking change lists suggestions on how to upgrade your project. This can be out of your control in case of dependencies. In that case, please raise issues with the maintainers of those libraries. diff --git a/_blogposts/2023-02-02-release-10-1.mdx b/_blogposts/2023-02-02-release-10-1.mdx index 9c2eeb077..18628c6b4 100644 --- a/_blogposts/2023-02-02-release-10-1.mdx +++ b/_blogposts/2023-02-02-release-10-1.mdx @@ -27,7 +27,7 @@ This version comes with two major language improvements we've all been waiting f Alongside the major changes, there have been many bugfixes and other improvements that won't be covered in this post. -Feel free to check the [Changelog](https://github.com/rescript-lang/rescript-compiler/blob/master/CHANGELOG.md#1011) for all the details. +Feel free to check the [Changelog](https://github.com/rescript-lang/rescript/blob/master/CHANGELOG.md#1011) for all the details. ## New `async` / `await` syntax @@ -70,11 +70,10 @@ Way easier on the eyes, don't you think? Note that the new `promise` type is ful Additionally, we also introduced the `Js.Promise2` module as a stepping stone to migrate `Js.Promise` based code to a first-pipe (->) friendly solution. For the daily practise you'll almost always want to use `async` / `await` to handle promises. -(*Sidenote*: We are also well aware that our users want a solution to unify `Belt`, `Js` and `Js.xxx2` and have a fully featured "standard library" instead of adding more `Js.xxx2` modules. Good news is that we have a solution in the pipeline to fix this. `Js.Promise2` was introduced to ease the process later on and is not supposed to be the panacea of promise handling.) +(_Sidenote_: We are also well aware that our users want a solution to unify `Belt`, `Js` and `Js.xxx2` and have a fully featured "standard library" instead of adding more `Js.xxx2` modules. Good news is that we have a solution in the pipeline to fix this. `Js.Promise2` was introduced to ease the process later on and is not supposed to be the panacea of promise handling.) If you are already using a third-party promise library like [ryyppy/rescript-promise](https://github.com/ryyppy/rescript-promise) or similar, there's no need to migrate any existing code. Introduce `async` / `await` gradually in your codebase as you go. - ## New JSX v4 syntax ReScript 10.1 now ships with JSX v4. Here's what's new: @@ -83,7 +82,7 @@ ReScript 10.1 now ships with JSX v4. Here's what's new: - **Two new transformation modes**. JSX v4 comes with a `classic` mode (= `React.createElement`) and `automatic` mode (= `jsx-runtime` calls). The latter is the new default, moving forward with `rescript/react@0.11` and `React@18`. - **Allow mixing JSX configurations on the project and module level.** Gradually mix and match JSX transformations and modes without migrating any old code! - **Pass `prop` types** to `@react.component`. You can now fine tune `@react.component` with your specific prop type needs. Very useful for libraries and frameworks to define component interfaces. -- **Less boilerplate when using `React.Context`**. Check out our [example](/docs/react/latest/migrate-react#reactcontext) for comparison. +- **Less boilerplate when using `React.Context`**. Check out our [example](/docs/react/latest/migrate-react#reactcontext) for comparison. - **Revisited props spread operator.** This will allow users to spread records in JSX without sacrificing their sanity. Note that this implementation has harder constraints than its JS counterpart. (requires `rescript/react@0.11` or higher) - **Better type inference of props.** Type inference when passing e.g. variants that are defined in the same module as the component is much improved. With the earlier JSX version, you'd often need to write code like this in order for the compiler to understand which variant you're passing: ` + + preludeSection +
+
+ {"Overview"->React.string} +
+ Array.length == 1 ? classNameActive : "")} + href={node.path->Array.join("/")}> + {node.name->React.string} + + {moduleRoute->Array.length === 1 ? subMenu : React.null} +
+
{"submodules"->React.string}
+ {node.children + ->Array.toSorted((v1, v2) => String.compare(v1.name, v2.name)) + ->Array.map(renderNode) + ->React.array} + + + } +} + +type module_ = { + id: string, + docstrings: array, + deprecated: Null.t, + name: string, + items: array, +} + +type api = { + module_: module_, + toctree: node, +} + +type params = {slug: array} +type props = result + +module MarkdownStylize = { + @react.component + let make = (~content, ~rehypePlugins) => { + let components = { + ...MarkdownComponents.default, + h2: MarkdownComponents.default.h3->Obj.magic, + } + content + } +} + +module DeprecatedMessage = { + @react.component + let make = (~deprecated) => { + switch deprecated->Null.toOption { + | Some(content) => + +

{"Deprecated"->React.string}

+ +
+ | None => React.null + } + } +} + +module DocstringsStylize = { + @react.component + let make = (~docstrings, ~slugPrefix) => { + let rehypePlugins = + [Rehype.WithOptions([Plugin(Rehype.slug), SlugOption({prefix: slugPrefix ++ "-"})])]->Some + + let content = switch docstrings->Array.length > 1 { + | true => docstrings->Array.slice(~start=1) + | false => docstrings + }->Array.join("\n") + +
+ +
+ } +} + +let default = (props: props) => { + let (isSidebarOpen, setSidebarOpen) = React.useState(_ => false) + let toggleSidebar = () => setSidebarOpen(prev => !prev) + let router = Next.Router.useRouter() + + let title = switch props { + | Ok({module_: {id}}) => id + | _ => "API" + } + + let children = { + open Markdown + switch props { + | Ok({module_: {id, name, docstrings, items}}) => + let valuesAndType = items->Array.map(item => { + switch item { + | Value({name, signature, docstrings, deprecated}) => + let code = String.replaceRegExp(signature, /\\n/g, "\n") + let slugPrefix = "value-" ++ name + +

{name->React.string}

+ + + +
+ | Type({name, signature, docstrings, deprecated}) => + let code = String.replaceRegExp(signature, /\\n/g, "\n") + let slugPrefix = "type-" ++ name + +

{name->React.string}

+ + + +
+ } + }) + + <> +

{name->React.string}

+ + {valuesAndType->React.array} + + | _ => React.null + } + } + + let rightSidebar = switch props { + | Ok({module_: {items}}) if Array.length(items) > 0 => +
+ +
+ | _ => React.null + } + + let version = Url.parse(router.asPath)->Url.getVersionString + + let sidebar = switch props { + | Ok({toctree, module_: {items}}) => + + | Error(_) => React.null + } + + let prefix = {Url.name: "API", href: "/docs/manual/" ++ (version ++ "/api")} + + let breadcrumbs = ApiLayout.makeBreadcrumbs(~prefix, router.asPath) + + + children + +} + +module Data = { + type t = { + mainModule: Dict.t, + tree: Dict.t, + } + + let dir = Node.Path.resolve("data", "api") + + let getVersion = (~version: string, ~moduleName: string) => { + open Node + + let pathModule = Path.join([dir, version, `${moduleName}.json`]) + + let moduleContent = Fs.readFileSync(pathModule)->JSON.parseOrThrow + + let content = switch moduleContent { + | Object(dict) => dict->Some + | _ => None + } + + let toctree = switch Path.join([dir, version, "toc_tree.json"]) + ->Fs.readFileSync + ->JSON.parseOrThrow { + | Object(dict) => dict->Some + | _ => None + } + + switch (content, toctree) { + | (Some(content), Some(toctree)) => Some({mainModule: content, tree: toctree}) + | _ => None + } + } +} + +let processStaticProps = (~slug: array, ~version: string) => { + let moduleName = slug->Belt.Array.getExn(0) + let content = Data.getVersion(~version, ~moduleName) + + let modulePath = slug->Array.join("/") + + switch content { + | Some({mainModule, tree}) => + switch mainModule->Dict.get(modulePath) { + | Some(json) => + let {items, docstrings, deprecated, name} = Docgen.decodeFromJson(json) + let id = switch json { + | Object(dict) => + switch Dict.get(dict, "id") { + | Some(String(s)) => s + | _ => "" + } + | _ => "" + } + + let items = items->Array.map(item => + switch item { + | Docgen.Value({id, docstrings, signature, name, ?deprecated}) => + Value({ + id, + docstrings, + signature, + name, + deprecated: deprecated->Null.fromOption, + }) + | Type({id, docstrings, signature, name, ?deprecated, ?detail}) => + let detail = switch detail { + | Some(kind) => + switch kind { + | Docgen.Record({items}) => + let items = items->Array.map(({ + name, + docstrings, + signature, + optional, + ?deprecated, + }) => { + { + name, + docstrings, + signature, + optional, + deprecated: deprecated->Null.fromOption, + } + }) + Record({items: items})->Null.make + | Variant({items}) => + let items = items->Array.map(({name, docstrings, signature, ?deprecated}) => { + { + name, + docstrings, + signature, + deprecated: deprecated->Null.fromOption, + } + }) + + Variant({items: items})->Null.make + | Signature(_) => Null.null + } + | None => Null.null + } + Type({ + id, + docstrings, + signature, + name, + deprecated: deprecated->Null.fromOption, + detail, + }) + | _ => assert(false) + } + ) + let module_ = { + id, + name, + docstrings, + deprecated: deprecated->Null.fromOption, + items, + } + + let toctree = tree->Dict.get(moduleName) + + switch toctree { + | Some(toctree) => Ok({module_, toctree: (Obj.magic(toctree): node)}) + | None => Error(`Failed to find toctree to ${modulePath}`) + } + + | None => Error(`Failed to get key for ${modulePath}`) + } + | None => Error(`Failed to get API Data for version ${version} and module ${moduleName}`) + } +} + +let getStaticPropsByVersion = async (ctx: {"params": params, "version": string}) => { + let params = ctx["params"] + let version = ctx["version"] + + let slug = params.slug + + let result = processStaticProps(~slug, ~version) + + {"props": result} +} + +let getStaticPathsByVersion = async (~version: string) => { + open Node + + let pathDir = Path.join([Data.dir, version]) + + let slugs = + pathDir + ->Fs.readdirSync + ->Array.reduce([], (acc, file) => { + switch file == "toc_tree.json" { + | true => acc + | false => + let paths = switch Path.join2(pathDir, file) + ->Fs.readFileSync + ->JSON.parseOrThrow { + | Object(dict) => + dict + ->Dict.keysToArray + ->Array.map(modPath => modPath->String.split("/")) + | _ => acc + } + Array.concat(acc, paths) + } + }) + + let paths = slugs->Array.map(slug => + { + "params": { + "slug": slug, + }, + } + ) + + {"paths": paths, "fallback": false} +} diff --git a/src/ApiDocs.resi b/src/ApiDocs.resi new file mode 100644 index 000000000..7b9092be6 --- /dev/null +++ b/src/ApiDocs.resi @@ -0,0 +1,15 @@ +type params = {slug: array} +type props + +let default: props => React.element + +let getStaticPropsByVersion: {"params": params, "version": string} => promise<{"props": props}> + +let getStaticPathsByVersion: ( + ~version: string, +) => promise<{ + "fallback": bool, + "paths": array<{ + "params": {"slug": array}, + }>, +}> diff --git a/src/Blog.res b/src/Blog.res index 1a9a786d4..392f7fc3e 100644 --- a/src/Blog.res +++ b/src/Blog.res @@ -18,13 +18,13 @@ module Link = Next.Link let defaultPreviewImg = "/static/Art-3-rescript-launch.jpg" // For encoding reasons, see https://shripadk.github.io/react/docs/jsx-gotchas.html -let middleDotSpacer = " " ++ (Js.String.fromCharCode(183) ++ " ") +let middleDotSpacer = " " ++ (String.fromCharCode(183) ++ " ") module Badge = { @react.component let make = (~badge: BlogFrontmatter.Badge.t) => { let bgColor = switch badge { - | Preview | Roadmap | Release => "bg-turtle" + | Preview | Roadmap | Release | Community => "bg-turtle" | Testing => "bg-orange" } @@ -39,44 +39,35 @@ module Badge = { } } -module CategorySelector = { - type selection = - | All - | Archived - let renderTab = (~text: string, ~isActive: bool, ~onClick) => { - let active = "bg-gray-20 text-gray-80 rounded py-1" -
- {React.string(text)} -
- } +type category = + /** Actually only unarchived */ + | All + | Archived +module CategorySelector = { @react.component - let make = (~selected: selection, ~onSelected: selection => unit) => { + let make = (~selected: category) => { let tabs = [All, Archived]
- {Belt.Array.map(tabs, tab => { - let onClick = evt => { - evt->ReactEvent.Mouse.preventDefault - onSelected(tab) - } - + {tabs + ->Array.map(tab => { // Deep comparison here! let isActive = selected == tab - - let text = switch tab { - | All => "All" - | Archived => "Archived" + let text = (tab :> string) + let href = switch tab { + | All => "/blog" + | Archived => "/blog/archived" } - - renderTab(~isActive, ~text, ~onClick) - })->React.array} + let className = + switch isActive { + | true => "bg-gray-20 text-gray-80 rounded py-1" + | false => "hover:cursor-pointer bg-white hover:text-gray-80" + } ++ " px-4 inline-block" + {React.string(text)} + }) + ->React.array}
} } @@ -89,7 +80,7 @@ module BlogCard = { ~author as _: BlogFrontmatter.author, ~category: option=?, ~badge: option=?, - ~date: Js.Date.t, + ~date: Date.t, ~slug: string, ) =>
@@ -101,30 +92,26 @@ module BlogCard = { }} - - - { - let className = "absolute top-0 h-full w-full object-cover" - switch previewImg { - | Some(src) => - | None => - } + + { + let className = "absolute top-0 h-full w-full object-cover" + switch previewImg { + | Some(src) => + | None => } - + }
- - -

{React.string(title)}

-
+ +

{React.string(title)}

{switch category { | Some(category) => <> {React.string(category)} - {React.string(j` · `)} + {React.string(` · `)} | None => React.null }} @@ -141,39 +128,36 @@ module FeatureCard = { ~title: string="Unknown Title", ~author: BlogFrontmatter.author, ~badge: option=?, - ~date: Js.Date.t, + ~date: Date.t, ~category: option=?, ~firstParagraph: string="", ~slug: string, ) => { - let authorImg = - + let authorImg = switch author.imgUrl { + | "" => React.null + | imgUrl => +
+ +
+ }
-
@@ -217,42 +202,32 @@ module FeatureCard = { type params = {slug: string} -type props = { - posts: array, - archived: array, -} +type props = {posts: array, category: category} let default = (props: props): React.element => { - let {posts, archived} = props + let {posts, category} = props - let (currentSelection, setSelection) = React.useState(() => CategorySelector.All) - - let content = if Belt.Array.length(posts) === 0 { + let content = if Array.length(posts) === 0 { /*
{React.string("Currently no posts available")}
; */
{React.string("Blog not yet available")} {React.string("This blog is currently in the works.")}
} else { - let filtered = switch currentSelection { - | All => posts - | Archived => archived - } - - let result = switch Belt.Array.length(filtered) { + let result = switch Array.length(posts) { | 0 =>
{React.string("No posts for this category available...")}
| _ => - let first = Belt.Array.getExn(filtered, 0) - let rest = Js.Array2.sliceFrom(filtered, 1) + let first = Belt.Array.getExn(posts, 0) + let rest = Array.slice(posts, ~start=1) let featureBox =
Js.Null.toOption} + previewImg=?{first.frontmatter.previewImg->Null.toOption} title=first.frontmatter.title - badge=?{first.frontmatter.badge->Js.Null.toOption} + badge=?{first.frontmatter.badge->Null.toOption} author=first.frontmatter.author - firstParagraph=?{first.frontmatter.description->Js.Null.toOption} + firstParagraph=?{first.frontmatter.description->Null.toOption} date={first.frontmatter.date->DateStr.toDate} slug={BlogApi.blogPathToSlug(first.path)} /> @@ -263,12 +238,12 @@ let default = (props: props): React.element => { | rest =>
- {Js.Array2.map(rest, post => { - let badge = post.frontmatter.badge->Js.Null.toOption + {Array.map(rest, post => { + let badge = post.frontmatter.badge->Null.toOption Js.Null.toOption} + previewImg=?{post.frontmatter.previewImg->Null.toOption} title=post.frontmatter.title author=post.frontmatter.author ?badge @@ -287,17 +262,15 @@ let default = (props: props): React.element => { <>
-
- setSelection(_ => selection)} selected=currentSelection - /> +
+
result } - let overlayState = React.useState(() => false) + let (isOverlayOpen, setOverlayOpen) = React.useState(() => false) let title = "Blog | ReScript Documentation" <> @@ -306,16 +279,14 @@ let default = (props: props): React.element => { />
- +
- +
-
- content -
+
content
-
+