effect 4.0.3 → 4.0.5

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 (449) hide show
  1. package/AGENTS.md +24 -0
  2. package/CLAUDE.md +24 -0
  3. package/ai-docs/package.json +2 -2
  4. package/ai-docs/src/52_graphql/10_basics.ts +117 -0
  5. package/ai-docs/src/52_graphql/20_testing.ts +45 -0
  6. package/ai-docs/src/52_graphql/30_batching.ts +118 -0
  7. package/ai-docs/src/52_graphql/40_aliased-batching.ts +124 -0
  8. package/ai-docs/src/52_graphql/50_errors-and-retries.ts +74 -0
  9. package/ai-docs/src/52_graphql/index.md +6 -0
  10. package/dist/Array.d.ts +90 -6
  11. package/dist/Array.d.ts.map +1 -1
  12. package/dist/Array.js +4 -2
  13. package/dist/Array.js.map +1 -1
  14. package/dist/Channel.d.ts +6 -1
  15. package/dist/Channel.d.ts.map +1 -1
  16. package/dist/Channel.js +17 -3
  17. package/dist/Channel.js.map +1 -1
  18. package/dist/ConfigProvider.d.ts.map +1 -1
  19. package/dist/ConfigProvider.js +33 -32
  20. package/dist/ConfigProvider.js.map +1 -1
  21. package/dist/Context.d.ts.map +1 -1
  22. package/dist/Context.js +9 -0
  23. package/dist/Context.js.map +1 -1
  24. package/dist/Duration.d.ts.map +1 -1
  25. package/dist/Duration.js +2 -5
  26. package/dist/Duration.js.map +1 -1
  27. package/dist/Effect.d.ts +61 -19
  28. package/dist/Effect.d.ts.map +1 -1
  29. package/dist/Effect.js +58 -39
  30. package/dist/Effect.js.map +1 -1
  31. package/dist/FileSystem.d.ts +23 -9
  32. package/dist/FileSystem.d.ts.map +1 -1
  33. package/dist/FileSystem.js.map +1 -1
  34. package/dist/Match.d.ts +20 -6
  35. package/dist/Match.d.ts.map +1 -1
  36. package/dist/Match.js +2 -2
  37. package/dist/Match.js.map +1 -1
  38. package/dist/Path.d.ts +37 -5
  39. package/dist/Path.d.ts.map +1 -1
  40. package/dist/Path.js +36 -5
  41. package/dist/Path.js.map +1 -1
  42. package/dist/RequestResolver.d.ts.map +1 -1
  43. package/dist/RequestResolver.js +4 -10
  44. package/dist/RequestResolver.js.map +1 -1
  45. package/dist/Scheduler.d.ts +9 -0
  46. package/dist/Scheduler.d.ts.map +1 -1
  47. package/dist/Scheduler.js +9 -0
  48. package/dist/Scheduler.js.map +1 -1
  49. package/dist/Schema.d.ts +15 -2
  50. package/dist/Schema.d.ts.map +1 -1
  51. package/dist/Schema.js +16 -2
  52. package/dist/Schema.js.map +1 -1
  53. package/dist/SchemaGetter.d.ts +4 -0
  54. package/dist/SchemaGetter.d.ts.map +1 -1
  55. package/dist/SchemaGetter.js +52 -33
  56. package/dist/SchemaGetter.js.map +1 -1
  57. package/dist/Sink.d.ts.map +1 -1
  58. package/dist/Sink.js +38 -17
  59. package/dist/Sink.js.map +1 -1
  60. package/dist/Stream.d.ts +11 -0
  61. package/dist/Stream.d.ts.map +1 -1
  62. package/dist/Stream.js +16 -1
  63. package/dist/Stream.js.map +1 -1
  64. package/dist/String.d.ts +12 -0
  65. package/dist/String.d.ts.map +1 -1
  66. package/dist/String.js +17 -4
  67. package/dist/String.js.map +1 -1
  68. package/dist/TxRef.d.ts.map +1 -1
  69. package/dist/TxRef.js +3 -2
  70. package/dist/TxRef.js.map +1 -1
  71. package/dist/Utils.js +8 -3
  72. package/dist/Utils.js.map +1 -1
  73. package/dist/ai/AiError.d.ts +10 -10
  74. package/dist/ai/AiError.d.ts.map +1 -1
  75. package/dist/ai/AiError.js +1 -1
  76. package/dist/ai/AiError.js.map +1 -1
  77. package/dist/ai/AnthropicStructuredOutput.js +0 -2
  78. package/dist/ai/AnthropicStructuredOutput.js.map +1 -1
  79. package/dist/ai/Chat.d.ts +2 -2
  80. package/dist/ai/Chat.d.ts.map +1 -1
  81. package/dist/ai/Decision.d.ts +70 -19
  82. package/dist/ai/Decision.d.ts.map +1 -1
  83. package/dist/ai/Decision.js +37 -3
  84. package/dist/ai/Decision.js.map +1 -1
  85. package/dist/ai/DecisionModel.js +1 -1
  86. package/dist/ai/DecisionModel.js.map +1 -1
  87. package/dist/ai/LanguageModel.d.ts +38 -7
  88. package/dist/ai/LanguageModel.d.ts.map +1 -1
  89. package/dist/ai/LanguageModel.js +70 -40
  90. package/dist/ai/LanguageModel.js.map +1 -1
  91. package/dist/ai/McpServer.d.ts +61 -52
  92. package/dist/ai/McpServer.d.ts.map +1 -1
  93. package/dist/ai/McpServer.js +134 -50
  94. package/dist/ai/McpServer.js.map +1 -1
  95. package/dist/ai/Prompt.d.ts.map +1 -1
  96. package/dist/ai/Prompt.js +28 -5
  97. package/dist/ai/Prompt.js.map +1 -1
  98. package/dist/ai/Response.d.ts +5 -4
  99. package/dist/ai/Response.d.ts.map +1 -1
  100. package/dist/ai/Response.js.map +1 -1
  101. package/dist/cli/Completions.d.ts +5 -0
  102. package/dist/cli/Completions.d.ts.map +1 -1
  103. package/dist/cli/Completions.js.map +1 -1
  104. package/dist/cli/Flag.d.ts +100 -0
  105. package/dist/cli/Flag.d.ts.map +1 -1
  106. package/dist/cli/Flag.js +33 -0
  107. package/dist/cli/Flag.js.map +1 -1
  108. package/dist/cli/Param.d.ts +87 -0
  109. package/dist/cli/Param.d.ts.map +1 -1
  110. package/dist/cli/Param.js +30 -0
  111. package/dist/cli/Param.js.map +1 -1
  112. package/dist/cli/internal/command.d.ts.map +1 -1
  113. package/dist/cli/internal/command.js +2 -1
  114. package/dist/cli/internal/command.js.map +1 -1
  115. package/dist/cli/internal/completions/bash.js +4 -3
  116. package/dist/cli/internal/completions/bash.js.map +1 -1
  117. package/dist/cli/internal/completions/descriptor.js +8 -1
  118. package/dist/cli/internal/completions/descriptor.js.map +1 -1
  119. package/dist/cli/internal/completions/fish.js +4 -4
  120. package/dist/cli/internal/completions/fish.js.map +1 -1
  121. package/dist/cli/internal/completions/powershell.js +3 -2
  122. package/dist/cli/internal/completions/powershell.js.map +1 -1
  123. package/dist/cli/internal/completions/zsh.js +7 -3
  124. package/dist/cli/internal/completions/zsh.js.map +1 -1
  125. package/dist/cli/internal/parser.js +11 -3
  126. package/dist/cli/internal/parser.js.map +1 -1
  127. package/dist/cli/internal/wizard.d.ts.map +1 -1
  128. package/dist/cli/internal/wizard.js +2 -1
  129. package/dist/cli/internal/wizard.js.map +1 -1
  130. package/dist/cluster/ClusterWorkflowEngine.d.ts +1 -0
  131. package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
  132. package/dist/cluster/ClusterWorkflowEngine.js +113 -21
  133. package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
  134. package/dist/cluster/MessageStorage.d.ts.map +1 -1
  135. package/dist/cluster/MessageStorage.js +20 -12
  136. package/dist/cluster/MessageStorage.js.map +1 -1
  137. package/dist/cluster/Runners.d.ts.map +1 -1
  138. package/dist/cluster/Runners.js +54 -34
  139. package/dist/cluster/Runners.js.map +1 -1
  140. package/dist/cluster/Sharding.d.ts.map +1 -1
  141. package/dist/cluster/Sharding.js +6 -4
  142. package/dist/cluster/Sharding.js.map +1 -1
  143. package/dist/cluster/internal/entityManager.js +1 -1
  144. package/dist/cluster/internal/entityManager.js.map +1 -1
  145. package/dist/encoding/Sse.d.ts +6 -0
  146. package/dist/encoding/Sse.d.ts.map +1 -1
  147. package/dist/encoding/Sse.js +63 -71
  148. package/dist/encoding/Sse.js.map +1 -1
  149. package/dist/graphql/GraphQL.d.ts +349 -0
  150. package/dist/graphql/GraphQL.d.ts.map +1 -0
  151. package/dist/graphql/GraphQL.js +207 -0
  152. package/dist/graphql/GraphQL.js.map +1 -0
  153. package/dist/graphql/GraphQLClient.d.ts +562 -0
  154. package/dist/graphql/GraphQLClient.d.ts.map +1 -0
  155. package/dist/graphql/GraphQLClient.js +505 -0
  156. package/dist/graphql/GraphQLClient.js.map +1 -0
  157. package/dist/graphql/GraphQLClientError.d.ts +445 -0
  158. package/dist/graphql/GraphQLClientError.d.ts.map +1 -0
  159. package/dist/graphql/GraphQLClientError.js +479 -0
  160. package/dist/graphql/GraphQLClientError.js.map +1 -0
  161. package/dist/graphql/GraphQLGroup.d.ts +118 -0
  162. package/dist/graphql/GraphQLGroup.d.ts.map +1 -0
  163. package/dist/graphql/GraphQLGroup.js +109 -0
  164. package/dist/graphql/GraphQLGroup.js.map +1 -0
  165. package/dist/graphql/GraphQLMiddleware.d.ts +249 -0
  166. package/dist/graphql/GraphQLMiddleware.d.ts.map +1 -0
  167. package/dist/graphql/GraphQLMiddleware.js +130 -0
  168. package/dist/graphql/GraphQLMiddleware.js.map +1 -0
  169. package/dist/graphql/GraphQLProtocol.d.ts +969 -0
  170. package/dist/graphql/GraphQLProtocol.d.ts.map +1 -0
  171. package/dist/graphql/GraphQLProtocol.js +809 -0
  172. package/dist/graphql/GraphQLProtocol.js.map +1 -0
  173. package/dist/graphql/GraphQLResolver.d.ts +453 -0
  174. package/dist/graphql/GraphQLResolver.d.ts.map +1 -0
  175. package/dist/graphql/GraphQLResolver.js +582 -0
  176. package/dist/graphql/GraphQLResolver.js.map +1 -0
  177. package/dist/graphql/index.d.ts +40 -0
  178. package/dist/graphql/index.d.ts.map +1 -0
  179. package/dist/graphql/index.js +41 -0
  180. package/dist/graphql/index.js.map +1 -0
  181. package/dist/http/FetchHttpClient.d.ts +6 -3
  182. package/dist/http/FetchHttpClient.d.ts.map +1 -1
  183. package/dist/http/FetchHttpClient.js +6 -3
  184. package/dist/http/FetchHttpClient.js.map +1 -1
  185. package/dist/http/FindMyWay/internal/router.js +2 -1
  186. package/dist/http/FindMyWay/internal/router.js.map +1 -1
  187. package/dist/http/Headers.d.ts +3 -3
  188. package/dist/http/Headers.d.ts.map +1 -1
  189. package/dist/http/Headers.js +6 -5
  190. package/dist/http/Headers.js.map +1 -1
  191. package/dist/http/HttpClient.d.ts +27 -0
  192. package/dist/http/HttpClient.d.ts.map +1 -1
  193. package/dist/http/HttpClient.js +38 -11
  194. package/dist/http/HttpClient.js.map +1 -1
  195. package/dist/http/HttpClientError.d.ts.map +1 -1
  196. package/dist/http/HttpClientError.js +8 -6
  197. package/dist/http/HttpClientError.js.map +1 -1
  198. package/dist/http/HttpClientRequest.d.ts +147 -4
  199. package/dist/http/HttpClientRequest.d.ts.map +1 -1
  200. package/dist/http/HttpClientRequest.js +47 -1
  201. package/dist/http/HttpClientRequest.js.map +1 -1
  202. package/dist/http/HttpEffect.d.ts.map +1 -1
  203. package/dist/http/HttpEffect.js +14 -7
  204. package/dist/http/HttpEffect.js.map +1 -1
  205. package/dist/http/HttpMiddleware.d.ts +60 -0
  206. package/dist/http/HttpMiddleware.d.ts.map +1 -1
  207. package/dist/http/HttpMiddleware.js +93 -32
  208. package/dist/http/HttpMiddleware.js.map +1 -1
  209. package/dist/http/HttpRouter.d.ts +35 -0
  210. package/dist/http/HttpRouter.d.ts.map +1 -1
  211. package/dist/http/HttpRouter.js +87 -13
  212. package/dist/http/HttpRouter.js.map +1 -1
  213. package/dist/http/HttpServerError.d.ts.map +1 -1
  214. package/dist/http/HttpServerError.js +6 -4
  215. package/dist/http/HttpServerError.js.map +1 -1
  216. package/dist/http/HttpServerRequest.js +2 -2
  217. package/dist/http/HttpServerRequest.js.map +1 -1
  218. package/dist/http/HttpServerResponse.d.ts +8 -6
  219. package/dist/http/HttpServerResponse.d.ts.map +1 -1
  220. package/dist/http/HttpServerResponse.js +27 -16
  221. package/dist/http/HttpServerResponse.js.map +1 -1
  222. package/dist/http/HttpStaticServer.d.ts.map +1 -1
  223. package/dist/http/HttpStaticServer.js +4 -10
  224. package/dist/http/HttpStaticServer.js.map +1 -1
  225. package/dist/http/HttpTraceContext.js +1 -1
  226. package/dist/http/HttpTraceContext.js.map +1 -1
  227. package/dist/http/Multipart.d.ts.map +1 -1
  228. package/dist/http/Multipart.js +15 -1
  229. package/dist/http/Multipart.js.map +1 -1
  230. package/dist/http/Url.d.ts.map +1 -1
  231. package/dist/http/Url.js +2 -1
  232. package/dist/http/Url.js.map +1 -1
  233. package/dist/http/UrlParams.d.ts +112 -8
  234. package/dist/http/UrlParams.d.ts.map +1 -1
  235. package/dist/http/UrlParams.js +141 -14
  236. package/dist/http/UrlParams.js.map +1 -1
  237. package/dist/http/internal/compression.d.ts +1 -1
  238. package/dist/http/internal/compression.d.ts.map +1 -1
  239. package/dist/http/internal/compression.js +2 -10
  240. package/dist/http/internal/compression.js.map +1 -1
  241. package/dist/http/internal/compressionBody.d.ts +2 -0
  242. package/dist/http/internal/compressionBody.d.ts.map +1 -0
  243. package/dist/http/internal/compressionBody.js +36 -0
  244. package/dist/http/internal/compressionBody.js.map +1 -0
  245. package/dist/http/internal/decompression.d.ts +2 -0
  246. package/dist/http/internal/decompression.d.ts.map +1 -0
  247. package/dist/http/internal/decompression.js +162 -0
  248. package/dist/http/internal/decompression.js.map +1 -0
  249. package/dist/http/internal/tracing.js +14 -4
  250. package/dist/http/internal/tracing.js.map +1 -1
  251. package/dist/http/internal/urlParams.d.ts +2 -0
  252. package/dist/http/internal/urlParams.d.ts.map +1 -0
  253. package/dist/http/internal/urlParams.js +4 -0
  254. package/dist/http/internal/urlParams.js.map +1 -0
  255. package/dist/http-api/HttpApiClient.d.ts.map +1 -1
  256. package/dist/http-api/HttpApiClient.js +2 -1
  257. package/dist/http-api/HttpApiClient.js.map +1 -1
  258. package/dist/http-api/HttpApiScalar.d.ts +5 -0
  259. package/dist/http-api/HttpApiScalar.d.ts.map +1 -1
  260. package/dist/http-api/HttpApiScalar.js.map +1 -1
  261. package/dist/internal/core.js +17 -1
  262. package/dist/internal/core.js.map +1 -1
  263. package/dist/internal/dateTime.js +40 -35
  264. package/dist/internal/dateTime.js.map +1 -1
  265. package/dist/internal/effect.js +13 -6
  266. package/dist/internal/effect.js.map +1 -1
  267. package/dist/internal/graphql.d.ts +2 -0
  268. package/dist/internal/graphql.d.ts.map +1 -0
  269. package/dist/internal/graphql.js +205 -0
  270. package/dist/internal/graphql.js.map +1 -0
  271. package/dist/internal/graphqlHeaders.d.ts +4 -0
  272. package/dist/internal/graphqlHeaders.d.ts.map +1 -0
  273. package/dist/internal/graphqlHeaders.js +11 -0
  274. package/dist/internal/graphqlHeaders.js.map +1 -0
  275. package/dist/internal/request.js +20 -1
  276. package/dist/internal/request.js.map +1 -1
  277. package/dist/internal/schema/toCodeDocument.js +4 -1
  278. package/dist/internal/schema/toCodeDocument.js.map +1 -1
  279. package/dist/internal/schema/toJsonSchemaDocument.js +29 -5
  280. package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
  281. package/dist/internal/version.js +1 -1
  282. package/dist/net/Host.d.ts +49 -0
  283. package/dist/net/Host.d.ts.map +1 -1
  284. package/dist/net/Host.js +55 -0
  285. package/dist/net/Host.js.map +1 -1
  286. package/dist/net/NetAddress.d.ts +8 -0
  287. package/dist/net/NetAddress.d.ts.map +1 -1
  288. package/dist/net/NetAddress.js +8 -0
  289. package/dist/net/NetAddress.js.map +1 -1
  290. package/dist/observability/Otlp.d.ts +15 -0
  291. package/dist/observability/Otlp.d.ts.map +1 -1
  292. package/dist/observability/Otlp.js +3 -0
  293. package/dist/observability/Otlp.js.map +1 -1
  294. package/dist/observability/OtlpExporter.d.ts +8 -0
  295. package/dist/observability/OtlpExporter.d.ts.map +1 -1
  296. package/dist/observability/OtlpExporter.js +10 -1
  297. package/dist/observability/OtlpExporter.js.map +1 -1
  298. package/dist/observability/OtlpLogger.d.ts +17 -0
  299. package/dist/observability/OtlpLogger.d.ts.map +1 -1
  300. package/dist/observability/OtlpLogger.js +14 -1
  301. package/dist/observability/OtlpLogger.js.map +1 -1
  302. package/dist/observability/OtlpMetrics.d.ts +17 -0
  303. package/dist/observability/OtlpMetrics.d.ts.map +1 -1
  304. package/dist/observability/OtlpMetrics.js +13 -0
  305. package/dist/observability/OtlpMetrics.js.map +1 -1
  306. package/dist/observability/OtlpTracer.d.ts +17 -0
  307. package/dist/observability/OtlpTracer.d.ts.map +1 -1
  308. package/dist/observability/OtlpTracer.js +15 -2
  309. package/dist/observability/OtlpTracer.js.map +1 -1
  310. package/dist/reactivity/AsyncResult.d.ts +6 -0
  311. package/dist/reactivity/AsyncResult.d.ts.map +1 -1
  312. package/dist/reactivity/AsyncResult.js +27 -0
  313. package/dist/reactivity/AsyncResult.js.map +1 -1
  314. package/dist/reactivity/AtomRegistry.js +3 -1
  315. package/dist/reactivity/AtomRegistry.js.map +1 -1
  316. package/dist/rpc/RpcClient.d.ts.map +1 -1
  317. package/dist/rpc/RpcClient.js +6 -1
  318. package/dist/rpc/RpcClient.js.map +1 -1
  319. package/dist/rpc/RpcServer.d.ts.map +1 -1
  320. package/dist/rpc/RpcServer.js +36 -9
  321. package/dist/rpc/RpcServer.js.map +1 -1
  322. package/dist/socket/Socket.d.ts +6 -0
  323. package/dist/socket/Socket.d.ts.map +1 -1
  324. package/dist/socket/Socket.js.map +1 -1
  325. package/dist/sql/SqlClient.d.ts +8 -7
  326. package/dist/sql/SqlClient.d.ts.map +1 -1
  327. package/dist/sql/SqlClient.js +8 -7
  328. package/dist/sql/SqlClient.js.map +1 -1
  329. package/dist/testing/TestClock.d.ts +16 -3
  330. package/dist/testing/TestClock.d.ts.map +1 -1
  331. package/dist/testing/TestClock.js +112 -22
  332. package/dist/testing/TestClock.js.map +1 -1
  333. package/dist/workflow/Activity.js +1 -0
  334. package/dist/workflow/Activity.js.map +1 -1
  335. package/dist/workflow/DurableDeferred.d.ts.map +1 -1
  336. package/dist/workflow/DurableDeferred.js +32 -3
  337. package/dist/workflow/DurableDeferred.js.map +1 -1
  338. package/dist/workflow/Workflow.d.ts +22 -0
  339. package/dist/workflow/Workflow.d.ts.map +1 -1
  340. package/dist/workflow/Workflow.js +15 -3
  341. package/dist/workflow/Workflow.js.map +1 -1
  342. package/dist/workflow/WorkflowEngine.d.ts +44 -3
  343. package/dist/workflow/WorkflowEngine.d.ts.map +1 -1
  344. package/dist/workflow/WorkflowEngine.js +45 -22
  345. package/dist/workflow/WorkflowEngine.js.map +1 -1
  346. package/package.json +6 -3
  347. package/src/Array.ts +95 -6
  348. package/src/Channel.ts +24 -3
  349. package/src/ConfigProvider.ts +40 -44
  350. package/src/Context.ts +9 -0
  351. package/src/Duration.ts +4 -5
  352. package/src/Effect.ts +140 -53
  353. package/src/FileSystem.ts +23 -9
  354. package/src/Match.ts +65 -12
  355. package/src/Path.ts +52 -7
  356. package/src/RequestResolver.ts +4 -10
  357. package/src/Scheduler.ts +9 -0
  358. package/src/Schema.ts +25 -4
  359. package/src/SchemaGetter.ts +47 -35
  360. package/src/Sink.ts +45 -18
  361. package/src/Stream.ts +33 -4
  362. package/src/String.ts +17 -4
  363. package/src/TxRef.ts +4 -2
  364. package/src/Utils.ts +8 -5
  365. package/src/ai/AiError.ts +3 -1
  366. package/src/ai/AnthropicStructuredOutput.ts +2 -2
  367. package/src/ai/Chat.ts +2 -2
  368. package/src/ai/Decision.ts +70 -21
  369. package/src/ai/DecisionModel.ts +1 -1
  370. package/src/ai/LanguageModel.ts +141 -63
  371. package/src/ai/McpServer.ts +259 -145
  372. package/src/ai/Prompt.ts +24 -10
  373. package/src/ai/Response.ts +6 -3
  374. package/src/cli/Completions.ts +5 -0
  375. package/src/cli/Flag.ts +101 -0
  376. package/src/cli/Param.ts +96 -0
  377. package/src/cli/internal/command.ts +2 -1
  378. package/src/cli/internal/completions/bash.ts +4 -3
  379. package/src/cli/internal/completions/descriptor.ts +10 -1
  380. package/src/cli/internal/completions/fish.ts +4 -4
  381. package/src/cli/internal/completions/powershell.ts +5 -2
  382. package/src/cli/internal/completions/zsh.ts +7 -3
  383. package/src/cli/internal/parser.ts +12 -3
  384. package/src/cli/internal/wizard.ts +2 -1
  385. package/src/cluster/ClusterWorkflowEngine.ts +143 -36
  386. package/src/cluster/MessageStorage.ts +14 -3
  387. package/src/cluster/Runners.ts +88 -66
  388. package/src/cluster/Sharding.ts +12 -9
  389. package/src/cluster/internal/entityManager.ts +1 -1
  390. package/src/encoding/Sse.ts +70 -80
  391. package/src/graphql/GraphQL.ts +494 -0
  392. package/src/graphql/GraphQLClient.ts +924 -0
  393. package/src/graphql/GraphQLClientError.ts +542 -0
  394. package/src/graphql/GraphQLGroup.ts +167 -0
  395. package/src/graphql/GraphQLMiddleware.ts +253 -0
  396. package/src/graphql/GraphQLProtocol.ts +1540 -0
  397. package/src/graphql/GraphQLResolver.ts +1038 -0
  398. package/src/graphql/index.ts +48 -0
  399. package/src/http/FetchHttpClient.ts +6 -3
  400. package/src/http/FindMyWay/internal/router.ts +2 -1
  401. package/src/http/Headers.ts +6 -9
  402. package/src/http/HttpClient.ts +72 -11
  403. package/src/http/HttpClientError.ts +10 -6
  404. package/src/http/HttpClientRequest.ts +173 -7
  405. package/src/http/HttpEffect.ts +11 -5
  406. package/src/http/HttpMiddleware.ts +113 -34
  407. package/src/http/HttpRouter.ts +95 -13
  408. package/src/http/HttpServerError.ts +8 -4
  409. package/src/http/HttpServerRequest.ts +2 -2
  410. package/src/http/HttpServerResponse.ts +28 -16
  411. package/src/http/HttpStaticServer.ts +4 -10
  412. package/src/http/HttpTraceContext.ts +1 -1
  413. package/src/http/Multipart.ts +17 -1
  414. package/src/http/Url.ts +2 -1
  415. package/src/http/UrlParams.ts +225 -26
  416. package/src/http/internal/compression.ts +3 -17
  417. package/src/http/internal/compressionBody.ts +56 -0
  418. package/src/http/internal/decompression.ts +226 -0
  419. package/src/http/internal/tracing.ts +21 -4
  420. package/src/http/internal/urlParams.ts +5 -0
  421. package/src/http-api/HttpApiClient.ts +2 -1
  422. package/src/http-api/HttpApiScalar.ts +5 -0
  423. package/src/internal/core.ts +21 -1
  424. package/src/internal/dateTime.ts +13 -10
  425. package/src/internal/effect.ts +13 -7
  426. package/src/internal/graphql.ts +286 -0
  427. package/src/internal/graphqlHeaders.ts +11 -0
  428. package/src/internal/request.ts +31 -3
  429. package/src/internal/schema/toCodeDocument.ts +7 -1
  430. package/src/internal/schema/toJsonSchemaDocument.ts +34 -2
  431. package/src/internal/version.ts +1 -1
  432. package/src/net/Host.ts +72 -0
  433. package/src/net/NetAddress.ts +9 -0
  434. package/src/observability/Otlp.ts +18 -0
  435. package/src/observability/OtlpExporter.ts +14 -3
  436. package/src/observability/OtlpLogger.ts +31 -2
  437. package/src/observability/OtlpMetrics.ts +30 -1
  438. package/src/observability/OtlpTracer.ts +32 -3
  439. package/src/reactivity/AsyncResult.ts +31 -0
  440. package/src/reactivity/AtomRegistry.ts +3 -1
  441. package/src/rpc/RpcClient.ts +6 -1
  442. package/src/rpc/RpcServer.ts +55 -15
  443. package/src/socket/Socket.ts +6 -0
  444. package/src/sql/SqlClient.ts +9 -7
  445. package/src/testing/TestClock.ts +144 -29
  446. package/src/workflow/Activity.ts +1 -0
  447. package/src/workflow/DurableDeferred.ts +43 -5
  448. package/src/workflow/Workflow.ts +31 -5
  449. package/src/workflow/WorkflowEngine.ts +107 -25
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @stability experimental
3
+ * @since 4.0.0
4
+ */
5
+
6
+ // @barrel: Auto-generated exports. Do not edit manually.
7
+
8
+ /**
9
+ * @stability experimental
10
+ * @since 4.0.0
11
+ */
12
+ export * as GraphQL from "./GraphQL.ts"
13
+
14
+ /**
15
+ * @stability experimental
16
+ * @since 4.0.0
17
+ */
18
+ export * as GraphQLClient from "./GraphQLClient.ts"
19
+
20
+ /**
21
+ * @stability experimental
22
+ * @since 4.0.0
23
+ */
24
+ export * as GraphQLClientError from "./GraphQLClientError.ts"
25
+
26
+ /**
27
+ * @stability experimental
28
+ * @since 4.0.0
29
+ */
30
+ export * as GraphQLGroup from "./GraphQLGroup.ts"
31
+
32
+ /**
33
+ * @stability experimental
34
+ * @since 4.0.0
35
+ */
36
+ export * as GraphQLMiddleware from "./GraphQLMiddleware.ts"
37
+
38
+ /**
39
+ * @stability experimental
40
+ * @since 4.0.0
41
+ */
42
+ export * as GraphQLProtocol from "./GraphQLProtocol.ts"
43
+
44
+ /**
45
+ * @stability experimental
46
+ * @since 4.0.0
47
+ */
48
+ export * as GraphQLResolver from "./GraphQLResolver.ts"
@@ -115,12 +115,15 @@ const fetch: HttpClient.HttpClient = HttpClient.make((request, url, signal, fibe
115
115
  * **Gotchas**
116
116
  *
117
117
  * Fetch behavior comes from the runtime's implementation, so CORS, cookies,
118
- * redirects, abort handling, and streaming support can vary by platform. Stream
119
- * request bodies are sent as Web streams with `duplex: "half"`, and any
120
- * `content-length` header is removed before calling `fetch`.
118
+ * redirects, abort handling, and streaming support can vary by platform. Trace
119
+ * propagation is on by default, and a browser preflight fails unless the
120
+ * target allows `b3` and `traceparent`. Stream request bodies are sent as Web
121
+ * streams with `duplex: "half"`, and any `content-length` header is removed
122
+ * before calling `fetch`.
121
123
  *
122
124
  * @see {@link Fetch} for supplying the fetch implementation used by this layer
123
125
  * @see {@link RequestInit} for default `RequestInit` options applied before request-specific fields
126
+ * @see {@link HttpClient.TracerPropagationEnabled} for leaving `b3` and `traceparent` off a browser request
124
127
  *
125
128
  * @stability unstable
126
129
  * @category layers
@@ -857,7 +857,8 @@ function makeCreateParams(
857
857
  }
858
858
  }
859
859
 
860
- function getClosingParenthensePosition(path: string, idx: number) {
860
+ /** @internal */
861
+ export function getClosingParenthensePosition(path: string, idx: number) {
861
862
  // `path.indexOf()` will always return the first position of the closing parenthese,
862
863
  // but it's inefficient for grouped or wrong regexp expressions.
863
864
  // see issues #62 and #63 for more info
@@ -731,10 +731,11 @@ export const isRedactedName = (
731
731
  name: string,
732
732
  patterns: ReadonlyArray<string | RegExp>
733
733
  ): boolean => {
734
+ const lowerName = name.toLowerCase()
734
735
  for (let i = 0; i < patterns.length; i++) {
735
736
  const pattern = patterns[i]
736
737
  if (typeof pattern === "string") {
737
- if (pattern.toLowerCase() === name.toLowerCase()) {
738
+ if (pattern.toLowerCase() === lowerName) {
738
739
  return true
739
740
  }
740
741
  } else if (name.search(pattern) !== -1) {
@@ -749,9 +750,9 @@ export const isRedactedName = (
749
750
  *
750
751
  * **Details**
751
752
  *
752
- * Defaults include `authorization`, `cookie`, `set-cookie`, `x-api-key` and
753
- * `AWSAccessKeyId`, `Signature`, `sig` and `X-Goog-Signature`. Names match
754
- * case-insensitively, and providing a new list replaces the defaults.
753
+ * Defaults include `authorization`, `cookie`, `set-cookie` and `x-api-key`.
754
+ * A custom list replaces the defaults. Matching uses `isRedactedName`.
755
+ * Use `UrlParams.CurrentRedactedNames` for query parameters.
755
756
  *
756
757
  * @stability unstable
757
758
  * @category services
@@ -764,10 +765,6 @@ export const CurrentRedactedNames = Context.Reference<
764
765
  "authorization",
765
766
  "cookie",
766
767
  "set-cookie",
767
- "x-api-key",
768
- "AWSAccessKeyId",
769
- "Signature",
770
- "sig",
771
- "X-Goog-Signature"
768
+ "x-api-key"
772
769
  ]
773
770
  })
@@ -47,6 +47,7 @@ import * as HttpMethod from "./HttpMethod.ts"
47
47
  import * as TraceContext from "./HttpTraceContext.ts"
48
48
  import * as tracing from "./internal/tracing.ts"
49
49
  import * as Url from "./Url.ts"
50
+ import * as UrlParams from "./UrlParams.ts"
50
51
 
51
52
  const TypeId = "~effect/http/HttpClient"
52
53
 
@@ -905,7 +906,11 @@ export const make = (
905
906
  (span) => {
906
907
  span.attribute("http.request.method", request.method)
907
908
  const redactedHeaderNames = fiber.getRef(Headers.CurrentRedactedNames)
908
- tracing.addUrlAttributes(span, url)
909
+ tracing.addUrlAttributes(
910
+ span,
911
+ url,
912
+ tracing.redactedNames(request.urlParams, fiber.getRef(UrlParams.CurrentRedactedNames))
913
+ )
909
914
  const headerFilter = fiber.getRef(TracerHeaderFilter)
910
915
  tracing.addHeaderAttributes(span, "request", request.headers, headerFilter, redactedHeaderNames)
911
916
  request = fiber.getRef(TracerPropagationEnabled)
@@ -1204,6 +1209,9 @@ export const retry: {
1204
1209
  * Specifying a `while` predicate allows you to consider other errors as
1205
1210
  * transient, and is ignored in "response-only" mode.
1206
1211
  *
1212
+ * A `Retry-After` header on a transient response, or on the response of a
1213
+ * status code error, sets the minimum delay before the next attempt.
1214
+ *
1207
1215
  * @stability unstable
1208
1216
  * @category error handling
1209
1217
  * @since 4.0.0
@@ -1221,6 +1229,9 @@ export const retryTransient: {
1221
1229
  * Specifying a `while` predicate allows you to consider other errors as
1222
1230
  * transient, and is ignored in "response-only" mode.
1223
1231
  *
1232
+ * A `Retry-After` header on a transient response, or on the response of a
1233
+ * status code error, sets the minimum delay before the next attempt.
1234
+ *
1224
1235
  * @stability unstable
1225
1236
  * @category error handling
1226
1237
  * @since 4.0.0
@@ -1257,6 +1268,9 @@ export const retryTransient: {
1257
1268
  * Specifying a `while` predicate allows you to consider other errors as
1258
1269
  * transient, and is ignored in "response-only" mode.
1259
1270
  *
1271
+ * A `Retry-After` header on a transient response, or on the response of a
1272
+ * status code error, sets the minimum delay before the next attempt.
1273
+ *
1260
1274
  * @stability unstable
1261
1275
  * @category error handling
1262
1276
  * @since 4.0.0
@@ -1295,6 +1309,9 @@ export const retryTransient: {
1295
1309
  * Specifying a `while` predicate allows you to consider other errors as
1296
1310
  * transient, and is ignored in "response-only" mode.
1297
1311
  *
1312
+ * A `Retry-After` header on a transient response, or on the response of a
1313
+ * status code error, sets the minimum delay before the next attempt.
1314
+ *
1298
1315
  * @stability unstable
1299
1316
  * @category error handling
1300
1317
  * @since 4.0.0
@@ -1314,6 +1331,9 @@ export const retryTransient: {
1314
1331
  * Specifying a `while` predicate allows you to consider other errors as
1315
1332
  * transient, and is ignored in "response-only" mode.
1316
1333
  *
1334
+ * A `Retry-After` header on a transient response, or on the response of a
1335
+ * status code error, sets the minimum delay before the next attempt.
1336
+ *
1317
1337
  * @stability unstable
1318
1338
  * @category error handling
1319
1339
  * @since 4.0.0
@@ -1341,14 +1361,15 @@ export const retryTransient: {
1341
1361
  ): HttpClient.With<E | ES, R1 | R> => {
1342
1362
  const isOnlySchedule = Schedule.isSchedule(options)
1343
1363
  const retryOn = isOnlySchedule ? "errors-and-responses" : options.retryOn ?? "errors-and-responses"
1344
- const schedule = isOnlySchedule ? options : options.schedule
1345
- const passthroughSchedule = schedule && Schedule.passthrough(schedule)
1364
+ const schedule = withRetryAfter(
1365
+ isOnlySchedule ? options : options.schedule ?? Schedule.forever
1366
+ )
1346
1367
  const times = isOnlySchedule ? undefined : options.times
1347
1368
  return transformResponse(
1348
1369
  self,
1349
1370
  flow(
1350
1371
  retryOn === "errors-only" ? identity : Effect.repeat({
1351
- schedule: passthroughSchedule!,
1372
+ schedule,
1352
1373
  times,
1353
1374
  while: isTransientResponse
1354
1375
  }),
@@ -1643,7 +1664,10 @@ export const withRateLimiter: {
1643
1664
  */
1644
1665
  Duration.Duration | undefined>(undefined);
1645
1666
  }
1646
- const retryAfter = parseRetryAfter(clock, getHeader(response.headers, ...headerNames.retryAfter))
1667
+ const retryAfter = parseRetryAfter(
1668
+ clock.currentTimeMillisUnsafe(),
1669
+ getHeader(response.headers, ...headerNames.retryAfter)
1670
+ )
1647
1671
  if (retryAfter === undefined) {
1648
1672
  return Effect.succeed</**
1649
1673
  * Applies request rate limiting using the `RateLimiter` service.
@@ -1865,21 +1889,24 @@ const parseRateLimitWindow = (
1865
1889
  }
1866
1890
 
1867
1891
  const parseRetryAfter = (
1868
- clock: Clock,
1892
+ nowMillis: number,
1869
1893
  value: string | undefined
1870
1894
  ): Duration.Duration | undefined => {
1871
1895
  if (value === undefined) {
1872
1896
  return undefined
1873
1897
  }
1874
- const numeric = parseNumberHeader(value)
1875
- if (numeric !== undefined) {
1876
- return Duration.max(Duration.seconds(numeric), Duration.millis(1))
1898
+ const trimmed = value.trim()
1899
+ if (/^\d+(?:\.\d+)?$/.test(trimmed)) {
1900
+ const numeric = Number(trimmed)
1901
+ return Number.isFinite(numeric)
1902
+ ? Duration.max(Duration.seconds(numeric), Duration.millis(1))
1903
+ : undefined
1877
1904
  }
1878
- const parsedDate = Date.parse(value)
1905
+ const parsedDate = Date.parse(trimmed)
1879
1906
  if (Number.isNaN(parsedDate)) {
1880
1907
  return undefined
1881
1908
  }
1882
- const millis = parsedDate - clock.currentTimeMillisUnsafe()
1909
+ const millis = parsedDate - nowMillis
1883
1910
  if (millis <= 0) {
1884
1911
  return Duration.millis(1)
1885
1912
  }
@@ -2233,6 +2260,18 @@ export const TracerHeaderFilter = Context.Reference<
2233
2260
  /**
2234
2261
  * Context reference that controls whether outgoing client spans are propagated to request headers.
2235
2262
  *
2263
+ * **Details**
2264
+ *
2265
+ * When this is `true`, the client writes the compact B3 `b3` header and the
2266
+ * W3C `traceparent` header. The default is on. The client span is still
2267
+ * created when this is `false`.
2268
+ *
2269
+ * **Gotchas**
2270
+ *
2271
+ * A browser preflight fails when the target does not list `b3` and
2272
+ * `traceparent` in `Access-Control-Allow-Headers`. Set this to `false` for
2273
+ * those requests.
2274
+ *
2236
2275
  * @stability unstable
2237
2276
  * @category services
2238
2277
  * @since 4.0.0
@@ -2417,6 +2456,28 @@ const isTransientHttpError = (error: unknown) =>
2417
2456
  (error.reason._tag === "TransportError" ||
2418
2457
  (error.reason._tag === "StatusCodeError" && isTransientResponse(error.reason.response)))
2419
2458
 
2459
+ const retryAfterOf = (input: unknown, nowMillis: number): Duration.Duration | undefined => {
2460
+ const response = Error.isHttpClientError(input)
2461
+ ? input.response
2462
+ : Predicate.hasProperty(input, HttpClientResponse.TypeId)
2463
+ ? input as HttpClientResponse.HttpClientResponse
2464
+ : undefined
2465
+ return parseRetryAfter(nowMillis, response?.headers["retry-after"])
2466
+ }
2467
+
2468
+ const withRetryAfter = <ES, R1>(
2469
+ schedule: Schedule.Schedule<unknown, any, ES, R1>
2470
+ ): Schedule.Schedule<unknown, any, ES, R1> =>
2471
+ Schedule.fromStep(
2472
+ Effect.map(Schedule.toStep(schedule), (step) => (now: number, input: unknown) => {
2473
+ const retryAfter = retryAfterOf(input, now)
2474
+ if (retryAfter === undefined) {
2475
+ return step(now, input)
2476
+ }
2477
+ return Effect.map(step(now, input), ([output, delay]) => [output, Duration.max(delay, retryAfter)])
2478
+ })
2479
+ )
2480
+
2420
2481
  const isTooManyRequestsHttpClientError = (
2421
2482
  error: unknown
2422
2483
  ): error is Error.HttpClientError & { readonly reason: Error.StatusCodeError } =>
@@ -15,6 +15,7 @@ import { hasProperty } from "../Predicate.ts"
15
15
  import * as Schema from "../Schema.ts"
16
16
  import type * as HttpClientRequest from "./HttpClientRequest.ts"
17
17
  import type * as ClientResponse from "./HttpClientResponse.ts"
18
+ import * as UrlParams from "./UrlParams.ts"
18
19
 
19
20
  const TypeId = "~effect/http/HttpClientError"
20
21
 
@@ -88,6 +89,9 @@ const formatReason = (tag: string) => tag.endsWith("Error") ? tag.slice(0, -5) :
88
89
  const formatMessage = (reason: string, description: string | undefined, info: string) =>
89
90
  description ? `${reason}: ${description} (${info})` : `${reason} error (${info})`
90
91
 
92
+ const formatMethodAndUrl = (request: HttpClientRequest.HttpClientRequest) =>
93
+ `${request.method} ${UrlParams.redactUrl(request.url)}`
94
+
91
95
  /**
92
96
  * Error describing transport-level failures that occur while sending an HTTP request.
93
97
  *
@@ -107,7 +111,7 @@ export class TransportError extends Data.TaggedError("TransportError")<{
107
111
  * @since 4.0.0
108
112
  */
109
113
  get methodAndUrl() {
110
- return `${this.request.method} ${this.request.url}`
114
+ return formatMethodAndUrl(this.request)
111
115
  }
112
116
 
113
117
  /**
@@ -140,7 +144,7 @@ export class EncodeError extends Data.TaggedError("EncodeError")<{
140
144
  * @since 4.0.0
141
145
  */
142
146
  get methodAndUrl() {
143
- return `${this.request.method} ${this.request.url}`
147
+ return formatMethodAndUrl(this.request)
144
148
  }
145
149
 
146
150
  /**
@@ -173,7 +177,7 @@ export class InvalidUrlError extends Data.TaggedError("InvalidUrlError")<{
173
177
  * @since 4.0.0
174
178
  */
175
179
  get methodAndUrl() {
176
- return `${this.request.method} ${this.request.url}`
180
+ return formatMethodAndUrl(this.request)
177
181
  }
178
182
 
179
183
  /**
@@ -207,7 +211,7 @@ export class StatusCodeError extends Data.TaggedError("StatusCodeError")<{
207
211
  * @since 4.0.0
208
212
  */
209
213
  get methodAndUrl() {
210
- return `${this.request.method} ${this.request.url}`
214
+ return formatMethodAndUrl(this.request)
211
215
  }
212
216
 
213
217
  /**
@@ -242,7 +246,7 @@ export class DecodeError extends Data.TaggedError("DecodeError")<{
242
246
  * @since 4.0.0
243
247
  */
244
248
  get methodAndUrl() {
245
- return `${this.request.method} ${this.request.url}`
249
+ return formatMethodAndUrl(this.request)
246
250
  }
247
251
 
248
252
  /**
@@ -277,7 +281,7 @@ export class EmptyBodyError extends Data.TaggedError("EmptyBodyError")<{
277
281
  * @since 4.0.0
278
282
  */
279
283
  get methodAndUrl() {
280
- return `${this.request.method} ${this.request.url}`
284
+ return formatMethodAndUrl(this.request)
281
285
  }
282
286
 
283
287
  /**
@@ -30,6 +30,7 @@ import * as Stream from "../Stream.ts"
30
30
  import * as Headers from "./Headers.ts"
31
31
  import * as HttpBody from "./HttpBody.ts"
32
32
  import { hasBody, type HttpMethod } from "./HttpMethod.ts"
33
+ import * as compression from "./internal/compressionBody.ts"
33
34
  import * as bodyInternal from "./internal/httpBody.ts"
34
35
  import * as Url from "./Url.ts"
35
36
  import * as UrlParams from "./UrlParams.ts"
@@ -104,7 +105,7 @@ const Proto = {
104
105
  return {
105
106
  _id: "HttpClientRequest",
106
107
  method: this.method,
107
- url: this.url,
108
+ url: UrlParams.redactUrl(this.url),
108
109
  urlParams: this.urlParams,
109
110
  hash: this.hash,
110
111
  headers: redact(this.headers),
@@ -755,6 +756,10 @@ export const updateUrl: {
755
756
  /**
756
757
  * Sets one query parameter, replacing existing values for that parameter name.
757
758
  *
759
+ * **Details**
760
+ *
761
+ * A `Redacted` value is sent unwrapped and stays redacted in inspection, errors and spans.
762
+ *
758
763
  * @stability unstable
759
764
  * @category combinators
760
765
  * @since 4.0.0
@@ -763,20 +768,28 @@ export const setUrlParam: {
763
768
  /**
764
769
  * Sets one query parameter, replacing existing values for that parameter name.
765
770
  *
771
+ * **Details**
772
+ *
773
+ * A `Redacted` value is sent unwrapped and stays redacted in inspection, errors and spans.
774
+ *
766
775
  * @stability unstable
767
776
  * @category combinators
768
777
  * @since 4.0.0
769
778
  */
770
- (key: string, value: string): (self: HttpClientRequest) => HttpClientRequest
779
+ (key: string, value: string | Redacted.Redacted): (self: HttpClientRequest) => HttpClientRequest
771
780
  /**
772
781
  * Sets one query parameter, replacing existing values for that parameter name.
773
782
  *
783
+ * **Details**
784
+ *
785
+ * A `Redacted` value is sent unwrapped and stays redacted in inspection, errors and spans.
786
+ *
774
787
  * @stability unstable
775
788
  * @category combinators
776
789
  * @since 4.0.0
777
790
  */
778
- (self: HttpClientRequest, key: string, value: string): HttpClientRequest
779
- } = dual(3, (self: HttpClientRequest, key: string, value: string): HttpClientRequest =>
791
+ (self: HttpClientRequest, key: string, value: string | Redacted.Redacted): HttpClientRequest
792
+ } = dual(3, (self: HttpClientRequest, key: string, value: string | Redacted.Redacted): HttpClientRequest =>
780
793
  makeWith(
781
794
  self.method,
782
795
  self.url,
@@ -823,6 +836,10 @@ export const setUrlParams: {
823
836
  /**
824
837
  * Appends one query parameter value without removing existing values for the same name.
825
838
  *
839
+ * **Details**
840
+ *
841
+ * A `Redacted` value is sent unwrapped and stays redacted in inspection, errors and spans.
842
+ *
826
843
  * @stability unstable
827
844
  * @category combinators
828
845
  * @since 4.0.0
@@ -831,20 +848,28 @@ export const appendUrlParam: {
831
848
  /**
832
849
  * Appends one query parameter value without removing existing values for the same name.
833
850
  *
851
+ * **Details**
852
+ *
853
+ * A `Redacted` value is sent unwrapped and stays redacted in inspection, errors and spans.
854
+ *
834
855
  * @stability unstable
835
856
  * @category combinators
836
857
  * @since 4.0.0
837
858
  */
838
- (key: string, value: string): (self: HttpClientRequest) => HttpClientRequest
859
+ (key: string, value: string | Redacted.Redacted): (self: HttpClientRequest) => HttpClientRequest
839
860
  /**
840
861
  * Appends one query parameter value without removing existing values for the same name.
841
862
  *
863
+ * **Details**
864
+ *
865
+ * A `Redacted` value is sent unwrapped and stays redacted in inspection, errors and spans.
866
+ *
842
867
  * @stability unstable
843
868
  * @category combinators
844
869
  * @since 4.0.0
845
870
  */
846
- (self: HttpClientRequest, key: string, value: string): HttpClientRequest
847
- } = dual(3, (self: HttpClientRequest, key: string, value: string): HttpClientRequest =>
871
+ (self: HttpClientRequest, key: string, value: string | Redacted.Redacted): HttpClientRequest
872
+ } = dual(3, (self: HttpClientRequest, key: string, value: string | Redacted.Redacted): HttpClientRequest =>
848
873
  makeWith(
849
874
  self.method,
850
875
  self.url,
@@ -974,6 +999,147 @@ export const setBody: {
974
999
  )
975
1000
  })
976
1001
 
1002
+ /**
1003
+ * Algorithms supported by Web `CompressionStream` for request body compression.
1004
+ *
1005
+ * @stability unstable
1006
+ * @category models
1007
+ * @since 4.0.0
1008
+ */
1009
+ export type CompressionAlgorithm = "gzip" | "deflate"
1010
+
1011
+ /**
1012
+ * Options for request body compression.
1013
+ *
1014
+ * @stability unstable
1015
+ * @category options
1016
+ * @since 4.0.0
1017
+ */
1018
+ export interface CompressionOptions {
1019
+ /**
1020
+ * Minimum known body length in bytes to compress. Defaults to `1024`.
1021
+ * Bodies with unknown length are always compressed.
1022
+ */
1023
+ readonly minSize?: number | undefined
1024
+ }
1025
+
1026
+ /**
1027
+ * Compresses a request body using Web `CompressionStream` and sets `Content-Encoding`.
1028
+ *
1029
+ * **Details**
1030
+ *
1031
+ * Byte-array bodies (including text, JSON, and URL-encoded bodies) are compressed
1032
+ * into a new `Uint8Array` body, preserving the content type and updating
1033
+ * `Content-Length`. The compressed body does not retain the original lazy text.
1034
+ * Stream bodies are compressed lazily and have their content length removed.
1035
+ * They still require a client runtime that supports streaming request bodies
1036
+ * (Fetch requires `duplex: "half"`, which Safari and Firefox do not support).
1037
+ *
1038
+ * Returns the original request unchanged for empty, FormData, and raw bodies,
1039
+ * bodies with a known length below `options.minSize`, or requests with any
1040
+ * existing `Content-Encoding` header, including `identity`. Unknown-length
1041
+ * streams are always compressed. The default minimum is 1024 bytes because
1042
+ * gzip can make very small bodies larger.
1043
+ *
1044
+ * Requires `CompressionStream` (available in browsers, Node 18+, Bun, and Deno).
1045
+ * There is no typed error channel: byte compression failures are defects;
1046
+ * stream failures surface when the body is sent.
1047
+ *
1048
+ * To compress every request, use
1049
+ * `HttpClient.mapRequestEffect(HttpClientRequest.compressBody("gzip"))`.
1050
+ * `HttpClient.retryTransient` re-runs preprocessing, so this recompresses on
1051
+ * every retry. For large bodies, compress once before calling `client.execute`.
1052
+ *
1053
+ * @stability unstable
1054
+ * @category combinators
1055
+ * @since 4.0.0
1056
+ */
1057
+ export const compressBody: {
1058
+ /**
1059
+ * Compresses a request body using Web `CompressionStream` and sets `Content-Encoding`.
1060
+ *
1061
+ * **Details**
1062
+ *
1063
+ * Byte-array bodies (including text, JSON, and URL-encoded bodies) are compressed
1064
+ * into a new `Uint8Array` body, preserving the content type and updating
1065
+ * `Content-Length`. The compressed body does not retain the original lazy text.
1066
+ * Stream bodies are compressed lazily and have their content length removed.
1067
+ * They still require a client runtime that supports streaming request bodies
1068
+ * (Fetch requires `duplex: "half"`, which Safari and Firefox do not support).
1069
+ *
1070
+ * Returns the original request unchanged for empty, FormData, and raw bodies,
1071
+ * bodies with a known length below `options.minSize`, or requests with any
1072
+ * existing `Content-Encoding` header, including `identity`. Unknown-length
1073
+ * streams are always compressed. The default minimum is 1024 bytes because
1074
+ * gzip can make very small bodies larger.
1075
+ *
1076
+ * Requires `CompressionStream` (available in browsers, Node 18+, Bun, and Deno).
1077
+ * There is no typed error channel: byte compression failures are defects;
1078
+ * stream failures surface when the body is sent.
1079
+ *
1080
+ * To compress every request, use
1081
+ * `HttpClient.mapRequestEffect(HttpClientRequest.compressBody("gzip"))`.
1082
+ * `HttpClient.retryTransient` re-runs preprocessing, so this recompresses on
1083
+ * every retry. For large bodies, compress once before calling `client.execute`.
1084
+ *
1085
+ * @stability unstable
1086
+ * @category combinators
1087
+ * @since 4.0.0
1088
+ */
1089
+ (algorithm: CompressionAlgorithm, options?: CompressionOptions | undefined): (self: HttpClientRequest) => Effect.Effect<HttpClientRequest>
1090
+ /**
1091
+ * Compresses a request body using Web `CompressionStream` and sets `Content-Encoding`.
1092
+ *
1093
+ * **Details**
1094
+ *
1095
+ * Byte-array bodies (including text, JSON, and URL-encoded bodies) are compressed
1096
+ * into a new `Uint8Array` body, preserving the content type and updating
1097
+ * `Content-Length`. The compressed body does not retain the original lazy text.
1098
+ * Stream bodies are compressed lazily and have their content length removed.
1099
+ * They still require a client runtime that supports streaming request bodies
1100
+ * (Fetch requires `duplex: "half"`, which Safari and Firefox do not support).
1101
+ *
1102
+ * Returns the original request unchanged for empty, FormData, and raw bodies,
1103
+ * bodies with a known length below `options.minSize`, or requests with any
1104
+ * existing `Content-Encoding` header, including `identity`. Unknown-length
1105
+ * streams are always compressed. The default minimum is 1024 bytes because
1106
+ * gzip can make very small bodies larger.
1107
+ *
1108
+ * Requires `CompressionStream` (available in browsers, Node 18+, Bun, and Deno).
1109
+ * There is no typed error channel: byte compression failures are defects;
1110
+ * stream failures surface when the body is sent.
1111
+ *
1112
+ * To compress every request, use
1113
+ * `HttpClient.mapRequestEffect(HttpClientRequest.compressBody("gzip"))`.
1114
+ * `HttpClient.retryTransient` re-runs preprocessing, so this recompresses on
1115
+ * every retry. For large bodies, compress once before calling `client.execute`.
1116
+ *
1117
+ * @stability unstable
1118
+ * @category combinators
1119
+ * @since 4.0.0
1120
+ */
1121
+ (
1122
+ self: HttpClientRequest,
1123
+ algorithm: CompressionAlgorithm,
1124
+ options?: CompressionOptions | undefined
1125
+ ): Effect.Effect<HttpClientRequest>
1126
+ } = dual(
1127
+ (args) => isHttpClientRequest(args[0]),
1128
+ (
1129
+ self: HttpClientRequest,
1130
+ algorithm: CompressionAlgorithm,
1131
+ options?: CompressionOptions | undefined
1132
+ ): Effect.Effect<HttpClientRequest> => {
1133
+ if (self.headers["content-encoding"] !== undefined) {
1134
+ return Effect.succeed(self)
1135
+ }
1136
+ return Effect.map(
1137
+ compression.compressBody(self.body, algorithm, options),
1138
+ (body) => body === self.body ? self : setHeader(setBody(self, body), "content-encoding", algorithm)
1139
+ )
1140
+ }
1141
+ )
1142
+
977
1143
  /**
978
1144
  * Sets a `Uint8Array` request body with an optional content type.
979
1145
  *
@@ -347,10 +347,11 @@ export const toWebHandlerWith = <Provided, R = never, ReqR = Exclude<R, Provided
347
347
  const httpApp = toHandled(self, (request, response) => {
348
348
  const withoutBody = request.method === "HEAD"
349
349
  if (!Response.omitsBody(response, withoutBody)) {
350
+ // The transferred request scope closes when an abort interrupts the body, even if it is no longer read.
350
351
  response = scopeTransferToStream(response)
351
352
  }
352
353
  ;(request as any)[resolveSymbol](
353
- Response.toWeb(response, { withoutBody, context })
354
+ Response.toWeb(response, { withoutBody, context, signal: (request.source as globalThis.Request).signal })
354
355
  )
355
356
  return Effect.void
356
357
  }, middleware)
@@ -366,10 +367,15 @@ export const toWebHandlerWith = <Provided, R = never, ReqR = Exclude<R, Provided
366
367
  reqContext = Context.add(reqContext, HttpServerRequest, httpServerRequest)
367
368
  ;(httpServerRequest as any)[resolveSymbol] = resolve
368
369
  const fiber = Effect.runForkWith(reqContext)(httpApp as any)
369
- if (fiber.pollUnsafe() === undefined) {
370
- request.signal?.addEventListener("abort", () => {
371
- fiber.interruptUnsafe(undefined, ClientAbort.annotation)
372
- }, { once: true })
370
+ const signal = request.signal
371
+ if (fiber.pollUnsafe() === undefined && signal) {
372
+ const onAbort = () => fiber.interruptUnsafe(undefined, ClientAbort.annotation)
373
+ if (signal.aborted) {
374
+ onAbort()
375
+ } else {
376
+ signal.addEventListener("abort", onAbort, { once: true })
377
+ fiber.addObserver(() => signal.removeEventListener("abort", onAbort))
378
+ }
373
379
  }
374
380
  })
375
381
  }