├── .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 |
--------------------------------------------------------------------------------