Skip to content

Commit bd5e9ce

Browse files
committed
Add selector to init funciton using somewhat existentials (Thanks Hayleigh!!)
1 parent 73d56ea commit bd5e9ce

File tree

7 files changed

+479
-102
lines changed

7 files changed

+479
-102
lines changed

examples/src/working_with_websockets/app/router.gleam

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import gleam/int
2+
import gleam/option
23
import wisp.{type Request, type Response}
34
import wisp/websocket
45

@@ -114,7 +115,7 @@ fn home_page() -> Response {
114115
fn websocket_handler(request: Request) -> Response {
115116
wisp.websocket(
116117
request,
117-
on_init: fn(_connection) { 0 },
118+
on_init: fn(_connection) { #(0, option.None) },
118119
on_message: fn(state, message, connection) {
119120
case message {
120121
websocket.Text(text) -> {
@@ -133,6 +134,7 @@ fn websocket_handler(request: Request) -> Response {
133134
}
134135
websocket.Closed -> websocket.Stop
135136
websocket.Shutdown -> websocket.Stop
137+
websocket.Custom(_) -> websocket.Stop
136138
}
137139
},
138140
on_close: fn(state) {

examples/test/working_with_websockets/app_test.gleam

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub fn websocket_text_echo_test() {
3030
let response = router.handle_request(request)
3131

3232
let assert wisp.WebSocket(upgrade) = response.body
33-
let handler = wisp.upgrade_to_websocket(upgrade)
33+
let handler = wisp.recover(upgrade)
3434
let assert Ok(ws) = simulate.create_websocket(handler)
3535

3636
// Send first text message
@@ -54,7 +54,7 @@ pub fn websocket_binary_echo_test() {
5454
let response = router.handle_request(request)
5555

5656
let assert wisp.WebSocket(upgrade) = response.body
57-
let handler = wisp.upgrade_to_websocket(upgrade)
57+
let handler = wisp.recover(upgrade)
5858
let assert Ok(ws) = simulate.create_websocket(handler)
5959

6060
// Send binary message
@@ -73,7 +73,7 @@ pub fn websocket_mixed_messages_test() {
7373
let response = router.handle_request(request)
7474

7575
let assert wisp.WebSocket(upgrade) = response.body
76-
let handler = wisp.upgrade_to_websocket(upgrade)
76+
let handler = wisp.recover(upgrade)
7777
let assert Ok(ws) = simulate.create_websocket(handler)
7878

7979
// Send text message
@@ -96,7 +96,7 @@ pub fn websocket_close_test() {
9696
let response = router.handle_request(request)
9797

9898
let assert wisp.WebSocket(upgrade) = response.body
99-
let handler = wisp.upgrade_to_websocket(upgrade)
99+
let handler = wisp.recover(upgrade)
100100
let assert Ok(ws) = simulate.create_websocket(handler)
101101

102102
// Send some messages
@@ -116,7 +116,7 @@ pub fn websocket_closed_ignores_messages_test() {
116116
let response = router.handle_request(request)
117117

118118
let assert wisp.WebSocket(upgrade) = response.body
119-
let handler = wisp.upgrade_to_websocket(upgrade)
119+
let handler = wisp.recover(upgrade)
120120
let assert Ok(ws) = simulate.create_websocket(handler)
121121

122122
// Send a message

src/wisp.gleam

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import gleam/dynamic.{type Dynamic}
99
import gleam/dynamic/decode
1010
import gleam/erlang/application
1111
import gleam/erlang/atom.{type Atom}
12+
import gleam/erlang/process
1213
import gleam/http.{type Method}
1314
import gleam/http/cookie
1415
import gleam/http/request.{type Request as HttpRequest}
@@ -75,12 +76,19 @@ pub type Body {
7576
WebSocket(WebSocketUpgrade)
7677
}
7778

78-
/// A completely type-safe WebSocket upgrade that maintains type safety
79-
/// throughout the connection lifecycle without any dynamic casts.
80-
///
81-
pub opaque type WebSocketUpgrade {
82-
WebSocketUpgrade(ws: websocket.WebSocket)
83-
}
79+
pub type WebSocketUpgrade
80+
81+
@internal
82+
pub type Unknown
83+
84+
@external(erlang, "gleam@function", "identity")
85+
fn erase(callbacks: websocket.WebSocket(state, message)) -> WebSocketUpgrade
86+
87+
@external(erlang, "gleam@function", "identity")
88+
@internal
89+
pub fn recover(
90+
upgrade: WebSocketUpgrade,
91+
) -> websocket.WebSocket(Unknown, Unknown)
8492

8593
/// An alias for a HTTP response containing a `Body`.
8694
pub type Response =
@@ -2046,16 +2054,20 @@ pub fn get_cookie(
20462054
///
20472055
pub fn websocket(
20482056
request _request: Request,
2049-
on_init on_init: fn(websocket.Connection) -> state,
2050-
on_message on_message: fn(state, websocket.Message, websocket.Connection) ->
2057+
on_init on_init: fn(websocket.Connection) ->
2058+
#(state, Option(process.Selector(message))),
2059+
on_message on_message: fn(
2060+
state,
2061+
websocket.Message(custom),
2062+
websocket.Connection,
2063+
) ->
20512064
websocket.Next(state),
20522065
on_close on_close: fn(state) -> Nil,
20532066
) -> Response {
20542067
let ws = websocket.new(on_init, on_message, on_close)
2055-
let upgrade = WebSocketUpgrade(ws: ws)
20562068

20572069
response(200)
2058-
|> set_body(WebSocket(upgrade))
2070+
|> set_body(WebSocket(erase(ws)))
20592071
}
20602072

20612073
//
@@ -2162,8 +2174,3 @@ pub fn csrf_known_header_protection(
21622174
}
21632175
}
21642176
}
2165-
2166-
@internal
2167-
pub fn upgrade_to_websocket(upgrade: WebSocketUpgrade) -> websocket.WebSocket {
2168-
upgrade.ws
2169-
}

0 commit comments

Comments
 (0)