effect 4.0.0-rc.118 → 4.0.1

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 (254) hide show
  1. package/README.md +17 -4
  2. package/dist/Array.d.ts +25 -25
  3. package/dist/Array.d.ts.map +1 -1
  4. package/dist/Array.js +16 -16
  5. package/dist/Array.js.map +1 -1
  6. package/dist/Cache.d.ts.map +1 -1
  7. package/dist/Cache.js +20 -16
  8. package/dist/Cache.js.map +1 -1
  9. package/dist/Cause.d.ts.map +1 -1
  10. package/dist/Cause.js +1 -1
  11. package/dist/Cause.js.map +1 -1
  12. package/dist/Chunk.d.ts +26 -26
  13. package/dist/Chunk.d.ts.map +1 -1
  14. package/dist/Chunk.js +15 -15
  15. package/dist/Chunk.js.map +1 -1
  16. package/dist/Effect.d.ts +167 -39
  17. package/dist/Effect.d.ts.map +1 -1
  18. package/dist/Effect.js +16 -10
  19. package/dist/Effect.js.map +1 -1
  20. package/dist/HashRing.d.ts.map +1 -1
  21. package/dist/HashRing.js +13 -5
  22. package/dist/HashRing.js.map +1 -1
  23. package/dist/MutableHashMap.d.ts.map +1 -1
  24. package/dist/MutableHashMap.js +4 -22
  25. package/dist/MutableHashMap.js.map +1 -1
  26. package/dist/Option.d.ts +17 -17
  27. package/dist/Option.d.ts.map +1 -1
  28. package/dist/Option.js +6 -6
  29. package/dist/Option.js.map +1 -1
  30. package/dist/Pool.d.ts +9 -5
  31. package/dist/Pool.d.ts.map +1 -1
  32. package/dist/Pool.js +34 -41
  33. package/dist/Pool.js.map +1 -1
  34. package/dist/Queue.d.ts +19 -2
  35. package/dist/Queue.d.ts.map +1 -1
  36. package/dist/Queue.js +9 -4
  37. package/dist/Queue.js.map +1 -1
  38. package/dist/RcMap.d.ts.map +1 -1
  39. package/dist/RcMap.js +16 -1
  40. package/dist/RcMap.js.map +1 -1
  41. package/dist/Record.d.ts +14 -14
  42. package/dist/Record.d.ts.map +1 -1
  43. package/dist/Record.js +10 -10
  44. package/dist/Record.js.map +1 -1
  45. package/dist/Schema.d.ts +37 -21
  46. package/dist/Schema.d.ts.map +1 -1
  47. package/dist/Schema.js +29 -10
  48. package/dist/Schema.js.map +1 -1
  49. package/dist/SchemaAST.d.ts.map +1 -1
  50. package/dist/SchemaAST.js +116 -97
  51. package/dist/SchemaAST.js.map +1 -1
  52. package/dist/SchemaRepresentation.d.ts +3 -1
  53. package/dist/SchemaRepresentation.d.ts.map +1 -1
  54. package/dist/SchemaRepresentation.js +3 -1
  55. package/dist/SchemaRepresentation.js.map +1 -1
  56. package/dist/ScopedCache.d.ts.map +1 -1
  57. package/dist/ScopedCache.js +24 -16
  58. package/dist/ScopedCache.js.map +1 -1
  59. package/dist/Stream.d.ts +45 -6
  60. package/dist/Stream.d.ts.map +1 -1
  61. package/dist/Stream.js +55 -44
  62. package/dist/Stream.js.map +1 -1
  63. package/dist/ai/LanguageModel.d.ts +8 -0
  64. package/dist/ai/LanguageModel.d.ts.map +1 -1
  65. package/dist/ai/LanguageModel.js +13 -2
  66. package/dist/ai/LanguageModel.js.map +1 -1
  67. package/dist/ai/McpSchema.d.ts +402 -402
  68. package/dist/ai/McpSchema.d.ts.map +1 -1
  69. package/dist/ai/McpSchema.js +1 -1
  70. package/dist/ai/McpSchema.js.map +1 -1
  71. package/dist/ai/McpServer.d.ts.map +1 -1
  72. package/dist/ai/McpServer.js +11 -3
  73. package/dist/ai/McpServer.js.map +1 -1
  74. package/dist/ai/Response.d.ts.map +1 -1
  75. package/dist/ai/Response.js +22 -12
  76. package/dist/ai/Response.js.map +1 -1
  77. package/dist/ai/internal/mcpProtocol/v2024_11_05.js +1 -0
  78. package/dist/ai/internal/mcpProtocol/v2024_11_05.js.map +1 -1
  79. package/dist/ai/internal/mcpProtocol/v2025_03_26.js +1 -0
  80. package/dist/ai/internal/mcpProtocol/v2025_03_26.js.map +1 -1
  81. package/dist/ai/internal/mcpProtocol/v2025_06_18.js +1 -0
  82. package/dist/ai/internal/mcpProtocol/v2025_06_18.js.map +1 -1
  83. package/dist/ai/internal/mcpProtocol/v2025_11_25.js +1 -0
  84. package/dist/ai/internal/mcpProtocol/v2025_11_25.js.map +1 -1
  85. package/dist/ai/internal/mcpSchema/v2024_11_05.js +3 -1
  86. package/dist/ai/internal/mcpSchema/v2024_11_05.js.map +1 -1
  87. package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
  88. package/dist/cluster/ClusterWorkflowEngine.js +16 -3
  89. package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
  90. package/dist/cluster/MessageStorage.d.ts +32 -8
  91. package/dist/cluster/MessageStorage.d.ts.map +1 -1
  92. package/dist/cluster/MessageStorage.js +2 -1
  93. package/dist/cluster/MessageStorage.js.map +1 -1
  94. package/dist/cluster/Sharding.d.ts +5 -2
  95. package/dist/cluster/Sharding.d.ts.map +1 -1
  96. package/dist/cluster/Sharding.js +15 -8
  97. package/dist/cluster/Sharding.js.map +1 -1
  98. package/dist/cluster/SqlMessageStorage.d.ts.map +1 -1
  99. package/dist/cluster/SqlMessageStorage.js +36 -16
  100. package/dist/cluster/SqlMessageStorage.js.map +1 -1
  101. package/dist/cluster/SqlRunnerStorage.d.ts.map +1 -1
  102. package/dist/cluster/SqlRunnerStorage.js +30 -44
  103. package/dist/cluster/SqlRunnerStorage.js.map +1 -1
  104. package/dist/cluster/internal/entityManager.js +63 -62
  105. package/dist/cluster/internal/entityManager.js.map +1 -1
  106. package/dist/cluster/internal/interruptors.js +8 -0
  107. package/dist/cluster/internal/interruptors.js.map +1 -1
  108. package/dist/cluster/internal/resourceMap.js +39 -14
  109. package/dist/cluster/internal/resourceMap.js.map +1 -1
  110. package/dist/cluster/internal/resourceRef.js +168 -87
  111. package/dist/cluster/internal/resourceRef.js.map +1 -1
  112. package/dist/http/HttpEffect.d.ts +1 -0
  113. package/dist/http/HttpEffect.d.ts.map +1 -1
  114. package/dist/http/HttpEffect.js +29 -22
  115. package/dist/http/HttpEffect.js.map +1 -1
  116. package/dist/http/HttpMiddleware.d.ts.map +1 -1
  117. package/dist/http/HttpMiddleware.js +3 -2
  118. package/dist/http/HttpMiddleware.js.map +1 -1
  119. package/dist/http/HttpStaticServer.d.ts.map +1 -1
  120. package/dist/http/HttpStaticServer.js +14 -0
  121. package/dist/http/HttpStaticServer.js.map +1 -1
  122. package/dist/http/HttpTraceContext.d.ts +1 -1
  123. package/dist/http/HttpTraceContext.d.ts.map +1 -1
  124. package/dist/http/HttpTraceContext.js +4 -4
  125. package/dist/http/HttpTraceContext.js.map +1 -1
  126. package/dist/http-api/HttpApiError.d.ts +1 -0
  127. package/dist/http-api/HttpApiError.d.ts.map +1 -1
  128. package/dist/http-api/HttpApiError.js +1 -0
  129. package/dist/http-api/HttpApiError.js.map +1 -1
  130. package/dist/internal/core.js +43 -2
  131. package/dist/internal/core.js.map +1 -1
  132. package/dist/internal/dateTime.js +1 -1
  133. package/dist/internal/dateTime.js.map +1 -1
  134. package/dist/internal/effect.js +138 -165
  135. package/dist/internal/effect.js.map +1 -1
  136. package/dist/internal/rcRef.js +59 -23
  137. package/dist/internal/rcRef.js.map +1 -1
  138. package/dist/internal/schema/annotations.js +1 -7
  139. package/dist/internal/schema/annotations.js.map +1 -1
  140. package/dist/internal/schema/codegen.js +56 -28
  141. package/dist/internal/schema/codegen.js.map +1 -1
  142. package/dist/internal/schema/fromJsonSchemaDocument.js +11 -8
  143. package/dist/internal/schema/fromJsonSchemaDocument.js.map +1 -1
  144. package/dist/internal/schema/toCodeDocument.js +10 -30
  145. package/dist/internal/schema/toCodeDocument.js.map +1 -1
  146. package/dist/internal/schema/toCodec.js +1 -15
  147. package/dist/internal/schema/toCodec.js.map +1 -1
  148. package/dist/internal/schema/toEquivalence.js +4 -3
  149. package/dist/internal/schema/toEquivalence.js.map +1 -1
  150. package/dist/internal/schema/toFormatter.js +4 -4
  151. package/dist/internal/schema/toFormatter.js.map +1 -1
  152. package/dist/reactivity/Atom.d.ts.map +1 -1
  153. package/dist/reactivity/Atom.js +6 -2
  154. package/dist/reactivity/Atom.js.map +1 -1
  155. package/dist/reactivity/AtomRpc.d.ts +3 -3
  156. package/dist/reactivity/AtomRpc.d.ts.map +1 -1
  157. package/dist/rpc/Rpc.d.ts +2 -2
  158. package/dist/rpc/Rpc.d.ts.map +1 -1
  159. package/dist/rpc/RpcClient.d.ts +7 -7
  160. package/dist/rpc/RpcClient.d.ts.map +1 -1
  161. package/dist/rpc/RpcClient.js +21 -16
  162. package/dist/rpc/RpcClient.js.map +1 -1
  163. package/dist/rpc/RpcMessage.d.ts +1 -1
  164. package/dist/rpc/RpcMessage.d.ts.map +1 -1
  165. package/dist/rpc/RpcServer.d.ts.map +1 -1
  166. package/dist/rpc/RpcServer.js +2 -2
  167. package/dist/rpc/RpcServer.js.map +1 -1
  168. package/dist/rpc/Utils.d.ts +2 -3
  169. package/dist/rpc/Utils.d.ts.map +1 -1
  170. package/dist/rpc/Utils.js +3 -4
  171. package/dist/rpc/Utils.js.map +1 -1
  172. package/dist/schema/SchemaCompiler/runtime.js +6 -1
  173. package/dist/schema/SchemaCompiler/runtime.js.map +1 -1
  174. package/dist/testing/TestSchema.d.ts +234 -6
  175. package/dist/testing/TestSchema.d.ts.map +1 -1
  176. package/dist/testing/TestSchema.js +244 -25
  177. package/dist/testing/TestSchema.js.map +1 -1
  178. package/dist/testing/index.d.ts +1 -0
  179. package/dist/testing/index.d.ts.map +1 -1
  180. package/dist/testing/index.js +1 -0
  181. package/dist/testing/index.js.map +1 -1
  182. package/dist/workflow/DurableDeferred.js +1 -1
  183. package/dist/workflow/DurableDeferred.js.map +1 -1
  184. package/dist/workflow/Workflow.js +1 -1
  185. package/dist/workflow/Workflow.js.map +1 -1
  186. package/dist/workflow/WorkflowEngine.d.ts +2 -0
  187. package/dist/workflow/WorkflowEngine.d.ts.map +1 -1
  188. package/dist/workflow/WorkflowEngine.js +1 -0
  189. package/dist/workflow/WorkflowEngine.js.map +1 -1
  190. package/package.json +1 -1
  191. package/src/Array.ts +31 -31
  192. package/src/Cache.ts +22 -16
  193. package/src/Cause.ts +1 -1
  194. package/src/Chunk.ts +29 -29
  195. package/src/Effect.ts +170 -39
  196. package/src/HashRing.ts +14 -5
  197. package/src/MutableHashMap.ts +4 -24
  198. package/src/Option.ts +19 -19
  199. package/src/Pool.ts +28 -36
  200. package/src/Queue.ts +26 -6
  201. package/src/RcMap.ts +26 -2
  202. package/src/Record.ts +20 -20
  203. package/src/Schema.ts +48 -24
  204. package/src/SchemaAST.ts +135 -115
  205. package/src/SchemaRepresentation.ts +3 -1
  206. package/src/ScopedCache.ts +27 -16
  207. package/src/Stream.ts +158 -88
  208. package/src/ai/LanguageModel.ts +27 -2
  209. package/src/ai/McpSchema.ts +3 -3
  210. package/src/ai/McpServer.ts +12 -3
  211. package/src/ai/Response.ts +27 -12
  212. package/src/ai/internal/mcpProtocol/v2024_11_05.ts +1 -0
  213. package/src/ai/internal/mcpProtocol/v2025_03_26.ts +1 -0
  214. package/src/ai/internal/mcpProtocol/v2025_06_18.ts +1 -0
  215. package/src/ai/internal/mcpProtocol/v2025_11_25.ts +1 -0
  216. package/src/ai/internal/mcpSchema/v2024_11_05.ts +4 -2
  217. package/src/cluster/ClusterWorkflowEngine.ts +26 -5
  218. package/src/cluster/MessageStorage.ts +22 -5
  219. package/src/cluster/Sharding.ts +32 -28
  220. package/src/cluster/SqlMessageStorage.ts +45 -21
  221. package/src/cluster/SqlRunnerStorage.ts +85 -113
  222. package/src/cluster/internal/entityManager.ts +68 -80
  223. package/src/cluster/internal/interruptors.ts +13 -0
  224. package/src/cluster/internal/resourceMap.ts +55 -17
  225. package/src/cluster/internal/resourceRef.ts +189 -96
  226. package/src/http/HttpEffect.ts +15 -9
  227. package/src/http/HttpMiddleware.ts +8 -2
  228. package/src/http/HttpStaticServer.ts +16 -0
  229. package/src/http/HttpTraceContext.ts +8 -4
  230. package/src/http-api/HttpApiError.ts +1 -0
  231. package/src/internal/core.ts +56 -2
  232. package/src/internal/dateTime.ts +3 -1
  233. package/src/internal/effect.ts +146 -173
  234. package/src/internal/rcRef.ts +83 -33
  235. package/src/internal/schema/annotations.ts +0 -9
  236. package/src/internal/schema/codegen.ts +90 -43
  237. package/src/internal/schema/fromJsonSchemaDocument.ts +5 -3
  238. package/src/internal/schema/toCodeDocument.ts +10 -47
  239. package/src/internal/schema/toCodec.ts +3 -16
  240. package/src/internal/schema/toEquivalence.ts +4 -5
  241. package/src/internal/schema/toFormatter.ts +4 -6
  242. package/src/reactivity/Atom.ts +6 -2
  243. package/src/reactivity/AtomRpc.ts +5 -5
  244. package/src/rpc/Rpc.ts +2 -2
  245. package/src/rpc/RpcClient.ts +35 -32
  246. package/src/rpc/RpcMessage.ts +1 -1
  247. package/src/rpc/RpcServer.ts +2 -1
  248. package/src/rpc/Utils.ts +4 -10
  249. package/src/schema/SchemaCompiler/runtime.ts +17 -1
  250. package/src/testing/TestSchema.ts +315 -63
  251. package/src/testing/index.ts +1 -0
  252. package/src/workflow/DurableDeferred.ts +1 -1
  253. package/src/workflow/Workflow.ts +1 -1
  254. package/src/workflow/WorkflowEngine.ts +4 -0
@@ -1453,8 +1453,9 @@ function makeResultFn<Arg, E, A>(
1453
1453
  Effect.forkDetach(eff, { startImmediately: true }),
1454
1454
  (fiber) => {
1455
1455
  fibers.add(fiber)
1456
+ const runningFibers = Array.from(fibers)
1456
1457
  fiber.addObserver(() => fibers.delete(fiber))
1457
- return Effect.map(Fiber.joinAll(fibers), (arr) => arr[0])
1458
+ return Effect.map(Fiber.joinAll(runningFibers), (arr) => arr[0])
1458
1459
  }
1459
1460
  )
1460
1461
  }
@@ -1619,7 +1620,10 @@ export const family = typeof WeakRef === "undefined" || typeof FinalizationRegis
1619
1620
  ): (arg: Arg) => T => {
1620
1621
  const atoms = MutableHashMap.empty<Arg, WeakRef<T>>()
1621
1622
  const registry = new FinalizationRegistry<Arg>((arg) => {
1622
- MutableHashMap.remove(atoms, arg)
1623
+ const entry = MutableHashMap.get(atoms, arg)
1624
+ if (entry._tag === "Some" && entry.value.deref() === undefined) {
1625
+ MutableHashMap.remove(atoms, arg)
1626
+ }
1623
1627
  })
1624
1628
  return function(arg) {
1625
1629
  const atomEntry = MutableHashMap.get(atoms, arg).pipe(
@@ -57,8 +57,8 @@ export interface AtomRpcClient<Self, Id extends string, Rpcs extends Rpc.Any> ex
57
57
 
58
58
  readonly mutation: <Tag extends Rpc.Tag<Rpcs>>(
59
59
  arg: Tag
60
- ) => Rpc.ExtractTag<Rpcs, Tag> extends Rpc.Rpc<
61
- infer _Tag,
60
+ ) => Rpcs extends Rpc.Rpc<
61
+ infer _Tag extends Tag,
62
62
  infer _Payload,
63
63
  infer _Success,
64
64
  infer _Error,
@@ -67,7 +67,7 @@ export interface AtomRpcClient<Self, Id extends string, Rpcs extends Rpc.Any> ex
67
67
  > ? [_Success] extends [RpcSchema.Stream<infer _A, infer _E>] ? never
68
68
  : Atom.AtomResultFn<
69
69
  {
70
- readonly payload: Rpc.PayloadConstructor<Rpc.ExtractTag<Rpcs, Tag>>
70
+ readonly payload: Rpc.PayloadConstructor<Rpcs>
71
71
  readonly reactivityKeys?:
72
72
  | ReadonlyArray<unknown>
73
73
  | ReadonlyRecord<string, ReadonlyArray<unknown>>
@@ -91,8 +91,8 @@ export interface AtomRpcClient<Self, Id extends string, Rpcs extends Rpc.Any> ex
91
91
  readonly timeToLive?: Duration.Input | undefined
92
92
  readonly serializationKey?: string | undefined
93
93
  }
94
- ) => Rpc.ExtractTag<Rpcs, Tag> extends Rpc.Rpc<
95
- infer _Tag,
94
+ ) => Rpcs extends Rpc.Rpc<
95
+ infer _Tag extends Tag,
96
96
  infer _Payload,
97
97
  infer _Success,
98
98
  infer _Error,
package/src/rpc/Rpc.ts CHANGED
@@ -687,14 +687,14 @@ export type IsStream<R extends Any, Tag extends string> = R extends Rpc<
687
687
  never
688
688
 
689
689
  /**
690
- * Extracts the RPC with the specified tag from an RPC union.
690
+ * Extracts RPCs whose tags match the given tag or union of tags.
691
691
  *
692
692
  * @stability unstable
693
693
  * @category utility types
694
694
  * @since 4.0.0
695
695
  */
696
696
  export type ExtractTag<R extends Any, Tag extends string> = R extends Rpc<
697
- Tag,
697
+ infer _Tag extends Tag,
698
698
  infer _Payload,
699
699
  infer _Success,
700
700
  infer _Error,
@@ -166,8 +166,8 @@ export declare namespace RpcClient {
166
166
  readonly context?: Context.Context<never> | undefined
167
167
  readonly discard?: Discard | undefined
168
168
  }
169
- ) => Rpc.ExtractTag<Rpcs, Tag> extends Rpc.Rpc<
170
- infer _Tag,
169
+ ) => Rpcs extends Rpc.Rpc<
170
+ infer _Tag extends Tag,
171
171
  infer _Payload,
172
172
  infer _Success,
173
173
  infer _Error,
@@ -454,9 +454,11 @@ export const makeNoSerialization: <Rpcs extends Rpc.Any, E, const Flatten extend
454
454
  const id = generateRequestId()
455
455
 
456
456
  const scope = Context.getUnsafe(fiber.context, Scope.Scope)
457
+ const queue = yield* Queue.bounded<any, any>(streamBufferSize)
457
458
  yield* Scope.addFinalizerExit(
458
459
  scope,
459
460
  (exit) => {
461
+ Queue.shutdownUnsafe(queue)
460
462
  if (!entries.has(id)) return Effect.void
461
463
  entries.delete(id)
462
464
  return sendInterrupt(
@@ -469,7 +471,6 @@ export const makeNoSerialization: <Rpcs extends Rpc.Any, E, const Flatten extend
469
471
  }
470
472
  )
471
473
 
472
- const queue = yield* Queue.bounded<any, any>(streamBufferSize)
473
474
  entries.set(id, {
474
475
  _tag: "Queue",
475
476
  rpc,
@@ -671,6 +672,12 @@ export const make: <Rpcs extends Rpc.Any, const Flatten extends boolean = false>
671
672
  }
672
673
  const entries = new Map<RequestId, ClientEntry>()
673
674
 
675
+ const interruptRequest = (requestId: RequestId): Effect.Effect<void, RpcClientError> => {
676
+ if (!entries.has(requestId)) return Effect.void
677
+ entries.delete(requestId)
678
+ return send(clientId, { _tag: "Interrupt", requestId }) as Effect.Effect<void, RpcClientError>
679
+ }
680
+
674
681
  const { client, write } = yield* makeNoSerialization(group, {
675
682
  ...options,
676
683
  supportsAck,
@@ -711,13 +718,7 @@ export const make: <Rpcs extends Rpc.Any, const Flatten extends boolean = false>
711
718
  }) as Effect.Effect<void, RpcClientError>
712
719
  }
713
720
  case "Interrupt": {
714
- const entry = entries.get(message.requestId)
715
- if (!entry) return Effect.void
716
- entries.delete(message.requestId)
717
- return send(clientId, {
718
- _tag: "Interrupt",
719
- requestId: message.requestId
720
- }) as Effect.Effect<void, RpcClientError>
721
+ return interruptRequest(message.requestId)
721
722
  }
722
723
  case "Eof": {
723
724
  return Effect.void
@@ -732,19 +733,22 @@ export const make: <Rpcs extends Rpc.Any, const Flatten extends boolean = false>
732
733
  const requestId = RequestId(message.requestId)
733
734
  const entry = entries.get(requestId)
734
735
  if (!entry || Option.isNone(entry.schemas.decodeChunk)) return Effect.void
735
- return entry.schemas.decodeChunk.value(message.values).pipe(
736
- Effect.provideContext(entry.context),
737
- Effect.orDie,
738
- Effect.flatMap((chunk) =>
739
- write({ _tag: "Chunk", clientId: 0, requestId: RequestId(message.requestId), values: chunk })
740
- ),
741
- Effect.onError((cause) =>
742
- write({
743
- _tag: "Exit",
744
- clientId: 0,
745
- requestId: RequestId(message.requestId),
746
- exit: Exit.failCause(cause)
747
- })
736
+ const decodeChunk = entry.schemas.decodeChunk.value
737
+ return Effect.uninterruptibleMask((restore) =>
738
+ restore(
739
+ decodeChunk(message.values).pipe(
740
+ Effect.provideContext(entry.context),
741
+ Effect.orDie,
742
+ Effect.flatMap((chunk) => write({ _tag: "Chunk", clientId: 0, requestId, values: chunk }))
743
+ )
744
+ ).pipe(
745
+ Effect.onError((cause) =>
746
+ write({ _tag: "Exit", clientId: 0, requestId, exit: Exit.failCause(cause) }).pipe(
747
+ Effect.andThen(Cause.hasInterrupts(cause) ? Effect.void : Effect.ignore(interruptRequest(requestId)))
748
+ )
749
+ ),
750
+ // a decode failure only ends its own request; interruption still propagates
751
+ Effect.catchCauseIf((cause) => !Cause.hasInterrupts(cause), () => Effect.void)
748
752
  )
749
753
  ) as Effect.Effect<void>
750
754
  }
@@ -768,7 +772,7 @@ export const make: <Rpcs extends Rpc.Any, const Flatten extends boolean = false>
768
772
  case "ClientProtocolError": {
769
773
  const exit = Exit.fail(message.error)
770
774
  return Effect.forEach(
771
- entries.keys(),
775
+ Array.from(entries.keys()),
772
776
  (requestId) => write({ _tag: "Exit", clientId: 0, requestId, exit: exit as any })
773
777
  )
774
778
  }
@@ -1051,9 +1055,9 @@ export const makeProtocolSocket = (options?: {
1051
1055
  readonly retryPolicy?: Schedule.Schedule<any, Socket.SocketError> | undefined
1052
1056
  /**
1053
1057
  * Runs for each retried `SocketOpenError` when `retryTransientErrors` is enabled.
1054
- * Ping timeouts are also reported because the protocol classifies them as
1055
- * `SocketOpenError`. The returned `Effect<void>` cannot fail with a typed error
1056
- * or require services; defects are logged and ignored so retries can continue.
1058
+ * A missed pong fails in-flight calls and is not reported through this hook.
1059
+ * The returned `Effect<void>` cannot fail with a typed error or require
1060
+ * services; defects are logged and ignored so retries can continue.
1057
1061
  */
1058
1062
  readonly onTransientError?: ((error: RpcClientError) => Effect.Effect<void>) | undefined
1059
1063
  }): Effect.Effect<
@@ -1149,8 +1153,7 @@ export const makeProtocolSocket = (options?: {
1149
1153
  () =>
1150
1154
  Effect.fail(
1151
1155
  new Socket.SocketError({
1152
- reason: new Socket.SocketOpenError({
1153
- kind: "Timeout",
1156
+ reason: new Socket.SocketReadError({
1154
1157
  cause: new Error("ping timeout")
1155
1158
  })
1156
1159
  })
@@ -1251,9 +1254,9 @@ export const layerProtocolSocket = (options?: {
1251
1254
  readonly retryTransientErrors?: boolean | undefined
1252
1255
  /**
1253
1256
  * Runs for each retried `SocketOpenError` when `retryTransientErrors` is enabled.
1254
- * Ping timeouts are also reported because the protocol classifies them as
1255
- * `SocketOpenError`. The returned `Effect<void>` cannot fail with a typed error
1256
- * or require services; defects are logged and ignored so retries can continue.
1257
+ * A missed pong fails in-flight calls and is not reported through this hook.
1258
+ * The returned `Effect<void>` cannot fail with a typed error or require
1259
+ * services; defects are logged and ignored so retries can continue.
1257
1260
  */
1258
1261
  readonly onTransientError?: ((error: RpcClientError) => Effect.Effect<void>) | undefined
1259
1262
  }): Layer.Layer<
@@ -297,7 +297,7 @@ export type ExitEncoded<A, E> = {
297
297
  readonly defect: unknown
298
298
  } | {
299
299
  readonly _tag: "Interrupt"
300
- readonly fiberId: number | undefined
300
+ readonly fiberId: number | null | undefined
301
301
  }
302
302
  >
303
303
  }
@@ -1392,13 +1392,14 @@ export const makeProtocolStdio = Effect.gen(function*() {
1392
1392
  Effect.sandbox,
1393
1393
  Effect.tapError(Effect.logError),
1394
1394
  Effect.retry(Schedule.spaced(500)),
1395
- Effect.ensuring(Effect.forkDetach(Fiber.interrupt(fiber), { startImmediately: true })),
1395
+ Effect.andThen(() => writeRequest(0, constEof)),
1396
1396
  Effect.forkScoped
1397
1397
  )
1398
1398
 
1399
1399
  yield* Stream.fromQueue(queue).pipe(
1400
1400
  Stream.run(stdio.stdout()),
1401
1401
  Effect.retry(Schedule.spaced(500)),
1402
+ Effect.ensuring(Effect.forkDetach(Fiber.interrupt(fiber), { startImmediately: true })),
1402
1403
  Effect.forkScoped
1403
1404
  )
1404
1405
 
package/src/rpc/Utils.ts CHANGED
@@ -1,10 +1,5 @@
1
1
  /**
2
- * Helps RPC protocol services buffer messages until their receive loop starts.
3
- *
4
- * Client and server protocol constructors use these helpers to expose a stable
5
- * service before the active receiver is installed. Writes made before `run`
6
- * starts are buffered with their current `Context`, then replayed once the
7
- * receiver is ready.
2
+ * Buffers RPC protocol messages until their receive loop starts.
8
3
  *
9
4
  * @stability unstable
10
5
  * @since 4.0.0
@@ -16,9 +11,8 @@ import type { Protocol } from "./RpcClient.ts"
16
11
  import type { FromServerEncoded } from "./RpcMessage.ts"
17
12
 
18
13
  /**
19
- * Builds a service with a `run` method that buffers writes until `run` installs
20
- * a writer, replays buffered writes with their original contexts, and restores
21
- * the previous writer when the run ends.
14
+ * Buffers writes until `run` replays them with their original contexts and
15
+ * installs the writer. Restores the previous writer when `run` ends.
22
16
  *
23
17
  * @stability unstable
24
18
  * @category services
@@ -43,12 +37,12 @@ export const withRun = <
43
37
  run(f) {
44
38
  return semaphore.withPermits(1)(Effect.gen(function*() {
45
39
  const prev = write
46
- write = f
47
40
 
48
41
  for (const [args, context] of buffer) {
49
42
  yield* Effect.provideContext(Effect.suspend(() => f(...args)), context)
50
43
  }
51
44
  buffer = []
45
+ write = f
52
46
 
53
47
  return yield* Effect.onExit(Effect.never, () => {
54
48
  write = prev
@@ -237,6 +237,21 @@ const invalidEncoding = (
237
237
  ? invalidType(ast, value, options)
238
238
  : Interpreter.wrapEncoding(ast, input, options, invalidType(ast.encoding[index - 1].to, value, options))
239
239
 
240
+ const invalidEncodingChecks = (
241
+ ast: SchemaAST.AST & { readonly encoding: SchemaAST.Encoding },
242
+ input: unknown,
243
+ issues: readonly [SchemaIssue.Issue, ...Array<SchemaIssue.Issue>],
244
+ options: SchemaAST.ParseOptions
245
+ ) => {
246
+ const source = ast.encoding[ast.encoding.length - 1].to
247
+ return Interpreter.wrapEncoding(
248
+ ast,
249
+ input,
250
+ options,
251
+ Effect.fail(new SchemaIssue.Composite(source, issues, input, options))
252
+ )
253
+ }
254
+
240
255
  /**
241
256
  * @internal
242
257
  */
@@ -255,6 +270,7 @@ export const runtime = {
255
270
  die: Effect.die,
256
271
  invalidType,
257
272
  invalidEncoding,
273
+ invalidEncodingChecks,
258
274
  getCheckIssues,
259
275
  check,
260
276
  getExpectedKeys: (ast: SchemaAST.Objects) =>
@@ -262,7 +278,7 @@ export const runtime = {
262
278
  hasExcessProperties,
263
279
  matchesTemplateLiteral: (ast: SchemaAST.TemplateLiteral, input: unknown, options: SchemaAST.ParseOptions) =>
264
280
  typeof input === "string" && ast.matchPart(input, options) !== undefined,
265
- getCandidates: SchemaAST.getCandidates,
281
+ getCandidateIndex: SchemaAST.getCandidateIndex,
266
282
  getIndexSignatureKeys: SchemaAST.getIndexSignatureKeys,
267
283
  parameterFromPropertyKey: SchemaAST.parameterFromPropertyKey,
268
284
  getConstructorDescriptor: SchemaAST.getConstructorDescriptor,