Skip to content

Commit d4b6b65

Browse files
authored
Refactor with React integration (#9)
1 parent d1d7551 commit d4b6b65

File tree

19 files changed

+5206
-318
lines changed

19 files changed

+5206
-318
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@
88
/.purs*
99
/.psa*
1010
/.spago
11+
/.cache
12+
/dist

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@
55
"main": "index.js",
66
"scripts": {
77
"build": "spago build",
8+
"serve": "spago --config spago.test.dhall build && parcel serve test/index.html",
89
"test": "spago --config spago.test.dhall test"
910
},
1011
"author": "",
1112
"license": "ISC",
1213
"devDependencies": {
13-
"purescript": "^0.13.6",
14+
"parcel-bundler": "^1.12.4",
15+
"purescript": "^0.13.8",
1416
"purescript-psa": "^0.7.3",
1517
"purty": "^6.2.0",
16-
"spago": "^0.15.2"
18+
"react": "^16.13.1",
19+
"react-dom": "^16.13.1",
20+
"spago": "^0.15.3"
1721
}
1822
}

packages.dhall

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ let additions =
119119

120120

121121
let upstream =
122-
https://github.com/purescript/package-sets/releases/download/psc-0.13.6-20200507/packages.dhall sha256:9c1e8951e721b79de1de551f31ecb5a339e82bbd43300eb5ccfb1bf8cf7bbd62
122+
https://github.com/purescript/package-sets/releases/download/psc-0.13.8-20200615/packages.dhall sha256:5d0cfad9408c84db0a3fdcea2d708f9ed8f64297e164dc57a7cf6328706df93a
123123

124124
let overrides = {=}
125125

spago.dhall

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ You can edit this file as you like.
55
{ name = "wire"
66
, dependencies =
77
[ "arrays"
8-
, "avar"
98
, "filterable"
10-
, "profunctor"
9+
, "foreign-object"
10+
, "free"
11+
, "freet"
12+
, "react-basic-hooks"
1113
, "refs"
1214
, "unsafe-reference"
1315
]

src/Wire/Event.purs

Lines changed: 66 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import Prelude
44
import Control.Alt (class Alt, alt)
55
import Control.Alternative (class Alternative, class Plus, empty)
66
import Control.Apply (lift2)
7-
import Control.Monad.Rec.Class (Step(..), tailRecM)
7+
import Control.Monad.Rec.Class (class MonadRec, Step(..), tailRecM)
88
import Data.Array as Array
9-
import Data.Either (Either(..), either, hush)
9+
import Data.Either (either, hush)
1010
import Data.Filterable (class Compactable, class Filterable, filterMap, partitionMap)
1111
import Data.Foldable (class Foldable, for_, sequence_, traverse_)
1212
import Data.Maybe (Maybe(..), fromJust, isJust)
@@ -17,47 +17,45 @@ import Effect.Class (liftEffect)
1717
import Effect.Ref as Ref
1818
import Partial.Unsafe (unsafePartial)
1919
import Unsafe.Reference (unsafeRefEq)
20-
import Wire.Event.Queue as Queue
2120

2221
newtype Event a
23-
= Event (Subscriber a -> Effect Canceler)
22+
= Event ((a -> Effect Unit) -> Effect (Effect Unit))
2423

25-
type Subscriber a
26-
= a -> Effect Unit
27-
28-
type Canceler
29-
= Effect Unit
30-
31-
create :: forall a. Effect { event :: Event a, push :: a -> Effect Unit, cancel :: Effect Unit }
24+
create :: forall a. Effect { event :: Event a, push :: a -> Effect Unit }
3225
create = do
3326
subscribers <- Ref.new []
34-
queue <- Queue.create \a -> Ref.read subscribers >>= traverse_ \k -> k a
3527
let
3628
event =
37-
Event \emit -> do
29+
Event \notify -> do
3830
unsubscribing <- Ref.new false
3931
let
40-
subscriber = \a -> unlessM (Ref.read unsubscribing) do emit a
32+
isUnsubscribing = Ref.read unsubscribing
33+
34+
subscriber = \a -> unlessM isUnsubscribing $ notify a
4135
Ref.modify_ (flip Array.snoc subscriber) subscribers
4236
pure do
4337
Ref.write true unsubscribing
4438
Ref.modify_ (Array.deleteBy unsafeRefEq subscriber) subscribers
45-
pure { event, push: queue.push, cancel: queue.kill }
4639

47-
makeEvent :: forall a. (Subscriber a -> Effect Canceler) -> Event a
40+
push a = Ref.read subscribers >>= traverse_ \notify -> notify a
41+
pure { event, push }
42+
43+
makeEvent :: forall a. ((a -> Effect Unit) -> Effect (Effect Unit)) -> Event a
4844
makeEvent = Event
4945

50-
subscribe :: forall a. Event a -> Subscriber a -> Effect Canceler
51-
subscribe (Event event) = event
46+
subscribe :: forall a b. Event a -> (a -> Effect b) -> Effect (Effect Unit)
47+
subscribe (Event event) = event <<< (void <<< _)
5248

5349
filter :: forall a. (a -> Boolean) -> Event a -> Event a
54-
filter f (Event event) = Event \emit -> event \a -> when (f a) (emit a)
50+
filter pred (Event event) = Event \notify -> event \a -> if pred a then notify a else pure unit
5551

5652
fold :: forall a b. (b -> a -> b) -> b -> Event a -> Event b
5753
fold f b (Event event) =
58-
Event \emit -> do
54+
Event \notify -> do
5955
accum <- Ref.new b
60-
event \a -> Ref.modify (flip f a) accum >>= emit
56+
event \a -> do
57+
value <- Ref.modify (flip f a) accum
58+
notify value
6159

6260
share :: forall a. Event a -> Effect (Event a)
6361
share source = do
@@ -66,33 +64,33 @@ share source = do
6664
shared <- create
6765
let
6866
incrementCount = do
69-
count <- liftEffect do Ref.modify (_ + 1) subscriberCount
67+
count <- Ref.modify (_ + 1) subscriberCount
7068
when (count == 1) do
71-
cancel <- subscribe source do liftEffect <<< shared.push
72-
liftEffect do Ref.write (Just cancel) cancelSource
69+
cancel <- subscribe source shared.push
70+
Ref.write (Just cancel) cancelSource
7371

7472
decrementCount = do
75-
count <- liftEffect do Ref.modify (_ - 1) subscriberCount
73+
count <- Ref.modify (_ - 1) subscriberCount
7674
when (count == 0) do
77-
liftEffect (Ref.read cancelSource) >>= sequence_
78-
liftEffect do Ref.write Nothing cancelSource
75+
Ref.read cancelSource >>= sequence_
76+
Ref.write Nothing cancelSource
7977

8078
event =
81-
Event \emit -> do
79+
Event \notify -> do
8280
incrementCount
83-
cancel <- subscribe shared.event emit
84-
pure do cancel *> decrementCount
81+
cancel <- subscribe shared.event notify
82+
pure $ cancel *> decrementCount
8583
pure event
8684

8785
distinct :: forall a. Eq a => Event a -> Event a
8886
distinct (Event event) =
89-
Event \emit -> do
87+
Event \notify -> do
9088
latest <- Ref.new Nothing
9189
event \a -> do
9290
b <- Ref.read latest
9391
when (pure a /= b) do
9492
Ref.write (pure a) latest
95-
emit a
93+
notify a
9694

9795
bufferUntil :: forall b a. Event b -> Event a -> Event (Array a)
9896
bufferUntil flush source =
@@ -107,31 +105,33 @@ bufferUntil flush source =
107105

108106
fromFoldable :: forall a f. Foldable f => f a -> Event a
109107
fromFoldable xs =
110-
Event \emit -> do
108+
Event \notify -> do
111109
fiber <-
112-
Aff.launchAff do
113-
for_ xs \x -> do
114-
liftEffect do emit x
115-
Aff.delay (Milliseconds 0.0)
116-
pure do
117-
Aff.launchAff_ do Aff.killFiber (Aff.error "canceled") fiber
110+
Aff.launchAff
111+
$ for_ xs \x -> do
112+
liftEffect $ notify x
113+
Aff.delay (Milliseconds 0.0)
114+
pure
115+
$ Aff.launchAff_
116+
$ Aff.killFiber (Aff.error "canceled") fiber
118117

119118
range :: Int -> Int -> Event Int
120119
range start end =
121-
Event \emit -> do
120+
Event \notify -> do
122121
let
123122
go pos
124123
| pos /= end = do
125-
liftEffect do emit pos
124+
liftEffect $ notify pos
126125
Aff.delay (Milliseconds 0.0)
127126
pure (Loop (pos + step))
128127

129128
go _ = do
130-
liftEffect do emit end
129+
liftEffect $ notify end
131130
pure (Done unit)
132-
fiber <- Aff.launchAff do tailRecM go start
133-
pure do
134-
Aff.launchAff_ do Aff.killFiber (Aff.error "canceled") fiber
131+
fiber <- Aff.launchAff $ tailRecM go start
132+
pure
133+
$ Aff.launchAff_
134+
$ Aff.killFiber (Aff.error "canceled") fiber
135135
where
136136
step = if start < end then 1 else -1
137137

@@ -142,55 +142,49 @@ times n
142142
times _ = empty
143143

144144
instance functorEvent :: Functor Event where
145-
map f (Event event) =
146-
Event \emit -> do
147-
queue <- Queue.create (emit <<< f)
148-
cancel <- event queue.push
149-
pure do
150-
cancel
151-
queue.kill
145+
map f (Event event) = Event \notify -> event (notify <<< f)
152146

153147
instance applyEvent :: Apply Event where
154-
apply eventF eventA =
155-
alt (Left <$> eventF) (Right <$> eventA)
156-
# fold
157-
( \{ left, right } -> case _ of
158-
Left l -> { left: Just l, right }
159-
Right r -> { left, right: Just r }
160-
)
161-
{ left: Nothing, right: Nothing }
162-
# filterMap (\{ left, right } -> apply left right)
148+
apply = ap
163149

164150
instance applicativeEvent :: Applicative Event where
165-
pure a = Event \emit -> emit a *> mempty
151+
pure a = Event \notify -> notify a *> mempty
166152

167153
instance bindEvent :: Bind Event where
168154
bind (Event outer) f =
169-
Event \emit -> do
155+
Event \notify -> do
170156
cancelInner <- Ref.new Nothing
171157
cancelOuter <-
172-
outer \a ->
173-
liftEffect do
174-
Ref.read cancelInner >>= sequence_
175-
cancel <- subscribe (f a) emit
176-
Ref.write (Just cancel) cancelInner
158+
outer \a -> do
159+
Ref.read cancelInner >>= sequence_
160+
c <- subscribe (f a) notify
161+
Ref.write (Just c) cancelInner
177162
pure do
178163
Ref.read cancelInner >>= sequence_
179164
cancelOuter
180165

181166
instance monadEvent :: Monad Event
182167

168+
instance monadRecEventMonadRec Event where
169+
tailRecM k = go
170+
where
171+
go a = do
172+
res ← k a
173+
case res of
174+
Done r → pure r
175+
Loop b → go b
176+
183177
instance plusEvent :: Plus Event where
184178
empty = Event \_ -> mempty
185179

186180
instance alternativeEvent :: Alternative Event
187181

188182
instance altEvent :: Alt Event where
189183
alt (Event event1) (Event event2) =
190-
Event \emit -> do
191-
cancel1 <- event1 emit
192-
cancel2 <- event2 emit
193-
pure do cancel1 *> cancel2
184+
Event \notify -> do
185+
cancel1 <- event1 notify
186+
cancel2 <- event2 notify
187+
pure $ cancel1 *> cancel2
194188

195189
instance semigroupEvent :: Semigroup a => Semigroup (Event a) where
196190
append = lift2 append

src/Wire/Event/Queue.purs

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/Wire/Event/Time.purs

Lines changed: 0 additions & 41 deletions
This file was deleted.

0 commit comments

Comments
 (0)