├── .gitignore ├── README.md ├── bower.json ├── index.html ├── package.json ├── src ├── Cycle.js ├── Cycle.purs ├── Cycle │ ├── Dom.js │ └── Dom.purs └── Main.purs └── test └── Main.purs /.gitignore: -------------------------------------------------------------------------------- 1 | /bower_components/ 2 | /node_modules/ 3 | /output/ 4 | /.psci* 5 | /src/.webpack.js 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # purescript-cycle 2 | 3 | Bindings for Cycle.js. 4 | Very straightforward, quite ill-typed. 5 | 6 | See `src/Main.purs` for simple example (yeah, it's a counter). 7 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "purescript-cycle", 3 | "moduleType": [ 4 | "node" 5 | ], 6 | "ignore": [ 7 | "**/.*", 8 | "node_modules", 9 | "bower_components", 10 | "output" 11 | ], 12 | "dependencies": { 13 | "purescript-rx": "~0.8.1", 14 | "purescript-halogen": "~0.5.8" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Cycle.js example - Counter 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "purescript-cycle", 3 | "description": "Purescript bindings for cycle.js", 4 | "main": "index.js", 5 | "directories": { 6 | "test": "test" 7 | }, 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "author": "Konstantin Zudov ", 12 | "license": "BSD3", 13 | "dependencies": { 14 | "@cycle/core": "6.0.0-rc2", 15 | "@cycle/dom": "8.0.0-rc4", 16 | "rx": "^4.0.7", 17 | "virtual-dom": "^2.1.1" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Cycle.js: -------------------------------------------------------------------------------- 1 | // module Cycle 2 | const Cycle = require('@cycle/core'); 3 | 4 | exports.run = 5 | function(main) { 6 | return function(drivers) { 7 | return function() { 8 | Cycle.run(main, drivers); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Cycle.purs: -------------------------------------------------------------------------------- 1 | module Cycle where 2 | 3 | import Prelude (Unit()) 4 | 5 | import Control.Monad.Eff (Eff()) 6 | 7 | foreign import run :: forall inputs outputs drivers eff. 8 | ({ | inputs } -> { | outputs }) -> { | drivers } -> Eff eff Unit 9 | -------------------------------------------------------------------------------- /src/Cycle/Dom.js: -------------------------------------------------------------------------------- 1 | // module Cycle.Dom 2 | const CycleDOM = require('@cycle/dom') 3 | 4 | exports.makeDomDriver = CycleDOM.makeDOMDriver 5 | 6 | exports.select = 7 | function(selector) { 8 | return function(driver) { 9 | return driver.select(selector); 10 | } 11 | } 12 | 13 | exports.events = 14 | function(eventType) { 15 | return function(elements) { 16 | return elements.events(eventType); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Cycle/Dom.purs: -------------------------------------------------------------------------------- 1 | module Cycle.Dom where 2 | 3 | import Prelude hiding (div) 4 | 5 | import Data.Void (Void()) 6 | import Data.Identity (Identity(), runIdentity) 7 | 8 | import DOM.Event.Types (Event()) 9 | import Rx.Observable (Observable()) 10 | 11 | import Halogen.Internal.VirtualDOM (VTree()) 12 | import Halogen.HTML.Core (HTML()) 13 | import Halogen.HTML.Renderer.VirtualDOM as Renderer 14 | 15 | type CycleHTML = HTML Void (Identity Unit) 16 | 17 | renderHTML :: CycleHTML -> VTree 18 | renderHTML = Renderer.renderHTML (pure <<< runIdentity) 19 | 20 | type DomDriver = VTree -> DomInput 21 | 22 | foreign import makeDomDriver :: String -> DomDriver 23 | 24 | foreign import data DomInput :: * 25 | foreign import data DomSelection :: * 26 | 27 | foreign import select :: String -> DomInput -> DomSelection 28 | foreign import events :: String -> DomSelection -> Observable Event 29 | -------------------------------------------------------------------------------- /src/Main.purs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Prelude 4 | 5 | import Cycle 6 | import Cycle.Dom 7 | import Rx.Observable 8 | 9 | import Halogen.HTML as H 10 | import Halogen.HTML.Properties as P 11 | 12 | import Halogen.Internal.VirtualDOM (VTree()) 13 | 14 | main = run app drivers 15 | 16 | app :: { dom :: DomInput } -> { dom :: Observable VTree } 17 | app requests = { dom: map (renderHTML <<< render) count } 18 | where 19 | clicks = requests.dom # select "#count" # events "click" 20 | count = clicks # map (const 1) 21 | # startWith 0 22 | # scan (+) 0 23 | render state = H.div_ 24 | [ H.button 25 | [ P.id_ "count" ] 26 | [ H.text "Click me" ] 27 | , H.div_ 28 | [ H.text (show state) ] 29 | ] 30 | 31 | drivers :: { dom :: DomDriver } 32 | drivers = { dom: makeDomDriver "#app" } 33 | -------------------------------------------------------------------------------- /test/Main.purs: -------------------------------------------------------------------------------- 1 | module Test.Main where 2 | 3 | import Control.Monad.Eff.Console 4 | 5 | main = do 6 | log "You should add some tests." 7 | --------------------------------------------------------------------------------