git.iko.soy/rowtype-yoga/purescript-yoga-bun-yoga
on main help sign in
checkpoint
commit43a3e6e28d52c024ec3ca9b3c143a8745a6751b5 authorMark <mark.eibes@gmail.com> dateMon 16 Feb 2026, 23:45 (7 months ago) parent3a8638f
2 files changed+46−7
src/Yoga/Bun/HTTP.js+10−2 src/Yoga/Bun/HTTP.purs+36−5
src/Yoga/Bun/HTTP.js+10−2
@@ -1,11 +1,16 @@
11export const serveImpl = (options) => {
22 const server = Bun.serve(options);
33 return {
4− stop: (close) => server.stop(close),
5− upgrade: (req) => () => server.upgrade(req)
4+ stopForce: () => server.stop(true),
5+ stopGraceful: () => server.stop(false),
6+ upgrade: (req) => () => server.upgrade(req),
7+ port: server.port
68 };
79};
810
11+export const wsDataImpl = (ws) => ws.data;
12+export const setWsDataImpl = (ws, data) => { ws.data = data; };
13+
914// String/text Response
1015export const stringResponseImpl = (body, stuff) => new Response(body, stuff);
1116
@@ -25,3 +30,6 @@ export const responseErrorImpl = () => Response.error();
2530
2631// Response cloning
2732export const cloneResponseImpl = (response) => response.clone();
33+
34+// URL search param (pure: URL constructor + searchParams.get)
35+export const searchParamImpl = (url) => (name) => new URL(url).searchParams.get(name);
src/Yoga/Bun/HTTP.purs+36−5
@@ -2,6 +2,8 @@ module Yoga.Bun.HTTP where
22
33import Prelude
44
5+import Data.Maybe (Maybe)
6+import Data.Nullable (Nullable, toMaybe)
57import Effect (Effect)
68import Effect.Aff (Aff)
79import Effect.Uncurried (EffectFn1, EffectFn2, mkEffectFn1, runEffectFn1, runEffectFn2)
@@ -10,14 +12,17 @@ import Foreign.Object (Object)
1012import Prim.Row (class Union)
1113import Promise (Promise)
1214import Promise.Aff (toAffE, fromAff) as Promise
15+import Unsafe.Coerce (unsafeCoerce)
1316import Web.Fetch.Request (Request)
1417import Web.Fetch.Response (Response)
1518
16−type BunServerImpl = { stop :: EffectFn1 Boolean (Promise Unit), upgrade :: EffectFn1 Request Boolean }
19+foreign import data BunWebSocket :: Type
20+
21+type BunServerImpl = { stopForce :: Effect (Promise Unit), stopGraceful :: Effect (Promise Unit), upgrade :: EffectFn1 Request Boolean, port :: Int }
1722
1823data CloseActiveConnections = WaitForOpenConnections | ForceTerminateAllOpenConnections
1924
20−type BunServer = { stop :: CloseActiveConnections -> Aff Unit, upgrade :: Request -> Effect Boolean }
25+type BunServer = { stop :: CloseActiveConnections -> Aff Unit, upgrade :: Request -> Effect Boolean, port :: Int }
2126
2227foreign import serveImpl :: forall options. EffectFn1 options BunServerImpl
2328
@@ -36,10 +41,11 @@ serve :: forall opts opts_. Union opts opts_ BunServeOptionsImpl => { fetch :: E
3641serve opts = do
3742 serverImpl <- runEffectFn1 serveImpl opts
3843 pure
39− { stop: \closeActiveConnections -> case closeActiveConnections of
40− WaitForOpenConnections -> runEffectFn1 serverImpl.stop true # Promise.toAffE
41− ForceTerminateAllOpenConnections -> runEffectFn1 serverImpl.stop false # Promise.toAffE
44+ { stop: case _ of
45+ WaitForOpenConnections -> serverImpl.stopGraceful # Promise.toAffE
46+ ForceTerminateAllOpenConnections -> serverImpl.stopForce # Promise.toAffE
4247 , upgrade: runEffectFn1 serverImpl.upgrade
48+ , port: serverImpl.port
4349 }
4450
4551mkFetch :: (Request -> Aff Response) -> EffectFn1 Request (Promise Response)
@@ -89,3 +95,28 @@ foreign import cloneResponseImpl :: Response -> Effect Response
8995
9096cloneResponse :: Response -> Effect Response
9197cloneResponse = cloneResponseImpl
98+
99+foreign import wsDataImpl :: EffectFn1 BunWebSocket Foreign
100+foreign import setWsDataImpl :: EffectFn2 BunWebSocket Foreign Unit
101+
102+wsData :: BunWebSocket -> Effect Foreign
103+wsData = runEffectFn1 wsDataImpl
104+
105+setWsData :: BunWebSocket -> Foreign -> Effect Unit
106+setWsData = runEffectFn2 setWsDataImpl
107+
108+-- Request accessors (pure property reads on the opaque Request type)
109+
110+requestMethod :: Request -> String
111+requestMethod req = (unsafeCoerce req).method
112+
113+requestUrl :: Request -> String
114+requestUrl req = (unsafeCoerce req).url
115+
116+requestSearchParam :: Request -> String -> Maybe String
117+requestSearchParam req name = do
118+ let result :: Nullable String
119+ result = searchParamImpl (requestUrl req) name
120+ toMaybe result
121+
122+foreign import searchParamImpl :: String -> String -> Nullable String