diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 5780283..e345771 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -5,25 +5,24 @@ name: Node.js CI on: push: - branches: [ master ] + branches: [master] pull_request: - branches: [ master ] + branches: [master] jobs: build: - runs-on: ubuntu-latest strategy: matrix: - node-version: [16.x] + node-version: [24.x] steps: - - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - - run: npm install - - run: npm run build - - run: npm run test + - uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v6 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm run build + - run: npm run test diff --git a/.gitignore b/.gitignore index 06844f2..6790216 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ src/legacy/*.bs.js # React !/src/react/*.js +# ReScript +lib/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 6817d6e..7fe3f1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,12 @@ > - :house: [Internal] > - :nail_care: [Polish] +## 0.15.0-alpha.1 + +#### :boom: [Breaking Change] + +- Upgrade to ReScript 12.0.0 + ## 0.14.0 #### :nail_care: Polish @@ -149,7 +155,6 @@ No changes compared to rc.3. - Removed the deprecation attribute from apis of the new jsx transform (introduced in React v17). - New version requirements: - - ReScript compiler V10.1+ - ReactJS v18.2.0+ @@ -175,14 +180,12 @@ For history on previous evolution of the code, check out the original [reason-re - **IMPORTANT:** Currently, old third-party packages that are still dependent on `reason-react` will not mix with other `@rescript/react` based code due to a build system problem. Which means that every third-party dependency needs to be upgraded to `@rescript/react` first to make it compatible. See [this forum discussion](https://forum.rescript-lang.org/t/discussion-reason-react-rescript-react-migration-path/1086) for more details. - Removed legacy modules ("record api"): - - `ReasonReactCompat` - `ReactDOMServerRe` - `ReactEventRe` - `ReasonReactOptimizedCreateClass` - Renamed existing modules: - - `ReasonReactErrorBoundary` -> `RescriptReactErrorBoundary` - `ReasonReactRouter` -> `RescriptReactRouter` - (Note: Usually the two only valid styles would be `ReScript` or `rescript`, the latter being the version for technical writing. We are using `Rescript` here, since it is essentially the capitalized version of `rescript`) diff --git a/package-lock.json b/package-lock.json index ce2aa29..64f9003 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,20 +8,108 @@ "name": "@rescript/react", "version": "0.14.0", "license": "MIT", + "dependencies": { + "@rescript/runtime": ">=12.0.0" + }, "devDependencies": { - "react": "^19.1.0", - "react-dom": "^19.1.0", - "rescript": "^11.0.0" + "react": "^19.2.3", + "react-dom": "^19.2.3", + "rescript": "^12.1.0" }, "peerDependencies": { "react": ">=19.0.0", "react-dom": ">=19.0.0" } }, + "node_modules/@rescript/darwin-arm64": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@rescript/darwin-arm64/-/darwin-arm64-12.1.0.tgz", + "integrity": "sha512-OuJMT+2h2Lp60n8ONFx1oBAAePSVkM9zl7E/EX4VD2xkQoVTPklz0BpHYOICnFJSCOOdbOhbsTBXdLpo3yvllg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.11.0" + } + }, + "node_modules/@rescript/darwin-x64": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@rescript/darwin-x64/-/darwin-x64-12.1.0.tgz", + "integrity": "sha512-r5Iv4ga+LaNq+6g9LODwZG4bwydd9UDXACP/HKxOfrP9XQCITlF/XqB1ZDJWyJOgJLZSJCd7erlG38YtB0VZKA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.11.0" + } + }, + "node_modules/@rescript/linux-arm64": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@rescript/linux-arm64/-/linux-arm64-12.1.0.tgz", + "integrity": "sha512-UTZv4GTjbyQ/T5LQDfQiGcumK3SzE1K7+ug6gWpDcGZ7ALc7hCS6BVEFL/LDs8iWVwAwkK/6r456s2zRnvS7wQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.11.0" + } + }, + "node_modules/@rescript/linux-x64": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@rescript/linux-x64/-/linux-x64-12.1.0.tgz", + "integrity": "sha512-c0PXuBL09JRSA4nQusYbR4mW5QJrBPqxDrqvIX+M79fk3d6jQmj5x4NsBwk5BavxvmbR/JU1JjYBlSAa3h22Vg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.11.0" + } + }, + "node_modules/@rescript/runtime": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@rescript/runtime/-/runtime-12.1.0.tgz", + "integrity": "sha512-bvr9RfvBD+JS/6foWCA4l2fLXmUXN0KGqylXQPHt09QxUghqgoCiaWVHaHSx5dOIk/jAPlGQ7zB5yVeMas/EFQ==" + }, + "node_modules/@rescript/win32-x64": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@rescript/win32-x64/-/win32-x64-12.1.0.tgz", + "integrity": "sha512-nQC42QByyAbryfkbyK67iskipUqXVwTPCFrqissY4jJoP0128gg0yG6DydJnV1stXphtFdMFHtmyYE1ffG7UBg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.11.0" + } + }, "node_modules/react": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", - "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", + "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", "dev": true, "license": "MIT", "engines": { @@ -29,67 +117,137 @@ } }, "node_modules/react-dom": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", - "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", "dev": true, "license": "MIT", "dependencies": { - "scheduler": "^0.26.0" + "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.1.0" + "react": "^19.2.3" } }, "node_modules/rescript": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/rescript/-/rescript-11.0.0.tgz", - "integrity": "sha512-uIUwDZZmDUb7ymGkBiiGioxMg8hXh1mze/2k/qhYQcZGgi7PrLHQIW9AksM7gb9WnpjCAvFsA8U2VgC0nA468w==", + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/rescript/-/rescript-12.1.0.tgz", + "integrity": "sha512-n/B43wzIEKV4OmlrWbrlQOL4zZaz0RM/Cc8PG2YvhQvQDW7nscHJliDq1AGeVwHoMX68MeaKKzLDOMOMU9Z6FA==", "dev": true, - "hasInstallScript": true, + "license": "SEE LICENSE IN LICENSE", + "workspaces": [ + "packages/playground", + "packages/@rescript/*", + "tests/dependencies/**", + "tests/analysis_tests/**", + "tests/docstring_tests", + "tests/gentype_tests/**", + "tests/tools_tests", + "scripts/res" + ], + "dependencies": { + "@rescript/runtime": "12.1.0" + }, "bin": { - "bsc": "bsc", - "bstracing": "lib/bstracing", - "rescript": "rescript" + "bsc": "cli/bsc.js", + "bstracing": "cli/bstracing.js", + "rescript": "cli/rescript.js", + "rescript-legacy": "cli/rescript-legacy.js", + "rescript-tools": "cli/rescript-tools.js" }, "engines": { - "node": ">=10" + "node": ">=20.11.0" + }, + "optionalDependencies": { + "@rescript/darwin-arm64": "12.1.0", + "@rescript/darwin-x64": "12.1.0", + "@rescript/linux-arm64": "12.1.0", + "@rescript/linux-x64": "12.1.0", + "@rescript/win32-x64": "12.1.0" } }, "node_modules/scheduler": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "dev": true, "license": "MIT" } }, "dependencies": { + "@rescript/darwin-arm64": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@rescript/darwin-arm64/-/darwin-arm64-12.1.0.tgz", + "integrity": "sha512-OuJMT+2h2Lp60n8ONFx1oBAAePSVkM9zl7E/EX4VD2xkQoVTPklz0BpHYOICnFJSCOOdbOhbsTBXdLpo3yvllg==", + "dev": true, + "optional": true + }, + "@rescript/darwin-x64": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@rescript/darwin-x64/-/darwin-x64-12.1.0.tgz", + "integrity": "sha512-r5Iv4ga+LaNq+6g9LODwZG4bwydd9UDXACP/HKxOfrP9XQCITlF/XqB1ZDJWyJOgJLZSJCd7erlG38YtB0VZKA==", + "dev": true, + "optional": true + }, + "@rescript/linux-arm64": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@rescript/linux-arm64/-/linux-arm64-12.1.0.tgz", + "integrity": "sha512-UTZv4GTjbyQ/T5LQDfQiGcumK3SzE1K7+ug6gWpDcGZ7ALc7hCS6BVEFL/LDs8iWVwAwkK/6r456s2zRnvS7wQ==", + "dev": true, + "optional": true + }, + "@rescript/linux-x64": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@rescript/linux-x64/-/linux-x64-12.1.0.tgz", + "integrity": "sha512-c0PXuBL09JRSA4nQusYbR4mW5QJrBPqxDrqvIX+M79fk3d6jQmj5x4NsBwk5BavxvmbR/JU1JjYBlSAa3h22Vg==", + "dev": true, + "optional": true + }, + "@rescript/runtime": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@rescript/runtime/-/runtime-12.1.0.tgz", + "integrity": "sha512-bvr9RfvBD+JS/6foWCA4l2fLXmUXN0KGqylXQPHt09QxUghqgoCiaWVHaHSx5dOIk/jAPlGQ7zB5yVeMas/EFQ==" + }, + "@rescript/win32-x64": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@rescript/win32-x64/-/win32-x64-12.1.0.tgz", + "integrity": "sha512-nQC42QByyAbryfkbyK67iskipUqXVwTPCFrqissY4jJoP0128gg0yG6DydJnV1stXphtFdMFHtmyYE1ffG7UBg==", + "dev": true, + "optional": true + }, "react": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", - "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", + "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", "dev": true }, "react-dom": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", - "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", "dev": true, "requires": { - "scheduler": "^0.26.0" + "scheduler": "^0.27.0" } }, "rescript": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/rescript/-/rescript-11.0.0.tgz", - "integrity": "sha512-uIUwDZZmDUb7ymGkBiiGioxMg8hXh1mze/2k/qhYQcZGgi7PrLHQIW9AksM7gb9WnpjCAvFsA8U2VgC0nA468w==", - "dev": true + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/rescript/-/rescript-12.1.0.tgz", + "integrity": "sha512-n/B43wzIEKV4OmlrWbrlQOL4zZaz0RM/Cc8PG2YvhQvQDW7nscHJliDq1AGeVwHoMX68MeaKKzLDOMOMU9Z6FA==", + "dev": true, + "requires": { + "@rescript/darwin-arm64": "12.1.0", + "@rescript/darwin-x64": "12.1.0", + "@rescript/linux-arm64": "12.1.0", + "@rescript/linux-x64": "12.1.0", + "@rescript/runtime": "12.1.0", + "@rescript/win32-x64": "12.1.0" + } }, "scheduler": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "dev": true } } diff --git a/package.json b/package.json index 11c8dda..351133d 100644 --- a/package.json +++ b/package.json @@ -28,12 +28,15 @@ }, "homepage": "https://rescript-lang.org/docs/react/latest/introduction", "devDependencies": { - "react": "^19.1.0", - "react-dom": "^19.1.0", - "rescript": "^11.0.0" + "react": "^19.2.3", + "react-dom": "^19.2.3", + "rescript": "^12.1.0" }, "peerDependencies": { "react": ">=19.0.0", "react-dom": ">=19.0.0" + }, + "dependencies": { + "@rescript/runtime": ">=12.0.0" } } diff --git a/rescript.json b/rescript.json index 599e1f6..1069319 100644 --- a/rescript.json +++ b/rescript.json @@ -4,9 +4,7 @@ "version": 4, "mode": "classic" }, - "sources": [{ "dir": "src", "subdirs": true }], - "package-specs": [{ "module": "commonjs", "in-source": true }], - "suffix": ".bs.js", - "bs-dev-dependencies": [], - "bsc-flags": [] + "sources": [{ "dir": "src" }], + "package-specs": [{ "module": "esmodule", "in-source": true }], + "suffix": ".res.js" } diff --git a/src/React.bs.js b/src/React.bs.js deleted file mode 100644 index ef827dd..0000000 --- a/src/React.bs.js +++ /dev/null @@ -1,33 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE -'use strict'; - -var React = require("react"); - -var Children = {}; - -var Context = {}; - -var Fragment = {}; - -var StrictMode = {}; - -var Suspense = {}; - -function lazy_(load) { - return React.lazy(async function () { - return { - default: await load() - }; - }); -} - -var Uncurried = {}; - -exports.Children = Children; -exports.Context = Context; -exports.Fragment = Fragment; -exports.StrictMode = StrictMode; -exports.Suspense = Suspense; -exports.lazy_ = lazy_; -exports.Uncurried = Uncurried; -/* react Not a pure module */ diff --git a/src/React.res b/src/React.res index 0676012..73cdabe 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,8 +82,7 @@ module Context = { external createContext: 'a => Context.t<'a> = "createContext" @module("react") -external forwardRef: (('props, Js.Nullable.t>) => element) => component<'props> = - "forwardRef" +external forwardRef: (('props, Nullable.t>) => element) => component<'props> = "forwardRef" @module("react") external memo: component<'props> => component<'props> = "memo" @@ -257,56 +256,50 @@ 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>, - unit => 'value, - @as(json`[]`) _, -) => unit = "useImperativeHandle" +external useImperativeHandle0: (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>, - unit => 'value, - ('a, 'b, 'c, 'd), -) => unit = "useImperativeHandle" +external useImperativeHandle4: (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/React.res.js b/src/React.res.js new file mode 100644 index 0000000..1d52802 --- /dev/null +++ b/src/React.res.js @@ -0,0 +1,32 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as React from "react"; + +let Children = {}; + +let Context = {}; + +let Fragment = {}; + +let StrictMode = {}; + +let Suspense = {}; + +function lazy_(load) { + return React.lazy(async () => ({ + default: await load() + })); +} + +let Uncurried = {}; + +export { + Children, + Context, + Fragment, + StrictMode, + Suspense, + lazy_, + Uncurried, +} +/* react Not a pure module */ diff --git a/src/ReactDOM.bs.js b/src/ReactDOM.bs.js deleted file mode 100644 index fa51640..0000000 --- a/src/ReactDOM.bs.js +++ /dev/null @@ -1,58 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE -'use strict'; - -var Caml_option = require("rescript/lib/js/caml_option.js"); - -var Root = {}; - -var Client = { - Root: Root -}; - -function getString(formData, name) { - var value = formData.get(name); - if (!(value == null) && typeof value === "string") { - return Caml_option.some(value); - } - -} - -function getFile(formData, name) { - var value = formData.get(name); - if (!(value == null) && typeof value !== "string") { - return Caml_option.some(value); - } - -} - -function getAll(t, string) { - return t.getAll(string).map(function (value) { - if (typeof value === "string") { - return { - TAG: "String", - _0: value - }; - } else { - return { - TAG: "File", - _0: value - }; - } - }); -} - -var $$FormData = { - getString: getString, - getFile: getFile, - getAll: getAll -}; - -var Ref = {}; - -var Style; - -exports.Client = Client; -exports.$$FormData = $$FormData; -exports.Ref = Ref; -exports.Style = Style; -/* No side effect */ diff --git a/src/ReactDOM.res b/src/ReactDOM.res index fbd564b..7e094ef 100644 --- a/src/ReactDOM.res +++ b/src/ReactDOM.res @@ -43,7 +43,7 @@ module FormData = { let getString = (formData, name) => { switch formData->getUnsafe(name) { - | Some(value) => Js.typeof(value) === "string" ? Some(value) : None + | Some(value) => typeof(value) === #string ? Some(value) : None | _ => None } } @@ -52,7 +52,7 @@ module FormData = { let getFile = (formData, name) => { switch formData->getUnsafe(name) { - | Some(value) => Js.typeof(value) === "string" ? None : Some(value->_asFile) + | Some(value) => typeof(value) === #string ? None : Some(value->_asFile) | _ => None } } @@ -60,8 +60,8 @@ module FormData = { let getAll = (t, string) => { t ->getAllUnsafe(string) - ->Js.Array2.map(value => { - Js.typeof(value) === "string" ? String(value) : File(value->_asFile) + ->Array.map(value => { + typeof(value) === #string ? String(value) : File(value->_asFile) }) } @@ -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 => option unit> external domRef: currentDomRef => domRef = "%identity" external callbackDomRef: callbackDomRef => domRef = "%identity" diff --git a/src/ReactDOM.res.js b/src/ReactDOM.res.js new file mode 100644 index 0000000..766ec05 --- /dev/null +++ b/src/ReactDOM.res.js @@ -0,0 +1,57 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; + +let Root = {}; + +let Client = { + Root: Root +}; + +function getString(formData, name) { + let value = formData.get(name); + if (!(value == null) && typeof value === "string") { + return Primitive_option.some(value); + } +} + +function getFile(formData, name) { + let value = formData.get(name); + if (!(value == null) && typeof value !== "string") { + return Primitive_option.some(value); + } +} + +function getAll(t, string) { + return t.getAll(string).map(value => { + if (typeof value === "string") { + return { + TAG: "String", + _0: value + }; + } else { + return { + TAG: "File", + _0: value + }; + } + }); +} + +let FormData = { + getString: getString, + getFile: getFile, + getAll: getAll +}; + +let Ref = {}; + +let Style; + +export { + Client, + FormData, + Ref, + Style, +} +/* No side effect */ diff --git a/src/ReactDOMServer.bs.js b/src/ReactDOMServer.res.js similarity index 100% rename from src/ReactDOMServer.bs.js rename to src/ReactDOMServer.res.js diff --git a/src/ReactDOMStatic.bs.js b/src/ReactDOMStatic.res.js similarity index 100% rename from src/ReactDOMStatic.bs.js rename to src/ReactDOMStatic.res.js diff --git a/src/ReactDOMStyle.res b/src/ReactDOMStyle.res index ae68d03..545ebbf 100644 --- a/src/ReactDOMStyle.res +++ b/src/ReactDOMStyle.res @@ -4,11 +4,11 @@ type t = JsxDOMStyle.t @val external combine: (@as(json`{}`) _, t, t) => t = "Object.assign" -external _dictToStyle: Js.Dict.t => t = "%identity" +external _dictToStyle: dict => t = "%identity" let unsafeAddProp = (style, key, value) => { - let dict = Js.Dict.empty() - Js.Dict.set(dict, key, value) + let dict = Dict.make() + Dict.set(dict, key, value) combine(style, _dictToStyle(dict)) } diff --git a/src/ReactDOMStyle.bs.js b/src/ReactDOMStyle.res.js similarity index 72% rename from src/ReactDOMStyle.bs.js rename to src/ReactDOMStyle.res.js index 18702c8..f7f5e14 100644 --- a/src/ReactDOMStyle.bs.js +++ b/src/ReactDOMStyle.res.js @@ -1,12 +1,13 @@ // Generated by ReScript, PLEASE EDIT WITH CARE -'use strict'; function unsafeAddProp(style, key, value) { - var dict = {}; + let dict = {}; dict[key] = value; return Object.assign({}, style, dict); } -exports.unsafeAddProp = unsafeAddProp; +export { + unsafeAddProp, +} /* No side effect */ diff --git a/src/ReactEvent.bs.js b/src/ReactEvent.bs.js deleted file mode 100644 index 179cde2..0000000 --- a/src/ReactEvent.bs.js +++ /dev/null @@ -1,53 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE -'use strict'; - - -var Synthetic = {}; - -var Clipboard = {}; - -var Composition = {}; - -var Keyboard = {}; - -var Focus = {}; - -var Form = {}; - -var Mouse = {}; - -var Pointer = {}; - -var $$Selection = {}; - -var $$Touch = {}; - -var UI = {}; - -var Wheel = {}; - -var Media = {}; - -var $$Image = {}; - -var $$Animation = {}; - -var Transition = {}; - -exports.Synthetic = Synthetic; -exports.Clipboard = Clipboard; -exports.Composition = Composition; -exports.Keyboard = Keyboard; -exports.Focus = Focus; -exports.Form = Form; -exports.Mouse = Mouse; -exports.Pointer = Pointer; -exports.$$Selection = $$Selection; -exports.$$Touch = $$Touch; -exports.UI = UI; -exports.Wheel = Wheel; -exports.Media = Media; -exports.$$Image = $$Image; -exports.$$Animation = $$Animation; -exports.Transition = Transition; -/* No side effect */ diff --git a/src/ReactEvent.res b/src/ReactEvent.res index 2d927a1..54ac591 100644 --- a/src/ReactEvent.res +++ b/src/ReactEvent.res @@ -59,27 +59,21 @@ external toSyntheticEvent: synthetic<'a> => Synthetic.t = "%identity" module Clipboard = { type tag = JsxEvent.Clipboard.tag type t = synthetic - include MakeEventWithType({ - type t = t - }) + include MakeEventWithType({type t = t}) @get external clipboardData: t => {..} = "clipboardData" /* Should return Dom.dataTransfer */ } module Composition = { type tag = JsxEvent.Composition.tag type t = synthetic - include MakeEventWithType({ - type t = t - }) + include MakeEventWithType({type t = t}) @get external data: t => string = "data" } module Keyboard = { type tag = JsxEvent.Keyboard.tag type t = synthetic - include MakeEventWithType({ - type t = t - }) + include MakeEventWithType({type t = t}) @get external altKey: t => bool = "altKey" @get external charCode: t => int = "charCode" @get external code: t => string = "code" @@ -99,9 +93,7 @@ module Keyboard = { module Focus = { type tag = JsxEvent.Focus.tag type t = synthetic - include MakeEventWithType({ - type t = t - }) + include MakeEventWithType({type t = t}) @get @return(nullable) external relatedTarget: t => option<{..}> = "relatedTarget" /* Should return Dom.eventTarget */ } @@ -109,17 +101,13 @@ module Focus = { module Form = { type tag = JsxEvent.Form.tag type t = synthetic - include MakeEventWithType({ - type t = t - }) + include MakeEventWithType({type t = t}) } module Mouse = { type tag = JsxEvent.Mouse.tag type t = synthetic - include MakeEventWithType({ - type t = t - }) + include MakeEventWithType({type t = t}) @get external altKey: t => bool = "altKey" @get external button: t => int = "button" @get external buttons: t => int = "buttons" @@ -143,9 +131,7 @@ module Mouse = { module Pointer = { type tag = JsxEvent.Pointer.tag type t = synthetic - include MakeEventWithType({ - type t = t - }) + include MakeEventWithType({type t = t}) // UIEvent @get external detail: t => int = "detail" @@ -190,17 +176,13 @@ module Pointer = { module Selection = { type tag = JsxEvent.Selection.tag type t = synthetic - include MakeEventWithType({ - type t = t - }) + include MakeEventWithType({type t = t}) } module Touch = { type tag = JsxEvent.Touch.tag type t = synthetic - include MakeEventWithType({ - type t = t - }) + include MakeEventWithType({type t = t}) @get external altKey: t => bool = "altKey" @get external changedTouches: t => {..} = "changedTouches" /* Should return Dom.touchList */ @get external ctrlKey: t => bool = "ctrlKey" @@ -215,9 +197,7 @@ module Touch = { module UI = { type tag = JsxEvent.UI.tag type t = synthetic - include MakeEventWithType({ - type t = t - }) + include MakeEventWithType({type t = t}) @get external detail: t => int = "detail" @get external view: t => Dom.window = "view" /* Should return DOMAbstractView/WindowProxy */ } @@ -225,9 +205,7 @@ module UI = { module Wheel = { type tag = JsxEvent.Wheel.tag type t = synthetic - include MakeEventWithType({ - type t = t - }) + include MakeEventWithType({type t = t}) @get external deltaMode: t => int = "deltaMode" @get external deltaX: t => float = "deltaX" @get external deltaY: t => float = "deltaY" @@ -237,25 +215,19 @@ module Wheel = { module Media = { type tag = JsxEvent.Media.tag type t = synthetic - include MakeEventWithType({ - type t = t - }) + include MakeEventWithType({type t = t}) } module Image = { type tag = JsxEvent.Image.tag type t = synthetic - include MakeEventWithType({ - type t = t - }) + include MakeEventWithType({type t = t}) } module Animation = { type tag = JsxEvent.Animation.tag type t = synthetic - include MakeEventWithType({ - type t = t - }) + include MakeEventWithType({type t = t}) @get external animationName: t => string = "animationName" @get external pseudoElement: t => string = "pseudoElement" @get external elapsedTime: t => float = "elapsedTime" @@ -264,9 +236,7 @@ module Animation = { module Transition = { type tag = JsxEvent.Transition.tag type t = synthetic - include MakeEventWithType({ - type t = t - }) + include MakeEventWithType({type t = t}) @get external propertyName: t => string = "propertyName" @get external pseudoElement: t => string = "pseudoElement" @get external elapsedTime: t => float = "elapsedTime" diff --git a/src/ReactEvent.res.js b/src/ReactEvent.res.js new file mode 100644 index 0000000..5303ddd --- /dev/null +++ b/src/ReactEvent.res.js @@ -0,0 +1,54 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +let Synthetic = {}; + +let Clipboard = {}; + +let Composition = {}; + +let Keyboard = {}; + +let Focus = {}; + +let Form = {}; + +let Mouse = {}; + +let Pointer = {}; + +let Selection = {}; + +let Touch = {}; + +let UI = {}; + +let Wheel = {}; + +let Media = {}; + +let Image = {}; + +let Animation = {}; + +let Transition = {}; + +export { + Synthetic, + Clipboard, + Composition, + Keyboard, + Focus, + Form, + Mouse, + Pointer, + Selection, + Touch, + UI, + Wheel, + Media, + Image, + Animation, + Transition, +} +/* No side effect */ diff --git a/src/ReactTestUtils.bs.js b/src/ReactTestUtils.bs.js deleted file mode 100644 index 7ddadac..0000000 --- a/src/ReactTestUtils.bs.js +++ /dev/null @@ -1,105 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE -'use strict'; - -var Caml_option = require("rescript/lib/js/caml_option.js"); -var TestUtils = require("react-dom/test-utils"); - -function act(func) { - var reactFunc = function () { - func(); - }; - TestUtils.act(reactFunc); -} - -function actAsync(func) { - return TestUtils.act(function () { - return func(); - }); -} - -function changeWithValue(element, value) { - var $$event = { - target: { - value: value - } - }; - TestUtils.Simulate.change(element, $$event); -} - -function changeWithChecked(element, value) { - var $$event = { - target: { - checked: value - } - }; - TestUtils.Simulate.change(element, $$event); -} - -var Simulate = { - changeWithValue: changeWithValue, - changeWithChecked: changeWithChecked -}; - -function findBySelector(element, selector) { - return element.querySelector(selector); -} - -function findByAllSelector(element, selector) { - return Array.from(element.querySelectorAll(selector)); -} - -function findBySelectorAndTextContent(element, selector, content) { - return Caml_option.undefined_to_opt(Array.from(element.querySelectorAll(selector)).find(function (node) { - return node.textContent === content; - })); -} - -function findBySelectorAndPartialTextContent(element, selector, content) { - return Caml_option.undefined_to_opt(Array.from(element.querySelectorAll(selector)).find(function (node) { - return node.textContent.includes(content); - })); -} - -var DOM = { - findBySelector: findBySelector, - findByAllSelector: findByAllSelector, - findBySelectorAndTextContent: findBySelectorAndTextContent, - findBySelectorAndPartialTextContent: findBySelectorAndPartialTextContent -}; - -function prepareContainer(container, param) { - var containerElement = document.createElement("div"); - var body = document.body; - if (body !== undefined) { - Caml_option.valFromOption(body).appendChild(containerElement); - } - container.contents = Caml_option.some(containerElement); -} - -function cleanupContainer(container, param) { - var contents = container.contents; - if (contents !== undefined) { - Caml_option.valFromOption(contents).remove(); - } - container.contents = undefined; -} - -function getContainer(container) { - var contents = container.contents; - if (contents !== undefined) { - return Caml_option.valFromOption(contents); - } - throw { - RE_EXN_ID: "Not_found", - Error: new Error() - }; -} - -exports.act = act; -exports.actAsync = actAsync; -exports.Simulate = Simulate; -exports.DOM = DOM; -exports.prepareContainer = prepareContainer; -exports.cleanupContainer = cleanupContainer; -exports.getContainer = getContainer; -/* react-dom/test-utils Not a pure module */ diff --git a/src/ReactTestUtils.res b/src/ReactTestUtils.res index a6c2b5e..3b92614 100644 --- a/src/ReactTestUtils.res +++ b/src/ReactTestUtils.res @@ -1,6 +1,6 @@ -type undefined = Js.undefined +type undefined = nullable -let undefined: undefined = Js.Undefined.empty +let undefined: undefined = Nullable.undefined @module("react-dom/test-utils") external reactAct: (unit => undefined) => unit = "act" @@ -14,7 +14,7 @@ let act: (unit => unit) => unit = func => { } @module("react-dom/test-utils") -external reactActAsync: (unit => Js.Promise.t<'a>) => Js.Promise.t = "act" +external reactActAsync: (unit => promise<'a>) => promise = "act" let actAsync = func => { let reactFunc = () => func() @@ -80,7 +80,7 @@ module Simulate = { external querySelector: (Dom.element, string) => option = "querySelector" @send -external querySelectorAll: (Dom.element, string) => Js.Array.array_like = +external querySelectorAll: (Dom.element, string) => Array.arrayLike = "querySelectorAll" @get external textContent: Dom.element => string = "textContent" @@ -91,7 +91,7 @@ external createElement: (Dom.document, string) => Dom.element = "createElement" @send external appendChild: (Dom.element, Dom.element) => Dom.element = "appendChild" -let querySelectorAll = (element, string) => Js.Array.from(querySelectorAll(element, string)) +let querySelectorAll = (element, string) => Array.fromArrayLike(querySelectorAll(element, string)) module DOM = { @return(nullable) @get @@ -102,11 +102,11 @@ module DOM = { let findByAllSelector = (element, selector) => querySelectorAll(element, selector) let findBySelectorAndTextContent = (element, selector, content) => - querySelectorAll(element, selector)->Js.Array2.find(node => node->textContent === content) + querySelectorAll(element, selector)->Array.find(node => node->textContent === content) let findBySelectorAndPartialTextContent = (element, selector, content) => - querySelectorAll(element, selector)->Js.Array2.find(node => - node->textContent->Js.String2.includes(content) + querySelectorAll(element, selector)->Array.find(node => + node->textContent->String.includes(content) ) } @@ -130,5 +130,5 @@ let cleanupContainer = (container: ref>, ()) => { let getContainer = container => switch container.contents { | Some(contents) => contents - | None => raise(Not_found) + | None => throw(Not_found) } diff --git a/src/ReactTestUtils.res.js b/src/ReactTestUtils.res.js new file mode 100644 index 0000000..2166cce --- /dev/null +++ b/src/ReactTestUtils.res.js @@ -0,0 +1,100 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; +import * as TestUtils from "react-dom/test-utils"; + +function act(func) { + let reactFunc = () => { + func(); + }; + TestUtils.act(reactFunc); +} + +function actAsync(func) { + return TestUtils.act(() => func()); +} + +function changeWithValue(element, value) { + let event = { + target: { + value: value + } + }; + TestUtils.Simulate.change(element, event); +} + +function changeWithChecked(element, value) { + let event = { + target: { + checked: value + } + }; + TestUtils.Simulate.change(element, event); +} + +let Simulate = { + changeWithValue: changeWithValue, + changeWithChecked: changeWithChecked +}; + +function findBySelector(element, selector) { + return element.querySelector(selector); +} + +function findByAllSelector(element, selector) { + return Array.from(element.querySelectorAll(selector)); +} + +function findBySelectorAndTextContent(element, selector, content) { + return Array.from(element.querySelectorAll(selector)).find(node => node.textContent === content); +} + +function findBySelectorAndPartialTextContent(element, selector, content) { + return Array.from(element.querySelectorAll(selector)).find(node => node.textContent.includes(content)); +} + +let DOM = { + findBySelector: findBySelector, + findByAllSelector: findByAllSelector, + findBySelectorAndTextContent: findBySelectorAndTextContent, + findBySelectorAndPartialTextContent: findBySelectorAndPartialTextContent +}; + +function prepareContainer(container, param) { + let containerElement = document.createElement("div"); + let body = document.body; + if (body !== undefined) { + Primitive_option.valFromOption(body).appendChild(containerElement); + } + container.contents = Primitive_option.some(containerElement); +} + +function cleanupContainer(container, param) { + let contents = container.contents; + if (contents !== undefined) { + Primitive_option.valFromOption(contents).remove(); + } + container.contents = undefined; +} + +function getContainer(container) { + let contents = container.contents; + if (contents !== undefined) { + return Primitive_option.valFromOption(contents); + } + throw { + RE_EXN_ID: "Not_found", + Error: new Error() + }; +} + +export { + act, + actAsync, + Simulate, + DOM, + prepareContainer, + cleanupContainer, + getContainer, +} +/* react-dom/test-utils Not a pure module */ diff --git a/src/ReactTestUtils.resi b/src/ReactTestUtils.resi index 79afd69..f87e6d1 100644 --- a/src/ReactTestUtils.resi +++ b/src/ReactTestUtils.resi @@ -1,6 +1,6 @@ let act: (unit => unit) => unit -let actAsync: (unit => Js.Promise.t<'a>) => Js.Promise.t +let actAsync: (unit => promise<'a>) => promise @module("react-dom/test-utils") external isElement: 'element => bool = "isElement" diff --git a/src/RescriptReactErrorBoundary.bs.js b/src/RescriptReactErrorBoundary.res.js similarity index 80% rename from src/RescriptReactErrorBoundary.bs.js rename to src/RescriptReactErrorBoundary.res.js index fe5f73e..a491d09 100644 --- a/src/RescriptReactErrorBoundary.bs.js +++ b/src/RescriptReactErrorBoundary.res.js @@ -1,11 +1,10 @@ // Generated by ReScript, PLEASE EDIT WITH CARE -'use strict'; -var React = require("react"); +import * as React from "react"; -var noOp = (function (_x) {}); +let noOp = (function (_x) {}); -var reactComponentClass = React.Component; +let reactComponentClass = React.Component; noOp(reactComponentClass); @@ -27,7 +26,9 @@ var ErrorBoundary = (function (Component) { })(reactComponentClass); ; -var make = ErrorBoundary; +let make = ErrorBoundary; -exports.make = make; +export { + make, +} /* reactComponentClass Not a pure module */ diff --git a/src/RescriptReactRouter.bs.js b/src/RescriptReactRouter.bs.js deleted file mode 100644 index eb542b6..0000000 --- a/src/RescriptReactRouter.bs.js +++ /dev/null @@ -1,219 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE -'use strict'; - -var React = require("react"); -var Caml_option = require("rescript/lib/js/caml_option.js"); - -function safeMakeEvent(eventName) { - if (typeof Event === "function") { - return new Event(eventName); - } - var $$event = document.createEvent("Event"); - $$event.initEvent(eventName, true, true); - return $$event; -} - -function pathParse(str) { - switch (str) { - case "" : - case "/" : - return /* [] */0; - default: - var raw = str.slice(1); - var match = raw[raw.length - 1 | 0]; - var raw$1 = match === "/" ? raw.slice(0, -1) : raw; - var match$1 = raw$1.split("?", 2); - var raw$2 = match$1.length !== 2 ? raw$1 : match$1[0]; - var a = raw$2.split("/").filter(function (item) { - return item.length !== 0; - }); - var _i = a.length - 1 | 0; - var _res = /* [] */0; - while(true) { - var res = _res; - var i = _i; - if (i < 0) { - return res; - } - _res = { - hd: a[i], - tl: res - }; - _i = i - 1 | 0; - continue ; - }; - } -} - -function path(serverUrlString, param) { - var match = globalThis.window; - if (serverUrlString !== undefined) { - return pathParse(serverUrlString); - } else if (match !== undefined) { - return pathParse(Caml_option.valFromOption(match).location.pathname); - } else { - return /* [] */0; - } -} - -function hash() { - var $$window = globalThis.window; - if ($$window === undefined) { - return ""; - } - var raw = Caml_option.valFromOption($$window).location.hash; - switch (raw) { - case "" : - case "#" : - return ""; - default: - return raw.slice(1); - } -} - -function searchParse(str) { - switch (str) { - case "" : - case "?" : - return ""; - default: - var match = str.split("?", 2); - if (match.length !== 2) { - return ""; - } else { - return match[1]; - } - } -} - -function search(serverUrlString, param) { - var match = globalThis.window; - if (serverUrlString !== undefined) { - return searchParse(serverUrlString); - } else if (match !== undefined) { - return searchParse(Caml_option.valFromOption(match).location.search); - } else { - return ""; - } -} - -function push(path) { - var match = globalThis.history; - var match$1 = globalThis.window; - if (match !== undefined && match$1 !== undefined) { - Caml_option.valFromOption(match).pushState(null, "", path); - Caml_option.valFromOption(match$1).dispatchEvent(safeMakeEvent("popstate")); - return ; - } - -} - -function replace(path) { - var match = globalThis.history; - var match$1 = globalThis.window; - if (match !== undefined && match$1 !== undefined) { - Caml_option.valFromOption(match).replaceState(null, "", path); - Caml_option.valFromOption(match$1).dispatchEvent(safeMakeEvent("popstate")); - return ; - } - -} - -function urlNotEqual(a, b) { - if (a.hash !== b.hash || a.search !== b.search) { - return true; - } else { - var _aList = a.path; - var _bList = b.path; - while(true) { - var bList = _bList; - var aList = _aList; - if (!aList) { - if (bList) { - return true; - } else { - return false; - } - } - if (!bList) { - return true; - } - if (aList.hd !== bList.hd) { - return true; - } - _bList = bList.tl; - _aList = aList.tl; - continue ; - }; - } -} - -function url(serverUrlString, param) { - return { - path: path(serverUrlString, undefined), - hash: hash(), - search: search(serverUrlString, undefined) - }; -} - -function watchUrl(callback) { - var $$window = globalThis.window; - if ($$window === undefined) { - return function () { - - }; - } - var watcherID = function () { - callback(url(undefined, undefined)); - }; - Caml_option.valFromOption($$window).addEventListener("popstate", watcherID); - return watcherID; -} - -function unwatchUrl(watcherID) { - var $$window = globalThis.window; - if ($$window !== undefined) { - Caml_option.valFromOption($$window).removeEventListener("popstate", watcherID); - return ; - } - -} - -function useUrl(serverUrl, param) { - var match = React.useState(function () { - if (serverUrl !== undefined) { - return serverUrl; - } else { - return url(undefined, undefined); - } - }); - var setUrl = match[1]; - var url$1 = match[0]; - React.useEffect((function () { - var watcherId = watchUrl(function (url) { - setUrl(function (param) { - return url; - }); - }); - var newUrl = url(undefined, undefined); - if (urlNotEqual(newUrl, url$1)) { - setUrl(function (param) { - return newUrl; - }); - } - return (function () { - unwatchUrl(watcherId); - }); - }), []); - return url$1; -} - -var dangerouslyGetInitialUrl = url; - -exports.push = push; -exports.replace = replace; -exports.watchUrl = watchUrl; -exports.unwatchUrl = unwatchUrl; -exports.dangerouslyGetInitialUrl = dangerouslyGetInitialUrl; -exports.useUrl = useUrl; -/* react Not a pure module */ diff --git a/src/RescriptReactRouter.res b/src/RescriptReactRouter.res index 80f3d75..838eb84 100644 --- a/src/RescriptReactRouter.res +++ b/src/RescriptReactRouter.res @@ -40,7 +40,7 @@ external createEventNonIEBrowsers: string => Dom.event = "createEvent" external initEventNonIEBrowsers: (Dom.event, string, bool, bool) => unit = "initEvent" let safeMakeEvent = eventName => - if Js.typeof(event) == "function" { + if typeof(event) == #function { makeEventIE11Compatible(eventName) } else { let event = createEventNonIEBrowsers("Event") @@ -55,9 +55,9 @@ let arrayToList = a => { if i < 0 { res } else { - tolist(i - 1, list{a->Js.Array2.unsafe_get(i), ...res}) + tolist(i - 1, list{a->Array.getUnsafe(i), ...res}) } - tolist(a->Js.Array2.length - 1, list{}) + tolist(a->Array.length - 1, list{}) } /* if we ever roll our own parser in the future, make sure you test all url combinations e.g. foo.com/?#bar @@ -72,19 +72,19 @@ let pathParse = str => list{} | raw => /* remove the preceeding /, which every pathname seems to have */ - let raw = raw->Js.String2.sliceToEnd(~from=1) + let raw = raw->String.slice(~start=1) /* remove the trailing /, which some pathnames might have. Ugh */ - let raw = switch raw->Js.String2.get(raw->Js.String2.length - 1) { - | "/" => raw->Js.String2.slice(~from=0, ~to_=-1) + let raw = switch raw->String.getUnsafe(raw->String.length - 1) { + | "/" => raw->String.slice(~start=0, ~end=-1) | _ => raw } /* remove search portion if present in string */ - let raw = switch raw->Js.String2.splitAtMost("?", ~limit=2) { + let raw = switch raw->String.splitAtMost("?", ~limit=2) { | [path, _] => path | _ => raw } - raw->Js.String2.split("/")->Js.Array2.filter(item => item->Js.String2.length != 0)->arrayToList + raw->String.split("/")->Array.filter(item => item->String.length != 0)->arrayToList } let path = (~serverUrlString=?, ()) => switch (serverUrlString, window) { @@ -102,7 +102,7 @@ let hash = () => | raw => /* remove the preceeding #, which every hash seems to have. Why is this even included in location.hash?? */ - raw->Js.String2.sliceToEnd(~from=1) + raw->String.slice(~start=1) } } let searchParse = str => @@ -110,7 +110,7 @@ let searchParse = str => | "" | "?" => "" | raw => - switch raw->Js.String2.splitAtMost("?", ~limit=2) { + switch raw->String.splitAtMost("?", ~limit=2) { | [_, search] => search | _ => "" } diff --git a/src/RescriptReactRouter.res.js b/src/RescriptReactRouter.res.js new file mode 100644 index 0000000..3bee765 --- /dev/null +++ b/src/RescriptReactRouter.res.js @@ -0,0 +1,199 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as React from "react"; +import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; + +function safeMakeEvent(eventName) { + if (typeof Event === "function") { + return new Event(eventName); + } + let event = document.createEvent("Event"); + event.initEvent(eventName, true, true); + return event; +} + +function pathParse(str) { + switch (str) { + case "" : + case "/" : + return /* [] */0; + default: + let raw = str.slice(1); + let match = raw[raw.length - 1 | 0]; + let raw$1 = match === "/" ? raw.slice(0, -1) : raw; + let match$1 = raw$1.split("?", 2); + let raw$2 = match$1.length !== 2 ? raw$1 : match$1[0]; + let a = raw$2.split("/").filter(item => item.length !== 0); + let _i = a.length - 1 | 0; + let _res = /* [] */0; + while (true) { + let res = _res; + let i = _i; + if (i < 0) { + return res; + } + _res = { + hd: a[i], + tl: res + }; + _i = i - 1 | 0; + continue; + }; + } +} + +function path(serverUrlString, param) { + let match = globalThis.window; + if (serverUrlString !== undefined) { + return pathParse(serverUrlString); + } else if (match !== undefined) { + return pathParse(Primitive_option.valFromOption(match).location.pathname); + } else { + return /* [] */0; + } +} + +function hash() { + let window = globalThis.window; + if (window === undefined) { + return ""; + } + let raw = Primitive_option.valFromOption(window).location.hash; + switch (raw) { + case "" : + case "#" : + return ""; + default: + return raw.slice(1); + } +} + +function searchParse(str) { + switch (str) { + case "" : + case "?" : + return ""; + default: + let match = str.split("?", 2); + if (match.length !== 2) { + return ""; + } else { + return match[1]; + } + } +} + +function search(serverUrlString, param) { + let match = globalThis.window; + if (serverUrlString !== undefined) { + return searchParse(serverUrlString); + } else if (match !== undefined) { + return searchParse(Primitive_option.valFromOption(match).location.search); + } else { + return ""; + } +} + +function push(path) { + let match = globalThis.history; + let match$1 = globalThis.window; + if (match !== undefined && match$1 !== undefined) { + Primitive_option.valFromOption(match).pushState(null, "", path); + Primitive_option.valFromOption(match$1).dispatchEvent(safeMakeEvent("popstate")); + return; + } +} + +function replace(path) { + let match = globalThis.history; + let match$1 = globalThis.window; + if (match !== undefined && match$1 !== undefined) { + Primitive_option.valFromOption(match).replaceState(null, "", path); + Primitive_option.valFromOption(match$1).dispatchEvent(safeMakeEvent("popstate")); + return; + } +} + +function urlNotEqual(a, b) { + if (a.hash !== b.hash || a.search !== b.search) { + return true; + } else { + let _aList = a.path; + let _bList = b.path; + while (true) { + let bList = _bList; + let aList = _aList; + if (aList === 0) { + return bList !== 0; + } + if (bList === 0) { + return true; + } + if (aList.hd !== bList.hd) { + return true; + } + _bList = bList.tl; + _aList = aList.tl; + continue; + }; + } +} + +function url(serverUrlString, param) { + return { + path: path(serverUrlString, undefined), + hash: hash(), + search: search(serverUrlString, undefined) + }; +} + +function watchUrl(callback) { + let window = globalThis.window; + if (window === undefined) { + return () => {}; + } + let watcherID = () => callback(url(undefined, undefined)); + Primitive_option.valFromOption(window).addEventListener("popstate", watcherID); + return watcherID; +} + +function unwatchUrl(watcherID) { + let window = globalThis.window; + if (window !== undefined) { + Primitive_option.valFromOption(window).removeEventListener("popstate", watcherID); + return; + } +} + +function useUrl(serverUrl, param) { + let match = React.useState(() => { + if (serverUrl !== undefined) { + return serverUrl; + } else { + return url(undefined, undefined); + } + }); + let setUrl = match[1]; + let url$1 = match[0]; + React.useEffect(() => { + let watcherId = watchUrl(url => setUrl(param => url)); + let newUrl = url(undefined, undefined); + if (urlNotEqual(newUrl, url$1)) { + setUrl(param => newUrl); + } + return () => unwatchUrl(watcherId); + }, []); + return url$1; +} + +let dangerouslyGetInitialUrl = url; + +export { + push, + replace, + watchUrl, + unwatchUrl, + dangerouslyGetInitialUrl, + useUrl, +} +/* react Not a pure module */