Skip to content

Commit 40a31a3

Browse files
committed
WSSends{...} -> WSSends(...)
1 parent 5775a81 commit 40a31a3

6 files changed

Lines changed: 41 additions & 39 deletions

File tree

apps/landing/src/content/docs/docs/core-concepts/websockets.mdx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ sidebar:
2020
shiftapi.HandleWS(api, "GET /echo",
2121
shiftapi.Websocket(
2222
func(r *http.Request, s *shiftapi.WSSender, _ struct{}) (struct{}, error) { return struct{}{}, nil },
23-
shiftapi.WSSends{shiftapi.WSMessageType[ServerMsg]("server")},
23+
shiftapi.WSSends(shiftapi.WSMessageType[ServerMsg]("server")),
2424
shiftapi.WSOn("echo", func(s *shiftapi.WSSender, _ struct{}, msg ClientMsg) error {
2525
return s.Send(ServerMsg{Text: "echo: " + msg.Text})
2626
}),
@@ -34,7 +34,7 @@ shiftapi.HandleWS(api, "GET /echo",
3434

3535
- **`Websocket(setup, sends, handlers...)`** — creates a `*WSMessages[In]` value. Both `In` and `State` are inferred from the setup function's signature. The setup function runs after the WebSocket upgrade, receives the parsed input, and returns a `State` value that is passed to all handlers.
3636
- **`WSOn("name", fn)`** — registers a typed handler for messages with the given type name. The `State` and `Msg` type parameters are inferred from the handler function. `State` must match the setup function's return type.
37-
- **`WSSends{variants...}`** — a `[]WSMessageVariant` that registers named send types for auto-wrap envelopes and AsyncAPI schema generation.
37+
- **`WSSends(variants...)`** — a `[]WSMessageVariant` that registers named send types for auto-wrap envelopes and AsyncAPI schema generation.
3838

3939
Everything is configured in one place — no mutation after construction.
4040

@@ -102,7 +102,7 @@ shiftapi.HandleWS(api, "GET /rooms/{room}",
102102
// in.Room and in.Token are parsed and validated before upgrade.
103103
return &ChatState{Room: in.Room, Token: in.Token}, nil
104104
},
105-
shiftapi.WSSends{shiftapi.WSMessageType[ChatMessage]("chat")},
105+
shiftapi.WSSends(shiftapi.WSMessageType[ChatMessage]("chat")),
106106
shiftapi.WSOn("message", func(s *shiftapi.WSSender, state *ChatState, m UserMessage) error {
107107
return s.Send(ChatMessage{Room: state.Room, Text: m.Text})
108108
}),
@@ -136,7 +136,7 @@ shiftapi.HandleWS(api, "GET /rooms/{room}",
136136
room := rooms.Join(in.Room, user)
137137
return &RoomState{Room: room, User: user}, nil
138138
},
139-
shiftapi.WSSends{shiftapi.WSMessageType[ChatMessage]("chat")},
139+
shiftapi.WSSends(shiftapi.WSMessageType[ChatMessage]("chat")),
140140
shiftapi.WSOn("message", func(s *shiftapi.WSSender, state *RoomState, m UserMessage) error {
141141
return s.Send(ChatMessage{Room: state.Room.Name, User: state.User.Name, Text: m.Text})
142142
}),
@@ -223,7 +223,7 @@ shiftapi.Websocket(
223223
func(r *http.Request, s *shiftapi.WSSender, _ struct{}) (*RoomState, error) {
224224
return &RoomState{}, nil
225225
},
226-
shiftapi.WSSends{shiftapi.WSMessageType[ChatMessage]("chat")},
226+
shiftapi.WSSends(shiftapi.WSMessageType[ChatMessage]("chat")),
227227
shiftapi.WSOn("message", handleMessage),
228228
shiftapi.WSOnDecodeError(func(s *shiftapi.WSSender, state *RoomState, err *shiftapi.WSDecodeError) {
229229
log.Printf("bad payload for %s: %v", err.MessageType(), err.Unwrap())
@@ -240,7 +240,7 @@ shiftapi.Websocket(
240240
func(r *http.Request, s *shiftapi.WSSender, _ struct{}) (*RoomState, error) {
241241
return &RoomState{}, nil
242242
},
243-
shiftapi.WSSends{shiftapi.WSMessageType[ChatMessage]("chat")},
243+
shiftapi.WSSends(shiftapi.WSMessageType[ChatMessage]("chat")),
244244
shiftapi.WSOn("message", handleMessage),
245245
shiftapi.WSOnUnknownMessage(func(s *shiftapi.WSSender, state *RoomState, msgType string, data json.RawMessage) {
246246
log.Printf("unknown message type: %s", msgType)
@@ -256,7 +256,7 @@ WebSocket endpoints are documented in an [AsyncAPI 2.4](https://www.asyncapi.com
256256
shiftapi.HandleWS(api, "GET /echo",
257257
shiftapi.Websocket(
258258
func(r *http.Request, s *shiftapi.WSSender, _ struct{}) (struct{}, error) { return struct{}{}, nil },
259-
shiftapi.WSSends{shiftapi.WSMessageType[ServerMsg]("server")},
259+
shiftapi.WSSends(shiftapi.WSMessageType[ServerMsg]("server")),
260260
shiftapi.WSOn("echo", func(s *shiftapi.WSSender, _ struct{}, msg ClientMsg) error {
261261
return s.Send(ServerMsg{Text: msg.Text})
262262
}),
@@ -396,10 +396,10 @@ Pass `WSMessageType[T]` descriptors to declare each named send type. `WSSender.S
396396
shiftapi.HandleWS(api, "GET /chat",
397397
shiftapi.Websocket(
398398
func(r *http.Request, s *shiftapi.WSSender, _ struct{}) (struct{}, error) { return struct{}{}, nil },
399-
shiftapi.WSSends{
399+
shiftapi.WSSends(
400400
shiftapi.WSMessageType[ChatMessage]("chat"),
401401
shiftapi.WSMessageType[SystemMessage]("system"),
402-
},
402+
),
403403
shiftapi.WSOn("message", func(s *shiftapi.WSSender, _ struct{}, m UserMessage) error {
404404
return s.Send(ChatMessage{User: "server", Text: m.Text})
405405
}),
@@ -468,10 +468,10 @@ You can register multiple `WSOn` handlers for different client message types:
468468
shiftapi.HandleWS(api, "GET /chat",
469469
shiftapi.Websocket(
470470
func(r *http.Request, s *shiftapi.WSSender, _ struct{}) (struct{}, error) { return struct{}{}, nil },
471-
shiftapi.WSSends{
471+
shiftapi.WSSends(
472472
shiftapi.WSMessageType[ChatMessage]("chat"),
473473
shiftapi.WSMessageType[SystemMessage]("system"),
474-
},
474+
),
475475
shiftapi.WSOn("message", func(s *shiftapi.WSSender, _ struct{}, m UserMessage) error {
476476
return s.Send(ChatMessage{User: "echo", Text: m.Text})
477477
}),
@@ -528,7 +528,7 @@ The following are arguments to `Websocket()`:
528528
| Argument | Description |
529529
|----------|-------------|
530530
| `setup` | Connection setup function — returns `(State, error)` (required, first arg) |
531-
| `WSSends{...}` | Server-to-client message types (required, second arg) |
531+
| `WSSends(...)` | Server-to-client message types (required, second arg) |
532532
| `WSOn("name", fn)` | Typed message handler — variadic (required, at least one) |
533533
| `WSOnDecodeError(fn)` | Handle malformed message payloads (default: log + continue) |
534534
| `WSOnUnknownMessage(fn)` | Handle unrecognized message types (default: log + continue) |

example_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ func ExampleHandleWS() {
420420
shiftapi.HandleWS(api, "GET /echo",
421421
shiftapi.Websocket(
422422
func(r *http.Request, s *shiftapi.WSSender, _ struct{}) (struct{}, error) { return struct{}{}, nil },
423-
shiftapi.WSSends{shiftapi.WSMessageType[ServerMsg]("server")},
423+
shiftapi.WSSends(shiftapi.WSMessageType[ServerMsg]("server")),
424424
shiftapi.WSOn("echo", func(s *shiftapi.WSSender, _ struct{}, msg ClientMsg) error {
425425
return s.Send(ServerMsg{Text: "echo: " + msg.Text})
426426
}),
@@ -449,10 +449,10 @@ func ExampleHandleWS_multiType() {
449449
shiftapi.HandleWS(api, "GET /chat",
450450
shiftapi.Websocket(
451451
func(r *http.Request, s *shiftapi.WSSender, _ struct{}) (struct{}, error) { return struct{}{}, nil },
452-
shiftapi.WSSends{
452+
shiftapi.WSSends(
453453
shiftapi.WSMessageType[exChatMessage]("chat"),
454454
shiftapi.WSMessageType[exSystemMessage]("system"),
455-
},
455+
),
456456
shiftapi.WSOn("message", func(s *shiftapi.WSSender, _ struct{}, m exUserMessage) error {
457457
return s.Send(exChatMessage{User: "server", Text: m.Text})
458458
}),

examples/greeter/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ func main() {
191191
func(r *http.Request, s *shiftapi.WSSender, req JoinReq) (*State, error) {
192192
return &State{ID: req.ID}, nil
193193
},
194-
shiftapi.WSSends{shiftapi.WSMessageType[EchoReply]("echo")},
194+
shiftapi.WSSends(shiftapi.WSMessageType[EchoReply]("echo")),
195195
shiftapi.WSOn("chat", func(s *shiftapi.WSSender, state *State, msg ChatMsg) error {
196196
fmt.Println(state)
197197
return s.Send(EchoReply{Text: "echo: " + msg.Text})

handlerFuncs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ func registerWSRoute[In any](
513513
// shiftapi.HandleWS(api, "GET /chat",
514514
// shiftapi.Websocket(
515515
// func(r *http.Request, s *shiftapi.WSSender, _ struct{}) (struct{}, error) { return struct{}{}, nil },
516-
// shiftapi.WSSends{shiftapi.WSMessageType[ChatMessage]("chat")},
516+
// shiftapi.WSSends(shiftapi.WSMessageType[ChatMessage]("chat")),
517517
// shiftapi.WSOn("message", func(s *shiftapi.WSSender, _ struct{}, m UserMessage) error {
518518
// return s.Send(ChatMessage{User: "echo", Text: m.Text})
519519
// }),

ws.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,9 @@ type WSHandler[State any] struct {
158158
// shiftapi.WSMessageType[ChatMessage]("chat"),
159159
// shiftapi.WSMessageType[SystemMessage]("system"),
160160
// )
161-
type WSSends []WSMessageVariant
161+
func WSSends(variants ...WSMessageVariant) []WSMessageVariant {
162+
return variants
163+
}
162164

163165
// Websocket creates a new WebSocket endpoint configuration. The type
164166
// parameters In and State are both inferred from the setup function:
@@ -182,9 +184,9 @@ type WSSends []WSMessageVariant
182184
// }),
183185
// ),
184186
// )
185-
func Websocket[In, State any](setup func(r *http.Request, sender *WSSender, in In) (State, error), sends WSSends, handlers ...WSHandler[State]) *WSMessages[In] {
187+
func Websocket[In, State any](setup func(r *http.Request, sender *WSSender, in In) (State, error), sends []WSMessageVariant, handlers ...WSHandler[State]) *WSMessages[In] {
186188
cfg := &websocketConfig{
187-
sendVariants: []WSMessageVariant(sends),
189+
sendVariants: sends,
188190
setup: func(r *http.Request, ws *WSSender, input any) (any, error) {
189191
return setup(r, ws, input.(In))
190192
},

ws_test.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func TestHandleWS_AsyncAPISpec(t *testing.T) {
3232
shiftapi.HandleWS(api, "GET /ws",
3333
shiftapi.Websocket(
3434
noSetup,
35-
shiftapi.WSSends{shiftapi.WSMessageType[wsServerMsg]("server")},
35+
shiftapi.WSSends(shiftapi.WSMessageType[wsServerMsg]("server")),
3636
shiftapi.WSOn("echo", func(sender *shiftapi.WSSender, _ struct{}, msg wsClientMsg) error {
3737
return sender.Send(wsServerMsg(msg))
3838
}),
@@ -171,7 +171,7 @@ func TestHandleWS_InputParsing(t *testing.T) {
171171
func(r *http.Request, sender *shiftapi.WSSender, in Input) (*inputState, error) {
172172
return &inputState{Channel: in.Channel}, nil
173173
},
174-
shiftapi.WSSends{shiftapi.WSMessageType[wsServerMsg]("server")},
174+
shiftapi.WSSends(shiftapi.WSMessageType[wsServerMsg]("server")),
175175
shiftapi.WSOn("msg", func(sender *shiftapi.WSSender, state *inputState, msg wsClientMsg) error {
176176
return sender.Send(wsServerMsg{Text: "channel=" + state.Channel})
177177
}),
@@ -212,7 +212,7 @@ func TestHandleWS_OnDispatch(t *testing.T) {
212212
shiftapi.HandleWS(api, "GET /echo",
213213
shiftapi.Websocket(
214214
noSetup,
215-
shiftapi.WSSends{shiftapi.WSMessageType[wsServerMsg]("server")},
215+
shiftapi.WSSends(shiftapi.WSMessageType[wsServerMsg]("server")),
216216
shiftapi.WSOn("echo", func(sender *shiftapi.WSSender, _ struct{}, msg wsClientMsg) error {
217217
return sender.Send(wsServerMsg{Text: "echo: " + msg.Text})
218218
}),
@@ -257,7 +257,7 @@ func TestHandleWS_AutoWrapSend(t *testing.T) {
257257
shiftapi.HandleWS(api, "GET /ws",
258258
shiftapi.Websocket(
259259
noSetup,
260-
shiftapi.WSSends{shiftapi.WSMessageType[wsServerMsg]("server")},
260+
shiftapi.WSSends(shiftapi.WSMessageType[wsServerMsg]("server")),
261261
shiftapi.WSOn("ping", func(sender *shiftapi.WSSender, _ struct{}, msg wsClientMsg) error {
262262
return sender.Send(wsServerMsg{Text: "pong"})
263263
}),
@@ -308,7 +308,7 @@ func TestHandleWS_ErrorBeforeUpgrade(t *testing.T) {
308308
func(r *http.Request, sender *shiftapi.WSSender, in Input) (struct{}, error) {
309309
return struct{}{}, nil
310310
},
311-
shiftapi.WSSends{shiftapi.WSMessageType[wsServerMsg]("server")},
311+
shiftapi.WSSends(shiftapi.WSMessageType[wsServerMsg]("server")),
312312
shiftapi.WSOn("msg", func(sender *shiftapi.WSSender, _ struct{}, msg wsClientMsg) error {
313313
return nil
314314
}),
@@ -348,7 +348,7 @@ func TestHandleWS_ErrorAfterUpgrade(t *testing.T) {
348348
shiftapi.HandleWS(api, "GET /ws",
349349
shiftapi.Websocket(
350350
noSetup,
351-
shiftapi.WSSends{shiftapi.WSMessageType[wsServerMsg]("server")},
351+
shiftapi.WSSends(shiftapi.WSMessageType[wsServerMsg]("server")),
352352
shiftapi.WSOn("msg", func(sender *shiftapi.WSSender, _ struct{}, msg wsClientMsg) error {
353353
return fmt.Errorf("something went wrong")
354354
}),
@@ -388,7 +388,7 @@ func TestHandleWS_WSOnUnknownMessage(t *testing.T) {
388388
shiftapi.HandleWS(api, "GET /ws",
389389
shiftapi.Websocket(
390390
noSetup,
391-
shiftapi.WSSends{shiftapi.WSMessageType[wsServerMsg]("server")},
391+
shiftapi.WSSends(shiftapi.WSMessageType[wsServerMsg]("server")),
392392
shiftapi.WSOn("msg", func(sender *shiftapi.WSSender, _ struct{}, msg wsClientMsg) error {
393393
return sender.Send(wsServerMsg{Text: "ok"})
394394
}),
@@ -437,7 +437,7 @@ func TestHandleWS_WithWSAcceptOptions(t *testing.T) {
437437
shiftapi.HandleWS(api, "GET /ws",
438438
shiftapi.Websocket(
439439
noSetup,
440-
shiftapi.WSSends{shiftapi.WSMessageType[wsServerMsg]("server")},
440+
shiftapi.WSSends(shiftapi.WSMessageType[wsServerMsg]("server")),
441441
shiftapi.WSOn("msg", func(sender *shiftapi.WSSender, _ struct{}, msg wsClientMsg) error {
442442
return sender.Send(wsServerMsg{Text: "ok"})
443443
}),
@@ -498,7 +498,7 @@ func TestHandleWS_PathParams(t *testing.T) {
498498
func(r *http.Request, sender *shiftapi.WSSender, in Input) (*pathState, error) {
499499
return &pathState{ID: in.ID}, nil
500500
},
501-
shiftapi.WSSends{shiftapi.WSMessageType[wsServerMsg]("server")},
501+
shiftapi.WSSends(shiftapi.WSMessageType[wsServerMsg]("server")),
502502
shiftapi.WSOn("msg", func(sender *shiftapi.WSSender, state *pathState, msg wsClientMsg) error {
503503
return sender.Send(wsServerMsg{Text: "room=" + state.ID})
504504
}),
@@ -558,10 +558,10 @@ func TestHandleWS_MultiTypeDispatch(t *testing.T) {
558558
shiftapi.HandleWS(api, "GET /ws",
559559
shiftapi.Websocket(
560560
noSetup,
561-
shiftapi.WSSends{
561+
shiftapi.WSSends(
562562
shiftapi.WSMessageType[wsChatMsg]("chat"),
563563
shiftapi.WSMessageType[wsSystemMsg]("system"),
564-
},
564+
),
565565
shiftapi.WSOn("message", func(sender *shiftapi.WSSender, _ struct{}, m wsUserMsg) error {
566566
return sender.Send(wsChatMsg{User: "server", Text: "got: " + m.Text})
567567
}),
@@ -628,10 +628,10 @@ func TestHandleWS_WithMessages_AsyncAPISpec(t *testing.T) {
628628
shiftapi.HandleWS(api, "GET /ws",
629629
shiftapi.Websocket(
630630
noSetup,
631-
shiftapi.WSSends{
631+
shiftapi.WSSends(
632632
shiftapi.WSMessageType[wsChatMsg]("chat"),
633633
shiftapi.WSMessageType[wsSystemMsg]("system"),
634-
},
634+
),
635635
shiftapi.WSOn("message", func(sender *shiftapi.WSSender, _ struct{}, m wsUserMsg) error {
636636
return nil
637637
}),
@@ -731,10 +731,10 @@ func TestHandleWS_DuplicateSendNamePanics(t *testing.T) {
731731
shiftapi.HandleWS(api, "GET /dup",
732732
shiftapi.Websocket(
733733
noSetup,
734-
shiftapi.WSSends{
734+
shiftapi.WSSends(
735735
shiftapi.WSMessageType[wsChatMsg]("same"),
736736
shiftapi.WSMessageType[wsSystemMsg]("same"),
737-
},
737+
),
738738
shiftapi.WSOn("msg", func(sender *shiftapi.WSSender, _ struct{}, m wsClientMsg) error {
739739
return nil
740740
}),
@@ -757,7 +757,7 @@ func TestHandleWS_DuplicateOnNamePanics(t *testing.T) {
757757
shiftapi.HandleWS(api, "GET /dup",
758758
shiftapi.Websocket(
759759
noSetup,
760-
shiftapi.WSSends{shiftapi.WSMessageType[wsServerMsg]("server")},
760+
shiftapi.WSSends(shiftapi.WSMessageType[wsServerMsg]("server")),
761761
shiftapi.WSOn("msg", func(sender *shiftapi.WSSender, _ struct{}, m wsClientMsg) error {
762762
return nil
763763
}),
@@ -787,7 +787,7 @@ func TestHandleWS_Setup(t *testing.T) {
787787
}
788788
return &roomState{Room: in.Room}, nil
789789
},
790-
shiftapi.WSSends{shiftapi.WSMessageType[wsServerMsg]("server")},
790+
shiftapi.WSSends(shiftapi.WSMessageType[wsServerMsg]("server")),
791791
shiftapi.WSOn("message", func(sender *shiftapi.WSSender, state *roomState, msg wsClientMsg) error {
792792
return sender.Send(wsServerMsg{Text: "[" + state.Room + "] " + msg.Text})
793793
}),
@@ -836,7 +836,7 @@ func TestHandleWS_Setup_Error(t *testing.T) {
836836
func(r *http.Request, sender *shiftapi.WSSender, in joinInput) (struct{}, error) {
837837
return struct{}{}, fmt.Errorf("setup failed")
838838
},
839-
shiftapi.WSSends{shiftapi.WSMessageType[wsServerMsg]("server")},
839+
shiftapi.WSSends(shiftapi.WSMessageType[wsServerMsg]("server")),
840840
shiftapi.WSOn("message", func(sender *shiftapi.WSSender, _ struct{}, msg wsClientMsg) error {
841841
return sender.Send(wsServerMsg{Text: "should not reach"})
842842
}),
@@ -895,7 +895,7 @@ func TestWebsocket_NoHandlersPanics(t *testing.T) {
895895
shiftapi.HandleWS(api, "GET /ws",
896896
shiftapi.Websocket(
897897
noSetup,
898-
shiftapi.WSSends{shiftapi.WSMessageType[wsServerMsg]("server")},
898+
shiftapi.WSSends(shiftapi.WSMessageType[wsServerMsg]("server")),
899899
),
900900
)
901901
}

0 commit comments

Comments
 (0)