@effect/platform-bun 0.87.0 → 4.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (286) hide show
  1. package/dist/BunChildProcessSpawner.d.ts +7 -0
  2. package/dist/BunChildProcessSpawner.d.ts.map +1 -0
  3. package/dist/BunChildProcessSpawner.js +7 -0
  4. package/dist/BunChildProcessSpawner.js.map +1 -0
  5. package/dist/BunClusterHttp.d.ts +45 -0
  6. package/dist/BunClusterHttp.d.ts.map +1 -0
  7. package/dist/BunClusterHttp.js +48 -0
  8. package/dist/BunClusterHttp.js.map +1 -0
  9. package/dist/BunClusterSocket.d.ts +46 -0
  10. package/dist/BunClusterSocket.d.ts.map +1 -0
  11. package/dist/BunClusterSocket.js +60 -0
  12. package/dist/BunClusterSocket.js.map +1 -0
  13. package/dist/BunFileSystem.d.ts +8 -0
  14. package/dist/BunFileSystem.d.ts.map +1 -0
  15. package/dist/BunFileSystem.js.map +1 -0
  16. package/dist/BunHttpClient.d.ts +9 -0
  17. package/dist/BunHttpClient.d.ts.map +1 -0
  18. package/dist/BunHttpClient.js +9 -0
  19. package/dist/BunHttpClient.js.map +1 -0
  20. package/dist/BunHttpPlatform.d.ts +8 -0
  21. package/dist/BunHttpPlatform.d.ts.map +1 -0
  22. package/dist/BunHttpPlatform.js +35 -0
  23. package/dist/BunHttpPlatform.js.map +1 -0
  24. package/dist/BunHttpServer.d.ts +71 -0
  25. package/dist/BunHttpServer.d.ts.map +1 -0
  26. package/dist/{esm/internal/httpServer.js → BunHttpServer.js} +149 -118
  27. package/dist/BunHttpServer.js.map +1 -0
  28. package/dist/BunHttpServerRequest.d.ts +10 -0
  29. package/dist/BunHttpServerRequest.d.ts.map +1 -0
  30. package/dist/BunHttpServerRequest.js +6 -0
  31. package/dist/BunHttpServerRequest.js.map +1 -0
  32. package/dist/BunMultipart.d.ts +20 -0
  33. package/dist/BunMultipart.d.ts.map +1 -0
  34. package/dist/BunMultipart.js +17 -0
  35. package/dist/BunMultipart.js.map +1 -0
  36. package/dist/BunPath.d.ts +18 -0
  37. package/dist/BunPath.d.ts.map +1 -0
  38. package/dist/BunPath.js.map +1 -0
  39. package/dist/BunRedis.d.ts +35 -0
  40. package/dist/BunRedis.d.ts.map +1 -0
  41. package/dist/BunRedis.js +51 -0
  42. package/dist/BunRedis.js.map +1 -0
  43. package/dist/BunRuntime.d.ts +94 -0
  44. package/dist/BunRuntime.d.ts.map +1 -0
  45. package/dist/BunRuntime.js +33 -0
  46. package/dist/BunRuntime.js.map +1 -0
  47. package/dist/BunServices.d.ts +20 -0
  48. package/dist/BunServices.d.ts.map +1 -0
  49. package/dist/BunServices.js +12 -0
  50. package/dist/BunServices.js.map +1 -0
  51. package/dist/BunSink.d.ts.map +1 -0
  52. package/dist/BunSink.js.map +1 -0
  53. package/dist/BunSocket.d.ts +26 -0
  54. package/dist/BunSocket.d.ts.map +1 -0
  55. package/dist/BunSocket.js +18 -0
  56. package/dist/BunSocket.js.map +1 -0
  57. package/dist/BunSocketServer.d.ts.map +1 -0
  58. package/dist/BunSocketServer.js.map +1 -0
  59. package/dist/BunStdio.d.ts +8 -0
  60. package/dist/BunStdio.d.ts.map +1 -0
  61. package/dist/BunStdio.js +10 -0
  62. package/dist/BunStdio.js.map +1 -0
  63. package/dist/BunStream.d.ts +18 -0
  64. package/dist/BunStream.d.ts.map +1 -0
  65. package/dist/BunStream.js +44 -0
  66. package/dist/BunStream.js.map +1 -0
  67. package/dist/{dts/BunTerminal.d.ts → BunTerminal.d.ts} +2 -2
  68. package/dist/BunTerminal.d.ts.map +1 -0
  69. package/dist/{esm/BunTerminal.js → BunTerminal.js} +1 -1
  70. package/dist/BunTerminal.js.map +1 -0
  71. package/dist/BunWorker.d.ts +13 -0
  72. package/dist/BunWorker.d.ts.map +1 -0
  73. package/dist/BunWorker.js +59 -0
  74. package/dist/BunWorker.js.map +1 -0
  75. package/dist/BunWorkerRunner.d.ts +8 -0
  76. package/dist/BunWorkerRunner.d.ts.map +1 -0
  77. package/dist/BunWorkerRunner.js +88 -0
  78. package/dist/BunWorkerRunner.js.map +1 -0
  79. package/dist/index.d.ts +90 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/{esm/index.js → index.js} +21 -7
  82. package/dist/index.js.map +1 -0
  83. package/package.json +51 -195
  84. package/src/BunChildProcessSpawner.ts +6 -0
  85. package/src/BunClusterHttp.ts +48 -35
  86. package/src/BunClusterSocket.ts +55 -21
  87. package/src/BunFileSystem.ts +3 -3
  88. package/src/BunHttpClient.ts +9 -0
  89. package/src/BunHttpPlatform.ts +28 -9
  90. package/src/BunHttpServer.ts +510 -58
  91. package/src/BunHttpServerRequest.ts +4 -4
  92. package/src/BunMultipart.ts +22 -11
  93. package/src/BunPath.ts +5 -6
  94. package/src/BunRedis.ts +74 -0
  95. package/src/BunRuntime.ts +95 -3
  96. package/src/BunServices.ts +33 -0
  97. package/src/BunSocket.ts +20 -10
  98. package/src/BunStdio.ts +12 -0
  99. package/src/BunStream.ts +51 -0
  100. package/src/BunTerminal.ts +2 -2
  101. package/src/BunWorker.ts +63 -21
  102. package/src/BunWorkerRunner.ts +92 -11
  103. package/src/index.ts +37 -19
  104. package/BunClusterHttp/package.json +0 -6
  105. package/BunClusterSocket/package.json +0 -6
  106. package/BunCommandExecutor/package.json +0 -6
  107. package/BunContext/package.json +0 -6
  108. package/BunFileSystem/ParcelWatcher/package.json +0 -6
  109. package/BunFileSystem/package.json +0 -6
  110. package/BunHttpPlatform/package.json +0 -6
  111. package/BunHttpServer/package.json +0 -6
  112. package/BunHttpServerRequest/package.json +0 -6
  113. package/BunKeyValueStore/package.json +0 -6
  114. package/BunMultipart/package.json +0 -6
  115. package/BunPath/package.json +0 -6
  116. package/BunRuntime/package.json +0 -6
  117. package/BunSink/package.json +0 -6
  118. package/BunSocket/package.json +0 -6
  119. package/BunSocketServer/package.json +0 -6
  120. package/BunStream/package.json +0 -6
  121. package/BunTerminal/package.json +0 -6
  122. package/BunWorker/package.json +0 -6
  123. package/BunWorkerRunner/package.json +0 -6
  124. package/dist/cjs/BunClusterHttp.js +0 -59
  125. package/dist/cjs/BunClusterHttp.js.map +0 -1
  126. package/dist/cjs/BunClusterSocket.js +0 -55
  127. package/dist/cjs/BunClusterSocket.js.map +0 -1
  128. package/dist/cjs/BunCommandExecutor.js +0 -18
  129. package/dist/cjs/BunCommandExecutor.js.map +0 -1
  130. package/dist/cjs/BunContext.js +0 -20
  131. package/dist/cjs/BunContext.js.map +0 -1
  132. package/dist/cjs/BunFileSystem/ParcelWatcher.js +0 -18
  133. package/dist/cjs/BunFileSystem/ParcelWatcher.js.map +0 -1
  134. package/dist/cjs/BunFileSystem.js +0 -18
  135. package/dist/cjs/BunFileSystem.js.map +0 -1
  136. package/dist/cjs/BunHttpPlatform.js +0 -19
  137. package/dist/cjs/BunHttpPlatform.js.map +0 -1
  138. package/dist/cjs/BunHttpServer.js +0 -48
  139. package/dist/cjs/BunHttpServer.js.map +0 -1
  140. package/dist/cjs/BunHttpServerRequest.js +0 -14
  141. package/dist/cjs/BunHttpServerRequest.js.map +0 -1
  142. package/dist/cjs/BunKeyValueStore.js +0 -18
  143. package/dist/cjs/BunKeyValueStore.js.map +0 -1
  144. package/dist/cjs/BunMultipart.js +0 -19
  145. package/dist/cjs/BunMultipart.js.map +0 -1
  146. package/dist/cjs/BunPath.js +0 -28
  147. package/dist/cjs/BunPath.js.map +0 -1
  148. package/dist/cjs/BunRuntime.js +0 -18
  149. package/dist/cjs/BunRuntime.js.map +0 -1
  150. package/dist/cjs/BunSink.js +0 -17
  151. package/dist/cjs/BunSink.js.map +0 -1
  152. package/dist/cjs/BunSocket.js +0 -45
  153. package/dist/cjs/BunSocket.js.map +0 -1
  154. package/dist/cjs/BunSocketServer.js +0 -17
  155. package/dist/cjs/BunSocketServer.js.map +0 -1
  156. package/dist/cjs/BunStream.js +0 -17
  157. package/dist/cjs/BunStream.js.map +0 -1
  158. package/dist/cjs/BunTerminal.js +0 -23
  159. package/dist/cjs/BunTerminal.js.map +0 -1
  160. package/dist/cjs/BunWorker.js +0 -29
  161. package/dist/cjs/BunWorker.js.map +0 -1
  162. package/dist/cjs/BunWorkerRunner.js +0 -21
  163. package/dist/cjs/BunWorkerRunner.js.map +0 -1
  164. package/dist/cjs/index.js +0 -46
  165. package/dist/cjs/index.js.map +0 -1
  166. package/dist/cjs/internal/httpPlatform.js +0 -36
  167. package/dist/cjs/internal/httpPlatform.js.map +0 -1
  168. package/dist/cjs/internal/httpServer.js +0 -356
  169. package/dist/cjs/internal/httpServer.js.map +0 -1
  170. package/dist/cjs/internal/multipart.js +0 -160
  171. package/dist/cjs/internal/multipart.js.map +0 -1
  172. package/dist/cjs/internal/worker.js +0 -63
  173. package/dist/cjs/internal/worker.js.map +0 -1
  174. package/dist/cjs/internal/workerRunner.js +0 -84
  175. package/dist/cjs/internal/workerRunner.js.map +0 -1
  176. package/dist/dts/BunClusterHttp.d.ts +0 -30
  177. package/dist/dts/BunClusterHttp.d.ts.map +0 -1
  178. package/dist/dts/BunClusterSocket.d.ts +0 -35
  179. package/dist/dts/BunClusterSocket.d.ts.map +0 -1
  180. package/dist/dts/BunCommandExecutor.d.ts +0 -9
  181. package/dist/dts/BunCommandExecutor.d.ts.map +0 -1
  182. package/dist/dts/BunContext.d.ts +0 -20
  183. package/dist/dts/BunContext.d.ts.map +0 -1
  184. package/dist/dts/BunFileSystem/ParcelWatcher.d.ts +0 -8
  185. package/dist/dts/BunFileSystem/ParcelWatcher.d.ts.map +0 -1
  186. package/dist/dts/BunFileSystem.d.ts +0 -8
  187. package/dist/dts/BunFileSystem.d.ts.map +0 -1
  188. package/dist/dts/BunHttpPlatform.d.ts +0 -19
  189. package/dist/dts/BunHttpPlatform.d.ts.map +0 -1
  190. package/dist/dts/BunHttpServer.d.ts +0 -72
  191. package/dist/dts/BunHttpServer.d.ts.map +0 -1
  192. package/dist/dts/BunHttpServerRequest.d.ts +0 -10
  193. package/dist/dts/BunHttpServerRequest.d.ts.map +0 -1
  194. package/dist/dts/BunKeyValueStore.d.ts +0 -9
  195. package/dist/dts/BunKeyValueStore.d.ts.map +0 -1
  196. package/dist/dts/BunMultipart.d.ts +0 -20
  197. package/dist/dts/BunMultipart.d.ts.map +0 -1
  198. package/dist/dts/BunPath.d.ts +0 -21
  199. package/dist/dts/BunPath.d.ts.map +0 -1
  200. package/dist/dts/BunRuntime.d.ts +0 -7
  201. package/dist/dts/BunRuntime.d.ts.map +0 -1
  202. package/dist/dts/BunSink.d.ts.map +0 -1
  203. package/dist/dts/BunSocket.d.ts +0 -22
  204. package/dist/dts/BunSocket.d.ts.map +0 -1
  205. package/dist/dts/BunSocketServer.d.ts.map +0 -1
  206. package/dist/dts/BunStream.d.ts +0 -8
  207. package/dist/dts/BunStream.d.ts.map +0 -1
  208. package/dist/dts/BunTerminal.d.ts.map +0 -1
  209. package/dist/dts/BunWorker.d.ts +0 -26
  210. package/dist/dts/BunWorker.d.ts.map +0 -1
  211. package/dist/dts/BunWorkerRunner.d.ts +0 -17
  212. package/dist/dts/BunWorkerRunner.d.ts.map +0 -1
  213. package/dist/dts/index.d.ts +0 -77
  214. package/dist/dts/index.d.ts.map +0 -1
  215. package/dist/dts/internal/httpPlatform.d.ts +0 -2
  216. package/dist/dts/internal/httpPlatform.d.ts.map +0 -1
  217. package/dist/dts/internal/httpServer.d.ts +0 -2
  218. package/dist/dts/internal/httpServer.d.ts.map +0 -1
  219. package/dist/dts/internal/multipart.d.ts +0 -2
  220. package/dist/dts/internal/multipart.d.ts.map +0 -1
  221. package/dist/dts/internal/worker.d.ts +0 -2
  222. package/dist/dts/internal/worker.d.ts.map +0 -1
  223. package/dist/dts/internal/workerRunner.d.ts +0 -2
  224. package/dist/dts/internal/workerRunner.d.ts.map +0 -1
  225. package/dist/esm/BunClusterHttp.js +0 -50
  226. package/dist/esm/BunClusterHttp.js.map +0 -1
  227. package/dist/esm/BunClusterSocket.js +0 -45
  228. package/dist/esm/BunClusterSocket.js.map +0 -1
  229. package/dist/esm/BunCommandExecutor.js +0 -10
  230. package/dist/esm/BunCommandExecutor.js.map +0 -1
  231. package/dist/esm/BunContext.js +0 -13
  232. package/dist/esm/BunContext.js.map +0 -1
  233. package/dist/esm/BunFileSystem/ParcelWatcher.js +0 -10
  234. package/dist/esm/BunFileSystem/ParcelWatcher.js.map +0 -1
  235. package/dist/esm/BunFileSystem.js.map +0 -1
  236. package/dist/esm/BunHttpPlatform.js +0 -12
  237. package/dist/esm/BunHttpPlatform.js.map +0 -1
  238. package/dist/esm/BunHttpServer.js +0 -41
  239. package/dist/esm/BunHttpServer.js.map +0 -1
  240. package/dist/esm/BunHttpServerRequest.js +0 -7
  241. package/dist/esm/BunHttpServerRequest.js.map +0 -1
  242. package/dist/esm/BunKeyValueStore.js +0 -10
  243. package/dist/esm/BunKeyValueStore.js.map +0 -1
  244. package/dist/esm/BunMultipart.js +0 -12
  245. package/dist/esm/BunMultipart.js.map +0 -1
  246. package/dist/esm/BunPath.js.map +0 -1
  247. package/dist/esm/BunRuntime.js +0 -10
  248. package/dist/esm/BunRuntime.js.map +0 -1
  249. package/dist/esm/BunSink.js.map +0 -1
  250. package/dist/esm/BunSocket.js +0 -20
  251. package/dist/esm/BunSocket.js.map +0 -1
  252. package/dist/esm/BunSocketServer.js.map +0 -1
  253. package/dist/esm/BunStream.js +0 -8
  254. package/dist/esm/BunStream.js.map +0 -1
  255. package/dist/esm/BunTerminal.js.map +0 -1
  256. package/dist/esm/BunWorker.js +0 -22
  257. package/dist/esm/BunWorker.js.map +0 -1
  258. package/dist/esm/BunWorkerRunner.js +0 -13
  259. package/dist/esm/BunWorkerRunner.js.map +0 -1
  260. package/dist/esm/index.js.map +0 -1
  261. package/dist/esm/internal/httpPlatform.js +0 -29
  262. package/dist/esm/internal/httpPlatform.js.map +0 -1
  263. package/dist/esm/internal/httpServer.js.map +0 -1
  264. package/dist/esm/internal/multipart.js +0 -151
  265. package/dist/esm/internal/multipart.js.map +0 -1
  266. package/dist/esm/internal/worker.js +0 -54
  267. package/dist/esm/internal/worker.js.map +0 -1
  268. package/dist/esm/internal/workerRunner.js +0 -77
  269. package/dist/esm/internal/workerRunner.js.map +0 -1
  270. package/dist/esm/package.json +0 -4
  271. package/index/package.json +0 -6
  272. package/src/BunCommandExecutor.ts +0 -13
  273. package/src/BunContext.ts +0 -40
  274. package/src/BunFileSystem/ParcelWatcher.ts +0 -12
  275. package/src/BunKeyValueStore.ts +0 -15
  276. package/src/internal/httpPlatform.ts +0 -25
  277. package/src/internal/httpServer.ts +0 -478
  278. package/src/internal/multipart.ts +0 -149
  279. package/src/internal/worker.ts +0 -68
  280. package/src/internal/workerRunner.ts +0 -87
  281. /package/dist/{esm/BunFileSystem.js → BunFileSystem.js} +0 -0
  282. /package/dist/{esm/BunPath.js → BunPath.js} +0 -0
  283. /package/dist/{dts/BunSink.d.ts → BunSink.d.ts} +0 -0
  284. /package/dist/{esm/BunSink.js → BunSink.js} +0 -0
  285. /package/dist/{dts/BunSocketServer.d.ts → BunSocketServer.d.ts} +0 -0
  286. /package/dist/{esm/BunSocketServer.js → BunSocketServer.js} +0 -0
@@ -1,96 +1,548 @@
1
1
  /**
2
2
  * @since 1.0.0
3
3
  */
4
- import type * as Etag from "@effect/platform/Etag"
5
- import type * as HttpClient from "@effect/platform/HttpClient"
6
- import type * as Platform from "@effect/platform/HttpPlatform"
7
- import type * as Server from "@effect/platform/HttpServer"
8
- import type * as HttpServerError from "@effect/platform/HttpServerError"
9
- import type * as Bun from "bun"
10
- import type * as Config from "effect/Config"
11
- import type * as ConfigError from "effect/ConfigError"
12
- import type * as Effect from "effect/Effect"
13
- import type * as Layer from "effect/Layer"
4
+ import type { Server as BunServer, ServerWebSocket } from "bun"
5
+ import * as Config from "effect/Config"
6
+ import type { ConfigError } from "effect/Config"
7
+ import * as Deferred from "effect/Deferred"
8
+ import * as Effect from "effect/Effect"
9
+ import * as Exit from "effect/Exit"
10
+ import * as Fiber from "effect/Fiber"
11
+ import * as FiberSet from "effect/FiberSet"
12
+ import type * as FileSystem from "effect/FileSystem"
13
+ import { flow } from "effect/Function"
14
+ import * as Inspectable from "effect/Inspectable"
15
+ import * as Layer from "effect/Layer"
16
+ import type * as Path from "effect/Path"
17
+ import type * as Record from "effect/Record"
14
18
  import type * as Scope from "effect/Scope"
15
- import type * as BunContext from "./BunContext.js"
16
- import * as internal from "./internal/httpServer.js"
19
+ import * as ServiceMap from "effect/ServiceMap"
20
+ import * as Stream from "effect/Stream"
21
+ import * as Cookies from "effect/unstable/http/Cookies"
22
+ import * as Etag from "effect/unstable/http/Etag"
23
+ import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient"
24
+ import * as Headers from "effect/unstable/http/Headers"
25
+ import type { HttpClient } from "effect/unstable/http/HttpClient"
26
+ import * as HttpEffect from "effect/unstable/http/HttpEffect"
27
+ import * as IncomingMessage from "effect/unstable/http/HttpIncomingMessage"
28
+ import type { HttpMethod } from "effect/unstable/http/HttpMethod"
29
+ import type { HttpPlatform } from "effect/unstable/http/HttpPlatform"
30
+ import * as Server from "effect/unstable/http/HttpServer"
31
+ import * as Error from "effect/unstable/http/HttpServerError"
32
+ import * as ServerRequest from "effect/unstable/http/HttpServerRequest"
33
+ import type * as ServerResponse from "effect/unstable/http/HttpServerResponse"
34
+ import type * as Multipart from "effect/unstable/http/Multipart"
35
+ import * as UrlParams from "effect/unstable/http/UrlParams"
36
+ import * as Socket from "effect/unstable/socket/Socket"
37
+ import * as Platform from "./BunHttpPlatform.ts"
38
+ import * as BunMultipart from "./BunMultipart.ts"
39
+ import * as BunServices from "./BunServices.ts"
40
+ import * as BunStream from "./BunStream.ts"
17
41
 
18
42
  /**
19
43
  * @since 1.0.0
20
44
  * @category Options
21
45
  */
22
- export type ServeOptions<R extends { [K in keyof R]: Bun.RouterTypes.RouteValue<Extract<K, string>> }> =
46
+ export type ServeOptions<R extends string> =
23
47
  & (
24
- | Omit<Bun.ServeOptions, "fetch" | "error">
25
- | Bun.TLSServeOptions
26
- | Bun.UnixServeOptions
27
- | Bun.UnixTLSServeOptions
48
+ | Bun.Serve.UnixServeOptions<WebSocketContext>
49
+ | Bun.Serve.HostnamePortServeOptions<WebSocketContext>
28
50
  )
29
- & { readonly routes?: R }
51
+ & { readonly routes?: Bun.Serve.Routes<WebSocketContext, R> }
30
52
 
31
53
  /**
32
54
  * @since 1.0.0
33
- * @category constructors
55
+ * @category Constructors
34
56
  */
35
- export const make: <R extends { [K in keyof R]: Bun.RouterTypes.RouteValue<Extract<K, string>> } = {}>(
36
- options: ServeOptions<R>
37
- ) => Effect.Effect<Server.HttpServer, never, Scope.Scope> = internal.make
57
+ export const make = Effect.fnUntraced(
58
+ function*<R extends string>(
59
+ options: ServeOptions<R>
60
+ ) {
61
+ const handlerStack: Array<(request: Request, server: BunServer<WebSocketContext>) => Response | Promise<Response>> =
62
+ [
63
+ function(_request, _server) {
64
+ return new Response("not found", { status: 404 })
65
+ }
66
+ ]
67
+ const server = Bun.serve<WebSocketContext, R>({
68
+ ...options as ServeOptions<R>,
69
+ fetch: handlerStack[0],
70
+ websocket: {
71
+ open(ws) {
72
+ Deferred.doneUnsafe(ws.data.deferred, Exit.succeed(ws))
73
+ },
74
+ message(ws, message) {
75
+ ws.data.run(message)
76
+ },
77
+ close(ws, code, closeReason) {
78
+ Deferred.doneUnsafe(
79
+ ws.data.closeDeferred,
80
+ Socket.defaultCloseCodeIsError(code)
81
+ ? Exit.fail(
82
+ new Socket.SocketError({
83
+ reason: new Socket.SocketCloseError({ code, closeReason })
84
+ })
85
+ )
86
+ : Exit.void
87
+ )
88
+ }
89
+ }
90
+ })
91
+
92
+ yield* Effect.addFinalizer(() => Effect.promise(() => server.stop()))
93
+
94
+ return Server.make({
95
+ address: { _tag: "TcpAddress", port: server.port!, hostname: server.hostname! },
96
+ serve: Effect.fnUntraced(function*(httpApp, middleware) {
97
+ const scope = yield* Effect.scope
98
+ const services = yield* Effect.services<never>()
99
+ const httpEffect = HttpEffect.toHandled(httpApp, (request, response) =>
100
+ Effect.sync(() => {
101
+ ;(request as BunServerRequest).resolve(makeResponse(request, response, services, scope))
102
+ }), middleware)
103
+
104
+ function handler(request: Request, server: BunServer<WebSocketContext>) {
105
+ return new Promise<Response>((resolve, _reject) => {
106
+ const map = new Map(services.mapUnsafe)
107
+ map.set(
108
+ ServerRequest.HttpServerRequest.key,
109
+ new BunServerRequest(request, resolve, removeHost(request.url), server)
110
+ )
111
+ const fiber = Fiber.runIn(Effect.runForkWith(ServiceMap.makeUnsafe<any>(map))(httpEffect), scope)
112
+ request.signal.addEventListener("abort", () => {
113
+ fiber.interruptUnsafe(Error.clientAbortFiberId)
114
+ }, { once: true })
115
+ })
116
+ }
117
+
118
+ yield* Effect.acquireRelease(
119
+ Effect.sync(() => {
120
+ handlerStack.push(handler)
121
+ server.reload({ fetch: handler })
122
+ }),
123
+ () =>
124
+ Effect.sync(() => {
125
+ handlerStack.pop()
126
+ server.reload({ fetch: handlerStack[handlerStack.length - 1] })
127
+ })
128
+ )
129
+ })
130
+ })
131
+ }
132
+ )
133
+
134
+ const makeResponse = (
135
+ request: ServerRequest.HttpServerRequest,
136
+ response: ServerResponse.HttpServerResponse,
137
+ services: ServiceMap.ServiceMap<never>,
138
+ scope: Scope.Scope
139
+ ): Response => {
140
+ const fields: {
141
+ headers: globalThis.Headers
142
+ status?: number
143
+ statusText?: string
144
+ } = {
145
+ headers: new globalThis.Headers(response.headers),
146
+ status: response.status
147
+ }
148
+
149
+ if (!Cookies.isEmpty(response.cookies)) {
150
+ for (const header of Cookies.toSetCookieHeaders(response.cookies)) {
151
+ fields.headers.append("set-cookie", header)
152
+ }
153
+ }
154
+
155
+ if (response.statusText !== undefined) {
156
+ fields.statusText = response.statusText
157
+ }
158
+
159
+ if (request.method === "HEAD") {
160
+ return new Response(undefined, fields)
161
+ }
162
+ response = HttpEffect.scopeTransferToStream(response)
163
+ const body = response.body
164
+ switch (body._tag) {
165
+ case "Empty": {
166
+ return new Response(undefined, fields)
167
+ }
168
+ case "Uint8Array":
169
+ case "Raw": {
170
+ if (body.body instanceof Response) {
171
+ for (const [key, value] of fields.headers.entries()) {
172
+ body.body.headers.set(key, value)
173
+ }
174
+ return body.body
175
+ }
176
+ return new Response(body.body as any, fields)
177
+ }
178
+ case "FormData": {
179
+ return new Response(body.formData as any, fields)
180
+ }
181
+ case "Stream": {
182
+ return new Response(
183
+ Stream.toReadableStreamWith(
184
+ Stream.unwrap(Effect.withFiber((fiber) => {
185
+ Fiber.runIn(fiber, scope)
186
+ return Effect.succeed(body.stream)
187
+ })),
188
+ services
189
+ ),
190
+ fields
191
+ )
192
+ }
193
+ }
194
+ }
38
195
 
39
196
  /**
40
197
  * @since 1.0.0
41
- * @category layers
198
+ * @category Layers
42
199
  */
43
- export const layerServer: <R extends { [K in keyof R]: Bun.RouterTypes.RouteValue<Extract<K, string>> } = {}>(
200
+ export const layerServer: <R extends string>(
44
201
  options: ServeOptions<R>
45
- ) => Layer.Layer<Server.HttpServer> = internal.layerServer
202
+ ) => Layer.Layer<Server.HttpServer> = flow(make, Layer.effect(Server.HttpServer)) as any
46
203
 
47
204
  /**
48
205
  * @since 1.0.0
49
- * @category layers
206
+ * @category Layers
50
207
  */
51
- export const layer: <R extends { [K in keyof R]: Bun.RouterTypes.RouteValue<Extract<K, string>> } = {}>(
52
- options: ServeOptions<R>
53
- ) => Layer.Layer<Server.HttpServer | Platform.HttpPlatform | Etag.Generator | BunContext.BunContext> = internal.layer
208
+ export const layerHttpServices: Layer.Layer<
209
+ | HttpPlatform
210
+ | Etag.Generator
211
+ | BunServices.BunServices
212
+ > = Layer.mergeAll(
213
+ Platform.layer,
214
+ Etag.layerWeak,
215
+ BunServices.layer
216
+ )
54
217
 
55
218
  /**
56
- * Layer starting a server on a random port and producing an `HttpClient`
57
- * with prepended url of the running http server.
58
- *
59
219
  * @since 1.0.0
60
- * @category layers
220
+ * @category Layers
61
221
  */
62
- export const layerTest: Layer.Layer<
63
- | HttpClient.HttpClient
222
+ export const layer = <R extends string>(
223
+ options: ServeOptions<R>
224
+ ): Layer.Layer<
64
225
  | Server.HttpServer
65
- | Platform.HttpPlatform
226
+ | HttpPlatform
66
227
  | Etag.Generator
67
- | BunContext.BunContext,
68
- HttpServerError.ServeError
69
- > = internal.layerTest
228
+ | BunServices.BunServices
229
+ > => Layer.mergeAll(layerServer(options), layerHttpServices)
70
230
 
71
231
  /**
72
232
  * @since 1.0.0
73
- * @category layers
233
+ * @category Layers
74
234
  */
75
- export const layerConfig: <R extends { [K in keyof R]: Bun.RouterTypes.RouteValue<Extract<K, string>> } = {}>(
76
- options: Config.Config.Wrap<ServeOptions<R>>
77
- ) => Layer.Layer<
78
- Server.HttpServer | Platform.HttpPlatform | Etag.Generator | BunContext.BunContext,
79
- ConfigError.ConfigError
80
- > = internal.layerConfig
235
+ export const layerTest: Layer.Layer<
236
+ Server.HttpServer | HttpPlatform | FileSystem.FileSystem | Etag.Generator | Path.Path | HttpClient
237
+ > = Server.layerTestClient.pipe(
238
+ Layer.provide(FetchHttpClient.layer.pipe(
239
+ Layer.provide(Layer.succeed(FetchHttpClient.RequestInit)({ keepalive: false }))
240
+ )),
241
+ Layer.provideMerge(layer({ port: 0 }))
242
+ )
81
243
 
82
244
  /**
83
- * A Layer providing the `HttpPlatform`, `FileSystem`, `Etag.Generator`, and `Path`
84
- * services.
85
- *
86
- * The `FileSystem` service is a no-op implementation, so this layer is only
87
- * useful for platforms that have no file system.
88
- *
89
245
  * @since 1.0.0
90
- * @category layers
246
+ * @category Layers
91
247
  */
92
- export const layerContext: Layer.Layer<
93
- | Platform.HttpPlatform
94
- | Etag.Generator
95
- | BunContext.BunContext
96
- > = internal.layerContext
248
+ export const layerConfig = <R extends string>(
249
+ options: Config.Wrap<ServeOptions<R>>
250
+ ): Layer.Layer<
251
+ Server.HttpServer | HttpPlatform | FileSystem.FileSystem | Etag.Generator | Path.Path,
252
+ ConfigError
253
+ > =>
254
+ Layer.mergeAll(
255
+ Layer.effect(Server.HttpServer)(Effect.flatMap(Config.unwrap(options).asEffect(), make)),
256
+ layerHttpServices
257
+ )
258
+
259
+ // -----------------------------------------------------------------------------
260
+ // Internal
261
+ // -----------------------------------------------------------------------------
262
+
263
+ interface WebSocketContext {
264
+ readonly deferred: Deferred.Deferred<ServerWebSocket<WebSocketContext>>
265
+ readonly closeDeferred: Deferred.Deferred<void, Socket.SocketError>
266
+ readonly buffer: Array<Uint8Array | string>
267
+ run: (_: Uint8Array | string) => void
268
+ }
269
+
270
+ function wsDefaultRun(this: WebSocketContext, _: Uint8Array | string) {
271
+ this.buffer.push(_)
272
+ }
273
+
274
+ class BunServerRequest extends Inspectable.Class implements ServerRequest.HttpServerRequest {
275
+ readonly [ServerRequest.TypeId]: typeof ServerRequest.TypeId
276
+ readonly [IncomingMessage.TypeId]: typeof IncomingMessage.TypeId
277
+ readonly source: Request
278
+ public resolve: (response: Response) => void
279
+ readonly url: string
280
+ private bunServer: BunServer<WebSocketContext>
281
+ public headersOverride?: Headers.Headers | undefined
282
+ private remoteAddressOverride?: string | undefined
283
+
284
+ constructor(
285
+ source: Request,
286
+ resolve: (response: Response) => void,
287
+ url: string,
288
+ bunServer: BunServer<WebSocketContext>,
289
+ headersOverride?: Headers.Headers,
290
+ remoteAddressOverride?: string
291
+ ) {
292
+ super()
293
+ this[ServerRequest.TypeId] = ServerRequest.TypeId
294
+ this[IncomingMessage.TypeId] = IncomingMessage.TypeId
295
+ this.source = source
296
+ this.resolve = resolve
297
+ this.url = url
298
+ this.bunServer = bunServer
299
+ this.headersOverride = headersOverride
300
+ this.remoteAddressOverride = remoteAddressOverride
301
+ }
302
+ toJSON(): unknown {
303
+ return IncomingMessage.inspect(this, {
304
+ _id: "HttpServerRequest",
305
+ method: this.method,
306
+ url: this.originalUrl
307
+ })
308
+ }
309
+ modify(
310
+ options: {
311
+ readonly url?: string | undefined
312
+ readonly headers?: Headers.Headers | undefined
313
+ readonly remoteAddress?: string | undefined
314
+ }
315
+ ) {
316
+ return new BunServerRequest(
317
+ this.source,
318
+ this.resolve,
319
+ options.url ?? this.url,
320
+ this.bunServer,
321
+ options.headers ?? this.headersOverride,
322
+ options.remoteAddress ?? this.remoteAddressOverride
323
+ )
324
+ }
325
+ get method(): HttpMethod {
326
+ return this.source.method.toUpperCase() as HttpMethod
327
+ }
328
+ get originalUrl() {
329
+ return this.source.url
330
+ }
331
+ get remoteAddress(): string | undefined {
332
+ return this.remoteAddressOverride ?? this.bunServer.requestIP(this.source)?.address
333
+ }
334
+ get headers(): Headers.Headers {
335
+ this.headersOverride ??= Headers.fromInput(this.source.headers)
336
+ return this.headersOverride
337
+ }
338
+
339
+ private cachedCookies: Record.ReadonlyRecord<string, string> | undefined
340
+ get cookies() {
341
+ if (this.cachedCookies) {
342
+ return this.cachedCookies
343
+ }
344
+ return this.cachedCookies = Cookies.parseHeader(this.headers.cookie ?? "")
345
+ }
346
+
347
+ get stream(): Stream.Stream<Uint8Array, Error.HttpServerError> {
348
+ return this.source.body
349
+ ? BunStream.fromReadableStream({
350
+ evaluate: () => this.source.body as any,
351
+ onError: (cause) =>
352
+ new Error.HttpServerError({
353
+ reason: new Error.RequestParseError({
354
+ request: this,
355
+ cause
356
+ })
357
+ })
358
+ })
359
+ : Stream.fail(
360
+ new Error.HttpServerError({
361
+ reason: new Error.RequestParseError({
362
+ request: this,
363
+ description: "can not create stream from empty body"
364
+ })
365
+ })
366
+ )
367
+ }
368
+
369
+ private textEffect: Effect.Effect<string, Error.HttpServerError> | undefined
370
+ get text(): Effect.Effect<string, Error.HttpServerError> {
371
+ if (this.textEffect) {
372
+ return this.textEffect
373
+ }
374
+ this.textEffect = Effect.runSync(Effect.cached(
375
+ Effect.tryPromise({
376
+ try: () => this.source.text(),
377
+ catch: (cause) =>
378
+ new Error.HttpServerError({
379
+ reason: new Error.RequestParseError({
380
+ request: this,
381
+ cause
382
+ })
383
+ })
384
+ })
385
+ ))
386
+ return this.textEffect
387
+ }
388
+
389
+ get json(): Effect.Effect<unknown, Error.HttpServerError> {
390
+ return Effect.flatMap(this.text, (_) =>
391
+ Effect.try({
392
+ try: () => JSON.parse(_) as unknown,
393
+ catch: (cause) =>
394
+ new Error.HttpServerError({
395
+ reason: new Error.RequestParseError({
396
+ request: this,
397
+ cause
398
+ })
399
+ })
400
+ }))
401
+ }
402
+
403
+ get urlParamsBody(): Effect.Effect<UrlParams.UrlParams, Error.HttpServerError> {
404
+ return Effect.flatMap(this.text, (_) =>
405
+ Effect.try({
406
+ try: () => UrlParams.fromInput(new URLSearchParams(_)),
407
+ catch: (cause) =>
408
+ new Error.HttpServerError({
409
+ reason: new Error.RequestParseError({
410
+ request: this,
411
+ cause
412
+ })
413
+ })
414
+ }))
415
+ }
416
+
417
+ private multipartEffect:
418
+ | Effect.Effect<
419
+ Multipart.Persisted,
420
+ Multipart.MultipartError,
421
+ Scope.Scope | FileSystem.FileSystem | Path.Path
422
+ >
423
+ | undefined
424
+ get multipart(): Effect.Effect<
425
+ Multipart.Persisted,
426
+ Multipart.MultipartError,
427
+ Scope.Scope | FileSystem.FileSystem | Path.Path
428
+ > {
429
+ if (this.multipartEffect) {
430
+ return this.multipartEffect
431
+ }
432
+ this.multipartEffect = Effect.runSync(Effect.cached(
433
+ BunMultipart.persisted(this.source)
434
+ ))
435
+ return this.multipartEffect
436
+ }
437
+
438
+ get multipartStream(): Stream.Stream<Multipart.Part, Multipart.MultipartError> {
439
+ return BunMultipart.stream(this.source)
440
+ }
441
+
442
+ private arrayBufferEffect: Effect.Effect<ArrayBuffer, Error.HttpServerError> | undefined
443
+ get arrayBuffer(): Effect.Effect<ArrayBuffer, Error.HttpServerError> {
444
+ if (this.arrayBufferEffect) {
445
+ return this.arrayBufferEffect
446
+ }
447
+ this.arrayBufferEffect = Effect.runSync(Effect.cached(
448
+ Effect.tryPromise({
449
+ try: () => this.source.arrayBuffer(),
450
+ catch: (cause) =>
451
+ new Error.HttpServerError({
452
+ reason: new Error.RequestParseError({
453
+ request: this,
454
+ cause
455
+ })
456
+ })
457
+ })
458
+ ))
459
+ return this.arrayBufferEffect
460
+ }
461
+
462
+ get upgrade(): Effect.Effect<Socket.Socket, Error.HttpServerError> {
463
+ return Effect.callback<Socket.Socket, Error.HttpServerError>((resume) => {
464
+ const deferred = Deferred.makeUnsafe<ServerWebSocket<WebSocketContext>>()
465
+ const closeDeferred = Deferred.makeUnsafe<void, Socket.SocketError>()
466
+ const semaphore = Effect.makeSemaphoreUnsafe(1)
467
+
468
+ const success = this.bunServer.upgrade(this.source, {
469
+ data: {
470
+ deferred,
471
+ closeDeferred,
472
+ buffer: [],
473
+ run: wsDefaultRun
474
+ }
475
+ })
476
+ if (!success) {
477
+ resume(Effect.fail(
478
+ new Error.HttpServerError({
479
+ reason: new Error.RequestParseError({
480
+ request: this,
481
+ description: "Not an upgradeable ServerRequest"
482
+ })
483
+ })
484
+ ))
485
+ return
486
+ }
487
+ resume(Effect.map(Deferred.await(deferred), (ws) => {
488
+ const write = (chunk: Uint8Array | string | Socket.CloseEvent) =>
489
+ Effect.sync(() => {
490
+ if (typeof chunk === "string") {
491
+ ws.sendText(chunk)
492
+ } else if (Socket.isCloseEvent(chunk)) {
493
+ ws.close(chunk.code, chunk.reason)
494
+ } else {
495
+ ws.sendBinary(chunk)
496
+ }
497
+
498
+ return true
499
+ })
500
+ const writer = Effect.succeed(write)
501
+ const runRaw = Effect.fnUntraced(
502
+ function*<R, E, _>(
503
+ handler: (_: Uint8Array | string) => Effect.Effect<_, E, R> | void,
504
+ opts?: { readonly onOpen?: Effect.Effect<void> | undefined }
505
+ ) {
506
+ const set = yield* FiberSet.make<any, E>()
507
+ const run = yield* FiberSet.runtime(set)<R>()
508
+ function runRaw(data: Uint8Array | string) {
509
+ const result = handler(data)
510
+ if (Effect.isEffect(result)) {
511
+ run(result)
512
+ }
513
+ }
514
+ ws.data.run = runRaw
515
+ ws.data.buffer.forEach(runRaw)
516
+ ws.data.buffer.length = 0
517
+ if (opts?.onOpen) yield* opts.onOpen
518
+ return yield* FiberSet.join(set)
519
+ },
520
+ Effect.scoped,
521
+ Effect.onExit((exit) => Effect.sync(() => ws.close(exit._tag === "Success" ? 1000 : 1011))),
522
+ Effect.raceFirst(Deferred.await(closeDeferred)),
523
+ semaphore.withPermits(1)
524
+ )
525
+
526
+ const encoder = new TextEncoder()
527
+ const run = <R, E, _>(handler: (_: Uint8Array) => Effect.Effect<_, E, R> | void, opts?: {
528
+ readonly onOpen?: Effect.Effect<void> | undefined
529
+ }) => runRaw((data) => typeof data === "string" ? handler(encoder.encode(data)) : handler(data), opts)
530
+
531
+ return Socket.Socket.of({
532
+ [Socket.TypeId]: Socket.TypeId as typeof Socket.TypeId,
533
+ run,
534
+ runRaw,
535
+ writer
536
+ })
537
+ }))
538
+ })
539
+ }
540
+ }
541
+
542
+ const removeHost = (url: string) => {
543
+ if (url[0] === "/") {
544
+ return url
545
+ }
546
+ const index = url.indexOf("/", url.indexOf("//") + 2)
547
+ return index === -1 ? "/" : url.slice(index)
548
+ }
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * @since 1.0.0
3
3
  */
4
- import type * as ServerRequest from "@effect/platform/HttpServerRequest"
5
- import * as internal from "./internal/httpServer.js"
4
+ import type { HttpServerRequest } from "effect/unstable/http/HttpServerRequest"
6
5
 
7
6
  /**
8
- * @category conversions
9
7
  * @since 1.0.0
8
+ * @category Accessors
10
9
  */
11
- export const toRequest: (self: ServerRequest.HttpServerRequest) => Request = internal.requestSource
10
+ export const toBunServerRequest = <T extends string = string>(self: HttpServerRequest): Bun.BunRequest<T> =>
11
+ (self as any).source
@@ -1,25 +1,36 @@
1
1
  /**
2
2
  * @since 1.0.0
3
3
  */
4
- import type * as FileSystem from "@effect/platform/FileSystem"
5
- import type * as Multipart from "@effect/platform/Multipart"
6
- import type * as Path from "@effect/platform/Path"
7
4
  import type * as Effect from "effect/Effect"
5
+ import type { FileSystem } from "effect/FileSystem"
6
+ import type { Path } from "effect/Path"
8
7
  import type * as Scope from "effect/Scope"
9
- import type * as Stream from "effect/Stream"
10
- import * as internal from "./internal/multipart.js"
8
+ import * as Stream from "effect/Stream"
9
+ import * as Multipart from "effect/unstable/http/Multipart"
10
+ import * as BunStream from "./BunStream.ts"
11
11
 
12
12
  /**
13
13
  * @since 1.0.0
14
- * @category constructors
14
+ * @category Constructors
15
15
  */
16
- export const stream: (source: Request) => Stream.Stream<Multipart.Part, Multipart.MultipartError> = internal.stream
16
+ export const stream = (source: Request): Stream.Stream<Multipart.Part, Multipart.MultipartError> =>
17
+ BunStream.fromReadableStream({
18
+ evaluate: () => source.body!,
19
+ onError: (cause) => Multipart.MultipartError.fromReason("InternalError", cause)
20
+ }).pipe(
21
+ Stream.pipeThroughChannel(Multipart.makeChannel(Object.fromEntries(source.headers)))
22
+ )
17
23
 
18
24
  /**
19
25
  * @since 1.0.0
20
- * @category constructors
26
+ * @category Constructors
21
27
  */
22
- export const persisted: (
28
+ export const persisted = (
23
29
  source: Request
24
- ) => Effect.Effect<Multipart.Persisted, Multipart.MultipartError, FileSystem.FileSystem | Path.Path | Scope.Scope> =
25
- internal.persisted
30
+ ): Effect.Effect<
31
+ Multipart.Persisted,
32
+ Multipart.MultipartError,
33
+ | FileSystem
34
+ | Path
35
+ | Scope.Scope
36
+ > => Multipart.toPersisted(stream(source))