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
4 changes: 4 additions & 0 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ jobs:
run: yarn
- name: Test examples and hrefs
run: yarn test
- name: Check unused ReScript values and exports
run: yarn check:dead-code
- name: Test dead-code diagnostics
run: node --test scripts/__tests__/check-dead-code.test.mjs
# Confirms that Wrangler can start the Docs Pages and Guide local dev servers.
# This startup check intentionally excludes route-level application and Pages Function behavior.
Wrangler:
Expand Down
6 changes: 0 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ node_modules/
.next/
out/
apps/docs/out/
index_data/*.json
apps/docs/index_data/*.json

# Generated via docs test examples script
temp
Expand All @@ -36,9 +34,7 @@ apps/guide/src/**/*.mjs
apps/guide/src/**/*.jsx
packages/*/src/**/*.mjs
packages/*/src/**/*.jsx
apps/docs/scripts/gendocs.mjs
apps/docs/scripts/generate_*.mjs
apps/docs/scripts/gendocs.jsx
apps/docs/scripts/generate_*.jsx
apps/docs/scripts/LogAlgoliaEnvStatus.jsx
apps/docs/scripts/__tests__/**/*.jsx
Expand Down Expand Up @@ -80,8 +76,6 @@ apps/guide/__tests__/**/*.mjs
apps/guide/__tests__/**/*.jsx
apps/docs/e2e/**/*.mjs
apps/docs/e2e/**/*.jsx
!_shims.mjs
!_shims.jsx

# Yarn
.yarn/*
Expand Down
3 changes: 0 additions & 3 deletions .oxfmtrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"printWidth": 80,
"sortPackageJson": false,
"ignorePatterns": [
"!_shims.mjs",
"!apps/docs/public/_redirects",
".DS_Store",
".worktrees/",
Expand All @@ -17,7 +16,6 @@
"data/api/**/*.json",
"apps/docs/data/api/**/*.json",
"dist",
"apps/docs/index_data/*.json",
"node_modules/",
"apps/docs/out/",
"apps/docs/public/playground-bundles/",
Expand All @@ -33,7 +31,6 @@
"apps/docs/lib/",
".vercel",
"apps/docs/src/**/*.mjs",
"apps/docs/scripts/gendocs.mjs",
"apps/docs/scripts/generate_*.mjs",
"apps/docs/public/llms/manual/**/llm*.txt",
"apps/docs/public/llms/react/**/llm*.txt",
Expand Down
1 change: 0 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ data/ → Hand-curated data (API docs JSON, sidebar ordering)
styles/ → CSS files (Tailwind v4 config in main.css, custom utilities)
scripts/ → Build/codegen scripts (ReScript + JS)
functions/ → Cloudflare Pages Functions (e.g. OG image generation)
compilers/ → Bundled ReScript compiler versions (for the playground)
plugins/ → HighlightJS & CodeMirror plugins
public/ → Static assets (images, fonts, favicons)
__tests__/ → Vitest browser-mode tests (Playwright)
Expand Down
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,24 @@ Production crawler start URLs, ranking, and crawler schedules live in the Algoli
- `styles/`: Tailwind v4 theme and custom CSS
- `public/`: Static assets such as images, fonts, and favicons
- `plugins/`: HighlightJS, CodeMirror, and other content/build plugins
- `compilers/`: Bundled ReScript compiler versions for playground and example validation
- `__tests__/`: Vitest browser tests written in ReScript

Tailwind is configured in [`styles/main.css`](styles/main.css). There is no `tailwind.config.js`.

## Dead-code checks

`yarn check:dead-code` compiles every workspace and runs reanalyze across the
monorepo, including FFI exports. CI fails on unused values and exports. Bindings
whose names start with `_` are treated as intentional discards. Record fields,
variant cases, and argument diagnostics remain advisory because JavaScript and
FFI access can be invisible to the analyzer; inspect them with `yarn reanalyze`.

React Router and Cloudflare call exports from JavaScript. Their entry points are
marked `@live` individually in the `.resi` interface, or in `.res` when there is
no interface. Keep these annotations limited to real entry points and do not
duplicate them between files; check JavaScript imports and MDX mappings before
removing a reported export.

## Common Commands

| Command | Purpose |
Expand Down
29 changes: 0 additions & 29 deletions apps/docs/__tests__/Url_.test.res

This file was deleted.

2 changes: 1 addition & 1 deletion apps/docs/app/DocsRoot.resi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** Shared shell, token styles, and the stable Cypress bootstrap slot.
Runtime grammars belong to content routes and the playground. */
/** Keep server-rendered content visible; head stylesheets handle render blocking. */
@react.component
@react.component @live
let default: unit => Jsx.element
15 changes: 3 additions & 12 deletions apps/docs/app/DocsRoutes.resi
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
// Consumed by react-router.config.mjs and app/routes.js.
@live
let stdlibPaths: array<string>
let domPaths: array<string>
let beltPaths: array<string>
let stdlibRoutes: array<ReactRouter.Routes.t>
let domRoutes: array<ReactRouter.Routes.t>
let beltRoutes: array<ReactRouter.Routes.t>
let blogArticleRoutes: array<ReactRouter.Routes.t>
let docsManualRoutes: array<ReactRouter.Routes.t>
let docsReactRoutes: array<ReactRouter.Routes.t>
let docsGuidesRoutes: array<ReactRouter.Routes.t>
let communityRoutes: array<ReactRouter.Routes.t>
let syntaxLookupDetailRoutes: array<ReactRouter.Routes.t>
/** Keep homepage, playground, and content styles scoped to their route groups. */
@live
let default: array<ReactRouter.Routes.t>
3 changes: 2 additions & 1 deletion apps/docs/app/layouts/ContentLayoutRoute.resi
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
type stylesheet = {rel: string, href: string}

@live
let links: unit => array<stylesheet>

/** Own content styles and runtime highlighting without adding a DOM wrapper. */
@react.component
@react.component @live
let default: unit => React.element
2 changes: 1 addition & 1 deletion apps/docs/app/layouts/DocsLayoutRoute.resi
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
@react.component
@react.component @live
let default: unit => React.element
3 changes: 2 additions & 1 deletion apps/docs/app/layouts/HomepageLayoutRoute.resi
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
type stylesheet = {rel: string, href: string}

@live
let links: unit => array<stylesheet>

/** Own homepage styles without adding a DOM wrapper. */
@react.component
@react.component @live
let default: unit => React.element
9 changes: 2 additions & 7 deletions apps/docs/app/routes/ApiDocs.res
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,8 @@ module DocstringsStylize = {
}
}

@react.componentWithProps
// reanalyze does not see the JSX props spread call in ApiRoute.
@live @react.componentWithProps
let make = (props: props) => {
let children = {
open Markdown
Expand Down Expand Up @@ -342,12 +343,6 @@ module Data = {
tree: Dict.t<JSON.t>,
}

let dir = try {
Node.Path.resolve("data", "api")
} catch {
| _ => ""
}

let getVersion = (~moduleName: string) => {
open Node

Expand Down
4 changes: 2 additions & 2 deletions apps/docs/app/routes/ApiOverviewRoute.resi
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
let categories: array<SidebarNav.Category.t>

type loaderData = {
compiledMdx: CompiledMdx.t,
title: string,
description: string,
}

@live
let loader: ReactRouter.Loader.t<loaderData>

@live
let default: unit => React.element
2 changes: 2 additions & 0 deletions apps/docs/app/routes/ApiRoute.resi
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ type rec apiItem = {
}

/** Loads API documentation after normalizing React Router data-request pathnames. */
@live
let loader: ReactRouter.Loader.t<loaderData>

@live
let default: unit => React.element
2 changes: 2 additions & 0 deletions apps/docs/app/routes/BlogArticleRoute.resi
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ type loaderData = {
title: string,
}

@live
let loader: ReactRouter.Loader.t<loaderData>

@live
let default: unit => React.element
3 changes: 2 additions & 1 deletion apps/docs/app/routes/BlogRoute.resi
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
type loaderData = {posts: array<BlogApi.post>, category: Blog.category}

@live
let loader: ReactRouter.Loader.t<loaderData>

@react.component
@react.component @live
let default: unit => React.element
1 change: 1 addition & 0 deletions apps/docs/app/routes/BrandRoute.resi
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
@live
let default: unit => React.element
2 changes: 2 additions & 0 deletions apps/docs/app/routes/CommunityRoute.resi
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ type loaderData = {
categories: array<SidebarNav.Category.t>,
}

@live
let loader: ReactRouter.Loader.t<loaderData>

@live
let default: unit => React.element
2 changes: 2 additions & 0 deletions apps/docs/app/routes/DocsGuidesRoute.resi
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ type loaderData = {
filePath: string,
}

@live
let loader: ReactRouter.Loader.t<loaderData>

@live
let default: unit => React.element
2 changes: 2 additions & 0 deletions apps/docs/app/routes/DocsManualRoute.resi
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ type loaderData = {
filePath: string,
}

@live
let loader: ReactRouter.Loader.t<loaderData>

@live
let default: unit => React.element
2 changes: 2 additions & 0 deletions apps/docs/app/routes/DocsReactRoute.resi
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ type loaderData = {
filePath: string,
}

@live
let loader: ReactRouter.Loader.t<loaderData>

@live
let default: unit => React.element
4 changes: 3 additions & 1 deletion apps/docs/app/routes/LandingPageRoute.resi
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ type fontPreload = {
}

/** Preload above-the-fold faces, including Inter 700 only at the desktop breakpoint. */
@live
let links: unit => array<fontPreload>

type loaderData = {playgroundData: LandingPagePlayground.playgroundData}

/** Prerender the fixed example so highlighting and URL compression stay off the client. */
@live
let loader: ReactRouter.Loader.t<loaderData>

@react.component
@react.component @live
let default: unit => React.element
2 changes: 1 addition & 1 deletion apps/docs/app/routes/NotFoundRoute.resi
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
@react.component
@react.component @live
let default: unit => React.element
2 changes: 2 additions & 0 deletions apps/docs/app/routes/PackagesRoute.resi
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
@live
let loader: unit => promise<Packages.props>
@live
let default: unit => React.element
53 changes: 0 additions & 53 deletions apps/docs/app/routes/SyntaxLookup.res
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,6 @@ module Category = {
| _ => Other
}
}

@react.component
let make = (~title, ~children) => {
<div>
<h3 className="font-sans font-medium text-gray-100 tracking-wide text-14 uppercase mb-2">
{React.string(title)}
</h3>
<div className="flex flex-wrap"> children </div>
</div>
}
}

module Status = {
Expand Down Expand Up @@ -119,15 +109,6 @@ module Item = {
}
}

type itemInfo = {
id: string,
keywords: array<string>,
name: string,
summary: string,
category: Category.t,
status: Status.t,
}

module Tag = {
@react.component
let make = (~deprecated: bool, ~text: string, ~href) => {
Expand Down Expand Up @@ -174,40 +155,6 @@ type state =
| ShowFiltered(string, array<Item.t>) // (search, filteredItems)
| ShowDetails(Item.t)

let scrollToTop = () => WebAPI.Window.scrollTo(window, ~options={left: 0.0, top: 0.0})

type params = {slug: string}

let decode = (json: JSON.t) => {
open JSON
switch json {
| Object(dict{
"id": String(id),
"keywords": Array(keywords),
"name": String(name),
"summary": String(summary),
"category": String(category),
"status": ?status,
}) => {
id,
name,
summary,
category: Category.fromString(category),
keywords: keywords->Array.filterMap(k =>
switch k {
| String(k) => Some(k)
| _ => None
}
),
status: switch status {
| Some(String(status)) => status->Status.fromString
| _ => Status.Active
},
}
| _ => throw(Failure(`Failed to decode SyntaxLookup. ${__LOC__}`))
}
}

type item = {
id: string,
keywords: array<string>,
Expand Down
2 changes: 2 additions & 0 deletions apps/docs/app/routes/SyntaxLookupDetailRoute.resi
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ type loaderData = {
description: string,
}

@live
let loader: ReactRouter.Loader.t<loaderData>

@live
let default: unit => React.element
2 changes: 2 additions & 0 deletions apps/docs/app/routes/SyntaxLookupRoute.resi
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
type loaderData = {mdxSources: array<SyntaxLookup.item>}
@live
let loader: ReactRouter.Loader.t<loaderData>
@live
let default: unit => React.element
// TODO: move this out of the route file so it can export only a single react component
let convert: Mdx.attributes => SyntaxLookup.item
Loading
Loading