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
@@ -13,14 +13,14 @@
13
13
  */
14
14
  import * as Arr from "../Array.ts"
15
15
  import * as Clock from "../Clock.ts"
16
+ import * as Context from "../Context.ts"
16
17
  import * as Data from "../Data.ts"
17
18
  import * as Duration from "../Duration.ts"
18
19
  import * as Effect from "../Effect.ts"
19
20
  import * as Fiber from "../Fiber.ts"
20
- import { flow } from "../Function.ts"
21
21
  import * as Latch from "../Latch.ts"
22
22
  import * as Layer from "../Layer.ts"
23
- import * as Order from "../Order.ts"
23
+ import * as Scheduler from "../Scheduler.ts"
24
24
  import * as Semaphore from "../Semaphore.ts"
25
25
 
26
26
  /**
@@ -40,6 +40,9 @@ import * as Semaphore from "../Semaphore.ts"
40
40
  * the time is set to on or after the time they are scheduled to run. Fork the
41
41
  * effect being tested, then adjust the clock time, and finally verify that the
42
42
  * expected effects have been performed.
43
+ * The ordered execution of sleeps registered after multiple scheduler hops
44
+ * requires fibers running under {@link layer}; providing a clock from
45
+ * {@link make} by hand does not install the tracking scheduler.
43
46
  *
44
47
  * **Example** (Testing timeouts deterministically)
45
48
  *
@@ -142,7 +145,8 @@ export declare namespace TestClock {
142
145
  /**
143
146
  * Options used when constructing a `TestClock`. `warningDelay` controls how
144
147
  * long the live clock waits before logging a warning when a test uses time
145
- * without advancing the test clock.
148
+ * without advancing the test clock, or when a fiber woken by the test clock
149
+ * keeps running without suspending.
146
150
  *
147
151
  * **Example** (Configuring the warning delay)
148
152
  *
@@ -170,7 +174,8 @@ export declare namespace TestClock {
170
174
  export interface Options {
171
175
  /**
172
176
  * The amount of time to wait before displaying a warning message when a
173
- * test is using time but is not advancing the `TestClock`.
177
+ * test is using time but is not advancing the `TestClock`, or when a fiber
178
+ * woken by `adjust` or `setTime` keeps running without suspending.
174
179
  */
175
180
  readonly warningDelay?: Duration.Input
176
181
  }
@@ -197,15 +202,30 @@ const warningMessage = "A test is using time, but is not advancing the test " +
197
202
  "clock, which may result in the test hanging. Use TestClock.adjust to " +
198
203
  "manually advance the time."
199
204
 
205
+ /**
206
+ * The warning message that will be displayed if a fiber woken by the
207
+ * `TestClock` does not suspend within the warning delay.
208
+ */
209
+ const busyWarningMessage = "A fiber woken by the test clock is still running " +
210
+ "without suspending, so the test clock stopped waiting for it. Sleeps it " +
211
+ "starts later may be scheduled relative to a later time."
212
+
213
+ /**
214
+ * The live clock of each `TestClock`, so a `TestClock` constructed while
215
+ * another one is the current clock uses the outer clock's live clock instead
216
+ * of the outer `TestClock`, which only advances when adjusted.
217
+ */
218
+ const liveClocks = new WeakMap<Clock.Clock, Clock.Clock>()
219
+
220
+ interface WakeTracker {
221
+ pending: number
222
+ onIdle: (() => void) | undefined
223
+ }
224
+
200
225
  const defaultOptions: Required<TestClock.Options> = {
201
226
  warningDelay: "1 second"
202
227
  }
203
228
 
204
- const SleepOrder = Order.flip(Order.Struct({
205
- timestamp: Order.Number,
206
- sequence: Order.Number
207
- }))
208
-
209
229
  const nanosPerMilli = BigInt(1_000_000)
210
230
 
211
231
  const millisToNanos = (millis: number): bigint => {
@@ -217,6 +237,14 @@ const millisToNanos = (millis: number): bigint => {
217
237
  /**
218
238
  * Creates a `TestClock` with optional configuration.
219
239
  *
240
+ * **Gotchas**
241
+ *
242
+ * The guarantee that sleeps registered after multiple scheduler hops run in
243
+ * order applies only to fibers running under {@link layer}, which
244
+ * `@effect/vitest`'s `it.effect` uses. Providing a clock from `make` by hand
245
+ * waits only one scheduler turn after each woken sleep. Prefer `layer` when
246
+ * forked fibers sleep.
247
+ *
220
248
  * **Example** (Creating a test clock)
221
249
  *
222
250
  * ```ts import.meta.vitest
@@ -245,18 +273,21 @@ const millisToNanos = (millis: number): bigint => {
245
273
  * @category constructors
246
274
  * @since 4.0.0
247
275
  */
248
- export const make = Effect.fnUntraced(function*(
276
+ export const make = (options?: TestClock.Options) => Effect.map(makeWithScheduler(options), ([testClock]) => testClock)
277
+
278
+ const makeWithScheduler = Effect.fnUntraced(function*(
249
279
  options?: TestClock.Options
250
280
  ) {
251
281
  const config = { ...defaultOptions, ...options }
252
- let sequence = 0
282
+ // Sorted by descending timestamp, so `pop` wakes the earliest sleep first
253
283
  const sleeps: Array<{
254
- readonly sequence: number
255
284
  readonly timestamp: number
256
285
  readonly latch: Latch.Latch
257
286
  }> = []
258
- const liveClock = yield* Clock.clockWith(Effect.succeed)
287
+ const currentClock = yield* Clock.clockWith(Effect.succeed)
288
+ const liveClock = liveClocks.get(currentClock) ?? currentClock
259
289
  const warningSemaphore = yield* Semaphore.make(1)
290
+ const parentScheduler = yield* Scheduler.Scheduler
260
291
 
261
292
  let currentTimestamp: number = new Date(0).getTime()
262
293
  let currentWallNanos = BigInt(0)
@@ -332,17 +363,97 @@ export const make = Effect.fnUntraced(function*(
332
363
  const millis = Duration.toMillis(duration)
333
364
  const end = currentTimestamp + millis
334
365
  if (end <= currentTimestamp) return
335
- const latch = Latch.makeUnsafe()
336
- sleeps.push({
337
- sequence: sequence++,
338
- timestamp: end,
339
- latch
340
- })
341
- sleeps.sort(SleepOrder)
342
- yield* warningStart
343
- yield* latch.await
366
+ yield* Effect.acquireUseRelease(
367
+ Effect.sync(() => {
368
+ const entry = { timestamp: end, latch: Latch.makeUnsafe() }
369
+ // Insert before entries with an equal timestamp, so they wake in
370
+ // registration order
371
+ let low = 0
372
+ let high = sleeps.length
373
+ while (low < high) {
374
+ const mid = (low + high) >>> 1
375
+ if (sleeps[mid].timestamp > end) low = mid + 1
376
+ else high = mid
377
+ }
378
+ sleeps.splice(low, 0, entry)
379
+ return entry
380
+ }),
381
+ (entry) => Effect.andThen(warningStart, entry.latch.await),
382
+ (entry) =>
383
+ Effect.sync(() => {
384
+ // The entry is already gone if `run` popped it
385
+ const index = sleeps.indexOf(entry)
386
+ if (index !== -1) sleeps.splice(index, 1)
387
+ })
388
+ )
344
389
  })
345
390
 
391
+ /**
392
+ * Tasks scheduled while waking a sleeper, and tasks scheduled by those tasks,
393
+ * are counted by that wake's tracker so `run` can wait for the woken fiber,
394
+ * and any fibers it resumes or forks, to suspend before checking the next
395
+ * sleep.
396
+ */
397
+ let currentTracker: WakeTracker | undefined = undefined
398
+
399
+ function runTracked(tracker: WakeTracker, f: () => void): void {
400
+ const previous = currentTracker
401
+ currentTracker = tracker
402
+ try {
403
+ f()
404
+ } finally {
405
+ currentTracker = previous
406
+ }
407
+ }
408
+
409
+ const scheduler: Scheduler.Scheduler = {
410
+ executionMode: parentScheduler.executionMode,
411
+ shouldYield: (fiber) => parentScheduler.shouldYield(fiber),
412
+ makeDispatcher() {
413
+ const dispatcher = parentScheduler.makeDispatcher()
414
+ return {
415
+ scheduleTask(task, priority) {
416
+ const tracker = currentTracker
417
+ if (tracker === undefined) {
418
+ return dispatcher.scheduleTask(task, priority)
419
+ }
420
+ tracker.pending++
421
+ dispatcher.scheduleTask(() => {
422
+ try {
423
+ runTracked(tracker, task)
424
+ } finally {
425
+ if (--tracker.pending === 0) tracker.onIdle?.()
426
+ }
427
+ }, priority)
428
+ },
429
+ flush() {
430
+ dispatcher.flush()
431
+ }
432
+ }
433
+ }
434
+ }
435
+
436
+ const wake = (latch: Latch.Latch) =>
437
+ Effect.suspend(() => {
438
+ const tracker: WakeTracker = { pending: 0, onIdle: undefined }
439
+ runTracked(tracker, () => latch.openUnsafe())
440
+ if (tracker.pending === 0) return Effect.yieldNow
441
+ return Effect.callback<void>((resume) => {
442
+ if (tracker.pending === 0) return resume(Effect.void)
443
+ tracker.onIdle = () => resume(Effect.void)
444
+ return Effect.sync(() => {
445
+ tracker.onIdle = undefined
446
+ })
447
+ }).pipe(
448
+ Effect.timeoutOrElse({
449
+ duration: config.warningDelay,
450
+ orElse: () => Effect.logWarning(busyWarningMessage)
451
+ }),
452
+ withLive,
453
+ Effect.andThen(Effect.yieldNow)
454
+ )
455
+ })
456
+
346
457
  const runSemaphore = yield* Semaphore.make(1)
347
458
  const run = Effect.fnUntraced(function*(
348
459
  step: (currentTimestamp: number) => number,
@@ -366,8 +477,7 @@ export const make = Effect.fnUntraced(function*(
366
477
  if (Arr.lastNonEmpty(sleeps).timestamp > endTimestamp) break
367
478
  const entry = sleeps.pop()!
368
479
  advanceTo(entry.timestamp)
369
- entry.latch.openUnsafe()
370
- yield* Effect.yieldNow
480
+ yield* wake(entry.latch)
371
481
  }
372
482
  advanceTo(endTimestamp)
373
483
  if (adjustmentNanos !== undefined && Number.isFinite(endTimestamp)) {
@@ -391,7 +501,7 @@ export const make = Effect.fnUntraced(function*(
391
501
 
392
502
  yield* Effect.addFinalizer(() => warningDone)
393
503
 
394
- return {
504
+ const testClock = {
395
505
  currentTimeMillisUnsafe,
396
506
  currentTimeNanosUnsafe,
397
507
  monotonicTimeNanosUnsafe,
@@ -403,6 +513,8 @@ export const make = Effect.fnUntraced(function*(
403
513
  sleep,
404
514
  withLive
405
515
  }
516
+ liveClocks.set(testClock, liveClock)
517
+ return [testClock, scheduler] as const
406
518
  })
407
519
 
408
520
  /**
@@ -438,10 +550,13 @@ export const make = Effect.fnUntraced(function*(
438
550
  * @category layers
439
551
  * @since 4.0.0
440
552
  */
441
- export const layer: (options?: TestClock.Options) => Layer.Layer<TestClock> = flow(
442
- make,
443
- Layer.effect(Clock.Clock)
444
- ) as any
553
+ export const layer = (options?: TestClock.Options): Layer.Layer<TestClock> =>
554
+ Layer.effectContext(
555
+ Effect.map(makeWithScheduler(options), ([testClock, scheduler]) =>
556
+ Context.make(Clock.Clock, testClock).pipe(
557
+ Context.add(Scheduler.Scheduler, scheduler)
558
+ ))
559
+ ) as any
445
560
 
446
561
  /**
447
562
  * Retrieves the `TestClock` service for this test and uses it to run the
@@ -347,6 +347,7 @@ const makeExecute = Effect.fnUntraced(function*<
347
347
  (_) => _._tag === "Suspended"
348
348
  )
349
349
  if (result._tag === "Suspended") {
350
+ if (result.failed) instance.failed = true
350
351
  return yield* Workflow.suspend(instance)
351
352
  }
352
353
  return yield* result.exit
@@ -134,6 +134,25 @@ const CurrentAttempt = Context.Reference<number>(
134
134
  { defaultValue: () => 1 }
135
135
  )
136
136
 
137
+ /** Awaits registered under the instance copy of a `recordHeld` body. */
138
+ const awaitOwners = new WeakMap<WorkflowInstance["Service"], Array<string>>()
139
+
140
+ const registerAwait = (instance: WorkflowInstance["Service"], name: string) => {
141
+ instance.awaitedDeferreds.set(name, (instance.awaitedDeferreds.get(name) ?? 0) + 1)
142
+ awaitOwners.get(instance)?.push(name)
143
+ }
144
+
145
+ const releaseAwaits = (instance: WorkflowInstance["Service"], names: Array<string>) => {
146
+ for (const name of names) {
147
+ const count = instance.awaitedDeferreds.get(name)! - 1
148
+ if (count === 0) {
149
+ instance.awaitedDeferreds.delete(name)
150
+ } else {
151
+ instance.awaitedDeferreds.set(name, count)
152
+ }
153
+ }
154
+ }
155
+
137
156
  const await_: <Success extends Schema.Constraint, Error extends Schema.Constraint>(
138
157
  self: DurableDeferred<Success, Error>
139
158
  ) => Effect.Effect<
@@ -150,7 +169,7 @@ const await_: <Success extends Schema.Constraint, Error extends Schema.Constrain
150
169
  const engine = yield* EngineTag
151
170
  const instance = yield* InstanceTag
152
171
  // Register before the read so any later completion can preempt the run.
153
- instance.awaitedDeferreds.add(self.name)
172
+ registerAwait(instance, self.name)
154
173
  const exit = yield* Workflow.wrapActivityResult(
155
174
  engine.deferredResult(self),
156
175
  Option.isNone
@@ -343,6 +362,10 @@ const recordHeld = Effect.fnUntraced(function*<A, E, R>(
343
362
  suspended: false,
344
363
  activityState: { count: 0, latch: Latch.makeUnsafe() }
345
364
  }
365
+ // A losing branch parked on a durable wait has already exited when the
366
+ // race settles, so this body owns the waits registered beneath it.
367
+ const owned: Array<string> = []
368
+ awaitOwners.set(local, owned)
346
369
  // A parked `effect` interrupts the fiber it runs on. The child fiber
347
370
  // keeps that from skipping the suspension handling below.
348
371
  const fiber = yield* effect.pipe(
@@ -350,10 +373,25 @@ const recordHeld = Effect.fnUntraced(function*<A, E, R>(
350
373
  Effect.onExit((exit) => recordExit(engine, instance, self, exit)),
351
374
  Effect.forkChild({ startImmediately: true })
352
375
  )
353
- const exit = yield* Effect.onInterrupt(Fiber.await(fiber), () => Fiber.interrupt(fiber))
354
- return local.suspended && Exit.isFailure(exit) && Cause.hasInterruptsOnly(exit.cause)
355
- ? Option.none()
356
- : Option.some(exit)
376
+ return yield* Effect.onInterrupt(Fiber.await(fiber), () => Fiber.interrupt(fiber)).pipe(
377
+ Effect.map((exit) =>
378
+ local.suspended && Exit.isFailure(exit) && Cause.hasInterruptsOnly(exit.cause)
379
+ ? Option.none()
380
+ : Option.some(exit)
381
+ ),
382
+ // The waits are over once the body has a result. Otherwise every branch
383
+ // parked, or an enclosing race interrupted the body, and the waits move
384
+ // to the enclosing owner, if any, to be released when that race settles.
385
+ Effect.onExit((result) =>
386
+ Effect.sync(() => {
387
+ if (Exit.isSuccess(result) && Option.isSome(result.value)) {
388
+ releaseAwaits(instance, owned)
389
+ } else {
390
+ awaitOwners.get(instance)?.push(...owned)
391
+ }
392
+ })
393
+ )
394
+ )
357
395
  }),
358
396
  // Every branch of `effect` parked: release the hold and let the enclosing
359
397
  // activities finish before suspending. External preemption does not wait.
@@ -78,11 +78,26 @@ export interface Workflow<
78
78
 
79
79
  /**
80
80
  * Execute the workflow with the given payload.
81
+ *
82
+ * **Details**
83
+ *
84
+ * `discard: true` returns the execution ID without waiting for the result.
85
+ * The child remains linked to its parent for completion wakes and interruption.
86
+ *
87
+ * With `discard: true, detached: true`, the child neither wakes its parent
88
+ * nor gets interrupted with it. The cluster engine retains the parent for
89
+ * observability.
90
+ *
91
+ * **Gotchas**
92
+ *
93
+ * Do not await a detached execution later. Executing the same payload joins
94
+ * it, but its completion will not wake the awaiting workflow.
81
95
  */
82
96
  readonly execute: <const Discard extends boolean = false>(
83
97
  payload: Payload["~type.make.in"],
84
98
  options?: {
85
99
  readonly discard?: Discard
100
+ readonly detached?: [Discard] extends [true] ? boolean | undefined : undefined
86
101
  }
87
102
  ) => Effect.Effect<
88
103
  Discard extends true ? string : Success["Type"],
@@ -248,7 +263,7 @@ export interface AnyWithProps extends Any {
248
263
  readonly errorSchema: Schema.Top
249
264
  readonly execute: (
250
265
  payload: any,
251
- options?: { readonly discard?: boolean }
266
+ options?: { readonly discard?: boolean; readonly detached?: boolean | undefined }
252
267
  ) => Effect.Effect<any, any, any>
253
268
  readonly resume: (
254
269
  executionId: string
@@ -352,7 +367,7 @@ const Proto = {
352
367
  execute<const Discard extends boolean = false>(
353
368
  this: AnyWithProps,
354
369
  fields: any,
355
- opts?: { readonly discard?: Discard } | undefined
370
+ opts?: { readonly discard?: Discard; readonly detached?: boolean | undefined } | undefined
356
371
  ) {
357
372
  return Effect.suspend(() => {
358
373
  const payload = this.payloadSchema.make(fields)
@@ -366,6 +381,7 @@ const Proto = {
366
381
  executionId,
367
382
  payload,
368
383
  discard: opts?.discard,
384
+ detached: opts?.detached,
369
385
  suspendedRetrySchedule: this.suspendedRetrySchedule
370
386
  })
371
387
  ))
@@ -617,6 +633,11 @@ export class Complete<A, E> extends Data.TaggedClass("Complete")<{
617
633
  * Represents a suspended workflow execution, optionally carrying the cause that
618
634
  * triggered suspension.
619
635
  *
636
+ * **Details**
637
+ *
638
+ * `failed` marks this execution's own `SuspendOnFailure` and requires explicit
639
+ * `resume` or `interrupt`. Inherited child failures do not set it.
640
+ *
620
641
  * @stability unstable
621
642
  * @category schemas
622
643
  * @since 4.0.0
@@ -625,7 +646,8 @@ export class Suspended extends Schema.Class<Suspended>(
625
646
  "effect/workflow/Workflow/Suspended"
626
647
  )({
627
648
  _tag: Schema.tag("Suspended"),
628
- cause: Schema.optional(Schema.Cause(Schema.Never, Schema.Defect()))
649
+ cause: Schema.optional(Schema.Cause(Schema.Never, Schema.Defect())),
650
+ failed: Schema.optional(Schema.Boolean)
629
651
  }) {
630
652
  /**
631
653
  * Marks this value as a workflow result for runtime guards.
@@ -697,11 +719,13 @@ export const intoResult = <A, E, R>(
697
719
  Effect.interruptible,
698
720
  suspendOnFailure
699
721
  ? Effect.catchCause((cause) => {
700
- if (instance.abandoned) {
722
+ if (instance.abandoned || instance.interrupted) {
701
723
  return Effect.failCause(cause)
702
724
  }
703
725
  instance.suspended = true
726
+ // Ordinary suspension is a self-interrupt and also reaches here.
704
727
  if (!Cause.hasInterruptsOnly(cause)) {
728
+ instance.failed = true
705
729
  instance.cause = Cause.die(Cause.squash(cause))
706
730
  }
707
731
  return Effect.interrupt
@@ -720,7 +744,9 @@ export const intoResult = <A, E, R>(
720
744
  const abandoned = instance.abandoned && !instance.interrupted && hasInterruptsOnly
721
745
  instance.abandoned = abandoned
722
746
  if (instance.suspended && hasInterruptsOnly && !abandoned) {
723
- return Effect.succeed(new Suspended({ cause: instance.cause }))
747
+ return Effect.succeed(
748
+ new Suspended(instance.failed ? { cause: instance.cause, failed: true } : { cause: instance.cause })
749
+ )
724
750
  }
725
751
  if (!instance.interrupted && hasInterruptsOnly) {
726
752
  // External interrupts exit without a result. When the cluster has