effect 4.0.0-beta.104 → 4.0.0-beta.106

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 (300) hide show
  1. package/AGENTS.md +381 -0
  2. package/CLAUDE.md +381 -0
  3. package/ai-docs/README.md +44 -0
  4. package/ai-docs/package.json +36 -0
  5. package/ai-docs/src/01_effect/01_basics/01_effect-gen.ts +30 -0
  6. package/ai-docs/src/01_effect/01_basics/02_effect-fn.ts +39 -0
  7. package/ai-docs/src/01_effect/01_basics/10_creating-effects.ts +74 -0
  8. package/ai-docs/src/01_effect/01_basics/index.md +5 -0
  9. package/ai-docs/src/01_effect/02_schema/10_schema-basics.ts +43 -0
  10. package/ai-docs/src/01_effect/02_schema/index.md +7 -0
  11. package/ai-docs/src/01_effect/03_services/01_service.ts +45 -0
  12. package/ai-docs/src/01_effect/03_services/10_reference.ts +10 -0
  13. package/ai-docs/src/01_effect/03_services/20_layer-composition.ts +70 -0
  14. package/ai-docs/src/01_effect/03_services/20_layer-unwrap.ts +66 -0
  15. package/ai-docs/src/01_effect/03_services/index.md +5 -0
  16. package/ai-docs/src/01_effect/04_errors/01_error-handling.ts +30 -0
  17. package/ai-docs/src/01_effect/04_errors/10_catch-tags.ts +24 -0
  18. package/ai-docs/src/01_effect/04_errors/20_reason-errors.ts +64 -0
  19. package/ai-docs/src/01_effect/04_errors/index.md +1 -0
  20. package/ai-docs/src/01_effect/05_resources/10_acquire-release.ts +105 -0
  21. package/ai-docs/src/01_effect/05_resources/20_layer-side-effects.ts +31 -0
  22. package/ai-docs/src/01_effect/05_resources/30_layer-map.ts +86 -0
  23. package/ai-docs/src/01_effect/05_resources/index.md +3 -0
  24. package/ai-docs/src/01_effect/06_running/10_run-main.ts +30 -0
  25. package/ai-docs/src/01_effect/06_running/20_layer-launch.ts +27 -0
  26. package/ai-docs/src/01_effect/06_running/index.md +1 -0
  27. package/ai-docs/src/01_effect/07_pubsub/10_pubsub.ts +56 -0
  28. package/ai-docs/src/01_effect/07_pubsub/index.md +3 -0
  29. package/ai-docs/src/03_stream/10_creating-streams.ts +103 -0
  30. package/ai-docs/src/03_stream/20_consuming-streams.ts +137 -0
  31. package/ai-docs/src/03_stream/30_encoding.ts +165 -0
  32. package/ai-docs/src/03_stream/index.md +4 -0
  33. package/ai-docs/src/04_integration/10_managed-runtime.ts +129 -0
  34. package/ai-docs/src/04_integration/index.md +5 -0
  35. package/ai-docs/src/05_batching/10_request-resolver.ts +89 -0
  36. package/ai-docs/src/05_batching/index.md +3 -0
  37. package/ai-docs/src/06_schedule/10_schedules.ts +110 -0
  38. package/ai-docs/src/06_schedule/index.md +3 -0
  39. package/ai-docs/src/07_datetime/10_creating-and-formatting.ts +30 -0
  40. package/ai-docs/src/07_datetime/20_time-zones.ts +44 -0
  41. package/ai-docs/src/07_datetime/index.md +5 -0
  42. package/ai-docs/src/08_observability/10_logging.ts +66 -0
  43. package/ai-docs/src/08_observability/20_otlp-tracing.ts +95 -0
  44. package/ai-docs/src/08_observability/index.md +7 -0
  45. package/ai-docs/src/09_testing/10_effect-tests.ts +55 -0
  46. package/ai-docs/src/09_testing/20_layer-tests.ts +138 -0
  47. package/ai-docs/src/09_testing/index.md +1 -0
  48. package/ai-docs/src/10_predicate/01_basics.ts +14 -0
  49. package/ai-docs/src/10_predicate/index.md +9 -0
  50. package/ai-docs/src/50_http-client/10_basics.ts +102 -0
  51. package/ai-docs/src/50_http-client/index.md +3 -0
  52. package/ai-docs/src/51_http-server/10_basics.ts +116 -0
  53. package/ai-docs/src/51_http-server/fixtures/api/Api.ts +14 -0
  54. package/ai-docs/src/51_http-server/fixtures/api/Authorization.ts +36 -0
  55. package/ai-docs/src/51_http-server/fixtures/api/System.ts +10 -0
  56. package/ai-docs/src/51_http-server/fixtures/api/Users.ts +91 -0
  57. package/ai-docs/src/51_http-server/fixtures/domain/User.ts +12 -0
  58. package/ai-docs/src/51_http-server/fixtures/domain/UserErrors.ts +22 -0
  59. package/ai-docs/src/51_http-server/fixtures/server/Authorization.ts +36 -0
  60. package/ai-docs/src/51_http-server/fixtures/server/Users/http.ts +71 -0
  61. package/ai-docs/src/51_http-server/fixtures/server/Users.ts +62 -0
  62. package/ai-docs/src/51_http-server/index.md +3 -0
  63. package/ai-docs/src/60_child-process/10_working-with-child-processes.ts +117 -0
  64. package/ai-docs/src/60_child-process/index.md +3 -0
  65. package/ai-docs/src/70_cli/10_basics.ts +136 -0
  66. package/ai-docs/src/70_cli/index.md +5 -0
  67. package/ai-docs/src/71_ai/10_language-model.ts +156 -0
  68. package/ai-docs/src/71_ai/20_tools.ts +226 -0
  69. package/ai-docs/src/71_ai/30_chat.ts +158 -0
  70. package/ai-docs/src/71_ai/fixtures/domain/LaunchPlan.ts +9 -0
  71. package/ai-docs/src/71_ai/index.md +5 -0
  72. package/ai-docs/src/80_cluster/10_entities.ts +97 -0
  73. package/ai-docs/src/80_cluster/index.md +4 -0
  74. package/ai-docs/src/index.md +10 -0
  75. package/ai-docs/tsconfig.json +24 -0
  76. package/dist/Brand.d.ts +3 -3
  77. package/dist/Brand.d.ts.map +1 -1
  78. package/dist/Brand.js +4 -3
  79. package/dist/Brand.js.map +1 -1
  80. package/dist/Config.d.ts.map +1 -1
  81. package/dist/Config.js +5 -4
  82. package/dist/Config.js.map +1 -1
  83. package/dist/ConfigProvider.d.ts +35 -3
  84. package/dist/ConfigProvider.d.ts.map +1 -1
  85. package/dist/ConfigProvider.js +41 -8
  86. package/dist/ConfigProvider.js.map +1 -1
  87. package/dist/Context.d.ts +0 -1
  88. package/dist/Context.d.ts.map +1 -1
  89. package/dist/Context.js +1 -22
  90. package/dist/Context.js.map +1 -1
  91. package/dist/Cron.d.ts +31 -0
  92. package/dist/Cron.d.ts.map +1 -1
  93. package/dist/Cron.js +58 -2
  94. package/dist/Cron.js.map +1 -1
  95. package/dist/Fiber.d.ts +1 -1
  96. package/dist/Fiber.d.ts.map +1 -1
  97. package/dist/Function.d.ts +26 -0
  98. package/dist/Function.d.ts.map +1 -1
  99. package/dist/Function.js +36 -0
  100. package/dist/Function.js.map +1 -1
  101. package/dist/JsonSchema.d.ts.map +1 -1
  102. package/dist/JsonSchema.js +34 -17
  103. package/dist/JsonSchema.js.map +1 -1
  104. package/dist/Optic.d.ts +35 -21
  105. package/dist/Optic.d.ts.map +1 -1
  106. package/dist/Optic.js +33 -34
  107. package/dist/Optic.js.map +1 -1
  108. package/dist/Schema.d.ts +105 -109
  109. package/dist/Schema.d.ts.map +1 -1
  110. package/dist/Schema.js +141 -104
  111. package/dist/Schema.js.map +1 -1
  112. package/dist/SchemaAST.d.ts +32 -17
  113. package/dist/SchemaAST.d.ts.map +1 -1
  114. package/dist/SchemaAST.js +79 -60
  115. package/dist/SchemaAST.js.map +1 -1
  116. package/dist/SchemaError.d.ts +8 -8
  117. package/dist/SchemaError.d.ts.map +1 -1
  118. package/dist/SchemaError.js +7 -6
  119. package/dist/SchemaError.js.map +1 -1
  120. package/dist/SchemaGetter.d.ts +8 -5
  121. package/dist/SchemaGetter.d.ts.map +1 -1
  122. package/dist/SchemaGetter.js +41 -37
  123. package/dist/SchemaGetter.js.map +1 -1
  124. package/dist/SchemaIssue.d.ts +195 -38
  125. package/dist/SchemaIssue.d.ts.map +1 -1
  126. package/dist/SchemaIssue.js +243 -68
  127. package/dist/SchemaIssue.js.map +1 -1
  128. package/dist/SchemaParser.d.ts +30 -0
  129. package/dist/SchemaParser.d.ts.map +1 -1
  130. package/dist/SchemaParser.js +39 -9
  131. package/dist/SchemaParser.js.map +1 -1
  132. package/dist/SchemaRepresentation.d.ts +15 -3
  133. package/dist/SchemaRepresentation.d.ts.map +1 -1
  134. package/dist/SchemaRepresentation.js +8 -2
  135. package/dist/SchemaRepresentation.js.map +1 -1
  136. package/dist/SchemaTransformation.d.ts +2 -2
  137. package/dist/SchemaTransformation.d.ts.map +1 -1
  138. package/dist/SchemaTransformation.js +26 -26
  139. package/dist/SchemaTransformation.js.map +1 -1
  140. package/dist/ScopedRef.d.ts.map +1 -1
  141. package/dist/ScopedRef.js +1 -1
  142. package/dist/ScopedRef.js.map +1 -1
  143. package/dist/Stdio.d.ts +17 -4
  144. package/dist/Stdio.d.ts.map +1 -1
  145. package/dist/Stdio.js +6 -3
  146. package/dist/Stdio.js.map +1 -1
  147. package/dist/TxQueue.js +1 -1
  148. package/dist/TxQueue.js.map +1 -1
  149. package/dist/internal/effect.js +2 -4
  150. package/dist/internal/effect.js.map +1 -1
  151. package/dist/internal/executionPlan.js +3 -2
  152. package/dist/internal/executionPlan.js.map +1 -1
  153. package/dist/internal/rcRef.js +18 -13
  154. package/dist/internal/rcRef.js.map +1 -1
  155. package/dist/internal/schema/fromJsonSchemaDocument.js +10 -6
  156. package/dist/internal/schema/fromJsonSchemaDocument.js.map +1 -1
  157. package/dist/internal/schema/schema.js +1 -9
  158. package/dist/internal/schema/schema.js.map +1 -1
  159. package/dist/internal/schema/toArbitrary.d.ts +1 -4
  160. package/dist/internal/schema/toArbitrary.d.ts.map +1 -1
  161. package/dist/internal/schema/toArbitrary.js +0 -74
  162. package/dist/internal/schema/toArbitrary.js.map +1 -1
  163. package/dist/internal/schema/toJsonSchemaDocument.js +18 -4
  164. package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
  165. package/dist/internal/schema/toRepresentation.js +45 -43
  166. package/dist/internal/schema/toRepresentation.js.map +1 -1
  167. package/dist/testing/TestSchema.d.ts +1 -1
  168. package/dist/testing/TestSchema.d.ts.map +1 -1
  169. package/dist/testing/TestSchema.js +10 -9
  170. package/dist/testing/TestSchema.js.map +1 -1
  171. package/dist/unstable/ai/McpSchema.d.ts +110 -110
  172. package/dist/unstable/ai/McpSchema.d.ts.map +1 -1
  173. package/dist/unstable/ai/McpServer.d.ts.map +1 -1
  174. package/dist/unstable/ai/McpServer.js +23 -11
  175. package/dist/unstable/ai/McpServer.js.map +1 -1
  176. package/dist/unstable/ai/Prompt.d.ts +4 -3
  177. package/dist/unstable/ai/Prompt.d.ts.map +1 -1
  178. package/dist/unstable/ai/Prompt.js +42 -17
  179. package/dist/unstable/ai/Prompt.js.map +1 -1
  180. package/dist/unstable/cluster/Entity.d.ts +2 -2
  181. package/dist/unstable/cluster/Entity.d.ts.map +1 -1
  182. package/dist/unstable/cluster/Entity.js.map +1 -1
  183. package/dist/unstable/cluster/EntityProxy.d.ts +3 -3
  184. package/dist/unstable/cluster/EntityProxy.d.ts.map +1 -1
  185. package/dist/unstable/cluster/EntityProxy.js +4 -3
  186. package/dist/unstable/cluster/EntityProxy.js.map +1 -1
  187. package/dist/unstable/cluster/Reply.js +4 -4
  188. package/dist/unstable/cluster/Reply.js.map +1 -1
  189. package/dist/unstable/cluster/Sharding.d.ts +2 -2
  190. package/dist/unstable/cluster/Sharding.d.ts.map +1 -1
  191. package/dist/unstable/cluster/Sharding.js +14 -5
  192. package/dist/unstable/cluster/Sharding.js.map +1 -1
  193. package/dist/unstable/encoding/Msgpack.d.ts.map +1 -1
  194. package/dist/unstable/encoding/Msgpack.js +6 -6
  195. package/dist/unstable/encoding/Msgpack.js.map +1 -1
  196. package/dist/unstable/eventlog/EventLogEncryption.d.ts +6 -5
  197. package/dist/unstable/eventlog/EventLogEncryption.d.ts.map +1 -1
  198. package/dist/unstable/eventlog/EventLogEncryption.js +14 -12
  199. package/dist/unstable/eventlog/EventLogEncryption.js.map +1 -1
  200. package/dist/unstable/eventlog/EventLogMessage.d.ts +3 -3
  201. package/dist/unstable/eventlog/EventLogMessage.d.ts.map +1 -1
  202. package/dist/unstable/eventlog/EventLogMessage.js +2 -3
  203. package/dist/unstable/eventlog/EventLogMessage.js.map +1 -1
  204. package/dist/unstable/eventlog/EventLogRemote.js +4 -4
  205. package/dist/unstable/eventlog/EventLogRemote.js.map +1 -1
  206. package/dist/unstable/eventlog/EventLogServerEncrypted.js +3 -2
  207. package/dist/unstable/eventlog/EventLogServerEncrypted.js.map +1 -1
  208. package/dist/unstable/http/HttpClient.d.ts +59 -3
  209. package/dist/unstable/http/HttpClient.d.ts.map +1 -1
  210. package/dist/unstable/http/HttpClient.js +33 -19
  211. package/dist/unstable/http/HttpClient.js.map +1 -1
  212. package/dist/unstable/http/HttpServerRequest.d.ts.map +1 -1
  213. package/dist/unstable/http/HttpServerRequest.js +7 -1
  214. package/dist/unstable/http/HttpServerRequest.js.map +1 -1
  215. package/dist/unstable/http/MultipartParser/internal/multipart.d.ts.map +1 -1
  216. package/dist/unstable/http/MultipartParser/internal/multipart.js +18 -6
  217. package/dist/unstable/http/MultipartParser/internal/multipart.js.map +1 -1
  218. package/dist/unstable/httpapi/HttpApiBuilder.js +10 -10
  219. package/dist/unstable/httpapi/HttpApiBuilder.js.map +1 -1
  220. package/dist/unstable/httpapi/HttpApiClient.js +9 -9
  221. package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
  222. package/dist/unstable/httpapi/OpenApi.d.ts.map +1 -1
  223. package/dist/unstable/httpapi/OpenApi.js +1 -1
  224. package/dist/unstable/httpapi/OpenApi.js.map +1 -1
  225. package/dist/unstable/reactivity/AsyncResult.d.ts.map +1 -1
  226. package/dist/unstable/reactivity/AsyncResult.js +4 -4
  227. package/dist/unstable/reactivity/AsyncResult.js.map +1 -1
  228. package/dist/unstable/reactivity/Atom.d.ts +26 -11
  229. package/dist/unstable/reactivity/Atom.d.ts.map +1 -1
  230. package/dist/unstable/reactivity/Atom.js +9 -22
  231. package/dist/unstable/reactivity/Atom.js.map +1 -1
  232. package/dist/unstable/rpc/RpcClient.d.ts.map +1 -1
  233. package/dist/unstable/rpc/RpcClient.js +8 -1
  234. package/dist/unstable/rpc/RpcClient.js.map +1 -1
  235. package/dist/unstable/rpc/RpcServer.d.ts.map +1 -1
  236. package/dist/unstable/rpc/RpcServer.js +3 -2
  237. package/dist/unstable/rpc/RpcServer.js.map +1 -1
  238. package/dist/unstable/sql/SqlResolver.d.ts.map +1 -1
  239. package/dist/unstable/sql/SqlResolver.js +20 -16
  240. package/dist/unstable/sql/SqlResolver.js.map +1 -1
  241. package/dist/unstable/workers/Worker.d.ts.map +1 -1
  242. package/dist/unstable/workers/Worker.js +11 -12
  243. package/dist/unstable/workers/Worker.js.map +1 -1
  244. package/dist/unstable/workflow/Workflow.d.ts.map +1 -1
  245. package/dist/unstable/workflow/Workflow.js +2 -2
  246. package/dist/unstable/workflow/Workflow.js.map +1 -1
  247. package/package.json +5 -2
  248. package/src/Brand.ts +4 -4
  249. package/src/Config.ts +6 -4
  250. package/src/ConfigProvider.ts +43 -8
  251. package/src/Context.ts +1 -23
  252. package/src/Cron.ts +65 -2
  253. package/src/Fiber.ts +1 -1
  254. package/src/Function.ts +37 -0
  255. package/src/JsonSchema.ts +43 -42
  256. package/src/Optic.ts +59 -58
  257. package/src/Schema.ts +213 -217
  258. package/src/SchemaAST.ts +135 -78
  259. package/src/SchemaError.ts +9 -9
  260. package/src/SchemaGetter.ts +89 -30
  261. package/src/SchemaIssue.ts +285 -80
  262. package/src/SchemaParser.ts +51 -17
  263. package/src/SchemaRepresentation.ts +15 -3
  264. package/src/SchemaTransformation.ts +66 -18
  265. package/src/ScopedRef.ts +3 -1
  266. package/src/Stdio.ts +23 -4
  267. package/src/TxQueue.ts +1 -1
  268. package/src/internal/effect.ts +3 -6
  269. package/src/internal/executionPlan.ts +3 -2
  270. package/src/internal/rcRef.ts +24 -16
  271. package/src/internal/schema/fromJsonSchemaDocument.ts +19 -14
  272. package/src/internal/schema/schema.ts +1 -17
  273. package/src/internal/schema/toArbitrary.ts +0 -72
  274. package/src/internal/schema/toJsonSchemaDocument.ts +24 -4
  275. package/src/internal/schema/toRepresentation.ts +66 -48
  276. package/src/testing/TestSchema.ts +10 -10
  277. package/src/unstable/ai/McpServer.ts +23 -11
  278. package/src/unstable/ai/Prompt.ts +51 -19
  279. package/src/unstable/cluster/Entity.ts +7 -2
  280. package/src/unstable/cluster/EntityProxy.ts +12 -5
  281. package/src/unstable/cluster/Reply.ts +4 -4
  282. package/src/unstable/cluster/Sharding.ts +29 -17
  283. package/src/unstable/encoding/Msgpack.ts +12 -8
  284. package/src/unstable/eventlog/EventLogEncryption.ts +15 -16
  285. package/src/unstable/eventlog/EventLogMessage.ts +2 -3
  286. package/src/unstable/eventlog/EventLogRemote.ts +4 -4
  287. package/src/unstable/eventlog/EventLogServerEncrypted.ts +2 -2
  288. package/src/unstable/http/HttpClient.ts +132 -23
  289. package/src/unstable/http/HttpServerRequest.ts +8 -3
  290. package/src/unstable/http/MultipartParser/internal/multipart.ts +19 -6
  291. package/src/unstable/httpapi/HttpApiBuilder.ts +32 -13
  292. package/src/unstable/httpapi/HttpApiClient.ts +26 -8
  293. package/src/unstable/httpapi/OpenApi.ts +4 -1
  294. package/src/unstable/reactivity/AsyncResult.ts +11 -6
  295. package/src/unstable/reactivity/Atom.ts +44 -25
  296. package/src/unstable/rpc/RpcClient.ts +9 -1
  297. package/src/unstable/rpc/RpcServer.ts +4 -2
  298. package/src/unstable/sql/SqlResolver.ts +28 -20
  299. package/src/unstable/workers/Worker.ts +13 -14
  300. package/src/unstable/workflow/Workflow.ts +2 -5
@@ -436,14 +436,19 @@ export const toClientRequest = (request: HttpServerRequest): HttpClientRequest.H
436
436
  Option.getOrElse(toURL(request), () => request.url)
437
437
  )
438
438
 
439
- const toClientBody = (request: HttpServerRequest): HttpBody.HttpBody =>
440
- hasBody(request.method)
439
+ const toClientBody = (request: HttpServerRequest): HttpBody.HttpBody => {
440
+ if (!hasBody(request.method)) {
441
+ return HttpBody.empty
442
+ }
443
+ const formData = getFormDataBody(request)
444
+ return formData === undefined
441
445
  ? HttpBody.stream(
442
446
  request.stream,
443
447
  request.headers["content-type"],
444
448
  parseContentLength(request.headers["content-length"])
445
449
  )
446
- : HttpBody.empty
450
+ : HttpBody.formData(formData)
451
+ }
447
452
 
448
453
  const parseContentLength = (contentLength: string | undefined): number | undefined => {
449
454
  if (contentLength === undefined) {
@@ -74,7 +74,8 @@ export function make({
74
74
  isFile: false,
75
75
  fieldChunks: [] as Array<Uint8Array>,
76
76
  fieldSize: 0,
77
- done: false
77
+ done: false,
78
+ stopped: false
78
79
  }
79
80
 
80
81
  function skipBody() {
@@ -88,6 +89,10 @@ export function make({
88
89
  const split = Search.make(
89
90
  `\r\n--${boundary}`,
90
91
  function(index, chunk) {
92
+ if (state.stopped) {
93
+ return
94
+ }
95
+
91
96
  if (index === 0) {
92
97
  // data before the first boundary
93
98
  skipBody()
@@ -127,12 +132,14 @@ export function make({
127
132
 
128
133
  state.parts++
129
134
  if (state.parts > maxParts) {
130
- onError(errMaxParts)
135
+ state.stopped = true
136
+ return onError(errMaxParts)
131
137
  }
132
138
  }
133
139
 
134
140
  if ((state.partSize += chunk.length) > maxPartSize) {
135
- onError(errMaxPartSize)
141
+ state.stopped = true
142
+ return onError(errMaxPartSize)
136
143
  }
137
144
 
138
145
  if (state.state === State.headers) {
@@ -199,7 +206,8 @@ export function make({
199
206
  } else {
200
207
  const buf = chunk.subarray(result.endPosition)
201
208
  if ((state.fieldSize += buf.length) > maxFieldSize) {
202
- onError(errMaxFieldSize)
209
+ state.stopped = true
210
+ return onError(errMaxFieldSize)
203
211
  }
204
212
  state.fieldChunks.push(buf)
205
213
  }
@@ -208,7 +216,8 @@ export function make({
208
216
  state.onChunk(chunk)
209
217
  } else {
210
218
  if ((state.fieldSize += chunk.length) > maxFieldSize) {
211
- onError(errMaxFieldSize)
219
+ state.stopped = true
220
+ return onError(errMaxFieldSize)
212
221
  }
213
222
  state.fieldChunks.push(chunk)
214
223
  }
@@ -219,6 +228,9 @@ export function make({
219
228
 
220
229
  return {
221
230
  write(chunk: Uint8Array) {
231
+ if (state.stopped) {
232
+ return
233
+ }
222
234
  if ((state.totalSize += chunk.length) > maxTotalSize) {
223
235
  return onError(errMaxTotalSize)
224
236
  }
@@ -226,7 +238,7 @@ export function make({
226
238
  },
227
239
  end() {
228
240
  split.end()
229
- if (!state.done) {
241
+ if (!state.done && !state.stopped) {
230
242
  onError(errEndNotReached)
231
243
  }
232
244
 
@@ -240,6 +252,7 @@ export function make({
240
252
  state.fieldChunks = []
241
253
  state.fieldSize = 0
242
254
  state.done = false
255
+ state.stopped = false
243
256
  }
244
257
  } as const
245
258
  }
@@ -1101,10 +1101,10 @@ function toResponseErrorSchema(
1101
1101
  HttpApiSchema.isNoContent(schema.schema.ast)
1102
1102
  )
1103
1103
  const transformation = withHeadersTransformation<HttpApiSchema.withHeaders<unknown, Schema.StringTree>>(
1104
- (body) =>
1105
- encodeBody(body).pipe(
1104
+ (body, options) =>
1105
+ encodeBody(body, options).pipe(
1106
1106
  Effect.mapError((error) => error.issue),
1107
- Effect.flatMap(encodeResponse)
1107
+ Effect.flatMap((body) => encodeResponse(body, options))
1108
1108
  ),
1109
1109
  encodeHeaders
1110
1110
  )
@@ -1167,22 +1167,34 @@ function getResponseTransformation(
1167
1167
  )
1168
1168
 
1169
1169
  return SchemaTransformation.transformOrFail({
1170
- decode: () => Effect.fail(new SchemaIssue.Forbidden({ message: "Encode only schema" })),
1170
+ decode: (input, options) =>
1171
+ Effect.fail(
1172
+ new SchemaIssue.Forbidden({ message: "Encode only schema" }, input, options)
1173
+ ),
1171
1174
  encode
1172
1175
  })
1173
1176
  }
1174
1177
 
1175
1178
  function withHeadersTransformation<T = unknown>(
1176
- encodeBody: (body: unknown) => Effect.Effect<Response.HttpServerResponse, SchemaIssue.Issue, unknown>,
1177
- encodeHeaders: (headers: unknown) => Effect.Effect<unknown, Schema.SchemaError, unknown>
1179
+ encodeBody: (
1180
+ body: unknown,
1181
+ options?: SchemaAST.ParseOptions
1182
+ ) => Effect.Effect<Response.HttpServerResponse, SchemaIssue.Issue, unknown>,
1183
+ encodeHeaders: (
1184
+ headers: unknown,
1185
+ options?: SchemaAST.ParseOptions
1186
+ ) => Effect.Effect<unknown, Schema.SchemaError, unknown>
1178
1187
  ): SchemaTransformation.Transformation<T, Response.HttpServerResponse, never, unknown> {
1179
1188
  return SchemaTransformation.transformOrFail<T, Response.HttpServerResponse, never, unknown>({
1180
- decode: () => Effect.fail(new SchemaIssue.Forbidden({ message: "Encode only schema" })),
1181
- encode: (value) => {
1189
+ decode: (input, options) =>
1190
+ Effect.fail(
1191
+ new SchemaIssue.Forbidden({ message: "Encode only schema" }, input, options)
1192
+ ),
1193
+ encode: (value, options) => {
1182
1194
  const pair = value as { readonly body: unknown; readonly headers: unknown }
1183
- return Effect.flatMap(encodeBody(pair.body), (response) =>
1195
+ return Effect.flatMap(encodeBody(pair.body, options), (response) =>
1184
1196
  Effect.map(
1185
- encodeHeaders(pair.headers).pipe(Effect.mapError((error) => error.issue)),
1197
+ encodeHeaders(pair.headers, options).pipe(Effect.mapError((error) => error.issue)),
1186
1198
  (headers) => Response.setHeaders(response, headers as any)
1187
1199
  ))
1188
1200
  }
@@ -1193,10 +1205,13 @@ function getResponseEncode<E>(
1193
1205
  status: number,
1194
1206
  encoding: HttpApiSchema.ResponseEncoding,
1195
1207
  isNoContent: boolean
1196
- ): (e: E) => Effect.Effect<Response.HttpServerResponse, SchemaIssue.InvalidValue, never> {
1208
+ ): (
1209
+ e: E,
1210
+ options?: SchemaAST.ParseOptions
1211
+ ) => Effect.Effect<Response.HttpServerResponse, SchemaIssue.InvalidValue, never> {
1197
1212
  switch (encoding._tag) {
1198
1213
  case "Json": {
1199
- return ((e) => {
1214
+ return ((e, options) => {
1200
1215
  if (e === undefined || isNoContent) {
1201
1216
  return Effect.succeed(Response.empty({ status }))
1202
1217
  }
@@ -1205,7 +1220,11 @@ function getResponseEncode<E>(
1205
1220
  return Effect.succeed(Response.text(s, { status, contentType: encoding.contentType }))
1206
1221
  } catch {
1207
1222
  return Effect.fail(
1208
- new SchemaIssue.InvalidValue({ message: "Expected a JSON-serializable response body" })
1223
+ new SchemaIssue.InvalidValue(
1224
+ { expected: "a JSON-serializable response body" },
1225
+ e,
1226
+ options
1227
+ )
1209
1228
  )
1210
1229
  }
1211
1230
  })
@@ -1065,41 +1065,59 @@ function getEncodePayloadSchemaFromBody(
1065
1065
  const out = $HttpBody.pipe(Schema.decodeTo(
1066
1066
  schema,
1067
1067
  SchemaTransformation.transformOrFail<unknown, HttpBody.HttpBody>({
1068
- decode() {
1069
- return Effect.fail(new SchemaIssue.Forbidden({ message: "Encode only schema" }))
1068
+ decode(input, options) {
1069
+ return Effect.fail(
1070
+ new SchemaIssue.Forbidden({ message: "Encode only schema" }, input, options)
1071
+ )
1070
1072
  },
1071
- encode(t) {
1073
+ encode(t, options) {
1072
1074
  switch (encoding._tag) {
1073
1075
  case "Multipart":
1074
- return Effect.fail(new SchemaIssue.Forbidden({ message: "Payload must be a FormData" }))
1076
+ return Effect.fail(
1077
+ new SchemaIssue.Forbidden(
1078
+ { message: "Payload must be a FormData" },
1079
+ t,
1080
+ options
1081
+ )
1082
+ )
1075
1083
  case "Json": {
1076
1084
  try {
1077
1085
  const body = JSON.stringify(t)
1078
1086
  return Effect.succeed(HttpBody.text(body, encoding.contentType))
1079
1087
  } catch {
1080
1088
  return Effect.fail(
1081
- new SchemaIssue.InvalidValue({ message: "Expected a JSON-serializable request body" })
1089
+ new SchemaIssue.InvalidValue(
1090
+ { expected: "a JSON-serializable request body" },
1091
+ t,
1092
+ options
1093
+ )
1082
1094
  )
1083
1095
  }
1084
1096
  }
1085
1097
  case "Text": {
1086
1098
  if (typeof t !== "string") {
1087
1099
  return Effect.fail(
1088
- new SchemaIssue.InvalidValue({ message: "Expected a string" })
1100
+ new SchemaIssue.InvalidValue({ message: "Expected a string" }, t, options)
1089
1101
  )
1090
1102
  }
1091
1103
  return Effect.succeed(HttpBody.text(t, encoding.contentType))
1092
1104
  }
1093
1105
  case "FormUrlEncoded": {
1094
1106
  if (!Predicate.isObject(t)) {
1095
- return Effect.fail(new SchemaIssue.InvalidValue({ message: "Expected a record" }))
1107
+ return Effect.fail(
1108
+ new SchemaIssue.InvalidValue({ message: "Expected a record" }, t, options)
1109
+ )
1096
1110
  }
1097
1111
  return Effect.succeed(HttpBody.urlParams(UrlParams.fromInput(t as any), encoding.contentType))
1098
1112
  }
1099
1113
  case "Uint8Array": {
1100
1114
  if (!(t instanceof Uint8Array)) {
1101
1115
  return Effect.fail(
1102
- new SchemaIssue.InvalidValue({ message: "Expected a Uint8Array" })
1116
+ new SchemaIssue.InvalidValue(
1117
+ { message: "Expected a Uint8Array" },
1118
+ t,
1119
+ options
1120
+ )
1103
1121
  )
1104
1122
  }
1105
1123
  return Effect.succeed(HttpBody.uint8Array(t, encoding.contentType))
@@ -220,7 +220,10 @@ type CompileSchemas = (
220
220
  const compileSchemas: CompileSchemas = (asts) =>
221
221
  JsonSchema.toMultiDocumentOpenApi3_1(
222
222
  InternalToJsonSchemaDocument.toJsonSchemaMultiDocument(
223
- InternalToRepresentation.toRepresentations(Arr.map(asts, Schema.toCodecJsonAST))
223
+ InternalToRepresentation.toRepresentations(
224
+ Arr.map(asts, Schema.toCodecJsonAST),
225
+ InternalToJsonSchemaDocument.toRepresentationOptions
226
+ )
224
227
  )
225
228
  )
226
229
 
@@ -1101,7 +1101,7 @@ export const Schema = <
1101
1101
  [success_, Schema_.Cause(error, Schema_.Defect())],
1102
1102
  ([value, cause]) => (input, ast, options) => {
1103
1103
  if (!isAsyncResult(input)) {
1104
- return Effect.fail(new SchemaIssue.InvalidType(ast))
1104
+ return Effect.fail(new SchemaIssue.InvalidType(ast, input, options))
1105
1105
  }
1106
1106
  switch (input._tag) {
1107
1107
  case "Initial":
@@ -1111,7 +1111,7 @@ export const Schema = <
1111
1111
  SchemaParser.decodeUnknownEffect(value)(input.value, options),
1112
1112
  {
1113
1113
  onSuccess: (value) => success(value, input),
1114
- onFailure: (issue) => new SchemaIssue.Composite(ast, [new SchemaIssue.Pointer(["value"], issue)])
1114
+ onFailure: (issue) => SchemaIssue.makeCompositeAtKey(ast, "value", issue, input, options)
1115
1115
  }
1116
1116
  )
1117
1117
  case "Failure": {
@@ -1122,9 +1122,14 @@ export const Schema = <
1122
1122
  {
1123
1123
  onSuccess: (value) => Option.some(success<A["Type"], E["Type"]>(value, ps)),
1124
1124
  onFailure: (issue) =>
1125
- new SchemaIssue.Composite(ast, [
1126
- new SchemaIssue.Pointer(["previousSuccess", "value"], issue)
1127
- ])
1125
+ new SchemaIssue.Composite(
1126
+ ast,
1127
+ [
1128
+ new SchemaIssue.Pointer(["previousSuccess", "value"], issue)
1129
+ ],
1130
+ input,
1131
+ options
1132
+ )
1128
1133
  }
1129
1134
  )
1130
1135
  ),
@@ -1132,7 +1137,7 @@ export const Schema = <
1132
1137
  )
1133
1138
  const causeEffect = Effect.mapErrorEager(
1134
1139
  SchemaParser.decodeUnknownEffect(cause)(input.cause, options),
1135
- (issue) => new SchemaIssue.Composite(ast, [new SchemaIssue.Pointer(["cause"], issue)])
1140
+ (issue) => SchemaIssue.makeCompositeAtKey(ast, "cause", issue, input, options)
1136
1141
  )
1137
1142
  return Effect.flatMapEager(
1138
1143
  prevSuccessEffect,
@@ -790,7 +790,7 @@ export interface AtomRuntime<R, ER = never> extends Atom<AsyncResult.AsyncResult
790
790
  }
791
791
 
792
792
  /**
793
- * Factory for `AtomRuntime` values that share a `Layer.MemoMap` and a set of global layers.
793
+ * Factory for `AtomRuntime` values that share a set of global layers.
794
794
  *
795
795
  * @category models
796
796
  * @since 4.0.0
@@ -801,7 +801,6 @@ export interface RuntimeFactory {
801
801
  | Layer.Layer<R, E, AtomRegistry | Reactivity.Reactivity>
802
802
  | ((get: AtomContext) => Layer.Layer<R, E, AtomRegistry | Reactivity.Reactivity>)
803
803
  ): AtomRuntime<R, E>
804
- readonly memoMap: Layer.MemoMap
805
804
  readonly addGlobalLayer: <A, E>(layer: Layer.Layer<A, E, AtomRegistry | Reactivity.Reactivity>) => void
806
805
 
807
806
  /**
@@ -814,14 +813,40 @@ export interface RuntimeFactory {
814
813
  }
815
814
 
816
815
  /**
817
- * Creates a `RuntimeFactory` backed by the supplied `Layer.MemoMap`.
816
+ * A `RuntimeFactory` backed by an atom whose memo map is scoped to each registry.
818
817
  *
819
- * @category constructors
818
+ * @category models
820
819
  * @since 4.0.0
821
820
  */
822
- export const context: (options: {
821
+ export interface RegistryRuntimeFactory extends RuntimeFactory {
822
+ readonly memoMap: Atom<Layer.MemoMap>
823
+ }
824
+
825
+ /**
826
+ * A `RuntimeFactory` backed by a concrete memo map shared across registries.
827
+ *
828
+ * @category models
829
+ * @since 4.0.0
830
+ */
831
+ export interface SharedRuntimeFactory extends RuntimeFactory {
823
832
  readonly memoMap: Layer.MemoMap
824
- }) => RuntimeFactory = (options) => {
833
+ }
834
+
835
+ /**
836
+ * Creates a `RuntimeFactory` backed by a registry-scoped memo map by default,
837
+ * or by the supplied atom or concrete `Layer.MemoMap`.
838
+ *
839
+ * @category constructors
840
+ * @since 4.0.0
841
+ */
842
+ export function context(): RegistryRuntimeFactory
843
+ export function context(options: { readonly memoMap: Atom<Layer.MemoMap> }): RegistryRuntimeFactory
844
+ export function context(options: { readonly memoMap: Layer.MemoMap }): SharedRuntimeFactory
845
+ export function context(options?: {
846
+ readonly memoMap: Atom<Layer.MemoMap> | Layer.MemoMap
847
+ }): RegistryRuntimeFactory | SharedRuntimeFactory {
848
+ const memoMap = options?.memoMap ?? removeTtl(make(() => Layer.makeMemoMapUnsafe()))
849
+ const resolveMemoMap = (get: AtomContext): Layer.MemoMap => isAtom(memoMap) ? get(memoMap) : memoMap
825
850
  let globalLayer: Layer.Layer<any, any, AtomRegistry> = Reactivity.layer
826
851
  function factory<E, R>(
827
852
  create:
@@ -843,23 +868,25 @@ export const context: (options: {
843
868
 
844
869
  self.read = function read(get: AtomContext) {
845
870
  const layer = get(layerAtom)
846
- const build = Effect.flatMap(Effect.scope, (scope) => Layer.buildWithMemoMap(layer, options.memoMap, scope))
871
+ const build = Effect.flatMap(Effect.scope, (scope) => Layer.buildWithMemoMap(layer, resolveMemoMap(get), scope))
847
872
  return effect(get, build, { uninterruptible: true })
848
873
  }
849
874
 
850
875
  return self
851
876
  }
852
- factory.memoMap = options.memoMap
877
+ factory.memoMap = memoMap
853
878
  factory.addGlobalLayer = (layer: Layer.Layer<any, any, AtomRegistry | Reactivity.Reactivity>) => {
854
879
  globalLayer = Layer.provideMerge(globalLayer, Layer.provide(layer, Reactivity.layer))
855
880
  }
856
- const reactivityAtom = removeTtl(make(
857
- Effect.contextWith((services: Context.Context<Scope.Scope>) =>
858
- Layer.buildWithMemoMap(Reactivity.layer, options.memoMap, Context.get(services, Scope.Scope))
859
- ).pipe(
860
- Effect.map(Context.get(Reactivity.Reactivity))
881
+ const reactivityAtom = removeTtl(
882
+ make((get) =>
883
+ Effect.contextWith((services: Context.Context<Scope.Scope>) =>
884
+ Layer.buildWithMemoMap(Reactivity.layer, resolveMemoMap(get), Context.get(services, Scope.Scope))
885
+ ).pipe(
886
+ Effect.map(Context.get(Reactivity.Reactivity))
887
+ )
861
888
  )
862
- ))
889
+ )
863
890
  factory.withReactivity =
864
891
  (keys: ReadonlyArray<unknown> | ReadonlyRecord<string, ReadonlyArray<unknown>>) =>
865
892
  <A extends Atom<any>>(atom: A): A =>
@@ -871,24 +898,16 @@ export const context: (options: {
871
898
  get.subscribe(atom, (value) => get.setSelf(value))
872
899
  return get.once(atom)
873
900
  }, { initialValueTarget: atom }) as any as A
874
- return factory
901
+ return factory as any
875
902
  }
876
903
 
877
904
  /**
878
- * Default `Layer.MemoMap` used by the module-level `runtime` factory.
879
- *
880
- * @category context
881
- * @since 4.0.0
882
- */
883
- export const defaultMemoMap: Layer.MemoMap = Layer.makeMemoMapUnsafe()
884
-
885
- /**
886
- * Default `RuntimeFactory` created with `defaultMemoMap`.
905
+ * Default registry-scoped `RuntimeFactory`.
887
906
  *
888
907
  * @category context
889
908
  * @since 4.0.0
890
909
  */
891
- export const runtime: RuntimeFactory = context({ memoMap: defaultMemoMap })
910
+ export const runtime: RegistryRuntimeFactory = context()
892
911
 
893
912
  /**
894
913
  * Returns `Rx.runtime.withReactivity` for refreshing an atom whenever the
@@ -23,6 +23,7 @@ import * as Latch from "../../Latch.ts"
23
23
  import * as Layer from "../../Layer.ts"
24
24
  import * as Option from "../../Option.ts"
25
25
  import * as Pool from "../../Pool.ts"
26
+ import * as Predicate from "../../Predicate.ts"
26
27
  import * as Queue from "../../Queue.ts"
27
28
  import * as Result from "../../Result.ts"
28
29
  import * as Schedule from "../../Schedule.ts"
@@ -51,6 +52,8 @@ import * as RpcSerialization from "./RpcSerialization.ts"
51
52
  import * as RpcWorker from "./RpcWorker.ts"
52
53
  import { withRunClient } from "./Utils.ts"
53
54
 
55
+ const isRpcClientError = (u: unknown): u is RpcClientError => Predicate.isTagged(u, "RpcClientError")
56
+
54
57
  /**
55
58
  * The object-shaped client generated from a union of RPC definitions, with one
56
59
  * method per RPC tag.
@@ -974,7 +977,7 @@ export const makeProtocolHttp = (client: HttpClient.HttpClient): Effect.Effect<
974
977
  })
975
978
  })
976
979
  )).pipe(
977
- Effect.mapError((cause) => cause instanceof RpcClientError ? cause : httpClientError(cause))
980
+ Effect.mapError((cause) => isRpcClientError(cause) ? cause : httpClientError(cause))
978
981
  )
979
982
  if (!hasResponse) {
980
983
  return yield* emptyResponseError(request)
@@ -1296,6 +1299,11 @@ export const makeProtocolWorker = (
1296
1299
  undefined
1297
1300
  }).pipe(
1298
1301
  Effect.tapCause((cause) => {
1302
+ for (const [requestId, entry] of entries) {
1303
+ if (entry.worker !== backing) continue
1304
+ entries.delete(requestId)
1305
+ entry.latch.openUnsafe()
1306
+ }
1299
1307
  const error = Cause.findError(cause)
1300
1308
  return broadcast({
1301
1309
  _tag: "ClientProtocolError",
@@ -27,6 +27,7 @@ import * as Pull from "../../Pull.ts"
27
27
  import * as Queue from "../../Queue.ts"
28
28
  import * as Schedule from "../../Schedule.ts"
29
29
  import * as Schema from "../../Schema.ts"
30
+ import * as SchemaIssue from "../../SchemaIssue.ts"
30
31
  import * as Scope from "../../Scope.ts"
31
32
  import * as Semaphore from "../../Semaphore.ts"
32
33
  import { Stdio } from "../../Stdio.ts"
@@ -635,7 +636,7 @@ export const make: <Rpcs extends Rpc.Any>(
635
636
  Effect.flatMap((a) => send(client.id, onSuccess(a), collector && collector.clearUnsafe())),
636
637
  Effect.catchCause((cause) => {
637
638
  client.schemas.delete(requestId)
638
- const defect = Cause.squash(Cause.map(cause, (e) => e.issue.toString()))
639
+ const defect = Cause.squash(Cause.map(cause, (e) => SchemaIssue.defaultFormatter(e.issue)))
639
640
  return Effect.andThen(
640
641
  sendRequestDefect(client, requestId, encodeDefect, defect),
641
642
  server.write(client.id, { _tag: "Interrupt", requestId, interruptors: [] })
@@ -708,7 +709,8 @@ export const make: <Rpcs extends Rpc.Any>(
708
709
  return Effect.matchEffect(
709
710
  Effect.provideContext(schemas.decode(request.payload), schemas.context),
710
711
  {
711
- onFailure: (error) => sendRequestDefect(client, requestId, schemas.encodeDefect, error.issue.toString()),
712
+ onFailure: (error) =>
713
+ sendRequestDefect(client, requestId, schemas.encodeDefect, SchemaIssue.defaultFormatter(error.issue)),
712
714
  onSuccess: (payload) => {
713
715
  client.schemas.set(
714
716
  requestId,
@@ -134,7 +134,8 @@ export const ordered = <Req extends Schema.Constraint, Res extends Schema.Constr
134
134
  key: transactionKey,
135
135
  resolver: Effect.fnUntraced(function*(entries) {
136
136
  const [inputs, encodedEntries] = yield* partitionRequests(entries, options.Request)
137
- const results = yield* options.execute(inputs as any).pipe(
137
+ if (!Arr.isArrayNonEmpty(inputs)) return
138
+ const results = yield* options.execute(inputs).pipe(
138
139
  Effect.provideContext(entries[0].context)
139
140
  )
140
141
  if (results.length !== inputs.length) {
@@ -190,8 +191,9 @@ export const grouped = <Req extends Schema.Constraint, Res extends Schema.Constr
190
191
  key: transactionKey,
191
192
  resolver: Effect.fnUntraced(function*(entries) {
192
193
  const [inputs] = yield* partitionRequests(entries, options.Request)
194
+ if (!Arr.isArrayNonEmpty(inputs)) return
193
195
  const resultMap = MutableHashMap.empty<K, Arr.NonEmptyArray<Res["Type"]>>()
194
- const results = yield* options.execute(inputs as any).pipe(
196
+ const results = yield* options.execute(inputs).pipe(
195
197
  Effect.provideContext(entries[0].context)
196
198
  )
197
199
  const decodedResults = yield* decodeResults(results).pipe(
@@ -258,7 +260,8 @@ export const findById = <Id extends Schema.Constraint, Res extends Schema.Constr
258
260
  key: transactionKey,
259
261
  resolver: Effect.fnUntraced(function*(entries) {
260
262
  const [inputs, idMap] = yield* partitionRequestsById(entries, options.Id)
261
- const results = yield* options.execute(inputs as any).pipe(
263
+ if (!Arr.isArrayNonEmpty(inputs)) return
264
+ const results = yield* options.execute(inputs).pipe(
262
265
  Effect.provideContext(entries[0].context)
263
266
  )
264
267
  const decodedResults = yield* decodeResults(results).pipe(
@@ -311,7 +314,8 @@ const void_ = <Req extends Schema.Constraint, _, E, R>(
311
314
  key: transactionKey,
312
315
  resolver: Effect.fnUntraced(function*(entries) {
313
316
  const [inputs] = yield* partitionRequests(entries, options.Request)
314
- yield* options.execute(inputs as any).pipe(
317
+ if (!Arr.isArrayNonEmpty(inputs)) return
318
+ yield* options.execute(inputs).pipe(
315
319
  Effect.provideContext(entries[0].context)
316
320
  )
317
321
  for (let i = 0; i < entries.length; i++) {
@@ -366,35 +370,39 @@ const partitionRequestsById = function*<In, A, E, R, InE>(
366
370
  const len = requests.length
367
371
  const inputs = Arr.empty<InE>()
368
372
  const byIdMap = MutableHashMap.empty<In, Request.Entry<SqlRequest<In, A, E, R>>>()
369
- let entry!: Request.Entry<SqlRequest<In, A, E, R>>
370
- const encode = Schema.encodeEffect(schema)
371
- const handle = Effect.matchCauseEager({
372
- onFailure(cause: Cause.Cause<Schema.SchemaError>) {
373
- entry.completeUnsafe(Exit.failCause(cause))
374
- },
375
- onSuccess(value: InE) {
376
- inputs.push(value)
377
- }
378
- })
379
373
 
380
374
  for (let i = 0; i < len; i++) {
381
- entry = requests[i]
375
+ const entry = requests[i]
382
376
  const existing = MutableHashMap.get(byIdMap, entry.request.payload)
383
377
  if (Option.isSome(existing)) {
384
- const duplicate = entry
378
+ const previous = existing.value
385
379
  MutableHashMap.set(byIdMap, entry.request.payload, {
386
- ...existing.value,
380
+ ...previous,
387
381
  completeUnsafe(exit) {
388
- existing.value.completeUnsafe(exit)
389
- duplicate.completeUnsafe(exit)
382
+ previous.completeUnsafe(exit)
383
+ entry.completeUnsafe(exit)
390
384
  }
391
385
  })
392
386
  } else {
393
- yield (Effect.provideContext(handle(encode(entry.request.payload)), entry.context) as Effect.Effect<void>)
394
387
  MutableHashMap.set(byIdMap, entry.request.payload, entry)
395
388
  }
396
389
  }
397
390
 
391
+ const encode = Schema.encodeEffect(schema)
392
+ for (const [, entry] of byIdMap) {
393
+ yield* Effect.provideContext(
394
+ Effect.matchCauseEager(encode(entry.request.payload), {
395
+ onFailure(cause) {
396
+ entry.completeUnsafe(Exit.failCause(cause))
397
+ },
398
+ onSuccess(value) {
399
+ inputs.push(value)
400
+ }
401
+ }),
402
+ entry.context
403
+ )
404
+ }
405
+
398
406
  return [inputs, byIdMap] as const
399
407
  }
400
408
 
@@ -165,6 +165,17 @@ export const makePlatform = <W>() =>
165
165
  const spawn = (yield* Spawner) as SpawnerFn<W>
166
166
  let currentPort: P | undefined
167
167
  const buffer: Array<[unknown, ReadonlyArray<unknown> | undefined]> = []
168
+ const sendToPort = (port: P, message: unknown, transfers?: ReadonlyArray<unknown>) =>
169
+ Effect.try({
170
+ try: () => port.postMessage([0, message], transfers as any),
171
+ catch: (cause) =>
172
+ new WorkerError({
173
+ reason: new WorkerSendError({
174
+ message: "Failed to send message to worker",
175
+ cause
176
+ })
177
+ })
178
+ })
168
179
 
169
180
  const run = <A, E, R>(
170
181
  handler: (_: O) => Effect.Effect<A, E, R>,
@@ -209,7 +220,7 @@ export const makePlatform = <W>() =>
209
220
  currentPort = port
210
221
  if (buffer.length > 0) {
211
222
  for (const [message, transfers] of buffer) {
212
- port.postMessage([0, message], transfers as any)
223
+ yield* sendToPort(port, message, transfers)
213
224
  }
214
225
  buffer.length = 0
215
226
  }
@@ -224,19 +235,7 @@ export const makePlatform = <W>() =>
224
235
  buffer.push([message, transfers])
225
236
  return Effect.void
226
237
  }
227
- try {
228
- currentPort.postMessage([0, message], transfers as any)
229
- return Effect.void
230
- } catch (cause) {
231
- return Effect.fail(
232
- new WorkerError({
233
- reason: new WorkerSendError({
234
- message: "Failed to send message to worker",
235
- cause
236
- })
237
- })
238
- )
239
- }
238
+ return sendToPort(currentPort, message, transfers)
240
239
  })
241
240
 
242
241
  return { run, send }
@@ -557,16 +557,13 @@ export class Complete<A, E> extends Data.TaggedClass("Complete")<{
557
557
  [Schema.Exit(options.success, options.error, Schema.Defect())],
558
558
  ([exit]) => (input, ast, options) => {
559
559
  if (!(isResult(input) && input._tag === "Complete")) {
560
- return Effect.fail(new SchemaIssue.InvalidType(ast))
560
+ return Effect.fail(new SchemaIssue.InvalidType(ast, input, options))
561
561
  }
562
562
  return Effect.mapBothEager(
563
563
  SchemaParser.decodeEffect(exit)(input.exit, options),
564
564
  {
565
565
  onSuccess: (exit) => new Complete({ exit }),
566
- onFailure: (issue) =>
567
- new SchemaIssue.Composite(ast, [
568
- new SchemaIssue.Pointer(["exit"], issue)
569
- ])
566
+ onFailure: (issue) => SchemaIssue.makeCompositeAtKey(ast, "exit", issue, input, options)
570
567
  }
571
568
  )
572
569
  },