effect 4.0.4 → 4.0.6

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 (1079) hide show
  1. package/ai-docs/package.json +1 -1
  2. package/ai-docs/src/06_schedule/10_schedules.ts +5 -4
  3. package/ai-docs/src/52_graphql/10_basics.ts +19 -13
  4. package/ai-docs/src/52_graphql/30_batching.ts +6 -4
  5. package/ai-docs/src/52_graphql/40_aliased-batching.ts +6 -4
  6. package/ai-docs/tsconfig.json +3 -1
  7. package/dist/Array.d.ts +207 -58
  8. package/dist/Array.d.ts.map +1 -1
  9. package/dist/Array.js +45 -22
  10. package/dist/Array.js.map +1 -1
  11. package/dist/Bytes.d.ts +79 -0
  12. package/dist/Bytes.d.ts.map +1 -0
  13. package/dist/Bytes.js +109 -0
  14. package/dist/Bytes.js.map +1 -0
  15. package/dist/Channel.d.ts +187 -14
  16. package/dist/Channel.d.ts.map +1 -1
  17. package/dist/Channel.js +142 -33
  18. package/dist/Channel.js.map +1 -1
  19. package/dist/ChannelSchema.d.ts.map +1 -1
  20. package/dist/ChannelSchema.js.map +1 -1
  21. package/dist/Chunk.d.ts +39 -21
  22. package/dist/Chunk.d.ts.map +1 -1
  23. package/dist/Chunk.js +26 -17
  24. package/dist/Chunk.js.map +1 -1
  25. package/dist/Config.d.ts.map +1 -1
  26. package/dist/Config.js +8 -3
  27. package/dist/Config.js.map +1 -1
  28. package/dist/ConfigProvider.d.ts.map +1 -1
  29. package/dist/ConfigProvider.js +34 -32
  30. package/dist/ConfigProvider.js.map +1 -1
  31. package/dist/Cron.d.ts +2 -2
  32. package/dist/Cron.d.ts.map +1 -1
  33. package/dist/Cron.js +6 -3
  34. package/dist/Cron.js.map +1 -1
  35. package/dist/Duration.d.ts.map +1 -1
  36. package/dist/Duration.js +58 -21
  37. package/dist/Duration.js.map +1 -1
  38. package/dist/Effect.d.ts +548 -182
  39. package/dist/Effect.d.ts.map +1 -1
  40. package/dist/Effect.js +261 -76
  41. package/dist/Effect.js.map +1 -1
  42. package/dist/Equivalence.d.ts +2 -1
  43. package/dist/Equivalence.d.ts.map +1 -1
  44. package/dist/Equivalence.js +12 -8
  45. package/dist/Equivalence.js.map +1 -1
  46. package/dist/Exit.d.ts +24 -9
  47. package/dist/Exit.d.ts.map +1 -1
  48. package/dist/Exit.js +8 -3
  49. package/dist/Exit.js.map +1 -1
  50. package/dist/FiberHandle.d.ts +2 -0
  51. package/dist/FiberHandle.d.ts.map +1 -1
  52. package/dist/FiberHandle.js +9 -4
  53. package/dist/FiberHandle.js.map +1 -1
  54. package/dist/FiberMap.d.ts +2 -0
  55. package/dist/FiberMap.d.ts.map +1 -1
  56. package/dist/FiberMap.js +5 -2
  57. package/dist/FiberMap.js.map +1 -1
  58. package/dist/FileSystem.d.ts +28 -9
  59. package/dist/FileSystem.d.ts.map +1 -1
  60. package/dist/FileSystem.js +3 -0
  61. package/dist/FileSystem.js.map +1 -1
  62. package/dist/Graph.d.ts.map +1 -1
  63. package/dist/Graph.js.map +1 -1
  64. package/dist/HashSet.d.ts.map +1 -1
  65. package/dist/HashSet.js.map +1 -1
  66. package/dist/Iterable.d.ts.map +1 -1
  67. package/dist/Iterable.js +18 -17
  68. package/dist/Iterable.js.map +1 -1
  69. package/dist/JsonSchema.d.ts +9 -3
  70. package/dist/JsonSchema.d.ts.map +1 -1
  71. package/dist/JsonSchema.js +19 -3
  72. package/dist/JsonSchema.js.map +1 -1
  73. package/dist/Layer.d.ts.map +1 -1
  74. package/dist/Layer.js +2 -2
  75. package/dist/Layer.js.map +1 -1
  76. package/dist/ManagedRuntime.d.ts +19 -1
  77. package/dist/ManagedRuntime.d.ts.map +1 -1
  78. package/dist/ManagedRuntime.js +62 -6
  79. package/dist/ManagedRuntime.js.map +1 -1
  80. package/dist/Match.d.ts +20 -6
  81. package/dist/Match.d.ts.map +1 -1
  82. package/dist/Match.js +2 -2
  83. package/dist/Match.js.map +1 -1
  84. package/dist/Metric.d.ts +132 -0
  85. package/dist/Metric.d.ts.map +1 -1
  86. package/dist/Metric.js +197 -25
  87. package/dist/Metric.js.map +1 -1
  88. package/dist/MutableHashMap.d.ts.map +1 -1
  89. package/dist/MutableHashMap.js.map +1 -1
  90. package/dist/Number.js +2 -2
  91. package/dist/Number.js.map +1 -1
  92. package/dist/Optic.d.ts.map +1 -1
  93. package/dist/Optic.js.map +1 -1
  94. package/dist/Path.d.ts +37 -5
  95. package/dist/Path.d.ts.map +1 -1
  96. package/dist/Path.js +44 -6
  97. package/dist/Path.js.map +1 -1
  98. package/dist/PubSub.d.ts.map +1 -1
  99. package/dist/PubSub.js +12 -7
  100. package/dist/PubSub.js.map +1 -1
  101. package/dist/Queue.d.ts +4 -1
  102. package/dist/Queue.d.ts.map +1 -1
  103. package/dist/Queue.js +4 -1
  104. package/dist/Queue.js.map +1 -1
  105. package/dist/Random.d.ts.map +1 -1
  106. package/dist/Random.js +1 -1
  107. package/dist/Random.js.map +1 -1
  108. package/dist/RcMap.d.ts +12 -7
  109. package/dist/RcMap.d.ts.map +1 -1
  110. package/dist/RcMap.js +9 -6
  111. package/dist/RcMap.js.map +1 -1
  112. package/dist/Record.d.ts +51 -0
  113. package/dist/Record.d.ts.map +1 -1
  114. package/dist/Record.js +17 -0
  115. package/dist/Record.js.map +1 -1
  116. package/dist/Ref.d.ts.map +1 -1
  117. package/dist/Ref.js.map +1 -1
  118. package/dist/References.d.ts +5 -4
  119. package/dist/References.d.ts.map +1 -1
  120. package/dist/References.js +5 -4
  121. package/dist/References.js.map +1 -1
  122. package/dist/RequestResolver.d.ts +31 -1
  123. package/dist/RequestResolver.d.ts.map +1 -1
  124. package/dist/RequestResolver.js +39 -4
  125. package/dist/RequestResolver.js.map +1 -1
  126. package/dist/Resource.js +1 -1
  127. package/dist/Resource.js.map +1 -1
  128. package/dist/Runtime.d.ts +3 -3
  129. package/dist/Runtime.d.ts.map +1 -1
  130. package/dist/Runtime.js +18 -15
  131. package/dist/Runtime.js.map +1 -1
  132. package/dist/Schedule.d.ts.map +1 -1
  133. package/dist/Schedule.js.map +1 -1
  134. package/dist/Schema.d.ts +383 -326
  135. package/dist/Schema.d.ts.map +1 -1
  136. package/dist/Schema.js +338 -17
  137. package/dist/Schema.js.map +1 -1
  138. package/dist/SchemaAST.d.ts +5 -5
  139. package/dist/SchemaAST.d.ts.map +1 -1
  140. package/dist/SchemaAST.js +24 -8
  141. package/dist/SchemaAST.js.map +1 -1
  142. package/dist/SchemaGetter.d.ts +8 -3
  143. package/dist/SchemaGetter.d.ts.map +1 -1
  144. package/dist/SchemaGetter.js +15 -5
  145. package/dist/SchemaGetter.js.map +1 -1
  146. package/dist/SchemaIssue.d.ts +4 -4
  147. package/dist/SchemaIssue.d.ts.map +1 -1
  148. package/dist/SchemaIssue.js +29 -51
  149. package/dist/SchemaIssue.js.map +1 -1
  150. package/dist/SchemaRepresentation.d.ts +56 -1
  151. package/dist/SchemaRepresentation.d.ts.map +1 -1
  152. package/dist/SchemaRepresentation.js +18 -0
  153. package/dist/SchemaRepresentation.js.map +1 -1
  154. package/dist/SchemaTransformation.d.ts +1 -1
  155. package/dist/SchemaTransformation.js +1 -1
  156. package/dist/Scope.d.ts +12 -2
  157. package/dist/Scope.d.ts.map +1 -1
  158. package/dist/Scope.js +5 -0
  159. package/dist/Scope.js.map +1 -1
  160. package/dist/ScopedCache.d.ts +10 -7
  161. package/dist/ScopedCache.d.ts.map +1 -1
  162. package/dist/ScopedCache.js +9 -5
  163. package/dist/ScopedCache.js.map +1 -1
  164. package/dist/SemVer.d.ts +1196 -0
  165. package/dist/SemVer.d.ts.map +1 -0
  166. package/dist/SemVer.js +756 -0
  167. package/dist/SemVer.js.map +1 -0
  168. package/dist/SemVerRange.d.ts +559 -0
  169. package/dist/SemVerRange.d.ts.map +1 -0
  170. package/dist/SemVerRange.js +551 -0
  171. package/dist/SemVerRange.js.map +1 -0
  172. package/dist/Sink.d.ts.map +1 -1
  173. package/dist/Sink.js +6 -2
  174. package/dist/Sink.js.map +1 -1
  175. package/dist/Stream.d.ts +235 -8
  176. package/dist/Stream.d.ts.map +1 -1
  177. package/dist/Stream.js +145 -60
  178. package/dist/Stream.js.map +1 -1
  179. package/dist/String.d.ts +16 -2
  180. package/dist/String.d.ts.map +1 -1
  181. package/dist/String.js +25 -10
  182. package/dist/String.js.map +1 -1
  183. package/dist/TextDiff.d.ts +399 -0
  184. package/dist/TextDiff.d.ts.map +1 -0
  185. package/dist/TextDiff.js +634 -0
  186. package/dist/TextDiff.js.map +1 -0
  187. package/dist/TxHashMap.d.ts.map +1 -1
  188. package/dist/TxHashMap.js.map +1 -1
  189. package/dist/TxHashSet.d.ts.map +1 -1
  190. package/dist/TxHashSet.js.map +1 -1
  191. package/dist/TxRef.d.ts.map +1 -1
  192. package/dist/TxRef.js +3 -2
  193. package/dist/TxRef.js.map +1 -1
  194. package/dist/ai/AiError.d.ts +78 -14
  195. package/dist/ai/AiError.d.ts.map +1 -1
  196. package/dist/ai/AiError.js +51 -3
  197. package/dist/ai/AiError.js.map +1 -1
  198. package/dist/ai/Chat.d.ts +1 -2
  199. package/dist/ai/Chat.d.ts.map +1 -1
  200. package/dist/ai/Chat.js +6 -3
  201. package/dist/ai/Chat.js.map +1 -1
  202. package/dist/ai/Decision.d.ts +116 -20
  203. package/dist/ai/Decision.d.ts.map +1 -1
  204. package/dist/ai/Decision.js +37 -3
  205. package/dist/ai/Decision.js.map +1 -1
  206. package/dist/ai/DecisionModel.d.ts +129 -11
  207. package/dist/ai/DecisionModel.d.ts.map +1 -1
  208. package/dist/ai/DecisionModel.js +183 -95
  209. package/dist/ai/DecisionModel.js.map +1 -1
  210. package/dist/ai/EmbeddingModel.d.ts +10 -0
  211. package/dist/ai/EmbeddingModel.d.ts.map +1 -1
  212. package/dist/ai/EmbeddingModel.js +21 -7
  213. package/dist/ai/EmbeddingModel.js.map +1 -1
  214. package/dist/ai/LanguageModel.d.ts.map +1 -1
  215. package/dist/ai/LanguageModel.js +47 -35
  216. package/dist/ai/LanguageModel.js.map +1 -1
  217. package/dist/ai/McpClient.d.ts +289 -0
  218. package/dist/ai/McpClient.d.ts.map +1 -0
  219. package/dist/ai/McpClient.js +819 -0
  220. package/dist/ai/McpClient.js.map +1 -0
  221. package/dist/ai/McpClientError.d.ts +254 -0
  222. package/dist/ai/McpClientError.d.ts.map +1 -0
  223. package/dist/ai/McpClientError.js +260 -0
  224. package/dist/ai/McpClientError.js.map +1 -0
  225. package/dist/ai/McpProtocol.d.ts +2 -2
  226. package/dist/ai/McpProtocol.d.ts.map +1 -1
  227. package/dist/ai/McpSchema.d.ts +368 -235
  228. package/dist/ai/McpSchema.d.ts.map +1 -1
  229. package/dist/ai/McpSchema.js +94 -24
  230. package/dist/ai/McpSchema.js.map +1 -1
  231. package/dist/ai/McpServer.d.ts +6 -52
  232. package/dist/ai/McpServer.d.ts.map +1 -1
  233. package/dist/ai/McpServer.js +27 -50
  234. package/dist/ai/McpServer.js.map +1 -1
  235. package/dist/ai/Prompt.d.ts +22 -20
  236. package/dist/ai/Prompt.d.ts.map +1 -1
  237. package/dist/ai/Prompt.js +23 -1
  238. package/dist/ai/Prompt.js.map +1 -1
  239. package/dist/ai/Response.d.ts +148 -4
  240. package/dist/ai/Response.d.ts.map +1 -1
  241. package/dist/ai/Response.js +35 -37
  242. package/dist/ai/Response.js.map +1 -1
  243. package/dist/ai/Tool.d.ts +12 -4
  244. package/dist/ai/Tool.d.ts.map +1 -1
  245. package/dist/ai/Tool.js.map +1 -1
  246. package/dist/ai/Toolkit.d.ts +48 -1
  247. package/dist/ai/Toolkit.d.ts.map +1 -1
  248. package/dist/ai/Toolkit.js +65 -12
  249. package/dist/ai/Toolkit.js.map +1 -1
  250. package/dist/ai/index.d.ts +10 -0
  251. package/dist/ai/index.d.ts.map +1 -1
  252. package/dist/ai/index.js +10 -0
  253. package/dist/ai/index.js.map +1 -1
  254. package/dist/ai/internal/mcpCore.js.map +1 -1
  255. package/dist/ai/internal/mcpProtocol/v2024_11_05.js +1 -1
  256. package/dist/ai/internal/mcpProtocol/v2024_11_05.js.map +1 -1
  257. package/dist/ai/internal/mcpProtocol/v2025_03_26.js +1 -1
  258. package/dist/ai/internal/mcpProtocol/v2025_03_26.js.map +1 -1
  259. package/dist/ai/internal/mcpProtocol/v2025_06_18.js +2 -2
  260. package/dist/ai/internal/mcpProtocol/v2025_06_18.js.map +1 -1
  261. package/dist/ai/internal/mcpProtocol/v2025_11_25.js +2 -2
  262. package/dist/ai/internal/mcpProtocol/v2025_11_25.js.map +1 -1
  263. package/dist/ai/internal/mcpProtocol/v2026_07_28.js +4 -7
  264. package/dist/ai/internal/mcpProtocol/v2026_07_28.js.map +1 -1
  265. package/dist/ai/internal/mcpProtocol.js +16 -2
  266. package/dist/ai/internal/mcpProtocol.js.map +1 -1
  267. package/dist/ai/internal/mcpRuntime.js +3 -4
  268. package/dist/ai/internal/mcpRuntime.js.map +1 -1
  269. package/dist/ai/internal/mcpSchema/v2024_11_05.js +19 -13
  270. package/dist/ai/internal/mcpSchema/v2024_11_05.js.map +1 -1
  271. package/dist/ai/internal/mcpSchema/v2025_03_26.js +3 -2
  272. package/dist/ai/internal/mcpSchema/v2025_03_26.js.map +1 -1
  273. package/dist/ai/internal/mcpSchema/v2025_06_18.js +7 -7
  274. package/dist/ai/internal/mcpSchema/v2025_06_18.js.map +1 -1
  275. package/dist/ai/internal/mcpSchema/v2025_11_25.js +8 -8
  276. package/dist/ai/internal/mcpSchema/v2025_11_25.js.map +1 -1
  277. package/dist/ai/internal/mcpSchema/v2026_07_28.js +43 -42
  278. package/dist/ai/internal/mcpSchema/v2026_07_28.js.map +1 -1
  279. package/dist/cli/CliError.d.ts +42 -2
  280. package/dist/cli/CliError.d.ts.map +1 -1
  281. package/dist/cli/CliError.js +44 -5
  282. package/dist/cli/CliError.js.map +1 -1
  283. package/dist/cli/Command.d.ts +286 -2
  284. package/dist/cli/Command.d.ts.map +1 -1
  285. package/dist/cli/Command.js +107 -6
  286. package/dist/cli/Command.js.map +1 -1
  287. package/dist/cli/Completions.d.ts +10 -0
  288. package/dist/cli/Completions.d.ts.map +1 -1
  289. package/dist/cli/Completions.js.map +1 -1
  290. package/dist/cli/Flag.d.ts +215 -0
  291. package/dist/cli/Flag.d.ts.map +1 -1
  292. package/dist/cli/Flag.js +89 -0
  293. package/dist/cli/Flag.js.map +1 -1
  294. package/dist/cli/GlobalFlag.d.ts.map +1 -1
  295. package/dist/cli/GlobalFlag.js +3 -3
  296. package/dist/cli/GlobalFlag.js.map +1 -1
  297. package/dist/cli/Param.d.ts +194 -0
  298. package/dist/cli/Param.d.ts.map +1 -1
  299. package/dist/cli/Param.js +86 -0
  300. package/dist/cli/Param.js.map +1 -1
  301. package/dist/cli/TerminalCapabilities.d.ts +84 -0
  302. package/dist/cli/TerminalCapabilities.d.ts.map +1 -0
  303. package/dist/cli/TerminalCapabilities.js +122 -0
  304. package/dist/cli/TerminalCapabilities.js.map +1 -0
  305. package/dist/cli/index.d.ts +5 -0
  306. package/dist/cli/index.d.ts.map +1 -1
  307. package/dist/cli/index.js +5 -0
  308. package/dist/cli/index.js.map +1 -1
  309. package/dist/cli/internal/command.d.ts +2 -1
  310. package/dist/cli/internal/command.d.ts.map +1 -1
  311. package/dist/cli/internal/command.js +7 -3
  312. package/dist/cli/internal/command.js.map +1 -1
  313. package/dist/cli/internal/completions/bash.js +7 -5
  314. package/dist/cli/internal/completions/bash.js.map +1 -1
  315. package/dist/cli/internal/completions/descriptor.js +16 -1
  316. package/dist/cli/internal/completions/descriptor.js.map +1 -1
  317. package/dist/cli/internal/completions/fish.js +12 -10
  318. package/dist/cli/internal/completions/fish.js.map +1 -1
  319. package/dist/cli/internal/completions/powershell.js +20 -10
  320. package/dist/cli/internal/completions/powershell.js.map +1 -1
  321. package/dist/cli/internal/completions/zsh.js +15 -8
  322. package/dist/cli/internal/completions/zsh.js.map +1 -1
  323. package/dist/cli/internal/formatter.d.ts +2 -0
  324. package/dist/cli/internal/formatter.d.ts.map +1 -0
  325. package/dist/cli/internal/formatter.js +15 -0
  326. package/dist/cli/internal/formatter.js.map +1 -0
  327. package/dist/cli/internal/lexer.js +24 -10
  328. package/dist/cli/internal/lexer.js.map +1 -1
  329. package/dist/cli/internal/parser.js +35 -15
  330. package/dist/cli/internal/parser.js.map +1 -1
  331. package/dist/cli/internal/wizard.d.ts.map +1 -1
  332. package/dist/cli/internal/wizard.js +2 -1
  333. package/dist/cli/internal/wizard.js.map +1 -1
  334. package/dist/cluster/ClusterCron.d.ts +29 -1
  335. package/dist/cluster/ClusterCron.d.ts.map +1 -1
  336. package/dist/cluster/ClusterCron.js +64 -32
  337. package/dist/cluster/ClusterCron.js.map +1 -1
  338. package/dist/cluster/ClusterMetrics.d.ts +143 -7
  339. package/dist/cluster/ClusterMetrics.d.ts.map +1 -1
  340. package/dist/cluster/ClusterMetrics.js +151 -7
  341. package/dist/cluster/ClusterMetrics.js.map +1 -1
  342. package/dist/cluster/ClusterWorkflowEngine.d.ts +2 -1
  343. package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
  344. package/dist/cluster/ClusterWorkflowEngine.js +98 -18
  345. package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
  346. package/dist/cluster/Entity.d.ts +2 -0
  347. package/dist/cluster/Entity.d.ts.map +1 -1
  348. package/dist/cluster/Entity.js.map +1 -1
  349. package/dist/cluster/MessageStorage.d.ts +21 -0
  350. package/dist/cluster/MessageStorage.d.ts.map +1 -1
  351. package/dist/cluster/MessageStorage.js +20 -12
  352. package/dist/cluster/MessageStorage.js.map +1 -1
  353. package/dist/cluster/Runners.d.ts.map +1 -1
  354. package/dist/cluster/Runners.js +96 -37
  355. package/dist/cluster/Runners.js.map +1 -1
  356. package/dist/cluster/Sharding.d.ts +1 -0
  357. package/dist/cluster/Sharding.d.ts.map +1 -1
  358. package/dist/cluster/Sharding.js +95 -32
  359. package/dist/cluster/Sharding.js.map +1 -1
  360. package/dist/cluster/ShardingConfig.d.ts +20 -0
  361. package/dist/cluster/ShardingConfig.d.ts.map +1 -1
  362. package/dist/cluster/ShardingConfig.js +4 -0
  363. package/dist/cluster/ShardingConfig.js.map +1 -1
  364. package/dist/cluster/SqlMessageStorage.d.ts.map +1 -1
  365. package/dist/cluster/SqlMessageStorage.js +40 -50
  366. package/dist/cluster/SqlMessageStorage.js.map +1 -1
  367. package/dist/cluster/SqlRunnerStorage.d.ts +2 -2
  368. package/dist/cluster/SqlRunnerStorage.d.ts.map +1 -1
  369. package/dist/cluster/SqlRunnerStorage.js +10 -4
  370. package/dist/cluster/SqlRunnerStorage.js.map +1 -1
  371. package/dist/cluster/internal/entityManager.js +66 -9
  372. package/dist/cluster/internal/entityManager.js.map +1 -1
  373. package/dist/devtools/DevTools.d.ts +3 -2
  374. package/dist/devtools/DevTools.d.ts.map +1 -1
  375. package/dist/devtools/DevTools.js +3 -2
  376. package/dist/devtools/DevTools.js.map +1 -1
  377. package/dist/devtools/DevToolsClient.d.ts +11 -0
  378. package/dist/devtools/DevToolsClient.d.ts.map +1 -1
  379. package/dist/devtools/DevToolsClient.js +31 -4
  380. package/dist/devtools/DevToolsClient.js.map +1 -1
  381. package/dist/encoding/Base64Url.d.ts +29 -0
  382. package/dist/encoding/Base64Url.d.ts.map +1 -1
  383. package/dist/encoding/Base64Url.js +29 -0
  384. package/dist/encoding/Base64Url.js.map +1 -1
  385. package/dist/encoding/Ini.d.ts.map +1 -1
  386. package/dist/encoding/Ini.js +3 -0
  387. package/dist/encoding/Ini.js.map +1 -1
  388. package/dist/encoding/JsonArray.d.ts +270 -0
  389. package/dist/encoding/JsonArray.d.ts.map +1 -0
  390. package/dist/encoding/JsonArray.js +691 -0
  391. package/dist/encoding/JsonArray.js.map +1 -0
  392. package/dist/encoding/Ndjson.d.ts +43 -4
  393. package/dist/encoding/Ndjson.d.ts.map +1 -1
  394. package/dist/encoding/Ndjson.js +169 -18
  395. package/dist/encoding/Ndjson.js.map +1 -1
  396. package/dist/encoding/SchemaBinary.d.ts +9 -1
  397. package/dist/encoding/SchemaBinary.d.ts.map +1 -1
  398. package/dist/encoding/SchemaBinary.js +12 -19
  399. package/dist/encoding/SchemaBinary.js.map +1 -1
  400. package/dist/encoding/Sse.js +1 -1
  401. package/dist/encoding/Sse.js.map +1 -1
  402. package/dist/encoding/Tar.d.ts +309 -0
  403. package/dist/encoding/Tar.d.ts.map +1 -0
  404. package/dist/encoding/Tar.js +1182 -0
  405. package/dist/encoding/Tar.js.map +1 -0
  406. package/dist/encoding/Toml.js +3 -3
  407. package/dist/encoding/Toml.js.map +1 -1
  408. package/dist/encoding/Xml.d.ts +464 -0
  409. package/dist/encoding/Xml.d.ts.map +1 -0
  410. package/dist/encoding/Xml.js +1619 -0
  411. package/dist/encoding/Xml.js.map +1 -0
  412. package/dist/encoding/Yaml.d.ts +6 -2
  413. package/dist/encoding/Yaml.d.ts.map +1 -1
  414. package/dist/encoding/Yaml.js +97 -34
  415. package/dist/encoding/Yaml.js.map +1 -1
  416. package/dist/encoding/Zip.d.ts +413 -0
  417. package/dist/encoding/Zip.d.ts.map +1 -0
  418. package/dist/encoding/Zip.js +1255 -0
  419. package/dist/encoding/Zip.js.map +1 -0
  420. package/dist/encoding/index.d.ts +20 -0
  421. package/dist/encoding/index.d.ts.map +1 -1
  422. package/dist/encoding/index.js +20 -0
  423. package/dist/encoding/index.js.map +1 -1
  424. package/dist/eventlog/EventJournal.d.ts +90 -5
  425. package/dist/eventlog/EventJournal.d.ts.map +1 -1
  426. package/dist/eventlog/EventJournal.js +488 -228
  427. package/dist/eventlog/EventJournal.js.map +1 -1
  428. package/dist/eventlog/EventLog.d.ts +180 -12
  429. package/dist/eventlog/EventLog.d.ts.map +1 -1
  430. package/dist/eventlog/EventLog.js +394 -146
  431. package/dist/eventlog/EventLog.js.map +1 -1
  432. package/dist/eventlog/EventLogEncryption.d.ts +36 -30
  433. package/dist/eventlog/EventLogEncryption.d.ts.map +1 -1
  434. package/dist/eventlog/EventLogEncryption.js +97 -38
  435. package/dist/eventlog/EventLogEncryption.js.map +1 -1
  436. package/dist/eventlog/EventLogMessage.d.ts +74 -34
  437. package/dist/eventlog/EventLogMessage.d.ts.map +1 -1
  438. package/dist/eventlog/EventLogMessage.js +45 -11
  439. package/dist/eventlog/EventLogMessage.js.map +1 -1
  440. package/dist/eventlog/EventLogRemote.d.ts +45 -8
  441. package/dist/eventlog/EventLogRemote.d.ts.map +1 -1
  442. package/dist/eventlog/EventLogRemote.js +51 -14
  443. package/dist/eventlog/EventLogRemote.js.map +1 -1
  444. package/dist/eventlog/EventLogServer.d.ts +46 -3
  445. package/dist/eventlog/EventLogServer.d.ts.map +1 -1
  446. package/dist/eventlog/EventLogServer.js +119 -19
  447. package/dist/eventlog/EventLogServer.js.map +1 -1
  448. package/dist/eventlog/EventLogServerEncrypted.d.ts +23 -33
  449. package/dist/eventlog/EventLogServerEncrypted.d.ts.map +1 -1
  450. package/dist/eventlog/EventLogServerEncrypted.js +97 -70
  451. package/dist/eventlog/EventLogServerEncrypted.js.map +1 -1
  452. package/dist/eventlog/EventLogServerUnencrypted.d.ts +39 -5
  453. package/dist/eventlog/EventLogServerUnencrypted.d.ts.map +1 -1
  454. package/dist/eventlog/EventLogServerUnencrypted.js +151 -69
  455. package/dist/eventlog/EventLogServerUnencrypted.js.map +1 -1
  456. package/dist/eventlog/EventRow.d.ts +288 -0
  457. package/dist/eventlog/EventRow.d.ts.map +1 -0
  458. package/dist/eventlog/EventRow.js +435 -0
  459. package/dist/eventlog/EventRow.js.map +1 -0
  460. package/dist/eventlog/SqlEventJournal.d.ts +18 -18
  461. package/dist/eventlog/SqlEventJournal.d.ts.map +1 -1
  462. package/dist/eventlog/SqlEventJournal.js +387 -159
  463. package/dist/eventlog/SqlEventJournal.js.map +1 -1
  464. package/dist/eventlog/SqlEventLogServerEncrypted.d.ts +10 -18
  465. package/dist/eventlog/SqlEventLogServerEncrypted.d.ts.map +1 -1
  466. package/dist/eventlog/SqlEventLogServerEncrypted.js +179 -69
  467. package/dist/eventlog/SqlEventLogServerEncrypted.js.map +1 -1
  468. package/dist/eventlog/SqlEventLogServerUnencrypted.d.ts +23 -3
  469. package/dist/eventlog/SqlEventLogServerUnencrypted.d.ts.map +1 -1
  470. package/dist/eventlog/SqlEventLogServerUnencrypted.js +102 -51
  471. package/dist/eventlog/SqlEventLogServerUnencrypted.js.map +1 -1
  472. package/dist/eventlog/index.d.ts +5 -0
  473. package/dist/eventlog/index.d.ts.map +1 -1
  474. package/dist/eventlog/index.js +5 -0
  475. package/dist/eventlog/index.js.map +1 -1
  476. package/dist/eventlog/internal/conflicts.d.ts +47 -0
  477. package/dist/eventlog/internal/conflicts.d.ts.map +1 -0
  478. package/dist/eventlog/internal/conflicts.js +92 -0
  479. package/dist/eventlog/internal/conflicts.js.map +1 -0
  480. package/dist/graphql/GraphQLClient.d.ts.map +1 -1
  481. package/dist/graphql/GraphQLClient.js +12 -5
  482. package/dist/graphql/GraphQLClient.js.map +1 -1
  483. package/dist/graphql/GraphQLClientError.d.ts +2 -2
  484. package/dist/graphql/GraphQLClientError.d.ts.map +1 -1
  485. package/dist/graphql/GraphQLClientError.js +4 -18
  486. package/dist/graphql/GraphQLClientError.js.map +1 -1
  487. package/dist/graphql/GraphQLProtocol.d.ts +252 -11
  488. package/dist/graphql/GraphQLProtocol.d.ts.map +1 -1
  489. package/dist/graphql/GraphQLProtocol.js +99 -8
  490. package/dist/graphql/GraphQLProtocol.js.map +1 -1
  491. package/dist/graphql/GraphQLResolver.d.ts +3 -1
  492. package/dist/graphql/GraphQLResolver.d.ts.map +1 -1
  493. package/dist/graphql/GraphQLResolver.js +91 -19
  494. package/dist/graphql/GraphQLResolver.js.map +1 -1
  495. package/dist/http/FetchHttpClient.d.ts +13 -3
  496. package/dist/http/FetchHttpClient.d.ts.map +1 -1
  497. package/dist/http/FetchHttpClient.js +56 -6
  498. package/dist/http/FetchHttpClient.js.map +1 -1
  499. package/dist/http/FindMyWay/internal/router.js +12 -1
  500. package/dist/http/FindMyWay/internal/router.js.map +1 -1
  501. package/dist/http/Headers.d.ts +230 -3
  502. package/dist/http/Headers.d.ts.map +1 -1
  503. package/dist/http/Headers.js +267 -5
  504. package/dist/http/Headers.js.map +1 -1
  505. package/dist/http/HttpClient.d.ts +105 -0
  506. package/dist/http/HttpClient.d.ts.map +1 -1
  507. package/dist/http/HttpClient.js +69 -17
  508. package/dist/http/HttpClient.js.map +1 -1
  509. package/dist/http/HttpClientError.d.ts.map +1 -1
  510. package/dist/http/HttpClientError.js +8 -6
  511. package/dist/http/HttpClientError.js.map +1 -1
  512. package/dist/http/HttpClientRequest.d.ts +274 -7
  513. package/dist/http/HttpClientRequest.d.ts.map +1 -1
  514. package/dist/http/HttpClientRequest.js +91 -3
  515. package/dist/http/HttpClientRequest.js.map +1 -1
  516. package/dist/http/HttpClientResponse.d.ts +53 -0
  517. package/dist/http/HttpClientResponse.d.ts.map +1 -1
  518. package/dist/http/HttpClientResponse.js +47 -0
  519. package/dist/http/HttpClientResponse.js.map +1 -1
  520. package/dist/http/HttpEffect.d.ts +6 -2
  521. package/dist/http/HttpEffect.d.ts.map +1 -1
  522. package/dist/http/HttpEffect.js +21 -17
  523. package/dist/http/HttpEffect.js.map +1 -1
  524. package/dist/http/HttpIncomingMessage.d.ts +2 -1
  525. package/dist/http/HttpIncomingMessage.d.ts.map +1 -1
  526. package/dist/http/HttpIncomingMessage.js +3 -23
  527. package/dist/http/HttpIncomingMessage.js.map +1 -1
  528. package/dist/http/HttpMiddleware.d.ts +179 -2
  529. package/dist/http/HttpMiddleware.d.ts.map +1 -1
  530. package/dist/http/HttpMiddleware.js +226 -18
  531. package/dist/http/HttpMiddleware.js.map +1 -1
  532. package/dist/http/HttpRouter.d.ts.map +1 -1
  533. package/dist/http/HttpRouter.js +58 -14
  534. package/dist/http/HttpRouter.js.map +1 -1
  535. package/dist/http/HttpServerError.d.ts +5 -2
  536. package/dist/http/HttpServerError.d.ts.map +1 -1
  537. package/dist/http/HttpServerError.js +11 -7
  538. package/dist/http/HttpServerError.js.map +1 -1
  539. package/dist/http/HttpServerRequest.d.ts +25 -5
  540. package/dist/http/HttpServerRequest.d.ts.map +1 -1
  541. package/dist/http/HttpServerRequest.js +38 -12
  542. package/dist/http/HttpServerRequest.js.map +1 -1
  543. package/dist/http/HttpServerResponse.d.ts +17 -8
  544. package/dist/http/HttpServerResponse.d.ts.map +1 -1
  545. package/dist/http/HttpServerResponse.js +37 -21
  546. package/dist/http/HttpServerResponse.js.map +1 -1
  547. package/dist/http/HttpStaticServer.d.ts +0 -12
  548. package/dist/http/HttpStaticServer.d.ts.map +1 -1
  549. package/dist/http/HttpStaticServer.js +25 -17
  550. package/dist/http/HttpStaticServer.js.map +1 -1
  551. package/dist/http/HttpTraceContext.js +1 -1
  552. package/dist/http/HttpTraceContext.js.map +1 -1
  553. package/dist/http/MultipartParser/internal/contentType.d.ts +15 -1
  554. package/dist/http/MultipartParser/internal/contentType.d.ts.map +1 -1
  555. package/dist/http/MultipartParser/internal/contentType.js +87 -5
  556. package/dist/http/MultipartParser/internal/contentType.js.map +1 -1
  557. package/dist/http/MultipartParser/internal/headers.d.ts.map +1 -1
  558. package/dist/http/MultipartParser/internal/headers.js +4 -12
  559. package/dist/http/MultipartParser/internal/headers.js.map +1 -1
  560. package/dist/http/MultipartParser/internal/multipart.d.ts.map +1 -1
  561. package/dist/http/MultipartParser/internal/multipart.js +6 -27
  562. package/dist/http/MultipartParser/internal/multipart.js.map +1 -1
  563. package/dist/http/Url.d.ts.map +1 -1
  564. package/dist/http/Url.js +8 -2
  565. package/dist/http/Url.js.map +1 -1
  566. package/dist/http/UrlParams.d.ts +112 -8
  567. package/dist/http/UrlParams.d.ts.map +1 -1
  568. package/dist/http/UrlParams.js +141 -14
  569. package/dist/http/UrlParams.js.map +1 -1
  570. package/dist/http/internal/compression.d.ts +1 -1
  571. package/dist/http/internal/compression.d.ts.map +1 -1
  572. package/dist/http/internal/compression.js +2 -10
  573. package/dist/http/internal/compression.js.map +1 -1
  574. package/dist/http/internal/compressionBody.d.ts +2 -0
  575. package/dist/http/internal/compressionBody.d.ts.map +1 -0
  576. package/dist/http/internal/compressionBody.js +36 -0
  577. package/dist/http/internal/compressionBody.js.map +1 -0
  578. package/dist/http/internal/decompression.d.ts +2 -0
  579. package/dist/http/internal/decompression.d.ts.map +1 -0
  580. package/dist/http/internal/decompression.js +168 -0
  581. package/dist/http/internal/decompression.js.map +1 -0
  582. package/dist/http/internal/lazyStream.d.ts +2 -0
  583. package/dist/http/internal/lazyStream.d.ts.map +1 -0
  584. package/dist/http/internal/lazyStream.js +18 -0
  585. package/dist/http/internal/lazyStream.js.map +1 -0
  586. package/dist/http/internal/requestState.d.ts +2 -0
  587. package/dist/http/internal/requestState.d.ts.map +1 -0
  588. package/dist/http/internal/requestState.js +28 -0
  589. package/dist/http/internal/requestState.js.map +1 -0
  590. package/dist/http/internal/tracing.js +14 -4
  591. package/dist/http/internal/tracing.js.map +1 -1
  592. package/dist/http/internal/urlParams.d.ts +2 -0
  593. package/dist/http/internal/urlParams.d.ts.map +1 -0
  594. package/dist/http/internal/urlParams.js +4 -0
  595. package/dist/http/internal/urlParams.js.map +1 -0
  596. package/dist/http/internal/webResponse.d.ts +2 -0
  597. package/dist/http/internal/webResponse.d.ts.map +1 -0
  598. package/dist/http/internal/webResponse.js +12 -0
  599. package/dist/http/internal/webResponse.js.map +1 -0
  600. package/dist/http-api/HttpApi.js +1 -1
  601. package/dist/http-api/HttpApi.js.map +1 -1
  602. package/dist/http-api/HttpApiBuilder.d.ts.map +1 -1
  603. package/dist/http-api/HttpApiBuilder.js +121 -18
  604. package/dist/http-api/HttpApiBuilder.js.map +1 -1
  605. package/dist/http-api/HttpApiClient.d.ts +29 -4
  606. package/dist/http-api/HttpApiClient.d.ts.map +1 -1
  607. package/dist/http-api/HttpApiClient.js +85 -24
  608. package/dist/http-api/HttpApiClient.js.map +1 -1
  609. package/dist/http-api/HttpApiEndpoint.d.ts +55 -29
  610. package/dist/http-api/HttpApiEndpoint.d.ts.map +1 -1
  611. package/dist/http-api/HttpApiEndpoint.js +49 -5
  612. package/dist/http-api/HttpApiEndpoint.js.map +1 -1
  613. package/dist/http-api/HttpApiError.d.ts +58 -0
  614. package/dist/http-api/HttpApiError.d.ts.map +1 -1
  615. package/dist/http-api/HttpApiError.js +38 -12
  616. package/dist/http-api/HttpApiError.js.map +1 -1
  617. package/dist/http-api/HttpApiScalar.d.ts +2 -1
  618. package/dist/http-api/HttpApiScalar.d.ts.map +1 -1
  619. package/dist/http-api/HttpApiScalar.js +6 -3
  620. package/dist/http-api/HttpApiScalar.js.map +1 -1
  621. package/dist/http-api/HttpApiSchema.d.ts +191 -9
  622. package/dist/http-api/HttpApiSchema.d.ts.map +1 -1
  623. package/dist/http-api/HttpApiSchema.js +137 -4
  624. package/dist/http-api/HttpApiSchema.js.map +1 -1
  625. package/dist/http-api/HttpApiSwagger.d.ts +5 -0
  626. package/dist/http-api/HttpApiSwagger.d.ts.map +1 -1
  627. package/dist/http-api/HttpApiSwagger.js +14 -4
  628. package/dist/http-api/HttpApiSwagger.js.map +1 -1
  629. package/dist/http-api/HttpApiTest.d.ts +13 -2
  630. package/dist/http-api/HttpApiTest.d.ts.map +1 -1
  631. package/dist/http-api/HttpApiTest.js +30 -9
  632. package/dist/http-api/HttpApiTest.js.map +1 -1
  633. package/dist/http-api/OpenApi.d.ts +17 -3
  634. package/dist/http-api/OpenApi.d.ts.map +1 -1
  635. package/dist/http-api/OpenApi.js +57 -32
  636. package/dist/http-api/OpenApi.js.map +1 -1
  637. package/dist/http-api/internal/path.js +35 -10
  638. package/dist/http-api/internal/path.js.map +1 -1
  639. package/dist/index.d.ts +20 -0
  640. package/dist/index.d.ts.map +1 -1
  641. package/dist/index.js +20 -0
  642. package/dist/index.js.map +1 -1
  643. package/dist/internal/core.js +18 -2
  644. package/dist/internal/core.js.map +1 -1
  645. package/dist/internal/dateTime.js +19 -7
  646. package/dist/internal/dateTime.js.map +1 -1
  647. package/dist/internal/effect.js +89 -76
  648. package/dist/internal/effect.js.map +1 -1
  649. package/dist/internal/graphql.js +12 -2
  650. package/dist/internal/graphql.js.map +1 -1
  651. package/dist/internal/hashMap.js +2 -2
  652. package/dist/internal/hashMap.js.map +1 -1
  653. package/dist/internal/hydration.d.ts +2 -0
  654. package/dist/internal/hydration.d.ts.map +1 -0
  655. package/dist/internal/hydration.js +15 -0
  656. package/dist/internal/hydration.js.map +1 -0
  657. package/dist/internal/inflate.d.ts +2 -0
  658. package/dist/internal/inflate.d.ts.map +1 -0
  659. package/dist/internal/inflate.js +680 -0
  660. package/dist/internal/inflate.js.map +1 -0
  661. package/dist/internal/record.js +6 -0
  662. package/dist/internal/record.js.map +1 -1
  663. package/dist/internal/request.js +20 -7
  664. package/dist/internal/request.js.map +1 -1
  665. package/dist/internal/schedule.js +17 -22
  666. package/dist/internal/schedule.js.map +1 -1
  667. package/dist/internal/schema/fromJsonSchemaDocument.js +136 -126
  668. package/dist/internal/schema/fromJsonSchemaDocument.js.map +1 -1
  669. package/dist/internal/schema/interpreter.js +51 -36
  670. package/dist/internal/schema/interpreter.js.map +1 -1
  671. package/dist/internal/schema/standardSchema.js +34 -33
  672. package/dist/internal/schema/standardSchema.js.map +1 -1
  673. package/dist/internal/schema/toCodeDocument.js +7 -2
  674. package/dist/internal/schema/toCodeDocument.js.map +1 -1
  675. package/dist/internal/schema/toCodec.js +86 -1
  676. package/dist/internal/schema/toCodec.js.map +1 -1
  677. package/dist/internal/schema/toFormatter.js +5 -5
  678. package/dist/internal/schema/toFormatter.js.map +1 -1
  679. package/dist/internal/schema/toJsonSchemaDocument.js +60 -38
  680. package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
  681. package/dist/internal/trie.js +1 -3
  682. package/dist/internal/trie.js.map +1 -1
  683. package/dist/internal/uuid.js +7 -3
  684. package/dist/internal/uuid.js.map +1 -1
  685. package/dist/internal/version.js +1 -1
  686. package/dist/net/NetAddress.d.ts.map +1 -1
  687. package/dist/net/NetAddress.js +2 -8
  688. package/dist/net/NetAddress.js.map +1 -1
  689. package/dist/observability/Otlp.d.ts +15 -0
  690. package/dist/observability/Otlp.d.ts.map +1 -1
  691. package/dist/observability/Otlp.js +3 -0
  692. package/dist/observability/Otlp.js.map +1 -1
  693. package/dist/observability/OtlpExporter.d.ts +8 -0
  694. package/dist/observability/OtlpExporter.d.ts.map +1 -1
  695. package/dist/observability/OtlpExporter.js +15 -13
  696. package/dist/observability/OtlpExporter.js.map +1 -1
  697. package/dist/observability/OtlpLogger.d.ts +17 -0
  698. package/dist/observability/OtlpLogger.d.ts.map +1 -1
  699. package/dist/observability/OtlpLogger.js +14 -1
  700. package/dist/observability/OtlpLogger.js.map +1 -1
  701. package/dist/observability/OtlpMetrics.d.ts +17 -0
  702. package/dist/observability/OtlpMetrics.d.ts.map +1 -1
  703. package/dist/observability/OtlpMetrics.js +18 -3
  704. package/dist/observability/OtlpMetrics.js.map +1 -1
  705. package/dist/observability/OtlpResource.d.ts +3 -1
  706. package/dist/observability/OtlpResource.d.ts.map +1 -1
  707. package/dist/observability/OtlpResource.js +11 -4
  708. package/dist/observability/OtlpResource.js.map +1 -1
  709. package/dist/observability/OtlpSerialization.d.ts +5 -0
  710. package/dist/observability/OtlpSerialization.d.ts.map +1 -1
  711. package/dist/observability/OtlpSerialization.js +14 -3
  712. package/dist/observability/OtlpSerialization.js.map +1 -1
  713. package/dist/observability/OtlpTracer.d.ts +17 -0
  714. package/dist/observability/OtlpTracer.d.ts.map +1 -1
  715. package/dist/observability/OtlpTracer.js +15 -2
  716. package/dist/observability/OtlpTracer.js.map +1 -1
  717. package/dist/observability/internal/protobuf.d.ts +0 -9
  718. package/dist/observability/internal/protobuf.d.ts.map +1 -1
  719. package/dist/observability/internal/protobuf.js +2 -10
  720. package/dist/observability/internal/protobuf.js.map +1 -1
  721. package/dist/persistence/PersistedCache.d.ts.map +1 -1
  722. package/dist/persistence/PersistedCache.js +1 -1
  723. package/dist/persistence/PersistedCache.js.map +1 -1
  724. package/dist/persistence/PersistedQueue.d.ts +6 -2
  725. package/dist/persistence/PersistedQueue.d.ts.map +1 -1
  726. package/dist/persistence/PersistedQueue.js +162 -84
  727. package/dist/persistence/PersistedQueue.js.map +1 -1
  728. package/dist/persistence/Persistence.d.ts +28 -0
  729. package/dist/persistence/Persistence.d.ts.map +1 -1
  730. package/dist/persistence/Persistence.js +36 -8
  731. package/dist/persistence/Persistence.js.map +1 -1
  732. package/dist/persistence/RateLimiter.d.ts.map +1 -1
  733. package/dist/persistence/RateLimiter.js +8 -12
  734. package/dist/persistence/RateLimiter.js.map +1 -1
  735. package/dist/persistence/UserDirectories.d.ts +129 -0
  736. package/dist/persistence/UserDirectories.d.ts.map +1 -0
  737. package/dist/persistence/UserDirectories.js +178 -0
  738. package/dist/persistence/UserDirectories.js.map +1 -0
  739. package/dist/persistence/index.d.ts +5 -0
  740. package/dist/persistence/index.d.ts.map +1 -1
  741. package/dist/persistence/index.js +5 -0
  742. package/dist/persistence/index.js.map +1 -1
  743. package/dist/process/ChildProcess.d.ts +2 -1
  744. package/dist/process/ChildProcess.d.ts.map +1 -1
  745. package/dist/process/ChildProcess.js.map +1 -1
  746. package/dist/reactivity/AsyncResult.d.ts +6 -0
  747. package/dist/reactivity/AsyncResult.d.ts.map +1 -1
  748. package/dist/reactivity/AsyncResult.js +28 -1
  749. package/dist/reactivity/AsyncResult.js.map +1 -1
  750. package/dist/reactivity/Atom.d.ts +69 -30
  751. package/dist/reactivity/Atom.d.ts.map +1 -1
  752. package/dist/reactivity/Atom.js +40 -15
  753. package/dist/reactivity/Atom.js.map +1 -1
  754. package/dist/reactivity/AtomHttpApi.d.ts +5 -5
  755. package/dist/reactivity/AtomHttpApi.d.ts.map +1 -1
  756. package/dist/reactivity/AtomHttpApi.js +1 -1
  757. package/dist/reactivity/AtomHttpApi.js.map +1 -1
  758. package/dist/reactivity/AtomRegistry.d.ts +2 -2
  759. package/dist/reactivity/AtomRegistry.d.ts.map +1 -1
  760. package/dist/reactivity/AtomRegistry.js +47 -10
  761. package/dist/reactivity/AtomRegistry.js.map +1 -1
  762. package/dist/reactivity/AtomRpc.d.ts +3 -3
  763. package/dist/reactivity/AtomRpc.d.ts.map +1 -1
  764. package/dist/reactivity/AtomRpc.js +1 -1
  765. package/dist/reactivity/AtomRpc.js.map +1 -1
  766. package/dist/reactivity/Hydration.d.ts.map +1 -1
  767. package/dist/reactivity/Hydration.js +46 -12
  768. package/dist/reactivity/Hydration.js.map +1 -1
  769. package/dist/reactivity/Reactivity.d.ts +71 -7
  770. package/dist/reactivity/Reactivity.d.ts.map +1 -1
  771. package/dist/reactivity/Reactivity.js +21 -12
  772. package/dist/reactivity/Reactivity.js.map +1 -1
  773. package/dist/rpc/Rpc.d.ts +18 -0
  774. package/dist/rpc/Rpc.d.ts.map +1 -1
  775. package/dist/rpc/Rpc.js +20 -0
  776. package/dist/rpc/Rpc.js.map +1 -1
  777. package/dist/rpc/RpcClient.d.ts +26 -2
  778. package/dist/rpc/RpcClient.d.ts.map +1 -1
  779. package/dist/rpc/RpcClient.js +202 -61
  780. package/dist/rpc/RpcClient.js.map +1 -1
  781. package/dist/rpc/RpcSerialization.d.ts +15 -0
  782. package/dist/rpc/RpcSerialization.d.ts.map +1 -1
  783. package/dist/rpc/RpcSerialization.js +21 -5
  784. package/dist/rpc/RpcSerialization.js.map +1 -1
  785. package/dist/rpc/RpcServer.d.ts.map +1 -1
  786. package/dist/rpc/RpcServer.js +9 -18
  787. package/dist/rpc/RpcServer.js.map +1 -1
  788. package/dist/schema/Model.d.ts +1 -1
  789. package/dist/schema/VariantSchema.d.ts +22 -3
  790. package/dist/schema/VariantSchema.d.ts.map +1 -1
  791. package/dist/schema/VariantSchema.js +32 -18
  792. package/dist/schema/VariantSchema.js.map +1 -1
  793. package/dist/socket/Socket.d.ts +23 -1
  794. package/dist/socket/Socket.d.ts.map +1 -1
  795. package/dist/socket/Socket.js +36 -3
  796. package/dist/socket/Socket.js.map +1 -1
  797. package/dist/sql/Migrator.d.ts.map +1 -1
  798. package/dist/sql/Migrator.js +15 -3
  799. package/dist/sql/Migrator.js.map +1 -1
  800. package/dist/sql/SqlClient.d.ts +151 -12
  801. package/dist/sql/SqlClient.d.ts.map +1 -1
  802. package/dist/sql/SqlClient.js +156 -34
  803. package/dist/sql/SqlClient.js.map +1 -1
  804. package/dist/sql/SqlResolver.d.ts +9 -0
  805. package/dist/sql/SqlResolver.d.ts.map +1 -1
  806. package/dist/sql/SqlResolver.js +9 -0
  807. package/dist/sql/SqlResolver.js.map +1 -1
  808. package/dist/sql/Statement.d.ts +3 -1
  809. package/dist/sql/Statement.d.ts.map +1 -1
  810. package/dist/sql/Statement.js +24 -5
  811. package/dist/sql/Statement.js.map +1 -1
  812. package/dist/testing/TestClock.d.ts +16 -3
  813. package/dist/testing/TestClock.d.ts.map +1 -1
  814. package/dist/testing/TestClock.js +115 -23
  815. package/dist/testing/TestClock.js.map +1 -1
  816. package/dist/testing/TestSchema.d.ts +7 -1
  817. package/dist/testing/TestSchema.d.ts.map +1 -1
  818. package/dist/testing/TestSchema.js +9 -3
  819. package/dist/testing/TestSchema.js.map +1 -1
  820. package/dist/workflow/Activity.js +1 -0
  821. package/dist/workflow/Activity.js.map +1 -1
  822. package/dist/workflow/Workflow.d.ts +22 -0
  823. package/dist/workflow/Workflow.d.ts.map +1 -1
  824. package/dist/workflow/Workflow.js +15 -3
  825. package/dist/workflow/Workflow.js.map +1 -1
  826. package/dist/workflow/WorkflowEngine.d.ts +20 -1
  827. package/dist/workflow/WorkflowEngine.d.ts.map +1 -1
  828. package/dist/workflow/WorkflowEngine.js +52 -24
  829. package/dist/workflow/WorkflowEngine.js.map +1 -1
  830. package/package.json +13 -3
  831. package/src/Array.ts +223 -61
  832. package/src/Bytes.ts +111 -0
  833. package/src/Channel.ts +287 -439
  834. package/src/ChannelSchema.ts +1 -49
  835. package/src/Chunk.ts +55 -61
  836. package/src/Config.ts +12 -86
  837. package/src/ConfigProvider.ts +41 -44
  838. package/src/Cron.ts +6 -3
  839. package/src/Duration.ts +70 -21
  840. package/src/Effect.ts +642 -220
  841. package/src/Equivalence.ts +7 -4
  842. package/src/Exit.ts +24 -9
  843. package/src/FiberHandle.ts +10 -9
  844. package/src/FiberMap.ts +13 -66
  845. package/src/FileSystem.ts +33 -9
  846. package/src/Graph.ts +171 -1263
  847. package/src/HashSet.ts +0 -60
  848. package/src/Iterable.ts +15 -14
  849. package/src/JsonSchema.ts +28 -3
  850. package/src/Layer.ts +2 -2
  851. package/src/ManagedRuntime.ts +72 -6
  852. package/src/Match.ts +65 -12
  853. package/src/Metric.ts +249 -507
  854. package/src/MutableHashMap.ts +4 -473
  855. package/src/Number.ts +2 -2
  856. package/src/Optic.ts +17 -332
  857. package/src/Path.ts +61 -8
  858. package/src/PubSub.ts +12 -7
  859. package/src/Queue.ts +5 -37
  860. package/src/Random.ts +1 -1
  861. package/src/RcMap.ts +14 -8
  862. package/src/Record.ts +51 -0
  863. package/src/Ref.ts +7 -104
  864. package/src/References.ts +5 -4
  865. package/src/RequestResolver.ts +46 -87
  866. package/src/Resource.ts +1 -1
  867. package/src/Runtime.ts +19 -18
  868. package/src/Schedule.ts +2 -94
  869. package/src/Schema.ts +596 -348
  870. package/src/SchemaAST.ts +20 -9
  871. package/src/SchemaGetter.ts +22 -5
  872. package/src/SchemaIssue.ts +44 -53
  873. package/src/SchemaRepresentation.ts +64 -1
  874. package/src/SchemaTransformation.ts +1 -1
  875. package/src/Scope.ts +12 -2
  876. package/src/ScopedCache.ts +17 -142
  877. package/src/SemVer.ts +1528 -0
  878. package/src/SemVerRange.ts +883 -0
  879. package/src/Sink.ts +6 -2
  880. package/src/Stream.ts +334 -1011
  881. package/src/String.ts +25 -12
  882. package/src/TextDiff.ts +766 -0
  883. package/src/TxHashMap.ts +1 -103
  884. package/src/TxHashSet.ts +48 -753
  885. package/src/TxRef.ts +4 -2
  886. package/src/ai/AiError.ts +69 -5
  887. package/src/ai/Chat.ts +10 -5
  888. package/src/ai/Decision.ts +119 -22
  889. package/src/ai/DecisionModel.ts +265 -109
  890. package/src/ai/EmbeddingModel.ts +25 -13
  891. package/src/ai/LanguageModel.ts +57 -51
  892. package/src/ai/McpClient.ts +1211 -0
  893. package/src/ai/McpClientError.ts +329 -0
  894. package/src/ai/McpProtocol.ts +2 -2
  895. package/src/ai/McpSchema.ts +153 -35
  896. package/src/ai/McpServer.ts +232 -275
  897. package/src/ai/Prompt.ts +49 -35
  898. package/src/ai/Response.ts +195 -65
  899. package/src/ai/Tool.ts +12 -4
  900. package/src/ai/Toolkit.ts +78 -10
  901. package/src/ai/index.ts +12 -0
  902. package/src/ai/internal/mcpCore.ts +13 -14
  903. package/src/ai/internal/mcpProtocol/v2024_11_05.ts +1 -1
  904. package/src/ai/internal/mcpProtocol/v2025_03_26.ts +1 -1
  905. package/src/ai/internal/mcpProtocol/v2025_06_18.ts +3 -3
  906. package/src/ai/internal/mcpProtocol/v2025_11_25.ts +3 -3
  907. package/src/ai/internal/mcpProtocol/v2026_07_28.ts +12 -14
  908. package/src/ai/internal/mcpProtocol.ts +22 -2
  909. package/src/ai/internal/mcpRuntime.ts +3 -4
  910. package/src/ai/internal/mcpSchema/v2024_11_05.ts +20 -13
  911. package/src/ai/internal/mcpSchema/v2025_03_26.ts +4 -2
  912. package/src/ai/internal/mcpSchema/v2025_06_18.ts +7 -7
  913. package/src/ai/internal/mcpSchema/v2025_11_25.ts +8 -8
  914. package/src/ai/internal/mcpSchema/v2026_07_28.ts +44 -42
  915. package/src/cli/CliError.ts +49 -4
  916. package/src/cli/Command.ts +316 -9
  917. package/src/cli/Completions.ts +10 -0
  918. package/src/cli/Flag.ts +218 -0
  919. package/src/cli/GlobalFlag.ts +3 -3
  920. package/src/cli/Param.ts +218 -0
  921. package/src/cli/TerminalCapabilities.ts +156 -0
  922. package/src/cli/index.ts +6 -0
  923. package/src/cli/internal/command.ts +10 -4
  924. package/src/cli/internal/completions/bash.ts +7 -5
  925. package/src/cli/internal/completions/descriptor.ts +20 -1
  926. package/src/cli/internal/completions/fish.ts +12 -10
  927. package/src/cli/internal/completions/powershell.ts +25 -13
  928. package/src/cli/internal/completions/zsh.ts +15 -8
  929. package/src/cli/internal/formatter.ts +18 -0
  930. package/src/cli/internal/lexer.ts +12 -5
  931. package/src/cli/internal/parser.ts +43 -14
  932. package/src/cli/internal/wizard.ts +2 -1
  933. package/src/cluster/ClusterCron.ts +94 -35
  934. package/src/cluster/ClusterMetrics.ts +149 -7
  935. package/src/cluster/ClusterWorkflowEngine.ts +164 -53
  936. package/src/cluster/Entity.ts +4 -0
  937. package/src/cluster/MessageStorage.ts +21 -3
  938. package/src/cluster/Runners.ts +145 -72
  939. package/src/cluster/Sharding.ts +118 -38
  940. package/src/cluster/ShardingConfig.ts +15 -0
  941. package/src/cluster/SqlMessageStorage.ts +58 -55
  942. package/src/cluster/SqlRunnerStorage.ts +10 -4
  943. package/src/cluster/internal/entityManager.ts +81 -11
  944. package/src/devtools/DevTools.ts +3 -2
  945. package/src/devtools/DevToolsClient.ts +27 -10
  946. package/src/encoding/Base64Url.ts +31 -0
  947. package/src/encoding/Ini.ts +3 -0
  948. package/src/encoding/JsonArray.ts +849 -0
  949. package/src/encoding/Ndjson.ts +211 -20
  950. package/src/encoding/SchemaBinary.ts +14 -48
  951. package/src/encoding/Sse.ts +1 -1
  952. package/src/encoding/Tar.ts +1417 -0
  953. package/src/encoding/Toml.ts +3 -3
  954. package/src/encoding/Xml.ts +2037 -0
  955. package/src/encoding/Yaml.ts +108 -36
  956. package/src/encoding/Zip.ts +1558 -0
  957. package/src/encoding/index.ts +24 -0
  958. package/src/eventlog/EventJournal.ts +611 -227
  959. package/src/eventlog/EventLog.ts +496 -196
  960. package/src/eventlog/EventLogEncryption.ts +128 -43
  961. package/src/eventlog/EventLogMessage.ts +62 -11
  962. package/src/eventlog/EventLogRemote.ts +77 -21
  963. package/src/eventlog/EventLogServer.ts +162 -20
  964. package/src/eventlog/EventLogServerEncrypted.ts +121 -80
  965. package/src/eventlog/EventLogServerUnencrypted.ts +180 -77
  966. package/src/eventlog/EventRow.ts +706 -0
  967. package/src/eventlog/SqlEventJournal.ts +453 -173
  968. package/src/eventlog/SqlEventLogServerEncrypted.ts +212 -83
  969. package/src/eventlog/SqlEventLogServerUnencrypted.ts +141 -62
  970. package/src/eventlog/index.ts +6 -0
  971. package/src/eventlog/internal/conflicts.ts +123 -0
  972. package/src/graphql/GraphQLClient.ts +17 -5
  973. package/src/graphql/GraphQLClientError.ts +5 -12
  974. package/src/graphql/GraphQLProtocol.ts +277 -20
  975. package/src/graphql/GraphQLResolver.ts +109 -230
  976. package/src/http/FetchHttpClient.ts +61 -8
  977. package/src/http/FindMyWay/internal/router.ts +13 -1
  978. package/src/http/Headers.ts +343 -163
  979. package/src/http/HttpClient.ts +144 -136
  980. package/src/http/HttpClientError.ts +10 -6
  981. package/src/http/HttpClientRequest.ts +315 -11
  982. package/src/http/HttpClientResponse.ts +71 -0
  983. package/src/http/HttpEffect.ts +25 -33
  984. package/src/http/HttpIncomingMessage.ts +3 -23
  985. package/src/http/HttpMiddleware.ts +265 -28
  986. package/src/http/HttpRouter.ts +67 -14
  987. package/src/http/HttpServerError.ts +14 -7
  988. package/src/http/HttpServerRequest.ts +73 -14
  989. package/src/http/HttpServerResponse.ts +49 -23
  990. package/src/http/HttpStaticServer.ts +29 -19
  991. package/src/http/HttpTraceContext.ts +1 -1
  992. package/src/http/MultipartParser/internal/contentType.ts +107 -6
  993. package/src/http/MultipartParser/internal/headers.ts +4 -16
  994. package/src/http/MultipartParser/internal/multipart.ts +10 -32
  995. package/src/http/Url.ts +8 -2
  996. package/src/http/UrlParams.ts +225 -26
  997. package/src/http/internal/compression.ts +3 -17
  998. package/src/http/internal/compressionBody.ts +56 -0
  999. package/src/http/internal/decompression.ts +235 -0
  1000. package/src/http/internal/lazyStream.ts +25 -0
  1001. package/src/http/internal/requestState.ts +33 -0
  1002. package/src/http/internal/tracing.ts +21 -4
  1003. package/src/http/internal/urlParams.ts +5 -0
  1004. package/src/http/internal/webResponse.ts +20 -0
  1005. package/src/http-api/HttpApi.ts +1 -1
  1006. package/src/http-api/HttpApiBuilder.ts +151 -23
  1007. package/src/http-api/HttpApiClient.ts +160 -31
  1008. package/src/http-api/HttpApiEndpoint.ts +144 -33
  1009. package/src/http-api/HttpApiError.ts +55 -0
  1010. package/src/http-api/HttpApiScalar.ts +4 -3
  1011. package/src/http-api/HttpApiSchema.ts +275 -13
  1012. package/src/http-api/HttpApiSwagger.ts +11 -4
  1013. package/src/http-api/HttpApiTest.ts +33 -9
  1014. package/src/http-api/OpenApi.ts +84 -42
  1015. package/src/http-api/internal/path.ts +40 -12
  1016. package/src/index.ts +24 -0
  1017. package/src/internal/core.ts +22 -2
  1018. package/src/internal/dateTime.ts +20 -7
  1019. package/src/internal/effect.ts +125 -88
  1020. package/src/internal/graphql.ts +30 -7
  1021. package/src/internal/hashMap.ts +2 -2
  1022. package/src/internal/hydration.ts +15 -0
  1023. package/src/internal/inflate.ts +710 -0
  1024. package/src/internal/record.ts +6 -0
  1025. package/src/internal/request.ts +21 -6
  1026. package/src/internal/schedule.ts +20 -39
  1027. package/src/internal/schema/fromJsonSchemaDocument.ts +262 -193
  1028. package/src/internal/schema/interpreter.ts +58 -45
  1029. package/src/internal/schema/standardSchema.ts +32 -30
  1030. package/src/internal/schema/toCodeDocument.ts +8 -3
  1031. package/src/internal/schema/toCodec.ts +116 -1
  1032. package/src/internal/schema/toFormatter.ts +6 -6
  1033. package/src/internal/schema/toJsonSchemaDocument.ts +69 -39
  1034. package/src/internal/trie.ts +1 -3
  1035. package/src/internal/uuid.ts +15 -10
  1036. package/src/internal/version.ts +1 -1
  1037. package/src/net/NetAddress.ts +2 -9
  1038. package/src/observability/Otlp.ts +18 -0
  1039. package/src/observability/OtlpExporter.ts +19 -15
  1040. package/src/observability/OtlpLogger.ts +31 -2
  1041. package/src/observability/OtlpMetrics.ts +35 -4
  1042. package/src/observability/OtlpResource.ts +16 -6
  1043. package/src/observability/OtlpSerialization.ts +17 -3
  1044. package/src/observability/OtlpTracer.ts +32 -3
  1045. package/src/observability/internal/protobuf.ts +2 -10
  1046. package/src/persistence/PersistedCache.ts +3 -1
  1047. package/src/persistence/PersistedQueue.ts +223 -153
  1048. package/src/persistence/Persistence.ts +64 -30
  1049. package/src/persistence/RateLimiter.ts +18 -21
  1050. package/src/persistence/UserDirectories.ts +273 -0
  1051. package/src/persistence/index.ts +6 -0
  1052. package/src/process/ChildProcess.ts +2 -1
  1053. package/src/reactivity/AsyncResult.ts +35 -38
  1054. package/src/reactivity/Atom.ts +134 -166
  1055. package/src/reactivity/AtomHttpApi.ts +10 -16
  1056. package/src/reactivity/AtomRegistry.ts +53 -30
  1057. package/src/reactivity/AtomRpc.ts +6 -22
  1058. package/src/reactivity/Hydration.ts +53 -12
  1059. package/src/reactivity/Reactivity.ts +97 -39
  1060. package/src/rpc/Rpc.ts +21 -0
  1061. package/src/rpc/RpcClient.ts +285 -104
  1062. package/src/rpc/RpcSerialization.ts +21 -5
  1063. package/src/rpc/RpcServer.ts +11 -20
  1064. package/src/schema/VariantSchema.ts +86 -22
  1065. package/src/socket/Socket.ts +45 -20
  1066. package/src/sql/Migrator.ts +19 -9
  1067. package/src/sql/SqlClient.ts +275 -36
  1068. package/src/sql/SqlResolver.ts +9 -0
  1069. package/src/sql/Statement.ts +35 -8
  1070. package/src/testing/TestClock.ts +147 -29
  1071. package/src/testing/TestSchema.ts +9 -3
  1072. package/src/workflow/Activity.ts +1 -0
  1073. package/src/workflow/Workflow.ts +31 -5
  1074. package/src/workflow/WorkflowEngine.ts +93 -31
  1075. package/dist/http/internal/preResponseHandler.d.ts +0 -2
  1076. package/dist/http/internal/preResponseHandler.d.ts.map +0 -1
  1077. package/dist/http/internal/preResponseHandler.js +0 -14
  1078. package/dist/http/internal/preResponseHandler.js.map +0 -1
  1079. package/src/http/internal/preResponseHandler.ts +0 -19
@@ -0,0 +1,1558 @@
1
+ /**
2
+ * Encodes and decodes zip archives as streams in Effect channels.
3
+ *
4
+ * `encode` writes each entry as it arrives and adds the central directory once
5
+ * the input ends; `decode` reads entries in archive order from their local
6
+ * headers. `decode` never buffers an entire entry body, and `encode` only
7
+ * collects deflated bodies with a `size` of at most 64 KiB.
8
+ *
9
+ * Entries are stored or compressed with deflate, the methods every zip tool
10
+ * reads. Compression uses the runtime's `CompressionStream("deflate-raw")`;
11
+ * decompression is implemented here, so that `decode` can find the end of
12
+ * entries whose sizes follow their data. ZIP64 fields are written when sizes,
13
+ * offsets or the entry count need them, and read from local headers and data
14
+ * descriptors.
15
+ * Encryption, other compression methods and archives split across files are
16
+ * not supported.
17
+ *
18
+ * This module is experimental and may receive breaking changes in patch
19
+ * releases.
20
+ *
21
+ * @stability experimental
22
+ * @since 4.0.6
23
+ */
24
+ import * as Arr from "../Array.ts"
25
+ import * as Cause from "../Cause.ts"
26
+ import * as Channel from "../Channel.ts"
27
+ import * as Data from "../Data.ts"
28
+ import * as Effect from "../Effect.ts"
29
+ import * as Exit from "../Exit.ts"
30
+ import { ByteQueue, InflateError, InflateMemory, Inflater, NeedInput } from "../internal/inflate.ts"
31
+ import * as Predicate from "../Predicate.ts"
32
+ import * as Pull from "../Pull.ts"
33
+ import * as Scope from "../Scope.ts"
34
+ import * as Semaphore from "../Semaphore.ts"
35
+ import * as Stream from "../Stream.ts"
36
+
37
+ const ZipErrorTypeId = "~effect/encoding/Zip/ZipError"
38
+
39
+ /**
40
+ * Error raised when a zip archive cannot be encoded or decoded.
41
+ *
42
+ * **Details**
43
+ *
44
+ * The `kind` field identifies the failure:
45
+ *
46
+ * - `InvalidHeader`: a header has an unknown signature or a malformed field, or
47
+ * an entry has a value that cannot be written.
48
+ * - `InvalidData`: the compressed data of an entry is corrupt.
49
+ * - `Truncated`: the input ended inside an entry or before the central
50
+ * directory.
51
+ * - `Checksum`: the data of an entry does not match its CRC-32.
52
+ * - `SizeMismatch`: an entry body produced a byte count other than its declared
53
+ * `size`, or the data of an entry does not match the sizes in the archive.
54
+ * - `Unsupported`: the archive uses a feature this module does not read, such
55
+ * as encryption or a compression method other than store and deflate.
56
+ * - `BodyConsumed`: an entry body was read after the decoder had moved past it.
57
+ *
58
+ * @stability experimental
59
+ * @category errors
60
+ * @since 4.0.6
61
+ */
62
+ export class ZipError extends Data.TaggedError("ZipError")<{
63
+ readonly kind:
64
+ | "InvalidHeader"
65
+ | "InvalidData"
66
+ | "Truncated"
67
+ | "Checksum"
68
+ | "SizeMismatch"
69
+ | "Unsupported"
70
+ | "BodyConsumed"
71
+ readonly message: string
72
+ }> {
73
+ /**
74
+ * Marks this value as a zip error for runtime guards.
75
+ *
76
+ * @stability experimental
77
+ * @since 4.0.6
78
+ */
79
+ readonly [ZipErrorTypeId] = ZipErrorTypeId
80
+ }
81
+
82
+ /**
83
+ * Checks whether a value is a `ZipError`.
84
+ *
85
+ * @stability experimental
86
+ * @category guards
87
+ * @since 4.0.6
88
+ */
89
+ export const isZipError = (u: unknown): u is ZipError => Predicate.hasProperty(u, ZipErrorTypeId)
90
+
91
+ /**
92
+ * Kind of object described by a zip entry.
93
+ *
94
+ * @stability experimental
95
+ * @category models
96
+ * @since 4.0.6
97
+ */
98
+ export type EntryType = "File" | "Directory"
99
+
100
+ /**
101
+ * Compression method of a zip entry.
102
+ *
103
+ * @stability experimental
104
+ * @category models
105
+ * @since 4.0.6
106
+ */
107
+ export type Method = "Store" | "Deflate"
108
+
109
+ /**
110
+ * Metadata of a zip entry.
111
+ *
112
+ * **Details**
113
+ *
114
+ * `path` is the archive path, with `/` separators; directory paths end with
115
+ * `/`. `size` is the uncompressed byte length when it is known before the body:
116
+ * decoded entries whose sizes follow their data have no `size`. `mode` holds
117
+ * Unix permission bits and is written to the central directory, which `decode`
118
+ * does not read, so decoded headers have no `mode`. `mtime` has a resolution of
119
+ * one second when the archive has an extended timestamp and two seconds
120
+ * otherwise.
121
+ *
122
+ * @stability experimental
123
+ * @category models
124
+ * @since 4.0.6
125
+ */
126
+ export interface Header {
127
+ readonly path: string
128
+ readonly type: EntryType
129
+ readonly method: Method
130
+ readonly mtime: Date
131
+ readonly size?: number | undefined
132
+ readonly mode?: number | undefined
133
+ }
134
+
135
+ /**
136
+ * Zip entry: a header and a stream of the uncompressed body bytes.
137
+ *
138
+ * **Details**
139
+ *
140
+ * `decode` returns these, and `fileStream` builds them. `encode` writes the
141
+ * sizes and CRC-32 of a streamed body in a data descriptor after the data.
142
+ *
143
+ * @see {@link ContentEntry} for entries whose content is held in memory
144
+ *
145
+ * @stability experimental
146
+ * @category models
147
+ * @since 4.0.6
148
+ */
149
+ export interface Entry<E = never, R = never> {
150
+ readonly header: Header
151
+ readonly body: Stream.Stream<Uint8Array, E, R>
152
+ readonly content?: undefined
153
+ }
154
+
155
+ /**
156
+ * Zip entry whose uncompressed content is held in memory.
157
+ *
158
+ * **Details**
159
+ *
160
+ * `file` and `directory` build these. Because the content is known before the
161
+ * entry is written, `encode` puts its sizes and CRC-32 in the local header and
162
+ * writes no data descriptor, which every zip reader accepts. `content` and
163
+ * `body` exclude each other, so an entry whose body is replaced must drop
164
+ * `content`.
165
+ *
166
+ * @see {@link Entry} for entries whose content is streamed
167
+ *
168
+ * @stability experimental
169
+ * @category models
170
+ * @since 4.0.6
171
+ */
172
+ export interface ContentEntry {
173
+ readonly header: Header
174
+ readonly content: Uint8Array
175
+ readonly body?: undefined
176
+ }
177
+
178
+ /**
179
+ * Options for the entry constructors.
180
+ *
181
+ * **Details**
182
+ *
183
+ * Unset fields default to an mtime of 1980-01-01T00:00:00Z, the earliest time
184
+ * a zip header can hold, and mode `0o644` (`0o755` for directories). The
185
+ * defaults make archives reproducible.
186
+ *
187
+ * @stability experimental
188
+ * @category models
189
+ * @since 4.0.6
190
+ */
191
+ export interface EntryOptions {
192
+ readonly mtime?: Date | undefined
193
+ readonly mode?: number | undefined
194
+ }
195
+
196
+ /**
197
+ * Options for file entries.
198
+ *
199
+ * **Details**
200
+ *
201
+ * `method` defaults to `"Deflate"`. Use `"Store"` for content that is already
202
+ * compressed, such as images or archives.
203
+ *
204
+ * @stability experimental
205
+ * @category models
206
+ * @since 4.0.6
207
+ */
208
+ export interface FileOptions extends EntryOptions {
209
+ readonly method?: Method | undefined
210
+ }
211
+
212
+ /**
213
+ * Options for file entries whose content is streamed.
214
+ *
215
+ * **Details**
216
+ *
217
+ * `size` is the exact byte length of the body. It is required for `Store`,
218
+ * because streaming readers can only find the end of stored data from its
219
+ * size, and optional for `Deflate`, where it is checked against the body.
220
+ *
221
+ * @stability experimental
222
+ * @category models
223
+ * @since 4.0.6
224
+ */
225
+ export type FileStreamOptions =
226
+ & EntryOptions
227
+ & (
228
+ | { readonly method?: "Deflate" | undefined; readonly size?: number | undefined }
229
+ | { readonly method: "Store"; readonly size: number }
230
+ )
231
+
232
+ const MIN_MTIME = Date.UTC(1980, 0, 1)
233
+
234
+ const makeHeader = (
235
+ path: string,
236
+ type: EntryType,
237
+ method: Method,
238
+ options: EntryOptions | undefined,
239
+ size: number | undefined
240
+ ): Header => ({
241
+ path,
242
+ type,
243
+ method,
244
+ mtime: options?.mtime ?? new Date(MIN_MTIME),
245
+ mode: options?.mode ?? (type === "Directory" ? 0o755 : 0o644),
246
+ ...(size === undefined ? undefined : { size })
247
+ })
248
+
249
+ /**
250
+ * Creates a file entry from in-memory content.
251
+ *
252
+ * **Details**
253
+ *
254
+ * String content is encoded as UTF-8, and `size` is the byte length of the
255
+ * content. Because the content is known up front, its sizes and CRC-32 are
256
+ * written in the local header, which every zip reader accepts.
257
+ *
258
+ * @see {@link fileStream} for content that is streamed instead of held in memory
259
+ * @see {@link encode} for writing entries to an archive
260
+ *
261
+ * @stability experimental
262
+ * @category constructors
263
+ * @since 4.0.6
264
+ */
265
+ export const file = (path: string, content: string | Uint8Array, options?: FileOptions): ContentEntry => {
266
+ const bytes = typeof content === "string" ? textEncoder.encode(content) : content
267
+ return { header: makeHeader(path, "File", options?.method ?? "Deflate", options, bytes.length), content: bytes }
268
+ }
269
+
270
+ /**
271
+ * Creates a file entry whose content is streamed from `body`.
272
+ *
273
+ * **When to use**
274
+ *
275
+ * Use when the content is too large to hold in memory, or is read from a file
276
+ * or another stream.
277
+ *
278
+ * **Details**
279
+ *
280
+ * `body` is not run until the entry is encoded. Its sizes and CRC-32 are
281
+ * written in a data descriptor after the data.
282
+ *
283
+ * **Gotchas**
284
+ *
285
+ * - A stored entry without `size` fails with an `InvalidHeader` `ZipError`.
286
+ * - When `size` is set, `encode` fails with a `SizeMismatch` `ZipError` if the
287
+ * body produces fewer or more bytes.
288
+ * - Non-empty stored entries are followed by a data descriptor, which some
289
+ * streaming readers mishandle. Java's `ZipInputStream` rejects them, and
290
+ * libarchive reading from a pipe (as `bsdtar` does) ends them at the first
291
+ * bytes that look like a descriptor, so content can cut the entry short and
292
+ * add entries. Use `Deflate` or an in-memory `file` for untrusted content
293
+ * and for those readers.
294
+ *
295
+ * @see {@link file} for in-memory content
296
+ * @see {@link encode} for writing entries to an archive
297
+ *
298
+ * @stability experimental
299
+ * @category constructors
300
+ * @since 4.0.6
301
+ */
302
+ export const fileStream = <E = never, R = never>(
303
+ path: string,
304
+ body: Stream.Stream<Uint8Array, E, R>,
305
+ options?: FileStreamOptions
306
+ ): Entry<E, R> => ({
307
+ header: makeHeader(path, "File", options?.method ?? "Deflate", options, options?.size),
308
+ body
309
+ })
310
+
311
+ /**
312
+ * Creates a directory entry.
313
+ *
314
+ * **Details**
315
+ *
316
+ * A trailing `/` is added to a non-empty `path` when missing, as zip tools
317
+ * expect for directories.
318
+ *
319
+ * @stability experimental
320
+ * @category constructors
321
+ * @since 4.0.6
322
+ */
323
+ export const directory = (path: string, options?: EntryOptions): ContentEntry => ({
324
+ // An empty path stays empty, so that `encode` rejects it
325
+ header: makeHeader(path === "" || path.endsWith("/") ? path : `${path}/`, "Directory", "Store", options, 0),
326
+ content: emptyBody
327
+ })
328
+
329
+ /**
330
+ * Creates a channel that decodes zip archive bytes into entries.
331
+ *
332
+ * **Details**
333
+ *
334
+ * Entries are read in archive order from their local headers, so archives can
335
+ * be decoded as they arrive, for example from an HTTP response. Each output
336
+ * chunk holds one entry, and each body streams the uncompressed bytes of the
337
+ * entry. Pulling the next entry skips whatever is left of the current body.
338
+ * Stored and deflated entries are read, including ZIP64 sizes and deflated
339
+ * entries whose sizes follow their data in a data descriptor. Every body is
340
+ * checked against its CRC-32 and sizes. Reading stops at the central directory.
341
+ *
342
+ * Paths use the UTF-8 flag when set, and otherwise the first Info-ZIP Unicode
343
+ * path field when it matches the name, as Info-ZIP and 7-Zip do; other paths
344
+ * are read as UTF-8 when valid and as CP437 otherwise. Times are read from the
345
+ * extended timestamp field when present, and otherwise from the DOS time and
346
+ * date, which have no time zone and are read as UTC.
347
+ *
348
+ * **Gotchas**
349
+ *
350
+ * - Read each body before pulling the next entry: a body read afterwards fails
351
+ * with a `BodyConsumed` `ZipError`. Operators that pull ahead, such as
352
+ * `Stream.buffer`, therefore can't sit between `decode` and the body reads.
353
+ * - Read bodies while the entry stream runs, for example in `Stream.mapEffect`:
354
+ * once it has ended, as after `Stream.runCollect`, `Stream.runHead` or
355
+ * `Stream.take`, every body fails with a `BodyConsumed` `ZipError`.
356
+ * - A body reads the entry's bytes once: running it again continues where the
357
+ * previous run stopped.
358
+ * - The central directory is not read, so `mode`, comments and entries that
359
+ * only the central directory lists are not reported. Tools that read the
360
+ * central directory can see other entries and paths, for example in
361
+ * archives updated by appending.
362
+ * - Archives that do not start with an entry or a central directory, such as
363
+ * self-extracting archives, fail with an `InvalidHeader` `ZipError`.
364
+ * - Stored entries whose sizes only follow their data fail with an
365
+ * `Unsupported` `ZipError`. Python's `zipfile` writes them for stored
366
+ * entries on unseekable output, and Info-ZIP's `zip` for empty files when
367
+ * writing to a pipe. Searching for their end would let the content of an
368
+ * entry forge the entries after it.
369
+ * - A body that grows past its `size` fails with a `SizeMismatch` `ZipError`
370
+ * before the extra bytes are emitted, so `size` can be checked before reading.
371
+ * - Deflated data can expand about a thousand times, and pulling the next
372
+ * entry inflates the rest of the current body to find its end. To bound the
373
+ * work on untrusted archives, check `size`, count the bytes of bodies
374
+ * without one, and end the stream at an entry that is too large rather than
375
+ * skip it.
376
+ * - Every `ZipError` ends the archive: later entry and body reads fail with
377
+ * the same error.
378
+ * - The channel completes only when its input ends: input after the central
379
+ * directory is read and discarded, so that the upstream done value can be
380
+ * passed on.
381
+ * - Paths are returned as written in the archive: they can be absolute,
382
+ * contain `..`, drive letters, control characters or backslashes, which some
383
+ * tools read as separators, and can repeat. Validate them before writing
384
+ * entries to disk; `encode` rejects absolute paths, drive letters and
385
+ * backslashes. Paths with a NUL character, which other tools take as the end
386
+ * of the name, fail with an `InvalidHeader` `ZipError`.
387
+ *
388
+ * @see {@link encode} for the inverse operation
389
+ *
390
+ * @stability experimental
391
+ * @category decoding
392
+ * @since 4.0.6
393
+ */
394
+ export const decode = <IE = never, Done = unknown>(): Channel.Channel<
395
+ Arr.NonEmptyReadonlyArray<Entry<ZipError | IE>>,
396
+ ZipError | IE,
397
+ Done,
398
+ Arr.NonEmptyReadonlyArray<Uint8Array>,
399
+ IE,
400
+ Done
401
+ > =>
402
+ Channel.fromTransform((upstream, scope) =>
403
+ Effect.suspend(() => {
404
+ const decoder = new Decoder()
405
+ let done: { readonly value: Done } | undefined
406
+ let pulls = 0
407
+
408
+ const pullUpstream = upstream.pipe(
409
+ Effect.map((chunks) => {
410
+ pulls++
411
+ for (const chunk of chunks) decoder.push(chunk)
412
+ }),
413
+ Pull.catchDone((value) => {
414
+ pulls++
415
+ done = { value: value as Done }
416
+ decoder.end()
417
+ return Effect.void
418
+ })
419
+ )
420
+
421
+ // Serialize entry and body pulls; reuse input pulled while waiting for the lock.
422
+ const lock = Semaphore.makeUnsafe(1)
423
+ const pullInput = (seen: number) =>
424
+ lock.withPermit(Effect.suspend(() => pulls === seen ? pullUpstream : Effect.void))
425
+
426
+ const run = <A, D>(f: () => A | undefined | typeof NeedInput, end: () => D): Pull.Pull<A, ZipError | IE, D> =>
427
+ Effect.suspend(function loop(): Pull.Pull<A, ZipError | IE, D> {
428
+ const seen = pulls
429
+ let result: A | undefined | typeof NeedInput
430
+ try {
431
+ result = f()
432
+ } catch (error) {
433
+ return isZipError(error) ? Effect.fail(error) : Effect.die(error)
434
+ }
435
+ if (result === NeedInput) return Effect.flatMap(pullInput(seen), loop)
436
+ return result === undefined ? Cause.done(end()) : Effect.succeed(result)
437
+ })
438
+
439
+ const body = (id: number): Stream.Stream<Uint8Array, ZipError | IE> =>
440
+ Stream.fromPull(Effect.succeed(run(() => decoder.read(id), () => undefined)))
441
+
442
+ const next = run(() => {
443
+ const header = decoder.next()
444
+ return header === NeedInput || header === undefined
445
+ ? header
446
+ : Arr.of({ header, body: body(decoder.generation) })
447
+ }, () => done!.value)
448
+
449
+ return Effect.as(Scope.addFinalizer(scope, Effect.sync(() => decoder.close())), next)
450
+ })
451
+ )
452
+
453
+ /**
454
+ * Creates a channel that encodes entries into zip archive bytes.
455
+ *
456
+ * **Details**
457
+ *
458
+ * Each entry is written as soon as it arrives: a local header, the stored or
459
+ * deflated body and, for entries with a streamed `body`, a data descriptor
460
+ * with the CRC-32 and sizes. A `ContentEntry` has them in its local header.
461
+ * The central directory is written once the input ends. Paths are written as
462
+ * UTF-8, with the UTF-8 flag set when they are not ASCII. `mtime`
463
+ * is written both as a DOS time in UTC, which keeps two-second resolution and
464
+ * covers 1980 to 2107, and as an extended timestamp in whole seconds when it
465
+ * falls between 1970 and 2038. ZIP64 fields are added when a size, an offset
466
+ * or the entry count does not fit the classic fields, and to the local header
467
+ * of a deflated entry streamed without a `size` or with one near 4 GiB, so
468
+ * that readers know the width of the sizes after its data.
469
+ *
470
+ * Headers and body chunks below 16 KiB are gathered into output chunks of
471
+ * about 64 KiB, and larger body chunks pass through without copying. Output is
472
+ * handed out before waiting for more entries, but up to 64 KiB of it can be
473
+ * held while a body is pulled. Each body chunk of a streamed `Deflate` entry is
474
+ * a separate compressor job, so larger chunks compress faster. A `Deflate`
475
+ * body with a `size` of at most 64 KiB is instead collected and compressed in
476
+ * one job, and still gets a data descriptor; omit `size` to stream it.
477
+ *
478
+ * **Gotchas**
479
+ *
480
+ * - Deflated entries need `CompressionStream("deflate-raw")`. On a runtime
481
+ * without it, encoding a deflated entry dies with the runtime's error, as
482
+ * it does when the compressor fails: check for the API or use `Store`.
483
+ * - Deflated bytes come from the runtime's `CompressionStream`, so they can
484
+ * differ between runtimes. Archives of stored entries are byte-identical
485
+ * everywhere.
486
+ * - A body that produces a byte count other than a set `header.size`, or any
487
+ * bytes for a directory, fails with a `SizeMismatch` `ZipError`.
488
+ * - Directories are always stored, whatever their `method`.
489
+ * - Empty paths, paths starting with `/` or a drive letter such as `C:`, paths
490
+ * containing `\` or NUL, `File` paths ending with `/`, `Directory` paths not
491
+ * ending with `/`, and invalid modes, sizes or times fail with an
492
+ * `InvalidHeader` `ZipError`. Other paths are written as given, including
493
+ * `..` segments, so validate untrusted paths before encoding them.
494
+ *
495
+ * **Example** (Writing and reading an archive)
496
+ *
497
+ * ```ts import.meta.vitest
498
+ * import { Effect, Stream } from "effect"
499
+ * import { Zip } from "effect/encoding"
500
+ *
501
+ * const archive = Stream.make(
502
+ * Zip.directory("docs"),
503
+ * Zip.file("docs/readme.txt", "Hello, zip!")
504
+ * ).pipe(Stream.pipeThroughChannel(Zip.encode()))
505
+ *
506
+ * const listing = archive.pipe(
507
+ * Stream.pipeThroughChannel(Zip.decode()),
508
+ * Stream.mapEffect((entry) =>
509
+ * Stream.mkString(Stream.decodeText(entry.body)).pipe(
510
+ * Effect.map((text) => `${entry.header.path} ${JSON.stringify(text)}`)
511
+ * )
512
+ * ),
513
+ * Stream.runCollect
514
+ * )
515
+ * await Effect.runPromise(listing) // => ['docs/ ""', 'docs/readme.txt "Hello, zip!"']
516
+ * ```
517
+ *
518
+ * @see {@link decode} for the inverse operation
519
+ * @see {@link file} for building entries from in-memory content
520
+ * @see {@link fileStream} for building entries from streamed content
521
+ *
522
+ * @stability experimental
523
+ * @category encoding
524
+ * @since 4.0.6
525
+ */
526
+ export const encode = <
527
+ IE = never,
528
+ Done = unknown,
529
+ In extends Entry<any, any> | ContentEntry = Entry | ContentEntry
530
+ >(): Channel.Channel<
531
+ Arr.NonEmptyReadonlyArray<Uint8Array>,
532
+ ZipError | IE | (In extends Entry<infer E, any> ? E : never),
533
+ Done,
534
+ Arr.NonEmptyReadonlyArray<In>,
535
+ IE,
536
+ Done,
537
+ In extends Entry<any, infer R> ? R : never
538
+ > => {
539
+ // Distribute over entry unions to infer body errors and services.
540
+ type E = In extends Entry<infer E, any> ? E : never
541
+ type R = In extends Entry<any, infer R> ? R : never
542
+ return Channel.fromTransform((upstream: Pull.Pull<Arr.NonEmptyReadonlyArray<In>, IE, Done>, scope) =>
543
+ Effect.sync(() => {
544
+ const writer = new Writer()
545
+ let entries: ReadonlyArray<Entry<E, R> | ContentEntry> = []
546
+ let index = 0
547
+ let done: { readonly value: Done } | undefined
548
+ let body: Pull.Pull<Arr.NonEmptyReadonlyArray<Uint8Array>, E | ZipError, void, R> | undefined
549
+ let bodyScope: Scope.Closeable | undefined
550
+ // In-memory entries are deflated ahead of the one being written, so the
551
+ // deflates overlap
552
+ let deflates: Array<Deflating | undefined> = []
553
+
554
+ const startDeflates = (from: number): void => {
555
+ for (let i = from; i < Math.min(entries.length, from + DEFLATE_AHEAD); i++) {
556
+ if (deflates[i] !== undefined) continue
557
+ const { content, header } = entries[i]
558
+ if (header.type !== "File" || header.method !== "Deflate" || content === undefined) continue
559
+ if (i > from && content.length > DEFLATE_AHEAD_SIZE) continue
560
+ const deflating: Deflating = { promise: deflateBytes(content), data: undefined }
561
+ // Failures surface when the entry is written; deflates left behind by
562
+ // a failed encode finish on their own
563
+ deflating.promise.then((data) => {
564
+ deflating.data = data
565
+ }, () => {})
566
+ deflates[i] = deflating
567
+ }
568
+ }
569
+
570
+ const write = (f: () => void): Effect.Effect<void, ZipError> => {
571
+ try {
572
+ f()
573
+ } catch (error) {
574
+ return isZipError(error) ? Effect.fail(error) : Effect.die(error)
575
+ }
576
+ return Effect.void
577
+ }
578
+
579
+ return Effect.gen(function*() {
580
+ while (true) {
581
+ if (writer.buffered >= SLAB_SIZE) return writer.flush()
582
+ if (body !== undefined) {
583
+ const chunks = yield* Pull.catchDone(body, () => Effect.undefined)
584
+ if (chunks !== undefined) {
585
+ yield* write(() => writer.data(chunks))
586
+ continue
587
+ }
588
+ body = undefined
589
+ yield* Scope.close(bodyScope!, Exit.void)
590
+ yield* write(() => writer.end())
591
+ continue
592
+ }
593
+ if (index < entries.length) {
594
+ const entry = entries[index++]
595
+ const { header } = entry
596
+ yield* write(() => validate(header))
597
+ const compress = header.type === "File" && header.method === "Deflate"
598
+ if (entry.content !== undefined) {
599
+ const bytes = entry.content
600
+ let data = bytes
601
+ if (compress) {
602
+ startDeflates(index - 1)
603
+ const deflating = deflates[index - 1]!
604
+ deflates[index - 1] = undefined
605
+ data = deflating.data ?? (yield* Effect.promise(() => deflating.promise))
606
+ }
607
+ yield* write(() => writer.entry(header, bytes, data))
608
+ continue
609
+ }
610
+ yield* write(() => writer.begin(header))
611
+ if (compress && header.size !== undefined && header.size <= DEFLATE_AHEAD_SIZE) {
612
+ // A small body costs less to deflate in one piece than as a stream
613
+ const size = header.size
614
+ const chunks: Array<Uint8Array> = []
615
+ let length = 0
616
+ yield* Stream.runForEachArray(entry.body, (array) =>
617
+ write(() => {
618
+ for (const chunk of array) {
619
+ chunks.push(chunk)
620
+ length += chunk.length
621
+ }
622
+ if (length > size) throw sizeMismatch(header.path, length, size)
623
+ writer.update(array)
624
+ }))
625
+ const data = yield* Effect.promise(() => deflateBytes(concat(chunks, length)))
626
+ yield* write(() => {
627
+ writer.data([data])
628
+ writer.end()
629
+ })
630
+ continue
631
+ }
632
+ const raw = Stream.mapArray(entry.body, (chunks) => {
633
+ writer.update(chunks)
634
+ return chunks
635
+ })
636
+ bodyScope = Scope.forkUnsafe(scope)
637
+ body = yield* Channel.toPullScoped((compress ? deflate(raw) : raw).channel, bodyScope)
638
+ continue
639
+ }
640
+ if (writer.buffered > 0) return writer.flush()
641
+ if (done !== undefined) return yield* Cause.done(done.value)
642
+ const next = yield* Pull.catchDone(upstream, (value) => {
643
+ done = { value: value as Done }
644
+ return Effect.undefined
645
+ })
646
+ if (next === undefined) {
647
+ writer.finish()
648
+ continue
649
+ }
650
+ entries = next
651
+ index = 0
652
+ deflates = []
653
+ }
654
+ })
655
+ })
656
+ )
657
+ }
658
+
659
+ // Compressor failures, including a runtime without `deflate-raw`, are defects
660
+ const deflate = <E, R>(input: Stream.Stream<Uint8Array, E, R>): Stream.Stream<Uint8Array, E, R> =>
661
+ Stream.unwrap(Effect.map(
662
+ Effect.sync(() => new CompressionStream("deflate-raw")),
663
+ (compressor) => {
664
+ const writer = compressor.writable.getWriter()
665
+ const feed = Stream.runForEach(
666
+ input,
667
+ (chunk) => Effect.promise(() => writer.write(compressible(chunk)))
668
+ ).pipe(
669
+ Effect.andThen(Effect.promise(() => writer.close())),
670
+ Effect.onError(() =>
671
+ Effect.sync(() => {
672
+ writer.abort().catch(() => {})
673
+ })
674
+ )
675
+ )
676
+ const output = Stream.orDie(Stream.fromReadableStream({
677
+ evaluate: () => compressor.readable,
678
+ onError: (cause) => cause
679
+ }))
680
+ return Stream.merge(output, Stream.fromEffectDrain(feed))
681
+ }
682
+ ))
683
+
684
+ // CompressionStream rejects views of a SharedArrayBuffer
685
+ const compressible = (bytes: Uint8Array): Uint8Array<ArrayBuffer> =>
686
+ bytes.buffer instanceof ArrayBuffer ? bytes as Uint8Array<ArrayBuffer> : bytes.slice()
687
+
688
+ // How many in-memory entries are deflated at once, and the largest one that
689
+ // is deflated before its turn
690
+ const DEFLATE_AHEAD = 16
691
+ const DEFLATE_AHEAD_SIZE = 64 * 1024
692
+
693
+ // A deflate started ahead, with its data once it is done
694
+ interface Deflating {
695
+ readonly promise: Promise<Uint8Array>
696
+ data: Uint8Array | undefined
697
+ }
698
+
699
+ // One promise per in-memory entry costs less than a stream
700
+ const deflateBytes = async (bytes: Uint8Array): Promise<Uint8Array> => {
701
+ const compressor = new CompressionStream("deflate-raw")
702
+ const writer = compressor.writable.getWriter()
703
+ // A failed write errors the readable, so the reads report it
704
+ if (bytes.length > 0) writer.write(compressible(bytes)).catch(() => {})
705
+ writer.close().catch(() => {})
706
+ const reader = compressor.readable.getReader()
707
+ const chunks: Array<Uint8Array> = []
708
+ let length = 0
709
+ while (true) {
710
+ const { done, value } = await reader.read()
711
+ if (done) break
712
+ chunks.push(value)
713
+ length += value.length
714
+ }
715
+ return concat(chunks, length)
716
+ }
717
+
718
+ const concat = (chunks: ReadonlyArray<Uint8Array>, length: number): Uint8Array => {
719
+ if (chunks.length === 1) return chunks[0]
720
+ const out = new Uint8Array(length)
721
+ let at = 0
722
+ for (const chunk of chunks) {
723
+ out.set(chunk, at)
724
+ at += chunk.length
725
+ }
726
+ return out
727
+ }
728
+
729
+ const invalidHeader = (message: string) => new ZipError({ kind: "InvalidHeader", message })
730
+
731
+ const invalidData = (message: string) => new ZipError({ kind: "InvalidData", message })
732
+
733
+ const truncated = (at: number) =>
734
+ new ZipError({ kind: "Truncated", message: `unexpected end of zip archive at byte ${at}` })
735
+
736
+ const unsupported = (message: string) => new ZipError({ kind: "Unsupported", message })
737
+
738
+ const sizeMismatch = (path: string, actual: number, expected: number) =>
739
+ new ZipError({
740
+ kind: "SizeMismatch",
741
+ message: `body of ${JSON.stringify(path)} has ${
742
+ actual > expected ? "at least" : "only"
743
+ } ${actual} bytes, but its size is ${expected}`
744
+ })
745
+
746
+ const LOCAL = 0x04034b50
747
+ const CENTRAL = 0x02014b50
748
+ const DESCRIPTOR = 0x08074b50
749
+ const END = 0x06054b50
750
+ const END64 = 0x06064b50
751
+ const LOCATOR64 = 0x07064b50
752
+
753
+ const FLAG_ENCRYPTED = 0x0001
754
+ const FLAG_DESCRIPTOR = 0x0008
755
+ const FLAG_STRONG_ENCRYPTION = 0x0040
756
+ const FLAG_UTF8 = 0x0800
757
+
758
+ const EXTRA_ZIP64 = 0x0001
759
+ const EXTRA_TIMESTAMP = 0x5455
760
+ const EXTRA_UNICODE_PATH = 0x7075
761
+
762
+ const VERSION = 20
763
+ const VERSION_ZIP64 = 45
764
+ const CREATOR_UNIX = 3
765
+
766
+ const MAX16 = 0xffff
767
+ const MAX32 = 0xffffffff
768
+
769
+ const S_IFDIR = 0o040000
770
+ const S_IFREG = 0o100000
771
+ const DOS_DIRECTORY = 0x10
772
+
773
+ const textEncoder = new TextEncoder()
774
+ // Paths keep a leading byte order mark, as other zip tools do
775
+ const textDecoder = new TextDecoder("utf-8", { ignoreBOM: true })
776
+ const strictTextDecoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true })
777
+
778
+ const emptyBody = new Uint8Array(0)
779
+
780
+ // May exceed 2^53 - 1; callers check or compare
781
+ const readUint64 = (view: DataView, at: number): number =>
782
+ view.getUint32(at, true) + view.getUint32(at + 4, true) * 0x100000000
783
+
784
+ const getUint64 = (view: DataView, at: number): number => {
785
+ const value = readUint64(view, at)
786
+ if (!Number.isSafeInteger(value)) throw invalidHeader("a 64-bit field exceeds 2^53 - 1")
787
+ return value
788
+ }
789
+
790
+ const setUint64 = (view: DataView, at: number, value: number): void => {
791
+ view.setUint32(at, value % 0x100000000, true)
792
+ view.setUint32(at + 4, Math.floor(value / 0x100000000), true)
793
+ }
794
+
795
+ // DOS times have two-second resolution and cover 1980 to 2107
796
+ const toDos = (mtime: Date): { readonly time: number; readonly date: number } => {
797
+ const millis = mtime.getTime()
798
+ if (millis < MIN_MTIME) return { time: 0, date: (1 << 5) | 1 }
799
+ const date = new Date(millis)
800
+ const year = date.getUTCFullYear()
801
+ if (year > 2107) return { time: (23 << 11) | (59 << 5) | 29, date: (127 << 9) | (12 << 5) | 31 }
802
+ return {
803
+ time: (date.getUTCHours() << 11) | (date.getUTCMinutes() << 5) | (date.getUTCSeconds() >> 1),
804
+ date: ((year - 1980) << 9) | ((date.getUTCMonth() + 1) << 5) | date.getUTCDate()
805
+ }
806
+ }
807
+
808
+ const fromDos = (time: number, date: number): number =>
809
+ Date.UTC(
810
+ (date >> 9) + 1980,
811
+ ((date >> 5) & 0xf) - 1,
812
+ date & 0x1f,
813
+ time >> 11,
814
+ (time >> 5) & 0x3f,
815
+ (time & 0x1f) * 2
816
+ )
817
+
818
+ const CP437 = "ÇüéâäàåçêëèïîìÄÅ" +
819
+ "ÉæÆôöòûùÿÖÜ¢£¥₧ƒ" +
820
+ "áíóúñѪº¿⌐¬½¼¡«»" +
821
+ "░▒▓│┤╡╢╖╕╣║╗╝╜╛┐" +
822
+ "└┴┬├─┼╞╟╚╔╩╦╠═╬╧" +
823
+ "╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀" +
824
+ "αßΓπΣσµτΦΘΩδ∞φε∩" +
825
+ "≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "
826
+
827
+ const decodeName = (bytes: Uint8Array, utf8: boolean): string => {
828
+ if (utf8) return textDecoder.decode(bytes)
829
+ try {
830
+ return strictTextDecoder.decode(bytes)
831
+ } catch {
832
+ let name = ""
833
+ for (let i = 0; i < bytes.length; i++) {
834
+ name += bytes[i] < 0x80 ? String.fromCharCode(bytes[i]) : CP437[bytes[i] - 0x80]
835
+ }
836
+ return name
837
+ }
838
+ }
839
+
840
+ // CRC-32 (IEEE) lookup tables for sixteen bytes at a time
841
+ const CRC_TABLE = (() => {
842
+ const table = new Int32Array(16 * 256)
843
+ for (let n = 0; n < 256; n++) {
844
+ let c = n
845
+ for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1
846
+ table[n] = c
847
+ }
848
+ for (let n = 0; n < 256; n++) {
849
+ let c = table[n]
850
+ for (let k = 1; k < 16; k++) {
851
+ c = table[c & 0xff] ^ (c >>> 8)
852
+ table[k * 256 + n] = c
853
+ }
854
+ }
855
+ return table
856
+ })()
857
+
858
+ const littleEndian = new Uint8Array(new Uint32Array([1]).buffer)[0] === 1
859
+
860
+ const crc32 = (crc: number, bytes: Uint8Array): number => {
861
+ const t = CRC_TABLE
862
+ let c = ~crc
863
+ let i = 0
864
+ const length = bytes.length
865
+ // Reading whole words is faster than combining bytes, but needs aligned,
866
+ // little-endian words
867
+ if (littleEndian && length >= 64) {
868
+ for (; ((bytes.byteOffset + i) & 3) !== 0; i++) c = t[(c ^ bytes[i]) & 0xff] ^ (c >>> 8)
869
+ const count = ((length - i) >>> 4) << 2
870
+ const words = new Int32Array(bytes.buffer, bytes.byteOffset + i, count)
871
+ for (let j = 0; j < count; j += 4) {
872
+ const a = c ^ words[j]
873
+ const b = words[j + 1]
874
+ const d = words[j + 2]
875
+ const e = words[j + 3]
876
+ c = t[3840 + (a & 0xff)] ^ t[3584 + ((a >>> 8) & 0xff)] ^ t[3328 + ((a >>> 16) & 0xff)] ^
877
+ t[3072 + (a >>> 24)] ^ t[2816 + (b & 0xff)] ^ t[2560 + ((b >>> 8) & 0xff)] ^
878
+ t[2304 + ((b >>> 16) & 0xff)] ^ t[2048 + (b >>> 24)] ^ t[1792 + (d & 0xff)] ^
879
+ t[1536 + ((d >>> 8) & 0xff)] ^ t[1280 + ((d >>> 16) & 0xff)] ^ t[1024 + (d >>> 24)] ^
880
+ t[768 + (e & 0xff)] ^ t[512 + ((e >>> 8) & 0xff)] ^ t[256 + ((e >>> 16) & 0xff)] ^ t[e >>> 24]
881
+ }
882
+ i += count * 4
883
+ }
884
+ for (; i + 16 <= length; i += 16) {
885
+ const a = c ^ (bytes[i] | (bytes[i + 1] << 8) | (bytes[i + 2] << 16) | (bytes[i + 3] << 24))
886
+ c = t[3840 + (a & 0xff)] ^ t[3584 + ((a >>> 8) & 0xff)] ^ t[3328 + ((a >>> 16) & 0xff)] ^
887
+ t[3072 + (a >>> 24)] ^ t[2816 + bytes[i + 4]] ^ t[2560 + bytes[i + 5]] ^ t[2304 + bytes[i + 6]] ^
888
+ t[2048 + bytes[i + 7]] ^ t[1792 + bytes[i + 8]] ^ t[1536 + bytes[i + 9]] ^ t[1280 + bytes[i + 10]] ^
889
+ t[1024 + bytes[i + 11]] ^ t[768 + bytes[i + 12]] ^ t[512 + bytes[i + 13]] ^ t[256 + bytes[i + 14]] ^
890
+ t[bytes[i + 15]]
891
+ }
892
+ for (; i < length; i++) c = t[(c ^ bytes[i]) & 0xff] ^ (c >>> 8)
893
+ return ~c >>> 0
894
+ }
895
+
896
+ const validate = (header: Header): void => {
897
+ const { method, mode, mtime, path, size, type } = header
898
+ if (path === "") throw invalidHeader("path is empty")
899
+ const quoted = JSON.stringify(path)
900
+ if (path.startsWith("/")) throw invalidHeader(`path ${quoted} is absolute`)
901
+ // The zip format forbids these, and libarchive reads them as separators and roots
902
+ if (path.includes("\\")) throw invalidHeader(`path ${quoted} contains a backslash`)
903
+ if (/^[A-Za-z]:/.test(path)) throw invalidHeader(`path ${quoted} starts with a drive letter`)
904
+ if (path.includes("\0")) throw invalidHeader(`path ${quoted} contains a NUL character`)
905
+ if (type === "File") {
906
+ if (path.endsWith("/")) throw invalidHeader(`file path ${quoted} ends with "/"`)
907
+ if (method !== "Store" && method !== "Deflate") throw invalidHeader(`unknown method for ${quoted}`)
908
+ } else if (type === "Directory") {
909
+ if (!path.endsWith("/")) throw invalidHeader(`directory path ${quoted} does not end with "/"`)
910
+ if (size !== undefined && size !== 0) throw invalidHeader(`directory ${quoted} has a size`)
911
+ } else {
912
+ throw invalidHeader(`unknown entry type for ${quoted}`)
913
+ }
914
+ if (size !== undefined && !(Number.isSafeInteger(size) && size >= 0)) {
915
+ throw invalidHeader(`size of ${quoted} is not a non-negative safe integer`)
916
+ }
917
+ if (mode !== undefined && !(Number.isInteger(mode) && mode >= 0 && mode <= 0o7777)) {
918
+ throw invalidHeader(`mode of ${quoted} is not a permission mode`)
919
+ }
920
+ if (Number.isNaN(mtime.getTime())) {
921
+ throw invalidHeader(`mtime of ${quoted} is not a valid date`)
922
+ }
923
+ }
924
+
925
+ interface EntryRecord {
926
+ readonly name: Uint8Array
927
+ readonly flags: number
928
+ readonly method: number
929
+ readonly time: number
930
+ readonly date: number
931
+ readonly seconds: number | undefined
932
+ readonly external: number
933
+ readonly offset: number
934
+ // Whether the local header has ZIP64 sizes, which then also follow the data
935
+ zip64: boolean
936
+ crc: number
937
+ compressedSize: number
938
+ size: number
939
+ }
940
+
941
+ // An entry whose data is being written; `record` counts its bytes
942
+ interface Streaming {
943
+ readonly header: Header
944
+ readonly record: EntryRecord
945
+ readonly descriptor: boolean
946
+ }
947
+
948
+ const timestampLength = (record: EntryRecord): number => record.seconds === undefined ? 0 : 9
949
+
950
+ const writeTimestamp = (bytes: Uint8Array, view: DataView, at: number, record: EntryRecord): void => {
951
+ if (record.seconds === undefined) return
952
+ view.setUint16(at, EXTRA_TIMESTAMP, true)
953
+ view.setUint16(at + 2, 5, true)
954
+ bytes[at + 4] = 1
955
+ view.setUint32(at + 5, record.seconds, true)
956
+ }
957
+
958
+ const localHeader = (record: EntryRecord): Uint8Array => {
959
+ const { zip64 } = record
960
+ const extraLength = (zip64 ? 20 : 0) + timestampLength(record)
961
+ const bytes = new Uint8Array(30 + record.name.length + extraLength)
962
+ const view = new DataView(bytes.buffer)
963
+ view.setUint32(0, LOCAL, true)
964
+ view.setUint16(4, zip64 ? VERSION_ZIP64 : VERSION, true)
965
+ view.setUint16(6, record.flags, true)
966
+ view.setUint16(8, record.method, true)
967
+ view.setUint16(10, record.time, true)
968
+ view.setUint16(12, record.date, true)
969
+ view.setUint32(14, record.crc, true)
970
+ view.setUint32(18, zip64 ? MAX32 : record.compressedSize, true)
971
+ view.setUint32(22, zip64 ? MAX32 : record.size, true)
972
+ view.setUint16(26, record.name.length, true)
973
+ view.setUint16(28, extraLength, true)
974
+ bytes.set(record.name, 30)
975
+ let at = 30 + record.name.length
976
+ if (zip64) {
977
+ view.setUint16(at, EXTRA_ZIP64, true)
978
+ view.setUint16(at + 2, 16, true)
979
+ setUint64(view, at + 4, record.size)
980
+ setUint64(view, at + 12, record.compressedSize)
981
+ at += 20
982
+ }
983
+ writeTimestamp(bytes, view, at, record)
984
+ return bytes
985
+ }
986
+
987
+ const dataDescriptor = (record: EntryRecord): Uint8Array => {
988
+ const wide = record.zip64
989
+ const bytes = new Uint8Array(wide ? 24 : 16)
990
+ const view = new DataView(bytes.buffer)
991
+ view.setUint32(0, DESCRIPTOR, true)
992
+ view.setUint32(4, record.crc, true)
993
+ if (wide) {
994
+ setUint64(view, 8, record.compressedSize)
995
+ setUint64(view, 16, record.size)
996
+ } else {
997
+ view.setUint32(8, record.compressedSize, true)
998
+ view.setUint32(12, record.size, true)
999
+ }
1000
+ return bytes
1001
+ }
1002
+
1003
+ const centralHeader = (record: EntryRecord): Uint8Array => {
1004
+ // ZIP64 holds only the fields that overflow, in this order
1005
+ const wide: Array<number> = []
1006
+ if (record.size >= MAX32) wide.push(record.size)
1007
+ if (record.compressedSize >= MAX32) wide.push(record.compressedSize)
1008
+ if (record.offset >= MAX32) wide.push(record.offset)
1009
+ const zip64Length = wide.length === 0 ? 0 : 4 + 8 * wide.length
1010
+ const extraLength = zip64Length + timestampLength(record)
1011
+ const version = wide.length === 0 && !record.zip64 ? VERSION : VERSION_ZIP64
1012
+ const bytes = new Uint8Array(46 + record.name.length + extraLength)
1013
+ const view = new DataView(bytes.buffer)
1014
+ view.setUint32(0, CENTRAL, true)
1015
+ view.setUint16(4, (CREATOR_UNIX << 8) | version, true)
1016
+ view.setUint16(6, version, true)
1017
+ view.setUint16(8, record.flags, true)
1018
+ view.setUint16(10, record.method, true)
1019
+ view.setUint16(12, record.time, true)
1020
+ view.setUint16(14, record.date, true)
1021
+ view.setUint32(16, record.crc, true)
1022
+ view.setUint32(20, Math.min(record.compressedSize, MAX32), true)
1023
+ view.setUint32(24, Math.min(record.size, MAX32), true)
1024
+ view.setUint16(28, record.name.length, true)
1025
+ view.setUint16(30, extraLength, true)
1026
+ view.setUint32(38, record.external, true)
1027
+ view.setUint32(42, Math.min(record.offset, MAX32), true)
1028
+ bytes.set(record.name, 46)
1029
+ let at = 46 + record.name.length
1030
+ if (wide.length > 0) {
1031
+ view.setUint16(at, EXTRA_ZIP64, true)
1032
+ view.setUint16(at + 2, 8 * wide.length, true)
1033
+ for (let i = 0; i < wide.length; i++) setUint64(view, at + 4 + 8 * i, wide[i])
1034
+ at += zip64Length
1035
+ }
1036
+ writeTimestamp(bytes, view, at, record)
1037
+ return bytes
1038
+ }
1039
+
1040
+ const SLAB_SIZE = 64 * 1024
1041
+
1042
+ // Room for deflate to grow data that does not compress, when choosing ZIP64
1043
+ const DEFLATE_HEADROOM = 16 * 1024 * 1024
1044
+
1045
+ // Chunks below this size are copied together instead of being handed out alone
1046
+ const COPY_LIMIT = 16 * 1024
1047
+
1048
+ class Writer {
1049
+ private chunks: Array<Uint8Array> = []
1050
+ buffered = 0
1051
+ private offset = 0
1052
+ private readonly records: Array<EntryRecord> = []
1053
+ private current: Streaming | undefined
1054
+
1055
+ // Hands out the buffered output, joining runs of small chunks; needs `buffered > 0`
1056
+ flush(): Arr.NonEmptyArray<Uint8Array> {
1057
+ const out: Array<Uint8Array> = []
1058
+ let run: Array<Uint8Array> = []
1059
+ let runLength = 0
1060
+ const join = () => {
1061
+ if (run.length === 1) {
1062
+ out.push(run[0])
1063
+ } else if (run.length > 1) {
1064
+ const joined = new Uint8Array(runLength)
1065
+ let at = 0
1066
+ for (const chunk of run) {
1067
+ joined.set(chunk, at)
1068
+ at += chunk.length
1069
+ }
1070
+ out.push(joined)
1071
+ }
1072
+ run = []
1073
+ runLength = 0
1074
+ }
1075
+ for (const chunk of this.chunks) {
1076
+ if (chunk.length >= COPY_LIMIT) {
1077
+ join()
1078
+ out.push(chunk)
1079
+ } else {
1080
+ run.push(chunk)
1081
+ runLength += chunk.length
1082
+ }
1083
+ }
1084
+ join()
1085
+ this.chunks = []
1086
+ this.buffered = 0
1087
+ return out as Arr.NonEmptyArray<Uint8Array>
1088
+ }
1089
+
1090
+ private push(bytes: Uint8Array): void {
1091
+ if (bytes.length === 0) return
1092
+ this.chunks.push(bytes)
1093
+ this.offset += bytes.length
1094
+ this.buffered += bytes.length
1095
+ }
1096
+
1097
+ private record(header: Header, flags: number): EntryRecord {
1098
+ const name = textEncoder.encode(header.path)
1099
+ if (name.length > MAX16) throw invalidHeader(`path ${JSON.stringify(header.path)} is longer than 65535 bytes`)
1100
+ const { date, time } = toDos(header.mtime)
1101
+ const seconds = Math.floor(header.mtime.getTime() / 1000)
1102
+ const directory = header.type === "Directory"
1103
+ const mode = header.mode ?? (directory ? 0o755 : 0o644)
1104
+ return {
1105
+ name,
1106
+ // The UTF-8 byte length equals the string length only for ASCII
1107
+ flags: name.length === header.path.length ? flags : flags | FLAG_UTF8,
1108
+ method: header.type === "File" && header.method === "Deflate" ? 8 : 0,
1109
+ time,
1110
+ date,
1111
+ seconds: seconds >= 0 && seconds <= 0x7fffffff ? seconds : undefined,
1112
+ external: (((directory ? S_IFDIR : S_IFREG) | mode) * 0x10000 + (directory ? DOS_DIRECTORY : 0)) >>> 0,
1113
+ offset: this.offset,
1114
+ zip64: false,
1115
+ crc: 0,
1116
+ compressedSize: 0,
1117
+ size: 0
1118
+ }
1119
+ }
1120
+
1121
+ // Writes an entry whose content is known, with its sizes in the local header
1122
+ entry(header: Header, content: Uint8Array, data: Uint8Array): void {
1123
+ const size = header.type === "Directory" ? 0 : header.size
1124
+ if (size !== undefined && size !== content.length) throw sizeMismatch(header.path, content.length, size)
1125
+ const record = this.record(header, 0)
1126
+ record.crc = crc32(0, content)
1127
+ record.size = content.length
1128
+ record.compressedSize = data.length
1129
+ record.zip64 = record.size >= MAX32 || record.compressedSize >= MAX32
1130
+ this.push(localHeader(record))
1131
+ if (data.length > 0) this.push(data)
1132
+ this.records.push(record)
1133
+ }
1134
+
1135
+ // Starts an entry whose sizes and CRC-32 follow its data
1136
+ begin(header: Header): void {
1137
+ const directory = header.type === "Directory"
1138
+ const stored = directory || header.method === "Store"
1139
+ const size = directory ? 0 : header.size
1140
+ if (stored && size === undefined) {
1141
+ throw invalidHeader(`stored file ${JSON.stringify(header.path)} is streamed without a size`)
1142
+ }
1143
+ // An empty stored entry needs no descriptor: readers would take its zero
1144
+ // sizes for missing ones
1145
+ const descriptor = !(stored && size === 0)
1146
+ const record = this.record(header, descriptor ? FLAG_DESCRIPTOR : 0)
1147
+ // Streaming readers find the end of stored data from its size
1148
+ if (stored) {
1149
+ record.size = size!
1150
+ record.compressedSize = size!
1151
+ }
1152
+ // The local header fixes the width of the sizes after the data, so declare
1153
+ // ZIP64 whenever they could reach 4 GiB
1154
+ record.zip64 = size === undefined || size >= (stored ? MAX32 : MAX32 - DEFLATE_HEADROOM)
1155
+ this.push(localHeader(record))
1156
+ record.size = 0
1157
+ record.compressedSize = 0
1158
+ this.current = { header, record, descriptor }
1159
+ }
1160
+
1161
+ // Accounts for uncompressed body bytes
1162
+ update(chunks: ReadonlyArray<Uint8Array>): void {
1163
+ const { record } = this.current!
1164
+ for (const chunk of chunks) {
1165
+ record.crc = crc32(record.crc, chunk)
1166
+ record.size += chunk.length
1167
+ }
1168
+ }
1169
+
1170
+ // Writes stored or compressed body bytes
1171
+ data(chunks: ReadonlyArray<Uint8Array>): void {
1172
+ const { header, record } = this.current!
1173
+ for (const chunk of chunks) {
1174
+ this.push(chunk)
1175
+ record.compressedSize += chunk.length
1176
+ }
1177
+ const size = header.type === "Directory" ? 0 : header.size
1178
+ if (size !== undefined && record.size > size) throw sizeMismatch(header.path, record.size, size)
1179
+ if (!record.zip64 && record.compressedSize >= MAX32) {
1180
+ throw new ZipError({
1181
+ kind: "SizeMismatch",
1182
+ message: `compressed data of ${JSON.stringify(header.path)} reached 4 GiB, ` +
1183
+ `but its local header has no ZIP64 sizes`
1184
+ })
1185
+ }
1186
+ }
1187
+
1188
+ end(): void {
1189
+ const { descriptor, header, record } = this.current!
1190
+ this.current = undefined
1191
+ if (header.size !== undefined && record.size !== header.size) {
1192
+ throw sizeMismatch(header.path, record.size, header.size)
1193
+ }
1194
+ if (descriptor) this.push(dataDescriptor(record))
1195
+ this.records.push(record)
1196
+ }
1197
+
1198
+ finish(): void {
1199
+ const start = this.offset
1200
+ for (const record of this.records) this.push(centralHeader(record))
1201
+ const size = this.offset - start
1202
+ const count = this.records.length
1203
+ if (count >= MAX16 || size >= MAX32 || start >= MAX32) {
1204
+ const end64 = new Uint8Array(56)
1205
+ const view = new DataView(end64.buffer)
1206
+ view.setUint32(0, END64, true)
1207
+ setUint64(view, 4, 44)
1208
+ view.setUint16(12, (CREATOR_UNIX << 8) | VERSION_ZIP64, true)
1209
+ view.setUint16(14, VERSION_ZIP64, true)
1210
+ setUint64(view, 24, count)
1211
+ setUint64(view, 32, count)
1212
+ setUint64(view, 40, size)
1213
+ setUint64(view, 48, start)
1214
+ const locator = new Uint8Array(20)
1215
+ const locatorView = new DataView(locator.buffer)
1216
+ locatorView.setUint32(0, LOCATOR64, true)
1217
+ setUint64(locatorView, 8, this.offset)
1218
+ locatorView.setUint32(16, 1, true)
1219
+ this.push(end64)
1220
+ this.push(locator)
1221
+ }
1222
+ const end = new Uint8Array(22)
1223
+ const view = new DataView(end.buffer)
1224
+ view.setUint32(0, END, true)
1225
+ view.setUint16(8, Math.min(count, MAX16), true)
1226
+ view.setUint16(10, Math.min(count, MAX16), true)
1227
+ view.setUint32(12, Math.min(size, MAX32), true)
1228
+ view.setUint32(16, Math.min(start, MAX32), true)
1229
+ this.push(end)
1230
+ }
1231
+ }
1232
+
1233
+ interface Current {
1234
+ readonly header: Header
1235
+ readonly inflater: Inflater | undefined
1236
+ readonly descriptor: boolean
1237
+ readonly zip64: boolean
1238
+ // The values of the local header; sizes are unknown when they follow the data
1239
+ readonly crc: number
1240
+ readonly compressedSize: number | undefined
1241
+ readonly size: number | undefined
1242
+ // Queue position where the data starts
1243
+ readonly start: number
1244
+ remaining: number
1245
+ dataDone: boolean
1246
+ actualCrc: number
1247
+ actualSize: number
1248
+ actualCompressedSize: number
1249
+ }
1250
+
1251
+ // `next` skips the rest of the current body; `read` consumes it. Both preserve
1252
+ // progress across `NeedInput` retries.
1253
+ class Decoder {
1254
+ private readonly queue = new ByteQueue()
1255
+ private ended = false
1256
+ private finished = false
1257
+ private closed = false
1258
+ // Incremented whenever the current body is invalidated
1259
+ generation = 0
1260
+ private current: Current | undefined
1261
+ private inflateMemory: InflateMemory | undefined
1262
+ // The error that ended the archive, repeated by every later call
1263
+ private failure: ZipError | undefined
1264
+
1265
+ push(chunk: Uint8Array): void {
1266
+ if (!this.finished) this.queue.push(chunk)
1267
+ }
1268
+
1269
+ end(): void {
1270
+ this.ended = true
1271
+ }
1272
+
1273
+ close(): void {
1274
+ this.closed = true
1275
+ this.generation++
1276
+ this.queue.clear()
1277
+ }
1278
+
1279
+ // Returns the next entry header, or `undefined` once the entries and the
1280
+ // input have ended. Input after the entries is discarded.
1281
+ next(): Header | undefined | typeof NeedInput {
1282
+ this.generation++
1283
+ return this.guard(() => this.advance())
1284
+ }
1285
+
1286
+ private guard<A>(f: () => A): A {
1287
+ if (this.failure !== undefined) throw this.failure
1288
+ try {
1289
+ return f()
1290
+ } catch (error) {
1291
+ if (isZipError(error)) this.failure = error
1292
+ throw error
1293
+ }
1294
+ }
1295
+
1296
+ private advance(): Header | undefined | typeof NeedInput {
1297
+ while (this.current !== undefined) {
1298
+ if (this.readCurrent() === NeedInput) return NeedInput
1299
+ }
1300
+ if (this.finished) return this.finish()
1301
+ const queue = this.queue
1302
+ if (queue.length < 4) return this.needInput()
1303
+ const at = queue.consumed
1304
+ const head = queue.peek(Math.min(queue.length, 30))
1305
+ const view = new DataView(head.buffer)
1306
+ const signature = view.getUint32(0, true)
1307
+ if (signature === CENTRAL || signature === END || signature === END64) return this.finish()
1308
+ if (signature !== LOCAL) {
1309
+ throw invalidHeader(`unexpected signature 0x${signature.toString(16).padStart(8, "0")} at byte ${at}`)
1310
+ }
1311
+ if (head.length < 30) return this.needInput()
1312
+ const length = 30 + view.getUint16(26, true) + view.getUint16(28, true)
1313
+ if (queue.length < length) return this.needInput()
1314
+ try {
1315
+ this.current = this.parseLocal(queue.take(length))
1316
+ } catch (error) {
1317
+ if (isZipError(error)) {
1318
+ throw new ZipError({ kind: error.kind, message: `${error.message} (header at byte ${at})` })
1319
+ }
1320
+ throw error
1321
+ }
1322
+ return this.current.header
1323
+ }
1324
+
1325
+ // Returns the buffered body bytes of the entry from generation `id`, or
1326
+ // `undefined` once the whole body has been read and checked
1327
+ read(id: number): Arr.NonEmptyArray<Uint8Array> | undefined | typeof NeedInput {
1328
+ if (id !== this.generation) {
1329
+ throw new ZipError({
1330
+ kind: "BodyConsumed",
1331
+ message: this.closed ?
1332
+ "zip entry body read after the archive stream ended" :
1333
+ "zip entry body read after moving to the next entry"
1334
+ })
1335
+ }
1336
+ return this.guard(() => this.readCurrent())
1337
+ }
1338
+
1339
+ private readCurrent(): Arr.NonEmptyArray<Uint8Array> | undefined | typeof NeedInput {
1340
+ const current = this.current
1341
+ if (current === undefined) return undefined
1342
+ const queue = this.queue
1343
+ if (!current.dataDone) {
1344
+ if (current.inflater === undefined) {
1345
+ if (current.remaining > 0) {
1346
+ if (queue.length === 0) return this.needInput()
1347
+ const chunks: Array<Uint8Array> = []
1348
+ while (current.remaining > 0 && queue.length > 0) {
1349
+ const chunk = queue.takeSome(current.remaining)
1350
+ current.remaining -= chunk.length
1351
+ current.actualCrc = crc32(current.actualCrc, chunk)
1352
+ current.actualSize += chunk.length
1353
+ chunks.push(chunk)
1354
+ }
1355
+ current.actualCompressedSize = current.actualSize
1356
+ return chunks as Arr.NonEmptyArray<Uint8Array>
1357
+ }
1358
+ } else {
1359
+ let chunk: Uint8Array | undefined | typeof NeedInput
1360
+ try {
1361
+ chunk = current.inflater.pull()
1362
+ } catch (error) {
1363
+ throw error instanceof InflateError ? invalidData(error.message) : error
1364
+ }
1365
+ if (chunk === NeedInput) return this.needInput()
1366
+ if (chunk !== undefined) {
1367
+ current.actualSize += chunk.length
1368
+ // Fail before handing out bytes past the reported size, so that
1369
+ // consumers can limit what a small compressed entry inflates to
1370
+ const { path, size } = current.header
1371
+ if (size !== undefined && current.actualSize > size) throw sizeMismatch(path, current.actualSize, size)
1372
+ current.actualCrc = crc32(current.actualCrc, chunk)
1373
+ return [chunk]
1374
+ }
1375
+ current.actualCompressedSize = queue.consumed - current.start
1376
+ }
1377
+ current.dataDone = true
1378
+ }
1379
+ if (current.descriptor) {
1380
+ const descriptor = this.descriptor(current)
1381
+ if (descriptor === NeedInput) return NeedInput
1382
+ this.check(current, descriptor.crc, descriptor.compressedSize, descriptor.size)
1383
+ } else {
1384
+ this.check(current, current.crc, current.compressedSize!, current.size!)
1385
+ }
1386
+ this.current = undefined
1387
+ return undefined
1388
+ }
1389
+
1390
+ private check(current: Current, crc: number, compressedSize: number, size: number): void {
1391
+ if (current.actualCrc === crc && current.actualCompressedSize === compressedSize && current.actualSize === size) {
1392
+ return
1393
+ }
1394
+ const path = JSON.stringify(current.header.path)
1395
+ if (current.actualCrc !== crc) {
1396
+ throw new ZipError({
1397
+ kind: "Checksum",
1398
+ message: `CRC-32 of ${path} is ${hex(current.actualCrc)}, but the archive records ${hex(crc)}`
1399
+ })
1400
+ }
1401
+ throw new ZipError({
1402
+ kind: "SizeMismatch",
1403
+ message: `${path} has ${current.actualSize} bytes (${current.actualCompressedSize} compressed), ` +
1404
+ `but the archive records ${size} (${compressedSize} compressed)`
1405
+ })
1406
+ }
1407
+
1408
+ // Reads a data descriptor, whose signature is optional and whose sizes are
1409
+ // 4 bytes unless the local header has a ZIP64 field. Writers that widen the
1410
+ // sizes only on overflow are handled by matching each layout against the
1411
+ // data read; among several matches, one followed by a header signature wins.
1412
+ private descriptor(
1413
+ current: Current
1414
+ ): { readonly crc: number; readonly compressedSize: number; readonly size: number } | typeof NeedInput {
1415
+ const queue = this.queue
1416
+ if (queue.length < DESCRIPTOR_PEEK && !this.ended) return NeedInput
1417
+ const bytes = queue.peek(Math.min(queue.length, DESCRIPTOR_PEEK))
1418
+ const view = new DataView(bytes.buffer)
1419
+ const candidates: Array<{ length: number; crc: number; compressedSize: number; size: number }> = []
1420
+ const offsets = bytes.length >= 4 && view.getUint32(0, true) === DESCRIPTOR ? [4, 0] : [0]
1421
+ for (const offset of offsets) {
1422
+ for (const wide of current.zip64 ? [true, false] : [false, true]) {
1423
+ const length = offset + (wide ? 20 : 12)
1424
+ if (length > bytes.length) continue
1425
+ candidates.push({
1426
+ length,
1427
+ crc: view.getUint32(offset, true),
1428
+ compressedSize: wide ? readUint64(view, offset + 4) : view.getUint32(offset + 4, true),
1429
+ size: wide ? readUint64(view, offset + 12) : view.getUint32(offset + 8, true)
1430
+ })
1431
+ }
1432
+ }
1433
+ const matches = candidates.filter((candidate) =>
1434
+ candidate.crc === current.actualCrc && candidate.compressedSize === current.actualCompressedSize &&
1435
+ candidate.size === current.actualSize
1436
+ )
1437
+ const match =
1438
+ matches.find((candidate) =>
1439
+ candidate.length + 4 <= bytes.length && isHeaderSignature(view.getUint32(candidate.length, true))
1440
+ ) ?? matches[0]
1441
+ if (match !== undefined) {
1442
+ queue.skip(match.length)
1443
+ return match
1444
+ }
1445
+ // A complete archive has at least an end record after the descriptor
1446
+ if (candidates.length === 0 || (this.ended && bytes.length < DESCRIPTOR_PEEK)) {
1447
+ throw truncated(queue.consumed + queue.length)
1448
+ }
1449
+ queue.skip(candidates[0].length)
1450
+ return candidates[0]
1451
+ }
1452
+
1453
+ private parseLocal(bytes: Uint8Array): Current {
1454
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.length)
1455
+ const flags = view.getUint16(6, true)
1456
+ const method = view.getUint16(8, true)
1457
+ const crc = view.getUint32(14, true)
1458
+ let compressedSize = view.getUint32(18, true)
1459
+ let size = view.getUint32(22, true)
1460
+ const time = view.getUint16(10, true)
1461
+ const date = view.getUint16(12, true)
1462
+ const nameLength = view.getUint16(26, true)
1463
+ const rawName = bytes.subarray(30, 30 + nameLength)
1464
+ const utf8 = (flags & FLAG_UTF8) !== 0
1465
+ let path = decodeName(rawName, utf8)
1466
+ // As in Info-ZIP and 7-Zip, only the first Unicode path field is read, and
1467
+ // only without the UTF-8 flag
1468
+ let readUnicodePath = !utf8
1469
+ let seconds: number | undefined
1470
+ let zip64 = false
1471
+ let at = 30 + nameLength
1472
+ while (at + 4 <= bytes.length) {
1473
+ const id = view.getUint16(at, true)
1474
+ const start = at + 4
1475
+ const end = start + view.getUint16(at + 2, true)
1476
+ if (end > bytes.length) throw invalidHeader("extra field overflows the header")
1477
+ if (id === EXTRA_ZIP64) {
1478
+ zip64 = true
1479
+ let field = start
1480
+ if (size === MAX32 && field + 8 <= end) {
1481
+ size = getUint64(view, field)
1482
+ field += 8
1483
+ }
1484
+ if (compressedSize === MAX32 && field + 8 <= end) {
1485
+ compressedSize = getUint64(view, field)
1486
+ }
1487
+ } else if (id === EXTRA_TIMESTAMP && end - start >= 5 && (bytes[start] & 1) !== 0) {
1488
+ // Info-ZIP writes times before 1970 as negative numbers, and others
1489
+ // write times after 2038 as unsigned ones; the DOS date tells them apart
1490
+ const value = view.getUint32(start + 1, true)
1491
+ seconds = value >= 0x80000000 && (date >> 9) + 1980 < 2038 ? value - 0x100000000 : value
1492
+ } else if (id === EXTRA_UNICODE_PATH && readUnicodePath) {
1493
+ readUnicodePath = false
1494
+ if (end - start >= 5 && bytes[start] === 1 && view.getUint32(start + 1, true) === crc32(0, rawName)) {
1495
+ path = textDecoder.decode(bytes.subarray(start + 5, end))
1496
+ }
1497
+ }
1498
+ at = end
1499
+ }
1500
+ const quoted = JSON.stringify(path)
1501
+ // Other tools end the name at a NUL character, or reject it
1502
+ if (path.includes("\0")) throw invalidHeader(`path ${quoted} contains a NUL character`)
1503
+ if ((flags & (FLAG_ENCRYPTED | FLAG_STRONG_ENCRYPTION)) !== 0) throw unsupported(`entry ${quoted} is encrypted`)
1504
+ if (method !== 0 && method !== 8) throw unsupported(`entry ${quoted} uses compression method ${method}`)
1505
+ const descriptor = (flags & FLAG_DESCRIPTOR) !== 0
1506
+ // Writers that put sizes after the data usually leave zeros here
1507
+ const known = !descriptor || compressedSize !== 0 || size !== 0
1508
+ // Searching for the descriptor of stored data would let its content forge
1509
+ // the entries after it
1510
+ if (method === 0 && !known) throw unsupported(`stored entry ${quoted} has no size before its data`)
1511
+ if (method === 0 && compressedSize !== size) {
1512
+ throw invalidHeader(`stored entry ${quoted} has different sizes`)
1513
+ }
1514
+ const header: Header = {
1515
+ path,
1516
+ type: path.endsWith("/") ? "Directory" : "File",
1517
+ method: method === 8 ? "Deflate" : "Store",
1518
+ mtime: new Date(seconds === undefined ? fromDos(time, date) : seconds * 1000),
1519
+ ...(known && (method === 0 || !descriptor) ? { size } : undefined)
1520
+ }
1521
+ return {
1522
+ header,
1523
+ inflater: method === 8
1524
+ ? new Inflater(this.queue, this.inflateMemory ??= new InflateMemory())
1525
+ : undefined,
1526
+ descriptor,
1527
+ zip64,
1528
+ crc,
1529
+ compressedSize: known ? compressedSize : undefined,
1530
+ size: known ? size : undefined,
1531
+ start: this.queue.consumed,
1532
+ remaining: method === 0 ? compressedSize : 0,
1533
+ dataDone: false,
1534
+ actualCrc: 0,
1535
+ actualSize: 0,
1536
+ actualCompressedSize: 0
1537
+ }
1538
+ }
1539
+
1540
+ private needInput(): typeof NeedInput {
1541
+ if (this.ended) throw truncated(this.queue.consumed + this.queue.length)
1542
+ return NeedInput
1543
+ }
1544
+
1545
+ private finish(): undefined | typeof NeedInput {
1546
+ this.finished = true
1547
+ this.queue.clear()
1548
+ return this.ended ? undefined : NeedInput
1549
+ }
1550
+ }
1551
+
1552
+ const hex = (n: number): string => `0x${n.toString(16).padStart(8, "0")}`
1553
+
1554
+ // A ZIP64 data descriptor with its signature, and the signature after it
1555
+ const DESCRIPTOR_PEEK = 28
1556
+
1557
+ const isHeaderSignature = (signature: number): boolean =>
1558
+ signature === LOCAL || signature === CENTRAL || signature === END || signature === END64