effect 4.0.2 → 4.0.4

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 (389) 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 +111 -0
  5. package/ai-docs/src/52_graphql/20_testing.ts +45 -0
  6. package/ai-docs/src/52_graphql/30_batching.ts +116 -0
  7. package/ai-docs/src/52_graphql/40_aliased-batching.ts +122 -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/Context.d.ts.map +1 -1
  11. package/dist/Context.js +12 -3
  12. package/dist/Context.js.map +1 -1
  13. package/dist/Crypto.d.ts +33 -5
  14. package/dist/Crypto.d.ts.map +1 -1
  15. package/dist/Crypto.js +8 -2
  16. package/dist/Crypto.js.map +1 -1
  17. package/dist/DateTime.d.ts +9 -6
  18. package/dist/DateTime.d.ts.map +1 -1
  19. package/dist/DateTime.js +9 -6
  20. package/dist/DateTime.js.map +1 -1
  21. package/dist/Duration.d.ts +6 -6
  22. package/dist/Duration.d.ts.map +1 -1
  23. package/dist/Duration.js +27 -8
  24. package/dist/Duration.js.map +1 -1
  25. package/dist/FileSystem.d.ts +44 -2
  26. package/dist/FileSystem.d.ts.map +1 -1
  27. package/dist/FileSystem.js.map +1 -1
  28. package/dist/RequestResolver.d.ts.map +1 -1
  29. package/dist/RequestResolver.js +4 -10
  30. package/dist/RequestResolver.js.map +1 -1
  31. package/dist/Scheduler.d.ts +9 -0
  32. package/dist/Scheduler.d.ts.map +1 -1
  33. package/dist/Scheduler.js +9 -0
  34. package/dist/Scheduler.js.map +1 -1
  35. package/dist/Schema.d.ts +481 -1
  36. package/dist/Schema.d.ts.map +1 -1
  37. package/dist/Schema.js +362 -4
  38. package/dist/Schema.js.map +1 -1
  39. package/dist/SchemaGetter.d.ts +4 -0
  40. package/dist/SchemaGetter.d.ts.map +1 -1
  41. package/dist/SchemaGetter.js +52 -33
  42. package/dist/SchemaGetter.js.map +1 -1
  43. package/dist/Sink.d.ts.map +1 -1
  44. package/dist/Sink.js +38 -17
  45. package/dist/Sink.js.map +1 -1
  46. package/dist/Stdio.d.ts +7 -1
  47. package/dist/Stdio.d.ts.map +1 -1
  48. package/dist/Stdio.js +1 -0
  49. package/dist/Stdio.js.map +1 -1
  50. package/dist/Stream.d.ts +22 -11
  51. package/dist/Stream.d.ts.map +1 -1
  52. package/dist/Stream.js +21 -6
  53. package/dist/Stream.js.map +1 -1
  54. package/dist/Utils.js +8 -3
  55. package/dist/Utils.js.map +1 -1
  56. package/dist/ai/AnthropicStructuredOutput.js +0 -2
  57. package/dist/ai/AnthropicStructuredOutput.js.map +1 -1
  58. package/dist/ai/Chat.d.ts +2 -2
  59. package/dist/ai/Chat.d.ts.map +1 -1
  60. package/dist/ai/LanguageModel.d.ts +38 -7
  61. package/dist/ai/LanguageModel.d.ts.map +1 -1
  62. package/dist/ai/LanguageModel.js +25 -7
  63. package/dist/ai/LanguageModel.js.map +1 -1
  64. package/dist/ai/McpServer.d.ts +61 -0
  65. package/dist/ai/McpServer.d.ts.map +1 -1
  66. package/dist/ai/McpServer.js +196 -44
  67. package/dist/ai/McpServer.js.map +1 -1
  68. package/dist/ai/Prompt.d.ts.map +1 -1
  69. package/dist/ai/Prompt.js +28 -5
  70. package/dist/ai/Prompt.js.map +1 -1
  71. package/dist/ai/Response.d.ts +4 -3
  72. package/dist/ai/Response.d.ts.map +1 -1
  73. package/dist/ai/Response.js.map +1 -1
  74. package/dist/ai/internal/mcpProtocol/v2026_07_28.js +5 -0
  75. package/dist/ai/internal/mcpProtocol/v2026_07_28.js.map +1 -1
  76. package/dist/ai/internal/mcpProtocol.js.map +1 -1
  77. package/dist/ai/internal/mcpRuntime.js +1 -0
  78. package/dist/ai/internal/mcpRuntime.js.map +1 -1
  79. package/dist/cli/CliOutput.d.ts +27 -0
  80. package/dist/cli/CliOutput.d.ts.map +1 -1
  81. package/dist/cli/CliOutput.js +33 -10
  82. package/dist/cli/CliOutput.js.map +1 -1
  83. package/dist/cli/Command.d.ts.map +1 -1
  84. package/dist/cli/Command.js +6 -3
  85. package/dist/cli/Command.js.map +1 -1
  86. package/dist/cli/Completions.d.ts +3 -3
  87. package/dist/cli/Completions.d.ts.map +1 -1
  88. package/dist/cli/Completions.js +8 -5
  89. package/dist/cli/Completions.js.map +1 -1
  90. package/dist/cli/GlobalFlag.d.ts +5 -4
  91. package/dist/cli/GlobalFlag.d.ts.map +1 -1
  92. package/dist/cli/GlobalFlag.js +3 -3
  93. package/dist/cli/GlobalFlag.js.map +1 -1
  94. package/dist/cli/Prompt.d.ts +17 -1
  95. package/dist/cli/Prompt.d.ts.map +1 -1
  96. package/dist/cli/Prompt.js +119 -114
  97. package/dist/cli/Prompt.js.map +1 -1
  98. package/dist/cli/internal/ansi.d.ts +0 -1
  99. package/dist/cli/internal/ansi.d.ts.map +1 -1
  100. package/dist/cli/internal/ansi.js +20 -3
  101. package/dist/cli/internal/ansi.js.map +1 -1
  102. package/dist/cli/internal/completions/powershell.d.ts +2 -0
  103. package/dist/cli/internal/completions/powershell.d.ts.map +1 -0
  104. package/dist/cli/internal/completions/powershell.js +273 -0
  105. package/dist/cli/internal/completions/powershell.js.map +1 -0
  106. package/dist/cli/internal/completions/zsh.js +3 -2
  107. package/dist/cli/internal/completions/zsh.js.map +1 -1
  108. package/dist/cli/internal/wizard.d.ts +3 -3
  109. package/dist/cli/internal/wizard.d.ts.map +1 -1
  110. package/dist/cli/internal/wizard.js +21 -18
  111. package/dist/cli/internal/wizard.js.map +1 -1
  112. package/dist/cluster/ClusterSchema.d.ts +28 -0
  113. package/dist/cluster/ClusterSchema.d.ts.map +1 -1
  114. package/dist/cluster/ClusterSchema.js +30 -0
  115. package/dist/cluster/ClusterSchema.js.map +1 -1
  116. package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
  117. package/dist/cluster/ClusterWorkflowEngine.js +56 -26
  118. package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
  119. package/dist/cluster/MessageStorage.d.ts +18 -3
  120. package/dist/cluster/MessageStorage.d.ts.map +1 -1
  121. package/dist/cluster/MessageStorage.js +31 -11
  122. package/dist/cluster/MessageStorage.js.map +1 -1
  123. package/dist/cluster/Runners.d.ts.map +1 -1
  124. package/dist/cluster/Runners.js +8 -2
  125. package/dist/cluster/Runners.js.map +1 -1
  126. package/dist/cluster/Sharding.d.ts.map +1 -1
  127. package/dist/cluster/Sharding.js +187 -66
  128. package/dist/cluster/Sharding.js.map +1 -1
  129. package/dist/cluster/SqlMessageStorage.d.ts +59 -19
  130. package/dist/cluster/SqlMessageStorage.d.ts.map +1 -1
  131. package/dist/cluster/SqlMessageStorage.js +84 -55
  132. package/dist/cluster/SqlMessageStorage.js.map +1 -1
  133. package/dist/cluster/SqlRunnerStorage.d.ts +68 -19
  134. package/dist/cluster/SqlRunnerStorage.d.ts.map +1 -1
  135. package/dist/cluster/SqlRunnerStorage.js +191 -113
  136. package/dist/cluster/SqlRunnerStorage.js.map +1 -1
  137. package/dist/cluster/internal/entityManager.js +104 -37
  138. package/dist/cluster/internal/entityManager.js.map +1 -1
  139. package/dist/encoding/Sse.d.ts +6 -0
  140. package/dist/encoding/Sse.d.ts.map +1 -1
  141. package/dist/encoding/Sse.js +62 -70
  142. package/dist/encoding/Sse.js.map +1 -1
  143. package/dist/graphql/GraphQL.d.ts +349 -0
  144. package/dist/graphql/GraphQL.d.ts.map +1 -0
  145. package/dist/graphql/GraphQL.js +207 -0
  146. package/dist/graphql/GraphQL.js.map +1 -0
  147. package/dist/graphql/GraphQLClient.d.ts +562 -0
  148. package/dist/graphql/GraphQLClient.d.ts.map +1 -0
  149. package/dist/graphql/GraphQLClient.js +498 -0
  150. package/dist/graphql/GraphQLClient.js.map +1 -0
  151. package/dist/graphql/GraphQLClientError.d.ts +445 -0
  152. package/dist/graphql/GraphQLClientError.d.ts.map +1 -0
  153. package/dist/graphql/GraphQLClientError.js +479 -0
  154. package/dist/graphql/GraphQLClientError.js.map +1 -0
  155. package/dist/graphql/GraphQLGroup.d.ts +118 -0
  156. package/dist/graphql/GraphQLGroup.d.ts.map +1 -0
  157. package/dist/graphql/GraphQLGroup.js +109 -0
  158. package/dist/graphql/GraphQLGroup.js.map +1 -0
  159. package/dist/graphql/GraphQLMiddleware.d.ts +249 -0
  160. package/dist/graphql/GraphQLMiddleware.d.ts.map +1 -0
  161. package/dist/graphql/GraphQLMiddleware.js +130 -0
  162. package/dist/graphql/GraphQLMiddleware.js.map +1 -0
  163. package/dist/graphql/GraphQLProtocol.d.ts +731 -0
  164. package/dist/graphql/GraphQLProtocol.d.ts.map +1 -0
  165. package/dist/graphql/GraphQLProtocol.js +719 -0
  166. package/dist/graphql/GraphQLProtocol.js.map +1 -0
  167. package/dist/graphql/GraphQLResolver.d.ts +453 -0
  168. package/dist/graphql/GraphQLResolver.d.ts.map +1 -0
  169. package/dist/graphql/GraphQLResolver.js +552 -0
  170. package/dist/graphql/GraphQLResolver.js.map +1 -0
  171. package/dist/graphql/index.d.ts +40 -0
  172. package/dist/graphql/index.d.ts.map +1 -0
  173. package/dist/graphql/index.js +41 -0
  174. package/dist/graphql/index.js.map +1 -0
  175. package/dist/http/FindMyWay/internal/router.js +3 -6
  176. package/dist/http/FindMyWay/internal/router.js.map +1 -1
  177. package/dist/http/HttpClient.d.ts +21 -0
  178. package/dist/http/HttpClient.d.ts.map +1 -1
  179. package/dist/http/HttpClient.js +63 -12
  180. package/dist/http/HttpClient.js.map +1 -1
  181. package/dist/http/HttpEffect.d.ts.map +1 -1
  182. package/dist/http/HttpEffect.js +14 -7
  183. package/dist/http/HttpEffect.js.map +1 -1
  184. package/dist/http/HttpMiddleware.d.ts.map +1 -1
  185. package/dist/http/HttpMiddleware.js +31 -32
  186. package/dist/http/HttpMiddleware.js.map +1 -1
  187. package/dist/http/HttpRouter.d.ts +35 -0
  188. package/dist/http/HttpRouter.d.ts.map +1 -1
  189. package/dist/http/HttpRouter.js +35 -0
  190. package/dist/http/HttpRouter.js.map +1 -1
  191. package/dist/http/HttpServerResponse.d.ts +8 -6
  192. package/dist/http/HttpServerResponse.d.ts.map +1 -1
  193. package/dist/http/HttpServerResponse.js +27 -16
  194. package/dist/http/HttpServerResponse.js.map +1 -1
  195. package/dist/http/HttpTraceContext.d.ts.map +1 -1
  196. package/dist/http/HttpTraceContext.js +4 -2
  197. package/dist/http/HttpTraceContext.js.map +1 -1
  198. package/dist/http/Multipart.d.ts.map +1 -1
  199. package/dist/http/Multipart.js +15 -1
  200. package/dist/http/Multipart.js.map +1 -1
  201. package/dist/http-api/HttpApiScalar.d.ts +5 -0
  202. package/dist/http-api/HttpApiScalar.d.ts.map +1 -1
  203. package/dist/http-api/HttpApiScalar.js.map +1 -1
  204. package/dist/internal/dateTime.js +40 -35
  205. package/dist/internal/dateTime.js.map +1 -1
  206. package/dist/internal/effect.js +19 -9
  207. package/dist/internal/effect.js.map +1 -1
  208. package/dist/internal/graphql.d.ts +2 -0
  209. package/dist/internal/graphql.d.ts.map +1 -0
  210. package/dist/internal/graphql.js +195 -0
  211. package/dist/internal/graphql.js.map +1 -0
  212. package/dist/internal/graphqlHeaders.d.ts +4 -0
  213. package/dist/internal/graphqlHeaders.d.ts.map +1 -0
  214. package/dist/internal/graphqlHeaders.js +11 -0
  215. package/dist/internal/graphqlHeaders.js.map +1 -0
  216. package/dist/internal/request.js +20 -1
  217. package/dist/internal/request.js.map +1 -1
  218. package/dist/internal/schema/toCodeDocument.js +4 -1
  219. package/dist/internal/schema/toCodeDocument.js.map +1 -1
  220. package/dist/internal/schema/toJsonSchemaDocument.js +29 -5
  221. package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
  222. package/dist/internal/version.js +1 -1
  223. package/dist/net/AddressResolver.d.ts +145 -0
  224. package/dist/net/AddressResolver.d.ts.map +1 -0
  225. package/dist/net/AddressResolver.js +114 -0
  226. package/dist/net/AddressResolver.js.map +1 -0
  227. package/dist/net/Dns.d.ts +596 -0
  228. package/dist/net/Dns.d.ts.map +1 -0
  229. package/dist/net/Dns.js +549 -0
  230. package/dist/net/Dns.js.map +1 -0
  231. package/dist/net/Host.d.ts +369 -0
  232. package/dist/net/Host.d.ts.map +1 -0
  233. package/dist/net/Host.js +397 -0
  234. package/dist/net/Host.js.map +1 -0
  235. package/dist/net/IpInterface.d.ts +76 -3
  236. package/dist/net/IpInterface.d.ts.map +1 -1
  237. package/dist/net/IpInterface.js +53 -4
  238. package/dist/net/IpInterface.js.map +1 -1
  239. package/dist/net/IpNetwork.d.ts +82 -8
  240. package/dist/net/IpNetwork.d.ts.map +1 -1
  241. package/dist/net/IpNetwork.js +60 -4
  242. package/dist/net/IpNetwork.js.map +1 -1
  243. package/dist/net/NetAddress.d.ts +396 -35
  244. package/dist/net/NetAddress.d.ts.map +1 -1
  245. package/dist/net/NetAddress.js +358 -34
  246. package/dist/net/NetAddress.js.map +1 -1
  247. package/dist/net/index.d.ts +15 -0
  248. package/dist/net/index.d.ts.map +1 -1
  249. package/dist/net/index.js +15 -0
  250. package/dist/net/index.js.map +1 -1
  251. package/dist/observability/OtlpMetrics.d.ts.map +1 -1
  252. package/dist/observability/OtlpMetrics.js +15 -21
  253. package/dist/observability/OtlpMetrics.js.map +1 -1
  254. package/dist/observability/PrometheusMetrics.js +1 -0
  255. package/dist/observability/PrometheusMetrics.js.map +1 -1
  256. package/dist/persistence/PersistedQueue.d.ts +32 -3
  257. package/dist/persistence/PersistedQueue.d.ts.map +1 -1
  258. package/dist/persistence/PersistedQueue.js +75 -16
  259. package/dist/persistence/PersistedQueue.js.map +1 -1
  260. package/dist/rpc/RpcClient.d.ts +22 -6
  261. package/dist/rpc/RpcClient.d.ts.map +1 -1
  262. package/dist/rpc/RpcClient.js +12 -5
  263. package/dist/rpc/RpcClient.js.map +1 -1
  264. package/dist/rpc/RpcServer.d.ts +6 -0
  265. package/dist/rpc/RpcServer.d.ts.map +1 -1
  266. package/dist/rpc/RpcServer.js +78 -29
  267. package/dist/rpc/RpcServer.js.map +1 -1
  268. package/dist/socket/DatagramSocket.d.ts +456 -0
  269. package/dist/socket/DatagramSocket.d.ts.map +1 -0
  270. package/dist/socket/DatagramSocket.js +535 -0
  271. package/dist/socket/DatagramSocket.js.map +1 -0
  272. package/dist/socket/Socket.d.ts +20 -1
  273. package/dist/socket/Socket.d.ts.map +1 -1
  274. package/dist/socket/Socket.js +9 -1
  275. package/dist/socket/Socket.js.map +1 -1
  276. package/dist/socket/index.d.ts +5 -0
  277. package/dist/socket/index.d.ts.map +1 -1
  278. package/dist/socket/index.js +5 -0
  279. package/dist/socket/index.js.map +1 -1
  280. package/dist/sql/Migrator.d.ts.map +1 -1
  281. package/dist/sql/Migrator.js +7 -2
  282. package/dist/sql/Migrator.js.map +1 -1
  283. package/dist/sql/SqlClient.d.ts +7 -1
  284. package/dist/sql/SqlClient.d.ts.map +1 -1
  285. package/dist/sql/SqlClient.js +31 -6
  286. package/dist/sql/SqlClient.js.map +1 -1
  287. package/dist/testing/TestCrypto.d.ts +73 -0
  288. package/dist/testing/TestCrypto.d.ts.map +1 -0
  289. package/dist/testing/TestCrypto.js +87 -0
  290. package/dist/testing/TestCrypto.js.map +1 -0
  291. package/dist/testing/index.d.ts +5 -0
  292. package/dist/testing/index.d.ts.map +1 -1
  293. package/dist/testing/index.js +5 -0
  294. package/dist/testing/index.js.map +1 -1
  295. package/dist/workflow/DurableDeferred.d.ts +54 -0
  296. package/dist/workflow/DurableDeferred.d.ts.map +1 -1
  297. package/dist/workflow/DurableDeferred.js +108 -50
  298. package/dist/workflow/DurableDeferred.js.map +1 -1
  299. package/dist/workflow/WorkflowEngine.d.ts +24 -2
  300. package/dist/workflow/WorkflowEngine.d.ts.map +1 -1
  301. package/dist/workflow/WorkflowEngine.js +13 -3
  302. package/dist/workflow/WorkflowEngine.js.map +1 -1
  303. package/package.json +6 -3
  304. package/src/Context.ts +12 -3
  305. package/src/Crypto.ts +43 -9
  306. package/src/DateTime.ts +9 -6
  307. package/src/Duration.ts +36 -16
  308. package/src/FileSystem.ts +48 -2
  309. package/src/RequestResolver.ts +4 -10
  310. package/src/Scheduler.ts +9 -0
  311. package/src/Schema.ts +677 -5
  312. package/src/SchemaGetter.ts +47 -35
  313. package/src/Sink.ts +45 -18
  314. package/src/Stdio.ts +9 -2
  315. package/src/Stream.ts +44 -15
  316. package/src/Utils.ts +8 -5
  317. package/src/ai/AnthropicStructuredOutput.ts +2 -2
  318. package/src/ai/Chat.ts +2 -2
  319. package/src/ai/LanguageModel.ts +96 -24
  320. package/src/ai/McpServer.ts +288 -94
  321. package/src/ai/Prompt.ts +24 -10
  322. package/src/ai/Response.ts +6 -3
  323. package/src/ai/internal/mcpProtocol/v2026_07_28.ts +5 -0
  324. package/src/ai/internal/mcpProtocol.ts +3 -0
  325. package/src/ai/internal/mcpRuntime.ts +2 -0
  326. package/src/cli/CliOutput.ts +33 -16
  327. package/src/cli/Command.ts +4 -3
  328. package/src/cli/Completions.ts +9 -6
  329. package/src/cli/GlobalFlag.ts +19 -11
  330. package/src/cli/Prompt.ts +159 -149
  331. package/src/cli/internal/ansi.ts +26 -3
  332. package/src/cli/internal/completions/powershell.ts +322 -0
  333. package/src/cli/internal/completions/zsh.ts +4 -2
  334. package/src/cli/internal/wizard.ts +34 -26
  335. package/src/cluster/ClusterSchema.ts +32 -0
  336. package/src/cluster/ClusterWorkflowEngine.ts +64 -36
  337. package/src/cluster/MessageStorage.ts +45 -14
  338. package/src/cluster/Runners.ts +8 -2
  339. package/src/cluster/Sharding.ts +219 -58
  340. package/src/cluster/SqlMessageStorage.ts +118 -84
  341. package/src/cluster/SqlRunnerStorage.ts +224 -128
  342. package/src/cluster/internal/entityManager.ts +151 -55
  343. package/src/encoding/Sse.ts +69 -79
  344. package/src/graphql/GraphQL.ts +494 -0
  345. package/src/graphql/GraphQLClient.ts +912 -0
  346. package/src/graphql/GraphQLClientError.ts +542 -0
  347. package/src/graphql/GraphQLGroup.ts +167 -0
  348. package/src/graphql/GraphQLMiddleware.ts +253 -0
  349. package/src/graphql/GraphQLProtocol.ts +1286 -0
  350. package/src/graphql/GraphQLResolver.ts +1010 -0
  351. package/src/graphql/index.ts +48 -0
  352. package/src/http/FindMyWay/internal/router.ts +4 -7
  353. package/src/http/HttpClient.ts +110 -12
  354. package/src/http/HttpEffect.ts +11 -5
  355. package/src/http/HttpMiddleware.ts +33 -34
  356. package/src/http/HttpRouter.ts +35 -0
  357. package/src/http/HttpServerResponse.ts +28 -16
  358. package/src/http/HttpTraceContext.ts +8 -2
  359. package/src/http/Multipart.ts +17 -1
  360. package/src/http-api/HttpApiScalar.ts +5 -0
  361. package/src/internal/dateTime.ts +13 -10
  362. package/src/internal/effect.ts +22 -15
  363. package/src/internal/graphql.ts +263 -0
  364. package/src/internal/graphqlHeaders.ts +11 -0
  365. package/src/internal/request.ts +31 -3
  366. package/src/internal/schema/toCodeDocument.ts +7 -1
  367. package/src/internal/schema/toJsonSchemaDocument.ts +34 -2
  368. package/src/internal/version.ts +1 -1
  369. package/src/net/AddressResolver.ts +222 -0
  370. package/src/net/Dns.ts +1035 -0
  371. package/src/net/Host.ts +544 -0
  372. package/src/net/IpInterface.ts +117 -7
  373. package/src/net/IpNetwork.ts +116 -17
  374. package/src/net/NetAddress.ts +620 -76
  375. package/src/net/index.ts +18 -0
  376. package/src/observability/OtlpMetrics.ts +12 -23
  377. package/src/observability/PrometheusMetrics.ts +1 -0
  378. package/src/persistence/PersistedQueue.ts +146 -53
  379. package/src/rpc/RpcClient.ts +41 -19
  380. package/src/rpc/RpcServer.ts +115 -40
  381. package/src/socket/DatagramSocket.ts +919 -0
  382. package/src/socket/Socket.ts +28 -2
  383. package/src/socket/index.ts +6 -0
  384. package/src/sql/Migrator.ts +21 -5
  385. package/src/sql/SqlClient.ts +39 -15
  386. package/src/testing/TestCrypto.ts +94 -0
  387. package/src/testing/index.ts +6 -0
  388. package/src/workflow/DurableDeferred.ts +160 -47
  389. package/src/workflow/WorkflowEngine.ts +50 -5
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "effect",
3
3
  "type": "module",
4
- "version": "4.0.2",
4
+ "version": "4.0.4",
5
5
  "license": "MIT",
6
6
  "description": "The missing standard library for TypeScript, for writing production-grade software.",
7
7
  "homepage": "https://effect.website",
@@ -46,6 +46,7 @@
46
46
  "./persistence": "./dist/persistence/index.js",
47
47
  "./process": "./dist/process/index.js",
48
48
  "./reactivity": "./dist/reactivity/index.js",
49
+ "./graphql": "./dist/graphql/index.js",
49
50
  "./rpc": "./dist/rpc/index.js",
50
51
  "./schema": "./dist/schema/index.js",
51
52
  "./socket": "./dist/socket/index.js",
@@ -74,13 +75,15 @@
74
75
  "provenance": true
75
76
  },
76
77
  "devDependencies": {
77
- "@types/node": "^26.6.4",
78
+ "@types/node": "^26.6.5",
78
79
  "ajv": "^8.20.0",
79
80
  "ajv-draft-04": "^1.0.0",
80
81
  "ast-types": "^0.16.3",
82
+ "esbuild": "^0.28.2",
81
83
  "immer": "^11.1.21",
84
+ "miniflare": "5.20260925.0-alpha",
82
85
  "protobufjs": "^8.8.0",
83
- "tinybench": "^6.2.0",
86
+ "tinybench": "^6.2.1",
84
87
  "valibot": "^1.5.0"
85
88
  },
86
89
  "scripts": {
package/src/Context.ts CHANGED
@@ -1033,9 +1033,9 @@ export const addUnsafe = <Services, I, S>(
1033
1033
  const impl = self as ContextImpl<Services>
1034
1034
  const cacheRoot = cacheKeys.has(key) ? undefined : impl.cacheRoot
1035
1035
  if (impl.depth >= MaxDepth) {
1036
- // Rebase the overlay chain into a flat map, keeping the cacheRoot so a
1037
- // rebase on an ordinary key does not invalidate fiber caches
1038
- const map = new Map(impl.mapUnsafe)
1036
+ // Avoid mapUnsafe: it would flatten the parent before copying.
1037
+ const map = new Map(impl._flat ?? impl.base)
1038
+ if (!impl._flat) applyOverlays(map, impl.overlay)
1039
1039
  map.set(key, service)
1040
1040
  return makeImpl(cacheRoot, map, undefined, 0)
1041
1041
  }
@@ -1986,6 +1986,15 @@ export const pick = <S extends ReadonlyArray<Key<any, any>>>(
1986
1986
  ...services: S
1987
1987
  ) =>
1988
1988
  <Services>(self: Context<Services>): Context<Services & Service.Identifier<S[number]>> => {
1989
+ if (services.length <= 1) {
1990
+ const map = new Map<string, unknown>()
1991
+ if (services.length === 1) {
1992
+ const key = services[0].key
1993
+ const value = lookup(self, key)
1994
+ if (value !== notFound) map.set(key, value)
1995
+ }
1996
+ return makeUnsafe(map)
1997
+ }
1989
1998
  const keep = new Set(services.map((key) => key.key))
1990
1999
  return withFlat(self, (map) =>
1991
2000
  map.forEach((_, key) => {
package/src/Crypto.ts CHANGED
@@ -66,7 +66,7 @@ export type DigestAlgorithm = "SHA-1" | "SHA-256" | "SHA-384" | "SHA-512"
66
66
  * const program = Effect.gen(function*() {
67
67
  * const crypto = yield* Crypto.Crypto
68
68
  * const bytes = yield* crypto.randomBytes(16)
69
- * const uuidv4 = yield* crypto.randomUUIDv4
69
+ * const uuidv4 = yield* crypto.randomUUIDv4()
70
70
  * const hash = yield* crypto.digest("SHA-256", bytes)
71
71
  * return [bytes.length, uuidv4.length, hash.length]
72
72
  * })
@@ -148,14 +148,42 @@ export interface Crypto {
148
148
  randomShuffle<A>(elements: Iterable<A>): Effect.Effect<Array<A>>
149
149
 
150
150
  /**
151
- * Generates a cryptographically secure UUIDv4 string.
151
+ * Generates a cryptographically secure UUIDv4.
152
+ *
153
+ * **Details**
154
+ *
155
+ * The default `"hex"` format returns a lowercase, hyphenated UUID string
156
+ * (36 characters), not a bare hexadecimal string. The `"bytes"` format
157
+ * returns the 16 UUID bytes, including the version and variant bits.
152
158
  */
153
- readonly randomUUIDv4: Effect.Effect<string, PlatformError.PlatformError>
159
+ randomUUIDv4(options?: {
160
+ readonly format?: "hex" | undefined
161
+ }): Effect.Effect<string, PlatformError.PlatformError>
162
+ randomUUIDv4<Format extends "hex" | "bytes">(options: {
163
+ readonly format: Format
164
+ }): Effect.Effect<Format extends "bytes" ? Uint8Array : string, PlatformError.PlatformError>
165
+ randomUUIDv4(options?: {
166
+ readonly format?: "hex" | "bytes" | undefined
167
+ }): Effect.Effect<string | Uint8Array, PlatformError.PlatformError>
154
168
 
155
169
  /**
156
- * Generates a cryptographically secure UUIDv7 string.
170
+ * Generates a cryptographically secure UUIDv7 using the `Clock` timestamp.
171
+ *
172
+ * **Details**
173
+ *
174
+ * The default `"hex"` format returns a lowercase, hyphenated UUID string
175
+ * (36 characters), not a bare hexadecimal string. The `"bytes"` format
176
+ * returns the 16 UUID bytes, including the timestamp, version and variant bits.
157
177
  */
158
- readonly randomUUIDv7: Effect.Effect<string, PlatformError.PlatformError>
178
+ randomUUIDv7(options?: {
179
+ readonly format?: "hex" | undefined
180
+ }): Effect.Effect<string, PlatformError.PlatformError>
181
+ randomUUIDv7<Format extends "hex" | "bytes">(options: {
182
+ readonly format: Format
183
+ }): Effect.Effect<Format extends "bytes" ? Uint8Array : string, PlatformError.PlatformError>
184
+ randomUUIDv7(options?: {
185
+ readonly format?: "hex" | "bytes" | undefined
186
+ }): Effect.Effect<string | Uint8Array, PlatformError.PlatformError>
159
187
 
160
188
  /**
161
189
  * Generates a cryptographically secure ULID string.
@@ -293,10 +321,16 @@ export const make = (
293
321
  }
294
322
  return buffer
295
323
  }),
296
- randomUUIDv4: Effect.sync(() => Uuid.v4String(randomBytesUnsafe(16))),
297
- randomUUIDv7: Effect.clockWith((clock) =>
298
- Effect.succeed(Uuid.v7String(clock.currentTimeMillisUnsafe(), randomBytesUnsafe(16)))
299
- ),
324
+ randomUUIDv4: ((options?: { readonly format?: "hex" | "bytes" | undefined }) =>
325
+ Effect.sync(() => {
326
+ const bytes = Uuid.v4Bytes(randomBytesUnsafe(16))
327
+ return options?.format === "bytes" ? bytes : Uuid.stringify(bytes)
328
+ })) as Crypto["randomUUIDv4"],
329
+ randomUUIDv7: ((options?: { readonly format?: "hex" | "bytes" | undefined }) =>
330
+ Effect.clockWith((clock) => {
331
+ const bytes = Uuid.v7Bytes(clock.currentTimeMillisUnsafe(), randomBytesUnsafe(16))
332
+ return Effect.succeed(options?.format === "bytes" ? bytes : Uuid.stringify(bytes))
333
+ })) as Crypto["randomUUIDv7"],
300
334
  randomULID: Effect.clockWith((clock) =>
301
335
  Effect.succeed(Ulid.ulidString(clock.currentTimeMillisUnsafe(), randomBytesUnsafe(10)))
302
336
  )
package/src/DateTime.ts CHANGED
@@ -2108,7 +2108,7 @@ export const isPastUnsafe: (self: DateTime) => boolean = Internal.isPastUnsafe
2108
2108
  *
2109
2109
  * **Details**
2110
2110
  *
2111
- * This always returns the UTC representation, ignoring any time zone information.
2111
+ * This preserves the original instant, regardless of any time zone information.
2112
2112
  *
2113
2113
  * **Example** (Converting DateTime values to UTC Dates)
2114
2114
  *
@@ -2133,7 +2133,9 @@ export const toDateUtc: (self: DateTime) => Date = Internal.toDateUtc
2133
2133
  *
2134
2134
  * **Details**
2135
2135
  *
2136
- * For `DateTime.Zoned`, this adjusts for the time zone before converting.
2136
+ * For `DateTime.Zoned`, this stores the zoned wall-clock time in the returned
2137
+ * `Date`'s UTC fields, rather than preserving the original instant. Use
2138
+ * `toDateUtc` to preserve the instant.
2137
2139
  * For `DateTime.Utc`, this is equivalent to `toDateUtc`.
2138
2140
  *
2139
2141
  * **Example** (Converting DateTime values to Dates)
@@ -2141,13 +2143,14 @@ export const toDateUtc: (self: DateTime) => Date = Internal.toDateUtc
2141
2143
  * ```ts import.meta.vitest
2142
2144
  * import { DateTime } from "effect"
2143
2145
  *
2144
- * const utc = DateTime.makeUnsafe("2024-01-01T12:00:00Z")
2145
- * const zoned = DateTime.makeZonedUnsafe("2024-01-01T12:00:00Z", {
2146
+ * const utc = DateTime.makeUnsafe("2024-07-01T12:00:00Z")
2147
+ * const zoned = DateTime.makeZonedUnsafe("2024-07-01T12:00:00Z", {
2146
2148
  * timeZone: "Europe/London"
2147
2149
  * })
2148
2150
  *
2149
- * DateTime.toDate(utc).toISOString() // => "2024-01-01T12:00:00.000Z"
2150
- * DateTime.toDate(zoned).toISOString() // => "2024-01-01T12:00:00.000Z"
2151
+ * DateTime.toDate(utc).toISOString() // => "2024-07-01T12:00:00.000Z"
2152
+ * DateTime.toDate(zoned).toISOString() // => "2024-07-01T13:00:00.000Z"
2153
+ * DateTime.toDateUtc(zoned).toISOString() // => "2024-07-01T12:00:00.000Z"
2151
2154
  * ```
2152
2155
  *
2153
2156
  * @stability stable
package/src/Duration.ts CHANGED
@@ -36,11 +36,12 @@ const bigint1e3 = BigInt(1_000)
36
36
  const bigint1e6 = BigInt(1_000_000)
37
37
  const bigint1e9 = BigInt(1_000_000_000)
38
38
 
39
- const roundTiesAwayFromZero = (input: number): bigint =>
40
- BigInt(input < 0 ? Math.ceil(input - 0.5) : Math.floor(input + 0.5))
39
+ const roundTiesAwayFromZero = (input: number): bigint => BigInt(Math.sign(input) * Math.round(Math.abs(input)))
41
40
 
42
41
  const roundMillisToNanos = (millis: number): bigint => roundTiesAwayFromZero(millis * 1_000_000)
43
42
 
43
+ const fromNanosNumber = (nanos: number): Duration => make(Number.isFinite(nanos) ? roundTiesAwayFromZero(nanos) : nanos)
44
+
44
45
  const parseNanos = (input: string, scale: bigint): bigint => {
45
46
  const decimalIndex = input.indexOf(".")
46
47
  if (decimalIndex === -1) return BigInt(input) * scale
@@ -51,9 +52,13 @@ const parseNanos = (input: string, scale: bigint): bigint => {
51
52
  const scaled = (
52
53
  BigInt(input.slice(isNegative ? 1 : 0, decimalIndex)) * fractionalScale + BigInt(fractional)
53
54
  ) * scale
54
- const rounded = scaled / fractionalScale +
55
- (scaled % fractionalScale * bigint2 >= fractionalScale ? bigint1 : bigint0)
56
- return isNegative ? -rounded : rounded
55
+ return divideTiesAwayFromZero(isNegative ? -scaled : scaled, fractionalScale)
56
+ }
57
+
58
+ const divideTiesAwayFromZero = (numerator: bigint, denominator: bigint): bigint => {
59
+ const absolute = numerator < bigint0 ? -numerator : numerator
60
+ const rounded = absolute / denominator + (absolute % denominator * bigint2 >= denominator ? bigint1 : bigint0)
61
+ return numerator < bigint0 ? -rounded : rounded
57
62
  }
58
63
 
59
64
  const nanosToHrTime = (nanos: bigint): [seconds: number, nanos: number] => {
@@ -307,7 +312,7 @@ export const fromInputUnsafe = (input: Input): Duration => {
307
312
  if (input[0] === Infinity || input[1] === Infinity) {
308
313
  return infinity
309
314
  }
310
- return make(roundTiesAwayFromZero(input[0] * 1_000_000_000 + input[1]))
315
+ return fromNanosNumber(input[0] * 1_000_000_000 + input[1])
311
316
  }
312
317
  const obj = input as DurationObject
313
318
  let millis = 0
@@ -319,9 +324,7 @@ export const fromInputUnsafe = (input: Input): Duration => {
319
324
  if (obj.seconds) millis += obj.seconds * 1_000
320
325
  if (obj.milliseconds) millis += obj.milliseconds
321
326
  if (!obj.microseconds && !obj.nanoseconds) return make(millis)
322
- return make(roundTiesAwayFromZero(
323
- millis * 1_000_000 + (obj.microseconds ?? 0) * 1_000 + (obj.nanoseconds ?? 0)
324
- ))
327
+ return fromNanosNumber(millis * 1_000_000 + (obj.microseconds ?? 0) * 1_000 + (obj.nanoseconds ?? 0))
325
328
  }
326
329
  }
327
330
  return invalid(input)
@@ -1794,8 +1797,8 @@ export const divideUnsafe: {
1794
1797
  *
1795
1798
  * **Details**
1796
1799
  *
1797
- * For nanosecond-backed durations, the multiplier must be convertible to a
1798
- * `bigint`; fractional or non-finite multipliers can throw. Infinite
1800
+ * Fractional multipliers on nanosecond-backed durations round the result to
1801
+ * the nearest nanosecond, with ties rounding away from zero. Infinite
1799
1802
  * durations return positive infinity, negative infinity, or zero depending on
1800
1803
  * the multiplier sign.
1801
1804
  *
@@ -1817,8 +1820,8 @@ export const times: {
1817
1820
  *
1818
1821
  * **Details**
1819
1822
  *
1820
- * For nanosecond-backed durations, the multiplier must be convertible to a
1821
- * `bigint`; fractional or non-finite multipliers can throw. Infinite
1823
+ * Fractional multipliers on nanosecond-backed durations round the result to
1824
+ * the nearest nanosecond, with ties rounding away from zero. Infinite
1822
1825
  * durations return positive infinity, negative infinity, or zero depending on
1823
1826
  * the multiplier sign.
1824
1827
  *
@@ -1840,8 +1843,8 @@ export const times: {
1840
1843
  *
1841
1844
  * **Details**
1842
1845
  *
1843
- * For nanosecond-backed durations, the multiplier must be convertible to a
1844
- * `bigint`; fractional or non-finite multipliers can throw. Infinite
1846
+ * Fractional multipliers on nanosecond-backed durations round the result to
1847
+ * the nearest nanosecond, with ties rounding away from zero. Infinite
1845
1848
  * durations return positive infinity, negative infinity, or zero depending on
1846
1849
  * the multiplier sign.
1847
1850
  *
@@ -1863,7 +1866,24 @@ export const times: {
1863
1866
  (self: Duration, times: number): Duration =>
1864
1867
  match(self, {
1865
1868
  onMillis: (millis) => make(millis * times),
1866
- onNanos: (nanos) => make(nanos * BigInt(times)),
1869
+ onNanos: (nanos) => {
1870
+ if (Number.isInteger(times)) return make(nanos * BigInt(times))
1871
+ const nanosNumber = Number(nanos)
1872
+ const scaled = nanosNumber * times
1873
+ if (
1874
+ !Number.isFinite(times) ||
1875
+ (Number.isSafeInteger(nanosNumber) && Math.abs(scaled) <= Number.MAX_SAFE_INTEGER)
1876
+ ) {
1877
+ return fromNanosNumber(scaled)
1878
+ }
1879
+ let numerator = times
1880
+ let denominator = bigint1
1881
+ while (!Number.isInteger(numerator)) {
1882
+ numerator *= 2
1883
+ denominator *= bigint2
1884
+ }
1885
+ return make(divideTiesAwayFromZero(nanos * BigInt(numerator), denominator))
1886
+ },
1867
1887
  onInfinity: () => times > 0 ? infinity : times < 0 ? negativeInfinity : zero,
1868
1888
  onNegativeInfinity: () => times > 0 ? negativeInfinity : times < 0 ? infinity : zero
1869
1889
  })
package/src/FileSystem.ts CHANGED
@@ -220,12 +220,17 @@ export interface FileSystem {
220
220
  * **Details**
221
221
  *
222
222
  * The file handle will be automatically closed when the scope is closed.
223
+ *
224
+ * `noFollow` rejects symlinks at the final path component, not in parent
225
+ * directories. Node and Bun support it on POSIX; unsupported platforms,
226
+ * including Windows and Deno, fail with `BadArgument`.
223
227
  */
224
228
  readonly open: (
225
229
  path: string,
226
230
  options?: {
227
231
  readonly flag?: OpenFlag | undefined
228
232
  readonly mode?: number | undefined
233
+ readonly noFollow?: boolean | undefined
229
234
  }
230
235
  ) => Effect.Effect<File, PlatformError, Scope>
231
236
  /**
@@ -827,6 +832,10 @@ export const isFile = (u: unknown): u is File => hasProperty(u, FileTypeId)
827
832
  * cursor. Outside append mode, `truncate` clamps a cursor past the new length
828
833
  * to that length.
829
834
  *
835
+ * Positional reads leave the cursor unchanged and may run concurrently on
836
+ * one handle. Cursor operations (`seek`, reads without a position, and writes)
837
+ * must not run concurrently with each other.
838
+ *
830
839
  * **Example** (Working with file handles)
831
840
  *
832
841
  * ```ts import.meta.vitest
@@ -877,8 +886,20 @@ export interface File {
877
886
  */
878
887
  readonly seek: (offset: bigint, from: SeekMode) => Effect.Effect<bigint, PlatformError>
879
888
  readonly sync: Effect.Effect<void, PlatformError>
880
- readonly read: (buffer: Uint8Array) => Effect.Effect<number, PlatformError>
881
- readonly readAlloc: (size: number) => Effect.Effect<Option.Option<Uint8Array>, PlatformError>
889
+ /**
890
+ * Reads into `buffer`, returning the byte count or `0` at EOF. Advances the
891
+ * cursor unless `options.position` is set (see `File.ReadOptions`).
892
+ */
893
+ readonly read: (buffer: Uint8Array, options?: File.ReadOptions) => Effect.Effect<number, PlatformError>
894
+ /**
895
+ * Reads up to `size` bytes into a new buffer, returning `Option.none()` at
896
+ * EOF. Advances the cursor unless `options.position` is set (see
897
+ * `File.ReadOptions`).
898
+ */
899
+ readonly readAlloc: (
900
+ size: number,
901
+ options?: File.ReadOptions
902
+ ) => Effect.Effect<Option.Option<Uint8Array>, PlatformError>
882
903
  readonly truncate: (length?: number) => Effect.Effect<void, PlatformError>
883
904
  readonly write: (buffer: Uint8Array) => Effect.Effect<number, PlatformError>
884
905
  readonly writeAll: (buffer: Uint8Array) => Effect.Effect<void, PlatformError>
@@ -892,6 +913,31 @@ export interface File {
892
913
  * @since 4.0.0
893
914
  */
894
915
  export declare namespace File {
916
+ /**
917
+ * Options for `File.read` and `File.readAlloc`.
918
+ *
919
+ * **Details**
920
+ *
921
+ * `position` is a byte offset from the start of the file. It leaves the
922
+ * cursor unchanged, fails with `BadArgument` if negative, and reads nothing
923
+ * at or past EOF.
924
+ *
925
+ * **Example** (Reading a byte range without moving the cursor)
926
+ *
927
+ * ```ts import.meta.vitest
928
+ * import type { FileSystem } from "effect"
929
+ *
930
+ * const options: FileSystem.File.ReadOptions = { position: BigInt(1024) }
931
+ * options.position // => 1024n
932
+ * ```
933
+ *
934
+ * @category models
935
+ * @since 4.1.0
936
+ */
937
+ export interface ReadOptions {
938
+ readonly position?: bigint | undefined
939
+ }
940
+
895
941
  /**
896
942
  * Enumeration of possible file system entry types.
897
943
  *
@@ -311,16 +311,10 @@ export const makeGrouped = <A extends Request.Any, K>(options: {
311
311
  })
312
312
 
313
313
  const hashGroupKey = <A, K>(get: (entry: Request.Entry<A>) => K) => {
314
- const groupKeys = MutableHashMap.empty<K, K>()
315
- return (entry: Request.Entry<A>): unknown => {
316
- const key = get(entry)
317
- const okey = MutableHashMap.get(groupKeys, key)
318
- if (okey._tag === "Some") {
319
- return okey.value
320
- }
321
- MutableHashMap.set(groupKeys, key, key)
322
- return key
323
- }
314
+ // Pending batches match equal keys, so they share one batch.
315
+ const batchKey = (entry: Request.Entry<A>): unknown => get(entry)
316
+ internal.equalBatchKeys.add(batchKey)
317
+ return batchKey
324
318
  }
325
319
 
326
320
  /**
package/src/Scheduler.ts CHANGED
@@ -160,6 +160,15 @@ class PriorityBuckets {
160
160
  * operation counts to decide when fibers should yield, and is the default
161
161
  * scheduler implementation.
162
162
  *
163
+ * **Gotchas**
164
+ *
165
+ * On Cloudflare Workers, request-owned scheduler timers can be discarded,
166
+ * leaving shared fibers suspended. Use `new MixedScheduler("sync")` for the
167
+ * whole application; see `HttpRouter.toWebHandler` for a recipe.
168
+ * Sync mode does not yield to the event loop: CPU-heavy work delays other
169
+ * requests, and I/O-polling loops can exhaust the CPU limit. It does not fix
170
+ * request-owned timers (such as `Effect.sleep`) or request-bound async contexts.
171
+ *
163
172
  * @stability stable
164
173
  * @category models
165
174
  * @since 2.0.0