Skip to content

Commit 5a74784

Browse files
committed
Use Payload with EventSource
This removes manual handling of `JSVal` when working with `EventSource` (Server-sent events). Note, Payload is reused from `WebSocket`, but only the `TEXT` / `JSON` cases are valid. - [x] Add callbacks to `eventSourceConnect` to handle `Payload` - [x] Error handling now operates on `MisoString`
1 parent ddf1a39 commit 5a74784

File tree

6 files changed

+69
-38
lines changed

6 files changed

+69
-38
lines changed

js/miso.js

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -101,18 +101,27 @@ function websocketSend(socket, message) {
101101
socket.send(message);
102102
}
103103
}
104-
function eventSourceConnect(url, onOpen, onMessage, onError) {
105-
let eventSource = new EventSource(url);
106-
eventSource.onopen = function() {
107-
onOpen();
108-
};
109-
eventSource.onerror = function(error) {
110-
onError(error);
111-
};
112-
eventSource.onmessage = function(msg) {
113-
onMessage(msg.data);
114-
};
115-
return eventSource;
104+
function eventSourceConnect(url, onOpen, onMessageText, onMessageJSON, onError) {
105+
try {
106+
let eventSource = new EventSource(url);
107+
eventSource.onopen = function() {
108+
onOpen();
109+
};
110+
eventSource.onerror = function() {
111+
onError("EventSource error received");
112+
};
113+
eventSource.onmessage = function(msg) {
114+
try {
115+
const json = JSON.parse(msg.data);
116+
onMessageJSON(json);
117+
} catch (err) {
118+
onMessageText(msg.data);
119+
}
120+
};
121+
return eventSource;
122+
} catch (err) {
123+
onError(err.message);
124+
}
116125
}
117126
function eventSourceClose(eventSource) {
118127
if (eventSource) {

js/miso.prod.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Miso/EventSource.hs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,25 @@ module Miso.EventSource
2222
-- *** Types
2323
, EventSource (..)
2424
, URL
25+
-- *** Re-exports
26+
, Payload (..)
2527
) where
2628
-----------------------------------------------------------------------------
29+
import Data.Aeson
30+
-----------------------------------------------------------------------------
2731
import Miso.Effect
2832
import Miso.Runtime
29-
-----------------------------------------------------------------------------
30-
import Language.Javascript.JSaddle
33+
import Miso.String
3134
-----------------------------------------------------------------------------
3235
-- | <https://developer.mozilla.org/en-US/docs/Web/API/EventSource>
3336
connect
34-
:: URL
37+
:: FromJSON value
38+
=> URL
3539
-> (EventSource -> action)
3640
-- ^ onOpen
37-
-> (JSVal -> action)
41+
-> (Payload value -> action)
3842
-- ^ onMessage
39-
-> (JSVal -> action)
43+
-> (MisoString -> action)
4044
-- ^ onError
4145
-> Effect parent model action
4246
connect = eventSourceConnect

src/Miso/FFI/Internal.hs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -795,13 +795,15 @@ eventSourceConnect
795795
-> JSM ()
796796
-> (JSVal -> JSM ())
797797
-> (JSVal -> JSM ())
798+
-> (JSVal -> JSM ())
798799
-> JSM JSVal
799-
eventSourceConnect url onOpen onMessage onError = do
800+
eventSourceConnect url onOpen onMessageText onMessageJSON onError = do
800801
onOpen_ <- asyncCallback onOpen
801-
onMessage_ <- asyncCallback1 onMessage
802+
onMessageText_ <- asyncCallback1 onMessageText
803+
onMessageJSON_ <- asyncCallback1 onMessageJSON
802804
onError_ <- asyncCallback1 onError
803805
jsg "miso" # "eventSourceConnect" $
804-
(url, onOpen_, onMessage_, onError_)
806+
(url, onOpen_, onMessageText_, onMessageJSON_, onError_)
805807
-----------------------------------------------------------------------------
806808
eventSourceClose :: JSVal -> JSM ()
807809
eventSourceClose eventSource = void $ do

src/Miso/Runtime.hs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,13 +1292,14 @@ eventSourceConnectionIds = unsafePerformIO (newIORef (0 :: Int))
12921292
-----------------------------------------------------------------------------
12931293
-- | <https://developer.mozilla.org/en-US/docs/Web/API/EventSource/EventSource>
12941294
eventSourceConnect
1295-
:: URL
1295+
:: FromJSON value
1296+
=> URL
12961297
-- ^ EventSource URL
12971298
-> (EventSource -> action)
12981299
-- ^ onOpen
1299-
-> (JSVal -> action)
1300+
-> (Payload value -> action)
13001301
-- ^ onMessage
1301-
-> (JSVal -> action)
1302+
-> (MisoString -> action)
13021303
-- ^ onError
13031304
-> Effect parent model action
13041305
eventSourceConnect url onOpen onMessage onError = do
@@ -1307,8 +1308,13 @@ eventSourceConnect url onOpen onMessage onError = do
13071308
eventSourceId <- freshEventSource
13081309
socket <- FFI.eventSourceConnect url
13091310
(sink $ onOpen eventSourceId)
1310-
(sink . onMessage)
1311-
(sink . onError)
1311+
(\e -> do string <- fromJSValUnchecked e
1312+
sink (onMessage (TEXT string)))
1313+
(\e -> do value <- fromJSValUnchecked e
1314+
case fromJSON value of
1315+
Error errMsg -> sink (onError (ms errMsg))
1316+
Success json_ -> sink $ onMessage (JSON json_))
1317+
(sink . onError <=< fromJSValUnchecked)
13121318
insertEventSource _componentId eventSourceId socket
13131319
where
13141320
insertEventSource :: ComponentId -> EventSource -> Socket -> JSM ()

ts/miso/util.ts

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -157,20 +157,30 @@ export function websocketSend (
157157
export function eventSourceConnect (
158158
url: string,
159159
onOpen,
160-
onMessage,
160+
onMessageText,
161+
onMessageJSON,
161162
onError,
162163
): EventSource {
163-
let eventSource = new EventSource(url);
164-
eventSource.onopen = function () {
165-
onOpen();
166-
};
167-
eventSource.onerror = function (error) {
168-
onError(error);
169-
};
170-
eventSource.onmessage = function (msg) {
171-
onMessage(msg.data);
172-
};
173-
return eventSource;
164+
try {
165+
let eventSource = new EventSource(url);
166+
eventSource.onopen = function () {
167+
onOpen();
168+
};
169+
eventSource.onerror = function () {
170+
onError('EventSource error received');
171+
};
172+
eventSource.onmessage = function (msg) {
173+
try {
174+
const json = JSON.parse (msg.data);
175+
onMessageJSON(json);
176+
} catch (err) {
177+
onMessageText(msg.data)
178+
}
179+
};
180+
return eventSource;
181+
} catch (err) {
182+
onError (err.message);
183+
}
174184
}
175185

176186
export function eventSourceClose (

0 commit comments

Comments
 (0)