├── cabal.config ├── files ├── powershell ├── .xcconfig ├── .watchmanconfig ├── .babelrc ├── android │ ├── androidsdk │ │ └── libexec │ │ │ └── licenses │ │ │ ├── android-sdk-license │ │ │ ├── google-gdk-license │ │ │ ├── android-googletv-license │ │ │ ├── android-sdk-preview-license │ │ │ ├── intel-android-extra-license │ │ │ └── mips-android-sysimage-license │ └── app │ │ └── my-release-key.keystore ├── index.js ├── index.macos.js ├── index.web.js ├── register.js ├── require_app.web.js ├── require_app.macos.js ├── require_app.js ├── babel.config.js ├── webpack.config.js ├── register_rn.windows.js ├── package.json ├── rn-cli.config.js ├── register_rn.js └── ghcjsiClient.js ├── .gitignore ├── Setup.hs ├── README.rst ├── hseverywhere.png ├── nixpkgs.config ├── nix-revision.txt ├── quickstart.sh ├── cleanbuild.sh ├── shell.sh ├── package-all.sh ├── devtools.sh ├── repl.sh ├── run-all.sh ├── run-web.sh ├── addons.txt ├── init-WinRM.bat ├── run-windows.vbs ├── src ├── NodeMain.hs ├── Main.hs ├── Store.hs └── Views.hs ├── nix-shell-init.sh ├── index.html ├── package-windows.bat ├── run-ios.sh ├── package-web.sh ├── package-android.sh ├── init-addons.sh ├── start-packagers.sh ├── package-macos.sh ├── cc.sh ├── register_addons.macos.js ├── register_addons.android.js ├── register_addons.ios.js ├── register_addons.web.js ├── register_addons.windows.js ├── hseverywhere.cabal ├── run-android.sh ├── LICENSE ├── init-windows.bat ├── Vagrantfile ├── run-macos.sh ├── run-windows.bat ├── stack.yaml ├── default.nix ├── init.sh └── remove-symlinks.sh /cabal.config: -------------------------------------------------------------------------------- 1 | compiler: ghcjs 2 | -------------------------------------------------------------------------------- /files/powershell: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | pash $@ 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | release 3 | rnproject 4 | .vagrant 5 | -------------------------------------------------------------------------------- /Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Moved to https://codeberg.org/jyri-matti/hseverywhere 2 | -------------------------------------------------------------------------------- /files/.xcconfig: -------------------------------------------------------------------------------- 1 | LD = /usr/bin/clang 2 | LDPLUSPLUS = /usr/bin/clang++ 3 | -------------------------------------------------------------------------------- /files/.watchmanconfig: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_dirs": ["android", "ios", "macos", "windows"] 3 | } -------------------------------------------------------------------------------- /hseverywhere.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jyrimatti/hseverywhere/HEAD/hseverywhere.png -------------------------------------------------------------------------------- /nixpkgs.config: -------------------------------------------------------------------------------- 1 | { 2 | android_sdk.accept_license = true; 3 | allowUnfree = true; 4 | } 5 | -------------------------------------------------------------------------------- /files/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react-native"], 3 | "ignore": [ 4 | "all.js" 5 | ] 6 | } -------------------------------------------------------------------------------- /files/android/androidsdk/libexec/licenses/android-sdk-license: -------------------------------------------------------------------------------- 1 | 2 | 24333f8a63b6825ea9c5514f83c2829b004d1fee -------------------------------------------------------------------------------- /files/android/androidsdk/libexec/licenses/google-gdk-license: -------------------------------------------------------------------------------- 1 | 2 | 33b6a2b64607f11b759f320ef9dff4ae5c47d97a -------------------------------------------------------------------------------- /files/android/androidsdk/libexec/licenses/android-googletv-license: -------------------------------------------------------------------------------- 1 | 2 | 601085b94cd77f0b54ff86406957099ebe79c4d6 -------------------------------------------------------------------------------- /nix-revision.txt: -------------------------------------------------------------------------------- 1 | https://github.com/NixOS/nixpkgs/archive/c40f2114992f7387013a6113ebfd99ae63ec4f91.tar.gz 2 | -------------------------------------------------------------------------------- /files/android/androidsdk/libexec/licenses/android-sdk-preview-license: -------------------------------------------------------------------------------- 1 | 2 | 84831b9409646a918e30573bab4c9c91346d8abd -------------------------------------------------------------------------------- /files/android/androidsdk/libexec/licenses/intel-android-extra-license: -------------------------------------------------------------------------------- 1 | 2 | d975f751698a77b662f1254ddbeed3901e976f5a -------------------------------------------------------------------------------- /files/android/androidsdk/libexec/licenses/mips-android-sysimage-license: -------------------------------------------------------------------------------- 1 | 2 | e9acab5b5fbb560a72cfaecce8946896ff6aab9d -------------------------------------------------------------------------------- /files/android/app/my-release-key.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jyrimatti/hseverywhere/HEAD/files/android/app/my-release-key.keystore -------------------------------------------------------------------------------- /files/index.js: -------------------------------------------------------------------------------- 1 | var { Runmain } = require('./require_app'); 2 | for(var exported in Runmain) { 3 | window[exported] = Runmain[exported]; 4 | } 5 | -------------------------------------------------------------------------------- /files/index.macos.js: -------------------------------------------------------------------------------- 1 | var { Runmain } = require('./require_app.macos'); 2 | for(var exported in Runmain) { 3 | window[exported] = Runmain[exported]; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /quickstart.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | set -eu 3 | 4 | ./init.sh 5 | #./init-windows.bat 6 | ./package-all.sh 7 | ./build.sh 8 | ./start-packagers.sh & 9 | ./run-all.sh 10 | -------------------------------------------------------------------------------- /cleanbuild.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell --pure -i bash -p nix bash cacert 3 | set -eu 4 | source ./nix-shell-init.sh 5 | 6 | nix-shell --run "cabal clean" 7 | ./build.sh 8 | -------------------------------------------------------------------------------- /shell.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell -i bash -p nix bash 3 | 4 | set -eu 5 | source ./nix-shell-init.sh 6 | 7 | #nix-shell --argstr compiler default "$@" 8 | nix-shell "$@" 9 | -------------------------------------------------------------------------------- /package-all.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell -i bash -p bash 3 | set -eu 4 | 5 | ./cleanbuild.sh 6 | 7 | ./package-web.sh 8 | ./package-android.sh 9 | ./package-macos.sh 10 | -------------------------------------------------------------------------------- /devtools.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell --pure -i bash -p nix 3 | set -eu 4 | source ./nix-shell-init.sh 5 | 6 | nix-shell -p nodejs --run "rnproject/node_modules/.bin/react-devtools" 7 | -------------------------------------------------------------------------------- /repl.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell --pure -i bash -p nix bash 3 | set -eu 4 | source ./nix-shell-init.sh 5 | 6 | port=${1:-8080} 7 | 8 | nix-shell --run "GHCJSI_PORT=$port cabal repl" 9 | 10 | -------------------------------------------------------------------------------- /run-all.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell -i bash -p bash 3 | set -eux 4 | 5 | ./build.sh 6 | 7 | cp -fR files/. rnproject/ 8 | 9 | ./run-ios.sh 10 | ./run-web.sh 11 | ./run-macos.sh 12 | ./run-android.sh -------------------------------------------------------------------------------- /run-web.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell -i bash -p nix bash 3 | set -eu 4 | source ./nix-shell-init.sh 5 | 6 | port=${1:-8083} 7 | 8 | nix-shell -p xdg_utils --run "xdg-open http://localhost:$port/" 9 | 10 | -------------------------------------------------------------------------------- /addons.txt: -------------------------------------------------------------------------------- 1 | react-native-vector-icons@4.6.0 2 | #react-native-i18n@2.0.12 3 | react-native-animatable@1.3.0 4 | gl-react@3.15.0 5 | gl-react-native@3.15.0 6 | gl-react-dom@3.15.0 7 | #react-native-webgl@0.8.0 8 | react-native-maps@0.24.0 9 | -------------------------------------------------------------------------------- /init-WinRM.bat: -------------------------------------------------------------------------------- 1 | powershell "Set-NetConnectionProfile -NetworkCategory Private" 2 | winrm qc 3 | winrm set winrm/config/client/auth @{Basic="true"} 4 | winrm set winrm/config/service/auth @{Basic="true"} 5 | winrm set winrm/config/service @{AllowUnencrypted="true"} 6 | -------------------------------------------------------------------------------- /run-windows.vbs: -------------------------------------------------------------------------------- 1 | Set objShell = WScript.CreateObject("WScript.Shell") 2 | 3 | objShell.SendKeys "^{ESC}" 4 | 5 | WScript.Sleep 1000 6 | 7 | objShell.SendKeys WScript.Arguments.Item(0) 8 | 9 | WScript.Sleep 1000 10 | 11 | objShell.SendKeys "{ENTER}" 12 | -------------------------------------------------------------------------------- /src/NodeMain.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE NoImplicitPrelude #-} 2 | import Data.Text.IO (putStrLn) 3 | import React.Flux (reactRenderToString) 4 | import Views (app) 5 | import Prelude (Boolean(True), (>>=), IO) 6 | 7 | main :: IO () 8 | main = reactRenderToString True app () >>= T.putStrLn 9 | -------------------------------------------------------------------------------- /nix-shell-init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # copy-pasted from /.nix-profile/etc/profile.d/nix.sh to make SSL work: 4 | NIX_LINK="$HOME/.nix-profile" 5 | 6 | # always use a specific nixpkgs revision 7 | export NIX_PATH=nixpkgs=$(cat nix-revision.txt) 8 | 9 | export NIXPKGS_CONFIG=$PWD/nixpkgs.config 10 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Haskell Everywhere! 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /files/index.web.js: -------------------------------------------------------------------------------- 1 | var { Runmain } = require('./require_app.web'); 2 | for(var exported in Runmain) { 3 | window[exported] = Runmain[exported]; 4 | } 5 | 6 | setTimeout(function() { 7 | var { AppRegistry } = require('react-native'); 8 | AppRegistry.runApplication('actual-app', { rootTag: document.getElementById('react-root') }) 9 | }, 2000); 10 | -------------------------------------------------------------------------------- /files/register.js: -------------------------------------------------------------------------------- 1 | 2 | var doRegister = function(name,c,AppRegistry) { 3 | AppRegistry.registerComponent("actual-app", function() { return c; }); 4 | AppRegistry.registerRunnable(name, function(appParameters) { 5 | return AppRegistry.runApplication("actual-app", appParameters); 6 | }); 7 | }; 8 | 9 | module.exports = { 10 | doRegister: doRegister 11 | }; 12 | 13 | -------------------------------------------------------------------------------- /src/Main.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE NoImplicitPrelude #-} 2 | import Prelude (IO) 3 | import React.Flux (registerInitialStore) 4 | import React.Flux.Rn.App (registerApp) 5 | import Store (appStore) 6 | import Views (app) 7 | 8 | main :: IO () 9 | main = do 10 | registerInitialStore appStore 11 | registerApp "rnproject" app 12 | -------------------------------------------------------------------------------- /src/Store.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveAnyClass #-} 2 | {-# LANGUAGE NoImplicitPrelude #-} 3 | module Store where 4 | 5 | import Data.Typeable (Typeable) 6 | import Prelude (Show, Eq, pure) 7 | import React.Flux (StoreData(..)) 8 | 9 | data AppState = AppState { 10 | } deriving (Show, Typeable, Eq) 11 | 12 | instance StoreData AppState where 13 | transform action = pure 14 | 15 | appStore = AppState -------------------------------------------------------------------------------- /package-windows.bat: -------------------------------------------------------------------------------- 1 | :: 2>/dev/null || echo ' 2 | ::::::::::::::::::::::::::: Windows 3 | 4 | cd c:\vagrant 5 | "c:\Progra~2\MSBuild\14.0\Bin\MSBuild.exe" %1\windows\%1.sln /t:Publish 6 | 7 | exit /b %ERRORLEVEL% 8 | ' >/dev/null 9 | ########################### Others 10 | #! /bin/sh 11 | set -eu 12 | 13 | nix-shell -I channel:nixos-18.09 -p vagrant --run "command -v vagrant >/dev/null || (echo Please install VirtualBox for Windows development && false)" 14 | nix-shell -I channel:nixos-18.09 -p netcat --run "nc -z -w1 127.0.0.1 55985 || (echo 'Could not connect WinRM' && false)" 15 | nix-shell -I channel:nixos-18.09 -p vagrant --run "vagrant provision windows --provision-with package" 16 | -------------------------------------------------------------------------------- /run-ios.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell -i bash -p nix bash 3 | set -eu 4 | source ./nix-shell-init.sh 5 | 6 | ### Note! Note pure, requires xcode! ### 7 | 8 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" 9 | 10 | port=${1:-8081} 11 | 12 | nix-shell --pure --run "sed -i \"s/8081/$port/g\" rnproject/ios/rnproject/AppDelegate.m" 13 | 14 | # inject .xcconfig to ios build to force xcodebuild use clang as linker 15 | sed -i "s~var xcodebuildArgs = \[~var xcodebuildArgs = \['-xcconfig', '$DIR/rnproject/.xcconfig',~g" rnproject/node_modules/react-native/local-cli/runIOS/runIOS.js 16 | 17 | nix-shell -p nodejs-10_x --run "(cd rnproject && PATH=/usr/bin:\$PATH ./node_modules/.bin/react-native run-ios --no-packager)" 18 | -------------------------------------------------------------------------------- /package-web.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell --pure -i bash -p nix bash cacert 3 | set -eu 4 | source ./nix-shell-init.sh 5 | 6 | app=$(basename *.cabal .cabal) 7 | 8 | ./build.sh 9 | 10 | cp -fR files/. rnproject/ 11 | 12 | nix-shell -p nodejs-10_x --run "cd rnproject && npm run pack" 13 | 14 | test -d release || mkdir release 15 | test -f release/$app.html && rm release/$app.html 16 | echo "$app
" >> release/$app.html 21 | 22 | echo "Generated release/$app.html" 23 | -------------------------------------------------------------------------------- /package-android.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell --pure -i bash -p nix bash cacert 3 | set -eu 4 | source ./nix-shell-init.sh 5 | 6 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" 7 | app=$(basename *.cabal .cabal) 8 | 9 | ./build.sh 10 | 11 | cp -fR files/. rnproject/ 12 | 13 | ./remove-symlinks.sh 14 | 15 | nix-shell -p nodejs-10_x jre8 watchman --run "cd rnproject/android; ANDROID_HOME=$DIR/rnproject/android/androidsdk/libexec ANDROID_NDK=$DIR/rnproject/android/androidsdk/libexec/android-sdk/ndk-bundle ./gradlew --no-daemon assembleRelease --stacktrace" 16 | 17 | test -d release || mkdir release 18 | test -f release/$app.apk && rm release/$app.apk 19 | cp rnproject/android/app/build/outputs/apk/release/app-release.apk release/$app.apk 20 | echo "Generated release/$app.apk" 21 | -------------------------------------------------------------------------------- /files/require_app.web.js: -------------------------------------------------------------------------------- 1 | 2 | window.React = require('react'); 3 | window.createReactClass = require('create-react-class'); 4 | 5 | window.__registerComponent = function(name,c) { 6 | var { doRegister } = require('./register'); 7 | var { AppRegistry } = require('react-native'); 8 | doRegister(name,c,AppRegistry); 9 | }; 10 | 11 | if (!window.navigator) { 12 | window.navigator = {}; 13 | window.navigator.userAgent = 'react-native'; 14 | } 15 | 16 | var { registerRnComponents } = require('./register_rn'); 17 | var { registerAddons } = require('./register_addons.web'); 18 | var __rn = require('react-native'); 19 | 20 | module.exports = { 21 | RegRn: registerRnComponents(__rn), 22 | RegAddons: registerAddons(__rn.Platform.OS), 23 | Runmain: require('./all'), 24 | Repl: require('./ghcjsiClient') 25 | }; 26 | 27 | -------------------------------------------------------------------------------- /init-addons.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell --pure -i bash -p nix bash 3 | set -eux 4 | source ./nix-shell-init.sh 5 | 6 | buildToolsVersion=$(nix-store --query --references $(nix-instantiate '' -A androidsdk_9_0) | grep 'build-tools' | sed 's/.*build-tools-\([^.]*\).*.drv/\1/') 7 | 8 | cp -fR files/. rnproject/ 9 | cp register_addons*.js rnproject/ 10 | 11 | nix-shell -p nodejs-10_x --run "cd rnproject && cat ../addons.txt | grep -v '^#' | sed 's/@.*//' | xargs -L1 node_modules/.bin/react-native link || echo Link returned failure for some reason..." 12 | 13 | # change addon android buildTools version to that available from nixpkgs 14 | (cat addons.txt | grep -v '^#' | sed 's/@.*//' | xargs -I {} sed -i "s/buildToolsVersion [\"'][^\"']*[\"']/buildToolsVersion \"$buildToolsVersion\"/g" rnproject/node_modules/{}/android/build.gradle) || echo returned error... 15 | 16 | echo "init-addons done" 17 | -------------------------------------------------------------------------------- /start-packagers.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell -i bash -p bash 3 | set -eu 4 | source ./nix-shell-init.sh 5 | 6 | editor=${REACT_EDITOR:-xdg-open} 7 | 8 | mobileport=${1:-8081} 9 | macosport=${2:-8082} 10 | webport=${3:-8083} 11 | 12 | cp -fR files/. rnproject/ 13 | cd rnproject 14 | 15 | echo "Ensure you have enough file descriptors if you get 'Too many open files': https://facebook.github.io/watchman/docs/install.html" 16 | 17 | nix-shell -p nodejs-10_x xdg_utils watchman --run "REACT_EDITOR='$editor' PORT=$webport npm run start-web | sed 's/^/[Web ] /' || echo '[Web ] Died!'" & 18 | nix-shell -p nodejs-10_x xdg_utils watchman --run "REACT_EDITOR='$editor' PORT=$macosport npm run start-macos | sed 's/^/[MacOS ] /' || echo '[MacOS ] Died!'" & 19 | nix-shell -p nodejs-10_x xdg_utils watchman --run "REACT_EDITOR='$editor' PORT=$mobileport npm run start-mobile | sed 's/^/[Mobile] /' || echo '[Mobile] Died!'" 20 | -------------------------------------------------------------------------------- /src/Views.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE DataKinds #-} 3 | {-# LANGUAGE ExistentialQuantification #-} 4 | {-# LANGUAGE FlexibleContexts #-} 5 | {-# LANGUAGE FlexibleInstances #-} 6 | {-# LANGUAGE MultiParamTypeClasses #-} 7 | {-# LANGUAGE OverloadedStrings #-} 8 | {-# LANGUAGE PolyKinds #-} 9 | {-# LANGUAGE ScopedTypeVariables #-} 10 | {-# LANGUAGE TypeApplications #-} 11 | {-# LANGUAGE TypeFamilies #-} 12 | {-# LANGUAGE TypeFamilyDependencies #-} 13 | {-# LANGUAGE TypeOperators #-} 14 | {-# LANGUAGE UndecidableInstances #-} 15 | module Views where 16 | 17 | import Prelude (($)) 18 | import React.Flux.Rn.Views (mkControllerView,StoreArg,View) 19 | import Store (AppState) 20 | 21 | app :: View () 22 | app = mkControllerView @'[StoreArg AppState] "My app" $ \_ () -> 23 | "Hello world!" 24 | -------------------------------------------------------------------------------- /files/require_app.macos.js: -------------------------------------------------------------------------------- 1 | 2 | window.React = require('react'); 3 | window.createReactClass = require('create-react-class'); 4 | window.React.createClass = window.createReactClass; 5 | var { PropTypes } = require('prop-types'); 6 | window.React.PropTypes = PropTypes; 7 | 8 | window.__registerComponent = function(name,c) { 9 | var { doRegister } = require('./register'); 10 | var { AppRegistry } = require('react-native-macos'); 11 | doRegister(name,c,AppRegistry); 12 | }; 13 | 14 | if (!window.navigator) { 15 | window.navigator = {}; 16 | window.navigator.userAgent = 'react-native'; 17 | } 18 | 19 | var { registerRnComponents } = require('./register_rn'); 20 | var { registerAddons } = require('./register_addons'); 21 | var __rn = require('react-native-macos'); 22 | 23 | module.exports = { 24 | RegRn: registerRnComponents(__rn), 25 | RegAddons: registerAddons(__rn.Platform.OS), 26 | Runmain: require('./all'), 27 | Repl: require('./ghcjsiClient') 28 | }; 29 | 30 | -------------------------------------------------------------------------------- /package-macos.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell --pure -i bash -p nix bash cacert curl 3 | set -eu 4 | source ./nix-shell-init.sh 5 | 6 | ### Note! Note pure, requires xcodebuild and hdiutil! ### 7 | 8 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" 9 | app=$(basename *.cabal .cabal) 10 | 11 | ./build.sh 12 | 13 | cp -fR files/. rnproject/ 14 | 15 | ./remove-symlinks.sh 16 | 17 | test -d release || mkdir release 18 | test -f release/$app.dmg && rm release/$app.dmg 19 | nix-shell -p nodejs-10_x --run "(cd rnproject/macos && PATH=/usr/bin:\$PATH PLATFORM=macos /usr/bin/xcodebuild -UseModernBuildSystem=NO -xcconfig $DIR/rnproject/.xcconfig -scheme rnproject -configuration Release -target rnproject archive -archivePath $DIR/dist/rnproject.xcarchive)" 20 | 21 | /usr/bin/hdiutil create -volname rnproject -srcfolder dist/rnproject.xcarchive/Products/Applications/rnproject.app -ov -format UDZO release/$app.dmg 22 | 23 | echo "Generated release/$app.dmg" 24 | -------------------------------------------------------------------------------- /cc.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell --pure -i bash -p nix bash rsync 3 | set -eu 4 | source ./nix-shell-init.sh 5 | 6 | app=$(basename *.cabal .cabal) 7 | 8 | test -e dist || (mkdir dist && mkdir dist/build && mkdir dist/build/$app) 9 | 10 | while true; do 11 | printf '\033\143' #clear 12 | nix-shell --run "cabal configure --ghcjs && time cabal build $@; true" 13 | 14 | # used by ghcjsi repl 15 | test -f dist/build/$app/$app.jsexe/all.js && sed -i 's/h$main(h$mainZCZCMainzimain);/module.exports = { h$main: h$main, h$killThread: h$killThread, h$d: h$d, h$baseZCControlziExceptionziBasezinonTermination: h$baseZCControlziExceptionziBasezinonTermination };h$main(h$mainZCZCMainzimain);/g' dist/build/$app/$app.jsexe/all.js 16 | 17 | rsync --checksum dist/build/$app/$app.jsexe/all.js rnproject/ 18 | 19 | nix-shell -p fswatch --run "fswatch -1 -r -i '.*[.]hs$' --event Created --event Updated --event Removed --event Renamed --event MovedFrom --event MovedTo src; true" 20 | done 21 | 22 | -------------------------------------------------------------------------------- /register_addons.macos.js: -------------------------------------------------------------------------------- 1 | var registerAddons = function(platform) { 2 | /*window['Icon.Entypo'] = require('react-native-vector-icons/Entypo'); 3 | window['Icon.EvilIcons'] = require('react-native-vector-icons/EvilIcons'); 4 | window['Icon.FontAwesome'] = require('react-native-vector-icons/FontAwesome'); 5 | window['Icon.Foundation'] = require('react-native-vector-icons/Foundation'); 6 | window['Icon.Ionicons'] = require('react-native-vector-icons/Ionicons'); 7 | window['Icon.MaterialIcons'] = require('react-native-vector-icons/MaterialIcons'); 8 | window['Icon.Octicons'] = require('react-native-vector-icons/Octicons'); 9 | window['Icon.Zocial'] = require('react-native-vector-icons/Zocial');*/ 10 | 11 | //window['I18n'] = require('react-native-i18n'); 12 | 13 | //window['Animatable'] = require('react-native-animatable'); 14 | 15 | //window['GL'] = require('gl-react-native'); 16 | }; 17 | 18 | module.exports = { 19 | registerAddons: registerAddons 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /register_addons.android.js: -------------------------------------------------------------------------------- 1 | var registerAddons = function(platform) { 2 | /*window['Icon.Entypo'] = require('react-native-vector-icons/Entypo'); 3 | window['Icon.EvilIcons'] = require('react-native-vector-icons/EvilIcons'); 4 | window['Icon.FontAwesome'] = require('react-native-vector-icons/FontAwesome'); 5 | window['Icon.Foundation'] = require('react-native-vector-icons/Foundation'); 6 | window['Icon.Ionicons'] = require('react-native-vector-icons/Ionicons'); 7 | window['Icon.MaterialIcons'] = require('react-native-vector-icons/MaterialIcons'); 8 | window['Icon.Octicons'] = require('react-native-vector-icons/Octicons'); 9 | window['Icon.Zocial'] = require('react-native-vector-icons/Zocial'); 10 | */ 11 | //window['I18n'] = require('react-native-i18n'); 12 | 13 | //window['Animatable'] = require('react-native-animatable'); 14 | 15 | //window['GL'] = require('gl-react-native'); 16 | }; 17 | 18 | module.exports = { 19 | registerAddons: registerAddons 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /register_addons.ios.js: -------------------------------------------------------------------------------- 1 | var registerAddons = function(platform) { 2 | /*window['Icon.Entypo'] = require('react-native-vector-icons/Entypo'); 3 | window['Icon.EvilIcons'] = require('react-native-vector-icons/EvilIcons'); 4 | window['Icon.FontAwesome'] = require('react-native-vector-icons/FontAwesome'); 5 | window['Icon.Foundation'] = require('react-native-vector-icons/Foundation'); 6 | window['Icon.Ionicons'] = require('react-native-vector-icons/Ionicons'); 7 | window['Icon.MaterialIcons'] = require('react-native-vector-icons/MaterialIcons'); 8 | window['Icon.Octicons'] = require('react-native-vector-icons/Octicons'); 9 | window['Icon.Zocial'] = require('react-native-vector-icons/Zocial'); 10 | */ 11 | //window['I18n'] = require('react-native-i18n'); 12 | 13 | //window['Animatable'] = require('react-native-animatable'); 14 | 15 | //window['GL'] = require('gl-react-native'); 16 | }; 17 | 18 | module.exports = { 19 | registerAddons: registerAddons 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /register_addons.web.js: -------------------------------------------------------------------------------- 1 | var registerAddons = function(platform) { 2 | /*window['Icon.Entypo'] = require('react-native-vector-icons/Entypo'); 3 | window['Icon.EvilIcons'] = require('react-native-vector-icons/EvilIcons'); 4 | window['Icon.FontAwesome'] = require('react-native-vector-icons/FontAwesome'); 5 | window['Icon.Foundation'] = require('react-native-vector-icons/Foundation'); 6 | window['Icon.Ionicons'] = require('react-native-vector-icons/Ionicons'); 7 | window['Icon.MaterialIcons'] = require('react-native-vector-icons/MaterialIcons'); 8 | window['Icon.Octicons'] = require('react-native-vector-icons/Octicons'); 9 | window['Icon.Zocial'] = require('react-native-vector-icons/Zocial'); 10 | */ 11 | //window['I18n'] = require('react-native-i18n'); 12 | 13 | //window['Animatable'] = require('react-native-animatable'); 14 | 15 | //window['GL'] = require('gl-react-native'); 16 | }; 17 | 18 | module.exports = { 19 | registerAddons: registerAddons 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /register_addons.windows.js: -------------------------------------------------------------------------------- 1 | var registerAddons = function(platform) { 2 | /*window['Icon.Entypo'] = require('react-native-vector-icons/Entypo'); 3 | window['Icon.EvilIcons'] = require('react-native-vector-icons/EvilIcons'); 4 | window['Icon.FontAwesome'] = require('react-native-vector-icons/FontAwesome'); 5 | window['Icon.Foundation'] = require('react-native-vector-icons/Foundation'); 6 | window['Icon.Ionicons'] = require('react-native-vector-icons/Ionicons'); 7 | window['Icon.MaterialIcons'] = require('react-native-vector-icons/MaterialIcons'); 8 | window['Icon.Octicons'] = require('react-native-vector-icons/Octicons'); 9 | window['Icon.Zocial'] = require('react-native-vector-icons/Zocial'); 10 | */ 11 | //window['I18n'] = require('react-native-i18n'); 12 | 13 | //window['Animatable'] = require('react-native-animatable'); 14 | 15 | // window['GL'] = require('gl-react-native'); 16 | }; 17 | 18 | module.exports = { 19 | registerAddons: registerAddons 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /files/require_app.js: -------------------------------------------------------------------------------- 1 | 2 | window.React = require('react'); 3 | window.createReactClass = require('create-react-class'); 4 | window.React.createClass = window.createReactClass; 5 | var { PropTypes } = require('prop-types'); 6 | window.React.PropTypes = PropTypes; 7 | 8 | window.__registerComponent = function(name,c) { 9 | var { doRegister } = require('./register'); 10 | var { AppRegistry } = require('react-native'); 11 | doRegister(name,c,AppRegistry); 12 | }; 13 | 14 | if (!window.navigator) { 15 | window.navigator = {}; 16 | window.navigator.userAgent = 'react-native'; 17 | } 18 | 19 | var { registerRnComponents } = require('./register_rn'); 20 | var { registerAddons } = require('./register_addons'); 21 | var __rn = require('react-native'); 22 | 23 | var ___process = process; 24 | process = undefined; 25 | var main = require('./all'); 26 | process = ___process; 27 | 28 | module.exports = { 29 | RegRn: registerRnComponents(__rn), 30 | RegAddons: registerAddons(__rn.Platform.OS), 31 | Runmain: main, 32 | Repl: require('./ghcjsiClient') 33 | }; 34 | 35 | -------------------------------------------------------------------------------- /hseverywhere.cabal: -------------------------------------------------------------------------------- 1 | 2 | name: hseverywhere 3 | version: 0.1.0.0 4 | license: MIT 5 | license-file: LICENSE 6 | author: Jyri-Matti Lähteenmäki 7 | maintainer: jyri-matti@lahteenmaki.net 8 | build-type: Simple 9 | cabal-version: >=1.10 10 | 11 | executable hseverywhere 12 | main-is: Main.hs 13 | build-depends: base >=4.9 && <5.0, 14 | text, 15 | transformers, 16 | time, 17 | deepseq, 18 | react-hs, 19 | react-native-hs, 20 | aeson, 21 | containers, 22 | http-common, 23 | network-uri, 24 | semigroups 25 | 26 | if impl(ghcjs) 27 | build-depends: ghcjs-base 28 | else 29 | build-depends: ghcjs-base-stub 30 | hs-source-dirs: src 31 | default-language: Haskell2010 32 | ghc-options: -W 33 | cpp-options: -DGHCJS_BROWSER 34 | 35 | -------------------------------------------------------------------------------- /run-android.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell --pure -i bash -p nix bash 3 | set -eu 4 | source ./nix-shell-init.sh 5 | 6 | port=${1:-8081} 7 | 8 | androidDevice="Nexus S" 9 | 10 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" 11 | app=$(basename *.cabal .cabal) 12 | 13 | version=$(nix-store --query --references $(nix-instantiate '' -A androidsdk_9_0) | grep 'build-tools' | sed 's/.*build-tools-\([^.]*\).*.drv/\1/') 14 | 15 | echo "Make sure you don't have another emulator (VirtualBox, Docker...) running." 16 | 17 | # print available devices 18 | nix-shell -p jre8 --run "rnproject/android/androidsdk/bin/android list" 19 | 20 | nix-shell -p "androidenv.emulateApp { platformVersion = \"$version\"; abiVersion = \"x86_64\"; name = \"$app\"; }" --run "run-test-emulator" 21 | 22 | nix-shell -p jre8 which nodejs-10_x androidsdk_9_0 --run "cd rnproject; ADB_INSTALL_TIMEOUT=16 ANDROID_HOME=$DIR/rnproject/android/androidsdk/libexec PATH=$DIR/rnproject/android/androidsdk/libexec/platform-tools/:\$PATH ./node_modules/.bin/react-native run-android --no-packager" 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Jyri-Matti Lähteenmäki 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /files/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function (api) { 2 | api.cache(false); 3 | 4 | function platform() { 5 | if (process && (process.env.PLATFORM === 'macos' || process.argv.filter(a => a.indexOf('react-native-macos') > -1).length > 0)) { 6 | console.log("babel.config.js: macos"); 7 | return { 8 | "alias": { 9 | "react-native": "react-native-macos" 10 | } 11 | }; 12 | } else if (process && (process.env.PLATFORM === 'web' || process.argv.filter(a => a.indexOf('react-native-web') > -1).length > 0)) { 13 | console.log("babel.config.js: web"); 14 | return { 15 | "alias": { 16 | "react-native": "react-native-web" 17 | } 18 | }; 19 | } 20 | 21 | console.log("babel.config.js: mobile"); 22 | return {}; 23 | } 24 | 25 | const presets = ["module:metro-react-native-babel-preset"]; 26 | const plugins = [ 27 | ["module-resolver", platform()] 28 | ]; 29 | const ignore = ["**/all.js"]; 30 | 31 | return { 32 | presets, 33 | plugins, 34 | ignore 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /files/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | module.exports = { 4 | mode: 'development', 5 | node: { process: false }, 6 | module: { 7 | rules: [ 8 | { 9 | loaders: [], 10 | exclude: [ 11 | path.resolve(__dirname, "./~/react"), 12 | path.resolve(__dirname, "./~/react-native"), 13 | path.resolve(__dirname, "./~/react-native-web"), 14 | path.resolve(__dirname, "./~/react-native-macos") 15 | ], 16 | }, 17 | { 18 | loader: "babel-loader", 19 | test: /\.jsx?$/, 20 | exclude: [/all.js/,/rts.js/,/out.js/,/lib.js/,/runmain.js/,/node_modules(?!\/react-native-(vector-icons|animatable))/], 21 | options: { 22 | babelrc: false, 23 | presets: ['module:metro-react-native-babel-preset'], 24 | plugins: ['add-module-exports'] 25 | } 26 | }, 27 | { 28 | loader: "url-loader", 29 | test: /\.ttf$/ 30 | }, 31 | ] 32 |  }, 33 | entry: './index.web.js', 34 | output: { 35 | filename: "dist/bundle.js", 36 | }, 37 | resolve: { 38 | alias: { 39 | 'react-native': 'react-native-web' 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /init-windows.bat: -------------------------------------------------------------------------------- 1 | :: 2>/dev/null || echo ' 2 | ::::::::::::::::::::::::::: Windows 3 | 4 | cd c:\vagrant 5 | 6 | reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /t REG_DWORD /f /v "AllowDevelopmentWithoutDevLicense" /d "1" 7 | 8 | echo "Installing Visual Studio. This takes a while..." 9 | powershell -command "& { iwr http://download.microsoft.com/download/D/2/3/D23F4D0F-BA2D-4600-8725-6CCECEA05196/vs_community_ENU.exe -OutFile c:\tmp\vs.exe }" 10 | c:\tmp\vs.exe /InstallSelectableItems /Passive 11 | 12 | echo "Installing NuGet" 13 | powershell -command "& { iwr https://dist.nuget.org/win-x86-commandline/v3.4.4/NuGet.exe -OutFile c:\tmp\nuget.exe }" 14 | c:\tmp\nuget.exe restore 15 | 16 | exit /b %ERRORLEVEL% 17 | ' >/dev/null 18 | ########################### Others 19 | #! /bin/sh 20 | set -eu 21 | 22 | nix-shell -I channel:nixos-18.09 -p bash netcat vagrant curl --run "(vagrant up windows --no-provision && nc -z -w1 127.0.0.1 55985) || (echo Execute contents of init-WinRM.bat as Administrator, install Guest Additions, reboot, 'vagrant reload windows'. Then re-execute ./init-windows.bat && false)" 23 | nix-shell -I channel:nixos-18.09 -p vagrant --run "vagrant provision windows --provision-with init" 24 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | Vagrant.configure(2) do |config| 5 | config.vm.define "linux" do |c| 6 | c.vm.box = "bento/ubuntu-16.04" 7 | c.vm.network "forwarded_port", guest: 8081, host: 8084 8 | c.vm.provider "virtualbox" do |vb| 9 | vb.gui = true 10 | vb.memory = "1024" 11 | end 12 | 13 | c.vm.provision "shell", inline: <<-SHELL 14 | sudo apt-get update; 15 | sudo apt-get install -y ubuntu-desktop; 16 | SHELL 17 | end 18 | 19 | config.vm.define "windows" do |c| 20 | c.vm.communicator = "winrm" 21 | c.winrm.username = "IEUser" 22 | c.winrm.password = "Passw0rd!" 23 | c.vm.box = "chusiang/win10-x64-ansible" 24 | c.vm.box_version = "1.1.0" 25 | c.vm.boot_timeout = 600 26 | c.vm.provider "virtualbox" do |vb| 27 | vb.gui = true 28 | vb.memory = "2048" 29 | end 30 | 31 | c.vm.provision "init", type: "shell", path: "init-windows.bat", args: "rnproject", privileged: true 32 | c.vm.provision "run", type: "shell", path: "run-windows.bat", args: "rnproject", privileged: true, powershell_elevated_interactive: true 33 | c.vm.provision "package", type: "shell", path: "package-windows.bat", args: "rnproject", privileged: false 34 | 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /run-macos.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell -i bash -p nix bash 3 | set -eu 4 | source ./nix-shell-init.sh 5 | 6 | ### Note! Note pure, requires xcodebuild! ### 7 | 8 | port=${1:-8082} 9 | 10 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" 11 | 12 | sed -i "s/8081/8082/g" rnproject/node_modules/react-native-macos/React/Base/RCTDefines.h 13 | 14 | #nix-shell --pure --run "sed -i \"s/8081/$port/g\" rnproject/node_modules/react-native-macos/React/DevSupport/RCTPackagerConnection.m" 15 | nix-shell --pure --run "sed -i \"s/8081/$port/g\" rnproject/node_modules/react-native-macos/React/Base/RCTBundleURLProvider.m" 16 | nix-shell --pure --run "sed -i \"s/8081/$port/g\" rnproject/node_modules/react-native-macos/React/Modules/RCTRedBox.m" 17 | nix-shell --pure --run "sed -i \"s/8081/$port/g\" rnproject/node_modules/react-native-macos/Libraries/WebSocket/RCTWebSocketExecutor.m" 18 | 19 | nix-shell -p nodejs-10_x --run "cd rnproject/macos && PATH=/usr/bin:\$PATH PLATFORM=macos /usr/bin/xcodebuild -xcconfig $DIR/rnproject/.xcconfig -scheme rnproject -configuration Debug -target rnproject build" 20 | 21 | x=$( xcodebuild -showBuildSettings -project rnproject/macos/rnproject.xcodeproj | grep ' BUILD_DIR =' | sed -e 's/.*= *//' ) 22 | DYLD_FRAMEWORK_PATH=$x/Debug DYLD_LIBRARY_PATH=$x/Debug $x/Debug/rnproject.app/Contents/MacOS/rnproject & 23 | -------------------------------------------------------------------------------- /run-windows.bat: -------------------------------------------------------------------------------- 1 | :: 2>/dev/null || echo ' 2 | ::::::::::::::::::::::::::: Windows 3 | 4 | cd c:\vagrant 5 | ::"c:\Progra~2\MSBuild\14.0\Bin\MSBuild.exe" %1\windows\%1.sln /t:Build /p:OutDir=c:\vagrant-build\bin\x64\Debug\;Configuration=Debug;Platform=x64;AppxBundlePlatforms="x64";AppxBundle=Always;OutputPath=c:\vagrant-build\bin\x64\Debug\;TargetFrameworkVersion=v4.6 6 | "c:\Progra~2\MSBuild\14.0\Bin\MSBuild.exe" %1\windows\%1.sln /t:Build /p:OutDir=c:\vagrant-build\bin\x64\Debug\;Configuration=Debug;Platform=x64;AppxBundlePlatforms="x64";AppxBundle=Always;OutputPath=c:\vagrant-build\bin\x64\Debug\ 7 | powershell c:\vagrant-build\bin\x64\Debug\%1\AppPackages\%1_1.0.0.0_Debug_Test\Add-AppDevPackage.ps1 8 | 9 | timeout 3 10 | 11 | run-windows.vbs %1 12 | 13 | exit /b %ERRORLEVEL% 14 | ' >/dev/null 15 | ########################### Others 16 | #! /usr/bin/env nix-shell 17 | #! nix-shell -i bash -p bash netcat vagrant 18 | set -ux 19 | 20 | nix-shell -I channel:nixos-18.09 -p vagrant --run "command -v vagrant >/dev/null || (echo Please install Vagrant and VirtualBox for Windows development && false)" 21 | nix-shell -I channel:nixos-18.09 -p vagrant --run "vagrant up windows --no-provision" 22 | nix-shell -I channel:nixos-18.09 -p netcat --run "nc -z -w1 127.0.0.1 55985 || (echo 'Could not connect WinRM' && false)" 23 | nix-shell -I channel:nixos-18.09 -p vagrant --run "vagrant provision windows --provision-with run" 24 | -------------------------------------------------------------------------------- /files/register_rn.windows.js: -------------------------------------------------------------------------------- 1 | var registerRnComponents = function(__rn) { 2 | window['Image'] = __rn.Image; 3 | window['ListView'] = __rn.ListView; 4 | window['ListView.DataSource'] = __rn.ListView.DataSource; 5 | window['Navigator'] = __rn.Navigator; 6 | window['Picker'] = __rn.Picker; 7 | window['ScrollView'] = __rn.ScrollView; 8 | window['StatusBar'] = __rn.StatusBar; 9 | window['Switch'] = __rn.Switch; 10 | window['Text'] = __rn.Text; 11 | window['TextInput'] = __rn.TextInput; 12 | window['TouchableHighlight'] = __rn.TouchableHighlight; 13 | window['TouchableOpacity'] = __rn.TouchableOpacity; 14 | window['TouchableWithoutFeedback'] = __rn.TouchableWithoutFeedback; 15 | window['View'] = __rn.View; 16 | window['WebView'] = __rn.WebView; 17 | 18 | window['Alert'] = __rn.Alert; 19 | window['Animated'] = __rn.Animated; 20 | window['AppRegistry'] = __rn.AppRegistry; 21 | window['AppState'] = __rn.AppState; 22 | window['AsyncStorage'] = __rn.AsyncStorage; 23 | window['BackAndroid'] = __rn.BackAndroid; 24 | window['Clipboard'] = __rn.Clipboard; 25 | window['Dimensions'] = __rn.Dimensions; 26 | window['InteractionManager'] = __rn.InteractionManager; 27 | window['LayoutAnimation'] = __rn.LayoutAnimation; 28 | window['Linking'] = __rn.Linking; 29 | window['NativeMethodsMixin'] = __rn.NativeMethodsMixin; 30 | window['NetInfo'] = __rn.NetInfo; 31 | window['PanResponder'] = __rn.PanResponder; 32 | window['StyleSheet'] = __rn.StyleSheet; 33 | window['Vibration'] = __rn.Vibration; 34 | 35 | window['Platform'] = __rn.Platform; 36 | }; 37 | 38 | module.exports = { 39 | registerRnComponents: registerRnComponents 40 | }; 41 | -------------------------------------------------------------------------------- /files/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rnproject", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start-mobile": "PLATFORM=mobile ./node_modules/.bin/react-native start --reset-cache --port=$PORT", 7 | "start-macos": "PLATFORM=macos ./node_modules/.bin/react-native-macos start --reset-cache --port=$PORT", 8 | "start-web": "PLATFORM=web ./node_modules/.bin/webpack-dev-server --port=$PORT --progress --colors --content-base=../ --inline --hot", 9 | "pack": "./node_modules/.bin/webpack --verbose" 10 | }, 11 | "browser":{ 12 | "child_process": false, 13 | "fs": false 14 | }, 15 | "dependencies": { 16 | "json-loader": "0.5.4", 17 | "react": "16.6.3", 18 | "react-dom": "16.6.3", 19 | "react-native": "0.57.6", 20 | "react-native-windows": "0.57.1", 21 | "react-native-web": "0.11.2", 22 | "react-native-macos": "0.19.2", 23 | "react-art": "16.6.3", 24 | 25 | "react-native-vector-icons": "4.6.0", 26 | "react-native-animatable": "1.3.0", 27 | "gl-react": "3.15.0", 28 | "gl-react-native": "3.15.0", 29 | "gl-react-dom": "3.15.0", 30 | "react-native-maps": "0.24.0", 31 | 32 | "create-react-class": "15.6.3", 33 | "prop-types": "15.7.2", 34 | "socket.io-client": "1.5.1", 35 | "Base64": "0.3.0", 36 | "path": "0.12.7", 37 | "os": "0.1.1" 38 | }, 39 | "devDependencies": { 40 | "react-native-cli": "2.0.1", 41 | "react-native-macos-cli": "2.0.1", 42 | "rnpm": "1.9.0", 43 | "rnpm-plugin-windows": "0.2.8", 44 | "babel-loader": "8.0.5", 45 | "@babel/core": "7.4.0", 46 | "metro-react-native-babel-preset": "0.53.1", 47 | "babel-plugin-add-module-exports": "1.0.0", 48 | "babel-plugin-module-resolver": "3.2.0", 49 | "metro-config": "0.53.1", 50 | "metro-visualizer": "0.53.1", 51 | "metro": "0.53.1", 52 | "metro-core": "0.53.1", 53 | "metro-babel-register": "0.53.1", 54 | "react-devtools": "3.6.1", 55 | "webpack": "4.29.6", 56 | "webpack-cli": "3.3.0", 57 | "webpack-dev-server": "3.2.1" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /files/rn-cli.config.js: -------------------------------------------------------------------------------- 1 | // based on: 2 | // https://gist.githubusercontent.com/ndbroadbent/6261dbc0ed60e20a7f71e8987cf18aa7/raw/2e76e5321ae8331e662317f96930222fbbb6e308/rn-cli.config.js 3 | 4 | const path = require('path'); 5 | 6 | const sharedBlacklist = ['react-native/local-cli/core/__fixtures__.*']; 7 | 8 | 9 | const platformBlacklists = { 10 | mobile: [ 11 | '.web.js', 12 | '.windows.js', 13 | '.macos.js', 14 | 'node_modules/react-native-web/.*', 15 | 'node_modules/react-native-windows/.*', 16 | 'node_modules/react-native-macos/.*', 17 | 'node_modules/[^/]+/.git/.*' 18 | ], 19 | web: [ 20 | '.windows.js', 21 | '.macos.js', 22 | 'node_modules/react-native-windows/.*', 23 | 'node_modules/react-native-macos/.*', 24 | 'node_modules/[^/]+/.git/.*' 25 | ], 26 | windows: [ 27 | '.web.js', 28 | '.macos.js', 29 | 'node_modules/react-native-web/.*', 30 | 'node_modules/react-native/.*', 31 | 'node_modules/react-native-macos/.*', 32 | 'node_modules/[^/]+/.git/.*' 33 | ], 34 | macos: [ 35 | '.web.js', 36 | '.windows.js', 37 | 'node_modules/react-native-web/.*', 38 | 'node_modules/react-native-windows/.*', 39 | 'node_modules/[^/]+/.git/.*' 40 | ], 41 | } 42 | 43 | function blacklist(platform, additionalBlacklist) { 44 | // eslint-disable-next-line 45 | return new RegExp( 46 | (additionalBlacklist || []).concat(sharedBlacklist) 47 | .concat(platformBlacklists[platform] || []) 48 | .join('|')); 49 | } 50 | 51 | function bl() { 52 | if (process && (process.env.PLATFORM === 'macos' || process.argv.filter(a => a.indexOf('react-native-macos') > -1).length > 0)) { 53 | console.log("rn-cli.config.js: macos"); 54 | return blacklist('macos'); 55 | } else if (process && (process.env.PLATFORM === 'web' || process.argv.filter(a => a.indexOf('react-native-web') > -1).length > 0)) { 56 | console.log("rn-cli.config.js: web"); 57 | return blacklist('web'); 58 | } 59 | 60 | console.log("rn-cli.config.js: mobile"); 61 | return blacklist('mobile'); 62 | } 63 | 64 | module.exports = { 65 | resolver: { 66 | blacklistRE: bl() 67 | }, 68 | server: { 69 | enableVisualizer: true 70 | }, 71 | getBlacklistRE(platform) { 72 | return bl(); 73 | } 74 | } -------------------------------------------------------------------------------- /stack.yaml: -------------------------------------------------------------------------------- 1 | # This file was automatically generated by 'stack init' 2 | # 3 | # Some commonly used options have been documented as comments in this file. 4 | # For advanced use and comprehensive documentation of the format, please see: 5 | # https://docs.haskellstack.org/en/stable/yaml_configuration/ 6 | 7 | # Resolver to choose a 'specific' stackage snapshot or a compiler version. 8 | # A snapshot resolver dictates the compiler version and the set of packages 9 | # to be used for project dependencies. For example: 10 | # 11 | # resolver: lts-3.5 12 | # resolver: nightly-2015-09-21 13 | # resolver: ghc-7.10.2 14 | # resolver: ghcjs-0.1.0_ghc-7.10.2 15 | # resolver: 16 | # name: custom-snapshot 17 | # location: "./custom-snapshot.yaml" 18 | #resolver: lts-9.17 19 | resolver: ghc-7.10.2 20 | 21 | # User packages to be built. 22 | # Various formats can be used as shown in the example below. 23 | # 24 | # packages: 25 | # - some-directory 26 | # - https://example.com/foo/bar/baz-0.0.2.tar.gz 27 | # - location: 28 | # git: https://github.com/commercialhaskell/stack.git 29 | # commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a 30 | # - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a 31 | # extra-dep: true 32 | # subdirs: 33 | # - auto-update 34 | # - wai 35 | # 36 | # A package marked 'extra-dep: true' will only be built if demanded by a 37 | # non-dependency (i.e. a user package), and its test suites and benchmarks 38 | # will not be run. This is useful for tweaking upstream packages. 39 | packages: 40 | - . 41 | - location: 42 | git: https://github.com/jyrimatti/react-hs.git 43 | commit: 9390f850861102e84e38514a577ce7f3b1aac23f 44 | subdirs: 45 | - react-hs 46 | - location: ../react-native-hs 47 | extra-dep: true 48 | 49 | # Dependency packages to be pulled from upstream that are not in the resolver 50 | # (e.g., acme-missiles-0.3) 51 | extra-deps: 52 | - ghcjs-base-stub-0.1.0.4 53 | - string-conversions-0.4.0.1 54 | - http-common-0.8.2.0 55 | 56 | # Override default flag values for local packages and extra-deps 57 | flags: {} 58 | 59 | # Extra package databases containing global packages 60 | extra-package-dbs: [] 61 | 62 | # Control whether we use the GHC we find on the path 63 | # system-ghc: true 64 | # 65 | # Require a specific version of stack, using version ranges 66 | # require-stack-version: -any # Default 67 | # require-stack-version: ">=1.5" 68 | # 69 | # Override the architecture used by stack, especially useful on Windows 70 | # arch: i386 71 | # arch: x86_64 72 | # 73 | # Extra directories used by stack for building 74 | # extra-include-dirs: [/path/to/dir] 75 | # extra-lib-dirs: [/path/to/dir] 76 | # 77 | # Allow a newer minor version of GHC than the snapshot specifies 78 | # compiler-check: newer-minor 79 | -------------------------------------------------------------------------------- /files/register_rn.js: -------------------------------------------------------------------------------- 1 | var registerRnComponents = function(__rn) { 2 | // Components (corresponds to those in Components.hs) 3 | window['ActivityIndicator'] = __rn.ActivityIndicator; 4 | window['Button'] = __rn.Button; 5 | window['DatePickerIOS'] = __rn.DatePickerIOS; 6 | window['DrawerLayoutAndroid'] = __rn.DrawerLayoutAndroid; 7 | window['FlatList'] = __rn.FlatList; 8 | window['Image'] = __rn.Image; 9 | window['KeyboardAvoidingView'] = __rn.KeyboardAvoidingView; 10 | window['ListView'] = __rn.ListView; 11 | window['MaskedViewIOS'] = __rn.MaskedViewIOS; 12 | window['Modal'] = __rn.Modal; 13 | window['NavigatorIOS'] = __rn.NavigatorIOS; 14 | window['Picker'] = __rn.Picker; 15 | window['PickerIOS'] = __rn.PickerIOS; 16 | window['ProgressBarAndroid'] = __rn.ProgressBarAndroid; 17 | window['ProgressViewIOS'] = __rn.ProgressViewIOS; 18 | window['RefreshControl'] = __rn.RefreshControl; 19 | window['SafeAreaView'] = __rn.SafeAreaView; 20 | window['ScrollView'] = __rn.ScrollView; 21 | window['SectionList'] = __rn.SectionList; 22 | window['SegmentedControlIOS'] = __rn.SegmentedControlIOS; 23 | window['Slider'] = __rn.Slider; 24 | window['SnapshotViewIOS'] = __rn.SnapshotViewIOS; 25 | window['StatusBar'] = __rn.StatusBar; 26 | window['Switch'] = __rn.Switch; 27 | window['TabBarIOS'] = __rn.TabBarIOS; 28 | window['TabBarIOS_Item'] = __rn.TabBarIOS.Item; 29 | window['Text'] = __rn.Text; 30 | window['TextInput'] = __rn.TextInput; 31 | window['ToolbarAndroid'] = __rn.ToolbarAndroid; 32 | window['TouchableHighlight'] = __rn.TouchableHighlight; 33 | window['TouchableNativeFeedback'] = __rn.TouchableNativeFeedback; 34 | window['TouchableOpacity'] = __rn.TouchableOpacity; 35 | window['TouchableWithoutFeedback'] = __rn.TouchableWithoutFeedback; 36 | window['View'] = __rn.View; 37 | window['ViewPagerAndroid'] = __rn.ViewPagerAndroid; 38 | window['VirtualizedList'] = __rn.VirtualizedList; 39 | window['WebView'] = __rn.WebView; 40 | 41 | // APIs 42 | //window['AccessibilityInfo'] = __rn.AccessibilityInfo; 43 | window['ActionSheetIOS'] = __rn.ActionSheetIOS; 44 | window['Alert'] = __rn.Alert; 45 | window['AlertIOS'] = __rn.AlertIOS; 46 | window['Animated'] = __rn.Animated; 47 | window['AppRegistry'] = __rn.AppRegistry; 48 | window['AppState'] = __rn.AppState; 49 | window['AsyncStorage'] = __rn.AsyncStorage; 50 | window['BackAndroid'] = __rn.BackAndroid; 51 | window['BackHandler'] = __rn.BackHandler; 52 | window['CameraRoll'] = __rn.CameraRoll; 53 | window['Clipboard'] = __rn.Clipboard; 54 | window['DatePickerAndroid'] = __rn.DatePickerAndroid; 55 | window['Dimensions'] = __rn.Dimensions; 56 | window['Easing'] = __rn.Easing; 57 | window['Geolocation'] = __rn.Geolocation; 58 | window['ImageEditor'] = __rn.ImageEditor; 59 | window['ImagePickerIOS'] = __rn.ImagePickerIOS; 60 | window['ImageStore'] = __rn.ImageStore; 61 | window['InteractionManager'] = __rn.InteractionManager; 62 | window['Keyboard'] = __rn.Keyboard; 63 | window['LayoutAnimation'] = __rn.LayoutAnimation; 64 | window['Linking'] = __rn.Linking; 65 | window['ListViewDataSource'] = __rn.ListViewDataSource; 66 | window['NetInfo'] = __rn.NetInfo; 67 | window['PanResponder'] = __rn.PanResponder; 68 | window['PermissionsAndroid'] = __rn.PermissionsAndroid; 69 | window['PixelRatio'] = __rn.PixelRatio; 70 | //window['PushNotificationIOS'] = __rn.PushNotificationIOS; 71 | window['Settings'] = __rn.Settings; 72 | window['Share'] = __rn.Share; 73 | window['StatusBarIOS'] = __rn.StatusBarIOS; 74 | window['StyleSheet'] = __rn.StyleSheet; 75 | window['Systrace'] = __rn.Systrace; 76 | window['TimePickerAndroid'] = __rn.TimePickerAndroid; 77 | window['ToastAndroid'] = __rn.ToastAndroid; 78 | window['Transforms'] = __rn.Transforms; 79 | window['Vibration'] = __rn.Vibration; 80 | window['VibrationIOS'] = __rn.VibrationIOS; 81 | 82 | window['Platform'] = __rn.Platform; 83 | }; 84 | 85 | module.exports = { 86 | registerRnComponents: registerRnComponents 87 | }; 88 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | { nixpkgs ? import {}, compiler ? "ghcjs" }: 2 | 3 | let 4 | 5 | inherit (nixpkgs) pkgs; 6 | 7 | hp = if compiler == "default" 8 | then pkgs.haskellPackages 9 | else pkgs.haskell.packages.${compiler}; 10 | 11 | haskellPackages = hp.override (old: { 12 | overrides = pkgs.lib.composeExtensions (old.overrides or (_: _: {})) (self: super: { 13 | QuickCheck = pkgs.haskell.lib.dontCheck super.QuickCheck; 14 | }); 15 | }); 16 | 17 | myproject = { mkDerivation, base, deepseq, ghcjs-base, react-hs, react-native-hs, stdenv, nodejs, 18 | text, time, transformers, containers, network-uri 19 | }: 20 | mkDerivation { 21 | pname = "myproject"; 22 | version = "0.1.0.0"; 23 | src = if pkgs.lib.inNixShell then null else ./.; 24 | isLibrary = false; 25 | isExecutable = true; 26 | executableHaskellDepends = [ 27 | base deepseq ghcjs-base react-hs react-native-hs text time transformers containers network-uri 28 | ]; 29 | buildDepends = [pkgs.haskellPackages.cabal-install] ++ 30 | (if compiler == "default" 31 | then with pkgs.haskellPackages; [nodejs hlint stack intero hasktags pointfree hdevtools stylish-haskell hindent (hoogle.override { process-extras = pkgs.haskell.lib.dontCheck process-extras; }) (apply-refact.override { ghc-exactprint = pkgs.haskell.lib.dontCheck ghc-exactprint; })] 32 | else []); 33 | license = stdenv.lib.licenses.mit; 34 | }; 35 | 36 | ghcjsbase = if compiler == "default" 37 | then haskellPackages.ghcjs-base-stub 38 | else haskellPackages.ghcjs-base; 39 | 40 | # my fork, until it gets to Hackage 41 | react-hs-forked = { fetchgit, stdenv, mkDerivation, 42 | aeson, base, bytestring, ghcjs-base, mtl, string-conversions, 43 | template-haskell, text, time, unordered-containers 44 | }: 45 | mkDerivation { 46 | pname = "react-hs"; 47 | version = "0.1.1"; 48 | src = fetchgit { 49 | url = "https://github.com/jyrimatti/react-hs.git"; 50 | sha256 = "0s7c15pmfhlccr6qgl6jn6izbvnqchh739i0h0sx1yiaarqwmzwy"; 51 | rev = "9390f850861102e84e38514a577ce7f3b1aac23f"; 52 | }; 53 | postUnpack = "sourceRoot=$sourceRoot/react-hs"; 54 | libraryHaskellDepends = [ 55 | aeson base bytestring ghcjs-base mtl string-conversions 56 | template-haskell text time unordered-containers 57 | ]; 58 | homepage = "https://github.com/jyrimatti/react-hs"; 59 | description = "A binding to React based on the Flux application architecture for GHCJS"; 60 | license = stdenv.lib.licenses.bsd3; 61 | }; 62 | 63 | react-native-hs-git = { fetchgit, mkDerivation, base, deepseq, ghcjs-base, react-hs, stdenv, nodejs, 64 | text, time, transformers, containers, network-uri 65 | }: 66 | mkDerivation { 67 | pname = "react-native-hs"; 68 | version = "0.1.1"; 69 | src = fetchgit { 70 | url = "https://github.com/jyrimatti/react-native-hs.git"; 71 | sha256 = "0f6bzm072wxp47bxxyhf5vgz8yac7107prixga341bkxblzj56zy"; 72 | rev = "edbed40baa5391c907c42657f5365e62e4cc02ef"; 73 | }; 74 | libraryHaskellDepends = [ 75 | react-hs text time transformers containers network-uri 76 | ]; 77 | homepage = "https://github.com/jyrimatti/react-native-hs"; 78 | description = "React-native support for react-hs"; 79 | license = stdenv.lib.licenses.mit; 80 | }; 81 | 82 | react-native-hs-local = { mkDerivation, base, deepseq, ghcjs-base, react-hs, stdenv, nodejs, 83 | text, time, transformers, containers, network-uri 84 | }: 85 | mkDerivation { 86 | pname = "react-native-hs"; 87 | version = "0.1.1"; 88 | src = ../react-native-hs/.; 89 | libraryHaskellDepends = [ 90 | react-hs text time transformers containers network-uri 91 | ]; 92 | homepage = "https://github.com/jyrimatti/react-native-hs"; 93 | description = "React-native support for react-hs"; 94 | license = stdenv.lib.licenses.mit; 95 | }; 96 | 97 | react-hs = haskellPackages.callPackage react-hs-forked { ghcjs-base = ghcjsbase; }; 98 | 99 | #react-native-hs = haskellPackages.callPackage react-native-hs-local { react-hs = react-hs; ghcjs-base = ghcjsbase; }; 100 | react-native-hs = haskellPackages.callPackage react-native-hs-git { react-hs = react-hs; ghcjs-base = ghcjsbase; }; 101 | 102 | drv = haskellPackages.callPackage myproject { react-hs = react-hs; react-native-hs = react-native-hs; ghcjs-base = ghcjsbase; }; 103 | 104 | in 105 | 106 | if pkgs.lib.inNixShell then drv.env else drv 107 | -------------------------------------------------------------------------------- /init.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell -i bash -p nix bash cacert 3 | set -eux 4 | source ./nix-shell-init.sh 5 | 6 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" 7 | 8 | reactNativeVersion=$(cat files/package.json | grep '"react-native":\s*"[0-9]' | cut -d '"' -f4) 9 | reactNativeMacosVersion=$(cat files/package.json | grep '"react-native-macos":\s*"[0-9]' | cut -d '"' -f4) 10 | buildToolsVersion=$(nix-store --query --references $(nix-instantiate '' -A androidsdk_9_0) | grep 'build-tools' | sed 's/.*build-tools-\([^.]*\).*.drv/\1/') 11 | 12 | # install react-native-cli and react-native-macos-cli 13 | mkdir rnproject 14 | cp -R files/. rnproject/ 15 | 16 | # init ios/android/macos project 17 | nix-shell -p nodejs-10_x yarn --run "cd rnproject && yarn add react-native-macos-cli" 18 | nix-shell -p nodejs-10_x yarn python2 --run "echo yes | node ./rnproject/node_modules/react-native-macos-cli/index.js init rnproject --version=$reactNativeMacosVersion && rm rnproject/.gitignore" 19 | nix-shell -p nodejs-10_x yarn python2 --run "cd rnproject && yarn add react-native-cli" 20 | nix-shell -p nodejs-10_x yarn python2 --run "echo yes | node ./rnproject/node_modules/react-native-cli/index.js init rnproject --version=$reactNativeVersion" 21 | 22 | mkdir rnproject/ios/build 23 | mkdir rnproject/ios/build/Index 24 | mkdir rnproject/ios/build/Index/DataStore 25 | 26 | # Android package signing 27 | echo "MYAPP_RELEASE_STORE_FILE=my-release-key.keystore" >> rnproject/android/gradle.properties 28 | echo "MYAPP_RELEASE_KEY_ALIAS=my-key-alias" >> rnproject/android/gradle.properties 29 | echo "MYAPP_RELEASE_STORE_PASSWORD=foobar" >> rnproject/android/gradle.properties 30 | echo "MYAPP_RELEASE_KEY_PASSWORD=foobar" >> rnproject/android/gradle.properties 31 | sed -i "s/defaultConfig {/signingConfigs {release {storeFile file(MYAPP_RELEASE_STORE_FILE); storePassword MYAPP_RELEASE_STORE_PASSWORD;keyAlias MYAPP_RELEASE_KEY_ALIAS;keyPassword MYAPP_RELEASE_KEY_PASSWORD}}; buildTypes { release { signingConfig signingConfigs.release }}; defaultConfig {/g" rnproject/android/app/build.gradle 32 | sed -i "s/minifyEnabled/signingConfig signingConfigs.release; minifyEnabled/g" rnproject/android/app/build.gradle 33 | 34 | sed -i "s/^android [{]/android { adbOptions.timeOutInMs = 8*60*1000; com.android.ddmlib.DdmPreferences.setTimeOut(8*60*1000)/" rnproject/android/app/build.gradle 35 | 36 | # change project buildTools to that available from nixpkgs 37 | sed -i "s/buildToolsVersion \"[^\"]*\"/buildToolsVersion \"$buildToolsVersion\"/" rnproject/android/app/build.gradle 38 | 39 | # update minsdkversion if too old 40 | sed -i "s/minSdkVersion = 16/minSdkVersion = 17/g" rnproject/android/build.gradle 41 | 42 | # androidsdk wants license files, so we need to use a mutable copy of the sdk... 43 | rm -R rnproject/android/androidsdk 44 | nix-shell -p jre8 "(androidenv.composeAndroidPackages { platformVersions = [\"$buildToolsVersion\"]; abiVersions = [\"x86\" \"x86_64\"]; includeNDK = true; }).androidsdk" which --run "cd rnproject/android;\ 45 | nix-store --dump \$(which android | xargs dirname | xargs dirname) > androidsdk.nar;\ 46 | nix-store --restore androidsdk < androidsdk.nar && rm androidsdk.nar" 47 | 48 | # copy platforms from behind symplinks since the AVD refers to these locations 49 | for plat in rnproject/android/androidsdk/libexec/android-sdk/platforms/* 50 | do 51 | mkdir $plat'_' 52 | cp -R $plat/* $plat'_'/ 53 | rm -R $plat 54 | mv $plat'_' $plat 55 | chmod -R u+rw $plat 56 | done 57 | 58 | # node needs more memory: 59 | sed -i "s/^project.ext.react = \[/project.ext.react = \[ nodeExecutableAndArgs: \['node', '--max-old-space-size=4096'],/g" rnproject/android/app/build.gradle 60 | sed -i "s/export NODE_BINARY=node/export NODE_BINARY='node --max-old-space-size=4096'/g" rnproject/macos/rnproject.xcodeproj/project.pbxproj 61 | 62 | cp -fR files/. rnproject/ 63 | nix-shell -p nodejs-10_x yarn --run "cd rnproject && yarn install" 64 | 65 | # macos hack 66 | sed -i "s/const StatusBarManager = require('NativeModules').StatusBarManager;/const StatusBarManager = require('NativeModules').StatusBarManager;if (!StatusBarManager) StatusBarManager = { 'HEIGHT': -1 };/g" rnproject/node_modules/react-native-macos/Libraries/Components/StatusBar/StatusBar.js 67 | 68 | # init Windows project 69 | # I don't know why on earth I need the sed... 70 | nix-shell -p nodejs-10_x yarn python2 pash --run "cd rnproject && yarn add rnpm-plugin-windows --dev && sed -i \"s/this.flags = flags;/flags = flags || ''; this.flags = flags;/\" ./node_modules/commander/index.js && ./node_modules/.bin/rnpm windows" 71 | 72 | # 10.0.2.2 is a VirtualBox alias for localhost 73 | sed -i "s/localhost:8081/10.0.2.2:8081/" rnproject/node_modules/react-native-windows/ReactWindows/ReactNative.Shared/DevSupport/DevServerHelper.cs 74 | # change VS project output path outside of the network share. 75 | sed -r 's/()([^<]*)/\1c:\\vagrant-build\\\2/g' rnproject/windows/rnproject/rnproject.csproj > rnproject/windows/rnproject/rnproject.csproj.temp && mv rnproject/windows/rnproject/rnproject.csproj.temp rnproject/windows/rnproject/rnproject.csproj 76 | # enable private network to access react-packager 77 | sed -i 's/<\/Capabilities>/<\/Capabilities>/' rnproject/windows/rnproject/Package.appxmanifest 78 | 79 | # ignore ghcjs-generated files from transform since it fails in babel for some reason 80 | #sed -i "s/function transform(src, filename, options) {/function transform(src, filename, options) { if (filename.indexOf('all.js') > -1) return { code: src };/" rnproject/node_modules/react-native-macos/packager/transformer.js 81 | 82 | sed -i "s/if (!sha1) {/if (!sha1) { return require('crypto').createHash('sha1').update(fs.readFileSync(resolvedPath)).digest('hex');/" rnproject/node_modules/react-native/node_modules/metro/src/node-haste/DependencyGraph.js 83 | 84 | # otherwise Android emulator fails with "Strict mode does not allow function declarations in a lexically nested statement" 85 | find ./rnproject/node_modules/react-native/ -type f -exec sed -i 's/use strict//g' {} \; 86 | 87 | # fix finding ios simulators 88 | sed -i "s/version\.startsWith/version.includes/g" rnproject/node_modules/react-native/local-cli/runIOS/findMatchingSimulator.js 89 | 90 | ./init-addons.sh 91 | -------------------------------------------------------------------------------- /files/ghcjsiClient.js: -------------------------------------------------------------------------------- 1 | // copied with modifications from https://github.com/artemyarulin/ghcjs-repl-react-native/blob/master/replProject/ghcjsRNClient.js 2 | if (!window.navigator) 3 | window.navigator = {}; 4 | if (!window.navigator.userAgent) 5 | window.navigator.userAgent = "react-native"; 6 | 7 | var {btoa,atob} = require('Base64') 8 | window.btoa = btoa 9 | window.atob = atob 10 | 11 | var io = require("./node_modules/socket.io-client/socket.io"); 12 | 13 | var h$GHCJSiSocket = io('ws://localhost:8080',{transports: ['websocket']}); 14 | var global = window; 15 | 16 | var h$GHCJSi = { socket: io('ws://localhost:8080',{transports: ['websocket']}) 17 | , out: function(dat) { 18 | h$GHCJSi.socket.emit('out', dat); 19 | } 20 | , msg: function(msgType, msgPayload) { 21 | if(!msgPayload) msgPayload = new ArrayBuffer(0); 22 | h$GHCJSi.socket.emit('msg', { type: msgType, payload: msgPayload }); 23 | } 24 | , current: null 25 | , loadedSymbols: {} 26 | , done: function(thread) { 27 | h$GHCJSi.msg(0); 28 | h$GHCJSi.current = null; 29 | } 30 | }; 31 | 32 | h$GHCJSi.socket.on('msg', function(msg) { 33 | h$processMessage(msg.type, msg.payload); 34 | }); 35 | 36 | function h$processMessage(msgType, msgPayload) { 37 | // console.log("processMessage: " + msgType); 38 | switch(msgType) { 39 | case 0: // load initial code/rts and init 40 | h$loadInitialCode(h$decodeUtf8(h$wrapBuffer(msgPayload))); 41 | h$GHCJSi.msg(0); 42 | break; 43 | case 1: // load code 44 | h$loadCodeStr(h$decodeUtf8(h$wrapBuffer(msgPayload))); 45 | h$GHCJSi.msg(0); 46 | break; 47 | case 2: // run action 48 | var symb = h$decodeUtf8(h$wrapBuffer(msgPayload)); 49 | h$GHCJSi.current = h$main(h$GHCJSi.loadedSymbols[symb]); 50 | break; 51 | case 3: // abort 52 | if(h$GHCJSi.current) 53 | // fixme should probably be wrapped with Exception dict? 54 | h$killThread( h$GHCJSi.current 55 | , h$baseZCControlziExceptionziBasezinonTermination); 56 | break; 57 | default: 58 | throw new Error("unknown message type: " + msgType); 59 | } 60 | } 61 | 62 | function h$loadInitialCode(code) { 63 | h$loadCodeStr(code, true); 64 | 65 | // don't allow Haskell to read from stdin (fixme!) 66 | h$base_stdin_fd.read = function(fd, fdo, buf, buf_offset, n, c) { c(0); } 67 | 68 | // redirect Haskell's stderr to stdout since we use stderr to communicate (fixme!) 69 | h$base_stdout_fd.write = function(fd, fdo, buf, buf_offset, n, c) { 70 | h$GHCJSi.out(buf.buf.slice(buf_offset, buf_offset+n)); 71 | c(n); 72 | } 73 | h$base_stderr_fd.write = h$base_stdout_fd.write; 74 | } 75 | 76 | function h$loadCodeStr(str) { 77 | eval.call(null, str); 78 | } 79 | 80 | ///////////////////////////////////////////////////////////////////////// 81 | // UTF-8 functions from shims/src/string.js and shims/src/mem.js 82 | ///////////////////////////////////////////////////////////////////////// 83 | 84 | function h$wrapBuffer(buf, unalignedOk, offset, length) { 85 | if(!unalignedOk && offset && offset % 8 !== 0) { 86 | throw ("h$wrapBuffer: offset not aligned:" + offset); 87 | } 88 | if(!buf || !(buf instanceof ArrayBuffer)) 89 | throw "h$wrapBuffer: not an ArrayBuffer" 90 | if(!offset) { offset = 0; } 91 | if(!length || length < 0) { length = buf.byteLength - offset; } 92 | return { buf: buf 93 | , len: length 94 | , i3: (offset%4) ? null : new Int32Array(buf, offset, length >> 2) 95 | , u8: new Uint8Array(buf, offset, length) 96 | , u1: (offset%2) ? null : new Uint16Array(buf, offset, length >> 1) 97 | , f3: (offset%4) ? null : new Float32Array(buf, offset, length >> 2) 98 | , f6: (offset%8) ? null : new Float64Array(buf, offset, length >> 3) 99 | , dv: new DataView(buf, offset, length) 100 | }; 101 | } 102 | 103 | // decode a buffer with Utf8 chars to a JS string 104 | // invalid characters are ignored 105 | function h$decodeUtf8(v,n0,start) { 106 | var n = n0 || v.len; 107 | var arr = []; 108 | var i = start || 0; 109 | var code; 110 | var u8 = v.u8; 111 | while(i < n) { 112 | var c = u8[i]; 113 | while((c & 0xC0) === 0x80) { 114 | c = u8[++i]; 115 | } 116 | if((c & 0x80) === 0) { 117 | code = (c & 0x7F); 118 | i++; 119 | } else if((c & 0xE0) === 0xC0) { 120 | code = ( ((c & 0x1F) << 6) 121 | | (u8[i+1] & 0x3F) 122 | ); 123 | i+=2; 124 | } else if((c & 0xF0) === 0xE0) { 125 | code = ( ((c & 0x0F) << 12) 126 | | ((u8[i+1] & 0x3F) << 6) 127 | | (u8[i+2] & 0x3F) 128 | ); 129 | i+=3; 130 | } else if ((c & 0xF8) === 0xF0) { 131 | code = ( ((c & 0x07) << 18) 132 | | ((u8[i+1] & 0x3F) << 12) 133 | | ((u8[i+2] & 0x3F) << 6) 134 | | (u8[i+3] & 0x3F) 135 | ); 136 | i+=4; 137 | } else if((c & 0xFC) === 0xF8) { 138 | code = ( ((c & 0x03) << 24) 139 | | ((u8[i+1] & 0x3F) << 18) 140 | | ((u8[i+2] & 0x3F) << 12) 141 | | ((u8[i+3] & 0x3F) << 6) 142 | | (u8[i+4] & 0x3F) 143 | ); 144 | i+=5; 145 | } else { 146 | code = ( ((c & 0x01) << 30) 147 | | ((u8[i+1] & 0x3F) << 24) 148 | | ((u8[i+2] & 0x3F) << 18) 149 | | ((u8[i+3] & 0x3F) << 12) 150 | | ((u8[i+4] & 0x3F) << 6) 151 | | (u8[i+5] & 0x3F) 152 | ); 153 | i+=6; 154 | } 155 | if(code > 0xFFFF) { 156 | var offset = code - 0x10000; 157 | arr.push(0xD800 + (offset >> 10), 0xDC00 + (offset & 0x3FF)); 158 | } else { 159 | arr.push(code); 160 | } 161 | } 162 | return h$charCodeArrayToString(arr); 163 | } 164 | 165 | function h$charCodeArrayToString(arr) { 166 | if(arr.length <= 10000) { 167 | return String.fromCharCode.apply(this, arr); 168 | } 169 | var r = ''; 170 | for(var i=0;i