diff --git a/.gitignore b/.gitignore index 2536625df..bcfdd8381 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,11 @@ node_modules/ /configs/.config/fish/config.fish /configs/.config/fish/fish_variables /blog/public/ + +# ReasonML +.merlin +.bsb.lock +npm-debug.log +/nut-score/lib/bs/ +/nut-score/node_modules/ +/nut-score/bundleOutput/ \ No newline at end of file diff --git a/nut-score/README.md b/nut-score/README.md new file mode 100644 index 000000000..585967b8b --- /dev/null +++ b/nut-score/README.md @@ -0,0 +1,35 @@ +# Nut Score + +I cloned most of this start boilerplate from +github.com/BuckleScript/bucklescript by running the following: + +```shell +$ cd ~/programming +$ git clone git@github.com:BuckleScript/bucklescript +$ cp -R ./jscomp/bab/templates/react-hooks ~/briefcase/nut-score +``` + +## Installing + +```shell +$ nix-shell +$ yarn install +``` + +## Developing + +In one shell run: + +```shell +$ nix-shell +$ yarn server +``` + +In another shell run: + +```shell +$ nix-shell +$ yarn start +``` + +Now open a web browser and visit `localhost:8000`. diff --git a/nut-score/UNUSED_webpack.config.js b/nut-score/UNUSED_webpack.config.js new file mode 100644 index 000000000..3260e8f64 --- /dev/null +++ b/nut-score/UNUSED_webpack.config.js @@ -0,0 +1,14 @@ +const path = require('path'); + +module.exports = { + entry: './src/Index.bs.js', + // If you ever want to use webpack during development, change 'production' + // to 'development' as per webpack documentation. Again, you don't have to + // use webpack or any other bundler during development! Recheck README if + // you didn't know this + mode: 'production', + output: { + path: path.join(__dirname, "bundleOutput"), + filename: 'index.js', + }, +}; \ No newline at end of file diff --git a/nut-score/bsconfig.json b/nut-score/bsconfig.json new file mode 100644 index 000000000..72bbb4459 --- /dev/null +++ b/nut-score/bsconfig.json @@ -0,0 +1,21 @@ +{ + "name": "reason-react-examples", + "reason": { + "react-jsx": 3 + }, + "sources": { + "dir" : "src", + "subdirs" : true + }, + "bsc-flags": ["-bs-super-errors", "-bs-no-version-header"], + "package-specs": [{ + "module": "commonjs", + "in-source": true + }], + "suffix": ".bs.js", + "namespace": true, + "bs-dependencies": [ + "reason-react" + ], + "refmt": 3 +} diff --git a/nut-score/index.html b/nut-score/index.html new file mode 100644 index 000000000..5f1ac3926 --- /dev/null +++ b/nut-score/index.html @@ -0,0 +1,22 @@ + + + + + ReasonReact Examples + + + +
+ + + + + + diff --git a/nut-score/indexProduction.html b/nut-score/indexProduction.html new file mode 100644 index 000000000..1597bfa6c --- /dev/null +++ b/nut-score/indexProduction.html @@ -0,0 +1,10 @@ + + + + + ReasonReact Examples + + + + + diff --git a/nut-score/package.json b/nut-score/package.json new file mode 100644 index 000000000..1d982b2b2 --- /dev/null +++ b/nut-score/package.json @@ -0,0 +1,27 @@ +{ + "name": "nut-score", + "version": "1.0.0", + "scripts": { + "build": "bsb -make-world", + "start": "bsb -make-world -w -ws _ ", + "clean": "bsb -clean-world", + "server": "moduleserve ./ --port 8000", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [ + "BuckleScript", + "ReasonReact", + "reason-react" + ], + "author": "", + "license": "MIT", + "dependencies": { + "react": "^16.8.1", + "react-dom": "^16.8.1", + "reason-react": ">=0.7.0" + }, + "devDependencies": { + "bs-platform": "^${bsb:bs-version}", + "moduleserve": "^0.9.0" + } +} diff --git a/nut-score/shell.nix b/nut-score/shell.nix new file mode 100644 index 000000000..501fc07c8 --- /dev/null +++ b/nut-score/shell.nix @@ -0,0 +1,8 @@ +let + pkgs = import {}; +in pkgs.mkShell { + name = "nut-score"; + buildInputs = with pkgs; [ + yarn + ]; +} diff --git a/nut-score/src/Index.bs.js b/nut-score/src/Index.bs.js new file mode 100644 index 000000000..18775b27e --- /dev/null +++ b/nut-score/src/Index.bs.js @@ -0,0 +1,9 @@ +'use strict'; + +var React = require("react"); +var ReactDOMRe = require("reason-react/src/ReactDOMRe.js"); +var ReducerFromReactJSDocs$ReasonReactExamples = require("./ReducerFromReactJSDocs/ReducerFromReactJSDocs.bs.js"); + +ReactDOMRe.renderToElementWithId(React.createElement(ReducerFromReactJSDocs$ReasonReactExamples.make, { }), "mount"); + +/* Not a pure module */ diff --git a/nut-score/src/Index.re b/nut-score/src/Index.re new file mode 100644 index 000000000..fcbd4beef --- /dev/null +++ b/nut-score/src/Index.re @@ -0,0 +1 @@ +ReactDOMRe.renderToElementWithId(, "mount"); diff --git a/nut-score/src/ReducerFromReactJSDocs/ReducerFromReactJSDocs.bs.js b/nut-score/src/ReducerFromReactJSDocs/ReducerFromReactJSDocs.bs.js new file mode 100644 index 000000000..74322f4a8 --- /dev/null +++ b/nut-score/src/ReducerFromReactJSDocs/ReducerFromReactJSDocs.bs.js @@ -0,0 +1,35 @@ +'use strict'; + +var Curry = require("bs-platform/lib/js/curry.js"); +var React = require("react"); + +var initialState = /* record */[/* count */0]; + +function reducer(state, action) { + if (action) { + return /* record */[/* count */state[/* count */0] - 1 | 0]; + } else { + return /* record */[/* count */state[/* count */0] + 1 | 0]; + } +} + +function ReducerFromReactJSDocs(Props) { + var match = React.useReducer(reducer, initialState); + var dispatch = match[1]; + return React.createElement("div", undefined, React.createElement("div", undefined, "Count: ", String(match[0][/* count */0])), React.createElement("div", undefined, React.createElement("button", { + onClick: (function (_event) { + return Curry._1(dispatch, /* Decrement */1); + }) + }, "-"), React.createElement("button", { + onClick: (function (_event) { + return Curry._1(dispatch, /* Increment */0); + }) + }, "+"))); +} + +var make = ReducerFromReactJSDocs; + +exports.initialState = initialState; +exports.reducer = reducer; +exports.make = make; +/* react Not a pure module */ diff --git a/nut-score/src/ReducerFromReactJSDocs/ReducerFromReactJSDocs.re b/nut-score/src/ReducerFromReactJSDocs/ReducerFromReactJSDocs.re new file mode 100644 index 000000000..ddc5f0994 --- /dev/null +++ b/nut-score/src/ReducerFromReactJSDocs/ReducerFromReactJSDocs.re @@ -0,0 +1,39 @@ +// This is the ReactJS documentation's useReducer example, directly ported over +// https://reactjs.org/docs/hooks-reference.html#usereducer + +// Record and variant need explicit declarations. +type state = {count: int}; + +type action = + | Increment + | Decrement; + +let initialState = {count: 0}; + +let reducer = (state, action) => { + switch (action) { + | Increment => {count: state.count + 1} + | Decrement => {count: state.count - 1} + }; +}; + +[@react.component] +let make = () => { + let (state, dispatch) = React.useReducer(reducer, initialState); + + // We can use a fragment here, but we don't, because we want to style the counter +
+
+ {React.string("Count: ")} + {React.string(string_of_int(state.count))} +
+
+ + +
+
; +}; diff --git a/nut-score/watcher.js b/nut-score/watcher.js new file mode 100644 index 000000000..26fcd46c4 --- /dev/null +++ b/nut-score/watcher.js @@ -0,0 +1,39 @@ +// This is our simple, robust watcher. It hooks into the BuckleScript build +// system to listen for build events. +// See package.json's `start` script and `./node_modules/.bin/bsb --help` + +// Btw, if you change this file and reload the page, your browser cache +// _might_ not pick up the new version. If you're in Chrome, do Force Reload. + +var websocketReloader; +var LAST_SUCCESS_BUILD_STAMP = localStorage.getItem('LAST_SUCCESS_BUILD_STAMP') || 0; +// package.json's `start` script's `bsb -ws _` means it'll pipe build events +// through a websocket connection to a default port of 9999. This is +// configurable, e.g. `-ws 5000` +var webSocketPort = 9999; + +function setUpWebSocket() { + if (websocketReloader == null || websocketReloader.readyState !== 1) { + try { + websocketReloader = new WebSocket(`ws://${window.location.hostname}:${webSocketPort}`); + websocketReloader.onmessage = (message) => { + var newData = JSON.parse(message.data).LAST_SUCCESS_BUILD_STAMP; + if (newData > LAST_SUCCESS_BUILD_STAMP) { + LAST_SUCCESS_BUILD_STAMP = newData; + localStorage.setItem('LAST_SUCCESS_BUILD_STAMP', LAST_SUCCESS_BUILD_STAMP); + // Refresh the page! This will naturally re-run everything, + // including our moduleserve which will re-resolve all the modules. + // No stable build! + location.reload(true); + } + + } + } catch (exn) { + console.error("The watcher tried to connect to web socket, but failed. Here's the message:"); + console.error(exn); + } + } +}; + +setUpWebSocket(); +setInterval(setUpWebSocket, 2000); diff --git a/nut-score/yarn.lock b/nut-score/yarn.lock new file mode 100644 index 000000000..3f2b2fa10 --- /dev/null +++ b/nut-score/yarn.lock @@ -0,0 +1,216 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"bs-platform@^${bsb:bs-version}": + version "6.2.1" + resolved "https://registry.yarnpkg.com/bs-platform/-/bs-platform-6.2.1.tgz#30266c7f23a3b323e1fc9596a9a6eb9f053981b4" + integrity sha512-FmQ8kYV52A0Y302qh6o0/J9TO+kHzsjGQnsjrg/ONUYIY/jWzBnt9dCBO6EBnaEKfFJLqk5JrUDCxuihqtTcnw== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +inherits@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +moduleserve@^0.9.0: + version "0.9.1" + resolved "https://registry.yarnpkg.com/moduleserve/-/moduleserve-0.9.1.tgz#11bad4337ea248d7eaf10d2c7f8649a8c3b9c1f8" + integrity sha512-WF2BeGnM2Ko7bdICgJO+Ibu+ZD33ExJHzOzTDsCUzfZnvnFfheEIYBTWyIqSRU0tXh4UTQ1krDOCglFTJPBMow== + dependencies: + send "^0.17.1" + serve-static "^1.14.1" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +prop-types@^15.6.2: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +react-dom@>=16.8.1, react-dom@^16.8.1: + version "16.13.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.0.tgz#cdde54b48eb9e8a0ca1b3dc9943d9bb409b81866" + integrity sha512-y09d2c4cG220DzdlFkPTnVvGTszVvNpC73v+AaLGLHbkpy3SSgvYq8x0rNwPJ/Rk/CicTNgk0hbHNw1gMEZAXg== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.19.0" + +react-is@^16.8.1: + version "16.13.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.0.tgz#0f37c3613c34fe6b37cd7f763a0d6293ab15c527" + integrity sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA== + +react@>=16.8.1, react@^16.8.1: + version "16.13.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.13.0.tgz#d046eabcdf64e457bbeed1e792e235e1b9934cf7" + integrity sha512-TSavZz2iSLkq5/oiE7gnFzmURKZMltmi193rm5HEoUDAXpzT9Kzw6oNZnGoai/4+fUnm7FqS5dwgUL34TujcWQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + +reason-react@>=0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/reason-react/-/reason-react-0.7.0.tgz#46a975c321e81cd51310d7b1a02418ca7667b0d6" + integrity sha512-czR/f0lY5iyLCki9gwftOFF5Zs40l7ZSFmpGK/Z6hx2jBVeFDmIiXB8bAQW/cO6IvtuEt97OmsYueiuOYG9XjQ== + dependencies: + react ">=16.8.1" + react-dom ">=16.8.1" + +scheduler@^0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.0.tgz#a715d56302de403df742f4a9be11975b32f5698d" + integrity sha512-xowbVaTPe9r7y7RUejcK73/j8tt2jfiyTednOvHbA8JoClvMYCp+r8QegLwK/n8zWQAtZb1fFnER4XLBZXrCxA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +send@0.17.1, send@^0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serve-static@^1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +"statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==