effect 4.0.0-beta.100 → 4.0.0-beta.102

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 (502) hide show
  1. package/dist/Array.d.ts.map +1 -1
  2. package/dist/Array.js +81 -5
  3. package/dist/Array.js.map +1 -1
  4. package/dist/Channel.d.ts.map +1 -1
  5. package/dist/Channel.js +27 -9
  6. package/dist/Channel.js.map +1 -1
  7. package/dist/Config.d.ts +1 -1
  8. package/dist/Config.d.ts.map +1 -1
  9. package/dist/Config.js +6 -5
  10. package/dist/Config.js.map +1 -1
  11. package/dist/ConfigProvider.js +7 -7
  12. package/dist/ConfigProvider.js.map +1 -1
  13. package/dist/Data.d.ts.map +1 -1
  14. package/dist/Data.js +2 -1
  15. package/dist/Data.js.map +1 -1
  16. package/dist/Effect.d.ts +61 -100
  17. package/dist/Effect.d.ts.map +1 -1
  18. package/dist/Effect.js +66 -39
  19. package/dist/Effect.js.map +1 -1
  20. package/dist/FiberHandle.d.ts.map +1 -1
  21. package/dist/FiberHandle.js +3 -2
  22. package/dist/FiberHandle.js.map +1 -1
  23. package/dist/Iterable.d.ts.map +1 -1
  24. package/dist/Iterable.js +2 -1
  25. package/dist/Iterable.js.map +1 -1
  26. package/dist/JsonPatch.d.ts.map +1 -1
  27. package/dist/JsonPatch.js +4 -3
  28. package/dist/JsonPatch.js.map +1 -1
  29. package/dist/JsonSchema.d.ts.map +1 -1
  30. package/dist/JsonSchema.js +9 -11
  31. package/dist/JsonSchema.js.map +1 -1
  32. package/dist/Logger.d.ts.map +1 -1
  33. package/dist/Logger.js +3 -2
  34. package/dist/Logger.js.map +1 -1
  35. package/dist/ManagedRuntime.d.ts +9 -0
  36. package/dist/ManagedRuntime.d.ts.map +1 -1
  37. package/dist/ManagedRuntime.js +3 -0
  38. package/dist/ManagedRuntime.js.map +1 -1
  39. package/dist/Metric.d.ts.map +1 -1
  40. package/dist/Metric.js +4 -3
  41. package/dist/Metric.js.map +1 -1
  42. package/dist/MutableList.d.ts.map +1 -1
  43. package/dist/MutableList.js +4 -0
  44. package/dist/MutableList.js.map +1 -1
  45. package/dist/Optic.d.ts.map +1 -1
  46. package/dist/Optic.js +5 -4
  47. package/dist/Optic.js.map +1 -1
  48. package/dist/Option.d.ts.map +1 -1
  49. package/dist/Option.js +2 -1
  50. package/dist/Option.js.map +1 -1
  51. package/dist/PartitionedSemaphore.d.ts.map +1 -1
  52. package/dist/PartitionedSemaphore.js +1 -4
  53. package/dist/PartitionedSemaphore.js.map +1 -1
  54. package/dist/Record.d.ts +93 -1
  55. package/dist/Record.d.ts.map +1 -1
  56. package/dist/Record.js +57 -19
  57. package/dist/Record.js.map +1 -1
  58. package/dist/References.d.ts +0 -45
  59. package/dist/References.d.ts.map +1 -1
  60. package/dist/References.js +0 -45
  61. package/dist/References.js.map +1 -1
  62. package/dist/Request.d.ts.map +1 -1
  63. package/dist/Request.js +9 -6
  64. package/dist/Request.js.map +1 -1
  65. package/dist/Result.d.ts.map +1 -1
  66. package/dist/Result.js +2 -1
  67. package/dist/Result.js.map +1 -1
  68. package/dist/Schema.d.ts +1269 -496
  69. package/dist/Schema.d.ts.map +1 -1
  70. package/dist/Schema.js +2308 -614
  71. package/dist/Schema.js.map +1 -1
  72. package/dist/SchemaAST.d.ts +2 -2
  73. package/dist/SchemaAST.d.ts.map +1 -1
  74. package/dist/SchemaAST.js +189 -130
  75. package/dist/SchemaAST.js.map +1 -1
  76. package/dist/SchemaError.js +1 -1
  77. package/dist/SchemaError.js.map +1 -1
  78. package/dist/SchemaGetter.d.ts +13 -11
  79. package/dist/SchemaGetter.d.ts.map +1 -1
  80. package/dist/SchemaGetter.js +34 -24
  81. package/dist/SchemaGetter.js.map +1 -1
  82. package/dist/SchemaIssue.js +1 -1
  83. package/dist/SchemaIssue.js.map +1 -1
  84. package/dist/SchemaParser.d.ts.map +1 -1
  85. package/dist/SchemaParser.js +1 -12
  86. package/dist/SchemaParser.js.map +1 -1
  87. package/dist/SchemaRepresentation.d.ts +403 -1504
  88. package/dist/SchemaRepresentation.d.ts.map +1 -1
  89. package/dist/SchemaRepresentation.js +294 -2852
  90. package/dist/SchemaRepresentation.js.map +1 -1
  91. package/dist/SchemaTransformation.d.ts +2 -2
  92. package/dist/SchemaTransformation.js +3 -3
  93. package/dist/SchemaTransformation.js.map +1 -1
  94. package/dist/Semaphore.d.ts +5 -3
  95. package/dist/Semaphore.d.ts.map +1 -1
  96. package/dist/Semaphore.js.map +1 -1
  97. package/dist/Stream.d.ts +15 -9
  98. package/dist/Stream.d.ts.map +1 -1
  99. package/dist/Stream.js +46 -16
  100. package/dist/Stream.js.map +1 -1
  101. package/dist/Struct.d.ts.map +1 -1
  102. package/dist/Struct.js +5 -4
  103. package/dist/Struct.js.map +1 -1
  104. package/dist/Types.d.ts +1 -3
  105. package/dist/Types.d.ts.map +1 -1
  106. package/dist/index.d.ts +0 -4
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +0 -4
  109. package/dist/index.js.map +1 -1
  110. package/dist/internal/core.js +3 -2
  111. package/dist/internal/core.js.map +1 -1
  112. package/dist/internal/effect.js +119 -53
  113. package/dist/internal/effect.js.map +1 -1
  114. package/dist/internal/matcher.js +1 -1
  115. package/dist/internal/matcher.js.map +1 -1
  116. package/dist/internal/record.d.ts +0 -3
  117. package/dist/internal/record.d.ts.map +1 -1
  118. package/dist/internal/record.js +10 -5
  119. package/dist/internal/record.js.map +1 -1
  120. package/dist/internal/references.js +0 -4
  121. package/dist/internal/references.js.map +1 -1
  122. package/dist/internal/schema/annotations.js +12 -0
  123. package/dist/internal/schema/annotations.js.map +1 -1
  124. package/dist/internal/schema/fromJsonSchemaDocument.d.ts +2 -0
  125. package/dist/internal/schema/fromJsonSchemaDocument.d.ts.map +1 -0
  126. package/dist/internal/schema/fromJsonSchemaDocument.js +743 -0
  127. package/dist/internal/schema/fromJsonSchemaDocument.js.map +1 -0
  128. package/dist/internal/schema/fromRepresentation.d.ts +2 -0
  129. package/dist/internal/schema/fromRepresentation.d.ts.map +1 -0
  130. package/dist/internal/schema/fromRepresentation.js +252 -0
  131. package/dist/internal/schema/fromRepresentation.js.map +1 -0
  132. package/dist/internal/schema/schema.js +28 -40
  133. package/dist/internal/schema/schema.js.map +1 -1
  134. package/dist/internal/schema/{arbitrary.d.ts → toArbitrary.d.ts} +1 -1
  135. package/dist/internal/schema/toArbitrary.d.ts.map +1 -0
  136. package/dist/internal/schema/{arbitrary.js → toArbitrary.js} +8 -9
  137. package/dist/internal/schema/toArbitrary.js.map +1 -0
  138. package/dist/internal/schema/toCodeDocument.d.ts +2 -0
  139. package/dist/internal/schema/toCodeDocument.d.ts.map +1 -0
  140. package/dist/internal/schema/toCodeDocument.js +438 -0
  141. package/dist/internal/schema/toCodeDocument.js.map +1 -0
  142. package/dist/internal/schema/toEquivalence.d.ts +2 -0
  143. package/dist/internal/schema/toEquivalence.d.ts.map +1 -0
  144. package/dist/internal/schema/{equivalence.js → toEquivalence.js} +15 -13
  145. package/dist/internal/schema/toEquivalence.js.map +1 -0
  146. package/dist/internal/schema/toJsonSchemaDocument.d.ts +2 -0
  147. package/dist/internal/schema/toJsonSchemaDocument.d.ts.map +1 -0
  148. package/dist/internal/schema/toJsonSchemaDocument.js +466 -0
  149. package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -0
  150. package/dist/internal/schema/toRepresentation.d.ts +2 -0
  151. package/dist/internal/schema/toRepresentation.d.ts.map +1 -0
  152. package/dist/internal/schema/toRepresentation.js +369 -0
  153. package/dist/internal/schema/toRepresentation.js.map +1 -0
  154. package/dist/internal/stackTraceLimit.js +3 -6
  155. package/dist/internal/stackTraceLimit.js.map +1 -1
  156. package/dist/testing/TestClock.js +4 -1
  157. package/dist/testing/TestClock.js.map +1 -1
  158. package/dist/unstable/ai/AiError.d.ts +26 -26
  159. package/dist/unstable/ai/AiError.d.ts.map +1 -1
  160. package/dist/unstable/ai/AiError.js +5 -4
  161. package/dist/unstable/ai/AiError.js.map +1 -1
  162. package/dist/unstable/ai/AnthropicStructuredOutput.d.ts +21 -6
  163. package/dist/unstable/ai/AnthropicStructuredOutput.d.ts.map +1 -1
  164. package/dist/unstable/ai/AnthropicStructuredOutput.js +86 -316
  165. package/dist/unstable/ai/AnthropicStructuredOutput.js.map +1 -1
  166. package/dist/unstable/ai/EmbeddingModel.d.ts +1 -1
  167. package/dist/unstable/ai/EmbeddingModel.js +1 -1
  168. package/dist/unstable/ai/EmbeddingModel.js.map +1 -1
  169. package/dist/unstable/ai/LanguageModel.d.ts +4 -1
  170. package/dist/unstable/ai/LanguageModel.d.ts.map +1 -1
  171. package/dist/unstable/ai/LanguageModel.js +19 -17
  172. package/dist/unstable/ai/LanguageModel.js.map +1 -1
  173. package/dist/unstable/ai/McpSchema.d.ts +197 -197
  174. package/dist/unstable/ai/McpSchema.d.ts.map +1 -1
  175. package/dist/unstable/ai/McpSchema.js +13 -13
  176. package/dist/unstable/ai/McpSchema.js.map +1 -1
  177. package/dist/unstable/ai/McpServer.d.ts +4 -4
  178. package/dist/unstable/ai/McpServer.d.ts.map +1 -1
  179. package/dist/unstable/ai/McpServer.js +116 -49
  180. package/dist/unstable/ai/McpServer.js.map +1 -1
  181. package/dist/unstable/ai/OpenAiStructuredOutput.d.ts +32 -10
  182. package/dist/unstable/ai/OpenAiStructuredOutput.d.ts.map +1 -1
  183. package/dist/unstable/ai/OpenAiStructuredOutput.js +193 -377
  184. package/dist/unstable/ai/OpenAiStructuredOutput.js.map +1 -1
  185. package/dist/unstable/ai/Response.d.ts +19 -19
  186. package/dist/unstable/ai/Response.d.ts.map +1 -1
  187. package/dist/unstable/ai/Response.js +14 -14
  188. package/dist/unstable/ai/Response.js.map +1 -1
  189. package/dist/unstable/ai/Tool.d.ts +4 -0
  190. package/dist/unstable/ai/Tool.d.ts.map +1 -1
  191. package/dist/unstable/ai/Tool.js +11 -3
  192. package/dist/unstable/ai/Tool.js.map +1 -1
  193. package/dist/unstable/ai/Toolkit.d.ts +9 -1
  194. package/dist/unstable/ai/Toolkit.d.ts.map +1 -1
  195. package/dist/unstable/ai/Toolkit.js +14 -10
  196. package/dist/unstable/ai/Toolkit.js.map +1 -1
  197. package/dist/unstable/ai/internal/codec-transformer.js +15 -12
  198. package/dist/unstable/ai/internal/codec-transformer.js.map +1 -1
  199. package/dist/unstable/ai/internal/structured-output.d.ts +2 -0
  200. package/dist/unstable/ai/internal/structured-output.d.ts.map +1 -0
  201. package/dist/unstable/ai/internal/structured-output.js +316 -0
  202. package/dist/unstable/ai/internal/structured-output.js.map +1 -0
  203. package/dist/unstable/cli/CliError.d.ts +40 -2
  204. package/dist/unstable/cli/CliError.d.ts.map +1 -1
  205. package/dist/unstable/cli/CliError.js +45 -6
  206. package/dist/unstable/cli/CliError.js.map +1 -1
  207. package/dist/unstable/cli/Command.js +14 -5
  208. package/dist/unstable/cli/Command.js.map +1 -1
  209. package/dist/unstable/cli/Param.js +3 -3
  210. package/dist/unstable/cli/Param.js.map +1 -1
  211. package/dist/unstable/cli/Primitive.js +1 -1
  212. package/dist/unstable/cli/Primitive.js.map +1 -1
  213. package/dist/unstable/cli/internal/command.d.ts +3 -1
  214. package/dist/unstable/cli/internal/command.d.ts.map +1 -1
  215. package/dist/unstable/cli/internal/command.js +11 -4
  216. package/dist/unstable/cli/internal/command.js.map +1 -1
  217. package/dist/unstable/cli/internal/config.d.ts +0 -48
  218. package/dist/unstable/cli/internal/config.d.ts.map +1 -1
  219. package/dist/unstable/cli/internal/config.js +8 -10
  220. package/dist/unstable/cli/internal/config.js.map +1 -1
  221. package/dist/unstable/cluster/ClusterWorkflowEngine.js +1 -1
  222. package/dist/unstable/cluster/ClusterWorkflowEngine.js.map +1 -1
  223. package/dist/unstable/cluster/Entity.js +1 -1
  224. package/dist/unstable/cluster/Entity.js.map +1 -1
  225. package/dist/unstable/cluster/Envelope.d.ts.map +1 -1
  226. package/dist/unstable/cluster/Envelope.js +2 -1
  227. package/dist/unstable/cluster/Envelope.js.map +1 -1
  228. package/dist/unstable/cluster/Reply.js +1 -1
  229. package/dist/unstable/cluster/Reply.js.map +1 -1
  230. package/dist/unstable/cluster/Runner.d.ts +1 -1
  231. package/dist/unstable/cluster/Runner.js +1 -1
  232. package/dist/unstable/cluster/Runner.js.map +1 -1
  233. package/dist/unstable/cluster/RunnerAddress.d.ts +1 -1
  234. package/dist/unstable/cluster/RunnerAddress.js +1 -1
  235. package/dist/unstable/cluster/RunnerAddress.js.map +1 -1
  236. package/dist/unstable/cluster/ShardId.js +1 -1
  237. package/dist/unstable/cluster/ShardId.js.map +1 -1
  238. package/dist/unstable/cluster/Sharding.d.ts.map +1 -1
  239. package/dist/unstable/cluster/Sharding.js +125 -24
  240. package/dist/unstable/cluster/Sharding.js.map +1 -1
  241. package/dist/unstable/cluster/ShardingConfig.d.ts +10 -2
  242. package/dist/unstable/cluster/ShardingConfig.d.ts.map +1 -1
  243. package/dist/unstable/cluster/ShardingConfig.js.map +1 -1
  244. package/dist/unstable/cluster/SingleRunner.d.ts +4 -2
  245. package/dist/unstable/cluster/SingleRunner.d.ts.map +1 -1
  246. package/dist/unstable/cluster/SingleRunner.js +2 -1
  247. package/dist/unstable/cluster/SingleRunner.js.map +1 -1
  248. package/dist/unstable/cluster/SqlMessageStorage.d.ts +7 -4
  249. package/dist/unstable/cluster/SqlMessageStorage.d.ts.map +1 -1
  250. package/dist/unstable/cluster/SqlMessageStorage.js +55 -24
  251. package/dist/unstable/cluster/SqlMessageStorage.js.map +1 -1
  252. package/dist/unstable/cluster/SqlRunnerStorage.d.ts.map +1 -1
  253. package/dist/unstable/cluster/SqlRunnerStorage.js +109 -62
  254. package/dist/unstable/cluster/SqlRunnerStorage.js.map +1 -1
  255. package/dist/unstable/cluster/internal/entityManager.js +19 -7
  256. package/dist/unstable/cluster/internal/entityManager.js.map +1 -1
  257. package/dist/unstable/cluster/internal/shardLock.d.ts +2 -0
  258. package/dist/unstable/cluster/internal/shardLock.d.ts.map +1 -0
  259. package/dist/unstable/cluster/internal/shardLock.js +4 -0
  260. package/dist/unstable/cluster/internal/shardLock.js.map +1 -0
  261. package/dist/unstable/devtools/DevToolsSchema.d.ts +20 -20
  262. package/dist/unstable/devtools/DevToolsSchema.d.ts.map +1 -1
  263. package/dist/unstable/devtools/DevToolsSchema.js +8 -5
  264. package/dist/unstable/devtools/DevToolsSchema.js.map +1 -1
  265. package/dist/unstable/eventlog/EventJournal.d.ts +1 -1
  266. package/dist/unstable/eventlog/EventJournal.js +1 -1
  267. package/dist/unstable/eventlog/EventJournal.js.map +1 -1
  268. package/dist/unstable/eventlog/EventLog.d.ts.map +1 -1
  269. package/dist/unstable/eventlog/EventLog.js +15 -11
  270. package/dist/unstable/eventlog/EventLog.js.map +1 -1
  271. package/dist/unstable/eventlog/EventLogEncryption.d.ts +1 -1
  272. package/dist/unstable/eventlog/EventLogEncryption.js +1 -1
  273. package/dist/unstable/eventlog/EventLogEncryption.js.map +1 -1
  274. package/dist/unstable/eventlog/EventLogMessage.d.ts +26 -26
  275. package/dist/unstable/eventlog/EventLogMessage.d.ts.map +1 -1
  276. package/dist/unstable/eventlog/EventLogMessage.js +8 -3
  277. package/dist/unstable/eventlog/EventLogMessage.js.map +1 -1
  278. package/dist/unstable/eventlog/EventLogRemote.d.ts +1 -1
  279. package/dist/unstable/eventlog/SqlEventJournal.js +2 -2
  280. package/dist/unstable/eventlog/SqlEventJournal.js.map +1 -1
  281. package/dist/unstable/eventlog/SqlEventLogServerEncrypted.js +1 -1
  282. package/dist/unstable/eventlog/SqlEventLogServerEncrypted.js.map +1 -1
  283. package/dist/unstable/eventlog/SqlEventLogServerUnencrypted.js +3 -3
  284. package/dist/unstable/eventlog/SqlEventLogServerUnencrypted.js.map +1 -1
  285. package/dist/unstable/http/Cookies.d.ts.map +1 -1
  286. package/dist/unstable/http/Cookies.js +24 -22
  287. package/dist/unstable/http/Cookies.js.map +1 -1
  288. package/dist/unstable/http/Headers.js +8 -8
  289. package/dist/unstable/http/Headers.js.map +1 -1
  290. package/dist/unstable/http/HttpClientRequest.d.ts +44 -0
  291. package/dist/unstable/http/HttpClientRequest.d.ts.map +1 -1
  292. package/dist/unstable/http/HttpClientRequest.js +14 -0
  293. package/dist/unstable/http/HttpClientRequest.js.map +1 -1
  294. package/dist/unstable/http/HttpRouter.d.ts +2 -2
  295. package/dist/unstable/http/HttpRouter.d.ts.map +1 -1
  296. package/dist/unstable/http/HttpRouter.js.map +1 -1
  297. package/dist/unstable/http/HttpServerRequest.d.ts.map +1 -1
  298. package/dist/unstable/http/HttpServerRequest.js +5 -4
  299. package/dist/unstable/http/HttpServerRequest.js.map +1 -1
  300. package/dist/unstable/http/Multipart.d.ts.map +1 -1
  301. package/dist/unstable/http/Multipart.js +17 -15
  302. package/dist/unstable/http/Multipart.js.map +1 -1
  303. package/dist/unstable/http/Template.js +1 -1
  304. package/dist/unstable/http/Template.js.map +1 -1
  305. package/dist/unstable/http/UrlParams.d.ts.map +1 -1
  306. package/dist/unstable/http/UrlParams.js +17 -14
  307. package/dist/unstable/http/UrlParams.js.map +1 -1
  308. package/dist/unstable/httpapi/HttpApi.js +3 -3
  309. package/dist/unstable/httpapi/HttpApi.js.map +1 -1
  310. package/dist/unstable/httpapi/HttpApiClient.js +5 -5
  311. package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
  312. package/dist/unstable/httpapi/HttpApiGroup.js +1 -1
  313. package/dist/unstable/httpapi/HttpApiGroup.js.map +1 -1
  314. package/dist/unstable/httpapi/OpenApi.d.ts.map +1 -1
  315. package/dist/unstable/httpapi/OpenApi.js +37 -24
  316. package/dist/unstable/httpapi/OpenApi.js.map +1 -1
  317. package/dist/unstable/observability/OtlpExporter.d.ts +72 -1
  318. package/dist/unstable/observability/OtlpExporter.d.ts.map +1 -1
  319. package/dist/unstable/observability/OtlpExporter.js +69 -4
  320. package/dist/unstable/observability/OtlpExporter.js.map +1 -1
  321. package/dist/unstable/observability/OtlpLogger.d.ts +4 -3
  322. package/dist/unstable/observability/OtlpLogger.d.ts.map +1 -1
  323. package/dist/unstable/observability/OtlpLogger.js +2 -2
  324. package/dist/unstable/observability/OtlpLogger.js.map +1 -1
  325. package/dist/unstable/observability/OtlpMetrics.d.ts +7 -3
  326. package/dist/unstable/observability/OtlpMetrics.d.ts.map +1 -1
  327. package/dist/unstable/observability/OtlpMetrics.js +5 -2
  328. package/dist/unstable/observability/OtlpMetrics.js.map +1 -1
  329. package/dist/unstable/observability/OtlpTracer.d.ts +4 -3
  330. package/dist/unstable/observability/OtlpTracer.d.ts.map +1 -1
  331. package/dist/unstable/observability/OtlpTracer.js +2 -2
  332. package/dist/unstable/observability/OtlpTracer.js.map +1 -1
  333. package/dist/unstable/persistence/Persistable.d.ts.map +1 -1
  334. package/dist/unstable/persistence/Persistable.js +2 -1
  335. package/dist/unstable/persistence/Persistable.js.map +1 -1
  336. package/dist/unstable/persistence/RateLimiter.d.ts +2 -2
  337. package/dist/unstable/persistence/RateLimiter.js +2 -2
  338. package/dist/unstable/persistence/RateLimiter.js.map +1 -1
  339. package/dist/unstable/persistence/Redis.d.ts.map +1 -1
  340. package/dist/unstable/persistence/Redis.js +2 -2
  341. package/dist/unstable/persistence/Redis.js.map +1 -1
  342. package/dist/unstable/process/ChildProcessSpawner.js +3 -1
  343. package/dist/unstable/process/ChildProcessSpawner.js.map +1 -1
  344. package/dist/unstable/reactivity/AsyncResult.d.ts.map +1 -1
  345. package/dist/unstable/reactivity/AsyncResult.js +4 -3
  346. package/dist/unstable/reactivity/AsyncResult.js.map +1 -1
  347. package/dist/unstable/reactivity/Atom.d.ts +83 -0
  348. package/dist/unstable/reactivity/Atom.d.ts.map +1 -1
  349. package/dist/unstable/reactivity/Atom.js +31 -0
  350. package/dist/unstable/reactivity/Atom.js.map +1 -1
  351. package/dist/unstable/reactivity/AtomRegistry.js +1 -1
  352. package/dist/unstable/reactivity/AtomRegistry.js.map +1 -1
  353. package/dist/unstable/rpc/RpcClient.d.ts.map +1 -1
  354. package/dist/unstable/rpc/RpcClient.js +2 -1
  355. package/dist/unstable/rpc/RpcClient.js.map +1 -1
  356. package/dist/unstable/schema/VariantSchema.d.ts +1 -2
  357. package/dist/unstable/schema/VariantSchema.d.ts.map +1 -1
  358. package/dist/unstable/schema/VariantSchema.js +13 -10
  359. package/dist/unstable/schema/VariantSchema.js.map +1 -1
  360. package/dist/unstable/socket/Socket.d.ts +1 -1
  361. package/dist/unstable/socket/Socket.js +1 -1
  362. package/dist/unstable/socket/Socket.js.map +1 -1
  363. package/dist/unstable/sql/SqlError.d.ts +2 -2
  364. package/dist/unstable/sql/SqlError.js +2 -2
  365. package/dist/unstable/sql/SqlError.js.map +1 -1
  366. package/dist/unstable/sql/Statement.d.ts.map +1 -1
  367. package/dist/unstable/sql/Statement.js +7 -6
  368. package/dist/unstable/sql/Statement.js.map +1 -1
  369. package/package.json +1 -1
  370. package/src/Array.ts +86 -25
  371. package/src/Channel.ts +32 -14
  372. package/src/Config.ts +6 -5
  373. package/src/ConfigProvider.ts +7 -7
  374. package/src/Data.ts +3 -2
  375. package/src/Effect.ts +70 -116
  376. package/src/FiberHandle.ts +3 -2
  377. package/src/Iterable.ts +2 -1
  378. package/src/JsonPatch.ts +4 -3
  379. package/src/JsonSchema.ts +9 -11
  380. package/src/Logger.ts +3 -2
  381. package/src/ManagedRuntime.ts +13 -0
  382. package/src/Metric.ts +4 -3
  383. package/src/MutableList.ts +4 -0
  384. package/src/Optic.ts +5 -4
  385. package/src/Option.ts +2 -1
  386. package/src/PartitionedSemaphore.ts +1 -4
  387. package/src/Record.ts +119 -22
  388. package/src/References.ts +0 -46
  389. package/src/Request.ts +5 -7
  390. package/src/Result.ts +2 -1
  391. package/src/Schema.ts +2538 -987
  392. package/src/SchemaAST.ts +228 -149
  393. package/src/SchemaError.ts +1 -1
  394. package/src/SchemaGetter.ts +36 -29
  395. package/src/SchemaIssue.ts +1 -1
  396. package/src/SchemaParser.ts +1 -25
  397. package/src/SchemaRepresentation.ts +697 -3398
  398. package/src/SchemaTransformation.ts +3 -3
  399. package/src/Semaphore.ts +5 -3
  400. package/src/Stream.ts +63 -19
  401. package/src/Struct.ts +5 -4
  402. package/src/Types.ts +1 -3
  403. package/src/index.ts +0 -5
  404. package/src/internal/core.ts +4 -3
  405. package/src/internal/effect.ts +132 -70
  406. package/src/internal/matcher.ts +1 -1
  407. package/src/internal/record.ts +11 -7
  408. package/src/internal/references.ts +0 -5
  409. package/src/internal/schema/annotations.ts +44 -0
  410. package/src/internal/schema/fromJsonSchemaDocument.ts +957 -0
  411. package/src/internal/schema/fromRepresentation.ts +345 -0
  412. package/src/internal/schema/schema.ts +45 -46
  413. package/src/internal/schema/{arbitrary.ts → toArbitrary.ts} +8 -10
  414. package/src/internal/schema/toCodeDocument.ts +572 -0
  415. package/src/internal/schema/{equivalence.ts → toEquivalence.ts} +12 -7
  416. package/src/internal/schema/toJsonSchemaDocument.ts +475 -0
  417. package/src/internal/schema/toRepresentation.ts +401 -0
  418. package/src/internal/stackTraceLimit.ts +3 -7
  419. package/src/testing/TestClock.ts +1 -1
  420. package/src/unstable/ai/AiError.ts +5 -4
  421. package/src/unstable/ai/AnthropicStructuredOutput.ts +102 -333
  422. package/src/unstable/ai/EmbeddingModel.ts +1 -1
  423. package/src/unstable/ai/LanguageModel.ts +30 -28
  424. package/src/unstable/ai/McpSchema.ts +15 -15
  425. package/src/unstable/ai/McpServer.ts +172 -56
  426. package/src/unstable/ai/OpenAiStructuredOutput.ts +230 -395
  427. package/src/unstable/ai/Response.ts +24 -24
  428. package/src/unstable/ai/Tool.ts +22 -4
  429. package/src/unstable/ai/Toolkit.ts +19 -7
  430. package/src/unstable/ai/internal/codec-transformer.ts +13 -7
  431. package/src/unstable/ai/internal/structured-output.ts +458 -0
  432. package/src/unstable/cli/CliError.ts +51 -5
  433. package/src/unstable/cli/Command.ts +4 -4
  434. package/src/unstable/cli/Param.ts +3 -3
  435. package/src/unstable/cli/Primitive.ts +1 -1
  436. package/src/unstable/cli/internal/command.ts +13 -5
  437. package/src/unstable/cli/internal/config.ts +8 -10
  438. package/src/unstable/cluster/ClusterWorkflowEngine.ts +3 -3
  439. package/src/unstable/cluster/Entity.ts +1 -1
  440. package/src/unstable/cluster/Envelope.ts +2 -1
  441. package/src/unstable/cluster/Reply.ts +1 -1
  442. package/src/unstable/cluster/Runner.ts +1 -1
  443. package/src/unstable/cluster/RunnerAddress.ts +1 -1
  444. package/src/unstable/cluster/ShardId.ts +1 -1
  445. package/src/unstable/cluster/Sharding.ts +161 -34
  446. package/src/unstable/cluster/ShardingConfig.ts +5 -1
  447. package/src/unstable/cluster/SingleRunner.ts +4 -2
  448. package/src/unstable/cluster/SqlMessageStorage.ts +83 -35
  449. package/src/unstable/cluster/SqlRunnerStorage.ts +186 -116
  450. package/src/unstable/cluster/internal/entityManager.ts +31 -10
  451. package/src/unstable/cluster/internal/shardLock.ts +9 -0
  452. package/src/unstable/devtools/DevToolsSchema.ts +10 -5
  453. package/src/unstable/eventlog/EventJournal.ts +1 -1
  454. package/src/unstable/eventlog/EventLog.ts +21 -11
  455. package/src/unstable/eventlog/EventLogEncryption.ts +1 -1
  456. package/src/unstable/eventlog/EventLogMessage.ts +10 -3
  457. package/src/unstable/eventlog/SqlEventJournal.ts +2 -2
  458. package/src/unstable/eventlog/SqlEventLogServerEncrypted.ts +1 -1
  459. package/src/unstable/eventlog/SqlEventLogServerUnencrypted.ts +6 -3
  460. package/src/unstable/http/Cookies.ts +29 -24
  461. package/src/unstable/http/Headers.ts +8 -8
  462. package/src/unstable/http/HttpClientRequest.ts +57 -0
  463. package/src/unstable/http/HttpRouter.ts +6 -3
  464. package/src/unstable/http/HttpServerRequest.ts +5 -4
  465. package/src/unstable/http/Multipart.ts +16 -13
  466. package/src/unstable/http/Template.ts +1 -1
  467. package/src/unstable/http/UrlParams.ts +17 -14
  468. package/src/unstable/httpapi/HttpApi.ts +3 -3
  469. package/src/unstable/httpapi/HttpApiClient.ts +5 -5
  470. package/src/unstable/httpapi/HttpApiGroup.ts +1 -1
  471. package/src/unstable/httpapi/OpenApi.ts +52 -28
  472. package/src/unstable/observability/OtlpExporter.ts +109 -5
  473. package/src/unstable/observability/OtlpLogger.ts +5 -5
  474. package/src/unstable/observability/OtlpMetrics.ts +8 -4
  475. package/src/unstable/observability/OtlpTracer.ts +8 -4
  476. package/src/unstable/persistence/Persistable.ts +3 -2
  477. package/src/unstable/persistence/RateLimiter.ts +2 -2
  478. package/src/unstable/persistence/Redis.ts +2 -2
  479. package/src/unstable/process/ChildProcessSpawner.ts +1 -1
  480. package/src/unstable/reactivity/AsyncResult.ts +4 -3
  481. package/src/unstable/reactivity/Atom.ts +92 -0
  482. package/src/unstable/reactivity/AtomRegistry.ts +1 -1
  483. package/src/unstable/rpc/RpcClient.ts +2 -1
  484. package/src/unstable/schema/VariantSchema.ts +14 -24
  485. package/src/unstable/socket/Socket.ts +1 -1
  486. package/src/unstable/sql/SqlError.ts +2 -2
  487. package/src/unstable/sql/Statement.ts +7 -6
  488. package/dist/SchemaUtils.d.ts +0 -28
  489. package/dist/SchemaUtils.d.ts.map +0 -1
  490. package/dist/SchemaUtils.js +0 -45
  491. package/dist/SchemaUtils.js.map +0 -1
  492. package/dist/internal/schema/arbitrary.d.ts.map +0 -1
  493. package/dist/internal/schema/arbitrary.js.map +0 -1
  494. package/dist/internal/schema/equivalence.d.ts +0 -2
  495. package/dist/internal/schema/equivalence.d.ts.map +0 -1
  496. package/dist/internal/schema/equivalence.js.map +0 -1
  497. package/dist/internal/schema/representation.d.ts +0 -2
  498. package/dist/internal/schema/representation.d.ts.map +0 -1
  499. package/dist/internal/schema/representation.js +0 -865
  500. package/dist/internal/schema/representation.js.map +0 -1
  501. package/src/SchemaUtils.ts +0 -51
  502. package/src/internal/schema/representation.ts +0 -795
@@ -46,6 +46,7 @@
46
46
  * 1. Flat iteration over all params for parsing/validation
47
47
  * 2. Reconstruction of original nested shape for handler input
48
48
  */
49
+ import * as InternalRecord from "../../../internal/record.ts"
49
50
  import * as Param from "../Param.ts"
50
51
 
51
52
  /* ========================================================================== */
@@ -135,8 +136,8 @@ export const parseConfig = (config: Config): ConfigInternal => {
135
136
  const args: Array<Param.AnyArgument> = []
136
137
 
137
138
  function parse(config: Config): ConfigInternal.Tree {
138
- const tree: ConfigInternal.Tree = {}
139
- for (const key in config) {
139
+ const tree: ConfigInternal.Tree = Object.create(null)
140
+ for (const key of Object.keys(config)) {
140
141
  tree[key] = parseValue(config[key])
141
142
  }
142
143
  return tree
@@ -202,8 +203,8 @@ const shiftNodeIndexes = (node: ConfigInternal.Node, offset: number): ConfigInte
202
203
  }
203
204
 
204
205
  const shiftTreeIndexes = (tree: ConfigInternal.Tree, offset: number): ConfigInternal.Tree => {
205
- const output: ConfigInternal.Tree = {}
206
- for (const key in tree) {
206
+ const output: ConfigInternal.Tree = Object.create(null)
207
+ for (const key of Object.keys(tree)) {
207
208
  output[key] = shiftNodeIndexes(tree[key], offset)
208
209
  }
209
210
  return output
@@ -220,10 +221,7 @@ export const mergeConfig = (
220
221
  flags: [...left.flags, ...right.flags],
221
222
  arguments: [...left.arguments, ...right.arguments],
222
223
  orderedParams: [...left.orderedParams, ...right.orderedParams],
223
- tree: {
224
- ...left.tree,
225
- ...shiftTreeIndexes(right.tree, offset)
226
- }
224
+ tree: Object.assign(Object.create(null), left.tree, shiftTreeIndexes(right.tree, offset))
227
225
  }
228
226
  }
229
227
 
@@ -245,8 +243,8 @@ export const reconstructTree = (
245
243
  ): Record<string, any> => {
246
244
  const output: Record<string, any> = {}
247
245
 
248
- for (const key in tree) {
249
- output[key] = nodeValue(tree[key])
246
+ for (const key of Object.keys(tree)) {
247
+ InternalRecord.assignProperty(output, key, nodeValue(tree[key]))
250
248
  }
251
249
 
252
250
  return output
@@ -83,7 +83,7 @@ export const make = Effect.gen(function*() {
83
83
  | Rpc.Rpc<
84
84
  "activity",
85
85
  Schema.Struct<
86
- { name: typeof Schema.String; attempt: typeof Schema.Number; withTransaction: typeof Schema.Boolean }
86
+ { name: typeof Schema.String; attempt: typeof Schema.Int; withTransaction: typeof Schema.Boolean }
87
87
  >,
88
88
  Schema.declare<Workflow.Result<any, any>>
89
89
  >
@@ -97,7 +97,7 @@ export const make = Effect.gen(function*() {
97
97
  | Rpc.Rpc<"deferred", Schema.Struct<{ name: typeof Schema.String; exit: typeof ExitUnknown }>, typeof ExitUnknown>
98
98
  | Rpc.Rpc<
99
99
  "activity",
100
- Schema.Struct<{ name: typeof Schema.String; attempt: typeof Schema.Number }>,
100
+ Schema.Struct<{ name: typeof Schema.String; attempt: typeof Schema.Int }>,
101
101
  Schema.declare<Workflow.Result<any, any>>
102
102
  >
103
103
  | Rpc.Rpc<"resume">
@@ -644,7 +644,7 @@ const ExitUnknown = Schema.Exit(AnyOrVoid, AnyOrVoid, Schema.Any)
644
644
  const ActivityRpc = Rpc.make("activity", {
645
645
  payload: {
646
646
  name: Schema.String,
647
- attempt: Schema.Number,
647
+ attempt: Schema.Int,
648
648
  withTransaction: Schema.Boolean.pipe(
649
649
  Schema.withDecodingDefault(Effect.succeed(false))
650
650
  )
@@ -349,7 +349,7 @@ const Proto = {
349
349
  ),
350
350
  Stream.unwrap
351
351
  )
352
- const handlers: Record<string, any> = {}
352
+ const handlers: Record<string, any> = Object.create(null)
353
353
  for (const rpc_ of this.protocol.requests.values()) {
354
354
  const rpc = rpc_ as any as Rpc.AnyWithProps
355
355
  handlers[rpc._tag] = RpcSchema.isStreamSchema(rpc.successSchema) ? streamHandler : handler
@@ -429,5 +429,6 @@ export const primaryKeyByAddress = (options: {
429
429
  readonly tag: string
430
430
  readonly id: string
431
431
  }): string =>
432
- // hash the entity address to save space?
432
+ // storage drivers with fixed-width key columns (e.g. SqlMessageStorage)
433
+ // hash this composed key at their own boundary
433
434
  `${options.address.entityType}/${options.address.entityId}/${options.tag}/${options.id}`
@@ -258,7 +258,7 @@ export class Chunk<R extends Rpc.Any> extends Data.TaggedClass("Chunk")<{
258
258
  _tag: Schema.Literal("Chunk"),
259
259
  requestId: SnowflakeFromBigInt,
260
260
  id: SnowflakeFromBigInt,
261
- sequence: Schema.Number,
261
+ sequence: Schema.Int,
262
262
  values: Schema.NonEmptyArray(success)
263
263
  }),
264
264
  SchemaTransformation.transform({
@@ -29,7 +29,7 @@ const TypeId = "~effect/cluster/Runner"
29
29
  export class Runner extends Schema.Class<Runner>(TypeId)({
30
30
  address: RunnerAddress,
31
31
  groups: Schema.Array(Schema.String),
32
- weight: Schema.Number
32
+ weight: Schema.Finite
33
33
  }) {
34
34
  /**
35
35
  * Formatter for rendering runner values consistently.
@@ -28,7 +28,7 @@ const TypeId = "~effect/cluster/RunnerAddress"
28
28
  */
29
29
  export class RunnerAddress extends Schema.Class<RunnerAddress>(TypeId)({
30
30
  host: Schema.String,
31
- port: Schema.Number
31
+ port: Schema.Int
32
32
  }) {
33
33
  /**
34
34
  * Marks this value as a cluster runner address for runtime guards.
@@ -49,7 +49,7 @@ export const ShardId = S.declare(isShardId, {
49
49
  S.link<ShardId>()(
50
50
  S.Struct({
51
51
  group: S.String,
52
- id: S.Number
52
+ id: S.Int
53
53
  }),
54
54
  {
55
55
  decode: SchemaGetter.transform(({ group, id }) => make(group, id)),
@@ -23,6 +23,7 @@ import * as Fiber from "../../Fiber.ts"
23
23
  import * as FiberMap from "../../FiberMap.ts"
24
24
  import { constant, flow } from "../../Function.ts"
25
25
  import * as HashRing from "../../HashRing.ts"
26
+ import * as InternalRecord from "../../internal/record.ts"
26
27
  import * as Latch from "../../Latch.ts"
27
28
  import * as Layer from "../../Layer.ts"
28
29
  import * as MutableHashMap from "../../MutableHashMap.ts"
@@ -55,6 +56,7 @@ import { EntityReaper } from "./internal/entityReaper.ts"
55
56
  import { hashString } from "./internal/hash.ts"
56
57
  import { internalInterruptors } from "./internal/interruptors.ts"
57
58
  import { ResourceMap } from "./internal/resourceMap.ts"
59
+ import { effectiveInterval } from "./internal/shardLock.ts"
58
60
  import * as Message from "./Message.ts"
59
61
  import * as MessageStorage from "./MessageStorage.ts"
60
62
  import * as Reply from "./Reply.ts"
@@ -217,6 +219,7 @@ interface EntityManagerState {
217
219
 
218
220
  const make = Effect.gen(function*() {
219
221
  const config = yield* ShardingConfig
222
+ const shardLockInterval = effectiveInterval(config)
220
223
  const shardGroups = shardGroupConfig(config)
221
224
  const getRunnerAddress = () => Option.getOrUndefined(config.runnerAddress)
222
225
  const clock = yield* Clock
@@ -240,6 +243,8 @@ const make = Effect.gen(function*() {
240
243
 
241
244
  const shardAssignments = MutableHashMap.empty<ShardId, RunnerAddress>()
242
245
  const selfShards = MutableHashSet.empty<ShardId>()
246
+ // open while shard lock storage is healthy
247
+ const shardLocksHealthyLatch = Latch.makeUnsafe(true)
243
248
 
244
249
  // the active shards are the ones that we have acquired the lock for
245
250
  const acquiredShards = MutableHashSet.empty<ShardId>()
@@ -277,6 +282,9 @@ const make = Effect.gen(function*() {
277
282
  // allow them to move to another runner.
278
283
 
279
284
  const releasingShards = MutableHashSet.empty<ShardId>()
285
+ // Shards whose entities must be force interrupted and locks fully released
286
+ // before normal reacquisition.
287
+ const forceReleasingShards = MutableHashSet.empty<ShardId>()
280
288
  const initialRunnerAddress = getRunnerAddress()
281
289
  if (initialRunnerAddress) {
282
290
  const selfAddress = initialRunnerAddress
@@ -286,37 +294,88 @@ const make = Effect.gen(function*() {
286
294
  })
287
295
 
288
296
  const releaseShardsMap = yield* FiberMap.make<ShardId>()
289
- const releaseShard = Effect.fnUntraced(
290
- function*(shardId: ShardId) {
291
- const fibers = Arr.empty<Fiber.Fiber<void>>()
297
+ let forcedShardReleaseRunning = false
298
+ // Interrupt the shards' entities, wait for lock health, run the storage
299
+ // release, then clear the shards' bookkeeping.
300
+ const runShardRelease = Effect.fnUntraced(function*<E>(
301
+ shardIds: ReadonlyArray<ShardId>,
302
+ force: boolean,
303
+ release: Effect.Effect<void, E>
304
+ ) {
305
+ const fibers = Arr.empty<Fiber.Fiber<void>>()
306
+ for (const shardId of shardIds) {
292
307
  for (const state of entityManagers.values()) {
293
308
  if (state.status === "closed") continue
294
- fibers.push(yield* Effect.forkScoped(state.manager.interruptShard(shardId)))
309
+ fibers.push(yield* Effect.forkScoped(state.manager.interruptShard(shardId, { force })))
295
310
  }
296
- yield* Fiber.joinAll(fibers)
297
- yield* runnerStorage.release(selfAddress, shardId)
311
+ }
312
+ yield* Fiber.joinAll(fibers)
313
+ yield* shardLocksHealthyLatch.await
314
+ yield* release
315
+ for (const shardId of shardIds) {
298
316
  MutableHashSet.remove(releasingShards, shardId)
317
+ MutableHashSet.remove(forceReleasingShards, shardId)
299
318
  yield* storage.unregisterShardReplyHandlers(shardId)
300
- },
301
- Effect.sandbox,
302
- (effect, shardId) =>
319
+ }
320
+ })
321
+ const retryShardRelease =
322
+ (annotations: { readonly fiber: string; readonly shardId?: ShardId }) =>
323
+ <A, E, R>(effect: Effect.Effect<A, E, R>) =>
303
324
  effect.pipe(
325
+ Effect.sandbox,
304
326
  Effect.tapError((cause) =>
305
- Effect.logDebug(`Could not release shard, retrying`, cause).pipe(
327
+ Effect.logDebug(`Could not release shards, retrying`, cause).pipe(
306
328
  Effect.annotateLogs({
307
329
  module: "effect/cluster/Sharding",
308
- fiber: "releaseShard",
309
330
  runner: selfAddress,
310
- shardId
311
- })
331
+ ...annotations
332
+ }),
333
+ // Effect.eventually retries immediately, so space failures to
334
+ // avoid hot-looping while storage is unavailable.
335
+ Effect.andThen(Effect.sleep(50))
312
336
  )
313
337
  ),
314
- Effect.eventually,
338
+ Effect.eventually
339
+ )
340
+ const releaseShard = Effect.fnUntraced(
341
+ function*(shardId: ShardId) {
342
+ yield* runShardRelease(
343
+ [shardId],
344
+ MutableHashSet.has(forceReleasingShards, shardId),
345
+ runnerStorage.release(selfAddress, shardId)
346
+ )
347
+ },
348
+ (effect, shardId) =>
349
+ effect.pipe(
350
+ retryShardRelease({ fiber: "releaseShard", shardId }),
315
351
  FiberMap.run(releaseShardsMap, shardId, { onlyIfMissing: true })
316
352
  )
317
353
  )
354
+ // The forced release ends with `runnerStorage.releaseAll`, which drops
355
+ // every lock held by this runner. Shards must not be reacquired through the
356
+ // normal path while it is pending, otherwise the bulk release wipes a lock
357
+ // the runner already considers acquired.
358
+ const forcedShardReleasePending = () => forcedShardReleaseRunning || MutableHashSet.size(forceReleasingShards) > 0
359
+ const releaseForcedShards = Effect.suspend(() => {
360
+ if (forcedShardReleaseRunning || MutableHashSet.size(forceReleasingShards) === 0) {
361
+ return Effect.void
362
+ }
363
+ forcedShardReleaseRunning = true
364
+ const shardIds = [...forceReleasingShards]
365
+ return runShardRelease(shardIds, true, runnerStorage.releaseAll(selfAddress)).pipe(
366
+ retryShardRelease({ fiber: "releaseForcedShards" }),
367
+ Effect.ensuring(Effect.sync(() => {
368
+ forcedShardReleaseRunning = false
369
+ activeShardsLatch.openUnsafe()
370
+ })),
371
+ Effect.forkIn(shardingScope),
372
+ Effect.asVoid
373
+ )
374
+ })
318
375
  const releaseShards = Effect.gen(function*() {
376
+ yield* releaseForcedShards
319
377
  for (const shardId of releasingShards) {
378
+ if (MutableHashSet.has(forceReleasingShards, shardId)) continue
320
379
  if (FiberMap.hasUnsafe(releaseShardsMap, shardId)) continue
321
380
  yield* releaseShard(shardId)
322
381
  }
@@ -336,11 +395,21 @@ const make = Effect.gen(function*() {
336
395
  MutableHashSet.add(releasingShards, shardId)
337
396
  }
338
397
 
339
- if (MutableHashSet.size(releasingShards) > 0) {
398
+ if (MutableHashSet.size(releasingShards) > 0 || MutableHashSet.size(forceReleasingShards) > 0) {
340
399
  yield* Effect.forkIn(syncSingletons, shardingScope)
341
400
  yield* releaseShards
342
401
  }
343
402
 
403
+ if (!shardLocksHealthyLatch.isOpen()) {
404
+ continue
405
+ }
406
+
407
+ // Wait for the pending bulk release before reacquiring, so it cannot
408
+ // drop a lock acquired here. `releaseForcedShards` reopens the latch.
409
+ if (forcedShardReleasePending()) {
410
+ continue
411
+ }
412
+
344
413
  // if a shard has been assigned to this runner, we acquire it
345
414
  const unacquiredShards = MutableHashSet.empty<ShardId>()
346
415
  for (const shardId of selfShards) {
@@ -353,7 +422,7 @@ const make = Effect.gen(function*() {
353
422
  }
354
423
 
355
424
  const oacquired = yield* runnerStorage.acquire(selfAddress, unacquiredShards).pipe(
356
- Effect.timeoutOption(config.shardLockRefreshInterval)
425
+ Effect.timeoutOption(shardLockInterval)
357
426
  )
358
427
  if (Option.isNone(oacquired)) {
359
428
  activeShardsLatch.openUnsafe()
@@ -363,10 +432,19 @@ const make = Effect.gen(function*() {
363
432
  const acquired = oacquired.value
364
433
  yield* storage.resetShards(acquired).pipe(
365
434
  Effect.ignore,
366
- Effect.timeoutOption(config.shardLockRefreshInterval)
435
+ Effect.timeoutOption(shardLockInterval)
367
436
  )
437
+ // A forced release can start while `acquire` is in flight, so re-check
438
+ // it here as well as before acquiring.
439
+ const forcedReleasePending = forcedShardReleasePending()
368
440
  for (const shardId of acquired) {
369
- if (MutableHashSet.has(releasingShards, shardId) || !MutableHashSet.has(selfShards, shardId)) {
441
+ if (
442
+ !shardLocksHealthyLatch.isOpen() ||
443
+ forcedReleasePending ||
444
+ MutableHashSet.has(releasingShards, shardId) ||
445
+ !MutableHashSet.has(selfShards, shardId)
446
+ ) {
447
+ MutableHashSet.add(releasingShards, shardId)
370
448
  continue
371
449
  }
372
450
  MutableHashSet.add(acquiredShards, shardId)
@@ -392,8 +470,52 @@ const make = Effect.gen(function*() {
392
470
  Effect.forkIn(shardingScope)
393
471
  )
394
472
 
395
- // refresh the shard locks every `shardLockRefreshInterval`
396
- yield* Effect.suspend(() =>
473
+ const markShardLocksUnhealthy = (cause: Cause.Cause<unknown>) =>
474
+ Effect.suspend(() => {
475
+ if (!shardLocksHealthyLatch.closeUnsafe()) return Effect.void
476
+
477
+ const affectedShards = MutableHashSet.fromIterable([...acquiredShards, ...releasingShards])
478
+ MutableHashSet.clear(selfShards)
479
+ MutableHashSet.clear(acquiredShards)
480
+ for (const shardId of affectedShards) {
481
+ MutableHashSet.add(releasingShards, shardId)
482
+ MutableHashSet.add(forceReleasingShards, shardId)
483
+ }
484
+ ClusterMetrics.shards.updateUnsafe(BigInt(0), Context.empty())
485
+ activeShardsLatch.openUnsafe()
486
+
487
+ return Effect.gen(function*() {
488
+ yield* Effect.logError("Shard lock storage is unhealthy", cause)
489
+ yield* Effect.forkIn(syncSingletons, shardingScope, { startImmediately: true })
490
+
491
+ for (const shardId of affectedShards) {
492
+ for (const state of entityManagers.values()) {
493
+ if (state.status === "closed") continue
494
+ yield* Effect.forkIn(
495
+ state.manager.interruptShard(shardId, { force: true }),
496
+ shardingScope,
497
+ { startImmediately: true }
498
+ )
499
+ }
500
+ }
501
+ activeShardsLatch.openUnsafe()
502
+ })
503
+ })
504
+
505
+ const markShardLocksHealthy = Effect.suspend(() => {
506
+ if (!shardLocksHealthyLatch.openUnsafe()) return Effect.void
507
+
508
+ MutableHashSet.clear(selfShards)
509
+ MutableHashMap.forEach(shardAssignments, (runner, shardId) => {
510
+ if (isLocalRunner(runner)) {
511
+ MutableHashSet.add(selfShards, shardId)
512
+ }
513
+ })
514
+ activeShardsLatch.openUnsafe()
515
+ return Effect.logInfo("Shard lock storage has recovered")
516
+ })
517
+
518
+ const refreshShardLocks = Effect.suspend(() =>
397
519
  runnerStorage.refresh(selfAddress, [
398
520
  ...acquiredShards,
399
521
  ...releasingShards
@@ -421,12 +543,20 @@ const make = Effect.gen(function*() {
421
543
  times: 5,
422
544
  schedule: Schedule.spaced(50)
423
545
  }),
424
- Effect.catchCause((cause) =>
425
- Effect.logError("Could not refresh shard locks", cause).pipe(
426
- Effect.andThen(clearSelfShards)
427
- )
428
- ),
429
- Effect.repeat(Schedule.fixed(config.shardLockRefreshInterval)),
546
+ Effect.timeout(shardLockInterval),
547
+ Effect.catchCause(markShardLocksUnhealthy)
548
+ )
549
+
550
+ const probeShardLocks = runnerStorage.refresh(selfAddress, []).pipe(
551
+ Effect.timeout(shardLockInterval),
552
+ Effect.andThen(markShardLocksHealthy),
553
+ Effect.catchCause(() => Effect.void)
554
+ )
555
+
556
+ // Refresh shard locks at the lease-safe interval, or probe storage while
557
+ // lock ownership is uncertain.
558
+ yield* Effect.suspend(() => shardLocksHealthyLatch.isOpen() ? refreshShardLocks : probeShardLocks).pipe(
559
+ Effect.repeat(Schedule.fixed(shardLockInterval)),
430
560
  Effect.forever,
431
561
  Effect.forkIn(shardingScope)
432
562
  )
@@ -439,11 +569,6 @@ const make = Effect.gen(function*() {
439
569
  )
440
570
  }
441
571
 
442
- const clearSelfShards = Effect.sync(() => {
443
- MutableHashSet.clear(selfShards)
444
- activeShardsLatch.openUnsafe()
445
- })
446
-
447
572
  // --- Storage inbox ---
448
573
  //
449
574
  // Responsible for reading unprocessed messages from storage and sending them
@@ -977,7 +1102,7 @@ const make = Effect.gen(function*() {
977
1102
  if (newAssignments) {
978
1103
  const runner = newAssignments[i]
979
1104
  MutableHashMap.set(shardAssignments, shard, runner)
980
- if (isLocalRunner(runner)) {
1105
+ if (shardLocksHealthyLatch.isOpen() && isLocalRunner(runner)) {
981
1106
  MutableHashSet.add(selfShards, shard)
982
1107
  }
983
1108
  } else {
@@ -1167,12 +1292,14 @@ const make = Effect.gen(function*() {
1167
1292
  return entity.protocol.requests.has(p as string)
1168
1293
  },
1169
1294
  get(target, p) {
1170
- if (p in target) {
1295
+ if (Object.hasOwn(target, p)) {
1171
1296
  return target[p]
1172
1297
  } else if (!entity.protocol.requests.has(p as string)) {
1173
1298
  return undefined
1174
1299
  }
1175
- return target[p] = (payload: any, options?: {}) => clientFn(p as string, payload, options)
1300
+ const method = (payload: any, options?: {}) => clientFn(p as string, payload, options)
1301
+ InternalRecord.assignProperty(target, p, method)
1302
+ return method
1176
1303
  }
1177
1304
  })
1178
1305
  }
@@ -70,7 +70,11 @@ export class ShardingConfig extends Context.Service<ShardingConfig, {
70
70
  */
71
71
  readonly shardsPerGroup: number
72
72
  /**
73
- * Shard lock refresh interval.
73
+ * The maximum interval between shard lock refreshes.
74
+ *
75
+ * The runner may shorten this interval to one third of
76
+ * `shardLockExpiration` to preserve enough time to stop entities safely if
77
+ * lock storage becomes unavailable.
74
78
  */
75
79
  readonly shardLockRefreshInterval: Duration.Input
76
80
  /**
@@ -12,6 +12,7 @@
12
12
  */
13
13
  import * as Layer from "effect/Layer"
14
14
  import type { ConfigError } from "../../Config.ts"
15
+ import type * as Crypto from "../../Crypto.ts"
15
16
  import type * as SqlClient from "../sql/SqlClient.ts"
16
17
  import type * as MessageStorage from "./MessageStorage.ts"
17
18
  import * as RunnerHealth from "./RunnerHealth.ts"
@@ -42,7 +43,8 @@ import * as SqlRunnerStorage from "./SqlRunnerStorage.ts"
42
43
  * **Gotchas**
43
44
  *
44
45
  * - Even when `runnerStorage` is `"memory"`, message storage remains
45
- * SQL-backed, so callers must still provide `SqlClient`.
46
+ * SQL-backed, so callers must still provide `SqlClient` and `Crypto.Crypto`
47
+ * (used to hash over-length message deduplication keys).
46
48
  * - Runner communication and runner health are no-op services, so this layer is
47
49
  * for single-process use rather than multi-runner coordination.
48
50
  *
@@ -62,7 +64,7 @@ export const layer = (options?: {
62
64
  | Runners.Runners
63
65
  | MessageStorage.MessageStorage,
64
66
  ConfigError,
65
- SqlClient.SqlClient
67
+ SqlClient.SqlClient | Crypto.Crypto
66
68
  > =>
67
69
  Sharding.layer.pipe(
68
70
  Layer.provideMerge(Runners.layerNoop),