Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5026728
chore: add yarn workspaces
jderochervlk Apr 25, 2026
9c7eb50
fix: honor workspace resolutions at root
jderochervlk Apr 25, 2026
3bc1c9a
chore: move docs app into workspace
jderochervlk Apr 25, 2026
b136bda
chore: update workspace root tooling
jderochervlk Apr 25, 2026
26d2f1e
fix: generate docs scripts before index updates
jderochervlk Apr 25, 2026
c95c842
fix: make root build work from clean checkout
jderochervlk Apr 26, 2026
5237c1a
fix: resolve docs workspace paths
jderochervlk Apr 26, 2026
b962da6
fix: update repository links for docs workspace
jderochervlk Apr 26, 2026
b991130
fix: update deployment workflows for docs workspace
jderochervlk Apr 26, 2026
ec10200
fix: update formatter ignores for docs workspace
jderochervlk Apr 26, 2026
9814ff6
fix: run docs formatter from repo root
jderochervlk Apr 26, 2026
a444f75
fix: correct users source link
jderochervlk Apr 26, 2026
12a98e0
Merge branch 'master' of https://github.com/rescript-lang/rescript-la…
jderochervlk Apr 27, 2026
0d8e8f8
fix: load docs env from workspace root
jderochervlk Apr 27, 2026
4222f00
fix: handle nested public hrefs in docs checks
jderochervlk Apr 27, 2026
d5b8df0
fix: add root rescript monorepo config
jderochervlk Apr 27, 2026
9788098
refactor: split playground into workspace packages
jderochervlk Apr 27, 2026
0c45cb5
Merge remote-tracking branch 'origin/master' into codex/pr-1283-merge…
jderochervlk May 4, 2026
a7fee72
feat: add guide MVP
jderochervlk May 4, 2026
83a0f00
feat: persist guide editor state
jderochervlk May 4, 2026
2b6fb61
feat: add guide checkpoint progress
jderochervlk May 4, 2026
42d6c6d
feat: add second guide lesson
jderochervlk May 4, 2026
7101509
fix: support guide lesson back navigation
jderochervlk May 4, 2026
e8cc5a4
fix: keep guide output during compilation
jderochervlk May 4, 2026
a511db2
feat: add guide lesson back button
jderochervlk May 4, 2026
9636370
fix: enable completed guide done action
jderochervlk May 4, 2026
e56e0f0
feat: load guide lessons from mdx
jderochervlk May 4, 2026
078657d
fix: address guide review feedback
jderochervlk May 5, 2026
89abdac
refactor: group guide state hooks
jderochervlk May 5, 2026
d46e5eb
test: split guide coverage
jderochervlk May 5, 2026
941277b
refactor: share Babel bindings with playground
jderochervlk May 5, 2026
b662772
docs: explain shared Babel bindings
jderochervlk May 5, 2026
d086372
refactor: simplify Babel bindings
jderochervlk May 6, 2026
62620f5
chore: align guide app config
jderochervlk May 6, 2026
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
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ node_modules/
.next/
out/
apps/docs/out/
apps/guide/out/
index_data/*.json
apps/docs/index_data/*.json

Expand All @@ -25,12 +26,15 @@ apps/docs/temp-jsx-preserve
.merlin
lib/
apps/docs/lib/
apps/guide/lib/
packages/*/lib/

.vercel

apps/docs/src/**/*.mjs
apps/docs/src/**/*.jsx
apps/guide/src/**/*.mjs
apps/guide/src/**/*.jsx
packages/*/src/**/*.mjs
packages/*/src/**/*.jsx
apps/docs/scripts/gendocs.mjs
Expand All @@ -51,17 +55,26 @@ dist
build
apps/docs/dist
apps/docs/build
apps/guide/dist
apps/guide/build
.react-router
apps/docs/.react-router
apps/guide/.react-router
mdx-manifest.json
apps/docs/mdx-manifest.json

apps/docs/app/**/*.mjs
apps/docs/app/**/*.jsx
apps/guide/app/**/*.mjs
apps/guide/app/**/*.jsx
!apps/guide/app/root.jsx
!apps/guide/app/routes.jsx
apps/docs/functions/**/*.mjs
apps/docs/functions/**/*.jsx
apps/docs/__tests__/**/*.mjs
apps/docs/__tests__/**/*.jsx
apps/guide/__tests__/**/*.mjs
apps/guide/__tests__/**/*.jsx
apps/docs/e2e/**/*.mjs
apps/docs/e2e/**/*.jsx
!_shims.mjs
Expand Down Expand Up @@ -94,3 +107,4 @@ apps/docs/.env.local
!apps/docs/__tests__/__screenshots__/**/*
.vitest-attachments
apps/docs/.vitest-attachments
apps/guide/.vitest-attachments
68 changes: 41 additions & 27 deletions apps/docs/src/components/Search.res
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ let normalizeHitUrls = (items: array<DocSearch.docSearchHit>, ~siteUrl: string)
{...hit, url, url_without_anchor, hierarchy}
})

let navigator = (~siteUrl: string): DocSearch.navigator => {
let navigator = (~siteUrl: string, ~navigate: ReactRouter.navigate): DocSearch.navigator => {
navigate: ({itemUrl}) => {
ReactRouter.navigate(toRelativeSiteUrl(itemUrl, ~siteUrl))
navigate(toRelativeSiteUrl(itemUrl, ~siteUrl))
},
}

Expand Down Expand Up @@ -301,6 +301,44 @@ module ErrorBoundary = {
}
}

module ActiveDocSearch = {
@react.component
let make = (
~apiKey,
~appId,
~indexName,
~deactivateSearch: unit => unit,
~onClose: unit => unit,
) => {
let navigate = ReactRouter.useNavigate()

switch ReactDOM.querySelector("body") {
| Some(element) =>
ReactDOM.createPortal(
<ErrorBoundary onClose=deactivateSearch>
<DocSearch
apiKey
appId
indexName
navigator={navigator(~siteUrl=Env.root_url, ~navigate)}
transformItems={items => normalizeHitUrls(items, ~siteUrl=Env.root_url)}
hitComponent
onClose
initialScrollY={window.scrollY->Float.toInt}
searchParameters={
distinct: 3,
hitsPerPage: 20,
attributesToSnippet: ["content:9999"],
}
/>
</ErrorBoundary>,
element,
)
| None => React.null
}
}
}

@react.component
let make = () => {
let (state, setState) = React.useState(_ => Inactive)
Expand Down Expand Up @@ -392,31 +430,7 @@ let make = () => {
<Icon.MagnifierGlass className="fill-current" />
</button>
{switch state {
| Active =>
switch ReactDOM.querySelector("body") {
| Some(element) =>
ReactDOM.createPortal(
<ErrorBoundary onClose=deactivateSearch>
<DocSearch
apiKey=searchApiKey
appId
indexName
navigator={navigator(~siteUrl=Env.root_url)}
transformItems={items => normalizeHitUrls(items, ~siteUrl=Env.root_url)}
hitComponent
onClose
initialScrollY={window.scrollY->Float.toInt}
searchParameters={
distinct: 3,
hitsPerPage: 20,
attributesToSnippet: ["content:9999"],
}
/>
</ErrorBoundary>,
element,
)
| None => React.null
}
| Active => <ActiveDocSearch apiKey=searchApiKey appId indexName deactivateSearch onClose />
| Inactive => React.null
}}
</>
Expand Down
83 changes: 83 additions & 0 deletions apps/guide/__tests__/GuideCompilerFeedback_.test.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
open Vitest

test("maps compiler diagnostics into editor errors", async () => {
let locMsg: RescriptCompilerApi.LocMsg.t = {
fullMsg: "Full compiler error",
shortMsg: "Expected a string",
row: 2,
column: 7,
endRow: 2,
endColumn: 12,
}

let editorError = GuideCompilerFeedback.locMsgToEditorError(~kind=#Error, locMsg)

expect(editorError.row)->toBe(2)
expect(editorError.column)->toBe(7)
expect(editorError.endRow)->toBe(2)
expect(editorError.endColumn)->toBe(12)
expect(editorError.text)->toBe("Expected a string")

let outputLine =
GuideCompilerFeedback.compileFailToOutputLines(TypecheckErr([locMsg]))
->Array.get(0)
->Option.getOrThrow
expect(outputLine)->toBe("[E] Line 2, 7: Expected a string")
})

test("maps compiler type hints into hover hints", async () => {
let typeHint = RescriptCompilerApi.TypeHint.Binding({
start: {line: 1, col: 4},
end: {line: 1, col: 12},
hint: "string",
})

let hoverHint =
GuideCompilerFeedback.typeHintsToHoverHints([typeHint])->Array.get(0)->Option.getOrThrow

expect(hoverHint.start.line)->toBe(1)
expect(hoverHint.start.col)->toBe(4)
expect(hoverHint.end.line)->toBe(1)
expect(hoverHint.end.col)->toBe(12)
expect(hoverHint.hint)->toBe("string")
})

test("keeps the previous output while a successful compile waits for runtime logs", async () => {
let typeHint = RescriptCompilerApi.TypeHint.Binding({
start: {line: 1, col: 4},
end: {line: 1, col: 12},
hint: "string",
})

let outputUpdate = GuideCompilerFeedback.compilationResultToOutputUpdate(
Success({
jsCode: "let value = 52;",
warnings: [],
typeHints: [typeHint],
time: 1.0,
}),
)

expect(outputUpdate->Option.isNone)->toBe(true)
})

test("shows compiler errors as output updates", async () => {
let locMsg: RescriptCompilerApi.LocMsg.t = {
fullMsg: "Full compiler error",
shortMsg: "Expected a string",
row: 2,
column: 7,
endRow: 2,
endColumn: 12,
}

let output =
GuideCompilerFeedback.compilationResultToOutputUpdate(
Fail(TypecheckErr([locMsg])),
)->Option.getOrThrow

expect(output.status)->toBe("Compiler error")
expect(output.diagnostics->Array.get(0)->Option.getOrThrow)->toBe(
"[E] Line 2, 7: Expected a string",
)
})
18 changes: 18 additions & 0 deletions apps/guide/__tests__/GuideCompilerSettings_.test.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
open Vitest

test("selects the latest stable ReScript compiler with ESM output", async () => {
let version =
GuideCompilerSettings.latestStableVersion([
"v12.1.0-alpha.1",
"v11.1.4",
"v12.0.0",
"v12.2.0-beta.1",
"v12.1.3",
])
->Option.getOrThrow
->Semver.toString

expect(version)->toBe("v12.1.3")
expect(GuideCompilerSettings.moduleSystem)->toBe("esmodule")
expect(GuideCompilerSettings.warnFlags->String.includes("-109"))->toBe(true)
})
Loading
Loading