@effect-uai/core 0.12.0 → 0.12.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 (284) hide show
  1. package/dist/{AiError-Bf1pq4BB.d.mts → AiError-eLV9t1lU.d.mts} +12 -16
  2. package/dist/AiError-eLV9t1lU.d.mts.map +1 -0
  3. package/dist/{Audio-CR7CSljJ.d.mts → Audio-60lKKHxS.d.mts} +4 -5
  4. package/dist/Audio-60lKKHxS.d.mts.map +1 -0
  5. package/dist/{Image-C4vuBmu0.d.mts → Image-BK8-4H6s.d.mts} +12 -14
  6. package/dist/Image-BK8-4H6s.d.mts.map +1 -0
  7. package/dist/{Items-BKQgqJ8A.d.mts → Items-SfUabNuB.d.mts} +74 -76
  8. package/dist/Items-SfUabNuB.d.mts.map +1 -0
  9. package/dist/{Loop-D8nWpowc.d.mts → Loop-B54AB1ME.d.mts} +19 -21
  10. package/dist/Loop-B54AB1ME.d.mts.map +1 -0
  11. package/dist/{Media-D_CpcM1Z.d.mts → Media-DwgpifPD.d.mts} +1 -1
  12. package/dist/Media-DwgpifPD.d.mts.map +1 -0
  13. package/dist/{SandboxError-CIrVDOMV.d.mts → SandboxError-BN8b28Bh.d.mts} +11 -15
  14. package/dist/SandboxError-BN8b28Bh.d.mts.map +1 -0
  15. package/dist/{StructuredFormat-DHaUJBdd.d.mts → StructuredFormat-BlZhyOsi.d.mts} +3 -7
  16. package/dist/StructuredFormat-BlZhyOsi.d.mts.map +1 -0
  17. package/dist/{Tool-u5bag8SO.d.mts → Tool-DE-rnvkw.d.mts} +5 -8
  18. package/dist/Tool-DE-rnvkw.d.mts.map +1 -0
  19. package/dist/{ToolEvent-BBfOdhF_.d.mts → ToolEvent-D99MGQYH.d.mts} +56 -63
  20. package/dist/ToolEvent-D99MGQYH.d.mts.map +1 -0
  21. package/dist/{ToolResult-CRpmkBXR.d.mts → ToolResult-Cj8ChodL.d.mts} +49 -54
  22. package/dist/ToolResult-Cj8ChodL.d.mts.map +1 -0
  23. package/dist/{Toolkit-D4mQvhjq.d.mts → Toolkit-BEZrNPTI.d.mts} +13 -16
  24. package/dist/Toolkit-BEZrNPTI.d.mts.map +1 -0
  25. package/dist/browser/Browser.d.mts +11 -7
  26. package/dist/browser/Browser.d.mts.map +1 -1
  27. package/dist/browser/Browser.mjs +1 -1
  28. package/dist/browser/Browser.mjs.map +1 -1
  29. package/dist/browser/BrowserError.d.mts +9 -13
  30. package/dist/browser/BrowserError.d.mts.map +1 -1
  31. package/dist/browser/BrowserError.mjs +1 -1
  32. package/dist/browser/BrowserError.mjs.map +1 -1
  33. package/dist/browser/BrowserTool.d.mts +33 -36
  34. package/dist/browser/BrowserTool.d.mts.map +1 -1
  35. package/dist/browser/BrowserTool.mjs +1 -1
  36. package/dist/browser/BrowserTool.mjs.map +1 -1
  37. package/dist/capabilities/Capabilities.d.mts +8 -6
  38. package/dist/capabilities/Capabilities.d.mts.map +1 -1
  39. package/dist/capabilities/Capabilities.mjs +1 -1
  40. package/dist/capabilities/Capabilities.mjs.map +1 -1
  41. package/dist/dist-BaenoU1A.mjs +145 -0
  42. package/dist/dist-BaenoU1A.mjs.map +1 -0
  43. package/dist/{dist-C0m0QnUP.mjs → dist-nohcnkD6.mjs} +16 -15
  44. package/dist/dist-nohcnkD6.mjs.map +1 -0
  45. package/dist/domain/AiError.d.mts +1 -1
  46. package/dist/domain/AiError.mjs +1 -1
  47. package/dist/domain/AiError.mjs.map +1 -1
  48. package/dist/domain/Audio.d.mts +1 -1
  49. package/dist/domain/Audio.mjs +1 -1
  50. package/dist/domain/Citation.d.mts +0 -2
  51. package/dist/domain/Citation.d.mts.map +1 -1
  52. package/dist/domain/Citation.mjs +1 -1
  53. package/dist/domain/Image.d.mts +1 -1
  54. package/dist/domain/Image.mjs +1 -1
  55. package/dist/domain/Image.mjs.map +1 -1
  56. package/dist/domain/Items.d.mts +1 -1
  57. package/dist/domain/Items.mjs +1 -1
  58. package/dist/domain/Items.mjs.map +1 -1
  59. package/dist/domain/Media.d.mts +1 -1
  60. package/dist/domain/Media.mjs +1 -1
  61. package/dist/domain/Music.d.mts +18 -11
  62. package/dist/domain/Music.d.mts.map +1 -1
  63. package/dist/domain/Music.mjs +1 -1
  64. package/dist/domain/Music.mjs.map +1 -1
  65. package/dist/domain/Research.d.mts +3 -4
  66. package/dist/domain/Research.d.mts.map +1 -1
  67. package/dist/domain/Research.mjs +1 -1
  68. package/dist/domain/Transcript.d.mts +2 -3
  69. package/dist/domain/Transcript.d.mts.map +1 -1
  70. package/dist/domain/Transcript.mjs +1 -1
  71. package/dist/domain/Turn.d.mts +143 -164
  72. package/dist/domain/Turn.d.mts.map +1 -1
  73. package/dist/domain/Turn.mjs +1 -1
  74. package/dist/domain/Turn.mjs.map +1 -1
  75. package/dist/domain/Turn.test.d.mts +1 -1
  76. package/dist/domain/Turn.test.mjs +28 -18
  77. package/dist/domain/Turn.test.mjs.map +1 -1
  78. package/dist/embedding-model/Embedding.d.mts +1 -3
  79. package/dist/embedding-model/Embedding.d.mts.map +1 -1
  80. package/dist/embedding-model/Embedding.mjs +1 -1
  81. package/dist/embedding-model/EmbeddingModel.d.mts +1 -3
  82. package/dist/embedding-model/EmbeddingModel.d.mts.map +1 -1
  83. package/dist/embedding-model/EmbeddingModel.mjs +1 -1
  84. package/dist/embedding-model/EmbeddingModel.mjs.map +1 -1
  85. package/dist/embedding-model/EmbeddingModel.test.d.mts +1 -1
  86. package/dist/embedding-model/EmbeddingModel.test.mjs +14 -9
  87. package/dist/embedding-model/EmbeddingModel.test.mjs.map +1 -1
  88. package/dist/index.d.mts +12 -12
  89. package/dist/job/Job.d.mts +4 -4
  90. package/dist/job/Job.d.mts.map +1 -1
  91. package/dist/job/Job.mjs +1 -1
  92. package/dist/job/Job.mjs.map +1 -1
  93. package/dist/language-model/LanguageModel.d.mts +4 -6
  94. package/dist/language-model/LanguageModel.d.mts.map +1 -1
  95. package/dist/language-model/LanguageModel.mjs +1 -1
  96. package/dist/language-model/LanguageModel.mjs.map +1 -1
  97. package/dist/language-model/LanguageModel.test.d.mts +1 -1
  98. package/dist/language-model/LanguageModel.test.mjs +6 -3
  99. package/dist/language-model/LanguageModel.test.mjs.map +1 -1
  100. package/dist/loop/Loop.d.mts +1 -1
  101. package/dist/loop/Loop.mjs +1 -1
  102. package/dist/loop/Loop.mjs.map +1 -1
  103. package/dist/loop/Loop.test.d.mts +1 -1
  104. package/dist/loop/Loop.test.mjs +60 -34
  105. package/dist/loop/Loop.test.mjs.map +1 -1
  106. package/dist/{magic-string.es-Dk-MMA0F.mjs → magic-string.es-CB2hOw9v.mjs} +14 -13
  107. package/dist/{magic-string.es-Dk-MMA0F.mjs.map → magic-string.es-CB2hOw9v.mjs.map} +1 -1
  108. package/dist/math/Vector.d.mts +0 -2
  109. package/dist/math/Vector.d.mts.map +1 -1
  110. package/dist/math/Vector.mjs +1 -1
  111. package/dist/math/Vector.mjs.map +1 -1
  112. package/dist/music-generator/MusicGenerator.d.mts +2 -4
  113. package/dist/music-generator/MusicGenerator.d.mts.map +1 -1
  114. package/dist/music-generator/MusicGenerator.mjs +1 -1
  115. package/dist/music-generator/MusicGenerator.mjs.map +1 -1
  116. package/dist/music-generator/MusicGenerator.test.d.mts +1 -1
  117. package/dist/music-generator/MusicGenerator.test.mjs +19 -10
  118. package/dist/music-generator/MusicGenerator.test.mjs.map +1 -1
  119. package/dist/observability/Metrics.d.mts +10 -7
  120. package/dist/observability/Metrics.d.mts.map +1 -1
  121. package/dist/observability/Metrics.mjs +1 -1
  122. package/dist/observability/Metrics.mjs.map +1 -1
  123. package/dist/observability/Metrics.test.d.mts +1 -1
  124. package/dist/observability/Metrics.test.mjs +50 -28
  125. package/dist/observability/Metrics.test.mjs.map +1 -1
  126. package/dist/observability/Telemetry.d.mts +2 -3
  127. package/dist/observability/Telemetry.d.mts.map +1 -1
  128. package/dist/observability/Telemetry.mjs +1 -1
  129. package/dist/observability/Telemetry.mjs.map +1 -1
  130. package/dist/observability/Telemetry.test.d.mts +1 -1
  131. package/dist/observability/Telemetry.test.mjs +15 -7
  132. package/dist/observability/Telemetry.test.mjs.map +1 -1
  133. package/dist/research/DeepResearch.d.mts +1 -3
  134. package/dist/research/DeepResearch.d.mts.map +1 -1
  135. package/dist/research/DeepResearch.mjs +1 -1
  136. package/dist/research/DeepResearch.mjs.map +1 -1
  137. package/dist/retry/Retry.d.mts +2 -6
  138. package/dist/retry/Retry.d.mts.map +1 -1
  139. package/dist/retry/Retry.mjs +1 -1
  140. package/dist/retry/Retry.mjs.map +1 -1
  141. package/dist/retry/Retry.test.d.mts +1 -1
  142. package/dist/retry/Retry.test.mjs +6 -3
  143. package/dist/retry/Retry.test.mjs.map +1 -1
  144. package/dist/sandbox/Memory.d.mts +0 -2
  145. package/dist/sandbox/Memory.d.mts.map +1 -1
  146. package/dist/sandbox/Memory.mjs +4 -4
  147. package/dist/sandbox/Memory.mjs.map +1 -1
  148. package/dist/sandbox/Sandbox.d.mts +144 -156
  149. package/dist/sandbox/Sandbox.d.mts.map +1 -1
  150. package/dist/sandbox/Sandbox.mjs +1 -1
  151. package/dist/sandbox/Sandbox.mjs.map +1 -1
  152. package/dist/sandbox/SandboxError.d.mts +1 -1
  153. package/dist/sandbox/SandboxError.mjs +1 -1
  154. package/dist/sandbox/SandboxError.mjs.map +1 -1
  155. package/dist/sandbox/SandboxImage.d.mts +0 -2
  156. package/dist/sandbox/SandboxImage.d.mts.map +1 -1
  157. package/dist/sandbox/SandboxImage.mjs +1 -1
  158. package/dist/sandbox/SandboxImage.mjs.map +1 -1
  159. package/dist/sandbox/SandboxNetwork.d.mts +0 -2
  160. package/dist/sandbox/SandboxNetwork.d.mts.map +1 -1
  161. package/dist/sandbox/SandboxNetwork.mjs +1 -1
  162. package/dist/sandbox/SandboxNetwork.mjs.map +1 -1
  163. package/dist/speech-synthesizer/SpeechSynthesizer.d.mts +8 -7
  164. package/dist/speech-synthesizer/SpeechSynthesizer.d.mts.map +1 -1
  165. package/dist/speech-synthesizer/SpeechSynthesizer.mjs +1 -1
  166. package/dist/speech-synthesizer/SpeechSynthesizer.mjs.map +1 -1
  167. package/dist/speech-synthesizer/SpeechSynthesizer.test.d.mts +1 -1
  168. package/dist/speech-synthesizer/SpeechSynthesizer.test.mjs +31 -16
  169. package/dist/speech-synthesizer/SpeechSynthesizer.test.mjs.map +1 -1
  170. package/dist/streaming/JSONL.d.mts +1 -5
  171. package/dist/streaming/JSONL.d.mts.map +1 -1
  172. package/dist/streaming/JSONL.mjs +1 -1
  173. package/dist/streaming/JSONL.mjs.map +1 -1
  174. package/dist/streaming/JSONL.test.d.mts +1 -1
  175. package/dist/streaming/JSONL.test.mjs +16 -8
  176. package/dist/streaming/JSONL.test.mjs.map +1 -1
  177. package/dist/streaming/Lines.d.mts +0 -2
  178. package/dist/streaming/Lines.d.mts.map +1 -1
  179. package/dist/streaming/Lines.mjs +1 -1
  180. package/dist/streaming/Lines.mjs.map +1 -1
  181. package/dist/streaming/SSE.d.mts +0 -2
  182. package/dist/streaming/SSE.d.mts.map +1 -1
  183. package/dist/streaming/SSE.mjs +1 -1
  184. package/dist/streaming/SSE.mjs.map +1 -1
  185. package/dist/streaming/SSE.test.d.mts +1 -1
  186. package/dist/streaming/SSE.test.mjs +34 -17
  187. package/dist/streaming/SSE.test.mjs.map +1 -1
  188. package/dist/structured-format/StructuredFormat.d.mts +1 -1
  189. package/dist/structured-format/StructuredFormat.mjs +1 -1
  190. package/dist/structured-format/StructuredFormat.mjs.map +1 -1
  191. package/dist/structured-format/StructuredFormat.test.d.mts +1 -1
  192. package/dist/structured-format/StructuredFormat.test.mjs +7 -4
  193. package/dist/structured-format/StructuredFormat.test.mjs.map +1 -1
  194. package/dist/{dist-CcRV3-A5.mjs → test.DNmyFkvJ-YPzDR0Co.mjs} +1644 -5172
  195. package/dist/test.DNmyFkvJ-YPzDR0Co.mjs.map +1 -0
  196. package/dist/testing/MockMusicGenerator.d.mts +4 -3
  197. package/dist/testing/MockMusicGenerator.d.mts.map +1 -1
  198. package/dist/testing/MockMusicGenerator.mjs.map +1 -1
  199. package/dist/testing/MockProvider.d.mts +1 -2
  200. package/dist/testing/MockProvider.d.mts.map +1 -1
  201. package/dist/testing/MockProvider.mjs.map +1 -1
  202. package/dist/testing/MockSandbox.d.mts +256 -290
  203. package/dist/testing/MockSandbox.d.mts.map +1 -1
  204. package/dist/testing/MockSandbox.mjs.map +1 -1
  205. package/dist/testing/MockSpeechSynthesizer.d.mts +10 -6
  206. package/dist/testing/MockSpeechSynthesizer.d.mts.map +1 -1
  207. package/dist/testing/MockSpeechSynthesizer.mjs.map +1 -1
  208. package/dist/testing/MockTranscriber.d.mts +3 -2
  209. package/dist/testing/MockTranscriber.d.mts.map +1 -1
  210. package/dist/testing/MockTranscriber.mjs.map +1 -1
  211. package/dist/tool/Approval.d.mts +31 -36
  212. package/dist/tool/Approval.d.mts.map +1 -1
  213. package/dist/tool/Approval.mjs +1 -1
  214. package/dist/tool/Approval.mjs.map +1 -1
  215. package/dist/tool/Approval.test.d.mts +1 -1
  216. package/dist/tool/Approval.test.mjs +37 -24
  217. package/dist/tool/Approval.test.mjs.map +1 -1
  218. package/dist/tool/HistoryCheck.d.mts +2 -4
  219. package/dist/tool/HistoryCheck.d.mts.map +1 -1
  220. package/dist/tool/HistoryCheck.mjs +1 -1
  221. package/dist/tool/HistoryCheck.mjs.map +1 -1
  222. package/dist/tool/Tool.d.mts +1 -1
  223. package/dist/tool/Tool.mjs +4 -4
  224. package/dist/tool/Tool.mjs.map +1 -1
  225. package/dist/tool/Tool.test.d.mts +1 -1
  226. package/dist/tool/Tool.test.mjs +23 -11
  227. package/dist/tool/Tool.test.mjs.map +1 -1
  228. package/dist/tool/ToolEvent.d.mts +1 -1
  229. package/dist/tool/ToolEvent.mjs +1 -1
  230. package/dist/tool/ToolEvent.mjs.map +1 -1
  231. package/dist/tool/ToolResult.d.mts +1 -1
  232. package/dist/tool/ToolResult.mjs +1 -1
  233. package/dist/tool/ToolResult.mjs.map +1 -1
  234. package/dist/tool/Toolkit.d.mts +1 -1
  235. package/dist/tool/Toolkit.mjs +4 -3
  236. package/dist/tool/Toolkit.mjs.map +1 -1
  237. package/dist/tool/Toolkit.test.d.mts +1 -1
  238. package/dist/tool/Toolkit.test.mjs +40 -21
  239. package/dist/tool/Toolkit.test.mjs.map +1 -1
  240. package/dist/transcriber/Transcriber.d.mts +6 -6
  241. package/dist/transcriber/Transcriber.d.mts.map +1 -1
  242. package/dist/transcriber/Transcriber.mjs +1 -1
  243. package/dist/transcriber/Transcriber.mjs.map +1 -1
  244. package/dist/transcriber/Transcriber.test.d.mts +1 -1
  245. package/dist/transcriber/Transcriber.test.mjs +20 -10
  246. package/dist/transcriber/Transcriber.test.mjs.map +1 -1
  247. package/dist/utils-CiH_DjFW.mjs +3918 -0
  248. package/dist/utils-CiH_DjFW.mjs.map +1 -0
  249. package/dist/web-read/WebRead.d.mts +15 -9
  250. package/dist/web-read/WebRead.d.mts.map +1 -1
  251. package/dist/web-read/WebRead.mjs +1 -1
  252. package/dist/web-read/WebRead.mjs.map +1 -1
  253. package/dist/web-read/WebReadTool.d.mts +4 -5
  254. package/dist/web-read/WebReadTool.d.mts.map +1 -1
  255. package/dist/web-read/WebReadTool.mjs +1 -1
  256. package/dist/web-read/WebReadTool.mjs.map +1 -1
  257. package/dist/web-search/WebSearch.d.mts +22 -13
  258. package/dist/web-search/WebSearch.d.mts.map +1 -1
  259. package/dist/web-search/WebSearch.mjs +1 -1
  260. package/dist/web-search/WebSearch.mjs.map +1 -1
  261. package/dist/web-search/WebSearchTool.d.mts +6 -6
  262. package/dist/web-search/WebSearchTool.d.mts.map +1 -1
  263. package/dist/web-search/WebSearchTool.mjs +1 -1
  264. package/dist/web-search/WebSearchTool.mjs.map +1 -1
  265. package/package.json +4 -4
  266. package/src/loop/Loop.test.ts +13 -14
  267. package/src/loop/Loop.ts +74 -76
  268. package/src/testing/MockProvider.ts +8 -9
  269. package/src/tool/Tool.ts +13 -13
  270. package/dist/AiError-Bf1pq4BB.d.mts.map +0 -1
  271. package/dist/Audio-CR7CSljJ.d.mts.map +0 -1
  272. package/dist/Image-C4vuBmu0.d.mts.map +0 -1
  273. package/dist/Items-BKQgqJ8A.d.mts.map +0 -1
  274. package/dist/Loop-D8nWpowc.d.mts.map +0 -1
  275. package/dist/Media-D_CpcM1Z.d.mts.map +0 -1
  276. package/dist/SandboxError-CIrVDOMV.d.mts.map +0 -1
  277. package/dist/StructuredFormat-DHaUJBdd.d.mts.map +0 -1
  278. package/dist/Tool-u5bag8SO.d.mts.map +0 -1
  279. package/dist/ToolEvent-BBfOdhF_.d.mts.map +0 -1
  280. package/dist/ToolResult-CRpmkBXR.d.mts.map +0 -1
  281. package/dist/Toolkit-D4mQvhjq.d.mts.map +0 -1
  282. package/dist/dist-C0m0QnUP.mjs.map +0 -1
  283. package/dist/dist-CcRV3-A5.mjs.map +0 -1
  284. /package/dist/{chunk-uyGKjUfl.mjs → rolldown-runtime-EAsCxrDo.mjs} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"Lines.mjs","names":[],"sources":["../../src/streaming/Lines.ts"],"sourcesContent":["import { Stream } from \"effect\"\n\n/**\n * Split a string stream on `\\n`, emitting one line per element. Buffers\n * partial chunks until a newline arrives, and flushes any non-newline\n * tail at stream end - so streams that don't terminate with `\\n`\n * (typical of LLM token streams) still get their last line. Empty lines\n * are dropped, `\\r` is stripped (handles `\\r\\n` endings).\n *\n * Intended use: feed text deltas from a model that has been prompted to\n * emit JSONL (or any other newline-delimited format), then parse /\n * validate each emitted line.\n */\nexport const lines = <E, R>(self: Stream.Stream<string, E, R>): Stream.Stream<string, E, R> =>\n linesStrict(Stream.concat(self, Stream.make(\"\\n\")))\n\n/**\n * Like `lines`, but only emits lines that were terminated by `\\n`. Any\n * partial trailing content is dropped at stream end. Use when you want\n * strict \"complete-line-or-nothing\" semantics.\n */\nexport const linesStrict = <E, R>(self: Stream.Stream<string, E, R>): Stream.Stream<string, E, R> =>\n self.pipe(\n Stream.mapAccum(\n (): string => \"\",\n (buffer, chunk: string) => {\n const combined = buffer + chunk\n const parts = combined.split(\"\\n\")\n const tail = parts.pop() ?? \"\"\n return [tail, parts.map((line) => line.replace(/\\r/g, \"\"))] as const\n },\n ),\n Stream.filter((line) => line.trim().length > 0),\n )\n"],"mappings":";;;;;;;;;;;;;;;;;;AAaA,MAAa,SAAe,SAC1B,YAAY,OAAO,OAAO,MAAM,OAAO,KAAK,KAAK,CAAC,CAAC;;;;;;AAOrD,MAAa,eAAqB,SAChC,KAAK,KACH,OAAO,eACS,KACb,QAAQ,UAAkB;CAEzB,MAAM,SADW,SAAS,OACH,MAAM,KAAK;AAElC,QAAO,CADM,MAAM,KAAK,IAAI,IACd,MAAM,KAAK,SAAS,KAAK,QAAQ,OAAO,GAAG,CAAC,CAAC;EAE9D,EACD,OAAO,QAAQ,SAAS,KAAK,MAAM,CAAC,SAAS,EAAE,CAChD"}
1
+ {"version":3,"file":"Lines.mjs","names":[],"sources":["../../src/streaming/Lines.ts"],"sourcesContent":["import { Stream } from \"effect\"\n\n/**\n * Split a string stream on `\\n`, emitting one line per element. Buffers\n * partial chunks until a newline arrives, and flushes any non-newline\n * tail at stream end - so streams that don't terminate with `\\n`\n * (typical of LLM token streams) still get their last line. Empty lines\n * are dropped, `\\r` is stripped (handles `\\r\\n` endings).\n *\n * Intended use: feed text deltas from a model that has been prompted to\n * emit JSONL (or any other newline-delimited format), then parse /\n * validate each emitted line.\n */\nexport const lines = <E, R>(self: Stream.Stream<string, E, R>): Stream.Stream<string, E, R> =>\n linesStrict(Stream.concat(self, Stream.make(\"\\n\")))\n\n/**\n * Like `lines`, but only emits lines that were terminated by `\\n`. Any\n * partial trailing content is dropped at stream end. Use when you want\n * strict \"complete-line-or-nothing\" semantics.\n */\nexport const linesStrict = <E, R>(self: Stream.Stream<string, E, R>): Stream.Stream<string, E, R> =>\n self.pipe(\n Stream.mapAccum(\n (): string => \"\",\n (buffer, chunk: string) => {\n const combined = buffer + chunk\n const parts = combined.split(\"\\n\")\n const tail = parts.pop() ?? \"\"\n return [tail, parts.map((line) => line.replace(/\\r/g, \"\"))] as const\n },\n ),\n Stream.filter((line) => line.trim().length > 0),\n )\n"],"mappings":";;;;;;;;;;;;;;;;;;AAaA,MAAa,SAAe,SAC1B,YAAY,OAAO,OAAO,MAAM,OAAO,KAAK,IAAI,CAAC,CAAC;;;;;;AAOpD,MAAa,eAAqB,SAChC,KAAK,KACH,OAAO,eACS,KACb,QAAQ,UAAkB;CAEzB,MAAM,SADW,SAAS,MAAA,CACH,MAAM,IAAI;CAEjC,OAAO,CADM,MAAM,IAAI,KAAK,IACd,MAAM,KAAK,SAAS,KAAK,QAAQ,OAAO,EAAE,CAAC,CAAC;AAC5D,CACF,GACA,OAAO,QAAQ,SAAS,KAAK,KAAK,CAAC,CAAC,SAAS,CAAC,CAChD"}
@@ -1,6 +1,4 @@
1
1
  import { Stream } from "effect";
2
-
3
- //#region src/streaming/SSE.d.ts
4
2
  declare namespace SSE_d_exports {
5
3
  export { Event, fromBytes, toBytes };
6
4
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SSE.d.mts","names":[],"sources":["../../src/streaming/SSE.ts"],"mappings":";;;;;;;;;;;;KASY,KAAA;EAAA,SACD,KAAA;EAAA,SACA,IAAA;EAAA,SACA,EAAA;AAAA;;;;;;;AA8BX;cAAa,SAAA,SACX,IAAA,EAAM,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,CAAA,EAAG,CAAA,MAClC,MAAA,CAAO,MAAA,CAAO,KAAA,EAAO,CAAA,EAAG,CAAA;;;;;cAed,OAAA,SAAiB,IAAA,EAAM,MAAA,CAAO,MAAA,CAAO,KAAA,EAAO,CAAA,EAAG,CAAA,MAAK,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,CAAA,EAAG,CAAA"}
1
+ {"version":3,"file":"SSE.d.mts","names":[],"sources":["../../src/streaming/SSE.ts"],"mappings":";;;;;;;;;;KASY;WACD;WACA;WACA;;;;;;;;;cA8BE,YAAa,GAAG,GAAC,MACtB,OAAO,OAAO,YAAY,GAAG,OAClC,OAAO,OAAO,OAAO,GAAG;;;;;cAed,UAAW,GAAG,GAAC,MAAQ,OAAO,OAAO,OAAO,GAAG,OAAK,OAAO,OAAO,YAAY,GAAG"}
@@ -1,4 +1,4 @@
1
- import { n as __exportAll } from "../chunk-uyGKjUfl.mjs";
1
+ import { n as __exportAll } from "../rolldown-runtime-EAsCxrDo.mjs";
2
2
  import { Stream } from "effect";
3
3
  import { Sse } from "effect/unstable/encoding";
4
4
  //#region src/streaming/SSE.ts
@@ -1 +1 @@
1
- {"version":3,"file":"SSE.mjs","names":[],"sources":["../../src/streaming/SSE.ts"],"sourcesContent":["import { Stream } from \"effect\"\nimport { Sse } from \"effect/unstable/encoding\"\n\n/**\n * One Server-Sent Event. Fields per the WHATWG spec:\n * - `event`: optional event name (absent for the default \"message\")\n * - `data`: payload, with multiple `data:` lines joined by `\\n`\n * - `id`: optional last-event id\n */\nexport type Event = {\n readonly event?: string\n readonly data: string\n readonly id?: string\n}\n\nconst toEvent = (wire: Sse.Event): Event => ({\n data: wire.data,\n ...(wire.event !== \"message\" && { event: wire.event }),\n ...(wire.id !== undefined && { id: wire.id }),\n})\n\ntype ParserState = {\n readonly parser: Sse.Parser\n readonly out: Array<Event>\n}\n\nconst makeParserState = (): ParserState => {\n const out: Array<Event> = []\n const parser = Sse.makeParser((event) => {\n // `retry:` reconnection hints have no representation in `Event`\n if (event._tag === \"Event\") out.push(toEvent(event))\n })\n return { parser, out }\n}\n\n/**\n * Decode a `Stream<Uint8Array>` (e.g. an HTTP response body) into a\n * `Stream<SSE.Event>`, using the spec parser from `effect/unstable/encoding`.\n * An event is dispatched only once its terminating blank line arrives, so a\n * partial event at stream end (clean or failed) is discarded per the spec\n * rather than surfaced as a truncated frame.\n */\nexport const fromBytes = <E, R>(\n self: Stream.Stream<Uint8Array, E, R>,\n): Stream.Stream<Event, E, R> =>\n self.pipe(\n Stream.decodeText,\n Stream.mapAccum(makeParserState, (state, text: string) => {\n state.parser.feed(text)\n return [state, state.out.splice(0)] as const\n }),\n )\n\nconst encoder = new TextEncoder()\n\n/**\n * Encode a `Stream<Event>` as `Stream<Uint8Array>` ready to send on an\n * HTTP response with `Content-Type: text/event-stream`.\n */\nexport const toBytes = <E, R>(self: Stream.Stream<Event, E, R>): Stream.Stream<Uint8Array, E, R> =>\n Stream.map(self, (ev) =>\n encoder.encode(\n Sse.encoder.write({\n _tag: \"Event\",\n event: ev.event ?? \"message\",\n id: ev.id,\n data: ev.data,\n }),\n ),\n )\n"],"mappings":";;;;;;;;AAeA,MAAM,WAAW,UAA4B;CAC3C,MAAM,KAAK;CACX,GAAI,KAAK,UAAU,aAAa,EAAE,OAAO,KAAK,OAAO;CACrD,GAAI,KAAK,OAAO,KAAA,KAAa,EAAE,IAAI,KAAK,IAAI;CAC7C;AAOD,MAAM,wBAAqC;CACzC,MAAM,MAAoB,EAAE;AAK5B,QAAO;EAAE,QAJM,IAAI,YAAY,UAAU;AAEvC,OAAI,MAAM,SAAS,QAAS,KAAI,KAAK,QAAQ,MAAM,CAAC;IAEvC;EAAE;EAAK;;;;;;;;;AAUxB,MAAa,aACX,SAEA,KAAK,KACH,OAAO,YACP,OAAO,SAAS,kBAAkB,OAAO,SAAiB;AACxD,OAAM,OAAO,KAAK,KAAK;AACvB,QAAO,CAAC,OAAO,MAAM,IAAI,OAAO,EAAE,CAAC;EACnC,CACH;AAEH,MAAM,UAAU,IAAI,aAAa;;;;;AAMjC,MAAa,WAAiB,SAC5B,OAAO,IAAI,OAAO,OAChB,QAAQ,OACN,IAAI,QAAQ,MAAM;CAChB,MAAM;CACN,OAAO,GAAG,SAAS;CACnB,IAAI,GAAG;CACP,MAAM,GAAG;CACV,CAAC,CACH,CACF"}
1
+ {"version":3,"file":"SSE.mjs","names":[],"sources":["../../src/streaming/SSE.ts"],"sourcesContent":["import { Stream } from \"effect\"\nimport { Sse } from \"effect/unstable/encoding\"\n\n/**\n * One Server-Sent Event. Fields per the WHATWG spec:\n * - `event`: optional event name (absent for the default \"message\")\n * - `data`: payload, with multiple `data:` lines joined by `\\n`\n * - `id`: optional last-event id\n */\nexport type Event = {\n readonly event?: string\n readonly data: string\n readonly id?: string\n}\n\nconst toEvent = (wire: Sse.Event): Event => ({\n data: wire.data,\n ...(wire.event !== \"message\" && { event: wire.event }),\n ...(wire.id !== undefined && { id: wire.id }),\n})\n\ntype ParserState = {\n readonly parser: Sse.Parser\n readonly out: Array<Event>\n}\n\nconst makeParserState = (): ParserState => {\n const out: Array<Event> = []\n const parser = Sse.makeParser((event) => {\n // `retry:` reconnection hints have no representation in `Event`\n if (event._tag === \"Event\") out.push(toEvent(event))\n })\n return { parser, out }\n}\n\n/**\n * Decode a `Stream<Uint8Array>` (e.g. an HTTP response body) into a\n * `Stream<SSE.Event>`, using the spec parser from `effect/unstable/encoding`.\n * An event is dispatched only once its terminating blank line arrives, so a\n * partial event at stream end (clean or failed) is discarded per the spec\n * rather than surfaced as a truncated frame.\n */\nexport const fromBytes = <E, R>(\n self: Stream.Stream<Uint8Array, E, R>,\n): Stream.Stream<Event, E, R> =>\n self.pipe(\n Stream.decodeText,\n Stream.mapAccum(makeParserState, (state, text: string) => {\n state.parser.feed(text)\n return [state, state.out.splice(0)] as const\n }),\n )\n\nconst encoder = new TextEncoder()\n\n/**\n * Encode a `Stream<Event>` as `Stream<Uint8Array>` ready to send on an\n * HTTP response with `Content-Type: text/event-stream`.\n */\nexport const toBytes = <E, R>(self: Stream.Stream<Event, E, R>): Stream.Stream<Uint8Array, E, R> =>\n Stream.map(self, (ev) =>\n encoder.encode(\n Sse.encoder.write({\n _tag: \"Event\",\n event: ev.event ?? \"message\",\n id: ev.id,\n data: ev.data,\n }),\n ),\n )\n"],"mappings":";;;;;;;;AAeA,MAAM,WAAW,UAA4B;CAC3C,MAAM,KAAK;CACX,GAAI,KAAK,UAAU,aAAa,EAAE,OAAO,KAAK,MAAM;CACpD,GAAI,KAAK,OAAO,KAAA,KAAa,EAAE,IAAI,KAAK,GAAG;AAC7C;AAOA,MAAM,wBAAqC;CACzC,MAAM,MAAoB,CAAC;CAK3B,OAAO;EAAE,QAJM,IAAI,YAAY,UAAU;GAEvC,IAAI,MAAM,SAAS,SAAS,IAAI,KAAK,QAAQ,KAAK,CAAC;EACrD,CACc;EAAG;CAAI;AACvB;;;;;;;;AASA,MAAa,aACX,SAEA,KAAK,KACH,OAAO,YACP,OAAO,SAAS,kBAAkB,OAAO,SAAiB;CACxD,MAAM,OAAO,KAAK,IAAI;CACtB,OAAO,CAAC,OAAO,MAAM,IAAI,OAAO,CAAC,CAAC;AACpC,CAAC,CACH;AAEF,MAAM,UAAU,IAAI,YAAY;;;;;AAMhC,MAAa,WAAiB,SAC5B,OAAO,IAAI,OAAO,OAChB,QAAQ,OACN,IAAI,QAAQ,MAAM;CAChB,MAAM;CACN,OAAO,GAAG,SAAS;CACnB,IAAI,GAAG;CACP,MAAM,GAAG;AACX,CAAC,CACH,CACF"}
@@ -1 +1 @@
1
- export { };
1
+ export {}
@@ -1,5 +1,6 @@
1
1
  import { fromBytes, toBytes } from "./SSE.mjs";
2
- import { c as it, n as globalExpect, o as describe } from "../dist-CcRV3-A5.mjs";
2
+ import { m as it, o as describe } from "../utils-CiH_DjFW.mjs";
3
+ import { n as globalExpect } from "../test.DNmyFkvJ-YPzDR0Co.mjs";
3
4
  import { Cause, Deferred, Effect, Exit, Fiber, Result, Stream } from "effect";
4
5
  //#region src/streaming/SSE.test.ts
5
6
  const enc = new TextEncoder();
@@ -12,16 +13,19 @@ const runUntilEnd = (s) => Effect.runPromise(s.pipe(Stream.result, Stream.runCol
12
13
  const failuresOf = (exit) => Exit.isFailure(exit) ? exit.cause.reasons.filter(Cause.isFailReason).map((r) => r.error) : [];
13
14
  describe("SSE.fromBytes", () => {
14
15
  it("parses a single complete event", async () => {
15
- globalExpect(await collect(fromBytes(bytesOf("event: foo\ndata: hello\n\n")))).toEqual([{
16
+ const out = await collect(fromBytes(bytesOf("event: foo\ndata: hello\n\n")));
17
+ globalExpect(out).toEqual([{
16
18
  event: "foo",
17
19
  data: "hello"
18
20
  }]);
19
21
  });
20
22
  it("joins multiple data lines with \\n", async () => {
21
- globalExpect(await collect(fromBytes(bytesOf("data: line1\ndata: line2\ndata: line3\n\n")))).toEqual([{ data: "line1\nline2\nline3" }]);
23
+ const out = await collect(fromBytes(bytesOf("data: line1\ndata: line2\ndata: line3\n\n")));
24
+ globalExpect(out).toEqual([{ data: "line1\nline2\nline3" }]);
22
25
  });
23
26
  it("handles events split across chunk boundaries", async () => {
24
- globalExpect(await collect(fromBytes(bytesOf("event: split\nda", "ta: hi\n", "\nevent: next\ndata: x\n\n")))).toEqual([{
27
+ const out = await collect(fromBytes(bytesOf("event: split\nda", "ta: hi\n", "\nevent: next\ndata: x\n\n")));
28
+ globalExpect(out).toEqual([{
25
29
  event: "split",
26
30
  data: "hi"
27
31
  }, {
@@ -30,34 +34,41 @@ describe("SSE.fromBytes", () => {
30
34
  }]);
31
35
  });
32
36
  it("handles CRLF line endings", async () => {
33
- globalExpect(await collect(fromBytes(bytesOf("event: a\r\ndata: b\r\n\r\n")))).toEqual([{
37
+ const out = await collect(fromBytes(bytesOf("event: a\r\ndata: b\r\n\r\n")));
38
+ globalExpect(out).toEqual([{
34
39
  event: "a",
35
40
  data: "b"
36
41
  }]);
37
42
  });
38
43
  it("preserves id and skips comment lines", async () => {
39
- globalExpect(await collect(fromBytes(bytesOf(": ping\nid: 42\ndata: x\n\n")))).toEqual([{
44
+ const out = await collect(fromBytes(bytesOf(": ping\nid: 42\ndata: x\n\n")));
45
+ globalExpect(out).toEqual([{
40
46
  id: "42",
41
47
  data: "x"
42
48
  }]);
43
49
  });
44
50
  it("parses a data field with no space after the colon", async () => {
45
- globalExpect(await collect(fromBytes(bytesOf("data:x\n\n")))).toEqual([{ data: "x" }]);
51
+ const out = await collect(fromBytes(bytesOf("data:x\n\n")));
52
+ globalExpect(out).toEqual([{ data: "x" }]);
46
53
  });
47
54
  it("ignores an id containing a NUL character", async () => {
48
- globalExpect(await collect(fromBytes(bytesOf("id: a\0b\ndata: x\n\n")))).toEqual([{ data: "x" }]);
55
+ const out = await collect(fromBytes(bytesOf("id: a\0b\ndata: x\n\n")));
56
+ globalExpect(out).toEqual([{ data: "x" }]);
49
57
  });
50
58
  it("discards a trailing event without a closing blank line", async () => {
51
- globalExpect(await collect(fromBytes(bytesOf("data: tail")))).toEqual([]);
59
+ const out = await collect(fromBytes(bytesOf("data: tail")));
60
+ globalExpect(out).toEqual([]);
52
61
  });
53
62
  it("discards buffered partial data when the upstream fails mid-stream", async () => {
54
- const { seen, failures } = await runUntilEnd(fromBytes(Stream.concat(bytesOf("data: good\n\ndata: partial-tr"), Stream.fail("boom"))));
63
+ const failing = Stream.concat(bytesOf("data: good\n\ndata: partial-tr"), Stream.fail("boom"));
64
+ const { seen, failures } = await runUntilEnd(fromBytes(failing));
55
65
  globalExpect(seen).toEqual([{ data: "good" }]);
56
66
  globalExpect(failures).toEqual(["boom"]);
57
67
  });
58
68
  it("discards a partial multi-byte char in the text decoder when the upstream fails", async () => {
59
69
  const partialSquid = enc.encode("data: 🦑\n\n").slice(0, 8);
60
- const { seen, failures } = await runUntilEnd(fromBytes(Stream.concat(Stream.fromIterable([enc.encode("data: ok\n\n"), partialSquid]), Stream.fail("boom"))));
70
+ const failing = Stream.concat(Stream.fromIterable([enc.encode("data: ok\n\n"), partialSquid]), Stream.fail("boom"));
71
+ const { seen, failures } = await runUntilEnd(fromBytes(failing));
61
72
  globalExpect(seen).toEqual([{ data: "ok" }]);
62
73
  globalExpect(failures).toEqual(["boom"]);
63
74
  });
@@ -81,22 +92,27 @@ describe("SSE.fromBytes", () => {
81
92
  globalExpect(failuresOf(exit)).toEqual([]);
82
93
  });
83
94
  it("ignores retry directives", async () => {
84
- globalExpect(await collect(fromBytes(bytesOf("retry: 3000\n\ndata: a\n\n")))).toEqual([{ data: "a" }]);
95
+ const out = await collect(fromBytes(bytesOf("retry: 3000\n\ndata: a\n\n")));
96
+ globalExpect(out).toEqual([{ data: "a" }]);
85
97
  });
86
98
  it("treats an explicit 'event: message' as the default event", async () => {
87
- globalExpect(await collect(fromBytes(bytesOf("event: message\ndata: x\n\n")))).toEqual([{ data: "x" }]);
99
+ const out = await collect(fromBytes(bytesOf("event: message\ndata: x\n\n")));
100
+ globalExpect(out).toEqual([{ data: "x" }]);
88
101
  });
89
102
  it("does not dispatch events with no data", async () => {
90
- globalExpect(await collect(fromBytes(bytesOf("event: ping\n\ndata: x\n\n")))).toEqual([{ data: "x" }]);
103
+ const out = await collect(fromBytes(bytesOf("event: ping\n\ndata: x\n\n")));
104
+ globalExpect(out).toEqual([{ data: "x" }]);
91
105
  });
92
106
  it("ignores empty blocks between events", async () => {
93
- globalExpect(await collect(fromBytes(bytesOf("data: a\n\n\n\ndata: b\n\n")))).toEqual([{ data: "a" }, { data: "b" }]);
107
+ const out = await collect(fromBytes(bytesOf("data: a\n\n\n\ndata: b\n\n")));
108
+ globalExpect(out).toEqual([{ data: "a" }, { data: "b" }]);
94
109
  });
95
110
  it("handles a UTF-8 multi-byte char split across chunks", async () => {
96
111
  const squidBytes = enc.encode("data: 🦑\n\n");
97
112
  const a = squidBytes.slice(0, 8);
98
113
  const b = squidBytes.slice(8);
99
- globalExpect(await collect(fromBytes(Stream.fromIterable([a, b])))).toEqual([{ data: "🦑" }]);
114
+ const out = await collect(fromBytes(Stream.fromIterable([a, b])));
115
+ globalExpect(out).toEqual([{ data: "🦑" }]);
100
116
  });
101
117
  });
102
118
  describe("SSE.toBytes round-trip", () => {
@@ -113,7 +129,8 @@ describe("SSE.toBytes round-trip", () => {
113
129
  data: "x"
114
130
  }
115
131
  ];
116
- globalExpect(await collect(Stream.fromIterable(events).pipe(toBytes, fromBytes))).toEqual(events);
132
+ const reparsed = await collect(Stream.fromIterable(events).pipe(toBytes, fromBytes));
133
+ globalExpect(reparsed).toEqual(events);
117
134
  });
118
135
  });
119
136
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"SSE.test.mjs","names":["SSE.fromBytes","SSE.toBytes"],"sources":["../../src/streaming/SSE.test.ts"],"sourcesContent":["import { Cause, Deferred, Effect, Exit, Fiber, Result, Stream } from \"effect\"\nimport { describe, expect, it } from \"vitest\"\nimport * as SSE from \"./SSE.js\"\n\nconst enc = new TextEncoder()\nconst bytesOf = (...chunks: ReadonlyArray<string>) =>\n Stream.fromIterable(chunks.map((c) => enc.encode(c)))\n\nconst collect = <A, E>(s: Stream.Stream<A, E>) => Effect.runPromise(Stream.runCollect(s))\n\nconst runUntilEnd = <A, E>(s: Stream.Stream<A, E>) =>\n Effect.runPromise(\n s.pipe(\n Stream.result,\n Stream.runCollect,\n Effect.map((results) => ({\n seen: results.filter(Result.isSuccess).map((r) => r.success),\n failures: results.filter(Result.isFailure).map((r) => r.failure),\n })),\n ),\n )\n\nconst failuresOf = (exit: Exit.Exit<unknown, unknown>): ReadonlyArray<unknown> =>\n Exit.isFailure(exit) ? exit.cause.reasons.filter(Cause.isFailReason).map((r) => r.error) : []\n\ndescribe(\"SSE.fromBytes\", () => {\n it(\"parses a single complete event\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"event: foo\\ndata: hello\\n\\n\")))\n expect(out).toEqual([{ event: \"foo\", data: \"hello\" }])\n })\n\n it(\"joins multiple data lines with \\\\n\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"data: line1\\ndata: line2\\ndata: line3\\n\\n\")))\n expect(out).toEqual([{ data: \"line1\\nline2\\nline3\" }])\n })\n\n it(\"handles events split across chunk boundaries\", async () => {\n const out = await collect(\n SSE.fromBytes(bytesOf(\"event: split\\nda\", \"ta: hi\\n\", \"\\nevent: next\\ndata: x\\n\\n\")),\n )\n expect(out).toEqual([\n { event: \"split\", data: \"hi\" },\n { event: \"next\", data: \"x\" },\n ])\n })\n\n it(\"handles CRLF line endings\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"event: a\\r\\ndata: b\\r\\n\\r\\n\")))\n expect(out).toEqual([{ event: \"a\", data: \"b\" }])\n })\n\n it(\"preserves id and skips comment lines\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\": ping\\nid: 42\\ndata: x\\n\\n\")))\n expect(out).toEqual([{ id: \"42\", data: \"x\" }])\n })\n\n it(\"parses a data field with no space after the colon\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"data:x\\n\\n\")))\n expect(out).toEqual([{ data: \"x\" }])\n })\n\n it(\"ignores an id containing a NUL character\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"id: a\\u0000b\\ndata: x\\n\\n\")))\n expect(out).toEqual([{ data: \"x\" }])\n })\n\n it(\"discards a trailing event without a closing blank line\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"data: tail\")))\n expect(out).toEqual([])\n })\n\n it(\"discards buffered partial data when the upstream fails mid-stream\", async () => {\n const failing = Stream.concat(\n bytesOf(\"data: good\\n\\ndata: partial-tr\"),\n Stream.fail(\"boom\" as const),\n )\n const { seen, failures } = await runUntilEnd(SSE.fromBytes(failing))\n expect(seen).toEqual([{ data: \"good\" }])\n expect(failures).toEqual([\"boom\"])\n })\n\n it(\"discards a partial multi-byte char in the text decoder when the upstream fails\", async () => {\n const partialSquid = enc.encode(\"data: 🦑\\n\\n\").slice(0, 8)\n const failing = Stream.concat(\n Stream.fromIterable([enc.encode(\"data: ok\\n\\n\"), partialSquid]),\n Stream.fail(\"boom\" as const),\n )\n const { seen, failures } = await runUntilEnd(SSE.fromBytes(failing))\n expect(seen).toEqual([{ data: \"ok\" }])\n expect(failures).toEqual([\"boom\"])\n })\n\n it(\"discards buffered partial data when the stream is interrupted\", async () => {\n const { seen, exit } = await Effect.runPromise(\n Effect.gen(function* () {\n const seen: Array<SSE.Event> = []\n const latch = yield* Deferred.make<void>()\n const hanging = Stream.concat(bytesOf(\"data: good\\n\\ndata: partial\"), Stream.never)\n const fiber = yield* Stream.runForEach(SSE.fromBytes(hanging), (e) =>\n Effect.sync(() => {\n seen.push(e)\n }).pipe(Effect.andThen(Deferred.succeed(latch, void 0))),\n ).pipe(Effect.forkChild)\n yield* Deferred.await(latch)\n yield* Fiber.interrupt(fiber)\n const exit = yield* Fiber.await(fiber)\n return { seen, exit }\n }),\n )\n expect(seen).toEqual([{ data: \"good\" }])\n expect(Exit.isFailure(exit)).toBe(true)\n expect(failuresOf(exit)).toEqual([])\n })\n\n it(\"ignores retry directives\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"retry: 3000\\n\\ndata: a\\n\\n\")))\n expect(out).toEqual([{ data: \"a\" }])\n })\n\n it(\"treats an explicit 'event: message' as the default event\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"event: message\\ndata: x\\n\\n\")))\n expect(out).toEqual([{ data: \"x\" }])\n })\n\n it(\"does not dispatch events with no data\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"event: ping\\n\\ndata: x\\n\\n\")))\n expect(out).toEqual([{ data: \"x\" }])\n })\n\n it(\"ignores empty blocks between events\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"data: a\\n\\n\\n\\ndata: b\\n\\n\")))\n expect(out).toEqual([{ data: \"a\" }, { data: \"b\" }])\n })\n\n it(\"handles a UTF-8 multi-byte char split across chunks\", async () => {\n // \"🦑\" is 0xF0 0x9F 0xA6 0x91. Split between bytes 2 and 3.\n const squidBytes = enc.encode(\"data: 🦑\\n\\n\")\n const a = squidBytes.slice(0, 8) // \"data: \" + first 2 bytes of squid\n const b = squidBytes.slice(8) // remaining squid bytes + \"\\n\\n\"\n const out = await collect(SSE.fromBytes(Stream.fromIterable([a, b])))\n expect(out).toEqual([{ data: \"🦑\" }])\n })\n})\n\ndescribe(\"SSE.toBytes round-trip\", () => {\n it(\"re-parses what it serializes\", async () => {\n const events: ReadonlyArray<SSE.Event> = [\n { event: \"a\", data: \"hello\" },\n { data: \"multi\\nline\" },\n { event: \"b\", id: \"7\", data: \"x\" },\n ]\n const reparsed = await collect(Stream.fromIterable(events).pipe(SSE.toBytes, SSE.fromBytes))\n expect(reparsed).toEqual(events)\n })\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"SSE.test.mjs","names":["SSE.fromBytes","SSE.toBytes"],"sources":["../../src/streaming/SSE.test.ts"],"sourcesContent":["import { Cause, Deferred, Effect, Exit, Fiber, Result, Stream } from \"effect\"\nimport { describe, expect, it } from \"vitest\"\nimport * as SSE from \"./SSE.js\"\n\nconst enc = new TextEncoder()\nconst bytesOf = (...chunks: ReadonlyArray<string>) =>\n Stream.fromIterable(chunks.map((c) => enc.encode(c)))\n\nconst collect = <A, E>(s: Stream.Stream<A, E>) => Effect.runPromise(Stream.runCollect(s))\n\nconst runUntilEnd = <A, E>(s: Stream.Stream<A, E>) =>\n Effect.runPromise(\n s.pipe(\n Stream.result,\n Stream.runCollect,\n Effect.map((results) => ({\n seen: results.filter(Result.isSuccess).map((r) => r.success),\n failures: results.filter(Result.isFailure).map((r) => r.failure),\n })),\n ),\n )\n\nconst failuresOf = (exit: Exit.Exit<unknown, unknown>): ReadonlyArray<unknown> =>\n Exit.isFailure(exit) ? exit.cause.reasons.filter(Cause.isFailReason).map((r) => r.error) : []\n\ndescribe(\"SSE.fromBytes\", () => {\n it(\"parses a single complete event\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"event: foo\\ndata: hello\\n\\n\")))\n expect(out).toEqual([{ event: \"foo\", data: \"hello\" }])\n })\n\n it(\"joins multiple data lines with \\\\n\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"data: line1\\ndata: line2\\ndata: line3\\n\\n\")))\n expect(out).toEqual([{ data: \"line1\\nline2\\nline3\" }])\n })\n\n it(\"handles events split across chunk boundaries\", async () => {\n const out = await collect(\n SSE.fromBytes(bytesOf(\"event: split\\nda\", \"ta: hi\\n\", \"\\nevent: next\\ndata: x\\n\\n\")),\n )\n expect(out).toEqual([\n { event: \"split\", data: \"hi\" },\n { event: \"next\", data: \"x\" },\n ])\n })\n\n it(\"handles CRLF line endings\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"event: a\\r\\ndata: b\\r\\n\\r\\n\")))\n expect(out).toEqual([{ event: \"a\", data: \"b\" }])\n })\n\n it(\"preserves id and skips comment lines\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\": ping\\nid: 42\\ndata: x\\n\\n\")))\n expect(out).toEqual([{ id: \"42\", data: \"x\" }])\n })\n\n it(\"parses a data field with no space after the colon\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"data:x\\n\\n\")))\n expect(out).toEqual([{ data: \"x\" }])\n })\n\n it(\"ignores an id containing a NUL character\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"id: a\\u0000b\\ndata: x\\n\\n\")))\n expect(out).toEqual([{ data: \"x\" }])\n })\n\n it(\"discards a trailing event without a closing blank line\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"data: tail\")))\n expect(out).toEqual([])\n })\n\n it(\"discards buffered partial data when the upstream fails mid-stream\", async () => {\n const failing = Stream.concat(\n bytesOf(\"data: good\\n\\ndata: partial-tr\"),\n Stream.fail(\"boom\" as const),\n )\n const { seen, failures } = await runUntilEnd(SSE.fromBytes(failing))\n expect(seen).toEqual([{ data: \"good\" }])\n expect(failures).toEqual([\"boom\"])\n })\n\n it(\"discards a partial multi-byte char in the text decoder when the upstream fails\", async () => {\n const partialSquid = enc.encode(\"data: 🦑\\n\\n\").slice(0, 8)\n const failing = Stream.concat(\n Stream.fromIterable([enc.encode(\"data: ok\\n\\n\"), partialSquid]),\n Stream.fail(\"boom\" as const),\n )\n const { seen, failures } = await runUntilEnd(SSE.fromBytes(failing))\n expect(seen).toEqual([{ data: \"ok\" }])\n expect(failures).toEqual([\"boom\"])\n })\n\n it(\"discards buffered partial data when the stream is interrupted\", async () => {\n const { seen, exit } = await Effect.runPromise(\n Effect.gen(function* () {\n const seen: Array<SSE.Event> = []\n const latch = yield* Deferred.make<void>()\n const hanging = Stream.concat(bytesOf(\"data: good\\n\\ndata: partial\"), Stream.never)\n const fiber = yield* Stream.runForEach(SSE.fromBytes(hanging), (e) =>\n Effect.sync(() => {\n seen.push(e)\n }).pipe(Effect.andThen(Deferred.succeed(latch, void 0))),\n ).pipe(Effect.forkChild)\n yield* Deferred.await(latch)\n yield* Fiber.interrupt(fiber)\n const exit = yield* Fiber.await(fiber)\n return { seen, exit }\n }),\n )\n expect(seen).toEqual([{ data: \"good\" }])\n expect(Exit.isFailure(exit)).toBe(true)\n expect(failuresOf(exit)).toEqual([])\n })\n\n it(\"ignores retry directives\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"retry: 3000\\n\\ndata: a\\n\\n\")))\n expect(out).toEqual([{ data: \"a\" }])\n })\n\n it(\"treats an explicit 'event: message' as the default event\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"event: message\\ndata: x\\n\\n\")))\n expect(out).toEqual([{ data: \"x\" }])\n })\n\n it(\"does not dispatch events with no data\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"event: ping\\n\\ndata: x\\n\\n\")))\n expect(out).toEqual([{ data: \"x\" }])\n })\n\n it(\"ignores empty blocks between events\", async () => {\n const out = await collect(SSE.fromBytes(bytesOf(\"data: a\\n\\n\\n\\ndata: b\\n\\n\")))\n expect(out).toEqual([{ data: \"a\" }, { data: \"b\" }])\n })\n\n it(\"handles a UTF-8 multi-byte char split across chunks\", async () => {\n // \"🦑\" is 0xF0 0x9F 0xA6 0x91. Split between bytes 2 and 3.\n const squidBytes = enc.encode(\"data: 🦑\\n\\n\")\n const a = squidBytes.slice(0, 8) // \"data: \" + first 2 bytes of squid\n const b = squidBytes.slice(8) // remaining squid bytes + \"\\n\\n\"\n const out = await collect(SSE.fromBytes(Stream.fromIterable([a, b])))\n expect(out).toEqual([{ data: \"🦑\" }])\n })\n})\n\ndescribe(\"SSE.toBytes round-trip\", () => {\n it(\"re-parses what it serializes\", async () => {\n const events: ReadonlyArray<SSE.Event> = [\n { event: \"a\", data: \"hello\" },\n { data: \"multi\\nline\" },\n { event: \"b\", id: \"7\", data: \"x\" },\n ]\n const reparsed = await collect(Stream.fromIterable(events).pipe(SSE.toBytes, SSE.fromBytes))\n expect(reparsed).toEqual(events)\n })\n})\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { c as decodeJsonLines, d as parseJson, i as StructuredFormat, l as decodeJsonLinesRecoverable, n as JsonParseError, o as StructuredSchema, r as StructuredDecodeError, s as decode, t as DecodeIssue, u as fromEffectSchema } from "../StructuredFormat-DHaUJBdd.mjs";
1
+ import { c as decodeJsonLines, d as parseJson, i as StructuredFormat, l as decodeJsonLinesRecoverable, n as JsonParseError, o as StructuredSchema, r as StructuredDecodeError, s as decode, t as DecodeIssue, u as fromEffectSchema } from "../StructuredFormat-BlZhyOsi.mjs";
2
2
  export { DecodeIssue, JsonParseError, StructuredDecodeError, StructuredFormat, StructuredSchema, decode, decodeJsonLines, decodeJsonLinesRecoverable, fromEffectSchema, parseJson };
@@ -1,4 +1,4 @@
1
- import { n as __exportAll } from "../chunk-uyGKjUfl.mjs";
1
+ import { n as __exportAll } from "../rolldown-runtime-EAsCxrDo.mjs";
2
2
  import { Data, Effect, Match, Schema, Stream, pipe } from "effect";
3
3
  //#region src/structured-format/StructuredFormat.ts
4
4
  var StructuredFormat_exports = /* @__PURE__ */ __exportAll({
@@ -1 +1 @@
1
- {"version":3,"file":"StructuredFormat.mjs","names":[],"sources":["../../src/structured-format/StructuredFormat.ts"],"sourcesContent":["import type { StandardJSONSchemaV1, StandardSchemaV1 } from \"@standard-schema/spec\"\nimport { Data, Effect, Match, Result, Schema, Stream, pipe } from \"effect\"\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Cross-validator schema constraint for structured outputs. Any schema\n * implementing both Standard Schema (runtime validation) and Standard\n * JSON Schema (wire encoding) works directly: Zod 4+, Valibot, ArkType,\n * and Effect Schema after `fromEffectSchema`.\n */\nexport type StructuredSchema<Output = unknown> = StandardSchemaV1<unknown, Output> &\n StandardJSONSchemaV1<unknown, Output>\n\n/**\n * A schema-bound output the user wants the model to produce. Pairs the\n * cross-validator schema with metadata providers need (name, description,\n * strict-mode flag).\n */\nexport type StructuredFormat<A> = {\n readonly name: string\n readonly description?: string\n readonly schema: StructuredSchema<A>\n /**\n * Provider strict-mode flag. OpenAI, Anthropic, and Mistral honour it\n * (constrained decoding); other providers ignore.\n */\n readonly strict?: boolean\n}\n\n/** A single path-scoped validation problem. Library-agnostic shape. */\nexport type DecodeIssue = {\n readonly path: ReadonlyArray<string | number>\n readonly message: string\n}\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\n/**\n * Schema validation failed. `raw` is the original text (or stringified\n * value) that failed; `issues` is a flat list of per-field problems.\n */\nexport class StructuredDecodeError extends Data.TaggedError(\"StructuredDecodeError\")<{\n readonly raw: string\n readonly issues: ReadonlyArray<DecodeIssue>\n}> {}\n\n/**\n * `JSON.parse` threw on a string that was supposed to be JSON. Distinct\n * from `StructuredDecodeError`: the bytes weren't even JSON.\n */\nexport class JsonParseError extends Data.TaggedError(\"StructuredJsonParseError\")<{\n readonly raw: string\n readonly cause: unknown\n}> {}\n\n// ---------------------------------------------------------------------------\n// Constructors\n// ---------------------------------------------------------------------------\n\n/**\n * Wrap an Effect `Schema` as a `StructuredFormat`. Effect Schema doesn't\n * natively implement Standard Schema; this helper installs the\n * `~standard` and JSON Schema interfaces.\n */\nexport const fromEffectSchema = <S extends Schema.Codec<any, any, never, any>>(\n schema: S,\n options?: {\n readonly name?: string\n readonly description?: string\n readonly strict?: boolean\n },\n): StructuredFormat<S[\"Type\"]> => ({\n name: options?.name ?? \"output\",\n schema: Schema.toStandardJSONSchemaV1(Schema.toStandardSchemaV1(schema)),\n ...(options?.description !== undefined && {\n description: options.description,\n }),\n ...(options?.strict !== undefined && { strict: options.strict }),\n})\n\n// ---------------------------------------------------------------------------\n// Standard Schema → DecodeIssue\n// ---------------------------------------------------------------------------\n\nconst propertyKeyToScalar = Match.type<PropertyKey>().pipe(\n Match.when(Match.string, (s) => s),\n Match.when(Match.number, (n) => n),\n Match.when(Match.symbol, (s) => s.toString()),\n Match.exhaustive,\n)\n\nconst segmentToKey = Match.type<PropertyKey | StandardSchemaV1.PathSegment>().pipe(\n Match.when(Match.string, (s) => s),\n Match.when(Match.number, (n) => n),\n Match.when(Match.symbol, (s) => s.toString()),\n Match.orElse((segment) => propertyKeyToScalar(segment.key)),\n)\n\nconst issueToDecode = (issue: StandardSchemaV1.Issue): DecodeIssue => ({\n path: (issue.path ?? []).map(segmentToKey),\n message: issue.message,\n})\n\n// ---------------------------------------------------------------------------\n// Decoding\n// ---------------------------------------------------------------------------\n\n/**\n * Validate an `unknown` against the format's schema. Returns the typed\n * value or a `StructuredDecodeError`. Standard Schema's `validate` may\n * be async; this function handles both sync and async results.\n */\nexport const decode =\n <A>(format: StructuredFormat<A>) =>\n (raw: unknown): Effect.Effect<A, StructuredDecodeError> =>\n pipe(\n Effect.promise(async () => format.schema[\"~standard\"].validate(raw)),\n Effect.flatMap((result) =>\n result.issues === undefined\n ? Effect.succeed(result.value)\n : Effect.fail(\n new StructuredDecodeError({\n raw: typeof raw === \"string\" ? raw : JSON.stringify(raw),\n issues: result.issues.map(issueToDecode),\n }),\n ),\n ),\n )\n\n/**\n * Parse a JSON string then validate against the format's schema. Two\n * failure modes: `JsonParseError` (bytes weren't JSON) and\n * `StructuredDecodeError` (JSON didn't match the schema).\n */\nexport const parseJson =\n <A>(format: StructuredFormat<A>) =>\n (raw: string): Effect.Effect<A, JsonParseError | StructuredDecodeError> =>\n pipe(\n Effect.try({\n // Validation runs through Standard Schema (Zod / Valibot / Effect), not\n // Effect Schema, so its JSON codecs don't apply here; and JSON.parse is\n // a separate step on purpose, to surface JsonParseError distinctly.\n // @effect-diagnostics-next-line effect/preferSchemaOverJson:off\n try: () => JSON.parse(raw),\n catch: (cause) => new JsonParseError({ raw, cause }),\n }),\n Effect.flatMap(decode(format)),\n )\n\n/**\n * Stream operator: each input string is JSON-parsed and validated.\n * Failures surface in the stream's failure channel, distinguished by tag.\n */\nexport const decodeJsonLines =\n <A>(format: StructuredFormat<A>) =>\n <E, R>(\n self: Stream.Stream<string, E, R>,\n ): Stream.Stream<A, E | JsonParseError | StructuredDecodeError, R> =>\n self.pipe(Stream.mapEffect(parseJson(format)))\n\n/**\n * Like {@link decodeJsonLines}, but each line yields a `Result` instead of\n * failing the stream. Use when one bad line shouldn't abort the rest —\n * log-and-continue, or partial-recovery with a corrective re-prompt.\n * Upstream errors (the input stream's own `E`) still propagate normally.\n */\nexport const decodeJsonLinesRecoverable =\n <A>(format: StructuredFormat<A>) =>\n <E, R>(\n self: Stream.Stream<string, E, R>,\n ): Stream.Stream<Result.Result<A, JsonParseError | StructuredDecodeError>, E, R> =>\n self.pipe(Stream.mapEffect((line) => Effect.result(parseJson(format)(line))))\n"],"mappings":";;;;;;;;;;;;;;;;AA8CA,IAAa,wBAAb,cAA2C,KAAK,YAAY,wBAAwB,CAGjF;;;;;AAMH,IAAa,iBAAb,cAAoC,KAAK,YAAY,2BAA2B,CAG7E;;;;;;AAWH,MAAa,oBACX,QACA,aAKiC;CACjC,MAAM,SAAS,QAAQ;CACvB,QAAQ,OAAO,uBAAuB,OAAO,mBAAmB,OAAO,CAAC;CACxE,GAAI,SAAS,gBAAgB,KAAA,KAAa,EACxC,aAAa,QAAQ,aACtB;CACD,GAAI,SAAS,WAAW,KAAA,KAAa,EAAE,QAAQ,QAAQ,QAAQ;CAChE;AAMD,MAAM,sBAAsB,MAAM,MAAmB,CAAC,KACpD,MAAM,KAAK,MAAM,SAAS,MAAM,EAAE,EAClC,MAAM,KAAK,MAAM,SAAS,MAAM,EAAE,EAClC,MAAM,KAAK,MAAM,SAAS,MAAM,EAAE,UAAU,CAAC,EAC7C,MAAM,WACP;AAED,MAAM,eAAe,MAAM,MAAkD,CAAC,KAC5E,MAAM,KAAK,MAAM,SAAS,MAAM,EAAE,EAClC,MAAM,KAAK,MAAM,SAAS,MAAM,EAAE,EAClC,MAAM,KAAK,MAAM,SAAS,MAAM,EAAE,UAAU,CAAC,EAC7C,MAAM,QAAQ,YAAY,oBAAoB,QAAQ,IAAI,CAAC,CAC5D;AAED,MAAM,iBAAiB,WAAgD;CACrE,OAAO,MAAM,QAAQ,EAAE,EAAE,IAAI,aAAa;CAC1C,SAAS,MAAM;CAChB;;;;;;AAWD,MAAa,UACP,YACH,QACC,KACE,OAAO,QAAQ,YAAY,OAAO,OAAO,aAAa,SAAS,IAAI,CAAC,EACpE,OAAO,SAAS,WACd,OAAO,WAAW,KAAA,IACd,OAAO,QAAQ,OAAO,MAAM,GAC5B,OAAO,KACL,IAAI,sBAAsB;CACxB,KAAK,OAAO,QAAQ,WAAW,MAAM,KAAK,UAAU,IAAI;CACxD,QAAQ,OAAO,OAAO,IAAI,cAAc;CACzC,CAAC,CACH,CACN,CACF;;;;;;AAOL,MAAa,aACP,YACH,QACC,KACE,OAAO,IAAI;CAKT,WAAW,KAAK,MAAM,IAAI;CAC1B,QAAQ,UAAU,IAAI,eAAe;EAAE;EAAK;EAAO,CAAC;CACrD,CAAC,EACF,OAAO,QAAQ,OAAO,OAAO,CAAC,CAC/B;;;;;AAML,MAAa,mBACP,YAEF,SAEA,KAAK,KAAK,OAAO,UAAU,UAAU,OAAO,CAAC,CAAC;;;;;;;AAQlD,MAAa,8BACP,YAEF,SAEA,KAAK,KAAK,OAAO,WAAW,SAAS,OAAO,OAAO,UAAU,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"StructuredFormat.mjs","names":[],"sources":["../../src/structured-format/StructuredFormat.ts"],"sourcesContent":["import type { StandardJSONSchemaV1, StandardSchemaV1 } from \"@standard-schema/spec\"\nimport { Data, Effect, Match, Result, Schema, Stream, pipe } from \"effect\"\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Cross-validator schema constraint for structured outputs. Any schema\n * implementing both Standard Schema (runtime validation) and Standard\n * JSON Schema (wire encoding) works directly: Zod 4+, Valibot, ArkType,\n * and Effect Schema after `fromEffectSchema`.\n */\nexport type StructuredSchema<Output = unknown> = StandardSchemaV1<unknown, Output> &\n StandardJSONSchemaV1<unknown, Output>\n\n/**\n * A schema-bound output the user wants the model to produce. Pairs the\n * cross-validator schema with metadata providers need (name, description,\n * strict-mode flag).\n */\nexport type StructuredFormat<A> = {\n readonly name: string\n readonly description?: string\n readonly schema: StructuredSchema<A>\n /**\n * Provider strict-mode flag. OpenAI, Anthropic, and Mistral honour it\n * (constrained decoding); other providers ignore.\n */\n readonly strict?: boolean\n}\n\n/** A single path-scoped validation problem. Library-agnostic shape. */\nexport type DecodeIssue = {\n readonly path: ReadonlyArray<string | number>\n readonly message: string\n}\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\n/**\n * Schema validation failed. `raw` is the original text (or stringified\n * value) that failed; `issues` is a flat list of per-field problems.\n */\nexport class StructuredDecodeError extends Data.TaggedError(\"StructuredDecodeError\")<{\n readonly raw: string\n readonly issues: ReadonlyArray<DecodeIssue>\n}> {}\n\n/**\n * `JSON.parse` threw on a string that was supposed to be JSON. Distinct\n * from `StructuredDecodeError`: the bytes weren't even JSON.\n */\nexport class JsonParseError extends Data.TaggedError(\"StructuredJsonParseError\")<{\n readonly raw: string\n readonly cause: unknown\n}> {}\n\n// ---------------------------------------------------------------------------\n// Constructors\n// ---------------------------------------------------------------------------\n\n/**\n * Wrap an Effect `Schema` as a `StructuredFormat`. Effect Schema doesn't\n * natively implement Standard Schema; this helper installs the\n * `~standard` and JSON Schema interfaces.\n */\nexport const fromEffectSchema = <S extends Schema.Codec<any, any, never, any>>(\n schema: S,\n options?: {\n readonly name?: string\n readonly description?: string\n readonly strict?: boolean\n },\n): StructuredFormat<S[\"Type\"]> => ({\n name: options?.name ?? \"output\",\n schema: Schema.toStandardJSONSchemaV1(Schema.toStandardSchemaV1(schema)),\n ...(options?.description !== undefined && {\n description: options.description,\n }),\n ...(options?.strict !== undefined && { strict: options.strict }),\n})\n\n// ---------------------------------------------------------------------------\n// Standard Schema → DecodeIssue\n// ---------------------------------------------------------------------------\n\nconst propertyKeyToScalar = Match.type<PropertyKey>().pipe(\n Match.when(Match.string, (s) => s),\n Match.when(Match.number, (n) => n),\n Match.when(Match.symbol, (s) => s.toString()),\n Match.exhaustive,\n)\n\nconst segmentToKey = Match.type<PropertyKey | StandardSchemaV1.PathSegment>().pipe(\n Match.when(Match.string, (s) => s),\n Match.when(Match.number, (n) => n),\n Match.when(Match.symbol, (s) => s.toString()),\n Match.orElse((segment) => propertyKeyToScalar(segment.key)),\n)\n\nconst issueToDecode = (issue: StandardSchemaV1.Issue): DecodeIssue => ({\n path: (issue.path ?? []).map(segmentToKey),\n message: issue.message,\n})\n\n// ---------------------------------------------------------------------------\n// Decoding\n// ---------------------------------------------------------------------------\n\n/**\n * Validate an `unknown` against the format's schema. Returns the typed\n * value or a `StructuredDecodeError`. Standard Schema's `validate` may\n * be async; this function handles both sync and async results.\n */\nexport const decode =\n <A>(format: StructuredFormat<A>) =>\n (raw: unknown): Effect.Effect<A, StructuredDecodeError> =>\n pipe(\n Effect.promise(async () => format.schema[\"~standard\"].validate(raw)),\n Effect.flatMap((result) =>\n result.issues === undefined\n ? Effect.succeed(result.value)\n : Effect.fail(\n new StructuredDecodeError({\n raw: typeof raw === \"string\" ? raw : JSON.stringify(raw),\n issues: result.issues.map(issueToDecode),\n }),\n ),\n ),\n )\n\n/**\n * Parse a JSON string then validate against the format's schema. Two\n * failure modes: `JsonParseError` (bytes weren't JSON) and\n * `StructuredDecodeError` (JSON didn't match the schema).\n */\nexport const parseJson =\n <A>(format: StructuredFormat<A>) =>\n (raw: string): Effect.Effect<A, JsonParseError | StructuredDecodeError> =>\n pipe(\n Effect.try({\n // Validation runs through Standard Schema (Zod / Valibot / Effect), not\n // Effect Schema, so its JSON codecs don't apply here; and JSON.parse is\n // a separate step on purpose, to surface JsonParseError distinctly.\n // @effect-diagnostics-next-line effect/preferSchemaOverJson:off\n try: () => JSON.parse(raw),\n catch: (cause) => new JsonParseError({ raw, cause }),\n }),\n Effect.flatMap(decode(format)),\n )\n\n/**\n * Stream operator: each input string is JSON-parsed and validated.\n * Failures surface in the stream's failure channel, distinguished by tag.\n */\nexport const decodeJsonLines =\n <A>(format: StructuredFormat<A>) =>\n <E, R>(\n self: Stream.Stream<string, E, R>,\n ): Stream.Stream<A, E | JsonParseError | StructuredDecodeError, R> =>\n self.pipe(Stream.mapEffect(parseJson(format)))\n\n/**\n * Like {@link decodeJsonLines}, but each line yields a `Result` instead of\n * failing the stream. Use when one bad line shouldn't abort the rest —\n * log-and-continue, or partial-recovery with a corrective re-prompt.\n * Upstream errors (the input stream's own `E`) still propagate normally.\n */\nexport const decodeJsonLinesRecoverable =\n <A>(format: StructuredFormat<A>) =>\n <E, R>(\n self: Stream.Stream<string, E, R>,\n ): Stream.Stream<Result.Result<A, JsonParseError | StructuredDecodeError>, E, R> =>\n self.pipe(Stream.mapEffect((line) => Effect.result(parseJson(format)(line))))\n"],"mappings":";;;;;;;;;;;;;;;;AA8CA,IAAa,wBAAb,cAA2C,KAAK,YAAY,uBAAuB,CAAC,CAGjF,CAAC;;;;;AAMJ,IAAa,iBAAb,cAAoC,KAAK,YAAY,0BAA0B,CAAC,CAG7E,CAAC;;;;;;AAWJ,MAAa,oBACX,QACA,aAKiC;CACjC,MAAM,SAAS,QAAQ;CACvB,QAAQ,OAAO,uBAAuB,OAAO,mBAAmB,MAAM,CAAC;CACvE,GAAI,SAAS,gBAAgB,KAAA,KAAa,EACxC,aAAa,QAAQ,YACvB;CACA,GAAI,SAAS,WAAW,KAAA,KAAa,EAAE,QAAQ,QAAQ,OAAO;AAChE;AAMA,MAAM,sBAAsB,MAAM,KAAkB,CAAC,CAAC,KACpD,MAAM,KAAK,MAAM,SAAS,MAAM,CAAC,GACjC,MAAM,KAAK,MAAM,SAAS,MAAM,CAAC,GACjC,MAAM,KAAK,MAAM,SAAS,MAAM,EAAE,SAAS,CAAC,GAC5C,MAAM,UACR;AAEA,MAAM,eAAe,MAAM,KAAiD,CAAC,CAAC,KAC5E,MAAM,KAAK,MAAM,SAAS,MAAM,CAAC,GACjC,MAAM,KAAK,MAAM,SAAS,MAAM,CAAC,GACjC,MAAM,KAAK,MAAM,SAAS,MAAM,EAAE,SAAS,CAAC,GAC5C,MAAM,QAAQ,YAAY,oBAAoB,QAAQ,GAAG,CAAC,CAC5D;AAEA,MAAM,iBAAiB,WAAgD;CACrE,OAAO,MAAM,QAAQ,CAAC,EAAA,CAAG,IAAI,YAAY;CACzC,SAAS,MAAM;AACjB;;;;;;AAWA,MAAa,UACP,YACH,QACC,KACE,OAAO,QAAQ,YAAY,OAAO,OAAO,YAAY,CAAC,SAAS,GAAG,CAAC,GACnE,OAAO,SAAS,WACd,OAAO,WAAW,KAAA,IACd,OAAO,QAAQ,OAAO,KAAK,IAC3B,OAAO,KACL,IAAI,sBAAsB;CACxB,KAAK,OAAO,QAAQ,WAAW,MAAM,KAAK,UAAU,GAAG;CACvD,QAAQ,OAAO,OAAO,IAAI,aAAa;AACzC,CAAC,CACH,CACN,CACF;;;;;;AAOJ,MAAa,aACP,YACH,QACC,KACE,OAAO,IAAI;CAKT,WAAW,KAAK,MAAM,GAAG;CACzB,QAAQ,UAAU,IAAI,eAAe;EAAE;EAAK;CAAM,CAAC;AACrD,CAAC,GACD,OAAO,QAAQ,OAAO,MAAM,CAAC,CAC/B;;;;;AAMJ,MAAa,mBACP,YAEF,SAEA,KAAK,KAAK,OAAO,UAAU,UAAU,MAAM,CAAC,CAAC;;;;;;;AAQjD,MAAa,8BACP,YAEF,SAEA,KAAK,KAAK,OAAO,WAAW,SAAS,OAAO,OAAO,UAAU,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- export { };
1
+ export {}
@@ -1,11 +1,13 @@
1
1
  import { JsonParseError, StructuredDecodeError, decodeJsonLines, decodeJsonLinesRecoverable, fromEffectSchema } from "./StructuredFormat.mjs";
2
- import { c as it, n as globalExpect, o as describe } from "../dist-CcRV3-A5.mjs";
2
+ import { m as it, o as describe } from "../utils-CiH_DjFW.mjs";
3
+ import { n as globalExpect } from "../test.DNmyFkvJ-YPzDR0Co.mjs";
3
4
  import { Effect, Exit, Filter, Result, Schema, Stream } from "effect";
4
5
  //#region src/structured-format/StructuredFormat.test.ts
5
- const itemFormat = fromEffectSchema(Schema.Struct({
6
+ const Item = Schema.Struct({
6
7
  id: Schema.Number,
7
8
  name: Schema.String
8
- }), { name: "Item" });
9
+ });
10
+ const itemFormat = fromEffectSchema(Item, { name: "Item" });
9
11
  const linesOf = (...xs) => Stream.fromIterable(xs);
10
12
  const collect = (s) => Effect.runPromise(Stream.runCollect(s).pipe(Effect.map((c) => Array.from(c))));
11
13
  describe("decodeJsonLinesRecoverable", () => {
@@ -48,7 +50,8 @@ describe("decodeJsonLinesRecoverable", () => {
48
50
  globalExpect(Exit.isFailure(exit)).toBe(true);
49
51
  });
50
52
  it("composes with filter-success / log-and-continue", async () => {
51
- globalExpect(await collect(linesOf("{\"id\":1,\"name\":\"a\"}", "garbage", "{\"id\":2,\"name\":\"b\"}").pipe(decodeJsonLinesRecoverable(itemFormat), Stream.filterMap(Filter.fromPredicateOption(Result.getSuccess))))).toEqual([{
53
+ const out = await collect(linesOf("{\"id\":1,\"name\":\"a\"}", "garbage", "{\"id\":2,\"name\":\"b\"}").pipe(decodeJsonLinesRecoverable(itemFormat), Stream.filterMap(Filter.fromPredicateOption(Result.getSuccess))));
54
+ globalExpect(out).toEqual([{
52
55
  id: 1,
53
56
  name: "a"
54
57
  }, {
@@ -1 +1 @@
1
- {"version":3,"file":"StructuredFormat.test.mjs","names":[],"sources":["../../src/structured-format/StructuredFormat.test.ts"],"sourcesContent":["import { Effect, Exit, Filter, Result, Schema, Stream } from \"effect\"\nimport { describe, expect, it } from \"vitest\"\nimport {\n decodeJsonLines,\n decodeJsonLinesRecoverable,\n fromEffectSchema,\n JsonParseError,\n StructuredDecodeError,\n} from \"./StructuredFormat.js\"\n\nconst Item = Schema.Struct({ id: Schema.Number, name: Schema.String })\ntype Item = typeof Item.Type\nconst itemFormat = fromEffectSchema(Item, { name: \"Item\" })\n\nconst linesOf = (...xs: ReadonlyArray<string>): Stream.Stream<string> => Stream.fromIterable(xs)\n\nconst collect = <A, E>(s: Stream.Stream<A, E>) =>\n Effect.runPromise(Stream.runCollect(s).pipe(Effect.map((c) => Array.from(c))))\n\ndescribe(\"decodeJsonLinesRecoverable\", () => {\n it(\"yields a Success for each well-formed line\", async () => {\n const out = await collect(\n linesOf('{\"id\":1,\"name\":\"a\"}', '{\"id\":2,\"name\":\"b\"}').pipe(\n decodeJsonLinesRecoverable(itemFormat),\n ),\n )\n\n expect(out).toHaveLength(2)\n expect(Result.isSuccess(out[0]!)).toBe(true)\n expect(Result.isSuccess(out[1]!)).toBe(true)\n if (Result.isSuccess(out[0]!) && Result.isSuccess(out[1]!)) {\n expect(out[0]!.success).toEqual<Item>({ id: 1, name: \"a\" })\n expect(out[1]!.success).toEqual<Item>({ id: 2, name: \"b\" })\n }\n })\n\n it(\"yields a Failure for a malformed JSON line WITHOUT aborting the stream\", async () => {\n const out = await collect(\n linesOf('{\"id\":1,\"name\":\"a\"}', \"not json at all\", '{\"id\":3,\"name\":\"c\"}').pipe(\n decodeJsonLinesRecoverable(itemFormat),\n ),\n )\n\n expect(out).toHaveLength(3)\n expect(Result.isSuccess(out[0]!)).toBe(true)\n expect(Result.isFailure(out[1]!)).toBe(true)\n expect(Result.isSuccess(out[2]!)).toBe(true)\n if (Result.isFailure(out[1]!)) {\n expect(out[1]!.failure).toBeInstanceOf(JsonParseError)\n }\n })\n\n it(\"yields a Failure for a schema-invalid line without aborting\", async () => {\n const out = await collect(\n linesOf(\n '{\"id\":1,\"name\":\"a\"}',\n '{\"id\":\"not-a-number\",\"name\":\"b\"}', // schema fail\n '{\"id\":3,\"name\":\"c\"}',\n ).pipe(decodeJsonLinesRecoverable(itemFormat)),\n )\n\n expect(out).toHaveLength(3)\n expect(Result.isSuccess(out[0]!)).toBe(true)\n expect(Result.isFailure(out[1]!)).toBe(true)\n expect(Result.isSuccess(out[2]!)).toBe(true)\n if (Result.isFailure(out[1]!)) {\n expect(out[1]!.failure).toBeInstanceOf(StructuredDecodeError)\n }\n })\n\n it(\"propagates upstream errors normally (only DECODE failures are lifted into Result)\", async () => {\n const boom = new Error(\"upstream broke\")\n const stream = Stream.concat(linesOf('{\"id\":1,\"name\":\"a\"}'), Stream.fail(boom)).pipe(\n decodeJsonLinesRecoverable(itemFormat),\n )\n\n const exit = await Effect.runPromise(Effect.exit(Stream.runCollect(stream)))\n expect(Exit.isFailure(exit)).toBe(true)\n })\n\n it(\"composes with filter-success / log-and-continue\", async () => {\n const out = await collect(\n linesOf('{\"id\":1,\"name\":\"a\"}', \"garbage\", '{\"id\":2,\"name\":\"b\"}').pipe(\n decodeJsonLinesRecoverable(itemFormat),\n Stream.filterMap(Filter.fromPredicateOption(Result.getSuccess)),\n ),\n )\n\n expect(out).toEqual<Array<Item>>([\n { id: 1, name: \"a\" },\n { id: 2, name: \"b\" },\n ])\n })\n})\n\ndescribe(\"decodeJsonLines (fail-fast, sanity)\", () => {\n it(\"aborts the stream on the first bad line\", async () => {\n const stream = linesOf('{\"id\":1,\"name\":\"a\"}', \"garbage\", '{\"id\":3,\"name\":\"c\"}').pipe(\n decodeJsonLines(itemFormat),\n )\n\n const exit = await Effect.runPromise(Effect.exit(Stream.runCollect(stream)))\n expect(Exit.isFailure(exit)).toBe(true)\n })\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"StructuredFormat.test.mjs","names":[],"sources":["../../src/structured-format/StructuredFormat.test.ts"],"sourcesContent":["import { Effect, Exit, Filter, Result, Schema, Stream } from \"effect\"\nimport { describe, expect, it } from \"vitest\"\nimport {\n decodeJsonLines,\n decodeJsonLinesRecoverable,\n fromEffectSchema,\n JsonParseError,\n StructuredDecodeError,\n} from \"./StructuredFormat.js\"\n\nconst Item = Schema.Struct({ id: Schema.Number, name: Schema.String })\ntype Item = typeof Item.Type\nconst itemFormat = fromEffectSchema(Item, { name: \"Item\" })\n\nconst linesOf = (...xs: ReadonlyArray<string>): Stream.Stream<string> => Stream.fromIterable(xs)\n\nconst collect = <A, E>(s: Stream.Stream<A, E>) =>\n Effect.runPromise(Stream.runCollect(s).pipe(Effect.map((c) => Array.from(c))))\n\ndescribe(\"decodeJsonLinesRecoverable\", () => {\n it(\"yields a Success for each well-formed line\", async () => {\n const out = await collect(\n linesOf('{\"id\":1,\"name\":\"a\"}', '{\"id\":2,\"name\":\"b\"}').pipe(\n decodeJsonLinesRecoverable(itemFormat),\n ),\n )\n\n expect(out).toHaveLength(2)\n expect(Result.isSuccess(out[0]!)).toBe(true)\n expect(Result.isSuccess(out[1]!)).toBe(true)\n if (Result.isSuccess(out[0]!) && Result.isSuccess(out[1]!)) {\n expect(out[0]!.success).toEqual<Item>({ id: 1, name: \"a\" })\n expect(out[1]!.success).toEqual<Item>({ id: 2, name: \"b\" })\n }\n })\n\n it(\"yields a Failure for a malformed JSON line WITHOUT aborting the stream\", async () => {\n const out = await collect(\n linesOf('{\"id\":1,\"name\":\"a\"}', \"not json at all\", '{\"id\":3,\"name\":\"c\"}').pipe(\n decodeJsonLinesRecoverable(itemFormat),\n ),\n )\n\n expect(out).toHaveLength(3)\n expect(Result.isSuccess(out[0]!)).toBe(true)\n expect(Result.isFailure(out[1]!)).toBe(true)\n expect(Result.isSuccess(out[2]!)).toBe(true)\n if (Result.isFailure(out[1]!)) {\n expect(out[1]!.failure).toBeInstanceOf(JsonParseError)\n }\n })\n\n it(\"yields a Failure for a schema-invalid line without aborting\", async () => {\n const out = await collect(\n linesOf(\n '{\"id\":1,\"name\":\"a\"}',\n '{\"id\":\"not-a-number\",\"name\":\"b\"}', // schema fail\n '{\"id\":3,\"name\":\"c\"}',\n ).pipe(decodeJsonLinesRecoverable(itemFormat)),\n )\n\n expect(out).toHaveLength(3)\n expect(Result.isSuccess(out[0]!)).toBe(true)\n expect(Result.isFailure(out[1]!)).toBe(true)\n expect(Result.isSuccess(out[2]!)).toBe(true)\n if (Result.isFailure(out[1]!)) {\n expect(out[1]!.failure).toBeInstanceOf(StructuredDecodeError)\n }\n })\n\n it(\"propagates upstream errors normally (only DECODE failures are lifted into Result)\", async () => {\n const boom = new Error(\"upstream broke\")\n const stream = Stream.concat(linesOf('{\"id\":1,\"name\":\"a\"}'), Stream.fail(boom)).pipe(\n decodeJsonLinesRecoverable(itemFormat),\n )\n\n const exit = await Effect.runPromise(Effect.exit(Stream.runCollect(stream)))\n expect(Exit.isFailure(exit)).toBe(true)\n })\n\n it(\"composes with filter-success / log-and-continue\", async () => {\n const out = await collect(\n linesOf('{\"id\":1,\"name\":\"a\"}', \"garbage\", '{\"id\":2,\"name\":\"b\"}').pipe(\n decodeJsonLinesRecoverable(itemFormat),\n Stream.filterMap(Filter.fromPredicateOption(Result.getSuccess)),\n ),\n )\n\n expect(out).toEqual<Array<Item>>([\n { id: 1, name: \"a\" },\n { id: 2, name: \"b\" },\n ])\n })\n})\n\ndescribe(\"decodeJsonLines (fail-fast, sanity)\", () => {\n it(\"aborts the stream on the first bad line\", async () => {\n const stream = linesOf('{\"id\":1,\"name\":\"a\"}', \"garbage\", '{\"id\":3,\"name\":\"c\"}').pipe(\n decodeJsonLines(itemFormat),\n )\n\n const exit = await Effect.runPromise(Effect.exit(Stream.runCollect(stream)))\n expect(Exit.isFailure(exit)).toBe(true)\n })\n})\n"],"mappings":"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"}