diff --git a/.yarn/patches/@rescript-react-npm-0.14.2-b830f5af4f.patch b/.yarn/patches/@rescript-react-npm-0.14.2-b830f5af4f.patch new file mode 100644 index 000000000..f01366881 --- /dev/null +++ b/.yarn/patches/@rescript-react-npm-0.14.2-b830f5af4f.patch @@ -0,0 +1,117 @@ +diff --git a/rescript.json b/rescript.json +index 599e1f6777dcf8806780daba11ad6745d088aced..1ed044b3005d9941b62ae4ba0c1f339dded4ef03 100644 +--- a/rescript.json ++++ b/rescript.json +@@ -7,6 +7,6 @@ + "sources": [{ "dir": "src", "subdirs": true }], + "package-specs": [{ "module": "commonjs", "in-source": true }], + "suffix": ".bs.js", +- "bs-dev-dependencies": [], +- "bsc-flags": [] ++ "dev-dependencies": [], ++ "compiler-flags": [] + } +diff --git a/src/React.res b/src/React.res +index 4eb876a264c10e0b0f08f97162386ddebf798cd9..0e5f16c887056ff2d162028577656349cab1a4a4 100644 +--- a/src/React.res ++++ b/src/React.res +@@ -47,7 +47,7 @@ type fragmentProps = {children?: element} + type ref<'value> = {mutable current: 'value} + + @module("react") +-external createRef: unit => ref> = "createRef" ++external createRef: unit => ref> = "createRef" + + module Children = { + @module("react") @scope("Children") +@@ -82,7 +82,7 @@ module Context = { + external createContext: 'a => Context.t<'a> = "createContext" + + @module("react") +-external forwardRef: (('props, Js.Nullable.t>) => element) => component<'props> = ++external forwardRef: (('props, Nullable.t>) => element) => component<'props> = + "forwardRef" + + @module("react") +@@ -257,56 +257,56 @@ external usePromise: promise<'a> => 'a = "use" + @module("react") external useRef: 'value => ref<'value> = "useRef" + + @module("react") +-external useImperativeHandleOnEveryRender: (Js.Nullable.t>, unit => 'value) => unit = ++external useImperativeHandleOnEveryRender: (Nullable.t>, unit => 'value) => unit = + "useImperativeHandle" + + @module("react") +-external useImperativeHandle: (Js.Nullable.t>, unit => 'value, 'deps) => unit = ++external useImperativeHandle: (Nullable.t>, unit => 'value, 'deps) => unit = + "useImperativeHandle" + + @module("react") + external useImperativeHandle0: ( +- Js.Nullable.t>, ++ Nullable.t>, + unit => 'value, + @as(json`[]`) _, + ) => unit = "useImperativeHandle" + + @module("react") +-external useImperativeHandle1: (Js.Nullable.t>, unit => 'value, array<'a>) => unit = ++external useImperativeHandle1: (Nullable.t>, unit => 'value, array<'a>) => unit = + "useImperativeHandle" + + @module("react") +-external useImperativeHandle2: (Js.Nullable.t>, unit => 'value, ('a, 'b)) => unit = ++external useImperativeHandle2: (Nullable.t>, unit => 'value, ('a, 'b)) => unit = + "useImperativeHandle" + + @module("react") +-external useImperativeHandle3: (Js.Nullable.t>, unit => 'value, ('a, 'b, 'c)) => unit = ++external useImperativeHandle3: (Nullable.t>, unit => 'value, ('a, 'b, 'c)) => unit = + "useImperativeHandle" + + @module("react") + external useImperativeHandle4: ( +- Js.Nullable.t>, ++ Nullable.t>, + unit => 'value, + ('a, 'b, 'c, 'd), + ) => unit = "useImperativeHandle" + + @module("react") + external useImperativeHandle5: ( +- Js.Nullable.t>, ++ Nullable.t>, + unit => 'value, + ('a, 'b, 'c, 'd, 'e), + ) => unit = "useImperativeHandle" + + @module("react") + external useImperativeHandle6: ( +- Js.Nullable.t>, ++ Nullable.t>, + unit => 'value, + ('a, 'b, 'c, 'd, 'e, 'f), + ) => unit = "useImperativeHandle" + + @module("react") + external useImperativeHandle7: ( +- Js.Nullable.t>, ++ Nullable.t>, + unit => 'value, + ('a, 'b, 'c, 'd, 'e, 'f, 'g), + ) => unit = "useImperativeHandle" +diff --git a/src/ReactDOM.res b/src/ReactDOM.res +index fbd564bf4d35eb044eae8b5c7f06b11b4e7358de..c5a9e6381c83ebef9729510ebed67398c17378ea 100644 +--- a/src/ReactDOM.res ++++ b/src/ReactDOM.res +@@ -82,8 +82,8 @@ type domRef = JsxDOM.domRef + + module Ref = { + type t = domRef +- type currentDomRef = React.ref> +- type callbackDomRef = Js.nullable => option unit> ++ type currentDomRef = React.ref> ++ type callbackDomRef = Nullable.t => option unit> + + external domRef: currentDomRef => domRef = "%identity" + external callbackDomRef: callbackDomRef => domRef = "%identity" diff --git a/.yarn/patches/@rescript-webapi-npm-0.1.0-experimental-0781ac8-50def7723d.patch b/.yarn/patches/@rescript-webapi-npm-0.1.0-experimental-0781ac8-50def7723d.patch new file mode 100644 index 000000000..5ed814120 --- /dev/null +++ b/.yarn/patches/@rescript-webapi-npm-0.1.0-experimental-0781ac8-50def7723d.patch @@ -0,0 +1,60 @@ +diff --git a/package.json b/package.json +index 2f84ef58d1bf7f2f6782aeb7240fd0724b225ffa..80140c3cc8d345e09e64705ef07982091bf5534e 100644 +--- a/package.json ++++ b/package.json +@@ -53,6 +53,6 @@ + "sharp": "^0.34.0" + }, + "peerDependencies": { +- "rescript": ">=12.0.0 <13" ++ "rescript": ">=12.0.0 <14" + } + } +diff --git a/src/Fetch/FormData.res b/src/Fetch/FormData.res +index 709f31077b8daf3e7a4c136bfb61b3b9df4e31d9..478f1b2b2bf2f3f95e787d1f320c226a0cede535 100644 +--- a/src/Fetch/FormData.res ++++ b/src/Fetch/FormData.res +@@ -50,13 +50,13 @@ external has: (t, string) => bool = "has" + [Read more on MDN](https://developer.mozilla.org/docs/Web/API/FormData/entries) + */ + @send +-external entries: t => Iterator.t<(string, formDataEntryValue)> = "entries" ++external entries: t => Iterator.t<(string, formDataEntryValue), unit, unknown> = "entries" + + /** + [Read more on MDN](https://developer.mozilla.org/docs/Web/API/FormData/keys) + */ + @send +-external keys: t => Iterator.t = "keys" ++external keys: t => Iterator.t = "keys" + + /** + [Read more on MDN](https://developer.mozilla.org/docs/Web/API/FormData/set) +diff --git a/src/URL/URLSearchParams.res b/src/URL/URLSearchParams.res +index 845a9f1654fb17e545e0dbd1716c7784f2029192..0e0d64287d1397e8d50b796317ccf4407f5ef8f2 100644 +--- a/src/URL/URLSearchParams.res ++++ b/src/URL/URLSearchParams.res +@@ -46,7 +46,7 @@ Returns key/value pairs in the same order as they appear in the query string. + [Read more on MDN](https://developer.mozilla.org/docs/Web/API/URLSearchParams/entries) + */ + @send +-external entries: t => Iterator.t<(string, string)> = "entries" ++external entries: t => Iterator.t<(string, string), unit, unknown> = "entries" + + /** + Returns the first value associated to the given search parameter. +@@ -74,7 +74,7 @@ Returns an iterator allowing iteration through all keys contained in this object + [Read more on MDN](https://developer.mozilla.org/docs/Web/API/URLSearchParams/keys) + */ + @send +-external keys: t => Iterator.t = "keys" ++external keys: t => Iterator.t = "keys" + + /** + Sets the value associated to a given search parameter to the given value. If there were several values, delete the others. +@@ -101,4 +101,4 @@ Returns an iterator allowing iteration through all values contained in this obje + [Read more on MDN](https://developer.mozilla.org/docs/Web/API/URLSearchParams/values) + */ + @send +-external values: t => Iterator.t = "values" ++external values: t => Iterator.t = "values" diff --git a/apps/docs/__tests__/BlogArticleBehavior_.test.res b/apps/docs/__tests__/BlogArticleBehavior_.test.res index 6b0f0d317..a628f1ff5 100644 --- a/apps/docs/__tests__/BlogArticleBehavior_.test.res +++ b/apps/docs/__tests__/BlogArticleBehavior_.test.res @@ -1,7 +1,7 @@ open ReactRouter open Vitest -@get external textContent: WebAPI.DOMAPI.element => string = "textContent" +@get external textContent: DomTypes.element => string = "textContent" let mockAuthor: BlogFrontmatter.author = { username: "test-author", @@ -33,12 +33,12 @@ test("blog article marks body content for DocSearch crawling", async () => { , ) - switch document->WebAPI.Document.querySelector("article.DocSearch-content") { + switch document->Document.querySelector("article.DocSearch-content") { | Value(_) => () | Null => failwith("expected blog article body to be marked as DocSearch content") } - let lvl0 = switch document->WebAPI.Document.querySelector("article .DocSearch-lvl0") { + let lvl0 = switch document->Document.querySelector("article .DocSearch-lvl0") { | Value(element) => element | Null => failwith("expected blog article to render a DocSearch lvl0 marker") } diff --git a/apps/docs/__tests__/BreadcrumbsBehavior_.test.res b/apps/docs/__tests__/BreadcrumbsBehavior_.test.res index 4b5739be5..769c81b8c 100644 --- a/apps/docs/__tests__/BreadcrumbsBehavior_.test.res +++ b/apps/docs/__tests__/BreadcrumbsBehavior_.test.res @@ -1,7 +1,7 @@ open ReactRouter open Vitest -@get external textContent: WebAPI.DOMAPI.element => string = "textContent" +@get external textContent: DomTypes.element => string = "textContent" test("breadcrumbs do not repeat the current page crumb when it is already included", async () => { await viewport(1440, 900) @@ -21,7 +21,7 @@ test("breadcrumbs do not repeat the current page crumb when it is already includ ) let _breadcrumbs = await screen->getByTestId("breadcrumbs") - let breadcrumbs = switch document->WebAPI.Document.querySelector("[data-testid='breadcrumbs']") { + let breadcrumbs = switch document->Document.querySelector("[data-testid='breadcrumbs']") { | Value(breadcrumbs) => breadcrumbs | Null => failwith("expected breadcrumbs") } diff --git a/apps/docs/__tests__/DocsLayoutBehavior_.test.res b/apps/docs/__tests__/DocsLayoutBehavior_.test.res index 41441c221..41449fc43 100644 --- a/apps/docs/__tests__/DocsLayoutBehavior_.test.res +++ b/apps/docs/__tests__/DocsLayoutBehavior_.test.res @@ -1,7 +1,7 @@ open ReactRouter open Vitest -@get external textContent: WebAPI.DOMAPI.element => string = "textContent" +@get external textContent: DomTypes.element => string = "textContent" let mockCategories: array = [ { @@ -43,21 +43,21 @@ test("docs layout marks the textual content for DocSearch crawling", async () => let _mainContent = await screen->getByTestId("side-layout-children") - let mainContent = switch document->WebAPI.Document.querySelector( + let mainContent = switch document->Document.querySelector( "[data-testid='side-layout-children']", ) { | Value(element) => element | Null => failwith("expected docs layout main content") } - let className = switch mainContent->WebAPI.Element.getAttribute("class") { + let className = switch mainContent->Element.getAttribute("class") { | Value(value) => value | Null => "" } expect(className->String.includes("DocSearch-content"))->toBe(true) - let lvl0 = switch document->WebAPI.Document.querySelector(".DocSearch-lvl0") { + let lvl0 = switch document->Document.querySelector(".DocSearch-lvl0") { | Value(element) => element | Null => failwith("expected docs layout to render a DocSearch lvl0 marker") } diff --git a/apps/docs/__tests__/DocsOverviewBehavior_.test.res b/apps/docs/__tests__/DocsOverviewBehavior_.test.res index 19fbe58fe..9e8bac660 100644 --- a/apps/docs/__tests__/DocsOverviewBehavior_.test.res +++ b/apps/docs/__tests__/DocsOverviewBehavior_.test.res @@ -12,7 +12,7 @@ test("docs overview uses unversioned docs links", async () => { , ) - let overviewLink = switch document->WebAPI.Document.querySelector( + let overviewLink = switch document->Document.querySelector( "a[href='/docs/manual/introduction']", ) { | Value(link) => link @@ -20,7 +20,7 @@ test("docs overview uses unversioned docs links", async () => { } await element(overviewLink)->toBeVisible - let genTypeLink = switch document->WebAPI.Document.querySelector( + let genTypeLink = switch document->Document.querySelector( "a[href='/docs/manual/typescript-integration']", ) { | Value(link) => link @@ -28,7 +28,7 @@ test("docs overview uses unversioned docs links", async () => { } await element(genTypeLink)->toBeVisible - switch document->WebAPI.Document.querySelector("a[href*='/docs/manual/v']") { + switch document->Document.querySelector("a[href*='/docs/manual/v']") { | Value(_) => failwith("expected docs overview to avoid versioned manual links") | Null => () } diff --git a/apps/docs/__tests__/LandingPageBehavior_.test.res b/apps/docs/__tests__/LandingPageBehavior_.test.res index fd26b9843..0fa4cae84 100644 --- a/apps/docs/__tests__/LandingPageBehavior_.test.res +++ b/apps/docs/__tests__/LandingPageBehavior_.test.res @@ -26,21 +26,20 @@ test( let _ = await screen->getByText("Edit this example in Playground") - let href = switch document->WebAPI.Document.querySelector("a[href*='/try?code=']") { + let href = switch document->Document.querySelector("a[href*='/try?code=']") { | Value(link) => - switch link->WebAPI.Element.getAttribute("href") { + switch link->Element.getAttribute("href") { | Value(href) => href | Null => failwith("expected landing page playground link to have an href") } | Null => failwith("expected to find the landing page playground link") } - let {pathname, searchParams} = WebAPI.URL.make(~url=href, ~base="https://rescript-lang.org") + let {pathname, searchParams} = URL.make(~url=href, ~base="https://rescript-lang.org") expect(pathname)->toBe("/try") - let compressedCode = - searchParams->WebAPI.URLSearchParams.get("code")->Nullable.make->Nullable.toOption + let compressedCode = searchParams->URLSearchParams.get("code")->Null.toOption let decodedCode = compressedCode @@ -63,14 +62,14 @@ test("landing page playground hero renders highlighted code tokens", async () => let _ = await screen->getByText("Write in ReScript") - let rescriptCodeBlock = switch document->WebAPI.Document.querySelector( + let rescriptCodeBlock = switch document->Document.querySelector( "[data-testid='landing-playground-hero'] code.lang-res", ) { | Value(codeBlock) => codeBlock | Null => failwith("expected landing playground hero to render the ReScript code block") } - let javascriptCodeBlock = switch document->WebAPI.Document.querySelector( + let javascriptCodeBlock = switch document->Document.querySelector( "[data-testid='landing-playground-hero'] code.lang-js", ) { | Value(codeBlock) => codeBlock @@ -92,7 +91,7 @@ test( , ) - let sourceSection = switch document->WebAPI.Document.querySelector( + let sourceSection = switch document->Document.querySelector( "[data-testid='landing-playground-hero']", ) { | Value(section) => section @@ -113,16 +112,16 @@ test( let _ = await snapshotScreen->getByTestId(sandboxTestId) - let sandbox = switch document->WebAPI.Document.querySelector( + let sandbox = switch document->Document.querySelector( "[data-testid='landing-playground-hero-sandbox']", ) { | Value(sandbox) => sandbox | Null => failwith("expected to find the sandboxed landing playground hero") } - let sandboxRect: WebAPI.DOMAPI.domRect = sandbox->WebAPI.Element.getBoundingClientRect + let sandboxRect: DomTypes.domRect = sandbox->Element.getBoundingClientRect - let rescriptCodeBlock = switch document->WebAPI.Document.querySelector( + let rescriptCodeBlock = switch document->Document.querySelector( "[data-testid='landing-playground-hero-sandbox'] code.lang-res", ) { | Value(codeBlock) => codeBlock @@ -130,7 +129,7 @@ test( failwith("expected sandboxed landing playground hero to render the ReScript code block") } - let javascriptCodeBlock = switch document->WebAPI.Document.querySelector( + let javascriptCodeBlock = switch document->Document.querySelector( "[data-testid='landing-playground-hero-sandbox'] code.lang-js", ) { | Value(codeBlock) => codeBlock diff --git a/apps/docs/__tests__/MarkdownComponentsBehavior_.test.res b/apps/docs/__tests__/MarkdownComponentsBehavior_.test.res index 9b7e1cc3c..3a33690b7 100644 --- a/apps/docs/__tests__/MarkdownComponentsBehavior_.test.res +++ b/apps/docs/__tests__/MarkdownComponentsBehavior_.test.res @@ -9,7 +9,7 @@ test("h1 keeps the generated markdown id for DocSearch", async () => { , ) - switch document->WebAPI.Document.querySelector("h1#heading-level-1") { + switch document->Document.querySelector("h1#heading-level-1") { | Value(_) => () | Null => failwith("expected markdown h1 to keep the generated id") } @@ -28,23 +28,23 @@ test("markdown headings expose explicit DocSearch hierarchy markers", async () = , ) - switch document->WebAPI.Document.querySelector("h1.DocSearch-lvl1#heading-level-1") { + switch document->Document.querySelector("h1.DocSearch-lvl1#heading-level-1") { | Value(_) => () | Null => failwith("expected h1 to expose DocSearch lvl1") } - switch document->WebAPI.Document.querySelector("h2.DocSearch-lvl2#heading-level-2") { + switch document->Document.querySelector("h2.DocSearch-lvl2#heading-level-2") { | Value(_) => () | Null => failwith("expected h2 to expose DocSearch lvl2") } - switch document->WebAPI.Document.querySelector("h3.DocSearch-lvl3#heading-level-3") { + switch document->Document.querySelector("h3.DocSearch-lvl3#heading-level-3") { | Value(_) => () | Null => failwith("expected h3 to expose DocSearch lvl3") } - switch document->WebAPI.Document.querySelector("h4.DocSearch-lvl4#heading-level-4") { + switch document->Document.querySelector("h4.DocSearch-lvl4#heading-level-4") { | Value(_) => () | Null => failwith("expected h4 to expose DocSearch lvl4") } - switch document->WebAPI.Document.querySelector("h5.DocSearch-lvl5#heading-level-5") { + switch document->Document.querySelector("h5.DocSearch-lvl5#heading-level-5") { | Value(_) => () | Null => failwith("expected h5 to expose DocSearch lvl5") } @@ -59,7 +59,7 @@ test("heading anchor links do not duplicate heading ids", async () => { , ) - let matches = document->WebAPI.Document.querySelectorAll("[id='duplicate-check']") + let matches = document->Document.querySelectorAll("[id='duplicate-check']") expect(matches.length)->toBe(1) }) @@ -77,22 +77,20 @@ test("heading anchor scroll offset clears the sticky docs nav", async () => { , ) - let target = switch document->WebAPI.Document.querySelector("#anchor-offset-target") { + let target = switch document->Document.querySelector("#anchor-offset-target") { | Value(target) => target | Null => failwith("expected heading anchor target") } - let tertiaryNav = switch document->WebAPI.Document.querySelector( - "[data-testid='anchor-tertiary']", - ) { + let tertiaryNav = switch document->Document.querySelector("[data-testid='anchor-tertiary']") { | Value(nav) => nav | Null => failwith("expected tertiary nav") } - target->WebAPI.Element.scrollIntoView_alignToTop + target->Element.scrollIntoViewAlignToTop - let targetRect: WebAPI.DOMAPI.domRect = target->WebAPI.Element.getBoundingClientRect - let tertiaryNavRect: WebAPI.DOMAPI.domRect = tertiaryNav->WebAPI.Element.getBoundingClientRect + let targetRect: DomTypes.domRect = target->Element.getBoundingClientRect + let tertiaryNavRect: DomTypes.domRect = tertiaryNav->Element.getBoundingClientRect expect(targetRect.top >= tertiaryNavRect.bottom)->toBe(true) await screen->unmount diff --git a/apps/docs/__tests__/Meta_.test.res b/apps/docs/__tests__/Meta_.test.res index 15cd8ed45..59e8b2287 100644 --- a/apps/docs/__tests__/Meta_.test.res +++ b/apps/docs/__tests__/Meta_.test.res @@ -1,9 +1,9 @@ open Vitest let getMetaContent = name => { - switch document->WebAPI.Document.querySelector(`meta[name='${name}']`) { + switch document->Document.querySelector(`meta[name='${name}']`) { | Value(element) => - switch element->WebAPI.Element.getAttribute("content") { + switch element->Element.getAttribute("content") { | Value(content) => content | Null => failwith(`expected ${name} meta tag to have content`) } @@ -12,9 +12,9 @@ let getMetaContent = name => { } let getMetaPropertyContent = property => { - switch document->WebAPI.Document.querySelector(`meta[property='${property}']`) { + switch document->Document.querySelector(`meta[property='${property}']`) { | Value(element) => - switch element->WebAPI.Element.getAttribute("content") { + switch element->Element.getAttribute("content") { | Value(content) => content | Null => failwith(`expected ${property} meta tag to have content`) } diff --git a/apps/docs/__tests__/Search_.test.res b/apps/docs/__tests__/Search_.test.res index e481ff699..8a0fe2d8c 100644 --- a/apps/docs/__tests__/Search_.test.res +++ b/apps/docs/__tests__/Search_.test.res @@ -502,7 +502,7 @@ test("active DocSearch enables Algolia Insights", async () => { , ) - let hasInsightsScript = switch WebAPI.Document.querySelector( + let hasInsightsScript = switch Document.querySelector( document, "script[src*='search-insights']", ) { diff --git a/apps/docs/__tests__/SyntaxLookupBehavior_.test.res b/apps/docs/__tests__/SyntaxLookupBehavior_.test.res index 94b8fbe10..8d6abeb61 100644 --- a/apps/docs/__tests__/SyntaxLookupBehavior_.test.res +++ b/apps/docs/__tests__/SyntaxLookupBehavior_.test.res @@ -1,7 +1,7 @@ open ReactRouter open Vitest -@get external textContent: WebAPI.DOMAPI.element => string = "textContent" +@get external textContent: DomTypes.element => string = "textContent" let mockItems: array = [ { @@ -53,12 +53,12 @@ test("syntax lookup detail marks active content for DocSearch crawling", async ( , ) - switch document->WebAPI.Document.querySelector(".DocSearch-content h1") { + switch document->Document.querySelector(".DocSearch-content h1") { | Value(heading) => expect(heading->textContent)->toBe("@as") | Null => failwith("expected active syntax detail to provide a DocSearch heading") } - let lvl0 = switch document->WebAPI.Document.querySelector(".DocSearch-content .DocSearch-lvl0") { + let lvl0 = switch document->Document.querySelector(".DocSearch-content .DocSearch-lvl0") { | Value(element) => element | Null => failwith("expected syntax detail to render a DocSearch lvl0 marker") } diff --git a/apps/docs/__tests__/visual/LandingPage_.test.res b/apps/docs/__tests__/visual/LandingPage_.test.res index fd8d8aabc..820b6d4e5 100644 --- a/apps/docs/__tests__/visual/LandingPage_.test.res +++ b/apps/docs/__tests__/visual/LandingPage_.test.res @@ -10,9 +10,7 @@ let snapshotSection = async (~width, ~height, ~sectionTestId, ~screenshotName) = , ) - let sourceSection = switch document->WebAPI.Document.querySelector( - `[data-testid="${sectionTestId}"]`, - ) { + let sourceSection = switch document->Document.querySelector(`[data-testid="${sectionTestId}"]`) { | Value(section) => section | Null => failwith(`expected to find section ${sectionTestId}`) } diff --git a/apps/docs/app/DocsRoutes.res b/apps/docs/app/DocsRoutes.res index 2992c859f..0900b9d39 100644 --- a/apps/docs/app/DocsRoutes.res +++ b/apps/docs/app/DocsRoutes.res @@ -1,7 +1,7 @@ open ReactRouter.Routes let stdlibPaths = { - let rawFile = await Node.Fs.readFile("./markdown-pages/docs/api/stdlib.json", "utf-8") + let rawFile = await NodeJs.Fs.readFile("./markdown-pages/docs/api/stdlib.json", "utf-8") let json = JSON.parseOrThrow(rawFile) switch json { | Object(json) => Dict.keysToArray(json) @@ -12,7 +12,7 @@ let stdlibPaths = { } let domPaths = { - let rawFile = await Node.Fs.readFile("./markdown-pages/docs/api/dom.json", "utf-8") + let rawFile = await NodeJs.Fs.readFile("./markdown-pages/docs/api/dom.json", "utf-8") let json = JSON.parseOrThrow(rawFile) switch json { | Object(json) => Dict.keysToArray(json) @@ -23,7 +23,7 @@ let domPaths = { } let beltPaths = { - let rawFile = await Node.Fs.readFile("./markdown-pages/docs/api/belt.json", "utf-8") + let rawFile = await NodeJs.Fs.readFile("./markdown-pages/docs/api/belt.json", "utf-8") let json = JSON.parseOrThrow(rawFile) switch json { | Object(json) => Dict.keysToArray(json) diff --git a/apps/docs/app/routes/ApiDocs.res b/apps/docs/app/routes/ApiDocs.res index 3d5df459b..d73a27fcd 100644 --- a/apps/docs/app/routes/ApiDocs.res +++ b/apps/docs/app/routes/ApiDocs.res @@ -343,13 +343,13 @@ module Data = { } let dir = try { - Node.Path.resolve("data", "api") + NodeJs.Path.resolve("data", "api") } catch { | _ => "" } let getVersion = (~moduleName: string) => { - open Node + open NodeJs let moduleContent = Fs.readFileSync(`markdown-pages/docs/api/${moduleName}.json`)->JSON.parseOrThrow diff --git a/apps/docs/app/routes/ApiOverviewRoute.res b/apps/docs/app/routes/ApiOverviewRoute.res index b267717c0..c2a2a6632 100644 --- a/apps/docs/app/routes/ApiOverviewRoute.res +++ b/apps/docs/app/routes/ApiOverviewRoute.res @@ -22,14 +22,14 @@ type loaderData = { } let loader: ReactRouter.Loader.t = async ({request}) => { - let {pathname} = WebAPI.URL.make(~url=request.url) + let {pathname} = URL.make(~url=request.url) let filePath = MdxFile.resolveFilePath( (pathname :> string), ~dir="markdown-pages/docs/manual", ~alias="docs/manual", ) - let raw = await Node.Fs.readFile(filePath, "utf-8") + let raw = await NodeJs.Fs.readFile(filePath, "utf-8") let {frontmatter}: MarkdownParser.result = MarkdownParser.parseSync(raw) let description = FrontmatterUtils.getField(frontmatter, "description") diff --git a/apps/docs/app/routes/ApiRoute.res b/apps/docs/app/routes/ApiRoute.res index d0bdde5d8..4117c4787 100644 --- a/apps/docs/app/routes/ApiRoute.res +++ b/apps/docs/app/routes/ApiRoute.res @@ -123,16 +123,16 @@ let makeBreadcrumbs = (~prefix: Url.breadcrumb, route: Path.t): list = async args => { let path = - WebAPI.URL.make(~url=args.request.url).pathname + URL.make(~url=args.request.url).pathname ->String.replace("/docs/manual/api/", "") ->String.split("/") let basePath = path[0]->Option.getUnsafe let apiDocs = switch basePath { - | "belt" => parseApi(await Node.Fs.readFile("./markdown-pages/docs/api/belt.json", "utf-8")) - | "dom" => parseApi(await Node.Fs.readFile("./markdown-pages/docs/api/dom.json", "utf-8")) - | _ => parseApi(await Node.Fs.readFile("./markdown-pages/docs/api/stdlib.json", "utf-8")) + | "belt" => parseApi(await NodeJs.Fs.readFile("./markdown-pages/docs/api/belt.json", "utf-8")) + | "dom" => parseApi(await NodeJs.Fs.readFile("./markdown-pages/docs/api/dom.json", "utf-8")) + | _ => parseApi(await NodeJs.Fs.readFile("./markdown-pages/docs/api/stdlib.json", "utf-8")) } let toctree = groupItems(apiDocs) diff --git a/apps/docs/app/routes/BlogArticle.res b/apps/docs/app/routes/BlogArticle.res index 84aec2179..eae85a7b5 100644 --- a/apps/docs/app/routes/BlogArticle.res +++ b/apps/docs/app/routes/BlogArticle.res @@ -100,6 +100,7 @@ module BlogHeader = { } } +@react.componentWithProps let make = (props: props) => { let {children, isArchived, frontmatter} = props diff --git a/apps/docs/app/routes/BlogArticle.resi b/apps/docs/app/routes/BlogArticle.resi index 47a9b97bb..7d7009ae9 100644 --- a/apps/docs/app/routes/BlogArticle.resi +++ b/apps/docs/app/routes/BlogArticle.resi @@ -9,4 +9,4 @@ type props = { frontmatter: BlogFrontmatter.t, } -let make: props => React.element +let make: React.component diff --git a/apps/docs/app/routes/BlogArticleRoute.res b/apps/docs/app/routes/BlogArticleRoute.res index 6644a1509..dcc36d5ee 100644 --- a/apps/docs/app/routes/BlogArticleRoute.res +++ b/apps/docs/app/routes/BlogArticleRoute.res @@ -5,14 +5,14 @@ type loaderData = { } let loader: ReactRouter.Loader.t = async ({request}) => { - let {pathname} = WebAPI.URL.make(~url=request.url) + let {pathname} = URL.make(~url=request.url) let filePath = MdxFile.resolveFilePath( (pathname :> string), ~dir="markdown-pages/blog", ~alias="blog", ) - let raw = await Node.Fs.readFile(filePath, "utf-8") + let raw = await NodeJs.Fs.readFile(filePath, "utf-8") let {frontmatter}: MarkdownParser.result = MarkdownParser.parseSync(raw) let frontmatter = switch BlogFrontmatter.decode(frontmatter) { @@ -26,7 +26,7 @@ let loader: ReactRouter.Loader.t = async ({request}) => { let slug = filePath - ->Node.Path.basename + ->NodeJs.Path.basename ->String.replace(".mdx", "") ->String.replaceRegExp(/^\d\d\d\d-\d\d-\d\d-/, "") diff --git a/apps/docs/app/routes/CommunityRoute.res b/apps/docs/app/routes/CommunityRoute.res index 9fc078338..8fad9f04a 100644 --- a/apps/docs/app/routes/CommunityRoute.res +++ b/apps/docs/app/routes/CommunityRoute.res @@ -20,14 +20,14 @@ let communityTableOfContents = async () => { } let loader: ReactRouter.Loader.t = async ({request}) => { - let {pathname} = WebAPI.URL.make(~url=request.url) + let {pathname} = URL.make(~url=request.url) let filePath = MdxFile.resolveFilePath( (pathname :> string), ~dir="markdown-pages/community", ~alias="community", ) - let raw = await Node.Fs.readFile(filePath, "utf-8") + let raw = await NodeJs.Fs.readFile(filePath, "utf-8") let {frontmatter}: MarkdownParser.result = MarkdownParser.parseSync(raw) let description = FrontmatterUtils.getField(frontmatter, "description") diff --git a/apps/docs/app/routes/DocsGuidesRoute.res b/apps/docs/app/routes/DocsGuidesRoute.res index 820e81d92..34e3fb723 100644 --- a/apps/docs/app/routes/DocsGuidesRoute.res +++ b/apps/docs/app/routes/DocsGuidesRoute.res @@ -20,14 +20,14 @@ let guidesTableOfContents = async () => { } let loader: ReactRouter.Loader.t = async ({request}) => { - let {pathname} = WebAPI.URL.make(~url=request.url) + let {pathname} = URL.make(~url=request.url) let filePath = MdxFile.resolveFilePath( (pathname :> string), ~dir="markdown-pages/docs/guides", ~alias="docs/guides", ) - let raw = await Node.Fs.readFile(filePath, "utf-8") + let raw = await NodeJs.Fs.readFile(filePath, "utf-8") let {frontmatter}: MarkdownParser.result = MarkdownParser.parseSync(raw) let description = FrontmatterUtils.getField(frontmatter, "description") diff --git a/apps/docs/app/routes/DocsManualRoute.res b/apps/docs/app/routes/DocsManualRoute.res index 9c163bb03..eebfa256b 100644 --- a/apps/docs/app/routes/DocsManualRoute.res +++ b/apps/docs/app/routes/DocsManualRoute.res @@ -31,14 +31,14 @@ let manualTableOfContents = async () => { } let loader: ReactRouter.Loader.t = async ({request}) => { - let {pathname} = WebAPI.URL.make(~url=request.url) + let {pathname} = URL.make(~url=request.url) let filePath = MdxFile.resolveFilePath( (pathname :> string), ~dir="markdown-pages/docs/manual", ~alias="docs/manual", ) - let raw = await Node.Fs.readFile(filePath, "utf-8") + let raw = await NodeJs.Fs.readFile(filePath, "utf-8") let {frontmatter}: MarkdownParser.result = MarkdownParser.parseSync(raw) let description = FrontmatterUtils.getField(frontmatter, "description") diff --git a/apps/docs/app/routes/DocsOverview.res b/apps/docs/app/routes/DocsOverview.res index dbffbd735..6c26c26e5 100644 --- a/apps/docs/app/routes/DocsOverview.res +++ b/apps/docs/app/routes/DocsOverview.res @@ -15,7 +15,7 @@ module Card = { } @react.component -let default = (~showVersionSelect=true) => { +let default = () => { let languageManual = Constants.languageManual let ecosystem = [ diff --git a/apps/docs/app/routes/DocsOverview.resi b/apps/docs/app/routes/DocsOverview.resi index 45deeeacb..47fa1ac2e 100644 --- a/apps/docs/app/routes/DocsOverview.resi +++ b/apps/docs/app/routes/DocsOverview.resi @@ -1,2 +1,2 @@ @react.component -let default: (~showVersionSelect: bool=?) => React.element +let default: unit => React.element diff --git a/apps/docs/app/routes/DocsReactRoute.res b/apps/docs/app/routes/DocsReactRoute.res index 8e3dcb073..92e936f8c 100644 --- a/apps/docs/app/routes/DocsReactRoute.res +++ b/apps/docs/app/routes/DocsReactRoute.res @@ -24,14 +24,14 @@ let reactTableOfContents = async () => { } let loader: ReactRouter.Loader.t = async ({request}) => { - let {pathname} = WebAPI.URL.make(~url=request.url) + let {pathname} = URL.make(~url=request.url) let filePath = MdxFile.resolveFilePath( (pathname :> string), ~dir="markdown-pages/docs/react", ~alias="docs/react", ) - let raw = await Node.Fs.readFile(filePath, "utf-8") + let raw = await NodeJs.Fs.readFile(filePath, "utf-8") let {frontmatter}: MarkdownParser.result = MarkdownParser.parseSync(raw) let description = FrontmatterUtils.getField(frontmatter, "description") diff --git a/apps/docs/app/routes/LandingPage.res b/apps/docs/app/routes/LandingPage.res index aab1d4bbc..cfa7485a0 100644 --- a/apps/docs/app/routes/LandingPage.res +++ b/apps/docs/app/routes/LandingPage.res @@ -194,22 +194,28 @@ module QuickInstall = { // For Tailwind transitions to behave correctly, we need to first paint the DOM element in the tree, // and in the next tick, add the opacity-100 class, so the transition animation actually takes place. // If we don't do that, the banner will essentially pop up without any animation - let bannerEl = WebAPI.Document.createElement(document, "div") + let bannerEl = Document.createElement(document, "div") bannerEl.className = "foobar opacity-0 absolute top-0 mt-4 -mr-1 px-2 rounded right-0 bg-turtle text-gray-80-tr body-sm transition-all duration-500 ease-in-out " - let textNode = WebAPI.Document.createTextNode(document, "Copied!") - - WebAPI.Element.appendChild(bannerEl, textNode)->ignore - WebAPI.Element.appendChild(buttonEl, bannerEl)->ignore - - let nextFrameId = WebAPI.Window.requestAnimationFrame(window, _ => { - WebAPI.DOMTokenList.toggle(bannerEl.classList, ~token="opacity-0")->ignore - WebAPI.DOMTokenList.toggle(bannerEl.classList, ~token="opacity-100")->ignore + let textNode = Document.createTextNode(document, "Copied!") + + Element.appendChild(bannerEl, textNode)->ignore + Element.appendChild(buttonEl, bannerEl)->ignore + + let nextFrameId = Window.requestAnimationFrame(window, _ => { + DOMTokenList.toggle( + (bannerEl.classList :> DomTypes.domTokenList), + ~token="opacity-0", + )->ignore + DOMTokenList.toggle( + (bannerEl.classList :> DomTypes.domTokenList), + ~token="opacity-100", + )->ignore }) let timeoutId = setTimeout(~handler=() => { - buttonEl->WebAPI.Element.removeChild(bannerEl)->ignore + buttonEl->Element.removeChild(bannerEl)->ignore setState(_ => Init) }, ~timeout=2000) @@ -683,7 +689,7 @@ module CuratedResources = { } @react.component -let make = (~components=MarkdownComponents.default) => { +let make = () => { <> React.element +let make: unit => React.element diff --git a/apps/docs/app/routes/Packages.res b/apps/docs/app/routes/Packages.res index c8d2e416c..fcd644de7 100644 --- a/apps/docs/app/routes/Packages.res +++ b/apps/docs/app/routes/Packages.res @@ -310,6 +310,7 @@ type state = | All | Filtered(string) // search term +@react.componentWithProps let make = (props: props) => { open Markdown @@ -369,7 +370,7 @@ let make = (props: props) => { }) let onKeywordSelect = keyword => { - WebAPI.Window.scrollTo(window, ~options={left: 0.0, top: 0.0, behavior: Smooth}) + Window.scrollTo(window, ~options={left: 0.0, top: 0.0, behavior: Smooth}) setState(_ => { Filtered(keyword) }) @@ -519,14 +520,14 @@ let getStaticProps = async (): props => { let baseUrl = "https://registry.npmjs.org/-/v1/search?text=keywords:rescript&size=250&maintenance=1.0&popularity=0.5&quality=0.9" let (one, two, three) = await Promise.all3(( - fetch(baseUrl), - fetch(baseUrl ++ "&from=250"), - fetch(baseUrl ++ "&from=500"), + Fetch.fetch(baseUrl), + Fetch.fetch(baseUrl ++ "&from=250"), + Fetch.fetch(baseUrl ++ "&from=500"), )) let responseToOption = async response => { try { - let json = await response->WebAPI.Response.json + let json = await response->Response.json Some(json) } catch { | _ => diff --git a/apps/docs/app/routes/Packages.resi b/apps/docs/app/routes/Packages.resi index a89c521d5..4fe6f38bc 100644 --- a/apps/docs/app/routes/Packages.resi +++ b/apps/docs/app/routes/Packages.resi @@ -22,6 +22,6 @@ type props = { unmaintained: array, } -let make: props => React.element +let make: React.component let getStaticProps: unit => promise diff --git a/apps/docs/app/routes/SyntaxLookup.res b/apps/docs/app/routes/SyntaxLookup.res index fdddb1a60..9df7c8800 100644 --- a/apps/docs/app/routes/SyntaxLookup.res +++ b/apps/docs/app/routes/SyntaxLookup.res @@ -174,7 +174,7 @@ type state = | ShowFiltered(string, array) // (search, filteredItems) | ShowDetails(Item.t) -let scrollToTop = () => WebAPI.Window.scrollTo(window, ~options={left: 0.0, top: 0.0}) +let scrollToTop = () => Window.scrollTo(window, ~options={left: 0.0, top: 0.0}) type params = {slug: string} @@ -219,11 +219,7 @@ type item = { } @react.component -let make = ( - ~mdxSources: array, - ~children: option=React.null, - ~activeItem: option=?, -) => { +let make = (~mdxSources: array, ~children=React.null, ~activeItem: option=?) => { let allItems = mdxSources->Array.map(mdxSource => { let {id, keywords, category, summary, name, status, href} = mdxSource { diff --git a/apps/docs/app/routes/SyntaxLookupDetailRoute.res b/apps/docs/app/routes/SyntaxLookupDetailRoute.res index b5bdfda99..70b5045ea 100644 --- a/apps/docs/app/routes/SyntaxLookupDetailRoute.res +++ b/apps/docs/app/routes/SyntaxLookupDetailRoute.res @@ -7,14 +7,14 @@ type loaderData = { } let loader: ReactRouter.Loader.t = async ({request}) => { - let {pathname} = WebAPI.URL.make(~url=request.url) + let {pathname} = URL.make(~url=request.url) let filePath = MdxFile.resolveFilePath( (pathname :> string), ~dir="markdown-pages/syntax-lookup", ~alias="syntax-lookup", ) - let raw = await Node.Fs.readFile(filePath, "utf-8") + let raw = await NodeJs.Fs.readFile(filePath, "utf-8") let {frontmatter}: MarkdownParser.result = MarkdownParser.parseSync(raw) let id = FrontmatterUtils.getField(frontmatter, "id") diff --git a/apps/docs/app/routes/TryRoute.res b/apps/docs/app/routes/TryRoute.res index d3636e6f6..cddc08987 100644 --- a/apps/docs/app/routes/TryRoute.res +++ b/apps/docs/app/routes/TryRoute.res @@ -5,8 +5,8 @@ type props = { let loader = async () => { let (bundleBaseUrl, versionsBaseUrl) = switch ( - Node.Process.Env.playgroundBundleEndpoint, - Node.Process.Env.nodeEnv, + NodeJs.Process.Env.playgroundBundleEndpoint, + NodeJs.Process.Env.nodeEnv, ) { | (Some(baseUrl), _) => (baseUrl, baseUrl) | (None, "development") => { @@ -24,8 +24,8 @@ let loader = async () => { try { let versions = { - let response = await fetch(versionsBaseUrl + "/playground-bundles/versions.json") - let json = await WebAPI.Response.json(response) + let response = await Fetch.fetch(versionsBaseUrl + "/playground-bundles/versions.json") + let json = await Response.json(response) json ->JSON.Decode.array ->Option.getOrThrow diff --git a/apps/docs/functions/ogimage/[[path]]/index.png.res b/apps/docs/functions/ogimage/[[path]]/index.png.res index e3526a3f3..6c06f696a 100644 --- a/apps/docs/functions/ogimage/[[path]]/index.png.res +++ b/apps/docs/functions/ogimage/[[path]]/index.png.res @@ -1,23 +1,21 @@ -open WebAPI - %%raw("import React from 'react'") let loadGoogleFont = async (family: string) => { let url = `https://fonts.googleapis.com/css2?family=${family}` - let css = await (await fetch(url))->Response.text + let css = await (await Fetch.fetch(url))->Response.text // this function should fail if we can't load the font let resource = css->String.match(/src: url\((.+)\) format\('(opentype|truetype)'\)/)->Option.getOrThrow - let response = await fetch(resource[1]->Option.getOrThrow->Option.getOrThrow) + let response = await Fetch.fetch(resource[1]->Option.getOrThrow->Option.getOrThrow) await response->Response.arrayBuffer } type assets type env = {@as("ASSETS") assets: assets} -type context = {request: FetchAPI.request, params: {path: array}, env: env} +type context = {request: Request.t, params: {path: array}, env: env} -@send external fetchAsset: (assets, string) => promise = "fetch" +@send external fetchAsset: (assets, string) => promise = "fetch" let textResponse = (~status, message) => Response.fromString(message, ~init={status: status}) @@ -113,14 +111,14 @@ let splitPreviewText = (~title, ~description) => { (titleSegments[0]->Option.getOr("")->normalizeText, subTitle, description->normalizeText) } -let requestedUrl = (~requestUrl: URLAPI.url, ~params) => { - switch requestUrl.searchParams->URLSearchParams.get("url")->Nullable.make->Nullable.toOption { +let requestedUrl = (~requestUrl: UrlTypes.url, ~params) => { + switch requestUrl.searchParams->URLSearchParams.get("url")->Null.toOption { | Some(url) => Some(url) | None => params.path[0]->Option.map(decodeURIComponent) } } -let isHtmlResponse = (response: FetchAPI.response) => +let isHtmlResponse = (response: Response.t) => response.headers ->Headers.get("content-type") ->Null.toOption @@ -128,7 +126,7 @@ let isHtmlResponse = (response: FetchAPI.response) => contentType->String.toLowerCase->String.includes("text/html") ) -let renderImage = async (~assets, ~requestUrl: URLAPI.url, ~targetUrl: URLAPI.url) => { +let renderImage = async (~assets, ~requestUrl: UrlTypes.url, ~targetUrl: UrlTypes.url) => { if targetUrl.origin != requestUrl.origin { textResponse(~status=400, "Open Graph image URL must be same-origin") } else if targetUrl.pathname->String.startsWith("/ogimage/") { diff --git a/apps/docs/markdown-pages/docs/manual/attribute.mdx b/apps/docs/markdown-pages/docs/manual/attribute.mdx index fd59743da..e0ab29bbc 100644 --- a/apps/docs/markdown-pages/docs/manual/attribute.mdx +++ b/apps/docs/markdown-pages/docs/manual/attribute.mdx @@ -89,7 +89,7 @@ There's a second category of attributes, called "extension points" (a remnant te -```res +```res nocheck %raw("var a = 1") ``` diff --git a/apps/docs/markdown-pages/docs/manual/bind-to-global-js-values.mdx b/apps/docs/markdown-pages/docs/manual/bind-to-global-js-values.mdx index 840553d4b..e2657cd9a 100644 --- a/apps/docs/markdown-pages/docs/manual/bind-to-global-js-values.mdx +++ b/apps/docs/markdown-pages/docs/manual/bind-to-global-js-values.mdx @@ -104,25 +104,24 @@ This binds to `window.location.ancestorOrigins.length`. ## Special Global Values -Global values like `__filename` and `__DEV__` don't always exist; you can't even model them as an `option`, since the mere act of referring to them in ReScript (then compiled into JS) would trigger the usual `Uncaught ReferenceError: __filename is not defined` error in e.g. the browser environment. +Global values like `__filename` and `__DEV__` don't always exist. Referring to them directly could trigger an `Uncaught ReferenceError` in environments where they aren't defined. -For these troublesome global values, ReScript provides a special approach: `%external(a_single_identifier)`. +Access these values as optional properties of `globalThis` instead: ```res -switch %external(__DEV__) { +@scope("globalThis") +external dev: option = "__DEV__" + +switch dev { | Some(_) => Console.log("dev mode") | None => Console.log("production mode") } ``` ```js -import * as Js from "@rescript/runtime/lib/es6/Js.js"; - -let match = Js.undefinedToOption( - typeof __DEV__ === "undefined" ? undefined : __DEV__, -); +let match = globalThis.__DEV__; if (match !== undefined) { console.log("dev mode"); @@ -133,34 +132,30 @@ if (match !== undefined) { -That first line's `typeof` check won't trigger a JS ReferenceError. +Property access through `globalThis` safely produces `undefined` when the property doesn't exist. Another example: ```res -switch %external(__filename) { +@scope("globalThis") +external filename: option = "__filename" + +switch filename { | Some(f) => Console.log(f) | None => Console.log("non-node environment") }; ``` ```js -import * as Js from "@rescript/runtime/lib/es6/Js.js"; -import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; - -let f = Js.undefinedToOption( - typeof __filename === "undefined" ? undefined : __filename, -); +let f = globalThis.__filename; if (f !== undefined) { - console.log(Primitive_option.valFromOption(f)); + console.log(f); } else { console.log("non-node environment"); } ``` - -{/* TODO: revamp this page. Not good. Tell to use globalThis["foo"], and look in our stdlib */} diff --git a/apps/docs/markdown-pages/docs/manual/bind-to-js-function.mdx b/apps/docs/markdown-pages/docs/manual/bind-to-js-function.mdx index f7d319961..6ac781365 100644 --- a/apps/docs/markdown-pages/docs/manual/bind-to-js-function.mdx +++ b/apps/docs/markdown-pages/docs/manual/bind-to-js-function.mdx @@ -494,19 +494,18 @@ Currently 4 directives are supported: `null_to_opt`, `undefined_to_opt`, `nullab **Since 11.1** -**Experimental** You can easily bind to [JS tagged template functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates). +You can easily bind to [JS tagged template functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates). Tag functions in JS expect as input an array of strings and variadic parameters for the arguments of the interpolation. -To bind to those functions in ReScript, the binding signature must have two arrays as arguments, -the first one being an array of strings and the second can be an array of anything. -You add the `@taggedTemplate` annotation and you're good to go! +To bind to those functions in ReScript, use the built-in `taggedTemplate<'param, 'output>` type. +The first type parameter describes the interpolated values, and the second describes the tag's return value. ```res // see https://bun.sh/docs/runtime/shell type result = {exitCode: int} -@module("bun") @taggedTemplate -external sh: (array, array) => promise = "$" +@module("bun") +external sh: taggedTemplate> = "$" let filename = "index.res" let result = await sh`ls ${filename}` diff --git a/apps/docs/markdown-pages/docs/manual/generate-converters-accessors.mdx b/apps/docs/markdown-pages/docs/manual/generate-converters-accessors.mdx index 144ac6205..7519e3d57 100644 --- a/apps/docs/markdown-pages/docs/manual/generate-converters-accessors.mdx +++ b/apps/docs/markdown-pages/docs/manual/generate-converters-accessors.mdx @@ -94,7 +94,7 @@ let pets = [{name: "bob"}, {name: "bob2"}] pets ->Array.map(name) - ->Array.joinWith("&") + ->Array.join("&") ->Console.log ``` diff --git a/apps/docs/markdown-pages/docs/manual/interop-cheatsheet.mdx b/apps/docs/markdown-pages/docs/manual/interop-cheatsheet.mdx index 3ef87eda6..b26007c0c 100644 --- a/apps/docs/markdown-pages/docs/manual/interop-cheatsheet.mdx +++ b/apps/docs/markdown-pages/docs/manual/interop-cheatsheet.mdx @@ -38,7 +38,7 @@ This is a glossary with examples. All the features are described by later pages. - [`@uncurry`](./bind-to-js-function.mdx#extra-solution) - [`@unwrap`](./bind-to-js-function.mdx#trick-2-polymorphic-variant--bsunwrap) - [`@val`](./bind-to-global-js-values.mdx#global-modules) -- [`@taggedTemplate`](./bind-to-js-function.mdx#tagged_template-functions) +- [`taggedTemplate`](./bind-to-js-function.mdx#tagged-template-functions) - [`@deprecated`](./attribute.mdx#usage) - [`genType`](https://github.com/reason-association/genType) - [`@JSX`](./jsx.mdx) @@ -49,7 +49,6 @@ This is a glossary with examples. All the features are described by later pages. ### Extension Points - [`%debugger`](./embed-raw-javascript.mdx#debugger) -- [`%external`](./bind-to-global-js-values.mdx#special-global-values) - [`%raw`](./embed-raw-javascript.mdx#paste-raw-js-code) - [`%todo`](../../syntax-lookup/extension_todo.mdx) @@ -206,8 +205,8 @@ external join: array => string = "join" ```res // see https://bun.sh/docs/runtime/shell type result = {exitCode: int} -@module("bun") @taggedTemplate -external sh: (array, array) => promise = "$" +@module("bun") +external sh: taggedTemplate> = "$" let filename = "index.res" let result = await sh`ls ${filename}` diff --git a/apps/docs/markdown-pages/docs/manual/promise.mdx b/apps/docs/markdown-pages/docs/manual/promise.mdx index e64cbf5f4..1a6030001 100644 --- a/apps/docs/markdown-pages/docs/manual/promise.mdx +++ b/apps/docs/markdown-pages/docs/manual/promise.mdx @@ -50,19 +50,18 @@ let p3 = Promise.reject(MyOwnError("some rejection")) ```res let logAsyncMessage = () => { - open Promise Promise.resolve("hello world") - ->then(msg => { + ->Promise.then(msg => { // then callbacks require the result to be resolved explicitly - resolve("Message: " ++ msg) + Promise.resolve("Message: " ++ msg) }) - ->then(msg => { + ->Promise.then(msg => { Console.log(msg) // Even if there is no result, we need to use resolve() to return a promise - resolve() + Promise.resolve() }) - ->ignore // Requires ignoring due to unhandled return value + ->Promise.ignore // Requires ignoring due to unhandled return value } ``` @@ -94,7 +93,7 @@ external fetchMessage: string => promise = "global.fetchMessage" let logAsyncMessage = async () => { let messages = await Promise.all([fetchMessage("message1"), fetchMessage("message2")]) - Console.log(messages->Array.joinWith(", ")) + Console.log(messages->Array.join(", ")) } ``` diff --git a/apps/docs/markdown-pages/docs/manual/tagged-templates.mdx b/apps/docs/markdown-pages/docs/manual/tagged-templates.mdx index ca0081105..50d3bcb3e 100644 --- a/apps/docs/markdown-pages/docs/manual/tagged-templates.mdx +++ b/apps/docs/markdown-pages/docs/manual/tagged-templates.mdx @@ -18,13 +18,14 @@ to learn more about them. ## Define a tag function -Tag functions in ReScript have the following signature: +Tagged template values in ReScript have the following type: ```res sig -let myTagFunction : (array, array<'param>) => 'output +let myTagFunction: taggedTemplate<'param, 'output> ``` As you can see, you can have any type you want both for the placeholder array and for the output. +Use `TaggedTemplate.make` to create a tagged template value from a ReScript function. Given how string interpolation works, you'll always have the following invariant: @@ -44,7 +45,7 @@ type params = | S(string) | Bool(bool) -let s = (strings, parameters) => { +let s = TaggedTemplate.make((strings, parameters) => { let text = Array.reduceWithIndex(parameters, Array.getUnsafe(strings, 0), ( acc, param, @@ -61,35 +62,32 @@ let s = (strings, parameters) => { acc ++ p ++ s }) React.string(text) -} +}) ``` ```js -import * as Core__Array from "./stdlib/core__Array.js"; - -function s(strings, parameters) { - return Core__Array.reduceWithIndex( - parameters, - strings[0], - function (acc, param, i) { - var s = strings[(i + 1) | 0]; - var p; - switch (param.TAG) { - case "I": - case "F": - p = param._0.toString(); - break; - case "S": - p = param._0; - break; - case "Bool": - p = param._0 ? "true" : "false"; - break; - } - return acc + p + s; - }, - ); -} +import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.mjs"; +import * as Stdlib_TaggedTemplate from "@rescript/runtime/lib/es6/Stdlib_TaggedTemplate.mjs"; + +let s = Stdlib_TaggedTemplate.make((strings, parameters) => + Stdlib_Array.reduceWithIndex(parameters, strings[0], (acc, param, i) => { + let s = strings[(i + 1) | 0]; + let p; + switch (param.TAG) { + case "I": + case "F": + p = param._0.toString(); + break; + case "S": + p = param._0; + break; + case "Bool": + p = param._0 ? "true" : "false"; + break; + } + return acc + p + s; + }), +); ``` @@ -110,48 +108,39 @@ module Greetings = { ``` ```js -import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js"; +import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.mjs"; import * as JsxRuntime from "react/jsx-runtime"; - -function s(strings, parameters) { - return Stdlib_Array.reduceWithIndex( - parameters, - strings[0], - (acc, param, i) => { - let s = strings[(i + 1) | 0]; - let p; - switch (param.TAG) { - case "I": - case "F": - p = param._0.toString(); - break; - case "S": - p = param._0; - break; - case "Bool": - p = param._0 ? "true" : "false"; - break; - } - return acc + p + s; - }, - ); -} +import * as Stdlib_TaggedTemplate from "@rescript/runtime/lib/es6/Stdlib_TaggedTemplate.mjs"; + +let s = Stdlib_TaggedTemplate.make((strings, parameters) => + Stdlib_Array.reduceWithIndex(parameters, strings[0], (acc, param, i) => { + let s = strings[(i + 1) | 0]; + let p; + switch (param.TAG) { + case "I": + case "F": + p = param._0.toString(); + break; + case "S": + p = param._0; + break; + case "Bool": + p = param._0 ? "true" : "false"; + break; + } + return acc + p + s; + }), +); function Example$Greetings(props) { return JsxRuntime.jsx("div", { - children: s( - [`hello `, ` you're `, ` year old!`], - [ - { - TAG: "S", - _0: props.name, - }, - { - TAG: "I", - _0: props.age, - }, - ], - ), + children: s`hello ${{ + TAG: "S", + _0: props.name, + }} you're ${{ + TAG: "I", + _0: props.age, + }} year old!`, }); } @@ -163,49 +152,40 @@ export { s, Greetings }; ``` ```jsx -import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js"; +import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.mjs"; import * as JsxRuntime from "react/jsx-runtime"; - -function s(strings, parameters) { - return Stdlib_Array.reduceWithIndex( - parameters, - strings[0], - (acc, param, i) => { - let s = strings[(i + 1) | 0]; - let p; - switch (param.TAG) { - case "I": - case "F": - p = param._0.toString(); - break; - case "S": - p = param._0; - break; - case "Bool": - p = param._0 ? "true" : "false"; - break; - } - return acc + p + s; - }, - ); -} +import * as Stdlib_TaggedTemplate from "@rescript/runtime/lib/es6/Stdlib_TaggedTemplate.mjs"; + +let s = Stdlib_TaggedTemplate.make((strings, parameters) => + Stdlib_Array.reduceWithIndex(parameters, strings[0], (acc, param, i) => { + let s = strings[(i + 1) | 0]; + let p; + switch (param.TAG) { + case "I": + case "F": + p = param._0.toString(); + break; + case "S": + p = param._0; + break; + case "Bool": + p = param._0 ? "true" : "false"; + break; + } + return acc + p + s; + }), +); function Example$Greetings(props) { return (
- {s( - [`hello `, ` you're `, ` year old!`], - [ - { - TAG: "S", - _0: props.name, - }, - { - TAG: "I", - _0: props.age, - }, - ], - )} + {s`hello ${{ + TAG: "S", + _0: props.name, + }} you're ${{ + TAG: "I", + _0: props.age, + }} year old!`}
); } diff --git a/apps/docs/markdown-pages/docs/react/components-and-props.mdx b/apps/docs/markdown-pages/docs/react/components-and-props.mdx index 84fe33f2b..8626b6dbc 100644 --- a/apps/docs/markdown-pages/docs/react/components-and-props.mdx +++ b/apps/docs/markdown-pages/docs/react/components-and-props.mdx @@ -612,9 +612,9 @@ export { Greeting, make }; **Note:** React components are capitalized; primitive DOM elements like `div` or `button` are uncapitalized. More infos on the JSX specifics and code transformations can be found in our [JSX language manual section](../manual/jsx.mdx#capitalized-tag). -### Handwritten Components +### Components with a Props Record -You don't need to use the `@react.component` decorator to write components that can be used in JSX. Instead you can write the `make` function with type `props` and these will always work as React components. But then you will have the issue with the component name being "make" in the React dev tools. +Use `@react.componentWithProps` when a component takes a single props record instead of labeled arguments. For example: @@ -624,6 +624,7 @@ For example: module Link = { type props = {href: string, children: React.element}; + @react.componentWithProps let make = (props: props) => { {props.children} diff --git a/apps/docs/markdown-pages/docs/react/elements-and-jsx.mdx b/apps/docs/markdown-pages/docs/react/elements-and-jsx.mdx index c1401b171..c200abe17 100644 --- a/apps/docs/markdown-pages/docs/react/elements-and-jsx.mdx +++ b/apps/docs/markdown-pages/docs/react/elements-and-jsx.mdx @@ -146,7 +146,7 @@ Sometimes it's necessary to pass around component functions to have more control ```res type props = {name: string} -let render = (myComp: props => React.element) => { +let render = (myComp: React.component) => {
{React.createElement(myComp, {name: "Franz"})}
} ``` @@ -168,7 +168,7 @@ There is also a `React.createElementVariadic` function, which takes an array of ```res type props = {title: string, children: React.element} -let render = (article: props => React.element) => { +let render = (article: React.component) => { let children = [React.string("Introduction"), React.string("Body")] let props = {title: "Article #1", children: React.null} diff --git a/apps/docs/markdown-pages/docs/react/forwarding-refs.mdx b/apps/docs/markdown-pages/docs/react/forwarding-refs.mdx index b1655e8d4..eb387c491 100644 --- a/apps/docs/markdown-pages/docs/react/forwarding-refs.mdx +++ b/apps/docs/markdown-pages/docs/react/forwarding-refs.mdx @@ -85,7 +85,7 @@ This is how the previous example would look like with the `React.forwardRef` app -```res +```res nocheck // App.res module FancyInput = { diff --git a/apps/docs/markdown-pages/docs/react/memo.mdx b/apps/docs/markdown-pages/docs/react/memo.mdx index 2fa475e29..e9e78df43 100644 --- a/apps/docs/markdown-pages/docs/react/memo.mdx +++ b/apps/docs/markdown-pages/docs/react/memo.mdx @@ -128,7 +128,7 @@ export { make }; -Another approach is to use a custom prop type and remove the `@react.component` annotation. +Another approach is to use a custom prop type and wrap the component function with `React.component`. @@ -139,11 +139,11 @@ type props = { } let make = React.memoCustomCompareProps( - ({disabled, onClick}) => { + React.component(({disabled, onClick}: props) => { - }, + }), (p1, p2) => p1.disabled == p2.disabled, ) ``` diff --git a/apps/docs/markdown-pages/docs/react/server-components.mdx b/apps/docs/markdown-pages/docs/react/server-components.mdx index 0ee032169..2c7138d08 100644 --- a/apps/docs/markdown-pages/docs/react/server-components.mdx +++ b/apps/docs/markdown-pages/docs/react/server-components.mdx @@ -296,7 +296,7 @@ export { ClientComp, data, getData, make$1 as make }; @@directive("'use client'") @react.component -let make = (~submit) => +let make = (~submit: unit => unit) => ``` ```js diff --git a/apps/docs/package.json b/apps/docs/package.json index ecf71b37f..52aa7c92a 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -46,8 +46,8 @@ "@react-router/node": "^7.15.0", "@rescript-lang/playground": "workspace:*", "@rescript-lang/shared": "workspace:*", - "@rescript/react": "^0.14.2", - "@rescript/webapi": "0.1.0-experimental-29db5f4", + "@rescript/react": "patch:@rescript/react@npm%3A0.14.2#~/.yarn/patches/@rescript-react-npm-0.14.2-b830f5af4f.patch", + "@rescript/webapi": "patch:@rescript/webapi@npm%3A0.1.0-experimental-0781ac8#~/.yarn/patches/@rescript-webapi-npm-0.1.0-experimental-0781ac8-50def7723d.patch", "docson": "^2.1.0", "fuse.js": "^6.6.2", "highlight.js": "^11.11.1", @@ -68,7 +68,7 @@ "remark-frontmatter": "^5.0.0", "remark-gfm": "^4.0.1", "remark-validate-links": "^13.1.0", - "rescript": "^12.2.0", + "rescript": "https://pkg.pr.new/rescript@8425", "tinyglobby": "^0.2.15", "unified": "^11.0.5", "vfile-matter": "^5.0.1" diff --git a/apps/docs/rescript.json b/apps/docs/rescript.json index d77357b84..fb7dc924b 100644 --- a/apps/docs/rescript.json +++ b/apps/docs/rescript.json @@ -7,7 +7,7 @@ "@rescript/react", "@rescript/webapi" ], - "compiler-flags": ["-open WebAPI.Global"], + "compiler-flags": ["-open DomGlobal"], "sources": [ { "dir": "__tests__", @@ -45,8 +45,7 @@ "error": "+8" }, "gentypeconfig": { - "language": "untyped", "shims": [], - "module": "es6" + "module": "esmodule" } } diff --git a/apps/docs/scripts/LogAlgoliaEnvStatus.res b/apps/docs/scripts/LogAlgoliaEnvStatus.res index 887c08825..9f163e0cd 100644 --- a/apps/docs/scripts/LogAlgoliaEnvStatus.res +++ b/apps/docs/scripts/LogAlgoliaEnvStatus.res @@ -1,16 +1,16 @@ @val @scope(("import", "meta")) external url: string = "url" let run = () => { - let missing = AlgoliaEnvStatus.getMissingPublicAlgoliaVars(~env=Node.Process.env) + let missing = AlgoliaEnvStatus.getMissingPublicAlgoliaVars(~env=NodeJs.Process.env) if Array.length(missing) > 0 { Console.warn(AlgoliaEnvStatus.formatDisabledMessage(missing)) } } let isMainModule = () => - switch Node.Process.argv[1] { + switch NodeJs.Process.argv[1] { | Some(entrypoint) => - Node.URL.fileURLToPath(url) === Node.Path.resolve(Node.Process.cwd(), entrypoint) + NodeJs.URL.fileURLToPath(url) === NodeJs.Path.resolve(NodeJs.Process.cwd(), entrypoint) | None => false } diff --git a/apps/docs/scripts/gendocs.res b/apps/docs/scripts/gendocs.res index b2660f93e..1bf47a248 100644 --- a/apps/docs/scripts/gendocs.res +++ b/apps/docs/scripts/gendocs.res @@ -15,7 +15,7 @@ node scripts/gendocs.mjs path/to/rescript-compiler latest true */ @val @scope(("import", "meta")) external url: string = "url" -open Node +open NodeJs module Docgen = RescriptTools.Docgen let args = Process.argv->Array.slice(~start=2) diff --git a/apps/docs/scripts/generate_llms.res b/apps/docs/scripts/generate_llms.res index 0278caff0..54b67213b 100644 --- a/apps/docs/scripts/generate_llms.res +++ b/apps/docs/scripts/generate_llms.res @@ -1,13 +1,13 @@ let readMarkdownFile = (filePath: string): string => { - let fileContent = Node.Fs.readFileSync2(filePath, "utf8") + let fileContent = NodeJs.Fs.readFileSync2(filePath, "utf8") fileContent } let rec collectFiles = (dirPath: string): array => { - let entries = Node.Fs.readdirSync(dirPath) + let entries = NodeJs.Fs.readdirSync(dirPath) entries->Array.reduce([], (acc, entry) => { - let fullPath = Node.Path.join([dirPath, entry]) - let stats = Node.Fs.statSync(fullPath) + let fullPath = NodeJs.Path.join([dirPath, entry]) + let stats = NodeJs.Fs.statSync(fullPath) switch stats["isDirectory"]() { | true => acc->Array.concat(collectFiles(fullPath)) | false => { @@ -19,32 +19,32 @@ let rec collectFiles = (dirPath: string): array => { } let clearFile = (filePath: string): unit => { - Node.Fs.writeFileSync(filePath, "") + NodeJs.Fs.writeFileSync(filePath, "") } let removeFileIfExists = (filePath: string): unit => { - if Node.Fs.existsSync(filePath) { - Node.Fs.unlinkSync(filePath) + if NodeJs.Fs.existsSync(filePath) { + NodeJs.Fs.unlinkSync(filePath) } } let writeTextFile = (filePath: string, content: string): unit => { - Node.Fs.writeFileSync(filePath, content, ~encoding="utf8") + NodeJs.Fs.writeFileSync(filePath, content, ~encoding="utf8") } let removeLlmsTextFiles = (~llmsDirectory: string): unit => { - removeFileIfExists(llmsDirectory->Node.Path.join2("llms.txt")) - removeFileIfExists(llmsDirectory->Node.Path.join2("llm-full.txt")) - removeFileIfExists(llmsDirectory->Node.Path.join2("llm-small.txt")) + removeFileIfExists(llmsDirectory->NodeJs.Path.join2("llms.txt")) + removeFileIfExists(llmsDirectory->NodeJs.Path.join2("llm-full.txt")) + removeFileIfExists(llmsDirectory->NodeJs.Path.join2("llm-small.txt")) } let rec createDirectoryIfNotExists = (dirPath: string): unit => { - if !Node.Fs.existsSync(dirPath) { - let parentPath = Node.Path.dirname(dirPath) + if !NodeJs.Fs.existsSync(dirPath) { + let parentPath = NodeJs.Path.dirname(dirPath) if parentPath !== "" && parentPath !== dirPath { createDirectoryIfNotExists(parentPath) } - Node.Fs.mkdirSync(dirPath) + NodeJs.Fs.mkdirSync(dirPath) } } @@ -96,7 +96,7 @@ let readMdxDocument = (filePath: string): mdxDocument => { let {frontmatter}: MarkdownParser.result = rawContent->MarkdownParser.parseSync { title: frontmatter->getFrontmatterString("title"), - slug: filePath->Node.Path.basename->String.replace(".mdx", ""), + slug: filePath->NodeJs.Path.basename->String.replace(".mdx", ""), section: frontmatter->getFrontmatterString("section"), order: frontmatter->getFrontmatterNumber("order"), content: rawContent->removeFrontmatter->String.trim, @@ -117,7 +117,7 @@ let compareMdxDocuments = (a: mdxDocument, b: mdxDocument): float => { } let sectionLlmFilePath = (~llmsDirectory: string, sectionFile: sectionLlmFile): string => - llmsDirectory->Node.Path.join2(sectionFile.slug)->Node.Path.join2("llm.txt") + llmsDirectory->NodeJs.Path.join2(sectionFile.slug)->NodeJs.Path.join2("llm.txt") let createSectionLlmFiles = ( ~llmsDirectory: string, @@ -137,7 +137,7 @@ let createSectionLlmFiles = ( ->String.trim let filePath = sectionLlmFilePath(~llmsDirectory, sectionFile) - createDirectoryIfNotExists(Node.Path.dirname(filePath)) + createDirectoryIfNotExists(NodeJs.Path.dirname(filePath)) writeTextFile( filePath, `# ${sectionFile.title} @@ -185,7 +185,7 @@ let removeToDos = (content: string): string => { } let createFullFile = (content: string, filePath: string): unit => { - Node.Fs.appendFileSync(filePath, content ++ "\n", "utf8") + NodeJs.Fs.appendFileSync(filePath, content ++ "\n", "utf8") } let createSmallFile = (content: string, filePath: string): unit => { @@ -196,7 +196,7 @@ let createSmallFile = (content: string, filePath: string): unit => { ->removeToDos ->removeCodeBlocks ->removeUnnecessaryBreaks - Node.Fs.appendFileSync(filePath, smallContent, "utf8") + NodeJs.Fs.appendFileSync(filePath, smallContent, "utf8") } let replacePlaceholder = (content: string, placeholder: string, value: string): string => { @@ -224,9 +224,9 @@ let createLlmsFiles = ( docsDirectory: string, llmsDirectory: string, ): unit => { - let mdxFileTemplatePath = llmsDirectory->Node.Path.join2("template.mdx") - let mdxFilePath = docsDirectory->Node.Path.join2("llms.mdx") - let txtFileTemplatePath = llmsDirectory->Node.Path.join2("template.txt") + let mdxFileTemplatePath = llmsDirectory->NodeJs.Path.join2("template.mdx") + let mdxFilePath = docsDirectory->NodeJs.Path.join2("llms.mdx") + let txtFileTemplatePath = llmsDirectory->NodeJs.Path.join2("template.txt") Console.log(txtFilePath) @@ -264,8 +264,8 @@ let generateFile = ( let smallFileName = "llm-small.txt" let llmsDir = llmsDirectory - let fullFilePath = llmsDir->Node.Path.join2(fullFileName) - let smallFilePath = llmsDir->Node.Path.join2(smallFileName) + let fullFilePath = llmsDir->NodeJs.Path.join2(fullFileName) + let smallFilePath = llmsDir->NodeJs.Path.join2(smallFileName) createDirectoryIfNotExists(llmsDir) clearFile(fullFilePath) @@ -277,7 +277,7 @@ let generateFile = ( } staleVersions->Array.forEach(version => { - let versionedLlmsDirectory = llmsDirectory->Node.Path.join2(version) + let versionedLlmsDirectory = llmsDirectory->NodeJs.Path.join2(version) removeLlmsTextFiles(~llmsDirectory=versionedLlmsDirectory) removeSectionLlmFiles(~llmsDirectory=versionedLlmsDirectory, ~sectionFiles) }) @@ -366,7 +366,7 @@ generateFile( ~currentVersion=currentReactVersion, ~rescriptReactVersion=currentReactVersion, ~reactVersion=currentReactRuntimeVersion, - ~txtFilePath=reactLlmsDirectory->Node.Path.join2("llms.txt"), + ~txtFilePath=reactLlmsDirectory->NodeJs.Path.join2("llms.txt"), ~staleVersions=["latest", currentReactVersion], reactDocsDirectory, reactLlmsDirectory, diff --git a/apps/docs/scripts/generate_sitemap.res b/apps/docs/scripts/generate_sitemap.res index d85dc9f44..3ac810d80 100644 --- a/apps/docs/scripts/generate_sitemap.res +++ b/apps/docs/scripts/generate_sitemap.res @@ -1,7 +1,7 @@ let rec collectPagePaths = (dirPath, urlPath) => { - Node.Fs.readdirSync(dirPath)->Array.flatMap(entry => { - let fullPath = Node.Path.join2(dirPath, entry) - let stats = Node.Fs.statSync(fullPath) + NodeJs.Fs.readdirSync(dirPath)->Array.flatMap(entry => { + let fullPath = NodeJs.Path.join2(dirPath, entry) + let stats = NodeJs.Fs.statSync(fullPath) if stats["isDirectory"]() { let nextUrlPath = if urlPath === "" { @@ -20,7 +20,7 @@ let rec collectPagePaths = (dirPath, urlPath) => { } let outputDirs = { - let args = Node.Process.argv->Array.slice(~start=2) + let args = NodeJs.Process.argv->Array.slice(~start=2) switch args->Array.length { | 0 => ["build/client"] @@ -30,18 +30,18 @@ let outputDirs = { let sourceDir = outputDirs->Array.get(0)->Option.getOr("build/client") -if !Node.Fs.existsSync(sourceDir) { +if !NodeJs.Fs.existsSync(sourceDir) { Console.error(`Cannot generate sitemap: ${sourceDir} does not exist`) - Node.Process.exit(1) + NodeJs.Process.exit(1) } -let baseUrl = Node.Process.env->Dict.get("VITE_DEPLOYMENT_URL")->Option.getOr("") +let baseUrl = NodeJs.Process.env->Dict.get("VITE_DEPLOYMENT_URL")->Option.getOr("") let sitemap = sourceDir->collectPagePaths("")->Sitemap.render(~baseUrl) outputDirs->Array.forEach(outputDir => { - if Node.Fs.existsSync(outputDir) { - let filePath = Node.Path.join2(outputDir, "sitemap.xml") - Node.Fs.writeFileSync(filePath, sitemap, ~encoding="utf8") + if NodeJs.Fs.existsSync(outputDir) { + let filePath = NodeJs.Path.join2(outputDir, "sitemap.xml") + NodeJs.Fs.writeFileSync(filePath, sitemap, ~encoding="utf8") Console.log(`Generated ${filePath}`) } }) diff --git a/apps/docs/scripts/test-examples.mjs b/apps/docs/scripts/test-examples.mjs index 93846af3b..5698ae654 100644 --- a/apps/docs/scripts/test-examples.mjs +++ b/apps/docs/scripts/test-examples.mjs @@ -506,12 +506,11 @@ let ensureTempProject = ({ tempRoot, preserve = false }) => { fs.writeFileSync(tempModulePath(tempRoot, "res"), ""); let tempNodeModules = path.join(tempRoot, "node_modules", "@rescript"); let tempReactPackage = path.join(tempNodeModules, "react"); - if (!fs.existsSync(tempReactPackage)) { - fs.mkdirSync(tempNodeModules, { recursive: true }); - fs.cpSync(rescriptReactPackageRoot, tempReactPackage, { - recursive: true, - }); - } + fs.rmSync(tempReactPackage, { recursive: true, force: true }); + fs.mkdirSync(tempNodeModules, { recursive: true }); + fs.cpSync(rescriptReactPackageRoot, tempReactPackage, { + recursive: true, + }); }; export let collectCodeTabPairs = (content) => { diff --git a/apps/docs/src/bindings/Cloudflare.res b/apps/docs/src/bindings/Cloudflare.res index c179bc63b..23aab4cd8 100644 --- a/apps/docs/src/bindings/Cloudflare.res +++ b/apps/docs/src/bindings/Cloudflare.res @@ -1,5 +1,3 @@ -open WebAPI - type font = { name: string, data: ArrayBuffer.t, @@ -13,7 +11,7 @@ type ogImageOptions = { fonts: array, } -type t = FetchAPI.response +type t = Response.t @new @module("@cloudflare/pages-plugin-vercel-og/api") external imageResponse: (Jsx.element, ogImageOptions) => promise = "ImageResponse" diff --git a/apps/docs/src/bindings/Jsdom.res b/apps/docs/src/bindings/Jsdom.res index 43f12c740..bd88832eb 100644 --- a/apps/docs/src/bindings/Jsdom.res +++ b/apps/docs/src/bindings/Jsdom.res @@ -1,5 +1,5 @@ -type window = {document: WebAPI.DOMAPI.document} -type t = {window: WebAPI.DOMAPI.window} +type window = {document: DomTypes.document} +type t = {window: window} @module("jsdom") @new external make: string => t = "JSDOM" diff --git a/apps/docs/src/common/Hooks.res b/apps/docs/src/common/Hooks.res index 682355c21..341f663ea 100644 --- a/apps/docs/src/common/Hooks.res +++ b/apps/docs/src/common/Hooks.res @@ -63,8 +63,8 @@ let useScrollDirection = (~topMargin=80, ~threshold=20) => { // let onScroll = Util.debounce(onScroll, 50) - WebAPI.Window.addEventListener(window, Scroll, onScroll) - Some(() => WebAPI.Window.removeEventListener(window, Scroll, onScroll)) + Window.addEventListener(window, Scroll, onScroll) + Some(() => Window.removeEventListener(window, Scroll, onScroll)) }, [topMargin, threshold]) scrollDir @@ -78,13 +78,13 @@ let useMediaQuery = (query: string) => { }) React.useEffect(() => { - let mediaQueryList = WebAPI.Window.matchMedia(window, query) + let mediaQueryList = Window.matchMedia(window, query) setMatches(_ => mediaQueryList.matches) let listener = (e: mediaQueryListEvent) => setMatches(_ => e.matches) - WebAPI.MediaQueryList.addEventListener(mediaQueryList, Change, listener) - Some(() => WebAPI.MediaQueryList.removeEventListener(mediaQueryList, Change, listener)) + MediaQueryList.addEventListener(mediaQueryList, Change, listener) + Some(() => MediaQueryList.removeEventListener(mediaQueryList, Change, listener)) }, [query]) matches diff --git a/apps/docs/src/common/Url.res b/apps/docs/src/common/Url.res index 7f56de3fc..758e06d5d 100644 --- a/apps/docs/src/common/Url.res +++ b/apps/docs/src/common/Url.res @@ -33,7 +33,7 @@ type storageKey = let getVersionFromStorage = (key: storageKey) => { try { - WebAPI.Storage.getItem(window.localStorage, (key :> string))->Null.toOption + Storage.getItem(localStorage, (key :> string))->Null.toOption } catch { | JsExn(_) => None } diff --git a/apps/docs/src/components/ApiMarkdown.res b/apps/docs/src/components/ApiMarkdown.res index e517f4fa9..aad9c5660 100644 --- a/apps/docs/src/components/ApiMarkdown.res +++ b/apps/docs/src/components/ApiMarkdown.res @@ -24,7 +24,7 @@ let default = { p: P.make, li: Li.make, h1: H1.make, - h2: H2.make->asMarkdownH2, + h2: H2.make->asMarkdownH2->React.component, h3: H3.make, h4: H4.make, h5: H5.make, diff --git a/apps/docs/src/components/CodeExample.res b/apps/docs/src/components/CodeExample.res index 3736d8da0..d9f2bfe68 100644 --- a/apps/docs/src/components/CodeExample.res +++ b/apps/docs/src/components/CodeExample.res @@ -64,21 +64,27 @@ module CopyButton = { // For Tailwind transitions to behave correctly, we need to first paint the DOM element in the tree, // and in the next tick, add the opacity-100 class, so the transition animation actually takes place. // If we don't do that, the banner will essentially pop up without any animation - let bannerEl = WebAPI.Document.createElement(document, "div") + let bannerEl = Document.createElement(document, "div") bannerEl.className = "opacity-0 absolute -top-6 right-0 -mt-5 -mr-4 px-4 py-2 w-40 rounded-lg captions text-white bg-gray-100 text-gray-80-tr transition-all duration-1000 ease-in-out " - let textNode = WebAPI.Document.createTextNode(document, "Copied to clipboard") + let textNode = Document.createTextNode(document, "Copied to clipboard") - WebAPI.Element.appendChild(bannerEl, textNode)->ignore - WebAPI.Element.appendChild(buttonEl, bannerEl)->ignore + Element.appendChild(bannerEl, textNode)->ignore + Element.appendChild(buttonEl, bannerEl)->ignore - let nextFrameId = WebAPI.Window.requestAnimationFrame(window, _ => { - WebAPI.DOMTokenList.toggle(bannerEl.classList, ~token="opacity-0")->ignore - WebAPI.DOMTokenList.toggle(bannerEl.classList, ~token="opacity-100")->ignore + let nextFrameId = Window.requestAnimationFrame(window, _ => { + DOMTokenList.toggle( + (bannerEl.classList :> DomTypes.domTokenList), + ~token="opacity-0", + )->ignore + DOMTokenList.toggle( + (bannerEl.classList :> DomTypes.domTokenList), + ~token="opacity-100", + )->ignore }) let timeoutId = setTimeout(~handler=() => { - buttonEl->WebAPI.Element.removeChild(bannerEl)->ignore + buttonEl->Element.removeChild(bannerEl)->ignore setState(_ => Init) }, ~timeout=3000) @@ -105,8 +111,7 @@ module CopyButton = { } } -@react.component -let make = ( +let render = ( ~highlightedLines=[], ~code: string, ~showLabel=true, @@ -155,6 +160,15 @@ let make = ( } +@react.component +let make = ( + ~highlightedLines=[], + ~code: string, + ~showLabel=true, + ~lang="text", + ~showCopyButton=false, +) => render(~highlightedLines, ~code, ~showLabel, ~lang, ~showCopyButton) + module Toggle = { type tab = { highlightedLines: option>, @@ -169,13 +183,14 @@ module Toggle = { switch tabs { | [tab] => - make({ - highlightedLines: ?tab.highlightedLines, - code: tab.code, - lang: ?tab.lang, - showLabel: true, - showCopyButton: true, - }) + let {highlightedLines, code, lang} = tab + render( + ~highlightedLines=highlightedLines->Option.getOr([]), + ~code, + ~lang=lang->Option.getOr("text"), + ~showLabel=true, + ~showCopyButton=true, + ) | multiple => let numberOfItems = Array.length(multiple) let tabElements = Array.mapWithIndex(multiple, (tab, i) => { diff --git a/apps/docs/src/components/Docson.res b/apps/docs/src/components/Docson.res index d7e35ad0f..0ed6eb1ed 100644 --- a/apps/docs/src/components/Docson.res +++ b/apps/docs/src/components/Docson.res @@ -20,8 +20,8 @@ let make = (~tag) => { // The api for docson is a little bit funky, so you need to check out the source to understand what it's doing // See: https://github.com/lbovet/docson/blob/master/src/index.js let _ = - fetch(segment) - ->Promise.then(WebAPI.Response.json) + Fetch.fetch(segment) + ->Promise.then(Response.json) ->Promise.then(schema => { let _ = switch element.current->Nullable.toOption { | Some(_el) => diff --git a/apps/docs/src/components/MarkdownComponents.res b/apps/docs/src/components/MarkdownComponents.res index 145d118c7..25c4cdea9 100644 --- a/apps/docs/src/components/MarkdownComponents.res +++ b/apps/docs/src/components/MarkdownComponents.res @@ -3,50 +3,41 @@ open Markdown type t = { /* MDX shortnames for more advanced components */ @as("Cite") - cite?: React.componentLike, React.element>, React.element>, + cite?: React.component, React.element>>, @as("Info") - info?: React.componentLike, React.element>, + info?: React.component>, @as("Warn") - warn?: React.componentLike, React.element>, + warn?: React.component>, @as("Intro") - intro?: React.componentLike, React.element>, + intro?: React.component>, @as("Image") - image?: React.componentLike< - Image.props, - React.element, - >, + image?: React.component>, @as("Video") - video?: React.componentLike, React.element>, + video?: React.component>, @as("UrlBox") - urlBox?: React.componentLike< - UrlBox.props, - React.element, - >, + urlBox?: React.component>, @as("CodeTab") - codeTab?: CodeTab.props> => React.element, + codeTab?: React.component>>, /* Common markdown elements */ - p?: P.props => React.element, - li?: Li.props => React.element, - h1?: H1.props => React.element, - h2?: H2.props => React.element, - h3?: H3.props => React.element, - h4?: H4.props => React.element, - h5?: H5.props => React.element, - ul?: Ul.props => React.element, - ol?: Ol.props => React.element, - table?: Table.props => React.element, - thead?: Thead.props => React.element, - th?: Th.props => React.element, - td?: Td.props => React.element, - blockquote?: Blockquote.props => React.element, - strong?: Strong.props => React.element, - hr?: Hr.props => React.element, - code?: React.componentLike< - Code.props, MdxLegacy.Components.unknown>, - React.element, - >, - pre?: Pre.props => React.element, - a?: A.props => React.element, + p?: React.component>, + li?: React.component>, + h1?: React.component>, + h2?: React.component>, + h3?: React.component>, + h4?: React.component>, + h5?: React.component>, + ul?: React.component>, + ol?: React.component>, + table?: React.component>, + thead?: React.component>, + th?: React.component>, + td?: React.component>, + blockquote?: React.component>, + strong?: React.component>, + hr?: React.component, + code?: React.component, MdxLegacy.Components.unknown>>, + pre?: React.component>, + a?: React.component>, } let default = { diff --git a/apps/docs/src/components/NavbarUtils.res b/apps/docs/src/components/NavbarUtils.res index 0f639ffdb..96b8484f0 100644 --- a/apps/docs/src/components/NavbarUtils.res +++ b/apps/docs/src/components/NavbarUtils.res @@ -18,24 +18,27 @@ let linkOrActiveLink = (~target: Path.t, ~route: Path.t) => target === route ? a let linkOrActiveLinkSubroute = (~target: Path.t, ~route: Path.t) => String.startsWith((route :> string), (target :> string)) ? activeLink : link -external elementToDialog: WebAPI.DOMAPI.element => WebAPI.DOMAPI.htmlDialogElement = "%identity" +external elementToDialog: DomTypes.element => DomTypes.htmlDialogElement = "%identity" let getMobileOverlayDialog = () => { - Nullable.make(document->WebAPI.Document.getElementById("mobile-overlay")->elementToDialog) + document + ->Document.getElementById("mobile-overlay") + ->Null.map(elementToDialog) + ->Null.asNullable } -@get external _open: WebAPI.DOMAPI.htmlDialogElement => bool = "open" +@get external _open: DomTypes.htmlDialogElement => bool = "open" let openMobileOverlay = _ => switch getMobileOverlayDialog() { - | Nullable.Value(dialog) => dialog->WebAPI.HTMLDialogElement.showModal + | Nullable.Value(dialog) => dialog->HTMLDialogElement.showModal | Null => () | Undefined => () } let closeMobileOverlay = _ => switch getMobileOverlayDialog() { - | Nullable.Value(dialog) => dialog->WebAPI.HTMLDialogElement.close + | Nullable.Value(dialog) => dialog->HTMLDialogElement.close | Null => () | Undefined => () } @@ -55,19 +58,22 @@ let toggleMobileOverlay = _ => { } let getMobileTertiaryDialog = () => { - Nullable.make(document->WebAPI.Document.getElementById("mobile-tertiary-drawer")->elementToDialog) + document + ->Document.getElementById("mobile-tertiary-drawer") + ->Null.map(elementToDialog) + ->Null.asNullable } let openMobileTertiaryDrawer = _ => switch getMobileTertiaryDialog() { - | Nullable.Value(dialog) => dialog->WebAPI.HTMLDialogElement.showModal + | Nullable.Value(dialog) => dialog->HTMLDialogElement.showModal | Null => () | Undefined => () } let closeMobileTertiaryDrawer = _ => switch getMobileTertiaryDialog() { - | Nullable.Value(dialog) => dialog->WebAPI.HTMLDialogElement.close + | Nullable.Value(dialog) => dialog->HTMLDialogElement.close | Null => () | Undefined => () } diff --git a/apps/docs/src/components/Search.res b/apps/docs/src/components/Search.res index f650a1d4b..ef02cc8f8 100644 --- a/apps/docs/src/components/Search.res +++ b/apps/docs/src/components/Search.res @@ -325,7 +325,7 @@ module ActiveDocSearch = { hitComponent onClose insights=true - initialScrollY={window.scrollY->Float.toInt} + initialScrollY={scrollY->Float.toInt} searchParameters={ distinct: 3, hitsPerPage: 20, @@ -346,20 +346,21 @@ let make = () => { let algoliaConfig = Env.algoliaPublicConfig let deactivateSearch = () => { - switch WebAPI.Document.querySelector(document, "body") { - | Value(body) => WebAPI.DOMTokenList.remove(body.classList, "DocSearch--active") + switch Document.querySelector(document, "body") { + | Value(body) => + DOMTokenList.remove((body.classList :> DomTypes.domTokenList), "DocSearch--active") | Null => () } setState(_ => Inactive) } let handleCloseModal = () => { - let () = switch WebAPI.Document.querySelector(document, ".DocSearch-Modal") { + let () = switch Document.querySelector(document, ".DocSearch-Modal") { | Value(modal) => - switch WebAPI.Document.querySelector(document, "body") { + switch Document.querySelector(document, "body") { | Value(body) => - WebAPI.DOMTokenList.remove(body.classList, "DocSearch--active") - modal->WebAPI.Element.addEventListener(Transitionend, () => { + DOMTokenList.remove((body.classList :> DomTypes.domTokenList), "DocSearch--active") + modal->Element.addEventListener(Transitionend, () => { setState(_ => Inactive) }) | Null => setState(_ => Inactive) @@ -372,31 +373,31 @@ let make = () => { switch algoliaConfig { | None => None | Some(_) => - let isEditableTag = (el: WebAPI.DOMAPI.element) => + let isEditableTag = (el: DomTypes.element) => switch el.tagName { | "TEXTAREA" | "SELECT" | "INPUT" => true | _ => false } - let focusSearch = (e: WebAPI.UIEventsAPI.keyboardEvent) => { + let focusSearch = (e: UiEventsTypes.keyboardEvent) => { switch document.activeElement { | Value(el) - if el->isEditableTag || (Obj.magic(el): WebAPI.DOMAPI.htmlElement).isContentEditable => () + if el->isEditableTag || (Obj.magic(el): DomTypes.htmlElement).isContentEditable => () | _ => setState(_ => Active) - WebAPI.KeyboardEvent.preventDefault(e) + KeyboardEvent.preventDefault(e) } } - let handleGlobalKeyDown = (e: WebAPI.UIEventsAPI.keyboardEvent) => { + let handleGlobalKeyDown = (e: UiEventsTypes.keyboardEvent) => { switch e.key { | "/" => focusSearch(e) | "k" if e.ctrlKey || e.metaKey => focusSearch(e) | _ => () } } - WebAPI.Window.addEventListener(window, Keydown, handleGlobalKeyDown) - Some(() => WebAPI.Window.removeEventListener(window, Keydown, handleGlobalKeyDown)) + Window.addEventListener(window, Keydown, handleGlobalKeyDown) + Some(() => Window.removeEventListener(window, Keydown, handleGlobalKeyDown)) } }, [algoliaConfig]) diff --git a/apps/docs/src/components/SearchBox.res b/apps/docs/src/components/SearchBox.res index f99e31c3b..db6454848 100644 --- a/apps/docs/src/components/SearchBox.res +++ b/apps/docs/src/components/SearchBox.res @@ -23,8 +23,7 @@ let make = ( onClear() } - let focusInput = () => - textInput.current->Nullable.forEach(el => el->WebAPI.HTMLInputElement.focus) + let focusInput = () => textInput.current->Nullable.forEach(el => el->HTMLInputElement.focus) let onAreaFocus = evt => { let el = ReactEvent.Focus.target(evt) diff --git a/apps/docs/src/components/SidebarNav.res b/apps/docs/src/components/SidebarNav.res index e865eeb84..c445f2721 100644 --- a/apps/docs/src/components/SidebarNav.res +++ b/apps/docs/src/components/SidebarNav.res @@ -10,10 +10,9 @@ module Toc = { prefetch={#intent} onClick={evt => { evt->ReactEvent.Mouse.preventDefault - WebAPI.Document.getElementById( - document, - href->String.replace("#", ""), - )->WebAPI.Element.scrollIntoView_alignToTop + Document.getElementById(document, href->String.replace("#", "")) + ->Null.toOption + ->Option.forEach(element => element->Element.scrollIntoViewAlignToTop) onClick() }} to={"#" ++ href->Url.normalizeAnchor} diff --git a/apps/docs/src/data/BlogApi.res b/apps/docs/src/data/BlogApi.res index 4afd795c3..48b0e6e82 100644 --- a/apps/docs/src/data/BlogApi.res +++ b/apps/docs/src/data/BlogApi.res @@ -34,16 +34,16 @@ let blogPathToSlug = path => { } let mdxFiles = dir => { - Node.Fs.readdirSync(dir)->Array.filter(path => Node.Path.extname(path) === ".mdx") + NodeJs.Fs.readdirSync(dir)->Array.filter(path => NodeJs.Path.extname(path) === ".mdx") } let getAllPosts = () => { - let postsDirectory = Node.Path.join2(Node.Process.cwd(), "markdown-pages/blog") - let archivedPostsDirectory = Node.Path.join2(postsDirectory, "archived") + let postsDirectory = NodeJs.Path.join2(NodeJs.Process.cwd(), "markdown-pages/blog") + let archivedPostsDirectory = NodeJs.Path.join2(postsDirectory, "archived") let nonArchivedPosts = mdxFiles(postsDirectory)->Array.map(path => { let {frontmatter} = - Node.Path.join2(postsDirectory, path)->Node.Fs.readFileSync->MarkdownParser.parseSync + NodeJs.Path.join2(postsDirectory, path)->NodeJs.Fs.readFileSync->MarkdownParser.parseSync switch BlogFrontmatter.decode(frontmatter) { | Error(msg) => JsError.throwWithMessage(msg) | Ok(d) => { @@ -56,11 +56,13 @@ let getAllPosts = () => { let archivedPosts = mdxFiles(archivedPostsDirectory)->Array.map(path => { let {frontmatter} = - Node.Path.join2(archivedPostsDirectory, path)->Node.Fs.readFileSync->MarkdownParser.parseSync + NodeJs.Path.join2(archivedPostsDirectory, path) + ->NodeJs.Fs.readFileSync + ->MarkdownParser.parseSync switch BlogFrontmatter.decode(frontmatter) { | Error(msg) => JsError.throwWithMessage(msg) | Ok(d) => { - path: Node.Path.join2("archived", path), + path: NodeJs.Path.join2("archived", path), frontmatter: d, archived: true, } @@ -68,16 +70,16 @@ let getAllPosts = () => { }) Array.concat(nonArchivedPosts, archivedPosts)->Array.toSorted((a, b) => - String.compare(Node.Path.basename(b.path), Node.Path.basename(a.path)) + String.compare(NodeJs.Path.basename(b.path), NodeJs.Path.basename(a.path)) ) } let getLivePosts = () => { - let postsDirectory = Node.Path.join2(Node.Process.cwd(), "markdown-pages/blog") + let postsDirectory = NodeJs.Path.join2(NodeJs.Process.cwd(), "markdown-pages/blog") let livePosts = mdxFiles(postsDirectory)->Array.map(path => { let {frontmatter} = - Node.Path.join2(postsDirectory, path)->Node.Fs.readFileSync->MarkdownParser.parseSync + NodeJs.Path.join2(postsDirectory, path)->NodeJs.Fs.readFileSync->MarkdownParser.parseSync switch BlogFrontmatter.decode(frontmatter) { | Error(msg) => JsError.throwWithMessage(msg) | Ok(d) => { @@ -89,21 +91,23 @@ let getLivePosts = () => { }) livePosts->Array.toSorted((a, b) => - String.compare(Node.Path.basename(b.path), Node.Path.basename(a.path)) + String.compare(NodeJs.Path.basename(b.path), NodeJs.Path.basename(a.path)) ) } let getArchivedPosts = () => { - let postsDirectory = Node.Path.join2(Node.Process.cwd(), "markdown-pages/blog") - let archivedPostsDirectory = Node.Path.join2(postsDirectory, "archived") + let postsDirectory = NodeJs.Path.join2(NodeJs.Process.cwd(), "markdown-pages/blog") + let archivedPostsDirectory = NodeJs.Path.join2(postsDirectory, "archived") let archivedPosts = mdxFiles(archivedPostsDirectory)->Array.map(path => { let {frontmatter} = - Node.Path.join2(archivedPostsDirectory, path)->Node.Fs.readFileSync->MarkdownParser.parseSync + NodeJs.Path.join2(archivedPostsDirectory, path) + ->NodeJs.Fs.readFileSync + ->MarkdownParser.parseSync switch BlogFrontmatter.decode(frontmatter) { | Error(msg) => JsError.throwWithMessage(msg) | Ok(d) => { - path: Node.Path.join2("archived", path), + path: NodeJs.Path.join2("archived", path), frontmatter: d, archived: true, } @@ -111,7 +115,7 @@ let getArchivedPosts = () => { }) archivedPosts->Array.toSorted((a, b) => - String.compare(Node.Path.basename(b.path), Node.Path.basename(a.path)) + String.compare(NodeJs.Path.basename(b.path), NodeJs.Path.basename(a.path)) ) } diff --git a/apps/docs/src/data/MetaTagsApi.res b/apps/docs/src/data/MetaTagsApi.res index 7f3655d02..e299c24f7 100644 --- a/apps/docs/src/data/MetaTagsApi.res +++ b/apps/docs/src/data/MetaTagsApi.res @@ -6,30 +6,30 @@ type t = { /** This function uses JSDOM to fetch a webpage and extract the meta tags from it. - JSDOM is required since this runs on Node. + JSDOM is required since this runs on NodeJs. */ let extractMetaTags = async (url: string) => { try { - let response = await fetch(url) + let response = await Fetch.fetch(url) - let html = await response->WebAPI.Response.text + let html = await response->Response.text let dom = Jsdom.make(html) let document = dom.window.document - let nodeList = document->WebAPI.Document.querySelectorAll("meta") + let nodeList = document->Document.querySelectorAll("meta") let elements = [] for i in 0 to nodeList.length { - let node = WebAPI.NodeList.item(nodeList, i) + let node = NodeList.item(nodeList, i) // cast Node elements to Element - elements->Array.push((Obj.magic(node): WebAPI.DOMAPI.element)) + elements->Array.push((Obj.magic(node): DomTypes.element)) } let metaTags = elements->Array.reduce(Dict.fromArray([]), (tags, meta) => { - let name = meta->WebAPI.Element.getAttribute("name") - let property = meta->WebAPI.Element.getAttribute("property") - let itemprop = meta->WebAPI.Element.getAttribute("itemprop") + let name = meta->Element.getAttribute("name") + let property = meta->Element.getAttribute("property") + let itemprop = meta->Element.getAttribute("itemprop") let name = switch (name, property, itemprop) { | (Value(name), _, _) => Some(name) @@ -38,7 +38,7 @@ let extractMetaTags = async (url: string) => { | _ => None } - let content = meta->WebAPI.Element.getAttribute("content") + let content = meta->Element.getAttribute("content") switch (name, content) { | (Some(name), Value(content)) => tags->Dict.set(name, content) diff --git a/apps/docs/src/layouts/CommunityLayout.res b/apps/docs/src/layouts/CommunityLayout.res index 3c0177528..12f0d1ebd 100644 --- a/apps/docs/src/layouts/CommunityLayout.res +++ b/apps/docs/src/layouts/CommunityLayout.res @@ -22,7 +22,6 @@ let make = (~children, ~categories, ~entries) => { toggle={() => setSidebarOpen(prev => !prev)} activeToc={title: "Overview", entries} />} - sidebarState=(isSidebarOpen, setSidebarOpen) docSearchLvl0="Community" > children diff --git a/apps/docs/src/layouts/DocsLayout.res b/apps/docs/src/layouts/DocsLayout.res index 238f8d238..f88258494 100644 --- a/apps/docs/src/layouts/DocsLayout.res +++ b/apps/docs/src/layouts/DocsLayout.res @@ -7,7 +7,6 @@ module Sidebar = SidebarNav let make = ( ~activeToc: option=?, ~categories: array, - ~components=MarkdownComponents.default, ~docSearchLvl0=?, ~children, ) => { @@ -24,7 +23,5 @@ let make = ( let sidebar = - - children - + children } diff --git a/apps/docs/src/layouts/MainLayout.res b/apps/docs/src/layouts/MainLayout.res index 059e9f8d4..f30fb2efe 100644 --- a/apps/docs/src/layouts/MainLayout.res +++ b/apps/docs/src/layouts/MainLayout.res @@ -1,5 +1,5 @@ @react.component -let make = (~components=MarkdownComponents.default, ~children) => { +let make = (~children) => { <>
diff --git a/apps/docs/src/layouts/MainLayout.resi b/apps/docs/src/layouts/MainLayout.resi index e76a5ba10..940ed3d87 100644 --- a/apps/docs/src/layouts/MainLayout.resi +++ b/apps/docs/src/layouts/MainLayout.resi @@ -1,2 +1,2 @@ @react.component -let make: (~components: MarkdownComponents.t=?, ~children: React.element) => React.element +let make: (~children: React.element) => React.element diff --git a/apps/docs/src/layouts/SidebarPageLayout.res b/apps/docs/src/layouts/SidebarPageLayout.res index 8445b4572..d56d25bc9 100644 --- a/apps/docs/src/layouts/SidebarPageLayout.res +++ b/apps/docs/src/layouts/SidebarPageLayout.res @@ -2,8 +2,6 @@ module Link = ReactRouter.Link @react.component let make = ( - ~sidebarState: (bool, (bool => bool) => unit)=(false, _ => ()), - // (Sidebar, toggleSidebar) ... for toggling sidebar in mobile view ~sidebar: React.element, ~rightSidebar: option=?, ~categories: option>=?, diff --git a/apps/docs/src/layouts/SidebarPageLayout.resi b/apps/docs/src/layouts/SidebarPageLayout.resi index d9730f135..acf6130f8 100644 --- a/apps/docs/src/layouts/SidebarPageLayout.resi +++ b/apps/docs/src/layouts/SidebarPageLayout.resi @@ -1,7 +1,5 @@ @react.component let make: ( - // (Sidebar, toggleSidebar) ... for toggling sidebar in mobile view - ~sidebarState: (bool, (bool => bool) => unit)=?, ~sidebar: React.element, ~rightSidebar: React.element=?, ~categories: array=?, diff --git a/apps/docs/src/markdown/Mdx.res b/apps/docs/src/markdown/Mdx.res index dbb9bc9c5..bd620e8d7 100644 --- a/apps/docs/src/markdown/Mdx.res +++ b/apps/docs/src/markdown/Mdx.res @@ -166,7 +166,7 @@ let remarkLinkPlugin = (tree, vfile) => { // Strip put any file extensions from internal links node["url"] = - Node.Path.resolve(filePath, path) + NodeJs.Path.resolve(filePath, path) ->String.replace(vfile["cwd"] ++ "/markdown-pages", "") ->String.replaceAll(".mdx", "") ->String.replaceAll(".md", "") ++ hash diff --git a/apps/docs/src/markdown/MdxFile.res b/apps/docs/src/markdown/MdxFile.res index 58657d7cf..1fb5d325d 100644 --- a/apps/docs/src/markdown/MdxFile.res +++ b/apps/docs/src/markdown/MdxFile.res @@ -32,10 +32,10 @@ let resolveFilePath = (pathname, ~dir, ~alias) => { } let relativePath = if path->String.startsWith(alias ++ "/") { let rest = path->String.slice(~start=String.length(alias) + 1, ~end=String.length(path)) - Node.Path.join2(dir, rest) + NodeJs.Path.join2(dir, rest) } else if path->String.startsWith(alias) { let rest = path->String.slice(~start=String.length(alias), ~end=String.length(path)) - Node.Path.join2(dir, rest) + NodeJs.Path.join2(dir, rest) } else { path } @@ -43,19 +43,19 @@ let resolveFilePath = (pathname, ~dir, ~alias) => { } let loadFile = async filePath => { - let raw = await Node.Fs.readFile(filePath, "utf-8") + let raw = await NodeJs.Fs.readFile(filePath, "utf-8") let {frontmatter, content}: MarkdownParser.result = MarkdownParser.parseSync(raw) {content, frontmatter} } // Recursively scan a directory for .mdx files let rec scanDir = (baseDir, currentDir) => { - let entries = Node.Fs.readdirSync(currentDir) + let entries = NodeJs.Fs.readdirSync(currentDir) entries->Array.flatMap(entry => { - let fullPath = Node.Path.join2(currentDir, entry) - if Node.Fs.statSync(fullPath)["isDirectory"]() { + let fullPath = NodeJs.Path.join2(currentDir, entry) + if NodeJs.Fs.statSync(fullPath)["isDirectory"]() { scanDir(baseDir, fullPath) - } else if Node.Path.extname(entry) === ".mdx" { + } else if NodeJs.Path.extname(entry) === ".mdx" { // Get the relative path from baseDir let relativePath = fullPath @@ -86,8 +86,8 @@ let loadAllAttributes = async (~dir) => { let files = scanDir(dir, dir) await Promise.all( files->Array.map(async relativePath => { - let fullPath = Node.Path.join2(dir, relativePath ++ ".mdx")->String.replaceAll("\\", "/") - let raw = await Node.Fs.readFile(fullPath, "utf-8") + let fullPath = NodeJs.Path.join2(dir, relativePath ++ ".mdx")->String.replaceAll("\\", "/") + let raw = await NodeJs.Fs.readFile(fullPath, "utf-8") let {frontmatter}: MarkdownParser.result = MarkdownParser.parseSync(raw) let dict = switch frontmatter { @@ -97,7 +97,7 @@ let loadAllAttributes = async (~dir) => { // Add path and slug fields (same as react-router-mdx does) dict->Dict.set("path", JSON.String(fullPath)) - let slug = Node.Path.basename(relativePath) + let slug = NodeJs.Path.basename(relativePath) dict->Dict.set("slug", JSON.String(slug)) dictToAttributes(dict) diff --git a/apps/docs/test-utils/TestUtils.res b/apps/docs/test-utils/TestUtils.res index 6a5e7780d..c8597ae77 100644 --- a/apps/docs/test-utils/TestUtils.res +++ b/apps/docs/test-utils/TestUtils.res @@ -7,20 +7,20 @@ let sleep = ms => }, ~timeout=ms) }) -external imageFromNode: WebAPI.DOMAPI.node => WebAPI.DOMAPI.htmlImageElement = "%identity" +external imageFromElement: DomTypes.element => DomTypes.htmlImageElement = "%identity" let waitForImages = async (selector: string) => { - let root = switch document->WebAPI.Document.querySelector(selector) { + let root = switch document->Document.querySelector(selector) { | Value(root) => root | Null => failwith(`expected to find screenshot target ${selector}`) } - let images = root->WebAPI.Element.querySelectorAll("img") + let images = root->Element.querySelectorAll("img") if images.length > 0 { for i in 0 to images.length - 1 { - let image = images->WebAPI.NodeList.item(i)->imageFromNode - await image->WebAPI.HTMLImageElement.decode + let image = images->NodeList.item(i)->imageFromElement + await image->HTMLImageElement.decode } } } diff --git a/apps/guide/__tests__/GuideHome_.test.res b/apps/guide/__tests__/GuideHome_.test.res index b2786b7a1..45d2026ef 100644 --- a/apps/guide/__tests__/GuideHome_.test.res +++ b/apps/guide/__tests__/GuideHome_.test.res @@ -78,10 +78,10 @@ test("navigates to the function argument page", async () => { GuideLayout.clearExerciseCode(secondLesson.exercise.id) }) -let guideTestUrl = hash => window.location.pathname ++ window.location.search ++ hash +let guideTestUrl = hash => location.pathname ++ location.search ++ hash let resetGuideTestUrl = () => - WebAPI.History.replaceState(window.history, ~data=JSON.Null, ~unused="", ~url=guideTestUrl("")) + History.replaceState(history, ~data=JSON.Null, ~unused="", ~url=guideTestUrl("")) test("shows Back before lesson forward actions and returns to the previous lesson", async () => { await viewport(1440, 900) @@ -168,18 +168,8 @@ test("browser back returns to the previous guide lesson", async () => { GuideLayout.clearCompletedExercises() GuideLayout.clearExerciseCode(firstLesson.exercise.id) GuideLayout.clearExerciseCode(secondLesson.exercise.id) - WebAPI.History.replaceState( - window.history, - ~data=JSON.Null, - ~unused="", - ~url=guideTestUrl("#guide-test-start"), - ) - WebAPI.History.pushState( - window.history, - ~data=JSON.Null, - ~unused="", - ~url=guideTestUrl("#first-contact"), - ) + History.replaceState(history, ~data=JSON.Null, ~unused="", ~url=guideTestUrl("#guide-test-start")) + History.pushState(history, ~data=JSON.Null, ~unused="", ~url=guideTestUrl("#first-contact")) let screen = await renderGuideHomeInBrowser() @@ -187,7 +177,7 @@ test("browser back returns to the previous guide lesson", async () => { await (await screen->getByText("Next"))->click await (await screen->getByText("Call A Function"))->element->toBeVisible - WebAPI.History.back(window.history) + History.back(history) await (await screen->getByText("Learn ReScript Guide"))->element->toBeVisible diff --git a/apps/guide/app/GuideCompilerBridgeHook.res b/apps/guide/app/GuideCompilerBridgeHook.res index 2b19d1a1b..2c5ee7043 100644 --- a/apps/guide/app/GuideCompilerBridgeHook.res +++ b/apps/guide/app/GuideCompilerBridgeHook.res @@ -59,8 +59,8 @@ let useCompilerBridge = ( | _ => () } } - WebAPI.Window.addEventListener(window, Custom("message"), cb) - Some(() => WebAPI.Window.removeEventListener(window, Custom("message"), cb)) + Window.addEventListener(window, Custom("message"), cb) + Some(() => Window.removeEventListener(window, Custom("message"), cb)) }, [setOutput]) React.useEffect(() => { diff --git a/apps/guide/app/GuideCompilerData.res b/apps/guide/app/GuideCompilerData.res index d4a32be91..4ee09fd92 100644 --- a/apps/guide/app/GuideCompilerData.res +++ b/apps/guide/app/GuideCompilerData.res @@ -10,8 +10,8 @@ module Env = { } let fetchVersions = async versionsBaseUrl => { - let response = await fetch(versionsBaseUrl ++ "/playground-bundles/versions.json") - let json = await WebAPI.Response.json(response) + let response = await Fetch.fetch(versionsBaseUrl ++ "/playground-bundles/versions.json") + let json = await Response.json(response) json ->JSON.Decode.array ->Option.getOrThrow diff --git a/apps/guide/app/GuideDom.res b/apps/guide/app/GuideDom.res index 406bf1246..5be6239aa 100644 --- a/apps/guide/app/GuideDom.res +++ b/apps/guide/app/GuideDom.res @@ -1,3 +1,3 @@ -external domElementToWebElement: Dom.element => WebAPI.DOMAPI.element = "%identity" +external domElementToWebElement: Dom.element => DomTypes.element = "%identity" let toWebElement = domElementToWebElement diff --git a/apps/guide/app/GuideHome.res b/apps/guide/app/GuideHome.res index d6fad32f1..69167a225 100644 --- a/apps/guide/app/GuideHome.res +++ b/apps/guide/app/GuideHome.res @@ -1,4 +1,4 @@ -let navigateToDocsIntro = url => window.location->WebAPI.Location.assign(url) +let navigateToDocsIntro = url => location->Location.assign(url) @react.component let make = ( diff --git a/apps/guide/app/GuideLayout.res b/apps/guide/app/GuideLayout.res index 254d60598..11da22b0b 100644 --- a/apps/guide/app/GuideLayout.res +++ b/apps/guide/app/GuideLayout.res @@ -101,7 +101,7 @@ let themeToggleText = theme => // for the guide, so storage failures fall back to the current UI state. let getLocalStorageItem = key => { try { - WebAPI.Storage.getItem(window.localStorage, key)->Null.toOption + Storage.getItem(localStorage, key)->Null.toOption } catch { | JsExn(_) => None } @@ -109,7 +109,7 @@ let getLocalStorageItem = key => { let setLocalStorageItem = (~key, ~value) => { try { - WebAPI.Storage.setItem(window.localStorage, ~key, ~value) + Storage.setItem(localStorage, ~key, ~value) } catch { | JsExn(_) => () } @@ -117,7 +117,7 @@ let setLocalStorageItem = (~key, ~value) => { let removeLocalStorageItem = key => { try { - WebAPI.Storage.removeItem(window.localStorage, key) + Storage.removeItem(localStorage, key) } catch { | JsExn(_) => () } diff --git a/apps/guide/app/GuideLayoutHook.res b/apps/guide/app/GuideLayoutHook.res index 4ee7df26c..a647a40f7 100644 --- a/apps/guide/app/GuideLayoutHook.res +++ b/apps/guide/app/GuideLayoutHook.res @@ -23,8 +23,8 @@ let useLayout = (): t => { setTheme(_ => GuideLayout.loadTheme()) setPaneSizes(_ => GuideLayout.loadPaneSizes()->GuideLayout.clampPaneSizes( - ~viewportWidth=window.innerWidth->Int.toFloat, - ~viewportHeight=window.innerHeight->Int.toFloat, + ~viewportWidth=innerWidth->Int.toFloat, + ~viewportHeight=innerHeight->Int.toFloat, ) ) setThemeLoaded(_ => true) @@ -50,7 +50,7 @@ let useLayout = (): t => { switch shellRef.current { | Value(element) => // CSS variables keep the two resizable axes in one place for layout and tests. - WebAPI.Element.setAttribute( + Element.setAttribute( element->GuideDom.toWebElement, ~qualifiedName="style", ~value=paneSizes->GuideLayout.paneSizesStyle, @@ -67,24 +67,24 @@ let useLayout = (): t => { switch dragTarget.current { | ResizingColumns => let pointerX = event->ReactEvent.Mouse.clientX->Int.toFloat - let viewportWidth = window.innerWidth->Int.toFloat + let viewportWidth = innerWidth->Int.toFloat let instructionsWidth = GuideLayout.clampInstructionsWidth(~viewportWidth, ~pointerX) setPaneSizes(previous => {...previous, instructionsWidth: Some(instructionsWidth)}) | ResizingRows => let pointerY = event->ReactEvent.Mouse.clientY->Int.toFloat - let viewportHeight = window.innerHeight->Int.toFloat + let viewportHeight = innerHeight->Int.toFloat let outputHeight = GuideLayout.clampOutputHeight(~viewportHeight, ~pointerY) setPaneSizes(previous => {...previous, outputHeight}) | NotDragging => () } - WebAPI.Window.addEventListener(window, Mousemove, onMouseMove) - WebAPI.Window.addEventListener(window, Mouseup, stopDragging) + Window.addEventListener(window, Mousemove, onMouseMove) + Window.addEventListener(window, Mouseup, stopDragging) Some( () => { - WebAPI.Window.removeEventListener(window, Mousemove, onMouseMove) - WebAPI.Window.removeEventListener(window, Mouseup, stopDragging) + Window.removeEventListener(window, Mousemove, onMouseMove) + Window.removeEventListener(window, Mouseup, stopDragging) }, ) }, []) diff --git a/apps/guide/app/GuideLessonContent.res b/apps/guide/app/GuideLessonContent.res index 1e5d60e7c..f73be4b5a 100644 --- a/apps/guide/app/GuideLessonContent.res +++ b/apps/guide/app/GuideLessonContent.res @@ -48,7 +48,7 @@ let exerciseFromFrontmatter = (~dict, ~sourcePath): GuideLesson.exercise => { } let lessonFromFile = sourcePath => { - let raw = Node.Fs.readFileSync(sourcePath) + let raw = NodeJs.Fs.readFileSync(sourcePath) let {frontmatter, content}: MarkdownParser.result = MarkdownParser.parseSync(raw) let dict = frontmatterObject(~frontmatter, ~sourcePath) let exerciseDict = readObject(~dict, ~sourcePath, ~key="exercise") @@ -66,18 +66,18 @@ let lessonFromFile = sourcePath => { } let rec scanDir = currentDir => - Node.Fs.readdirSync(currentDir)->Array.flatMap(entry => { - let fullPath = Node.Path.join2(currentDir, entry) + NodeJs.Fs.readdirSync(currentDir)->Array.flatMap(entry => { + let fullPath = NodeJs.Path.join2(currentDir, entry) - if Node.Fs.statSync(fullPath)["isDirectory"]() { + if NodeJs.Fs.statSync(fullPath)["isDirectory"]() { scanDir(fullPath) - } else if Node.Path.extname(entry) === ".mdx" { + } else if NodeJs.Path.extname(entry) === ".mdx" { [fullPath] } else { [] } }) -let lessonsDir = () => Node.Path.join2(Node.Process.cwd(), "app/lessons") +let lessonsDir = () => NodeJs.Path.join2(NodeJs.Process.cwd(), "app/lessons") let load = (~dir=lessonsDir()) => scanDir(dir)->Array.map(lessonFromFile)->GuideLesson.sort diff --git a/apps/guide/app/root.jsx b/apps/guide/app/root.jsx index 38d3ccc4c..ee50dca94 100644 --- a/apps/guide/app/root.jsx +++ b/apps/guide/app/root.jsx @@ -7,29 +7,38 @@ import MainCssurl from "../styles/main.css?url"; let mainCss = MainCssurl; function Root$default(props) { - return ( - - - - - - - - {"ReScript Guide"} - - - - - - - - ); + return + + + + + + + + {"ReScript Guide"} + + + + + + + + ; } let $$default = Root$default; -export { $$default as default }; +export { + $$default as default, +} /* mainCss Not a pure module */ diff --git a/apps/guide/app/routes.jsx b/apps/guide/app/routes.jsx index c22c7185b..e793a07bf 100644 --- a/apps/guide/app/routes.jsx +++ b/apps/guide/app/routes.jsx @@ -4,5 +4,7 @@ import * as Routes from "@react-router/dev/routes"; let $$default = [Routes.index("./GuideHomeRoute.jsx")]; -export { $$default as default }; +export { + $$default as default, +} /* default Not a pure module */ diff --git a/apps/guide/package.json b/apps/guide/package.json index 9bd83e1d4..3ac994a92 100644 --- a/apps/guide/package.json +++ b/apps/guide/package.json @@ -19,8 +19,8 @@ "@react-router/node": "^7.15.0", "@rescript-lang/playground": "workspace:*", "@rescript-lang/shared": "workspace:*", - "@rescript/react": "^0.14.2", - "@rescript/webapi": "0.1.0-experimental-29db5f4", + "@rescript/react": "patch:@rescript/react@npm%3A0.14.2#~/.yarn/patches/@rescript-react-npm-0.14.2-b830f5af4f.patch", + "@rescript/webapi": "patch:@rescript/webapi@npm%3A0.1.0-experimental-0781ac8#~/.yarn/patches/@rescript-webapi-npm-0.1.0-experimental-0781ac8-50def7723d.patch", "isbot": "^5", "react": "^19.2.4", "react-dom": "^19.2.4", @@ -32,7 +32,7 @@ "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", - "rescript": "^12.2.0", + "rescript": "https://pkg.pr.new/rescript@8425", "unified": "^11.0.5", "vfile-matter": "^5.0.1" }, diff --git a/apps/guide/rescript.json b/apps/guide/rescript.json index 3c89889a8..f0df8e8fc 100644 --- a/apps/guide/rescript.json +++ b/apps/guide/rescript.json @@ -7,7 +7,7 @@ "@rescript/react", "@rescript/webapi" ], - "compiler-flags": ["-open WebAPI.Global"], + "compiler-flags": ["-open DomGlobal"], "sources": [ { "dir": "__tests__", diff --git a/apps/guide/vite.config.mjs b/apps/guide/vite.config.mjs index b6e1594e1..8840fb580 100644 --- a/apps/guide/vite.config.mjs +++ b/apps/guide/vite.config.mjs @@ -19,17 +19,17 @@ const sharedEditorDeps = [ "@codemirror/view", "@lezer/highlight", "@replit/codemirror-vim", - "@rescript/runtime/lib/es6/Belt_Array.js", - "@rescript/runtime/lib/es6/Primitive_int.js", - "@rescript/runtime/lib/es6/Primitive_object.js", - "@rescript/runtime/lib/es6/Primitive_option.js", - "@rescript/runtime/lib/es6/Primitive_string.js", - "@rescript/runtime/lib/es6/Stdlib_Array.js", - "@rescript/runtime/lib/es6/Stdlib_Dict.js", - "@rescript/runtime/lib/es6/Stdlib_Int.js", - "@rescript/runtime/lib/es6/Stdlib_JsExn.js", - "@rescript/runtime/lib/es6/Stdlib_List.js", - "@rescript/runtime/lib/es6/Stdlib_Option.js", + "@rescript/runtime/lib/es6/Belt_Array.mjs", + "@rescript/runtime/lib/es6/Primitive_int.mjs", + "@rescript/runtime/lib/es6/Primitive_object.mjs", + "@rescript/runtime/lib/es6/Primitive_option.mjs", + "@rescript/runtime/lib/es6/Primitive_string.mjs", + "@rescript/runtime/lib/es6/Stdlib_Array.mjs", + "@rescript/runtime/lib/es6/Stdlib_Dict.mjs", + "@rescript/runtime/lib/es6/Stdlib_Int.mjs", + "@rescript/runtime/lib/es6/Stdlib_JsExn.mjs", + "@rescript/runtime/lib/es6/Stdlib_List.mjs", + "@rescript/runtime/lib/es6/Stdlib_Option.mjs", "@tsnobip/rescript-lezer", "lz-string", "react-markdown", diff --git a/package.json b/package.json index e76950138..78f0552c1 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "devDependencies": { "lefthook": "^2.1.4", "oxfmt": "^0.46.0", - "rescript": "^12.2.0" + "rescript": "https://pkg.pr.new/rescript@8425" }, "resolutions": { "marked": "4.0.10" diff --git a/packages/playground/package.json b/packages/playground/package.json index 3fa96611d..b903d4062 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -6,8 +6,8 @@ "dependencies": { "@babel/parser": "^7.29.2", "@rescript-lang/shared": "workspace:*", - "@rescript/react": "^0.14.2", - "@rescript/webapi": "0.1.0-experimental-29db5f4", + "@rescript/react": "patch:@rescript/react@npm%3A0.14.2#~/.yarn/patches/@rescript-react-npm-0.14.2-b830f5af4f.patch", + "@rescript/webapi": "patch:@rescript/webapi@npm%3A0.1.0-experimental-0781ac8#~/.yarn/patches/@rescript-webapi-npm-0.1.0-experimental-0781ac8-50def7723d.patch", "lz-string": "^1.5.0", "react": "^19.2.4", "react-dom": "^19.2.4", diff --git a/packages/playground/rescript.json b/packages/playground/rescript.json index 997cde23e..baea88fb1 100644 --- a/packages/playground/rescript.json +++ b/packages/playground/rescript.json @@ -6,7 +6,7 @@ "@rescript/react", "@rescript/webapi" ], - "compiler-flags": ["-open WebAPI.Global"], + "compiler-flags": ["-open DomGlobal"], "sources": [ { "dir": "src", diff --git a/packages/playground/src/CompilerManagerHook.res b/packages/playground/src/CompilerManagerHook.res index 3e82102e8..931caaf13 100644 --- a/packages/playground/src/CompilerManagerHook.res +++ b/packages/playground/src/CompilerManagerHook.res @@ -627,7 +627,7 @@ let useCompilerManager = ( | SetupFailed(_) => () | Ready(ready) if syncUrl => let url = createUrl((pathname :> string), ready) - WebAPI.History.replaceState(history, ~data=JSON.Null, ~unused="", ~url) + History.replaceState(history, ~data=JSON.Null, ~unused="", ~url) | Ready(_) => () } } diff --git a/packages/playground/src/ConsolePanel.res b/packages/playground/src/ConsolePanel.res index 0c9bff4ed..d97acad87 100644 --- a/packages/playground/src/ConsolePanel.res +++ b/packages/playground/src/ConsolePanel.res @@ -6,7 +6,7 @@ type logLevel = [ type log = {level: logLevel, content: array} @react.component -let make = (~logs, ~appendLog) => { +let make = (~logs, ~appendLog: (logLevel, array) => unit) => { React.useEffect(() => { let cb = e => { let data = e["data"] @@ -17,8 +17,8 @@ let make = (~logs, ~appendLog) => { | _ => () } } - WebAPI.Window.addEventListener(window, Custom("message"), cb) - Some(() => WebAPI.Window.removeEventListener(window, Custom("message"), cb)) + Window.addEventListener(window, Custom("message"), cb) + Some(() => Window.removeEventListener(window, Custom("message"), cb)) }, [appendLog])
diff --git a/packages/playground/src/EvalIFrame.res b/packages/playground/src/EvalIFrame.res index 3531edcf1..2437985ff 100644 --- a/packages/playground/src/EvalIFrame.res +++ b/packages/playground/src/EvalIFrame.res @@ -70,20 +70,20 @@ let srcDoc = ` ` let sendOutput = (code, imports) => { - let frame = document->WebAPI.Document.querySelector("#iframe-eval") + let frame = document->Document.querySelector("#iframe-eval") switch frame { | Value(element) => - let element: WebAPI.DOMAPI.htmliFrameElement = element->Obj.magic + let element: DomTypes.htmliFrameElement = element->Obj.magic switch element.contentWindow { - | Value({window}) => + | Value(window) => let message = JSON.Object( dict{ "code": JSON.String(code), "imports": JSON.Object(imports->Dict.mapValues(v => JSON.String(v))), }, ) - window->WebAPI.Window.postMessage(~message, ~targetOrigin="*") + window->Window.postMessage(~message, ~targetOrigin="*") | Null => Console.error("contentWindow not found") } | Null => Console.error("iframe not found") diff --git a/packages/playground/src/Playground.res b/packages/playground/src/Playground.res index 37f210e68..cf69621a5 100644 --- a/packages/playground/src/Playground.res +++ b/packages/playground/src/Playground.res @@ -44,7 +44,7 @@ let dropdownLabelReleased = "--- Released ---" let getLocalStorageItem = key => { try { - WebAPI.Storage.getItem(window.localStorage, key)->Null.toOption + Storage.getItem(localStorage, key)->Null.toOption } catch { | JsExn(_) => None } @@ -52,7 +52,7 @@ let getLocalStorageItem = key => { let setLocalStorageItem = (~key, ~value) => { try { - WebAPI.Storage.setItem(window.localStorage, ~key, ~value) + Storage.setItem(localStorage, ~key, ~value) } catch { | JsExn(_) => () } @@ -60,7 +60,7 @@ let setLocalStorageItem = (~key, ~value) => { let getSessionStorageItem = key => { try { - WebAPI.Storage.getItem(window.sessionStorage, key)->Null.toOption + Storage.getItem(sessionStorage, key)->Null.toOption } catch { | JsExn(_) => None } @@ -68,7 +68,7 @@ let getSessionStorageItem = key => { let setSessionStorageItem = (~key, ~value) => { try { - WebAPI.Storage.setItem(window.sessionStorage, ~key, ~value) + Storage.setItem(sessionStorage, ~key, ~value) } catch { | JsExn(_) => () } @@ -127,8 +127,7 @@ module SelectionOption = { } module ToggleSelection = { - @react.component - let make = ( + let render = ( ~onChange: 'a => unit, ~values: array<'a>, ~toLabel: 'a => string, @@ -445,10 +444,7 @@ module ResultPane = { module WarningFlagsWidget = { // Inspired by MUI (who got inspired by WAI best practise examples) // https://github.com/mui-org/material-ui/blob/next/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js#L327 - let scrollToElement = ( - ~parent: WebAPI.DOMAPI.htmlElement, - element: WebAPI.DOMAPI.htmlElement, - ): unit => + let scrollToElement = (~parent: DomTypes.htmlElement, element: DomTypes.htmlElement): unit => if parent.scrollHeight > parent.clientHeight { let scrollBottom = parent.clientHeight + Float.toInt(parent.scrollTop) let elementBottom = element.offsetTop + element.offsetHeight @@ -608,11 +604,9 @@ module WarningFlagsWidget = { // Used for the text input let inputRef = React.useRef(Nullable.null) - let focusInput = () => - inputRef.current->Nullable.forEach(el => WebAPI.HTMLInputElement.focus(el)) + let focusInput = () => inputRef.current->Nullable.forEach(el => HTMLInputElement.focus(el)) - let blurInput = () => - inputRef.current->Nullable.forEach(el => WebAPI.HTMLInputElement.focus(el)) + let blurInput = () => inputRef.current->Nullable.forEach(el => HTMLInputElement.focus(el)) let chips = Array.mapWithIndex(flags, (token, i) => { let {WarningFlagDescription.Parser.flag: flag, enabled} = token @@ -781,7 +775,7 @@ module WarningFlagsWidget = { switch (parent, el) { | (Some(parent), Some(el)) => - Some(() => scrollToElement(~parent, (Obj.magic(el): WebAPI.DOMAPI.htmlElement))) + Some(() => scrollToElement(~parent, (Obj.magic(el): DomTypes.htmlElement))) | _ => None } })->Some @@ -1083,57 +1077,57 @@ module Settings = { {if availableTargetLangs->Array.length > 1 {
{React.string("Syntax")}
- lang->Api.Lang.toExt->String.toUpperCase} - selected=readyState.targetLang - onChange=onTargetLangSelect - /> + {ToggleSelection.render( + ~values=availableTargetLangs, + ~toLabel=lang => lang->Api.Lang.toExt->String.toUpperCase, + ~selected=readyState.targetLang, + ~onChange=onTargetLangSelect, + )}
} else { React.null }}
{React.string("Use Vim Keymap")}
- + {ToggleSelection.render( + ~values=[CodeMirror.KeyMap.Default, CodeMirror.KeyMap.Vim], + ~toLabel=enabled => switch enabled { | CodeMirror.KeyMap.Vim => "On" | CodeMirror.KeyMap.Default => "Off" - }} - selected=keyMap - onChange={value => setKeyMap(_ => value)} - /> + }, + ~selected=keyMap, + ~onChange=value => setKeyMap(_ => value), + )}
{React.string("Module-System")}
- value} - selected=config.moduleSystem - onChange=onModuleSystemUpdate - /> + {ToggleSelection.render( + ~values=["commonjs", "esmodule"], + ~toLabel=value => value, + ~selected=config.moduleSystem, + ~onChange=onModuleSystemUpdate, + )}
{React.string("Playground Theme")}
- setTheme(_ => value)} - /> + {ToggleSelection.render( + ~values=[CodeMirror.Theme.Dark, CodeMirror.Theme.Light], + ~toLabel=themeLabel, + ~selected=theme, + ~onChange=value => setTheme(_ => value), + )}
{readyState.selected.apiVersion->RescriptCompilerApi.Version.isMinimumVersion(V6) ? <>
{React.string("JSX")}
- Option.getOr(false)->JsxCompilation.fromBool} - onChange=onJsxPreserveModeUpdate - /> + {ToggleSelection.render( + ~values=[JsxCompilation.Plain, PreserveJsx], + ~toLabel=JsxCompilation.getLabel, + ~selected=config.jsxPreserveMode->Option.getOr(false)->JsxCompilation.fromBool, + ~onChange=onJsxPreserveModeUpdate, + )}
{React.string("Experimental Features")}
@@ -1168,7 +1162,8 @@ module Settings = {
{React.string("Warning Flags")} @@ -1235,7 +1230,7 @@ module ControlPanel = { let onClick = evt => { ReactEvent.Mouse.preventDefault(evt) - let ret = copyToClipboard(window.location.href) + let ret = copyToClipboard(location.href) if ret { setState(_ => CopySuccess) } @@ -1258,7 +1253,7 @@ module ControlPanel = { } let commandWithKeyboardShortcut = (commandName, ~key) => { - let userAgent = window.navigator.userAgent + let userAgent = navigator->Navigator.userAgent if userAgent->String.includes("iPhone") || userAgent->String.includes("Android") { commandName } else if userAgent->String.includes("Mac") { @@ -1301,8 +1296,8 @@ module ControlPanel = { } } - WebAPI.Window.addEventListener(window, Keydown, onKeyDown) - Some(() => WebAPI.Window.removeEventListener(window, Keydown, onKeyDown)) + Window.addEventListener(window, Keydown, onKeyDown) + Some(() => Window.removeEventListener(window, Keydown, onKeyDown)) | _ => None } }, (state, dispatch, setCurrentTab)) @@ -1687,11 +1682,11 @@ let make = (~bundleBaseUrl: string, ~versions: array) => { | [v] => Some(v) // only single version available. maybe local dev. | versions => { let lastStableVersion = versions->Array.find(version => version.preRelease->Option.isNone) - switch Nullable.make( - searchParams->WebAPI.URLSearchParams.get((CompilerManagerHook.Version :> string)), - ) { - | Nullable.Value(version) => version->Semver.parse - | _ => + switch searchParams + ->URLSearchParams.get((CompilerManagerHook.Version :> string)) + ->Null.toOption { + | Some(version) => version->Semver.parse + | None => switch getLocalStorageItem(playgroundVersionStorageKey) { | Some(v) => v->Semver.parse | None => lastStableVersion @@ -1700,33 +1695,28 @@ let make = (~bundleBaseUrl: string, ~versions: array) => { } } - let initialLang = switch Nullable.make( - searchParams->WebAPI.URLSearchParams.get((CompilerManagerHook.Ext :> string)), - ) { - | Nullable.Value("re") => Api.Lang.Reason + let initialLang = switch searchParams + ->URLSearchParams.get((CompilerManagerHook.Ext :> string)) + ->Null.toOption { + | Some("re") => Api.Lang.Reason | _ => Api.Lang.Res } - let initialModuleSystem = - Nullable.make(searchParams->WebAPI.URLSearchParams.get((Module :> string)))->Nullable.toOption + let initialModuleSystem = searchParams->URLSearchParams.get((Module :> string))->Null.toOption - let initialJsxPreserveMode = !( - Nullable.make( - searchParams->WebAPI.URLSearchParams.get((JsxPreserve :> string)), - )->Nullable.isNullable - ) + let initialJsxPreserveMode = + searchParams->URLSearchParams.get((JsxPreserve :> string))->Null.toOption->Option.isSome let initialExperimentalFeatures = - Nullable.make( - searchParams->WebAPI.URLSearchParams.get((Experiments :> string)), - )->Nullable.mapOr([], str => str->String.split(",")->Array.map(String.trim)) + searchParams + ->URLSearchParams.get((Experiments :> string)) + ->Null.mapOr([], str => str->String.split(",")->Array.map(String.trim)) let initialContent = switch ( - Nullable.make(searchParams->WebAPI.URLSearchParams.get((Code :> string))), + searchParams->URLSearchParams.get((Code :> string))->Null.toOption, initialLang, ) { - | (Nullable.Value(compressedCode), _) => - LzString.lzString.decompressFromEncodedURIComponent(compressedCode) + | (Some(compressedCode), _) => LzString.lzString.decompressFromEncodedURIComponent(compressedCode) | (_, Reason) => initialReContent | (_, Res) => switch initialVersion { @@ -1942,7 +1932,7 @@ let make = (~bundleBaseUrl: string, ~versions: array) => { let (layout, setLayout) = React.useState(() => Row) React.useEffect(() => { - setLayout(_ => window.innerWidth < breakingPoint ? Column : Row) + setLayout(_ => innerWidth < breakingPoint ? Column : Row) None }, []) @@ -1956,12 +1946,12 @@ let make = (~bundleBaseUrl: string, ~versions: array) => { let subPanelRef = React.useRef(Nullable.null) let onResize = () => { - let newLayout = window.innerWidth < breakingPoint ? Column : Row + let newLayout = innerWidth < breakingPoint ? Column : Row setLayout(_ => newLayout) switch panelRef.current->Nullable.toOption { | Some(element) => - let offsetTop = WebAPI.Element.getBoundingClientRect(element).top - WebAPI.Element.setAttribute( + let offsetTop = Element.getBoundingClientRect(element).top + Element.setAttribute( element, ~qualifiedName="style", ~value=`height: calc(100vh - ${offsetTop->Float.toString}px)`, @@ -1971,8 +1961,8 @@ let make = (~bundleBaseUrl: string, ~versions: array) => { switch subPanelRef.current->Nullable.toOption { | Some(element) => - let offsetTop = WebAPI.Element.getBoundingClientRect(element).top - WebAPI.Element.setAttribute( + let offsetTop = Element.getBoundingClientRect(element).top + Element.setAttribute( element, ~qualifiedName="style", ~value=`height: calc(100vh - ${offsetTop->Float.toString}px)`, @@ -1982,8 +1972,8 @@ let make = (~bundleBaseUrl: string, ~versions: array) => { } React.useEffect(() => { - WebAPI.Window.addEventListener(window, Resize, onResize) - Some(() => WebAPI.Window.removeEventListener(window, Resize, onResize)) + Window.addEventListener(window, Resize, onResize) + Some(() => Window.removeEventListener(window, Resize, onResize)) }, []) // To force CodeMirror render scrollbar on first render @@ -2006,11 +1996,11 @@ let make = (~bundleBaseUrl: string, ~versions: array) => { subPanelRef.current->Nullable.toOption, ) { | (Some(panelElement), Some(leftElement), Some(rightElement), Some(subElement)) => - let rectPanel = WebAPI.Element.getBoundingClientRect(panelElement) + let rectPanel = Element.getBoundingClientRect(panelElement) // Update OutputPanel height - let offsetTop = WebAPI.Element.getBoundingClientRect(subElement).top - WebAPI.Element.setAttribute( + let offsetTop = Element.getBoundingClientRect(subElement).top + Element.setAttribute( subElement, ~qualifiedName="style", ~value=`height: calc(100vh - ${offsetTop->Float.toString}px)`, @@ -2023,12 +2013,12 @@ let make = (~bundleBaseUrl: string, ~versions: array) => { let leftWidth = delta /. rectPanel.width *. 100.0 let rightWidth = (rectPanel.width -. delta) /. rectPanel.width *. 100.0 - WebAPI.Element.setAttribute( + Element.setAttribute( leftElement, ~qualifiedName="style", ~value=`width: ${leftWidth->Float.toString}%`, ) - WebAPI.Element.setAttribute( + Element.setAttribute( rightElement, ~qualifiedName="style", ~value=`width: ${rightWidth->Float.toString}%`, @@ -2040,12 +2030,12 @@ let make = (~bundleBaseUrl: string, ~versions: array) => { let topHeight = delta /. rectPanel.height *. 100. let bottomHeight = (rectPanel.height -. delta) /. rectPanel.height *. 100. - WebAPI.Element.setAttribute( + Element.setAttribute( leftElement, ~qualifiedName="style", ~value=`height: ${topHeight->Float.toString}%`, ) - WebAPI.Element.setAttribute( + Element.setAttribute( rightElement, ~qualifiedName="style", ~value=`height: ${bottomHeight->Float.toString}%`, @@ -2068,15 +2058,15 @@ let make = (~bundleBaseUrl: string, ~versions: array) => { onMove(position) } - WebAPI.Window.addEventListener(window, Mousemove, onMouseMove) - WebAPI.Window.addEventListener(window, Touchmove, onTouchMove) - WebAPI.Window.addEventListener(window, Mouseup, onMouseUp) + Window.addEventListener(window, Mousemove, onMouseMove) + Window.addEventListener(window, Touchmove, onTouchMove) + Window.addEventListener(window, Mouseup, onMouseUp) Some( () => { - WebAPI.Window.removeEventListener(window, Mousemove, onMouseMove) - WebAPI.Window.removeEventListener(window, Touchmove, onTouchMove) - WebAPI.Window.removeEventListener(window, Mouseup, onMouseUp) + Window.removeEventListener(window, Mousemove, onMouseMove) + Window.removeEventListener(window, Touchmove, onTouchMove) + Window.removeEventListener(window, Mouseup, onMouseUp) }, ) }, [layout]) @@ -2085,11 +2075,7 @@ let make = (~bundleBaseUrl: string, ~versions: array) => { let hideNewLightModeToast = () => { setShowNewLightModeToast(_ => false) - WebAPI.Storage.setItem( - window.sessionStorage, - ~key=newLightModeToastSeenStorageKey, - ~value="true", - ) + Storage.setItem(sessionStorage, ~key=newLightModeToastSeenStorageKey, ~value="true") } let tryLightModeFromToast = () => { diff --git a/packages/shared/package.json b/packages/shared/package.json index a74811bef..f18a3053c 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -17,8 +17,8 @@ "@codemirror/view": "^6.41.0", "@lezer/highlight": "^1.2.3", "@replit/codemirror-vim": "^6.3.0", - "@rescript/react": "^0.14.2", - "@rescript/webapi": "0.1.0-experimental-29db5f4", + "@rescript/react": "patch:@rescript/react@npm%3A0.14.2#~/.yarn/patches/@rescript-react-npm-0.14.2-b830f5af4f.patch", + "@rescript/webapi": "patch:@rescript/webapi@npm%3A0.1.0-experimental-0781ac8#~/.yarn/patches/@rescript-webapi-npm-0.1.0-experimental-0781ac8-50def7723d.patch", "@tsnobip/rescript-lezer": "^0.8.0", "highlight.js": "^11.11.1", "react": "^19.2.4", diff --git a/packages/shared/rescript.json b/packages/shared/rescript.json index 40328e643..8dbcba578 100644 --- a/packages/shared/rescript.json +++ b/packages/shared/rescript.json @@ -2,7 +2,7 @@ "name": "@rescript-lang/shared", "namespace": false, "dependencies": ["@rescript/react", "@rescript/webapi"], - "compiler-flags": ["-open WebAPI.Global"], + "compiler-flags": ["-open DomGlobal"], "sources": [ { "dir": "src", diff --git a/packages/shared/src/CodeMirror.res b/packages/shared/src/CodeMirror.res index 15fb80401..c1e3eb615 100644 --- a/packages/shared/src/CodeMirror.res +++ b/packages/shared/src/CodeMirror.res @@ -161,7 +161,7 @@ module CM6 = { module EditorView = { module Tooltip = { module View = { - type t = {dom: WebAPI.DOMAPI.element, offset?: {x: int, y: int}} + type t = {dom: DomTypes.element, offset?: {x: int, y: int}} } type t = { pos: int, @@ -174,13 +174,13 @@ module CM6 = { } } - type createConfig = {state: editorState, parent: WebAPI.DOMAPI.element} + type createConfig = {state: editorState, parent: DomTypes.element} @module("@codemirror/view") @new external create: createConfig => editorView = "EditorView" @send external destroy: editorView => unit = "destroy" @get external state: editorView => editorState = "state" - @get external dom: editorView => WebAPI.DOMAPI.htmlElement = "dom" + @get external dom: editorView => DomTypes.htmlElement = "dom" type change = {from: int, to: int, insert: string} type dispatchArg = {changes: change, selection?: EditorSelection.t} @@ -588,7 +588,7 @@ type editorInstance = { } type editorConfig = { - parent: WebAPI.DOMAPI.element, + parent: DomTypes.element, initialValue: string, mode: string, readOnly: bool, @@ -672,7 +672,7 @@ let createHoverHintExtension = (hoverHints: array) => { | Some({hint, start, end}) => let pos = CM6.Text.line(doc, start.line).from + start.col let end = CM6.Text.line(doc, end.line).from + end.col - let dom = WebAPI.Global.document->WebAPI.Document.createElement("div") + let dom = DomGlobal.document->Document.createElement("div") dom.textContent = Value(hint) dom.className = "p-1 border" Value({ diff --git a/packages/shared/src/CodeMirror.resi b/packages/shared/src/CodeMirror.resi index 6d7a39d24..6764dfb02 100644 --- a/packages/shared/src/CodeMirror.resi +++ b/packages/shared/src/CodeMirror.resi @@ -41,7 +41,7 @@ module HoverHint: { type editorInstance type editorConfig = { - parent: WebAPI.DOMAPI.element, + parent: DomTypes.element, initialValue: string, mode: string, readOnly: bool, diff --git a/packages/shared/src/Node.res b/packages/shared/src/NodeJs.res similarity index 100% rename from packages/shared/src/Node.res rename to packages/shared/src/NodeJs.res diff --git a/packages/shared/src/ReactRouter.res b/packages/shared/src/ReactRouter.res index a6d4ade12..687b32c00 100644 --- a/packages/shared/src/ReactRouter.res +++ b/packages/shared/src/ReactRouter.res @@ -6,7 +6,7 @@ type navigate = (string, ~options: navigateOptions=?) => unit external useNavigate: unit => navigate = "useNavigate" @module("react-router") -external useSearchParams: unit => (WebAPI.URLAPI.urlSearchParams, {..} => unit) = "useSearchParams" +external useSearchParams: unit => (URLSearchParams.t, {..} => unit) = "useSearchParams" @module("react-router") external useLoaderData: unit => 'a = "useLoaderData" @@ -15,7 +15,7 @@ external useLoaderData: unit => 'a = "useLoaderData" type path = {pathname: Path.t, search?: string, hash?: string} module Loader = { - type loaderArgs = {request: WebAPI.FetchAPI.request} + type loaderArgs = {request: Request.t} type t<'a> = loaderArgs => promise<'a> } diff --git a/packages/shared/src/Text.res b/packages/shared/src/TextStyles.res similarity index 74% rename from packages/shared/src/Text.res rename to packages/shared/src/TextStyles.res index 5e05e1557..ff4edaa8e 100644 --- a/packages/shared/src/Text.res +++ b/packages/shared/src/TextStyles.res @@ -1,4 +1,4 @@ -// This file was automatically converted to ReScript from 'Text.re' +// This file was automatically converted to ReScript from 'TextStyles.re' // Check the output and make sure to delete the original file module Link = { let inline = "no-underline border-b border-gray-80 hover:border-bs-purple text-inherit" diff --git a/packages/shared/src/Text.resi b/packages/shared/src/TextStyles.resi similarity index 100% rename from packages/shared/src/Text.resi rename to packages/shared/src/TextStyles.resi diff --git a/yarn.lock b/yarn.lock index 38f8e84ac..e0823df8d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2399,8 +2399,8 @@ __metadata: "@react-router/node": "npm:^7.15.0" "@rescript-lang/playground": "workspace:*" "@rescript-lang/shared": "workspace:*" - "@rescript/react": "npm:^0.14.2" - "@rescript/webapi": "npm:0.1.0-experimental-29db5f4" + "@rescript/react": "patch:@rescript/react@npm%3A0.14.2#~/.yarn/patches/@rescript-react-npm-0.14.2-b830f5af4f.patch" + "@rescript/webapi": "patch:@rescript/webapi@npm%3A0.1.0-experimental-0781ac8#~/.yarn/patches/@rescript-webapi-npm-0.1.0-experimental-0781ac8-50def7723d.patch" "@tailwindcss/vite": "npm:^4.3.0" "@types/react": "npm:^19.2.14" "@vitejs/plugin-react": "npm:^6.0.1" @@ -2435,7 +2435,7 @@ __metadata: remark-frontmatter: "npm:^5.0.0" remark-gfm: "npm:^4.0.1" remark-validate-links: "npm:^13.1.0" - rescript: "npm:^12.2.0" + rescript: "https://pkg.pr.new/rescript@8425" search-insights: "npm:^2.17.3" tailwindcss: "npm:^4" tinyglobby: "npm:^0.2.15" @@ -2464,8 +2464,8 @@ __metadata: "@react-router/node": "npm:^7.15.0" "@rescript-lang/playground": "workspace:*" "@rescript-lang/shared": "workspace:*" - "@rescript/react": "npm:^0.14.2" - "@rescript/webapi": "npm:0.1.0-experimental-29db5f4" + "@rescript/react": "patch:@rescript/react@npm%3A0.14.2#~/.yarn/patches/@rescript-react-npm-0.14.2-b830f5af4f.patch" + "@rescript/webapi": "patch:@rescript/webapi@npm%3A0.1.0-experimental-0781ac8#~/.yarn/patches/@rescript-webapi-npm-0.1.0-experimental-0781ac8-50def7723d.patch" "@vitejs/plugin-react": "npm:^6.0.1" "@vitest/browser-playwright": "npm:^4.1.5" isbot: "npm:^5" @@ -2481,7 +2481,7 @@ __metadata: remark-gfm: "npm:^4.0.1" remark-parse: "npm:^11.0.0" remark-stringify: "npm:^11.0.0" - rescript: "npm:^12.2.0" + rescript: "https://pkg.pr.new/rescript@8425" unified: "npm:^11.0.5" vfile-matter: "npm:^5.0.1" vite: "npm:^8.0.11" @@ -2497,8 +2497,8 @@ __metadata: dependencies: "@babel/parser": "npm:^7.29.2" "@rescript-lang/shared": "workspace:*" - "@rescript/react": "npm:^0.14.2" - "@rescript/webapi": "npm:0.1.0-experimental-29db5f4" + "@rescript/react": "patch:@rescript/react@npm%3A0.14.2#~/.yarn/patches/@rescript-react-npm-0.14.2-b830f5af4f.patch" + "@rescript/webapi": "patch:@rescript/webapi@npm%3A0.1.0-experimental-0781ac8#~/.yarn/patches/@rescript-webapi-npm-0.1.0-experimental-0781ac8-50def7723d.patch" lz-string: "npm:^1.5.0" react: "npm:^19.2.4" react-dom: "npm:^19.2.4" @@ -2523,8 +2523,8 @@ __metadata: "@codemirror/view": "npm:^6.41.0" "@lezer/highlight": "npm:^1.2.3" "@replit/codemirror-vim": "npm:^6.3.0" - "@rescript/react": "npm:^0.14.2" - "@rescript/webapi": "npm:0.1.0-experimental-29db5f4" + "@rescript/react": "patch:@rescript/react@npm%3A0.14.2#~/.yarn/patches/@rescript-react-npm-0.14.2-b830f5af4f.patch" + "@rescript/webapi": "patch:@rescript/webapi@npm%3A0.1.0-experimental-0781ac8#~/.yarn/patches/@rescript-webapi-npm-0.1.0-experimental-0781ac8-50def7723d.patch" "@tsnobip/rescript-lezer": "npm:^0.8.0" highlight.js: "npm:^11.11.1" react: "npm:^19.2.4" @@ -2539,35 +2539,35 @@ __metadata: languageName: unknown linkType: soft -"@rescript/darwin-arm64@npm:12.2.0": - version: 12.2.0 - resolution: "@rescript/darwin-arm64@npm:12.2.0" +"@rescript/darwin-arm64@https://pkg.pr.new/rescript-lang/rescript/@rescript/darwin-arm64@9c999ee": + version: 13.0.0-alpha.6 + resolution: "@rescript/darwin-arm64@https://pkg.pr.new/rescript-lang/rescript/@rescript/darwin-arm64@9c999ee" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rescript/darwin-x64@npm:12.2.0": - version: 12.2.0 - resolution: "@rescript/darwin-x64@npm:12.2.0" +"@rescript/darwin-x64@https://pkg.pr.new/rescript-lang/rescript/@rescript/darwin-x64@9c999ee": + version: 13.0.0-alpha.6 + resolution: "@rescript/darwin-x64@https://pkg.pr.new/rescript-lang/rescript/@rescript/darwin-x64@9c999ee" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rescript/linux-arm64@npm:12.2.0": - version: 12.2.0 - resolution: "@rescript/linux-arm64@npm:12.2.0" +"@rescript/linux-arm64@https://pkg.pr.new/rescript-lang/rescript/@rescript/linux-arm64@9c999ee": + version: 13.0.0-alpha.6 + resolution: "@rescript/linux-arm64@https://pkg.pr.new/rescript-lang/rescript/@rescript/linux-arm64@9c999ee" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@rescript/linux-x64@npm:12.2.0": - version: 12.2.0 - resolution: "@rescript/linux-x64@npm:12.2.0" +"@rescript/linux-x64@https://pkg.pr.new/rescript-lang/rescript/@rescript/linux-x64@9c999ee": + version: 13.0.0-alpha.6 + resolution: "@rescript/linux-x64@https://pkg.pr.new/rescript-lang/rescript/@rescript/linux-x64@9c999ee" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@rescript/react@npm:^0.14.2": +"@rescript/react@npm:0.14.2": version: 0.14.2 resolution: "@rescript/react@npm:0.14.2" peerDependencies: @@ -2577,25 +2577,44 @@ __metadata: languageName: node linkType: hard -"@rescript/runtime@npm:12.2.0": - version: 12.2.0 - resolution: "@rescript/runtime@npm:12.2.0" - checksum: 10c0/59c0194ae52fbbaadc736bbf1cfac1ed6ffde92b2346e36b9f1a29bb136e38b7ef203c780647203912fa657d293eab5c4e208f04dd65ed4bf47d53843980f7e1 +"@rescript/react@patch:@rescript/react@npm%3A0.14.2#~/.yarn/patches/@rescript-react-npm-0.14.2-b830f5af4f.patch": + version: 0.14.2 + resolution: "@rescript/react@patch:@rescript/react@npm%3A0.14.2#~/.yarn/patches/@rescript-react-npm-0.14.2-b830f5af4f.patch::version=0.14.2&hash=c22f9e" + peerDependencies: + react: ">=19.1.0" + react-dom: ">=19.1.0" + checksum: 10c0/dd9247f838b3e6a7040cbb1d366d244ab72f21dd9a49df84c4b00e15a5506bb1d2753ad476c37b1d463f1c0381d40e504ae1129ec794a95bdcc65f8b6589bd04 languageName: node linkType: hard -"@rescript/webapi@npm:0.1.0-experimental-29db5f4": - version: 0.1.0-experimental-29db5f4 - resolution: "@rescript/webapi@npm:0.1.0-experimental-29db5f4" - dependencies: - rescript: "npm:^12.0.0-beta.3" - checksum: 10c0/0ef8538fe59b2c058217dd17a5e653ac4902a87caad3b78bde2efc8099538c33e8c1fc7cef41595fd385a78de2ca172c60bdd36a100839f8983da7a40ebd9560 +"@rescript/runtime@https://pkg.pr.new/rescript-lang/rescript/@rescript/runtime@9c999ee": + version: 13.0.0-alpha.6 + resolution: "@rescript/runtime@https://pkg.pr.new/rescript-lang/rescript/@rescript/runtime@9c999ee" + checksum: 10c0/7da651746d837afe2f14aab6e2e7f34b2489ae06e64738a7204416055e29776cfd2a64429f017e9748b71eb2e9ff2a4982cd2e765b841eca9445448f8551a698 + languageName: node + linkType: hard + +"@rescript/webapi@npm:0.1.0-experimental-0781ac8": + version: 0.1.0-experimental-0781ac8 + resolution: "@rescript/webapi@npm:0.1.0-experimental-0781ac8" + peerDependencies: + rescript: ">=12.0.0 <13" + checksum: 10c0/2e5524b1609b82c70d735ce7b105ecb51ebc9af476c5e765d91ca066d4a12aeb21e1ca76db460955b5b58293fd251552dd7b438a10250d3c9b79f6ee671897cb + languageName: node + linkType: hard + +"@rescript/webapi@patch:@rescript/webapi@npm%3A0.1.0-experimental-0781ac8#~/.yarn/patches/@rescript-webapi-npm-0.1.0-experimental-0781ac8-50def7723d.patch": + version: 0.1.0-experimental-0781ac8 + resolution: "@rescript/webapi@patch:@rescript/webapi@npm%3A0.1.0-experimental-0781ac8#~/.yarn/patches/@rescript-webapi-npm-0.1.0-experimental-0781ac8-50def7723d.patch::version=0.1.0-experimental-0781ac8&hash=fc1254" + peerDependencies: + rescript: ">=12.0.0 <13" + checksum: 10c0/7ac8e28fa93abe601c57ecf699f03f428e5ec295ff98433c72dedce2ecb2e98b7d0f4de47a37a973cae2ec1d9bff855dfcad5d70a2455e8479473d3e34626012 languageName: node linkType: hard -"@rescript/win32-x64@npm:12.2.0": - version: 12.2.0 - resolution: "@rescript/win32-x64@npm:12.2.0" +"@rescript/win32-x64@https://pkg.pr.new/rescript-lang/rescript/@rescript/win32-x64@9c999ee": + version: 13.0.0-alpha.6 + resolution: "@rescript/win32-x64@https://pkg.pr.new/rescript-lang/rescript/@rescript/win32-x64@9c999ee" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -9835,20 +9854,20 @@ __metadata: dependencies: lefthook: "npm:^2.1.4" oxfmt: "npm:^0.46.0" - rescript: "npm:^12.2.0" + rescript: "https://pkg.pr.new/rescript@8425" languageName: unknown linkType: soft -"rescript@npm:^12.0.0-beta.3, rescript@npm:^12.2.0": - version: 12.2.0 - resolution: "rescript@npm:12.2.0" +"rescript@https://pkg.pr.new/rescript@8425": + version: 13.0.0-alpha.6 + resolution: "rescript@https://pkg.pr.new/rescript@8425" dependencies: - "@rescript/darwin-arm64": "npm:12.2.0" - "@rescript/darwin-x64": "npm:12.2.0" - "@rescript/linux-arm64": "npm:12.2.0" - "@rescript/linux-x64": "npm:12.2.0" - "@rescript/runtime": "npm:12.2.0" - "@rescript/win32-x64": "npm:12.2.0" + "@rescript/darwin-arm64": "https://pkg.pr.new/rescript-lang/rescript/@rescript/darwin-arm64@9c999ee" + "@rescript/darwin-x64": "https://pkg.pr.new/rescript-lang/rescript/@rescript/darwin-x64@9c999ee" + "@rescript/linux-arm64": "https://pkg.pr.new/rescript-lang/rescript/@rescript/linux-arm64@9c999ee" + "@rescript/linux-x64": "https://pkg.pr.new/rescript-lang/rescript/@rescript/linux-x64@9c999ee" + "@rescript/runtime": "https://pkg.pr.new/rescript-lang/rescript/@rescript/runtime@9c999ee" + "@rescript/win32-x64": "https://pkg.pr.new/rescript-lang/rescript/@rescript/win32-x64@9c999ee" dependenciesMeta: "@rescript/darwin-arm64": optional: true @@ -9862,11 +9881,9 @@ __metadata: optional: true bin: bsc: cli/bsc.js - bstracing: cli/bstracing.js rescript: cli/rescript.js - rescript-legacy: cli/rescript-legacy.js rescript-tools: cli/rescript-tools.js - checksum: 10c0/7650a77a66e2f2ba2523eac54fd930f0b70bad922e9b498678e701e842a56c7b6facd0daf1ef9c7b71d344d9483a0293d17db72a67515a22d07856bdfc34fb46 + checksum: 10c0/a9edf9affafb476e51d6fdb76138f35e97c5c8e0dcf1c4d4ef8ff8ed7b2104afef5b1fb07139f0903ca8b3c92b62e7a61f948f84cee90bd330c71b33bd31a5d5 languageName: node linkType: hard