effect 4.0.6 → 4.0.7

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 (480) hide show
  1. package/dist/Arbitrary.d.ts +10 -2
  2. package/dist/Arbitrary.d.ts.map +1 -1
  3. package/dist/Arbitrary.js +2 -1
  4. package/dist/Arbitrary.js.map +1 -1
  5. package/dist/Channel.d.ts.map +1 -1
  6. package/dist/Channel.js +21 -6
  7. package/dist/Channel.js.map +1 -1
  8. package/dist/Data.d.ts +54 -235
  9. package/dist/Data.d.ts.map +1 -1
  10. package/dist/Data.js.map +1 -1
  11. package/dist/Effect.d.ts +1 -1
  12. package/dist/Effect.js +1 -1
  13. package/dist/Equal.d.ts.map +1 -1
  14. package/dist/Equal.js +8 -1
  15. package/dist/Equal.js.map +1 -1
  16. package/dist/Exit.d.ts +3 -3
  17. package/dist/Exit.d.ts.map +1 -1
  18. package/dist/Exit.js.map +1 -1
  19. package/dist/Formatter.d.ts.map +1 -1
  20. package/dist/Formatter.js +27 -13
  21. package/dist/Formatter.js.map +1 -1
  22. package/dist/Hash.d.ts.map +1 -1
  23. package/dist/Hash.js +4 -1
  24. package/dist/Hash.js.map +1 -1
  25. package/dist/JsonPatch.js +4 -0
  26. package/dist/JsonPatch.js.map +1 -1
  27. package/dist/JsonSchema.d.ts.map +1 -1
  28. package/dist/JsonSchema.js +13 -40
  29. package/dist/JsonSchema.js.map +1 -1
  30. package/dist/Metric.d.ts +3 -3
  31. package/dist/MutableList.d.ts +5 -2
  32. package/dist/MutableList.d.ts.map +1 -1
  33. package/dist/MutableList.js +7 -5
  34. package/dist/MutableList.js.map +1 -1
  35. package/dist/MutableRef.d.ts.map +1 -1
  36. package/dist/MutableRef.js +7 -0
  37. package/dist/MutableRef.js.map +1 -1
  38. package/dist/PartitionedSemaphore.d.ts +2 -1
  39. package/dist/PartitionedSemaphore.d.ts.map +1 -1
  40. package/dist/PartitionedSemaphore.js +22 -12
  41. package/dist/PartitionedSemaphore.js.map +1 -1
  42. package/dist/Pool.d.ts.map +1 -1
  43. package/dist/Pool.js +77 -27
  44. package/dist/Pool.js.map +1 -1
  45. package/dist/PubSub.d.ts.map +1 -1
  46. package/dist/PubSub.js +5 -6
  47. package/dist/PubSub.js.map +1 -1
  48. package/dist/Ref.d.ts.map +1 -1
  49. package/dist/Ref.js +8 -0
  50. package/dist/Ref.js.map +1 -1
  51. package/dist/Schedule.js +1 -1
  52. package/dist/Schedule.js.map +1 -1
  53. package/dist/Schema.d.ts +24 -8
  54. package/dist/Schema.d.ts.map +1 -1
  55. package/dist/Schema.js +37 -28
  56. package/dist/Schema.js.map +1 -1
  57. package/dist/SchemaAST.d.ts +4 -2
  58. package/dist/SchemaAST.d.ts.map +1 -1
  59. package/dist/SchemaAST.js +14 -17
  60. package/dist/SchemaAST.js.map +1 -1
  61. package/dist/SchemaParser.d.ts.map +1 -1
  62. package/dist/SchemaParser.js +48 -22
  63. package/dist/SchemaParser.js.map +1 -1
  64. package/dist/SchemaRepresentation.d.ts +19 -10
  65. package/dist/SchemaRepresentation.d.ts.map +1 -1
  66. package/dist/SchemaRepresentation.js +23 -13
  67. package/dist/SchemaRepresentation.js.map +1 -1
  68. package/dist/SchemaTransformation.d.ts +4 -1
  69. package/dist/SchemaTransformation.d.ts.map +1 -1
  70. package/dist/SchemaTransformation.js +9 -2
  71. package/dist/SchemaTransformation.js.map +1 -1
  72. package/dist/Semaphore.d.ts.map +1 -1
  73. package/dist/Semaphore.js +54 -35
  74. package/dist/Semaphore.js.map +1 -1
  75. package/dist/Sink.d.ts.map +1 -1
  76. package/dist/Sink.js +7 -2
  77. package/dist/Sink.js.map +1 -1
  78. package/dist/Stream.d.ts.map +1 -1
  79. package/dist/Stream.js +22 -10
  80. package/dist/Stream.js.map +1 -1
  81. package/dist/String.d.ts +3 -0
  82. package/dist/String.d.ts.map +1 -1
  83. package/dist/String.js +3 -0
  84. package/dist/String.js.map +1 -1
  85. package/dist/Tracer.d.ts +11 -1
  86. package/dist/Tracer.d.ts.map +1 -1
  87. package/dist/Tracer.js +6 -1
  88. package/dist/Tracer.js.map +1 -1
  89. package/dist/ai/LanguageModel.d.ts.map +1 -1
  90. package/dist/ai/LanguageModel.js +9 -0
  91. package/dist/ai/LanguageModel.js.map +1 -1
  92. package/dist/ai/McpSchema.d.ts +110 -110
  93. package/dist/ai/McpSchema.d.ts.map +1 -1
  94. package/dist/ai/McpServer.d.ts.map +1 -1
  95. package/dist/ai/McpServer.js +21 -15
  96. package/dist/ai/McpServer.js.map +1 -1
  97. package/dist/ai/Prompt.d.ts +52 -0
  98. package/dist/ai/Prompt.d.ts.map +1 -1
  99. package/dist/ai/Prompt.js +38 -0
  100. package/dist/ai/Prompt.js.map +1 -1
  101. package/dist/ai/Response.d.ts +16 -3
  102. package/dist/ai/Response.d.ts.map +1 -1
  103. package/dist/ai/Response.js +4 -0
  104. package/dist/ai/Response.js.map +1 -1
  105. package/dist/ai/Tool.d.ts +24 -0
  106. package/dist/ai/Tool.d.ts.map +1 -1
  107. package/dist/ai/Tool.js +5 -2
  108. package/dist/ai/Tool.js.map +1 -1
  109. package/dist/ai/Toolkit.d.ts.map +1 -1
  110. package/dist/ai/Toolkit.js +8 -1
  111. package/dist/ai/Toolkit.js.map +1 -1
  112. package/dist/cli/Argument.d.ts +15 -0
  113. package/dist/cli/Argument.d.ts.map +1 -1
  114. package/dist/cli/Argument.js +5 -0
  115. package/dist/cli/Argument.js.map +1 -1
  116. package/dist/cli/CliError.d.ts +78 -0
  117. package/dist/cli/CliError.d.ts.map +1 -1
  118. package/dist/cli/CliError.js +65 -3
  119. package/dist/cli/CliError.js.map +1 -1
  120. package/dist/cli/CliOutput.d.ts +155 -6
  121. package/dist/cli/CliOutput.d.ts.map +1 -1
  122. package/dist/cli/CliOutput.js +62 -6
  123. package/dist/cli/CliOutput.js.map +1 -1
  124. package/dist/cli/Command.d.ts +24 -16
  125. package/dist/cli/Command.d.ts.map +1 -1
  126. package/dist/cli/Command.js +59 -29
  127. package/dist/cli/Command.js.map +1 -1
  128. package/dist/cli/Completions.d.ts +58 -0
  129. package/dist/cli/Completions.d.ts.map +1 -1
  130. package/dist/cli/Completions.js +49 -9
  131. package/dist/cli/Completions.js.map +1 -1
  132. package/dist/cli/Flag.d.ts +15 -0
  133. package/dist/cli/Flag.d.ts.map +1 -1
  134. package/dist/cli/Flag.js +5 -0
  135. package/dist/cli/Flag.js.map +1 -1
  136. package/dist/cli/GlobalFlag.d.ts.map +1 -1
  137. package/dist/cli/GlobalFlag.js +15 -7
  138. package/dist/cli/GlobalFlag.js.map +1 -1
  139. package/dist/cli/Param.d.ts +9 -0
  140. package/dist/cli/Param.d.ts.map +1 -1
  141. package/dist/cli/Param.js +21 -2
  142. package/dist/cli/Param.js.map +1 -1
  143. package/dist/cli/TerminalCapabilities.d.ts +3 -2
  144. package/dist/cli/TerminalCapabilities.d.ts.map +1 -1
  145. package/dist/cli/TerminalCapabilities.js +3 -1
  146. package/dist/cli/TerminalCapabilities.js.map +1 -1
  147. package/dist/cli/internal/completions/bash.js +73 -27
  148. package/dist/cli/internal/completions/bash.js.map +1 -1
  149. package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
  150. package/dist/cluster/ClusterWorkflowEngine.js +45 -10
  151. package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
  152. package/dist/cluster/MessageStorage.d.ts +23 -45
  153. package/dist/cluster/MessageStorage.d.ts.map +1 -1
  154. package/dist/cluster/MessageStorage.js +6 -7
  155. package/dist/cluster/MessageStorage.js.map +1 -1
  156. package/dist/cluster/Sharding.d.ts.map +1 -1
  157. package/dist/cluster/Sharding.js +61 -21
  158. package/dist/cluster/Sharding.js.map +1 -1
  159. package/dist/cluster/ShardingConfig.d.ts +10 -0
  160. package/dist/cluster/ShardingConfig.d.ts.map +1 -1
  161. package/dist/cluster/ShardingConfig.js.map +1 -1
  162. package/dist/cluster/Snowflake.d.ts.map +1 -1
  163. package/dist/cluster/Snowflake.js +3 -7
  164. package/dist/cluster/Snowflake.js.map +1 -1
  165. package/dist/cluster/SqlRunnerStorage.d.ts.map +1 -1
  166. package/dist/cluster/SqlRunnerStorage.js +87 -39
  167. package/dist/cluster/SqlRunnerStorage.js.map +1 -1
  168. package/dist/cluster/internal/entityManager.js +54 -20
  169. package/dist/cluster/internal/entityManager.js.map +1 -1
  170. package/dist/devtools/DevToolsClient.d.ts.map +1 -1
  171. package/dist/devtools/DevToolsClient.js +2 -0
  172. package/dist/devtools/DevToolsClient.js.map +1 -1
  173. package/dist/encoding/Base64.js +36 -0
  174. package/dist/encoding/Base64.js.map +1 -1
  175. package/dist/encoding/Sse.d.ts.map +1 -1
  176. package/dist/encoding/Sse.js +3 -3
  177. package/dist/encoding/Sse.js.map +1 -1
  178. package/dist/encoding/Toml.d.ts.map +1 -1
  179. package/dist/encoding/Toml.js +21 -16
  180. package/dist/encoding/Toml.js.map +1 -1
  181. package/dist/eventlog/SqlEventJournal.d.ts.map +1 -1
  182. package/dist/eventlog/SqlEventJournal.js +47 -27
  183. package/dist/eventlog/SqlEventJournal.js.map +1 -1
  184. package/dist/eventlog/internal/conflicts.d.ts +0 -1
  185. package/dist/eventlog/internal/conflicts.d.ts.map +1 -1
  186. package/dist/eventlog/internal/conflicts.js +0 -3
  187. package/dist/eventlog/internal/conflicts.js.map +1 -1
  188. package/dist/http/Cookies.d.ts.map +1 -1
  189. package/dist/http/Cookies.js +10 -9
  190. package/dist/http/Cookies.js.map +1 -1
  191. package/dist/http/HttpClient.d.ts +423 -0
  192. package/dist/http/HttpClient.d.ts.map +1 -1
  193. package/dist/http/HttpClient.js +231 -7
  194. package/dist/http/HttpClient.js.map +1 -1
  195. package/dist/http/HttpClientError.d.ts +8 -1
  196. package/dist/http/HttpClientError.d.ts.map +1 -1
  197. package/dist/http/HttpClientError.js +37 -1
  198. package/dist/http/HttpClientError.js.map +1 -1
  199. package/dist/http/HttpClientRequest.d.ts.map +1 -1
  200. package/dist/http/HttpClientRequest.js +1 -1
  201. package/dist/http/HttpClientRequest.js.map +1 -1
  202. package/dist/http/HttpMiddleware.d.ts +1 -1
  203. package/dist/http/HttpMiddleware.d.ts.map +1 -1
  204. package/dist/http/HttpMiddleware.js +14 -16
  205. package/dist/http/HttpMiddleware.js.map +1 -1
  206. package/dist/http/HttpRouter.d.ts.map +1 -1
  207. package/dist/http/HttpRouter.js +2 -1
  208. package/dist/http/HttpRouter.js.map +1 -1
  209. package/dist/http/HttpServerError.js +2 -2
  210. package/dist/http/HttpServerError.js.map +1 -1
  211. package/dist/http/HttpServerRequest.d.ts +6 -1
  212. package/dist/http/HttpServerRequest.d.ts.map +1 -1
  213. package/dist/http/HttpServerRequest.js +73 -10
  214. package/dist/http/HttpServerRequest.js.map +1 -1
  215. package/dist/http/HttpStaticServer.d.ts.map +1 -1
  216. package/dist/http/HttpStaticServer.js +48 -21
  217. package/dist/http/HttpStaticServer.js.map +1 -1
  218. package/dist/http/MultipartParser/internal/contentType.js +3 -3
  219. package/dist/http/UrlParams.d.ts +3 -1
  220. package/dist/http/UrlParams.d.ts.map +1 -1
  221. package/dist/http/UrlParams.js +4 -2
  222. package/dist/http/UrlParams.js.map +1 -1
  223. package/dist/http/internal/compression.js +4 -5
  224. package/dist/http/internal/compression.js.map +1 -1
  225. package/dist/http/internal/decompression.js +3 -0
  226. package/dist/http/internal/decompression.js.map +1 -1
  227. package/dist/http/internal/httpBody.js +8 -1
  228. package/dist/http/internal/httpBody.js.map +1 -1
  229. package/dist/http/internal/urlParams.js +25 -0
  230. package/dist/http/internal/urlParams.js.map +1 -1
  231. package/dist/http-api/HttpApi.d.ts +3 -6
  232. package/dist/http-api/HttpApi.d.ts.map +1 -1
  233. package/dist/http-api/HttpApi.js +3 -6
  234. package/dist/http-api/HttpApi.js.map +1 -1
  235. package/dist/http-api/HttpApiBuilder.d.ts.map +1 -1
  236. package/dist/http-api/HttpApiBuilder.js +27 -11
  237. package/dist/http-api/HttpApiBuilder.js.map +1 -1
  238. package/dist/http-api/HttpApiClient.d.ts +77 -7
  239. package/dist/http-api/HttpApiClient.d.ts.map +1 -1
  240. package/dist/http-api/HttpApiClient.js +142 -44
  241. package/dist/http-api/HttpApiClient.js.map +1 -1
  242. package/dist/http-api/HttpApiEndpoint.d.ts +24 -7
  243. package/dist/http-api/HttpApiEndpoint.d.ts.map +1 -1
  244. package/dist/http-api/HttpApiEndpoint.js +109 -27
  245. package/dist/http-api/HttpApiEndpoint.js.map +1 -1
  246. package/dist/http-api/HttpApiSchema.d.ts +76 -29
  247. package/dist/http-api/HttpApiSchema.d.ts.map +1 -1
  248. package/dist/http-api/HttpApiSchema.js +70 -59
  249. package/dist/http-api/HttpApiSchema.js.map +1 -1
  250. package/dist/http-api/HttpApiTest.d.ts.map +1 -1
  251. package/dist/http-api/HttpApiTest.js +3 -2
  252. package/dist/http-api/HttpApiTest.js.map +1 -1
  253. package/dist/http-api/OpenApi.d.ts.map +1 -1
  254. package/dist/http-api/OpenApi.js +25 -16
  255. package/dist/http-api/OpenApi.js.map +1 -1
  256. package/dist/http-api/internal/toCodecHttpProperties.d.ts +2 -0
  257. package/dist/http-api/internal/toCodecHttpProperties.d.ts.map +1 -0
  258. package/dist/http-api/internal/toCodecHttpProperties.js +38 -0
  259. package/dist/http-api/internal/toCodecHttpProperties.js.map +1 -0
  260. package/dist/internal/arbitrary/runner.d.ts.map +1 -1
  261. package/dist/internal/arbitrary/runner.js +120 -44
  262. package/dist/internal/arbitrary/runner.js.map +1 -1
  263. package/dist/internal/core.js +2 -0
  264. package/dist/internal/core.js.map +1 -1
  265. package/dist/internal/effect.js +21 -13
  266. package/dist/internal/effect.js.map +1 -1
  267. package/dist/internal/equal.js +14 -0
  268. package/dist/internal/equal.js.map +1 -1
  269. package/dist/internal/jsonSchema.d.ts +2 -0
  270. package/dist/internal/jsonSchema.d.ts.map +1 -0
  271. package/dist/internal/jsonSchema.js +28 -0
  272. package/dist/internal/jsonSchema.js.map +1 -0
  273. package/dist/internal/matcher.js +1 -1
  274. package/dist/internal/matcher.js.map +1 -1
  275. package/dist/internal/schema/compilerRegistry.js +4 -1
  276. package/dist/internal/schema/compilerRegistry.js.map +1 -1
  277. package/dist/internal/schema/content.d.ts +2 -0
  278. package/dist/internal/schema/content.d.ts.map +1 -0
  279. package/dist/internal/schema/content.js +13 -0
  280. package/dist/internal/schema/content.js.map +1 -0
  281. package/dist/internal/schema/fromJsonSchemaDocument.js +173 -185
  282. package/dist/internal/schema/fromJsonSchemaDocument.js.map +1 -1
  283. package/dist/internal/schema/fromRepresentation.js +2 -1
  284. package/dist/internal/schema/fromRepresentation.js.map +1 -1
  285. package/dist/internal/schema/standardSchema.js +8 -2
  286. package/dist/internal/schema/standardSchema.js.map +1 -1
  287. package/dist/internal/schema/toCodeDocument.js +3 -3
  288. package/dist/internal/schema/toCodeDocument.js.map +1 -1
  289. package/dist/internal/schema/toCodec.js +21 -24
  290. package/dist/internal/schema/toCodec.js.map +1 -1
  291. package/dist/internal/schema/toJsonSchemaDocument.js +205 -140
  292. package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
  293. package/dist/internal/schema/toRepresentation.js +107 -129
  294. package/dist/internal/schema/toRepresentation.js.map +1 -1
  295. package/dist/internal/sql.d.ts +2 -0
  296. package/dist/internal/sql.d.ts.map +1 -0
  297. package/dist/internal/sql.js +13 -0
  298. package/dist/internal/sql.js.map +1 -0
  299. package/dist/internal/version.js +1 -1
  300. package/dist/observability/OtlpProxy.d.ts +154 -0
  301. package/dist/observability/OtlpProxy.d.ts.map +1 -0
  302. package/dist/observability/OtlpProxy.js +235 -0
  303. package/dist/observability/OtlpProxy.js.map +1 -0
  304. package/dist/observability/OtlpTracer.d.ts.map +1 -1
  305. package/dist/observability/OtlpTracer.js +4 -0
  306. package/dist/observability/OtlpTracer.js.map +1 -1
  307. package/dist/observability/index.d.ts +5 -0
  308. package/dist/observability/index.d.ts.map +1 -1
  309. package/dist/observability/index.js +5 -0
  310. package/dist/observability/index.js.map +1 -1
  311. package/dist/persistence/CircuitBreaker.d.ts +897 -0
  312. package/dist/persistence/CircuitBreaker.d.ts.map +1 -0
  313. package/dist/persistence/CircuitBreaker.js +1165 -0
  314. package/dist/persistence/CircuitBreaker.js.map +1 -0
  315. package/dist/persistence/Redis.d.ts +78 -2
  316. package/dist/persistence/Redis.d.ts.map +1 -1
  317. package/dist/persistence/Redis.js +62 -7
  318. package/dist/persistence/Redis.js.map +1 -1
  319. package/dist/persistence/index.d.ts +5 -0
  320. package/dist/persistence/index.d.ts.map +1 -1
  321. package/dist/persistence/index.js +5 -0
  322. package/dist/persistence/index.js.map +1 -1
  323. package/dist/process/ChildProcess.d.ts +30 -4
  324. package/dist/process/ChildProcess.d.ts.map +1 -1
  325. package/dist/process/ChildProcess.js.map +1 -1
  326. package/dist/process/ChildProcessSpawner.d.ts +30 -0
  327. package/dist/process/ChildProcessSpawner.d.ts.map +1 -1
  328. package/dist/process/ChildProcessSpawner.js +5 -2
  329. package/dist/process/ChildProcessSpawner.js.map +1 -1
  330. package/dist/reactivity/AsyncResult.d.ts +1 -1
  331. package/dist/reactivity/AsyncResult.d.ts.map +1 -1
  332. package/dist/rpc/RpcClient.d.ts.map +1 -1
  333. package/dist/rpc/RpcClient.js +9 -8
  334. package/dist/rpc/RpcClient.js.map +1 -1
  335. package/dist/rpc/RpcSerialization.d.ts +14 -0
  336. package/dist/rpc/RpcSerialization.d.ts.map +1 -1
  337. package/dist/rpc/RpcSerialization.js +20 -8
  338. package/dist/rpc/RpcSerialization.js.map +1 -1
  339. package/dist/rpc/RpcServer.d.ts.map +1 -1
  340. package/dist/rpc/RpcServer.js +11 -1
  341. package/dist/rpc/RpcServer.js.map +1 -1
  342. package/dist/rpc/RpcTest.d.ts +1 -0
  343. package/dist/rpc/RpcTest.d.ts.map +1 -1
  344. package/dist/rpc/RpcTest.js +1 -0
  345. package/dist/rpc/RpcTest.js.map +1 -1
  346. package/dist/sql/Migrator.d.ts +2 -1
  347. package/dist/sql/Migrator.d.ts.map +1 -1
  348. package/dist/sql/Migrator.js +11 -8
  349. package/dist/sql/Migrator.js.map +1 -1
  350. package/dist/sql/SqlClient.d.ts +9 -4
  351. package/dist/sql/SqlClient.d.ts.map +1 -1
  352. package/dist/sql/SqlClient.js +8 -1
  353. package/dist/sql/SqlClient.js.map +1 -1
  354. package/dist/sql/SqlResolver.d.ts +4 -0
  355. package/dist/sql/SqlResolver.d.ts.map +1 -1
  356. package/dist/sql/SqlResolver.js +18 -4
  357. package/dist/sql/SqlResolver.js.map +1 -1
  358. package/dist/sql/Statement.d.ts +7 -0
  359. package/dist/sql/Statement.d.ts.map +1 -1
  360. package/dist/sql/Statement.js +21 -2
  361. package/dist/sql/Statement.js.map +1 -1
  362. package/dist/workflow/DurableDeferred.d.ts.map +1 -1
  363. package/dist/workflow/DurableDeferred.js +21 -2
  364. package/dist/workflow/DurableDeferred.js.map +1 -1
  365. package/package.json +1 -1
  366. package/src/Arbitrary.ts +10 -2
  367. package/src/Channel.ts +47 -18
  368. package/src/Data.ts +60 -265
  369. package/src/Effect.ts +1 -1
  370. package/src/Equal.ts +8 -1
  371. package/src/Exit.ts +3 -3
  372. package/src/Formatter.ts +28 -13
  373. package/src/Hash.ts +4 -1
  374. package/src/JsonPatch.ts +4 -0
  375. package/src/JsonSchema.ts +12 -40
  376. package/src/Metric.ts +3 -3
  377. package/src/MutableList.ts +7 -5
  378. package/src/MutableRef.ts +8 -1
  379. package/src/PartitionedSemaphore.ts +24 -13
  380. package/src/Pool.ts +109 -37
  381. package/src/PubSub.ts +5 -6
  382. package/src/Ref.ts +8 -0
  383. package/src/Schedule.ts +1 -1
  384. package/src/Schema.ts +48 -25
  385. package/src/SchemaAST.ts +20 -20
  386. package/src/SchemaParser.ts +51 -18
  387. package/src/SchemaRepresentation.ts +31 -34
  388. package/src/SchemaTransformation.ts +9 -2
  389. package/src/Semaphore.ts +67 -40
  390. package/src/Sink.ts +15 -2
  391. package/src/Stream.ts +33 -16
  392. package/src/String.ts +3 -0
  393. package/src/Tracer.ts +15 -1
  394. package/src/ai/LanguageModel.ts +9 -0
  395. package/src/ai/McpServer.ts +14 -13
  396. package/src/ai/Prompt.ts +65 -0
  397. package/src/ai/Response.ts +34 -9
  398. package/src/ai/Tool.ts +38 -2
  399. package/src/ai/Toolkit.ts +4 -1
  400. package/src/cli/Argument.ts +15 -0
  401. package/src/cli/CliError.ts +90 -3
  402. package/src/cli/CliOutput.ts +183 -6
  403. package/src/cli/Command.ts +53 -41
  404. package/src/cli/Completions.ts +51 -0
  405. package/src/cli/Flag.ts +15 -0
  406. package/src/cli/GlobalFlag.ts +6 -7
  407. package/src/cli/Param.ts +29 -6
  408. package/src/cli/TerminalCapabilities.ts +6 -3
  409. package/src/cli/internal/completions/bash.ts +79 -29
  410. package/src/cluster/ClusterWorkflowEngine.ts +46 -16
  411. package/src/cluster/MessageStorage.ts +19 -14
  412. package/src/cluster/Sharding.ts +83 -21
  413. package/src/cluster/ShardingConfig.ts +5 -0
  414. package/src/cluster/Snowflake.ts +3 -7
  415. package/src/cluster/SqlRunnerStorage.ts +110 -47
  416. package/src/cluster/internal/entityManager.ts +75 -22
  417. package/src/devtools/DevToolsClient.ts +2 -0
  418. package/src/encoding/Base64.ts +38 -0
  419. package/src/encoding/Sse.ts +4 -3
  420. package/src/encoding/Toml.ts +33 -16
  421. package/src/eventlog/SqlEventJournal.ts +68 -45
  422. package/src/eventlog/internal/conflicts.ts +0 -4
  423. package/src/http/Cookies.ts +10 -11
  424. package/src/http/HttpClient.ts +547 -7
  425. package/src/http/HttpClientError.ts +35 -1
  426. package/src/http/HttpClientRequest.ts +9 -1
  427. package/src/http/HttpMiddleware.ts +15 -18
  428. package/src/http/HttpRouter.ts +2 -1
  429. package/src/http/HttpServerError.ts +2 -2
  430. package/src/http/HttpServerRequest.ts +102 -16
  431. package/src/http/HttpStaticServer.ts +51 -22
  432. package/src/http/MultipartParser/internal/contentType.ts +3 -3
  433. package/src/http/UrlParams.ts +6 -1
  434. package/src/http/internal/compression.ts +4 -5
  435. package/src/http/internal/decompression.ts +6 -0
  436. package/src/http/internal/httpBody.ts +10 -2
  437. package/src/http/internal/urlParams.ts +29 -0
  438. package/src/http-api/HttpApi.ts +3 -6
  439. package/src/http-api/HttpApiBuilder.ts +45 -15
  440. package/src/http-api/HttpApiClient.ts +218 -72
  441. package/src/http-api/HttpApiEndpoint.ts +121 -30
  442. package/src/http-api/HttpApiSchema.ts +141 -48
  443. package/src/http-api/HttpApiTest.ts +3 -2
  444. package/src/http-api/OpenApi.ts +20 -17
  445. package/src/http-api/internal/toCodecHttpProperties.ts +56 -0
  446. package/src/internal/arbitrary/runner.ts +133 -36
  447. package/src/internal/core.ts +2 -0
  448. package/src/internal/effect.ts +24 -16
  449. package/src/internal/equal.ts +17 -0
  450. package/src/internal/jsonSchema.ts +27 -0
  451. package/src/internal/matcher.ts +1 -1
  452. package/src/internal/schema/compilerRegistry.ts +6 -1
  453. package/src/internal/schema/content.ts +18 -0
  454. package/src/internal/schema/fromJsonSchemaDocument.ts +228 -190
  455. package/src/internal/schema/fromRepresentation.ts +2 -1
  456. package/src/internal/schema/standardSchema.ts +2 -2
  457. package/src/internal/schema/toCodeDocument.ts +4 -4
  458. package/src/internal/schema/toCodec.ts +26 -22
  459. package/src/internal/schema/toJsonSchemaDocument.ts +189 -167
  460. package/src/internal/schema/toRepresentation.ts +122 -140
  461. package/src/internal/sql.ts +14 -0
  462. package/src/internal/version.ts +1 -1
  463. package/src/observability/OtlpProxy.ts +314 -0
  464. package/src/observability/OtlpTracer.ts +4 -0
  465. package/src/observability/index.ts +6 -0
  466. package/src/persistence/CircuitBreaker.ts +1678 -0
  467. package/src/persistence/Redis.ts +129 -8
  468. package/src/persistence/index.ts +6 -0
  469. package/src/process/ChildProcess.ts +30 -4
  470. package/src/process/ChildProcessSpawner.ts +41 -2
  471. package/src/reactivity/AsyncResult.ts +1 -1
  472. package/src/rpc/RpcClient.ts +13 -10
  473. package/src/rpc/RpcSerialization.ts +32 -9
  474. package/src/rpc/RpcServer.ts +16 -1
  475. package/src/rpc/RpcTest.ts +3 -0
  476. package/src/sql/Migrator.ts +12 -7
  477. package/src/sql/SqlClient.ts +11 -4
  478. package/src/sql/SqlResolver.ts +23 -9
  479. package/src/sql/Statement.ts +30 -2
  480. package/src/workflow/DurableDeferred.ts +23 -6
@@ -9,6 +9,62 @@
9
9
  * constructors, payload and response schema helpers, and type utilities used by
10
10
  * builders and generated clients.
11
11
  *
12
+ * **Request variants**
13
+ *
14
+ * A server needs a distinct method and path per endpoint.
15
+ * `HttpApiBuilder.layer` rejects two endpoints that share them, even when their
16
+ * query, headers or payload differ. Declare the variants of one operation as a
17
+ * single endpoint instead:
18
+ *
19
+ * - discriminate with a `query` or `headers` field, such as `stream: Schema.Boolean`
20
+ * - list several `payload` schemas, chosen by the request `Content-Type`
21
+ * - list several `success` schemas with distinct content types or statuses. One
22
+ * of them can be a stream. The server encodes whichever value the handler
23
+ * returns, and the client decodes by the response `Content-Type`
24
+ *
25
+ * The handler branches on the decoded request, and OpenAPI documents one
26
+ * operation with every alternative. The generated client returns the union of
27
+ * the success types. Wrap the client method to narrow the result per variant
28
+ * when callers need it.
29
+ *
30
+ * **Example** (Buffered and streaming variants of one operation)
31
+ *
32
+ * ```ts import.meta.vitest
33
+ * import { Effect, Schema, Stream } from "effect"
34
+ * import { HttpApi, HttpApiBuilder, HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from "effect/http-api"
35
+ *
36
+ * const Stats = Schema.Struct({ cpu: Schema.Number })
37
+ *
38
+ * const Api = HttpApi.make("Docker").add(
39
+ * HttpApiGroup.make("containers").add(
40
+ * // GET /stats?stream=false returns JSON, ?stream=true returns NDJSON
41
+ * HttpApiEndpoint.get("stats", "/stats", {
42
+ * query: { stream: Schema.Boolean },
43
+ * success: [Stats, HttpApiSchema.StreamNdjson({ schema: Stats })]
44
+ * }),
45
+ * // POST /images accepts a JSON pull request or a tar archive
46
+ * HttpApiEndpoint.post("createImage", "/images", {
47
+ * payload: [
48
+ * Schema.Struct({ fromImage: Schema.String }),
49
+ * HttpApiSchema.StreamUint8Array({ contentType: "application/x-tar" })
50
+ * ],
51
+ * success: Schema.String
52
+ * })
53
+ * )
54
+ * )
55
+ *
56
+ * const ContainersLive = HttpApiBuilder.group(Api, "containers", (handlers) =>
57
+ * handlers
58
+ * .handle("stats", ({ query }) =>
59
+ * Effect.succeed(query.stream ? Stream.make({ cpu: 1 }, { cpu: 2 }) : { cpu: 1 })
60
+ * )
61
+ * .handle("createImage", ({ payload }) =>
62
+ * Stream.isStream(payload)
63
+ * ? Effect.as(Stream.runDrain(payload), "imported")
64
+ * : Effect.succeed(`pulled ${payload.fromImage}`)
65
+ * ))
66
+ * ```
67
+ *
12
68
  * @stability unstable
13
69
  * @since 4.0.0
14
70
  */
@@ -36,6 +92,7 @@ import type * as HttpApiGroup from "./HttpApiGroup.ts"
36
92
  import type * as HttpApiMiddleware from "./HttpApiMiddleware.ts"
37
93
  import * as HttpApiSchema from "./HttpApiSchema.ts"
38
94
  import * as MediaType from "./internal/mediaType.ts"
95
+ import { toCodecHttpProperties } from "./internal/toCodecHttpProperties.ts"
39
96
 
40
97
  const TypeId = "~effect/http-api/HttpApiEndpoint"
41
98
 
@@ -71,6 +128,7 @@ type SuccessEncodingServices<S> = S extends HttpApiSchema.StreamSse<
71
128
  > ? _Events["EncodingServices"] | _Error["EncodingServices"]
72
129
  : S extends HttpApiSchema.StreamUint8Array ? never
73
130
  : S extends HttpApiSchema.StreamNdjson<infer _S> ? _S["EncodingServices"]
131
+ : S extends HttpApiSchema.Upgrade<infer _Headers> ? _Headers["EncodingServices"]
74
132
  : S extends Schema.Constraint ? S["EncodingServices"]
75
133
  : never
76
134
 
@@ -81,6 +139,7 @@ type SuccessDecodingServices<S> = S extends HttpApiSchema.StreamSse<
81
139
  > ? _Events["DecodingServices"] | _Error["DecodingServices"]
82
140
  : S extends HttpApiSchema.StreamUint8Array ? never
83
141
  : S extends HttpApiSchema.StreamNdjson<infer _S> ? _S["DecodingServices"]
142
+ : S extends HttpApiSchema.Upgrade<infer _Headers> ? _Headers["DecodingServices"]
84
143
  : S extends Schema.Constraint ? S["DecodingServices"]
85
144
  : never
86
145
 
@@ -95,10 +154,19 @@ type ExtractStreamSuccess<S extends SuccessConstraint> = UnwrapReadonlyArray<S>
95
154
  Success extends HttpApiSchema.StreamSchema ? Success : never
96
155
  : never
97
156
 
98
- type ExtractUpgradeSuccess<S extends SuccessConstraint> = Extract<UnwrapReadonlyArray<S>, HttpApiSchema.Upgrade>
157
+ type ExtractUpgradeSuccess<S extends SuccessConstraint> = UnwrapReadonlyArray<S> extends infer Success ?
158
+ Success extends HttpApiSchema.Upgrade<infer _Headers> ?
159
+ [_Headers] extends [never] ? Success : HttpApiSchema.Upgrade<Schema.toCodecStringTree<_Headers>>
160
+ : never
161
+ : never
162
+
163
+ type UpgradeRequest<Success> = [Extract<Success, HttpApiSchema.Upgrade>] extends [never] ? {}
164
+ : { readonly upgrade: UpgradeFunction<Extract<Success, HttpApiSchema.Upgrade>> }
99
165
 
100
- type UpgradeSocket<Success> = [Extract<Success, HttpApiSchema.Upgrade>] extends [never] ? {}
101
- : { readonly socket: Socket.Socket }
166
+ type UpgradeFunction<S> = S extends HttpApiSchema.Upgrade<infer _Headers> ?
167
+ [_Headers] extends [never] ? () => Effect<Socket.Socket>
168
+ : (options: { readonly headers: _Headers["Type"] }) => Effect<Socket.Socket>
169
+ : never
102
170
 
103
171
  type ExtractWithHeadersSuccess<S extends SuccessConstraint> = UnwrapReadonlyArray<S> extends infer Success ?
104
172
  Success extends HttpApiSchema.WithHeaders<infer _Inner, infer _Headers> ? HttpApiSchema.WithHeaders<
@@ -148,7 +216,7 @@ type PayloadError<Payload> = Payload extends HttpApiSchema.StreamUint8Array ? Ht
148
216
  : never
149
217
 
150
218
  type RequestFromParts<Endpoint, ParamsType, QueryType, Payload, HeadersType, Success> =
151
- & UpgradeSocket<Success>
219
+ & UpgradeRequest<Success>
152
220
  & ([ParamsType] extends [never] ? {} : { readonly params: Simplify<ParamsType> })
153
221
  & ([QueryType] extends [never] ? {} : { readonly query: Simplify<QueryType> })
154
222
  & ([Payload] extends [never] ? {} : { readonly payload: RequestPayload<Payload> })
@@ -160,7 +228,7 @@ type RequestFromParts<Endpoint, ParamsType, QueryType, Payload, HeadersType, Suc
160
228
  }
161
229
 
162
230
  type RequestRawFromParts<Endpoint, ParamsType, QueryType, HeadersType, Success> =
163
- & UpgradeSocket<Success>
231
+ & UpgradeRequest<Success>
164
232
  & ([ParamsType] extends [never] ? {} : { readonly params: Simplify<ParamsType> })
165
233
  & ([QueryType] extends [never] ? {} : { readonly query: Simplify<QueryType> })
166
234
  & ([HeadersType] extends [never] ? {} : { readonly headers: Simplify<HeadersType> })
@@ -1111,6 +1179,16 @@ type ErrorNoStream<S extends ErrorConstraint> = [
1111
1179
  * and response schemas, applying automatic JSON or string-tree codecs unless
1112
1180
  * `disableCodecs` is enabled.
1113
1181
  *
1182
+ * **Gotchas**
1183
+ *
1184
+ * URL parameters are flat on the server: each `query` field, each field of a
1185
+ * no-body `payload` and each field of a form-urlencoded `payload` should encode
1186
+ * to a string or an array of strings. A field that encodes to a nested object
1187
+ * is sent as bracket keys (`meta[k]=v`) that the server does not read back, so
1188
+ * it is dropped, or reported missing when required. Send structured values with
1189
+ * an explicit codec such as `Schema.fromJsonString(...)`, or declare bracket
1190
+ * keys literally, for example `"page[size]": Schema.String`.
1191
+ *
1114
1192
  * @stability unstable
1115
1193
  * @category constructors
1116
1194
  * @since 4.0.0
@@ -1217,16 +1295,17 @@ export const make = <Method extends HttpMethod>(method: Method): {
1217
1295
  Error extends ReadonlyArray<Schema.Constraint> ? Error[number] : Error
1218
1296
  > => {
1219
1297
  const disableCodecs = options?.disableCodecs ?? false
1220
- const transformStringTree = disableCodecs ? identity : Schema.toCodecStringTree
1298
+ const transformProperties = disableCodecs ? identity : toCodecHttpProperties
1299
+ const payload = getPayload(options?.payload, method, disableCodecs)
1221
1300
  return makeProto({
1222
1301
  identifier,
1223
1302
  path,
1224
1303
  method,
1225
- params: ensureStruct(options?.params, transformStringTree),
1226
- query: ensureStruct(options?.query, transformStringTree),
1227
- headers: ensureStruct(options?.headers, transformStringTree),
1228
- payload: getPayload(options?.payload, method, disableCodecs),
1229
- success: getSuccessResponse(options?.success, method, options?.payload !== undefined, disableCodecs),
1304
+ params: ensureStruct(options?.params, transformProperties),
1305
+ query: ensureStruct(options?.query, transformProperties),
1306
+ headers: ensureStruct(options?.headers, transformProperties),
1307
+ payload,
1308
+ success: getSuccessResponse(options?.success, method, payload, disableCodecs),
1230
1309
  error: getErrorResponse(options?.error, disableCodecs),
1231
1310
  annotations: Context.empty(),
1232
1311
  middlewares: new Set(),
@@ -1281,11 +1360,13 @@ function getPayload(
1281
1360
  throw new Error("Multiple streaming payloads are not supported")
1282
1361
  }
1283
1362
  hasStream = true
1284
- const contentType = MediaType.normalize(schema.contentType)
1285
- if (result.has(contentType)) {
1286
- throw new Error(`Cannot combine buffered and streaming payloads for content-type: ${schema.contentType}`)
1363
+ for (const declared of schema.contentTypes) {
1364
+ const contentType = MediaType.normalize(declared)
1365
+ if (result.has(contentType)) {
1366
+ throw new Error(`Cannot combine buffered and streaming payloads for content-type: ${declared}`)
1367
+ }
1368
+ result.set(contentType, { encoding: { _tag: "Stream", contentType: declared }, schemas: [schema] })
1287
1369
  }
1288
- result.set(contentType, { encoding: { _tag: "Stream", contentType: schema.contentType }, schemas: [schema] })
1289
1370
  continue
1290
1371
  }
1291
1372
  const encoding = HttpApiSchema.getPayloadEncoding(schema.ast, method)
@@ -1314,22 +1395,27 @@ const reservedStreamFailureEvent = "effect/http-api/stream/failure"
1314
1395
  function getSuccessResponse(
1315
1396
  success: Schema.Top | ReadonlyArray<Schema.Top> | undefined,
1316
1397
  method: HttpMethod,
1317
- hasPayload: boolean,
1398
+ payload: PayloadMap,
1318
1399
  disableCodecs: boolean
1319
1400
  ): Set<Schema.Top> {
1320
1401
  if (success === undefined) return new Set()
1321
1402
  const schemas = Arr.ensure(success)
1322
- validateSuccessResponse(schemas, method, hasPayload)
1403
+ validateSuccessResponse(schemas, method, payload)
1323
1404
  return new Set(disableCodecs ? schemas : schemas.map(transformResponseSchema))
1324
1405
  }
1325
1406
 
1326
1407
  const transformResponseSchema = memoize((schema: Schema.Top): Schema.Top => {
1327
- if (HttpApiSchema.isStreamSchema(schema) || HttpApiSchema.isUpgrade(schema)) return schema
1408
+ if (HttpApiSchema.isStreamSchema(schema)) return schema
1409
+ if (HttpApiSchema.isUpgrade(schema)) {
1410
+ return schema.headers === undefined
1411
+ ? schema
1412
+ : HttpApiSchema.rebuildUpgrade(schema.protocol, toCodecHttpProperties(schema.headers))
1413
+ }
1328
1414
  if (HttpApiSchema.isWithHeaders(schema)) {
1329
1415
  const inner = HttpApiSchema.isStreamSchema(schema.schema)
1330
1416
  ? schema.schema
1331
1417
  : applyResponseEncoding(schema.schema, HttpApiSchema.getResponseEncodingSchema(schema))
1332
- return HttpApiSchema.rebuildWithHeaders(schema, inner, Schema.toCodecStringTree(schema.headers))
1418
+ return HttpApiSchema.rebuildWithHeaders(schema, inner, toCodecHttpProperties(schema.headers))
1333
1419
  }
1334
1420
  return transformResponse(schema)
1335
1421
  })
@@ -1353,7 +1439,7 @@ function getErrorResponse(
1353
1439
  return new Set(disableCodecs ? schemas : schemas.map(transformResponseSchema))
1354
1440
  }
1355
1441
 
1356
- function validateSuccessResponse(schemas: ReadonlyArray<Schema.Constraint>, method: HttpMethod, hasPayload: boolean) {
1442
+ function validateSuccessResponse(schemas: ReadonlyArray<Schema.Constraint>, method: HttpMethod, payload: PayloadMap) {
1357
1443
  if (schemas.some(HttpApiSchema.isUpgrade)) {
1358
1444
  if (schemas.length > 1) {
1359
1445
  throw new Error("Cannot combine an upgrade with other success responses")
@@ -1361,8 +1447,11 @@ function validateSuccessResponse(schemas: ReadonlyArray<Schema.Constraint>, meth
1361
1447
  if (method === "HEAD") {
1362
1448
  throw new Error("HEAD endpoints cannot declare an upgrade")
1363
1449
  }
1364
- if (hasPayload) {
1365
- throw new Error("Upgrade endpoints cannot declare a payload")
1450
+ // The 101 can only follow the end of the request, so the body is read before the upgrade.
1451
+ for (const { encoding } of payload.values()) {
1452
+ if (encoding._tag === "Stream" || (encoding._tag === "Multipart" && encoding.mode === "stream")) {
1453
+ throw new Error("Upgrade endpoints cannot declare a streaming payload")
1454
+ }
1366
1455
  }
1367
1456
  return
1368
1457
  }
@@ -1386,10 +1475,12 @@ function validateSuccessResponse(schemas: ReadonlyArray<Schema.Constraint>, meth
1386
1475
  if (entry.noContent) {
1387
1476
  throw new Error(`Cannot combine no-content and streaming success responses for status: ${status}`)
1388
1477
  }
1389
- if (entry.bufferedContentTypes.has(MediaType.normalize(inner.contentType))) {
1390
- throw new Error(
1391
- `Cannot combine buffered and streaming success responses for status ${status} and content-type: ${inner.contentType}`
1392
- )
1478
+ for (const declared of inner.contentTypes) {
1479
+ if (entry.bufferedContentTypes.has(MediaType.normalize(declared))) {
1480
+ throw new Error(
1481
+ `Cannot combine buffered and streaming success responses for status ${status} and content-type: ${declared}`
1482
+ )
1483
+ }
1393
1484
  }
1394
1485
  statuses.set(status, { ...entry, stream: inner })
1395
1486
  } else {
@@ -1400,9 +1491,8 @@ function validateSuccessResponse(schemas: ReadonlyArray<Schema.Constraint>, meth
1400
1491
  throw new Error(`Cannot combine no-content and streaming success responses for status: ${status}`)
1401
1492
  }
1402
1493
  const encoding = HttpApiSchema.getResponseEncodingSchema(schema)
1403
- if (
1404
- MediaType.normalize(encoding.contentType) === MediaType.normalize(entry.stream.contentType)
1405
- ) {
1494
+ const contentType = MediaType.normalize(encoding.contentType)
1495
+ if (entry.stream.contentTypes.some((declared) => MediaType.normalize(declared) === contentType)) {
1406
1496
  throw new Error(
1407
1497
  `Cannot combine buffered and streaming success responses for status ${status} and content-type: ${encoding.contentType}`
1408
1498
  )
@@ -1535,7 +1625,7 @@ function transformResponse(schema: Schema.Top): Schema.Top {
1535
1625
  "~httpApiWithHeaders": {
1536
1626
  ...withHeaders,
1537
1627
  bodyCodec: applyResponseEncoding(withHeaders.body, encoding),
1538
- headersCodec: Schema.toCodecStringTree(withHeaders.headers)
1628
+ headersCodec: toCodecHttpProperties(withHeaders.headers)
1539
1629
  }
1540
1630
  })
1541
1631
  }
@@ -1553,6 +1643,7 @@ function applyResponseEncoding(schema: Schema.Top, encoding: HttpApiSchema.Respo
1553
1643
  }
1554
1644
 
1555
1645
  function transformPayload(schema: Schema.Top, method: HttpMethod): Schema.Top {
1646
+ if (!hasBody(method)) return toCodecHttpProperties(schema)
1556
1647
  const encoding = HttpApiSchema.getPayloadEncoding(schema.ast, method)
1557
1648
  switch (encoding._tag) {
1558
1649
  case "Json":
@@ -10,6 +10,7 @@
10
10
  * @stability unstable
11
11
  * @since 4.0.0
12
12
  */
13
+ import * as Arr from "../Array.ts"
13
14
  import * as ByteSize from "../ByteSize.ts"
14
15
  import * as Sse from "../encoding/Sse.ts"
15
16
  import { constVoid, type LazyArg } from "../Function.ts"
@@ -22,6 +23,7 @@ import * as SchemaAST from "../SchemaAST.ts"
22
23
  import * as SchemaTransformation from "../SchemaTransformation.ts"
23
24
  import * as Socket from "../socket/Socket.ts"
24
25
  import * as Stream from "../Stream.ts"
26
+ import * as MediaType from "./internal/mediaType.ts"
25
27
 
26
28
  declare module "../Schema.ts" {
27
29
  namespace Annotations {
@@ -122,13 +124,15 @@ export type StatusLiteral = HttpStatus.Literal
122
124
  *
123
125
  * **Details**
124
126
  *
125
- * The status is stored with `.annotateKey({ httpApiStatus: code })`, so a named
126
- * schema reused with different statuses still emits a single OpenAPI component.
127
- * If the schema has checks or already has an `httpApiStatus` annotation, it is
128
- * stored with `.annotate({ httpApiStatus: code })` instead. A later
129
- * `.annotate({ httpApiStatus })` takes precedence, and a later check drops the
130
- * status. You can pass either a numeric status code (for example, `201`) or a
131
- * common literal name (for example, `"Created"`).
127
+ * Stores the status with `.annotateKey({ httpApiStatus: code })` unless the
128
+ * schema or any of its checks already has an ordinary `httpApiStatus`
129
+ * annotation, including an explicit `undefined`. In that case, uses
130
+ * `.annotate({ httpApiStatus: code })` instead.
131
+ *
132
+ * Ordinary status annotations take precedence over key annotations. Checks
133
+ * without a status annotation preserve the existing status. You can pass
134
+ * either a numeric code (for example, `201`) or a common literal name
135
+ * (for example, `"Created"`).
132
136
  *
133
137
  * @stability unstable
134
138
  * @category schemas
@@ -149,9 +153,9 @@ export function status(code: StatusLiteral): {
149
153
  export function status(code: number | StatusLiteral) {
150
154
  const statusCode = typeof code === "string" ? HttpStatus.fromLiteral(code) : code
151
155
  return <S extends Schema.Top>(self: S): S["Rebuild"] =>
152
- self.ast.checks !== undefined || hasStatusAnnotation(self.ast)
153
- ? self.annotate({ httpApiStatus: statusCode })
154
- : self.annotateKey({ httpApiStatus: statusCode })
156
+ findHttpApiStatusAnnotation(self.ast) === undefined
157
+ ? self.annotateKey({ httpApiStatus: statusCode })
158
+ : self.annotate({ httpApiStatus: statusCode })
155
159
  }
156
160
 
157
161
  /**
@@ -321,6 +325,7 @@ export interface StreamSse<
321
325
  readonly mode: "sse"
322
326
  readonly sseMode: StreamSseMode
323
327
  readonly contentType: string
328
+ readonly contentTypes: Arr.NonEmptyReadonlyArray<string>
324
329
  readonly events: Events
325
330
  readonly error: Error
326
331
  readonly "~Value"?: Value | undefined
@@ -379,6 +384,7 @@ export interface StreamUint8Array extends
379
384
  readonly _tag: "StreamUint8Array"
380
385
  readonly mode: "uint8array"
381
386
  readonly contentType: string
387
+ readonly contentTypes: Arr.NonEmptyReadonlyArray<string>
382
388
  readonly maxBytes: ByteSize.ByteSize | undefined
383
389
  }
384
390
 
@@ -430,6 +436,7 @@ export interface StreamNdjson<S extends Schema.Constraint> extends
430
436
  readonly _tag: "StreamNdjson"
431
437
  readonly mode: "ndjson"
432
438
  readonly contentType: string
439
+ readonly contentTypes: Arr.NonEmptyReadonlyArray<string>
433
440
  readonly schema: S
434
441
  readonly maxBytes: ByteSize.ByteSize | undefined
435
442
  readonly maxElementBytes: ByteSize.ByteSize
@@ -523,7 +530,7 @@ export const StreamSse: {
523
530
  _tag: "StreamSse",
524
531
  mode: "sse",
525
532
  sseMode: options.events === undefined ? "data" : "events",
526
- contentType: options.contentType ?? defaultStreamContentType("sse"),
533
+ ...streamContentTypes(options.contentType, "sse"),
527
534
  events,
528
535
  error: options.error ?? Schema.Never
529
536
  })
@@ -534,22 +541,24 @@ export const StreamSse: {
534
541
  *
535
542
  * **Details**
536
543
  *
537
- * `contentType` defaults to `application/octet-stream`. `maxBytes` only applies
538
- * to request payloads and has no default.
544
+ * `contentType` defaults to `application/octet-stream`. Pass a list when the
545
+ * same stream is sent under several media types. The first entry is the
546
+ * default response type, and payloads are accepted under every entry.
547
+ * `maxBytes` only applies to request payloads and has no default.
539
548
  *
540
549
  * @stability unstable
541
550
  * @category constructors
542
551
  * @since 4.0.0
543
552
  */
544
553
  export const StreamUint8Array = (options?: {
545
- readonly contentType?: string | undefined
554
+ readonly contentType?: string | ReadonlyArray<string> | undefined
546
555
  readonly maxBytes?: ByteSize.Input | undefined
547
556
  }): StreamUint8Array =>
548
557
  Schema.make<StreamUint8Array>(streamSchema.ast, {
549
558
  [StreamSchemaTypeId]: StreamSchemaTypeId,
550
559
  _tag: "StreamUint8Array",
551
560
  mode: "uint8array",
552
- contentType: options?.contentType ?? defaultStreamContentType("uint8array"),
561
+ ...streamContentTypes(options?.contentType, "uint8array"),
553
562
  maxBytes: options?.maxBytes === undefined ? undefined : ByteSize.fromInputUnsafe(options.maxBytes)
554
563
  })
555
564
 
@@ -559,7 +568,8 @@ export const StreamUint8Array = (options?: {
559
568
  * **Details**
560
569
  *
561
570
  * `contentType` defaults to `application/x-ndjson` and `maxElementBytes` to 1
562
- * MiB. `maxBytes` has no default.
571
+ * MiB. `maxBytes` has no default. Pass a list of content types to accept
572
+ * aliases such as `application/jsonl`. The first entry is the default.
563
573
  *
564
574
  * **Example** (Declaring an NDJSON request payload)
565
575
  *
@@ -587,7 +597,7 @@ export const StreamUint8Array = (options?: {
587
597
  */
588
598
  export const StreamNdjson = <S extends Schema.Constraint>(options: {
589
599
  readonly schema: S
590
- readonly contentType?: string | undefined
600
+ readonly contentType?: string | ReadonlyArray<string> | undefined
591
601
  readonly maxBytes?: ByteSize.Input | undefined
592
602
  readonly maxElementBytes?: ByteSize.Input | undefined
593
603
  }): StreamNdjson<S> =>
@@ -595,7 +605,7 @@ export const StreamNdjson = <S extends Schema.Constraint>(options: {
595
605
  [StreamSchemaTypeId]: StreamSchemaTypeId,
596
606
  _tag: "StreamNdjson",
597
607
  mode: "ndjson",
598
- contentType: options.contentType ?? defaultStreamContentType("ndjson"),
608
+ ...streamContentTypes(options.contentType, "ndjson"),
599
609
  schema: options.schema,
600
610
  maxBytes: options.maxBytes === undefined ? undefined : ByteSize.fromInputUnsafe(options.maxBytes),
601
611
  maxElementBytes: options.maxElementBytes === undefined
@@ -637,24 +647,27 @@ const UpgradeTypeId = "~effect/http-api/HttpApiSchema/Upgrade"
637
647
  *
638
648
  * Created with {@link Upgrade}. The response is `101 Switching Protocols`, and
639
649
  * the connection then carries raw bytes in both directions as a `Socket`.
650
+ * `Headers` is the schema of the custom `101` headers, or `never` when the
651
+ * upgrade declares none.
640
652
  *
641
653
  * @stability unstable
642
654
  * @category models
643
655
  * @since 4.0.6
644
656
  */
645
- export interface Upgrade extends
657
+ export interface Upgrade<Headers extends Schema.Top = Schema.Top> extends
646
658
  Schema.Bottom<
647
659
  Socket.Socket,
648
660
  Socket.Socket,
649
661
  never,
650
662
  never,
651
663
  SchemaAST.Declaration,
652
- Upgrade
664
+ Upgrade<Headers>
653
665
  >
654
666
  {
655
- readonly "Rebuild": Upgrade
667
+ readonly "Rebuild": Upgrade<Headers>
656
668
  readonly [UpgradeTypeId]: typeof UpgradeTypeId
657
669
  readonly protocol: string
670
+ readonly headers: Headers | undefined
658
671
  }
659
672
 
660
673
  const upgradeSchema = Schema.declare(Socket.isSocket).pipe(status(101))
@@ -672,26 +685,41 @@ const upgradeSchema = Schema.declare(Socket.isSocket).pipe(status(101))
672
685
  *
673
686
  * **Details**
674
687
  *
675
- * The handler receives the connection as `socket`. The `101` response is
676
- * sent when the handler acquires the socket's reader, so a handler can still
677
- * fail with a declared error before then. Requests that do not ask for
678
- * `protocol` get `426 Upgrade Required`.
688
+ * The handler receives an `upgrade` function that returns the connection.
689
+ * The `101` response is sent when the handler acquires the socket's reader,
690
+ * so a handler can still fail with a declared error before then. Requests
691
+ * that do not ask for `protocol` get `426 Upgrade Required`.
679
692
  *
680
- * The client sends `Connection: Upgrade` and `Upgrade: protocol`, and returns
681
- * the response headers with the connection. Other responses are decoded as
682
- * the endpoint's errors.
693
+ * `headers` declares custom `101` response headers, encoded like
694
+ * `WithHeaders` headers. The handler passes them to `upgrade`, so they can
695
+ * depend on the decoded request. `Connection`, `Upgrade`, `Content-Length`
696
+ * and `Transfer-Encoding` cannot be set.
697
+ *
698
+ * The endpoint may declare a buffered payload, which is decoded before the
699
+ * handler runs. Streaming payloads are rejected.
683
700
  *
684
- * The endpoint cannot declare a payload or other success schemas.
701
+ * The client sends `Connection: Upgrade` and `Upgrade: protocol`, and returns
702
+ * the response headers with the connection, decoded with `headers` when
703
+ * declared. Other responses are decoded as the endpoint's errors.
685
704
  *
686
- * **Example** (Declaring an attach endpoint)
705
+ * **Example** (Declaring an exec start endpoint)
687
706
  *
688
707
  * ```ts
689
708
  * import { Schema } from "effect"
690
709
  * import { HttpApiEndpoint, HttpApiSchema } from "effect/http-api"
691
710
  *
692
- * const attach = HttpApiEndpoint.post("attach", "/containers/:id/attach", {
711
+ * const start = HttpApiEndpoint.post("start", "/exec/:id/start", {
693
712
  * params: { id: Schema.String },
694
- * success: HttpApiSchema.Upgrade({ protocol: "tcp" })
713
+ * payload: Schema.Struct({ Detach: Schema.Boolean, Tty: Schema.Boolean }),
714
+ * success: HttpApiSchema.Upgrade({
715
+ * protocol: "tcp",
716
+ * headers: {
717
+ * "content-type": Schema.Literals([
718
+ * "application/vnd.docker.raw-stream",
719
+ * "application/vnd.docker.multiplexed-stream"
720
+ * ])
721
+ * }
722
+ * })
695
723
  * })
696
724
  * ```
697
725
  *
@@ -699,23 +727,72 @@ const upgradeSchema = Schema.declare(Socket.isSocket).pipe(status(101))
699
727
  * @category constructors
700
728
  * @since 4.0.6
701
729
  */
702
- export const Upgrade = (options: {
730
+ export function Upgrade(options: { readonly protocol: string }): Upgrade<never>
731
+ /**
732
+ * @stability unstable
733
+ */
734
+ export function Upgrade<H extends Schema.Struct.Fields>(options: {
735
+ readonly protocol: string
736
+ readonly headers: H
737
+ }): Upgrade<Schema.Struct<H>>
738
+ /**
739
+ * @stability unstable
740
+ */
741
+ export function Upgrade<H extends Schema.Top>(options: {
703
742
  readonly protocol: string
704
- }): Upgrade => {
743
+ readonly headers: H
744
+ }): Upgrade<H>
745
+ /**
746
+ * @stability unstable
747
+ */
748
+ export function Upgrade(options: {
749
+ readonly protocol: string
750
+ readonly headers?: Schema.Top | Schema.Struct.Fields | undefined
751
+ }): Upgrade {
705
752
  if (options.protocol.toLowerCase() === "websocket") {
706
753
  throw new Error("Upgrade does not support WebSocket")
707
754
  }
708
- return Schema.make<Upgrade>(upgradeSchema.ast, {
755
+ const headers = options.headers === undefined || Schema.isSchema(options.headers)
756
+ ? options.headers
757
+ : Schema.Struct(options.headers)
758
+ return rebuildUpgrade(options.protocol, headers)
759
+ }
760
+
761
+ /**
762
+ * @internal
763
+ */
764
+ export const rebuildUpgrade = (protocol: string, headers: Schema.Top | undefined): Upgrade =>
765
+ Schema.make<Upgrade>(upgradeSchema.ast, {
709
766
  [UpgradeTypeId]: UpgradeTypeId,
710
- protocol: options.protocol
767
+ protocol,
768
+ headers
711
769
  })
712
- }
713
770
 
714
771
  /**
715
772
  * @internal
716
773
  */
717
774
  export const isUpgrade = (u: unknown): u is Upgrade => Schema.isSchema(u) && Predicate.hasProperty(u, UpgradeTypeId)
718
775
 
776
+ function streamContentTypes(
777
+ contentType: string | ReadonlyArray<string> | undefined,
778
+ mode: StreamMode
779
+ ): { readonly contentType: string; readonly contentTypes: Arr.NonEmptyReadonlyArray<string> } {
780
+ if (contentType === undefined) contentType = defaultStreamContentType(mode)
781
+ if (typeof contentType === "string") return { contentType, contentTypes: [contentType] }
782
+ if (!Arr.isReadonlyArrayNonEmpty(contentType)) {
783
+ throw new Error("Stream schemas require at least one content type")
784
+ }
785
+ const seen = new Set<string>()
786
+ for (const entry of contentType) {
787
+ const normalized = MediaType.normalize(entry)
788
+ if (seen.has(normalized)) {
789
+ throw new Error(`Duplicate stream content type: ${entry}`)
790
+ }
791
+ seen.add(normalized)
792
+ }
793
+ return { contentType: contentType[0], contentTypes: contentType }
794
+ }
795
+
719
796
  function defaultStreamContentType(mode: StreamMode): string {
720
797
  switch (mode) {
721
798
  case "sse":
@@ -779,8 +856,8 @@ export type WithHeadersValueTypeId = typeof WithHeadersValueTypeId
779
856
  * `StreamSse` and `StreamUint8Array`; error responses remain non-streaming.
780
857
  * Nesting `WithHeaders` is rejected at construction.
781
858
  * - `headers` is any schema; endpoint construction applies
782
- * `Schema.toCodecStringTree` unless codecs are disabled, so leaves become
783
- * `string | undefined` on the wire and `undefined` leaves are omitted from the response.
859
+ * a StringTree codec unless codecs are disabled. Optional headers that encode
860
+ * to `undefined` are omitted from the response.
784
861
  * - Status and response-encoding annotations are resolved from the wrapper
785
862
  * first, falling through to the inner schema.
786
863
  * - A header-carrying response cannot share its status and content type with
@@ -1224,6 +1301,12 @@ export function asJson(options?: {
1224
1301
  *
1225
1302
  * The schema's encoded side must be a record of strings.
1226
1303
  *
1304
+ * **Gotchas**
1305
+ *
1306
+ * Fields are flat on the server. A field that encodes to a nested object is
1307
+ * sent as bracket keys that the server does not read back; use an explicit
1308
+ * codec such as `Schema.fromJsonString(...)` for structured values.
1309
+ *
1227
1310
  * @stability unstable
1228
1311
  * @category encoding
1229
1312
  * @since 4.0.0
@@ -1299,18 +1382,28 @@ const resolveHttpApiEncoding = SchemaAST.resolveAt<Encoding>("~httpApiEncoding")
1299
1382
  */
1300
1383
  export const getWithHeadersAnnotation = SchemaAST.resolveAt<WithHeadersAnnotation>("~httpApiWithHeaders")
1301
1384
 
1302
- const resolveHttpApiStatusAnnotation = SchemaAST.resolveAt<number>("httpApiStatus")
1303
-
1304
- function hasStatusAnnotation(ast: SchemaAST.AST): boolean {
1305
- const annotations = SchemaAST.resolve(ast)
1306
- return annotations !== undefined && "httpApiStatus" in annotations
1385
+ function findHttpApiStatusAnnotation(
1386
+ ast: SchemaAST.AST | SchemaAST.FilterGroup<any>
1387
+ ): Schema.Annotations.Annotations | undefined {
1388
+ if (ast.checks) {
1389
+ for (let i = ast.checks.length - 1; i >= 0; i--) {
1390
+ const check = ast.checks[i]
1391
+ if (check.annotations && "httpApiStatus" in check.annotations) return check.annotations
1392
+ if (check._tag === "FilterGroup") {
1393
+ const annotations = findHttpApiStatusAnnotation(check)
1394
+ if (annotations !== undefined) return annotations
1395
+ }
1396
+ }
1397
+ }
1398
+ const annotations = ast.annotations
1399
+ return annotations && "httpApiStatus" in annotations ? annotations : undefined
1307
1400
  }
1308
1401
 
1309
- // An `httpApiStatus` annotation, even `undefined`, overrides the key context set by
1310
- // `status`, which a later check drops, matching annotations
1311
1402
  function resolveHttpApiStatus(ast: SchemaAST.AST): number | undefined {
1312
- if (hasStatusAnnotation(ast)) return resolveHttpApiStatusAnnotation(ast)
1313
- return ast.checks === undefined ? ast.context?.annotations?.httpApiStatus : undefined
1403
+ const annotations = findHttpApiStatusAnnotation(ast)
1404
+ // An explicit undefined clears the status instead of falling back to key context.
1405
+ if (annotations !== undefined) return annotations.httpApiStatus as number | undefined
1406
+ return ast.context?.annotations?.httpApiStatus
1314
1407
  }
1315
1408
 
1316
1409
  const defaultJsonEncoding: Encoding = {
@@ -25,7 +25,7 @@ import * as Layer from "../Layer.ts"
25
25
  import type { Path } from "../Path.ts"
26
26
  import * as Scope from "../Scope.ts"
27
27
  import type * as HttpApi from "./HttpApi.ts"
28
- import type { HandlerRuntime } from "./HttpApiBuilder.ts"
28
+ import type { GroupService, HandlerRuntime } from "./HttpApiBuilder.ts"
29
29
  import * as HttpApiBuilder from "./HttpApiBuilder.ts"
30
30
  import * as HttpApiClient from "./HttpApiClient.ts"
31
31
  import type * as HttpApiEndpoint from "./HttpApiEndpoint.ts"
@@ -98,7 +98,8 @@ export const groups = Effect.fnUntraced(function*<
98
98
  handlers.set(endpointIdentifier, handler)
99
99
  routes.push(HttpApiBuilder.handlerToRoute(api, group as any, handler, context))
100
100
  }
101
- context = Context.add(context, group as any, { handlers, routes })
101
+ const service: GroupService = { handlers, routes }
102
+ context = Context.add(context, group as any, service)
102
103
  }
103
104
 
104
105
  const layer: Layer.Layer<