@statewalker/cellb 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (365) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +323 -2
  3. package/dist/adapters/files-backup.d.ts +16 -0
  4. package/dist/adapters/files-backup.js +32 -0
  5. package/dist/adapters/files-backup.js.map +1 -0
  6. package/dist/adapters/files-changelog.d.ts +33 -0
  7. package/dist/adapters/files-changelog.js +96 -0
  8. package/dist/adapters/files-changelog.js.map +1 -0
  9. package/dist/adapters/files-ltx.d.ts +35 -0
  10. package/dist/adapters/files-ltx.js +9 -0
  11. package/dist/adapters/files-ltx.js.map +1 -0
  12. package/dist/adapters/ltx-vfs.d.ts +21 -0
  13. package/dist/adapters/ltx-vfs.js +286 -0
  14. package/dist/adapters/ltx-vfs.js.map +1 -0
  15. package/dist/adapters/node-sqlite.d.ts +45 -0
  16. package/dist/adapters/node-sqlite.js +254 -0
  17. package/dist/adapters/node-sqlite.js.map +1 -0
  18. package/dist/adapters/wasm-page-hook.d.ts +26 -0
  19. package/dist/adapters/wasm-page-hook.js +55 -0
  20. package/dist/adapters/wasm-page-hook.js.map +1 -0
  21. package/dist/adapters/wasm-session.d.ts +11 -0
  22. package/dist/adapters/wasm-session.js +76 -0
  23. package/dist/adapters/wasm-session.js.map +1 -0
  24. package/dist/adapters/wasm-sqlite.d.ts +89 -0
  25. package/dist/adapters/wasm-sqlite.js +258 -0
  26. package/dist/adapters/wasm-sqlite.js.map +1 -0
  27. package/dist/bindings/assets.d.ts +26 -0
  28. package/dist/bindings/assets.js +260 -0
  29. package/dist/bindings/assets.js.map +1 -0
  30. package/dist/bindings/cache.d.ts +16 -0
  31. package/dist/bindings/cache.js +34 -0
  32. package/dist/bindings/cache.js.map +1 -0
  33. package/dist/bindings/celld-kv.d.ts +26 -0
  34. package/dist/bindings/celld-kv.js +81 -0
  35. package/dist/bindings/celld-kv.js.map +1 -0
  36. package/dist/bindings/celld-queues.d.ts +56 -0
  37. package/dist/bindings/celld-queues.js +223 -0
  38. package/dist/bindings/celld-queues.js.map +1 -0
  39. package/dist/bindings/celld-workflows.d.ts +22 -0
  40. package/dist/bindings/celld-workflows.js +54 -0
  41. package/dist/bindings/celld-workflows.js.map +1 -0
  42. package/dist/bindings/cron.d.ts +27 -0
  43. package/dist/bindings/cron.js +232 -0
  44. package/dist/bindings/cron.js.map +1 -0
  45. package/dist/bindings/d1-migrations.d.ts +22 -0
  46. package/dist/bindings/d1-migrations.js +32 -0
  47. package/dist/bindings/d1-migrations.js.map +1 -0
  48. package/dist/bindings/html-rewriter.d.ts +8 -0
  49. package/dist/bindings/html-rewriter.js +75 -0
  50. package/dist/bindings/html-rewriter.js.map +1 -0
  51. package/dist/bindings/r2-celld.d.ts +3 -0
  52. package/dist/bindings/r2-celld.js +113 -0
  53. package/dist/bindings/r2-celld.js.map +1 -0
  54. package/dist/bindings/r2.d.ts +236 -0
  55. package/dist/bindings/r2.js +419 -0
  56. package/dist/bindings/r2.js.map +1 -0
  57. package/dist/bindings/worker-loader.d.ts +83 -0
  58. package/dist/bindings/worker-loader.js +183 -0
  59. package/dist/bindings/worker-loader.js.map +1 -0
  60. package/dist/bindings/workers-ai.d.ts +39 -0
  61. package/dist/bindings/workers-ai.js +175 -0
  62. package/dist/bindings/workers-ai.js.map +1 -0
  63. package/dist/browser.d.ts +7 -0
  64. package/dist/browser.js +8 -0
  65. package/dist/browser.js.map +1 -0
  66. package/dist/bucket/celld-cells.d.ts +86 -0
  67. package/dist/bucket/celld-cells.js +273 -0
  68. package/dist/bucket/celld-cells.js.map +1 -0
  69. package/dist/bucket/celld-format.d.ts +10 -0
  70. package/dist/bucket/celld-format.js +27 -0
  71. package/dist/bucket/celld-format.js.map +1 -0
  72. package/dist/bucket/idb-object-store.d.ts +9 -0
  73. package/dist/bucket/idb-object-store.js +73 -0
  74. package/dist/bucket/idb-object-store.js.map +1 -0
  75. package/dist/bucket/ltx-log.d.ts +34 -0
  76. package/dist/bucket/ltx-log.js +289 -0
  77. package/dist/bucket/ltx-log.js.map +1 -0
  78. package/dist/bucket/object-store.d.ts +51 -0
  79. package/dist/bucket/object-store.js +114 -0
  80. package/dist/bucket/object-store.js.map +1 -0
  81. package/dist/bucket/s3-object-store.d.ts +25 -0
  82. package/dist/bucket/s3-object-store.js +151 -0
  83. package/dist/bucket/s3-object-store.js.map +1 -0
  84. package/dist/bucket/sqlite-object-store.d.ts +10 -0
  85. package/dist/bucket/sqlite-object-store.js +107 -0
  86. package/dist/bucket/sqlite-object-store.js.map +1 -0
  87. package/dist/core/alarms.d.ts +27 -0
  88. package/dist/core/alarms.js +88 -0
  89. package/dist/core/alarms.js.map +1 -0
  90. package/dist/core/async-context.d.ts +34 -0
  91. package/dist/core/async-context.js +50 -0
  92. package/dist/core/async-context.js.map +1 -0
  93. package/dist/core/celld-schema.d.ts +14 -0
  94. package/dist/core/celld-schema.js +34 -0
  95. package/dist/core/celld-schema.js.map +1 -0
  96. package/dist/core/durable-object.d.ts +28 -0
  97. package/dist/core/durable-object.js +31 -0
  98. package/dist/core/durable-object.js.map +1 -0
  99. package/dist/core/gates.d.ts +33 -0
  100. package/dist/core/gates.js +89 -0
  101. package/dist/core/gates.js.map +1 -0
  102. package/dist/core/handles.d.ts +90 -0
  103. package/dist/core/handles.js +224 -0
  104. package/dist/core/handles.js.map +1 -0
  105. package/dist/core/id.d.ts +19 -0
  106. package/dist/core/id.js +64 -0
  107. package/dist/core/id.js.map +1 -0
  108. package/dist/core/namespace.d.ts +38 -0
  109. package/dist/core/namespace.js +141 -0
  110. package/dist/core/namespace.js.map +1 -0
  111. package/dist/core/object-host.d.ts +91 -0
  112. package/dist/core/object-host.js +616 -0
  113. package/dist/core/object-host.js.map +1 -0
  114. package/dist/core/request-body.d.ts +9 -0
  115. package/dist/core/request-body.js +55 -0
  116. package/dist/core/request-body.js.map +1 -0
  117. package/dist/core/runtime.d.ts +121 -0
  118. package/dist/core/runtime.js +366 -0
  119. package/dist/core/runtime.js.map +1 -0
  120. package/dist/core/shard.d.ts +7 -0
  121. package/dist/core/shard.js +10 -0
  122. package/dist/core/shard.js.map +1 -0
  123. package/dist/core/sql-split.d.ts +15 -0
  124. package/dist/core/sql-split.js +101 -0
  125. package/dist/core/sql-split.js.map +1 -0
  126. package/dist/core/sql-storage.d.ts +53 -0
  127. package/dist/core/sql-storage.js +407 -0
  128. package/dist/core/sql-storage.js.map +1 -0
  129. package/dist/core/state.d.ts +44 -0
  130. package/dist/core/state.js +93 -0
  131. package/dist/core/state.js.map +1 -0
  132. package/dist/core/storage.d.ts +103 -0
  133. package/dist/core/storage.js +351 -0
  134. package/dist/core/storage.js.map +1 -0
  135. package/dist/core/worker-rejections.d.ts +21 -0
  136. package/dist/core/worker-rejections.js +55 -0
  137. package/dist/core/worker-rejections.js.map +1 -0
  138. package/dist/index.d.ts +22 -0
  139. package/dist/index.js +23 -0
  140. package/dist/index.js.map +1 -0
  141. package/dist/isolate/browser.d.ts +16 -0
  142. package/dist/isolate/browser.js +37 -0
  143. package/dist/isolate/browser.js.map +1 -0
  144. package/dist/isolate/host.d.ts +24 -0
  145. package/dist/isolate/host.js +74 -0
  146. package/dist/isolate/host.js.map +1 -0
  147. package/dist/isolate/isolate-worker.d.ts +1 -0
  148. package/dist/isolate/isolate-worker.js +53 -0
  149. package/dist/isolate/isolate-worker.js.map +1 -0
  150. package/dist/isolate/isolate.d.ts +10 -0
  151. package/dist/isolate/isolate.js +169 -0
  152. package/dist/isolate/isolate.js.map +1 -0
  153. package/dist/isolate/node-entry.d.ts +1 -0
  154. package/dist/isolate/node-entry.js +12 -0
  155. package/dist/isolate/node-entry.js.map +1 -0
  156. package/dist/isolate/protocol.d.ts +66 -0
  157. package/dist/isolate/protocol.js +205 -0
  158. package/dist/isolate/protocol.js.map +1 -0
  159. package/dist/ltx/crc64.d.ts +6 -0
  160. package/dist/ltx/crc64.js +46 -0
  161. package/dist/ltx/crc64.js.map +1 -0
  162. package/dist/ltx/ltx-page-server.d.ts +65 -0
  163. package/dist/ltx/ltx-page-server.js +309 -0
  164. package/dist/ltx/ltx-page-server.js.map +1 -0
  165. package/dist/ltx/ltx-pages.d.ts +81 -0
  166. package/dist/ltx/ltx-pages.js +315 -0
  167. package/dist/ltx/ltx-pages.js.map +1 -0
  168. package/dist/ltx/ltx-store-worker.d.ts +1 -0
  169. package/dist/ltx/ltx-store-worker.js +38 -0
  170. package/dist/ltx/ltx-store-worker.js.map +1 -0
  171. package/dist/ltx/ltx.d.ts +45 -0
  172. package/dist/ltx/ltx.js +203 -0
  173. package/dist/ltx/ltx.js.map +1 -0
  174. package/dist/ltx/lz4.d.ts +9 -0
  175. package/dist/ltx/lz4.js +156 -0
  176. package/dist/ltx/lz4.js.map +1 -0
  177. package/dist/ltx/opfs-sync-files.d.ts +23 -0
  178. package/dist/ltx/opfs-sync-files.js +191 -0
  179. package/dist/ltx/opfs-sync-files.js.map +1 -0
  180. package/dist/ltx/xxh32.d.ts +1 -0
  181. package/dist/ltx/xxh32.js +43 -0
  182. package/dist/ltx/xxh32.js.map +1 -0
  183. package/dist/miniflare-compat/blob-service.d.ts +13 -0
  184. package/dist/miniflare-compat/blob-service.js +66 -0
  185. package/dist/miniflare-compat/blob-service.js.map +1 -0
  186. package/dist/miniflare-compat/kv-binding.d.ts +44 -0
  187. package/dist/miniflare-compat/kv-binding.js +99 -0
  188. package/dist/miniflare-compat/kv-binding.js.map +1 -0
  189. package/dist/miniflare-compat/shims/assert.d.ts +15 -0
  190. package/dist/miniflare-compat/shims/assert.js +24 -0
  191. package/dist/miniflare-compat/shims/assert.js.map +1 -0
  192. package/dist/miniflare-compat/shims/workerd-cloudflare.d.ts +7 -0
  193. package/dist/miniflare-compat/shims/workerd-cloudflare.js +6 -0
  194. package/dist/miniflare-compat/shims/workerd-cloudflare.js.map +1 -0
  195. package/dist/miniflare-compat/shims/workerd-globals.d.ts +1 -0
  196. package/dist/miniflare-compat/shims/workerd-globals.js +30 -0
  197. package/dist/miniflare-compat/shims/workerd-globals.js.map +1 -0
  198. package/dist/miniflare-compat/shims/workerd-internal.d.ts +20 -0
  199. package/dist/miniflare-compat/shims/workerd-internal.js +23 -0
  200. package/dist/miniflare-compat/shims/workerd-internal.js.map +1 -0
  201. package/dist/miniflare-compat/shims/workerd-performance.d.ts +4 -0
  202. package/dist/miniflare-compat/shims/workerd-performance.js +17 -0
  203. package/dist/miniflare-compat/shims/workerd-performance.js.map +1 -0
  204. package/dist/miniflare-compat/simulator-fetcher.d.ts +9 -0
  205. package/dist/miniflare-compat/simulator-fetcher.js +14 -0
  206. package/dist/miniflare-compat/simulator-fetcher.js.map +1 -0
  207. package/dist/miniflare-compat/vendored.d.ts +15 -0
  208. package/dist/miniflare-compat/vendored.js +27 -0
  209. package/dist/miniflare-compat/vendored.js.map +1 -0
  210. package/dist/node-compat/async_hooks.d.ts +22 -0
  211. package/dist/node-compat/async_hooks.js +176 -0
  212. package/dist/node-compat/async_hooks.js.map +1 -0
  213. package/dist/node-compat/browser-registry.d.ts +3 -0
  214. package/dist/node-compat/browser-registry.js +39 -0
  215. package/dist/node-compat/browser-registry.js.map +1 -0
  216. package/dist/node-compat/crypto.d.ts +60 -0
  217. package/dist/node-compat/crypto.js +143 -0
  218. package/dist/node-compat/crypto.js.map +1 -0
  219. package/dist/node-compat/diagnostics_channel.d.ts +27 -0
  220. package/dist/node-compat/diagnostics_channel.js +46 -0
  221. package/dist/node-compat/diagnostics_channel.js.map +1 -0
  222. package/dist/node-compat/fs.d.ts +35 -0
  223. package/dist/node-compat/fs.js +40 -0
  224. package/dist/node-compat/fs.js.map +1 -0
  225. package/dist/node-compat/globals.d.ts +3 -0
  226. package/dist/node-compat/globals.js +4 -0
  227. package/dist/node-compat/globals.js.map +1 -0
  228. package/dist/node-compat/install.d.ts +5 -0
  229. package/dist/node-compat/install.js +12 -0
  230. package/dist/node-compat/install.js.map +1 -0
  231. package/dist/node-compat/module.d.ts +12 -0
  232. package/dist/node-compat/module.js +36 -0
  233. package/dist/node-compat/module.js.map +1 -0
  234. package/dist/node-compat/modules.d.ts +8 -0
  235. package/dist/node-compat/modules.js +23 -0
  236. package/dist/node-compat/modules.js.map +1 -0
  237. package/dist/node-compat/os.d.ts +36 -0
  238. package/dist/node-compat/os.js +36 -0
  239. package/dist/node-compat/os.js.map +1 -0
  240. package/dist/node-compat/process.d.ts +14 -0
  241. package/dist/node-compat/process.js +16 -0
  242. package/dist/node-compat/process.js.map +1 -0
  243. package/dist/node-compat/shims.d.ts +4 -0
  244. package/dist/node.d.ts +5 -0
  245. package/dist/node.js +6 -0
  246. package/dist/node.js.map +1 -0
  247. package/dist/peer/celld-peer.d.ts +53 -0
  248. package/dist/peer/celld-peer.js +555 -0
  249. package/dist/peer/celld-peer.js.map +1 -0
  250. package/dist/ports.d.ts +183 -0
  251. package/dist/ports.js +10 -0
  252. package/dist/ports.js.map +1 -0
  253. package/dist/project/browser-bundle.d.ts +17 -0
  254. package/dist/project/browser-bundle.js +125 -0
  255. package/dist/project/browser-bundle.js.map +1 -0
  256. package/dist/project/browser-cookies.d.ts +12 -0
  257. package/dist/project/browser-cookies.js +90 -0
  258. package/dist/project/browser-cookies.js.map +1 -0
  259. package/dist/project/browser-host.d.ts +173 -0
  260. package/dist/project/browser-host.js +200 -0
  261. package/dist/project/browser-host.js.map +1 -0
  262. package/dist/project/browser-modules.d.ts +17 -0
  263. package/dist/project/browser-modules.js +89 -0
  264. package/dist/project/browser-modules.js.map +1 -0
  265. package/dist/project/browser-shards.d.ts +62 -0
  266. package/dist/project/browser-shards.js +210 -0
  267. package/dist/project/browser-shards.js.map +1 -0
  268. package/dist/project/browser-tabs.d.ts +103 -0
  269. package/dist/project/browser-tabs.js +418 -0
  270. package/dist/project/browser-tabs.js.map +1 -0
  271. package/dist/project/cloudflare-email.d.ts +8 -0
  272. package/dist/project/cloudflare-email.js +11 -0
  273. package/dist/project/cloudflare-email.js.map +1 -0
  274. package/dist/project/cloudflare-workers.d.ts +12 -0
  275. package/dist/project/cloudflare-workers.js +16 -0
  276. package/dist/project/cloudflare-workers.js.map +1 -0
  277. package/dist/project/host-modules.d.ts +4 -0
  278. package/dist/project/host-modules.js +40 -0
  279. package/dist/project/host-modules.js.map +1 -0
  280. package/dist/project/jsonc.d.ts +2 -0
  281. package/dist/project/jsonc.js +27 -0
  282. package/dist/project/jsonc.js.map +1 -0
  283. package/dist/project/lower-await.d.ts +2 -0
  284. package/dist/project/lower-await.js +151 -0
  285. package/dist/project/lower-await.js.map +1 -0
  286. package/dist/project/node-project.d.ts +38 -0
  287. package/dist/project/node-project.js +373 -0
  288. package/dist/project/node-project.js.map +1 -0
  289. package/dist/project/own-module.d.ts +6 -0
  290. package/dist/project/own-module.js +13 -0
  291. package/dist/project/own-module.js.map +1 -0
  292. package/dist/project/scheduler.d.ts +2 -0
  293. package/dist/project/scheduler.js +3 -0
  294. package/dist/project/scheduler.js.map +1 -0
  295. package/dist/project/site.d.ts +74 -0
  296. package/dist/project/site.js +206 -0
  297. package/dist/project/site.js.map +1 -0
  298. package/dist/project/virtual-modules.d.ts +3 -0
  299. package/dist/project/worker-scope.d.ts +27 -0
  300. package/dist/project/worker-scope.js +46 -0
  301. package/dist/project/worker-scope.js.map +1 -0
  302. package/dist/project/workerd-message-channel.d.ts +13 -0
  303. package/dist/project/workerd-message-channel.js +137 -0
  304. package/dist/project/workerd-message-channel.js.map +1 -0
  305. package/dist/project/workers-global-names.d.ts +6 -0
  306. package/dist/project/workers-global-names.js +15 -0
  307. package/dist/project/workers-global-names.js.map +1 -0
  308. package/dist/project/workers-globals-module.d.ts +8 -0
  309. package/dist/project/workers-globals-module.js +9 -0
  310. package/dist/project/workers-globals-module.js.map +1 -0
  311. package/dist/project/workers-globals.d.ts +9 -0
  312. package/dist/project/workers-globals.js +19 -0
  313. package/dist/project/workers-globals.js.map +1 -0
  314. package/dist/project/wrangler.d.ts +116 -0
  315. package/dist/project/wrangler.js +342 -0
  316. package/dist/project/wrangler.js.map +1 -0
  317. package/dist/router/cell-router.d.ts +72 -0
  318. package/dist/router/cell-router.js +247 -0
  319. package/dist/router/cell-router.js.map +1 -0
  320. package/dist/router/shard-worker.d.ts +44 -0
  321. package/dist/router/shard-worker.js +163 -0
  322. package/dist/router/shard-worker.js.map +1 -0
  323. package/dist/transport/cells-http.d.ts +25 -0
  324. package/dist/transport/cells-http.js +141 -0
  325. package/dist/transport/cells-http.js.map +1 -0
  326. package/dist/transport/cells-link.d.ts +27 -0
  327. package/dist/transport/cells-link.js +71 -0
  328. package/dist/transport/cells-link.js.map +1 -0
  329. package/dist/transport/port.d.ts +26 -0
  330. package/dist/transport/port.js +100 -0
  331. package/dist/transport/port.js.map +1 -0
  332. package/dist/v8/codec.d.ts +6 -0
  333. package/dist/v8/codec.js +9 -0
  334. package/dist/v8/codec.js.map +1 -0
  335. package/dist/v8/serialize.d.ts +10 -0
  336. package/dist/v8/serialize.js +601 -0
  337. package/dist/v8/serialize.js.map +1 -0
  338. package/dist/ws/client.d.ts +25 -0
  339. package/dist/ws/client.js +203 -0
  340. package/dist/ws/client.js.map +1 -0
  341. package/dist/ws/control.d.ts +48 -0
  342. package/dist/ws/control.js +44 -0
  343. package/dist/ws/control.js.map +1 -0
  344. package/dist/ws/frames.d.ts +38 -0
  345. package/dist/ws/frames.js +39 -0
  346. package/dist/ws/frames.js.map +1 -0
  347. package/dist/ws/server.d.ts +99 -0
  348. package/dist/ws/server.js +295 -0
  349. package/dist/ws/server.js.map +1 -0
  350. package/dist/ws/sw-connector.d.ts +10 -0
  351. package/dist/ws/sw-connector.js +25 -0
  352. package/dist/ws/sw-connector.js.map +1 -0
  353. package/dist/ws/upgrade.d.ts +28 -0
  354. package/dist/ws/upgrade.js +75 -0
  355. package/dist/ws/upgrade.js.map +1 -0
  356. package/package.json +111 -3
  357. package/vendor/celld/LICENSE +202 -0
  358. package/vendor/celld/kv.js +1131 -0
  359. package/vendor/celld/queues.js +1656 -0
  360. package/vendor/celld/workflows.js +1610 -0
  361. package/vendor/html-rewriter-wasm/html_rewriter.js +925 -0
  362. package/vendor/html-rewriter-wasm/html_rewriter_bg.wasm +0 -0
  363. package/vendor/miniflare/d1-api.js +738 -0
  364. package/vendor/miniflare/d1-database.js +6978 -0
  365. package/vendor/miniflare/kv-namespace.js +3061 -0
@@ -0,0 +1,419 @@
1
+ import { md5 } from "@noble/hashes/legacy";
2
+ import { bytesToHex } from "@noble/hashes/utils";
3
+ export class R2Object {
4
+ key;
5
+ version;
6
+ size;
7
+ etag;
8
+ httpEtag;
9
+ uploaded;
10
+ httpMetadata;
11
+ customMetadata;
12
+ checksums;
13
+ storageClass = "Standard";
14
+ range;
15
+ constructor(m, range) {
16
+ this.key = m.key;
17
+ this.version = m.version;
18
+ this.size = m.size;
19
+ this.etag = m.etag;
20
+ this.httpEtag = `"${m.etag}"`;
21
+ this.uploaded = new Date(m.uploaded);
22
+ this.httpMetadata = { ...m.httpMetadata };
23
+ this.customMetadata = { ...m.customMetadata };
24
+ // The MD5 of the bytes: recorded separately when the etag is not it (celld's bucket), and
25
+ // "" when the object has none (a multipart object).
26
+ const bytes = (m.md5 ?? m.etag).match(/../g)?.map((h) => Number.parseInt(h, 16)) ?? [];
27
+ this.checksums = bytes.length ? { md5: new Uint8Array(bytes).buffer } : {};
28
+ if (range)
29
+ this.range = range;
30
+ }
31
+ /** The JSON form celld gives an R2Object (r2-details project): checksums as hex. */
32
+ toJSON() {
33
+ const md5 = this.checksums.md5
34
+ ? [...new Uint8Array(this.checksums.md5)].map((b) => b.toString(16).padStart(2, "0")).join("")
35
+ : undefined;
36
+ return {
37
+ key: this.key,
38
+ version: this.version,
39
+ size: this.size,
40
+ etag: this.etag,
41
+ httpEtag: this.httpEtag,
42
+ uploaded: this.uploaded.toISOString(),
43
+ httpMetadata: this.httpMetadata,
44
+ customMetadata: this.customMetadata,
45
+ ...(this.range ? { range: this.range } : {}),
46
+ checksums: md5 ? { md5 } : {},
47
+ storageClass: this.storageClass,
48
+ };
49
+ }
50
+ writeHttpMetadata(headers) {
51
+ const h = this.httpMetadata;
52
+ if (h.contentType)
53
+ headers.set("content-type", h.contentType);
54
+ if (h.contentLanguage)
55
+ headers.set("content-language", h.contentLanguage);
56
+ if (h.contentDisposition)
57
+ headers.set("content-disposition", h.contentDisposition);
58
+ if (h.contentEncoding)
59
+ headers.set("content-encoding", h.contentEncoding);
60
+ if (h.cacheControl)
61
+ headers.set("cache-control", h.cacheControl);
62
+ if (h.cacheExpiry)
63
+ headers.set("expires", new Date(h.cacheExpiry).toUTCString());
64
+ }
65
+ }
66
+ export class R2ObjectBody extends R2Object {
67
+ #bytes;
68
+ #used = false;
69
+ constructor(m, bytes, range) {
70
+ super(m, range);
71
+ this.#bytes = bytes;
72
+ }
73
+ get bodyUsed() {
74
+ return this.#used;
75
+ }
76
+ get body() {
77
+ this.#used = true;
78
+ const bytes = this.#bytes;
79
+ return new ReadableStream({
80
+ start(c) {
81
+ c.enqueue(bytes.slice());
82
+ c.close();
83
+ },
84
+ });
85
+ }
86
+ #take() {
87
+ if (this.#used)
88
+ throw new TypeError("Body has already been used");
89
+ this.#used = true;
90
+ return this.#bytes;
91
+ }
92
+ async arrayBuffer() {
93
+ const b = this.#take();
94
+ return b.buffer.slice(b.byteOffset, b.byteOffset + b.byteLength);
95
+ }
96
+ async bytes() {
97
+ return this.#take().slice();
98
+ }
99
+ async text() {
100
+ return new TextDecoder().decode(this.#take());
101
+ }
102
+ async json() {
103
+ return JSON.parse(await this.text());
104
+ }
105
+ async blob() {
106
+ return new Blob([this.#take()], { type: this.httpMetadata.contentType ?? "" });
107
+ }
108
+ }
109
+ const enc = (key) => encodeURIComponent(key);
110
+ async function readAll(files, path) {
111
+ if (!(await files.exists(path)))
112
+ return undefined;
113
+ const chunks = [];
114
+ for await (const c of files.read(path))
115
+ chunks.push(c);
116
+ const out = new Uint8Array(chunks.reduce((n, c) => n + c.byteLength, 0));
117
+ let o = 0;
118
+ for (const c of chunks) {
119
+ out.set(c, o);
120
+ o += c.byteLength;
121
+ }
122
+ return out;
123
+ }
124
+ async function toBytes(value) {
125
+ if (value === null)
126
+ return new Uint8Array();
127
+ if (typeof value === "string")
128
+ return new TextEncoder().encode(value);
129
+ if (value instanceof ArrayBuffer)
130
+ return new Uint8Array(value.slice(0));
131
+ if (ArrayBuffer.isView(value))
132
+ return new Uint8Array(value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength));
133
+ return new Uint8Array(await new Response(value).arrayBuffer());
134
+ }
135
+ function httpMetadataOf(input) {
136
+ if (!input)
137
+ return {};
138
+ if (input instanceof Headers) {
139
+ const m = {};
140
+ const map = [
141
+ ["contentType", "content-type"],
142
+ ["contentLanguage", "content-language"],
143
+ ["contentDisposition", "content-disposition"],
144
+ ["contentEncoding", "content-encoding"],
145
+ ["cacheControl", "cache-control"],
146
+ ];
147
+ for (const [k, h] of map) {
148
+ const v = input.get(h);
149
+ if (v !== null)
150
+ m[k] = v;
151
+ }
152
+ const expires = input.get("expires");
153
+ if (expires)
154
+ m.cacheExpiry = new Date(expires);
155
+ return m;
156
+ }
157
+ return { ...input };
158
+ }
159
+ function conditionOf(onlyIf) {
160
+ if (!(onlyIf instanceof Headers))
161
+ return onlyIf;
162
+ const unquote = (v) => v?.replace(/^W\//, "").replace(/^"(.*)"$/, "$1") ?? undefined;
163
+ const date = (v) => (v ? new Date(v) : undefined);
164
+ return {
165
+ etagMatches: unquote(onlyIf.get("if-match")),
166
+ etagDoesNotMatch: unquote(onlyIf.get("if-none-match")),
167
+ uploadedBefore: date(onlyIf.get("if-unmodified-since")),
168
+ uploadedAfter: date(onlyIf.get("if-modified-since")),
169
+ secondsGranularity: true,
170
+ };
171
+ }
172
+ /** Evaluates a conditional against a stored object (no object: only etagMatches fails). */
173
+ function conditionHolds(c, m) {
174
+ if (!c)
175
+ return true;
176
+ const etagIn = (list) => list.split(",").map((e) => e.trim().replace(/^"(.*)"$/, "$1"));
177
+ if (c.etagMatches !== undefined &&
178
+ (!m || !(c.etagMatches === "*" || etagIn(c.etagMatches).includes(m.etag))))
179
+ return false;
180
+ if (c.etagDoesNotMatch !== undefined &&
181
+ m &&
182
+ (c.etagDoesNotMatch === "*" || etagIn(c.etagDoesNotMatch).includes(m.etag)))
183
+ return false;
184
+ if (m) {
185
+ const t = c.secondsGranularity ? Math.floor(m.uploaded / 1000) * 1000 : m.uploaded;
186
+ if (c.uploadedBefore && !(t < new Date(c.uploadedBefore).getTime()))
187
+ return false;
188
+ if (c.uploadedAfter && !(t > new Date(c.uploadedAfter).getTime()))
189
+ return false;
190
+ }
191
+ return true;
192
+ }
193
+ export function filesR2Backend(files, root) {
194
+ const objectPath = (key) => `${root}/objects/${enc(key)}`;
195
+ const metaPath = (key) => `${root}/meta/${enc(key)}.json`;
196
+ return {
197
+ async meta(key) {
198
+ const raw = await readAll(files, metaPath(key));
199
+ return raw ? JSON.parse(new TextDecoder().decode(raw)) : undefined;
200
+ },
201
+ body: (key) => readAll(files, objectPath(key)),
202
+ async write(key, bytes, m) {
203
+ const version = crypto.randomUUID().replace(/-/g, "");
204
+ const meta = {
205
+ ...(m.md5 === undefined && { md5: "" }),
206
+ key,
207
+ size: bytes.byteLength,
208
+ etag: m.md5 ?? version,
209
+ version,
210
+ uploaded: Date.now(),
211
+ httpMetadata: m.httpMetadata,
212
+ customMetadata: m.customMetadata,
213
+ };
214
+ await files.write(objectPath(key), [bytes]);
215
+ await files.write(metaPath(key), [new TextEncoder().encode(JSON.stringify(meta))]);
216
+ return meta;
217
+ },
218
+ async remove(key) {
219
+ await files.remove(metaPath(key));
220
+ await files.remove(objectPath(key));
221
+ },
222
+ async keys() {
223
+ const keys = [];
224
+ if (await files.exists(`${root}/meta`))
225
+ for await (const f of files.list(`${root}/meta`)) {
226
+ const name = f.path.split("/").pop() ?? "";
227
+ if (f.kind === "file" && name.endsWith(".json"))
228
+ keys.push(decodeURIComponent(name.slice(0, -5)));
229
+ }
230
+ return keys;
231
+ },
232
+ scratch: {
233
+ write: (path, bytes) => files.write(`${root}/multipart/${path}`, [bytes]).then(() => { }),
234
+ read: (path) => readAll(files, `${root}/multipart/${path}`),
235
+ removeDir: (path) => files.remove(`${root}/multipart/${path}`).then(() => { }),
236
+ },
237
+ };
238
+ }
239
+ export function r2Bucket(files, root, binding = "BUCKET") {
240
+ return r2BucketOn(filesR2Backend(files, root), binding);
241
+ }
242
+ export function r2BucketOn(backend, binding = "BUCKET") {
243
+ const readMeta = (key) => backend.meta(key);
244
+ // celld's messages: "R2 <op> (binding <name>): a key is 1 to 1024 bytes, not <n>".
245
+ const checkKey = (key, op = "get") => {
246
+ const n = new TextEncoder().encode(String(key)).byteLength;
247
+ if (n < 1 || n > 1024)
248
+ throw new Error(`R2 ${op} (binding ${binding}): a key is 1 to 1024 bytes, not ${n}`);
249
+ };
250
+ return {
251
+ async head(key) {
252
+ checkKey(key, "head");
253
+ const m = await readMeta(key);
254
+ return m ? new R2Object(m) : null;
255
+ },
256
+ async get(key, options = {}) {
257
+ checkKey(key, "get");
258
+ const m = await readMeta(key);
259
+ if (!m)
260
+ return null;
261
+ // A failed condition returns the object's metadata without a body.
262
+ if (!conditionHolds(conditionOf(options.onlyIf), m))
263
+ return new R2Object(m);
264
+ const bytes = (await backend.body(key)) ?? new Uint8Array();
265
+ let r = options.range;
266
+ if (r instanceof Headers) {
267
+ const h = /^bytes=(\d*)-(\d*)$/.exec(r.get("range") ?? "");
268
+ r = h
269
+ ? h[1] === ""
270
+ ? { suffix: Number(h[2]) }
271
+ : {
272
+ offset: Number(h[1]),
273
+ length: h[2] === "" ? undefined : Number(h[2]) - Number(h[1]) + 1,
274
+ }
275
+ : undefined;
276
+ }
277
+ // A full read reports the whole object as its range (workerd/celld behaviour).
278
+ if (!r)
279
+ return new R2ObjectBody(m, bytes, { offset: 0, length: bytes.byteLength });
280
+ const offset = r.suffix !== undefined ? Math.max(0, bytes.byteLength - r.suffix) : (r.offset ?? 0);
281
+ const length = r.suffix !== undefined
282
+ ? bytes.byteLength - offset
283
+ : (r.length ?? bytes.byteLength - offset);
284
+ return new R2ObjectBody(m, bytes.slice(offset, offset + length), { offset, length });
285
+ },
286
+ async put(key, value, options = {}) {
287
+ checkKey(key, "put");
288
+ // A refused condition stores nothing and returns null.
289
+ if (options.onlyIf && !conditionHolds(conditionOf(options.onlyIf), await readMeta(key)))
290
+ return null;
291
+ const bytes = await toBytes(value);
292
+ const etag = bytesToHex(md5(bytes));
293
+ if (options.md5 !== undefined) {
294
+ const expected = typeof options.md5 === "string" ? options.md5 : bytesToHex(new Uint8Array(options.md5));
295
+ if (expected.toLowerCase() !== etag)
296
+ throw new Error(`R2 put: the md5 checksum of the body is ${etag}, not the ${expected} the caller asserted`);
297
+ }
298
+ const meta = await backend.write(key, bytes, {
299
+ httpMetadata: httpMetadataOf(options.httpMetadata),
300
+ customMetadata: { ...options.customMetadata },
301
+ md5: etag,
302
+ });
303
+ return new R2Object(meta);
304
+ },
305
+ async createMultipartUpload(key, options = {}) {
306
+ checkKey(key, "createMultipartUpload");
307
+ const uploadId = crypto.randomUUID().replace(/-/g, "");
308
+ await backend.scratch.write(`${uploadId}/upload.json`, new TextEncoder().encode(JSON.stringify({
309
+ key,
310
+ httpMetadata: httpMetadataOf(options.httpMetadata),
311
+ customMetadata: options.customMetadata ?? {},
312
+ })));
313
+ return this.resumeMultipartUpload(key, uploadId);
314
+ },
315
+ /** A handle on an open upload; parts live under {root}/multipart/{uploadId}/ until complete or abort. */
316
+ resumeMultipartUpload(key, uploadId) {
317
+ const dir = uploadId;
318
+ const info = async () => {
319
+ const raw = await backend.scratch.read(`${dir}/upload.json`);
320
+ if (!raw)
321
+ throw new Error("completeMultipartUpload: The specified multipart upload does not exist. (10024)");
322
+ return JSON.parse(new TextDecoder().decode(raw));
323
+ };
324
+ return {
325
+ key,
326
+ uploadId,
327
+ async uploadPart(partNumber, value) {
328
+ if (!Number.isInteger(partNumber) || partNumber < 1 || partNumber > 10_000)
329
+ throw new Error("uploadPart: part number must be between 1 and 10000");
330
+ await info();
331
+ const bytes = await toBytes(value);
332
+ const etag = bytesToHex(md5(bytes));
333
+ await backend.scratch.write(`${dir}/${String(partNumber).padStart(5, "0")}.part`, bytes);
334
+ return { partNumber, etag };
335
+ },
336
+ async abort() {
337
+ await backend.scratch.removeDir(dir);
338
+ },
339
+ async complete(parts) {
340
+ const u = await info();
341
+ const chunks = [];
342
+ for (const p of parts) {
343
+ const bytes = await backend.scratch.read(`${dir}/${String(p.partNumber).padStart(5, "0")}.part`);
344
+ if (!bytes || bytesToHex(md5(bytes)) !== p.etag)
345
+ throw new Error(`completeMultipartUpload: There was a problem with the multipart upload. (10025)`);
346
+ chunks.push(bytes);
347
+ }
348
+ const total = new Uint8Array(chunks.reduce((n, c) => n + c.byteLength, 0));
349
+ let o = 0;
350
+ for (const c of chunks) {
351
+ total.set(c, o);
352
+ o += c.byteLength;
353
+ }
354
+ // A multipart object has no MD5 checksum (celld, Cloudflare).
355
+ const meta = await backend.write(u.key, total, {
356
+ httpMetadata: u.httpMetadata,
357
+ customMetadata: u.customMetadata,
358
+ });
359
+ await backend.scratch.removeDir(dir);
360
+ return new R2Object(meta);
361
+ },
362
+ };
363
+ },
364
+ async delete(keys) {
365
+ const list = Array.isArray(keys) ? keys : [keys];
366
+ if (list.length > 1000)
367
+ throw new Error(`R2 delete (binding ${binding}) takes at most 1000 keys, not ${list.length}`);
368
+ for (const key of list) {
369
+ checkKey(key, "delete");
370
+ await backend.remove(key);
371
+ }
372
+ },
373
+ async list(options = {}) {
374
+ // celld: a limit above 1000 is clamped, and 0 (or less) means the default 1000.
375
+ const limit = !options.limit || options.limit < 1 ? 1000 : Math.min(options.limit, 1000);
376
+ const keys = (await backend.keys()).sort();
377
+ const after = options.cursor ?? options.startAfter;
378
+ const prefixes = new Set();
379
+ const objects = [];
380
+ let last;
381
+ let truncated = false;
382
+ for (const key of keys) {
383
+ if (options.prefix && !key.startsWith(options.prefix))
384
+ continue;
385
+ if (after !== undefined && key <= after)
386
+ continue;
387
+ if (options.delimiter) {
388
+ const rest = key.slice(options.prefix?.length ?? 0);
389
+ const i = rest.indexOf(options.delimiter);
390
+ if (i >= 0) {
391
+ prefixes.add((options.prefix ?? "") + rest.slice(0, i + options.delimiter.length));
392
+ continue;
393
+ }
394
+ }
395
+ if (objects.length === limit) {
396
+ truncated = true;
397
+ break;
398
+ }
399
+ const m = await readMeta(key);
400
+ if (!m)
401
+ continue;
402
+ const include = options.include ?? [];
403
+ if (!include.includes("httpMetadata"))
404
+ m.httpMetadata = {};
405
+ if (!include.includes("customMetadata"))
406
+ m.customMetadata = {};
407
+ objects.push(new R2Object(m));
408
+ last = key;
409
+ }
410
+ return {
411
+ objects,
412
+ truncated,
413
+ cursor: truncated ? last : undefined,
414
+ delimitedPrefixes: [...prefixes].sort(),
415
+ };
416
+ },
417
+ };
418
+ }
419
+ //# sourceMappingURL=r2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"r2.js","sourceRoot":"","sources":["../../src/bindings/r2.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAkCjD,MAAM,OAAO,QAAQ;IACV,GAAG,CAAS;IACZ,OAAO,CAAS;IAChB,IAAI,CAAS;IACb,IAAI,CAAS;IACb,QAAQ,CAAS;IACjB,QAAQ,CAAO;IACf,YAAY,CAAiB;IAC7B,cAAc,CAAyB;IACvC,SAAS,CAAwB;IACjC,YAAY,GAAG,UAAU,CAAC;IAC1B,KAAK,CAAsC;IACpD,YAAY,CAAa,EAAE,KAA0C;QACnE,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC;QAC9B,IAAI,CAAC,QAAQ,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACrC,IAAI,CAAC,YAAY,GAAG,EAAE,GAAG,CAAC,CAAC,YAAY,EAAE,CAAC;QAC1C,IAAI,CAAC,cAAc,GAAG,EAAE,GAAG,CAAC,CAAC,cAAc,EAAE,CAAC;QAC9C,0FAA0F;QAC1F,oDAAoD;QACpD,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACvF,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3E,IAAI,KAAK;YAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IAChC,CAAC;IACD,oFAAoF;IACpF,MAAM;QACJ,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG;YAC5B,CAAC,CAAC,CAAC,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9F,CAAC,CAAC,SAAS,CAAC;QACd,OAAO;YACL,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE;YACrC,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5C,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE;YAC7B,YAAY,EAAE,IAAI,CAAC,YAAY;SAChC,CAAC;IACJ,CAAC;IACD,iBAAiB,CAAC,OAAgB;QAChC,MAAM,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC;QAC5B,IAAI,CAAC,CAAC,WAAW;YAAE,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;QAC9D,IAAI,CAAC,CAAC,eAAe;YAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC;QAC1E,IAAI,CAAC,CAAC,kBAAkB;YAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC,CAAC,kBAAkB,CAAC,CAAC;QACnF,IAAI,CAAC,CAAC,eAAe;YAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC;QAC1E,IAAI,CAAC,CAAC,YAAY;YAAE,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC;QACjE,IAAI,CAAC,CAAC,WAAW;YAAE,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IACnF,CAAC;CACF;AAED,MAAM,OAAO,YAAa,SAAQ,QAAQ;IAC/B,MAAM,CAAa;IAC5B,KAAK,GAAG,KAAK,CAAC;IACd,YAAY,CAAa,EAAE,KAAiB,EAAE,KAA0C;QACtF,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAChB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IACD,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IACD,IAAI,IAAI;QACN,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,OAAO,IAAI,cAAc,CAAC;YACxB,KAAK,CAAC,CAAC;gBACL,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;gBACzB,CAAC,CAAC,KAAK,EAAE,CAAC;YACZ,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IACD,KAAK;QACH,IAAI,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,SAAS,CAAC,4BAA4B,CAAC,CAAC;QAClE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IACD,KAAK,CAAC,WAAW;QACf,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QACvB,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAgB,CAAC;IAClF,CAAC;IACD,KAAK,CAAC,KAAK;QACT,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC;IAC9B,CAAC;IACD,KAAK,CAAC,IAAI;QACR,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IAChD,CAAC;IACD,KAAK,CAAC,IAAI;QACR,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAM,CAAC;IAC5C,CAAC;IACD,KAAK,CAAC,IAAI;QACR,OAAO,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,EAAc,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC,CAAC;IAC7F,CAAC;CACF;AAaD,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;AAErD,KAAK,UAAU,OAAO,CAAC,KAAe,EAAE,IAAY;IAClD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IAClD,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;IACzE,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACd,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC;IACpB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,KAAiB;IACtC,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,UAAU,EAAE,CAAC;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtE,IAAI,KAAK,YAAY,WAAW;QAAE,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC;QAC3B,OAAO,IAAI,UAAU,CACnB,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,CAC1E,CAAC;IACJ,OAAO,IAAI,UAAU,CAAC,MAAM,IAAI,QAAQ,CAAC,KAAiB,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,cAAc,CAAC,KAA2C;IACjE,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,IAAI,KAAK,YAAY,OAAO,EAAE,CAAC;QAC7B,MAAM,CAAC,GAAmB,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAqC;YAC5C,CAAC,aAAa,EAAE,cAAc,CAAC;YAC/B,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;YACvC,CAAC,oBAAoB,EAAE,qBAAqB,CAAC;YAC7C,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;YACvC,CAAC,cAAc,EAAE,eAAe,CAAC;SAClC,CAAC;QACF,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;YACzB,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,CAAC,KAAK,IAAI;gBAAG,CAA4B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACvD,CAAC;QACD,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACrC,IAAI,OAAO;YAAE,CAAC,CAAC,WAAW,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/C,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;AACtB,CAAC;AAWD,SAAS,WAAW,CAAC,MAA2C;IAC9D,IAAI,CAAC,CAAC,MAAM,YAAY,OAAO,CAAC;QAAE,OAAO,MAAM,CAAC;IAChD,MAAM,OAAO,GAAG,CAAC,CAAgB,EAAE,EAAE,CACnC,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,SAAS,CAAC;IAChE,MAAM,IAAI,GAAG,CAAC,CAAgB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACjE,OAAO;QACL,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC5C,gBAAgB,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QACtD,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACvD,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QACpD,kBAAkB,EAAE,IAAI;KACzB,CAAC;AACJ,CAAC;AAED,2FAA2F;AAC3F,SAAS,cAAc,CAAC,CAA4B,EAAE,CAAyB;IAC7E,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;IAChG,IACE,CAAC,CAAC,WAAW,KAAK,SAAS;QAC3B,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAE1E,OAAO,KAAK,CAAC;IACf,IACE,CAAC,CAAC,gBAAgB,KAAK,SAAS;QAChC,CAAC;QACD,CAAC,CAAC,CAAC,gBAAgB,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAE3E,OAAO,KAAK,CAAC;IACf,IAAI,CAAC,EAAE,CAAC;QACN,MAAM,CAAC,GAAG,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QACnF,IAAI,CAAC,CAAC,cAAc,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE,CAAC;YAAE,OAAO,KAAK,CAAC;QAClF,IAAI,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE,CAAC;YAAE,OAAO,KAAK,CAAC;IAClF,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAyBD,MAAM,UAAU,cAAc,CAAC,KAAe,EAAE,IAAY;IAC1D,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG,IAAI,YAAY,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;IAClE,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG,IAAI,SAAS,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;IAClE,OAAO;QACL,KAAK,CAAC,IAAI,CAAC,GAAG;YACZ,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;YAChD,OAAO,GAAG,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAgB,CAAC,CAAC,CAAC,SAAS,CAAC;QACrF,CAAC;QACD,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;QAC9C,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACtD,MAAM,IAAI,GAAe;gBACvB,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,SAAS,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;gBACvC,GAAG;gBACH,IAAI,EAAE,KAAK,CAAC,UAAU;gBACtB,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,OAAO;gBACtB,OAAO;gBACP,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE;gBACpB,YAAY,EAAE,CAAC,CAAC,YAAY;gBAC5B,cAAc,EAAE,CAAC,CAAC,cAAc;aACjC,CAAC;YACF,MAAM,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;YAC5C,MAAM,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACnF,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,GAAG;YACd,MAAM,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;YAClC,MAAM,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QACtC,CAAC;QACD,KAAK,CAAC,IAAI;YACR,MAAM,IAAI,GAAa,EAAE,CAAC;YAC1B,IAAI,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC;gBACpC,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,EAAE,CAAC;oBACjD,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;oBAC3C,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;wBAC7C,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrD,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE;YACP,KAAK,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,cAAc,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;YACxF,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,IAAI,cAAc,IAAI,EAAE,CAAC;YAC3D,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,cAAc,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;SAC9E;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAe,EAAE,IAAY,EAAE,OAAO,GAAG,QAAQ;IACxE,OAAO,UAAU,CAAC,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAkB,EAAE,OAAO,GAAG,QAAQ;IAC/D,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpD,mFAAmF;IACnF,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,EAAE,GAAG,KAAK,EAAE,EAAE;QAC3C,MAAM,CAAC,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC;QAC3D,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI;YACnB,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE,aAAa,OAAO,oCAAoC,CAAC,EAAE,CAAC,CAAC;IACzF,CAAC,CAAC;IAEF,OAAO;QACL,KAAK,CAAC,IAAI,CAAC,GAAW;YACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACtB,MAAM,CAAC,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC9B,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACpC,CAAC;QAED,KAAK,CAAC,GAAG,CACP,GAAW,EACX,OAAO,GAGH,EAAE;YAEN,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACrB,MAAM,CAAC,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC9B,IAAI,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YACpB,mEAAmE;YACnE,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAAE,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC5E,MAAM,KAAK,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,UAAU,EAAE,CAAC;YAC5D,IAAI,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC;YACtB,IAAI,CAAC,YAAY,OAAO,EAAE,CAAC;gBACzB,MAAM,CAAC,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC3D,CAAC,GAAG,CAAC;oBACH,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;wBACX,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;wBAC1B,CAAC,CAAC;4BACE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;4BACpB,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;yBAClE;oBACL,CAAC,CAAC,SAAS,CAAC;YAChB,CAAC;YACD,+EAA+E;YAC/E,IAAI,CAAC,CAAC;gBAAE,OAAO,IAAI,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;YACnF,MAAM,MAAM,GACV,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;YACtF,MAAM,MAAM,GACV,CAAC,CAAC,MAAM,KAAK,SAAS;gBACpB,CAAC,CAAC,KAAK,CAAC,UAAU,GAAG,MAAM;gBAC3B,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC,CAAC;YAC9C,OAAO,IAAI,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACvF,CAAC;QAED,KAAK,CAAC,GAAG,CACP,GAAW,EACX,KAAiB,EACjB,OAAO,GAKH,EAAE;YAEN,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACrB,uDAAuD;YACvD,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;gBACrF,OAAO,IAAI,CAAC;YACd,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;YACpC,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;gBAC9B,MAAM,QAAQ,GACZ,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC1F,IAAI,QAAQ,CAAC,WAAW,EAAE,KAAK,IAAI;oBACjC,MAAM,IAAI,KAAK,CACb,2CAA2C,IAAI,aAAa,QAAQ,sBAAsB,CAC3F,CAAC;YACN,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE;gBAC3C,YAAY,EAAE,cAAc,CAAC,OAAO,CAAC,YAAY,CAAC;gBAClD,cAAc,EAAE,EAAE,GAAG,OAAO,CAAC,cAAc,EAAE;gBAC7C,GAAG,EAAE,IAAI;aACV,CAAC,CAAC;YACH,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAED,KAAK,CAAC,qBAAqB,CACzB,GAAW,EACX,OAAO,GAGH,EAAE;YAEN,QAAQ,CAAC,GAAG,EAAE,uBAAuB,CAAC,CAAC;YACvC,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACvD,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,CACzB,GAAG,QAAQ,cAAc,EACzB,IAAI,WAAW,EAAE,CAAC,MAAM,CACtB,IAAI,CAAC,SAAS,CAAC;gBACb,GAAG;gBACH,YAAY,EAAE,cAAc,CAAC,OAAO,CAAC,YAAY,CAAC;gBAClD,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,EAAE;aAC7C,CAAC,CACH,CACF,CAAC;YACF,OAAO,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACnD,CAAC;QAED,yGAAyG;QACzG,qBAAqB,CAAC,GAAW,EAAE,QAAgB;YACjD,MAAM,GAAG,GAAG,QAAQ,CAAC;YACrB,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;gBACtB,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,cAAc,CAAC,CAAC;gBAC7D,IAAI,CAAC,GAAG;oBACN,MAAM,IAAI,KAAK,CACb,iFAAiF,CAClF,CAAC;gBACJ,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAI9C,CAAC;YACJ,CAAC,CAAC;YACF,OAAO;gBACL,GAAG;gBACH,QAAQ;gBACR,KAAK,CAAC,UAAU,CAAC,UAAkB,EAAE,KAAiB;oBACpD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,IAAI,UAAU,GAAG,MAAM;wBACxE,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;oBACzE,MAAM,IAAI,EAAE,CAAC;oBACb,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;oBACnC,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;oBACpC,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;oBACzF,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;gBAC9B,CAAC;gBACD,KAAK,CAAC,KAAK;oBACT,MAAM,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACvC,CAAC;gBACD,KAAK,CAAC,QAAQ,CAAC,KAA6C;oBAC1D,MAAM,CAAC,GAAG,MAAM,IAAI,EAAE,CAAC;oBACvB,MAAM,MAAM,GAAiB,EAAE,CAAC;oBAChC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;wBACtB,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CACtC,GAAG,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CACvD,CAAC;wBACF,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI;4BAC7C,MAAM,IAAI,KAAK,CACb,iFAAiF,CAClF,CAAC;wBACJ,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACrB,CAAC;oBACD,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;oBAC3E,IAAI,CAAC,GAAG,CAAC,CAAC;oBACV,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;wBACvB,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;wBAChB,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC;oBACpB,CAAC;oBACD,8DAA8D;oBAC9D,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE;wBAC7C,YAAY,EAAE,CAAC,CAAC,YAAY;wBAC5B,cAAc,EAAE,CAAC,CAAC,cAAc;qBACjC,CAAC,CAAC;oBACH,MAAM,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;oBACrC,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC5B,CAAC;aACF,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,IAAuB;YAClC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACjD,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI;gBACpB,MAAM,IAAI,KAAK,CACb,sBAAsB,OAAO,kCAAkC,IAAI,CAAC,MAAM,EAAE,CAC7E,CAAC;YACJ,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;gBACxB,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,OAAO,GAAkB,EAAE;YACpC,gFAAgF;YAChF,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACzF,MAAM,IAAI,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,UAAU,CAAC;YACnD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;YACnC,MAAM,OAAO,GAAe,EAAE,CAAC;YAC/B,IAAI,IAAwB,CAAC;YAC7B,IAAI,SAAS,GAAG,KAAK,CAAC;YACtB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC;oBAAE,SAAS;gBAChE,IAAI,KAAK,KAAK,SAAS,IAAI,GAAG,IAAI,KAAK;oBAAE,SAAS;gBAClD,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;oBACtB,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;oBACpD,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;oBAC1C,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;wBACX,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;wBACnF,SAAS;oBACX,CAAC;gBACH,CAAC;gBACD,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;oBAC7B,SAAS,GAAG,IAAI,CAAC;oBACjB,MAAM;gBACR,CAAC;gBACD,MAAM,CAAC,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAC9B,IAAI,CAAC,CAAC;oBAAE,SAAS;gBACjB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;gBACtC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;oBAAE,CAAC,CAAC,YAAY,GAAG,EAAE,CAAC;gBAC3D,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;oBAAE,CAAC,CAAC,cAAc,GAAG,EAAE,CAAC;gBAC/D,OAAO,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC9B,IAAI,GAAG,GAAG,CAAC;YACb,CAAC;YACD,OAAO;gBACL,OAAO;gBACP,SAAS;gBACT,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;gBACpC,iBAAiB,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,EAAE;aACxC,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { md5 } from \"@noble/hashes/legacy\";\nimport { bytesToHex } from \"@noble/hashes/utils\";\nimport type { FilesApi } from \"@statewalker/webrun-files\";\n\n/**\n * The R2 binding (`env.BUCKET.get/put/head/delete/list`, conditional requests, multipart\n * uploads) on an R2Backend: a webrun-files FilesApi here, or celld's fleet bucket layout\n * (r2-celld.ts). Like celld — whose R2 bindings read and write objects directly in the fleet\n * bucket, not through a cell — the FilesApi backend keeps objects as files:\n * {root}/objects/<encoded key> the bytes\n * {root}/meta/<encoded key>.json key, size, etag (MD5; a multipart object has none), version,\n * uploaded, metadata\n * {root}/multipart/<uploadId>/ an open upload's description and parts, until complete or abort\n */\nexport interface R2HTTPMetadata {\n contentType?: string;\n contentLanguage?: string;\n contentDisposition?: string;\n contentEncoding?: string;\n cacheControl?: string;\n cacheExpiry?: Date;\n}\n\nexport interface StoredMeta {\n /** Hex MD5 of the bytes when the etag is something else (a store's own etag); \"\" for none. */\n md5?: string;\n key: string;\n size: number;\n etag: string;\n version: string;\n uploaded: number;\n httpMetadata: R2HTTPMetadata;\n customMetadata: Record<string, string>;\n}\n\nexport class R2Object {\n readonly key: string;\n readonly version: string;\n readonly size: number;\n readonly etag: string;\n readonly httpEtag: string;\n readonly uploaded: Date;\n readonly httpMetadata: R2HTTPMetadata;\n readonly customMetadata: Record<string, string>;\n readonly checksums: { md5?: ArrayBuffer };\n readonly storageClass = \"Standard\";\n readonly range?: { offset: number; length: number };\n constructor(m: StoredMeta, range?: { offset: number; length: number }) {\n this.key = m.key;\n this.version = m.version;\n this.size = m.size;\n this.etag = m.etag;\n this.httpEtag = `\"${m.etag}\"`;\n this.uploaded = new Date(m.uploaded);\n this.httpMetadata = { ...m.httpMetadata };\n this.customMetadata = { ...m.customMetadata };\n // The MD5 of the bytes: recorded separately when the etag is not it (celld's bucket), and\n // \"\" when the object has none (a multipart object).\n const bytes = (m.md5 ?? m.etag).match(/../g)?.map((h) => Number.parseInt(h, 16)) ?? [];\n this.checksums = bytes.length ? { md5: new Uint8Array(bytes).buffer } : {};\n if (range) this.range = range;\n }\n /** The JSON form celld gives an R2Object (r2-details project): checksums as hex. */\n toJSON() {\n const md5 = this.checksums.md5\n ? [...new Uint8Array(this.checksums.md5)].map((b) => b.toString(16).padStart(2, \"0\")).join(\"\")\n : undefined;\n return {\n key: this.key,\n version: this.version,\n size: this.size,\n etag: this.etag,\n httpEtag: this.httpEtag,\n uploaded: this.uploaded.toISOString(),\n httpMetadata: this.httpMetadata,\n customMetadata: this.customMetadata,\n ...(this.range ? { range: this.range } : {}),\n checksums: md5 ? { md5 } : {},\n storageClass: this.storageClass,\n };\n }\n writeHttpMetadata(headers: Headers): void {\n const h = this.httpMetadata;\n if (h.contentType) headers.set(\"content-type\", h.contentType);\n if (h.contentLanguage) headers.set(\"content-language\", h.contentLanguage);\n if (h.contentDisposition) headers.set(\"content-disposition\", h.contentDisposition);\n if (h.contentEncoding) headers.set(\"content-encoding\", h.contentEncoding);\n if (h.cacheControl) headers.set(\"cache-control\", h.cacheControl);\n if (h.cacheExpiry) headers.set(\"expires\", new Date(h.cacheExpiry).toUTCString());\n }\n}\n\nexport class R2ObjectBody extends R2Object {\n readonly #bytes: Uint8Array;\n #used = false;\n constructor(m: StoredMeta, bytes: Uint8Array, range?: { offset: number; length: number }) {\n super(m, range);\n this.#bytes = bytes;\n }\n get bodyUsed(): boolean {\n return this.#used;\n }\n get body(): ReadableStream<Uint8Array> {\n this.#used = true;\n const bytes = this.#bytes;\n return new ReadableStream({\n start(c) {\n c.enqueue(bytes.slice());\n c.close();\n },\n });\n }\n #take(): Uint8Array {\n if (this.#used) throw new TypeError(\"Body has already been used\");\n this.#used = true;\n return this.#bytes;\n }\n async arrayBuffer(): Promise<ArrayBuffer> {\n const b = this.#take();\n return b.buffer.slice(b.byteOffset, b.byteOffset + b.byteLength) as ArrayBuffer;\n }\n async bytes(): Promise<Uint8Array> {\n return this.#take().slice();\n }\n async text(): Promise<string> {\n return new TextDecoder().decode(this.#take());\n }\n async json<T = unknown>(): Promise<T> {\n return JSON.parse(await this.text()) as T;\n }\n async blob(): Promise<Blob> {\n return new Blob([this.#take() as BlobPart], { type: this.httpMetadata.contentType ?? \"\" });\n }\n}\n\nexport type R2PutValue = ReadableStream | ArrayBuffer | ArrayBufferView | string | Blob | null;\n\nexport interface R2ListOptions {\n limit?: number;\n prefix?: string;\n cursor?: string;\n delimiter?: string;\n startAfter?: string;\n include?: (\"httpMetadata\" | \"customMetadata\")[];\n}\n\nconst enc = (key: string) => encodeURIComponent(key);\n\nasync function readAll(files: FilesApi, path: string): Promise<Uint8Array | undefined> {\n if (!(await files.exists(path))) return undefined;\n const chunks: Uint8Array[] = [];\n for await (const c of files.read(path)) chunks.push(c);\n const out = new Uint8Array(chunks.reduce((n, c) => n + c.byteLength, 0));\n let o = 0;\n for (const c of chunks) {\n out.set(c, o);\n o += c.byteLength;\n }\n return out;\n}\n\nasync function toBytes(value: R2PutValue): Promise<Uint8Array> {\n if (value === null) return new Uint8Array();\n if (typeof value === \"string\") return new TextEncoder().encode(value);\n if (value instanceof ArrayBuffer) return new Uint8Array(value.slice(0));\n if (ArrayBuffer.isView(value))\n return new Uint8Array(\n value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength),\n );\n return new Uint8Array(await new Response(value as BodyInit).arrayBuffer());\n}\n\nfunction httpMetadataOf(input: R2HTTPMetadata | Headers | undefined): R2HTTPMetadata {\n if (!input) return {};\n if (input instanceof Headers) {\n const m: R2HTTPMetadata = {};\n const map: [keyof R2HTTPMetadata, string][] = [\n [\"contentType\", \"content-type\"],\n [\"contentLanguage\", \"content-language\"],\n [\"contentDisposition\", \"content-disposition\"],\n [\"contentEncoding\", \"content-encoding\"],\n [\"cacheControl\", \"cache-control\"],\n ];\n for (const [k, h] of map) {\n const v = input.get(h);\n if (v !== null) (m as Record<string, string>)[k] = v;\n }\n const expires = input.get(\"expires\");\n if (expires) m.cacheExpiry = new Date(expires);\n return m;\n }\n return { ...input };\n}\n\n/** R2 conditional request: an object or the equivalent HTTP headers. */\nexport interface R2Conditional {\n etagMatches?: string;\n etagDoesNotMatch?: string;\n uploadedBefore?: Date;\n uploadedAfter?: Date;\n secondsGranularity?: boolean;\n}\n\nfunction conditionOf(onlyIf: R2Conditional | Headers | undefined): R2Conditional | undefined {\n if (!(onlyIf instanceof Headers)) return onlyIf;\n const unquote = (v: string | null) =>\n v?.replace(/^W\\//, \"\").replace(/^\"(.*)\"$/, \"$1\") ?? undefined;\n const date = (v: string | null) => (v ? new Date(v) : undefined);\n return {\n etagMatches: unquote(onlyIf.get(\"if-match\")),\n etagDoesNotMatch: unquote(onlyIf.get(\"if-none-match\")),\n uploadedBefore: date(onlyIf.get(\"if-unmodified-since\")),\n uploadedAfter: date(onlyIf.get(\"if-modified-since\")),\n secondsGranularity: true,\n };\n}\n\n/** Evaluates a conditional against a stored object (no object: only etagMatches fails). */\nfunction conditionHolds(c: R2Conditional | undefined, m: StoredMeta | undefined): boolean {\n if (!c) return true;\n const etagIn = (list: string) => list.split(\",\").map((e) => e.trim().replace(/^\"(.*)\"$/, \"$1\"));\n if (\n c.etagMatches !== undefined &&\n (!m || !(c.etagMatches === \"*\" || etagIn(c.etagMatches).includes(m.etag)))\n )\n return false;\n if (\n c.etagDoesNotMatch !== undefined &&\n m &&\n (c.etagDoesNotMatch === \"*\" || etagIn(c.etagDoesNotMatch).includes(m.etag))\n )\n return false;\n if (m) {\n const t = c.secondsGranularity ? Math.floor(m.uploaded / 1000) * 1000 : m.uploaded;\n if (c.uploadedBefore && !(t < new Date(c.uploadedBefore).getTime())) return false;\n if (c.uploadedAfter && !(t > new Date(c.uploadedAfter).getTime())) return false;\n }\n return true;\n}\n\n/**\n * Where an R2 binding keeps objects: a FilesApi (cellb's own layout) or a celld bucket\n * (`r2/<bucket>/<key>` with celld's `celld-r2` record — r2-celld.ts).\n */\nexport interface R2Backend {\n meta(key: string): Promise<StoredMeta | undefined>;\n body(key: string): Promise<Uint8Array | undefined>;\n /** Stores the object; the backend decides etag, version and upload time. No md5: multipart. */\n write(\n key: string,\n bytes: Uint8Array,\n m: { httpMetadata: R2HTTPMetadata; customMetadata: Record<string, string>; md5?: string },\n ): Promise<StoredMeta>;\n remove(key: string): Promise<void>;\n keys(): Promise<string[]>;\n /** Scratch space for multipart uploads. */\n scratch: {\n write(path: string, bytes: Uint8Array): Promise<void>;\n read(path: string): Promise<Uint8Array | undefined>;\n removeDir(path: string): Promise<void>;\n };\n}\n\nexport function filesR2Backend(files: FilesApi, root: string): R2Backend {\n const objectPath = (key: string) => `${root}/objects/${enc(key)}`;\n const metaPath = (key: string) => `${root}/meta/${enc(key)}.json`;\n return {\n async meta(key) {\n const raw = await readAll(files, metaPath(key));\n return raw ? (JSON.parse(new TextDecoder().decode(raw)) as StoredMeta) : undefined;\n },\n body: (key) => readAll(files, objectPath(key)),\n async write(key, bytes, m) {\n const version = crypto.randomUUID().replace(/-/g, \"\");\n const meta: StoredMeta = {\n ...(m.md5 === undefined && { md5: \"\" }),\n key,\n size: bytes.byteLength,\n etag: m.md5 ?? version,\n version,\n uploaded: Date.now(),\n httpMetadata: m.httpMetadata,\n customMetadata: m.customMetadata,\n };\n await files.write(objectPath(key), [bytes]);\n await files.write(metaPath(key), [new TextEncoder().encode(JSON.stringify(meta))]);\n return meta;\n },\n async remove(key) {\n await files.remove(metaPath(key));\n await files.remove(objectPath(key));\n },\n async keys() {\n const keys: string[] = [];\n if (await files.exists(`${root}/meta`))\n for await (const f of files.list(`${root}/meta`)) {\n const name = f.path.split(\"/\").pop() ?? \"\";\n if (f.kind === \"file\" && name.endsWith(\".json\"))\n keys.push(decodeURIComponent(name.slice(0, -5)));\n }\n return keys;\n },\n scratch: {\n write: (path, bytes) => files.write(`${root}/multipart/${path}`, [bytes]).then(() => {}),\n read: (path) => readAll(files, `${root}/multipart/${path}`),\n removeDir: (path) => files.remove(`${root}/multipart/${path}`).then(() => {}),\n },\n };\n}\n\nexport function r2Bucket(files: FilesApi, root: string, binding = \"BUCKET\") {\n return r2BucketOn(filesR2Backend(files, root), binding);\n}\n\nexport function r2BucketOn(backend: R2Backend, binding = \"BUCKET\") {\n const readMeta = (key: string) => backend.meta(key);\n // celld's messages: \"R2 <op> (binding <name>): a key is 1 to 1024 bytes, not <n>\".\n const checkKey = (key: string, op = \"get\") => {\n const n = new TextEncoder().encode(String(key)).byteLength;\n if (n < 1 || n > 1024)\n throw new Error(`R2 ${op} (binding ${binding}): a key is 1 to 1024 bytes, not ${n}`);\n };\n\n return {\n async head(key: string): Promise<R2Object | null> {\n checkKey(key, \"head\");\n const m = await readMeta(key);\n return m ? new R2Object(m) : null;\n },\n\n async get(\n key: string,\n options: {\n range?: { offset?: number; length?: number; suffix?: number } | Headers;\n onlyIf?: R2Conditional | Headers;\n } = {},\n ): Promise<R2ObjectBody | R2Object | null> {\n checkKey(key, \"get\");\n const m = await readMeta(key);\n if (!m) return null;\n // A failed condition returns the object's metadata without a body.\n if (!conditionHolds(conditionOf(options.onlyIf), m)) return new R2Object(m);\n const bytes = (await backend.body(key)) ?? new Uint8Array();\n let r = options.range;\n if (r instanceof Headers) {\n const h = /^bytes=(\\d*)-(\\d*)$/.exec(r.get(\"range\") ?? \"\");\n r = h\n ? h[1] === \"\"\n ? { suffix: Number(h[2]) }\n : {\n offset: Number(h[1]),\n length: h[2] === \"\" ? undefined : Number(h[2]) - Number(h[1]) + 1,\n }\n : undefined;\n }\n // A full read reports the whole object as its range (workerd/celld behaviour).\n if (!r) return new R2ObjectBody(m, bytes, { offset: 0, length: bytes.byteLength });\n const offset =\n r.suffix !== undefined ? Math.max(0, bytes.byteLength - r.suffix) : (r.offset ?? 0);\n const length =\n r.suffix !== undefined\n ? bytes.byteLength - offset\n : (r.length ?? bytes.byteLength - offset);\n return new R2ObjectBody(m, bytes.slice(offset, offset + length), { offset, length });\n },\n\n async put(\n key: string,\n value: R2PutValue,\n options: {\n httpMetadata?: R2HTTPMetadata | Headers;\n customMetadata?: Record<string, string>;\n md5?: string | ArrayBuffer;\n onlyIf?: R2Conditional | Headers;\n } = {},\n ): Promise<R2Object | null> {\n checkKey(key, \"put\");\n // A refused condition stores nothing and returns null.\n if (options.onlyIf && !conditionHolds(conditionOf(options.onlyIf), await readMeta(key)))\n return null;\n const bytes = await toBytes(value);\n const etag = bytesToHex(md5(bytes));\n if (options.md5 !== undefined) {\n const expected =\n typeof options.md5 === \"string\" ? options.md5 : bytesToHex(new Uint8Array(options.md5));\n if (expected.toLowerCase() !== etag)\n throw new Error(\n `R2 put: the md5 checksum of the body is ${etag}, not the ${expected} the caller asserted`,\n );\n }\n const meta = await backend.write(key, bytes, {\n httpMetadata: httpMetadataOf(options.httpMetadata),\n customMetadata: { ...options.customMetadata },\n md5: etag,\n });\n return new R2Object(meta);\n },\n\n async createMultipartUpload(\n key: string,\n options: {\n httpMetadata?: R2HTTPMetadata | Headers;\n customMetadata?: Record<string, string>;\n } = {},\n ) {\n checkKey(key, \"createMultipartUpload\");\n const uploadId = crypto.randomUUID().replace(/-/g, \"\");\n await backend.scratch.write(\n `${uploadId}/upload.json`,\n new TextEncoder().encode(\n JSON.stringify({\n key,\n httpMetadata: httpMetadataOf(options.httpMetadata),\n customMetadata: options.customMetadata ?? {},\n }),\n ),\n );\n return this.resumeMultipartUpload(key, uploadId);\n },\n\n /** A handle on an open upload; parts live under {root}/multipart/{uploadId}/ until complete or abort. */\n resumeMultipartUpload(key: string, uploadId: string) {\n const dir = uploadId;\n const info = async () => {\n const raw = await backend.scratch.read(`${dir}/upload.json`);\n if (!raw)\n throw new Error(\n \"completeMultipartUpload: The specified multipart upload does not exist. (10024)\",\n );\n return JSON.parse(new TextDecoder().decode(raw)) as {\n key: string;\n httpMetadata: R2HTTPMetadata;\n customMetadata: Record<string, string>;\n };\n };\n return {\n key,\n uploadId,\n async uploadPart(partNumber: number, value: R2PutValue) {\n if (!Number.isInteger(partNumber) || partNumber < 1 || partNumber > 10_000)\n throw new Error(\"uploadPart: part number must be between 1 and 10000\");\n await info();\n const bytes = await toBytes(value);\n const etag = bytesToHex(md5(bytes));\n await backend.scratch.write(`${dir}/${String(partNumber).padStart(5, \"0\")}.part`, bytes);\n return { partNumber, etag };\n },\n async abort() {\n await backend.scratch.removeDir(dir);\n },\n async complete(parts: { partNumber: number; etag: string }[]) {\n const u = await info();\n const chunks: Uint8Array[] = [];\n for (const p of parts) {\n const bytes = await backend.scratch.read(\n `${dir}/${String(p.partNumber).padStart(5, \"0\")}.part`,\n );\n if (!bytes || bytesToHex(md5(bytes)) !== p.etag)\n throw new Error(\n `completeMultipartUpload: There was a problem with the multipart upload. (10025)`,\n );\n chunks.push(bytes);\n }\n const total = new Uint8Array(chunks.reduce((n, c) => n + c.byteLength, 0));\n let o = 0;\n for (const c of chunks) {\n total.set(c, o);\n o += c.byteLength;\n }\n // A multipart object has no MD5 checksum (celld, Cloudflare).\n const meta = await backend.write(u.key, total, {\n httpMetadata: u.httpMetadata,\n customMetadata: u.customMetadata,\n });\n await backend.scratch.removeDir(dir);\n return new R2Object(meta);\n },\n };\n },\n\n async delete(keys: string | string[]): Promise<void> {\n const list = Array.isArray(keys) ? keys : [keys];\n if (list.length > 1000)\n throw new Error(\n `R2 delete (binding ${binding}) takes at most 1000 keys, not ${list.length}`,\n );\n for (const key of list) {\n checkKey(key, \"delete\");\n await backend.remove(key);\n }\n },\n\n async list(options: R2ListOptions = {}) {\n // celld: a limit above 1000 is clamped, and 0 (or less) means the default 1000.\n const limit = !options.limit || options.limit < 1 ? 1000 : Math.min(options.limit, 1000);\n const keys = (await backend.keys()).sort();\n const after = options.cursor ?? options.startAfter;\n const prefixes = new Set<string>();\n const objects: R2Object[] = [];\n let last: string | undefined;\n let truncated = false;\n for (const key of keys) {\n if (options.prefix && !key.startsWith(options.prefix)) continue;\n if (after !== undefined && key <= after) continue;\n if (options.delimiter) {\n const rest = key.slice(options.prefix?.length ?? 0);\n const i = rest.indexOf(options.delimiter);\n if (i >= 0) {\n prefixes.add((options.prefix ?? \"\") + rest.slice(0, i + options.delimiter.length));\n continue;\n }\n }\n if (objects.length === limit) {\n truncated = true;\n break;\n }\n const m = await readMeta(key);\n if (!m) continue;\n const include = options.include ?? [];\n if (!include.includes(\"httpMetadata\")) m.httpMetadata = {};\n if (!include.includes(\"customMetadata\")) m.customMetadata = {};\n objects.push(new R2Object(m));\n last = key;\n }\n return {\n objects,\n truncated,\n cursor: truncated ? last : undefined,\n delimitedPrefixes: [...prefixes].sort(),\n };\n },\n };\n}\n"]}
@@ -0,0 +1,83 @@
1
+ /** What `env.LOADER.get(id, () => code)` returns from its callback (workerd's WorkerCode). */
2
+ export interface WorkerCode {
3
+ compatibilityDate?: string;
4
+ compatibilityFlags?: string[];
5
+ mainModule: string;
6
+ modules: Record<string, string | {
7
+ js?: string;
8
+ esModule?: string;
9
+ text?: string;
10
+ json?: unknown;
11
+ wasm?: BufferSource;
12
+ } | {
13
+ data: BufferSource;
14
+ }>;
15
+ env?: Record<string, unknown>;
16
+ globalOutbound?: unknown;
17
+ /** Tail Workers: stubs whose `tail(events)` receives each invocation's logs and exceptions. */
18
+ tails?: {
19
+ tail(events: TailEvent[]): unknown;
20
+ }[];
21
+ }
22
+ export interface TailLog {
23
+ message: unknown[];
24
+ level: string;
25
+ timestamp: number;
26
+ }
27
+ export interface TailEvent {
28
+ scriptName: string;
29
+ outcome: "ok" | "exception";
30
+ eventTimestamp: number;
31
+ event: {
32
+ request?: {
33
+ url: string;
34
+ method: string;
35
+ };
36
+ } | null;
37
+ logs: TailLog[];
38
+ exceptions: {
39
+ name: string;
40
+ message: string;
41
+ timestamp: number;
42
+ }[];
43
+ diagnosticsChannelEvents: unknown[];
44
+ }
45
+ /**
46
+ * One `WorkerCode.modules` entry as ES module source; text and JSON become a default export,
47
+ * wasm bytes a compiled `WebAssembly.Module`.
48
+ */
49
+ export declare function moduleText(entry: WorkerCode["modules"][string]): string;
50
+ /**
51
+ * The `fetch` loaded code sees, from `WorkerCode.globalOutbound`: omitted → the loader's own
52
+ * (undefined: no override); `null` → every fetch throws; a Fetcher → each fetch goes through it.
53
+ */
54
+ export declare function outboundFetch(code: WorkerCode): typeof fetch | undefined;
55
+ /** Where the `console` of loaded code writes (the host forwards to the real console too). */
56
+ export type LogSink = (level: string, args: unknown[]) => void;
57
+ /** Compiles a WorkerCode into a module namespace (host specific: esbuild on Node, webrun-modules in browsers). */
58
+ export type ModuleLoader = (id: string, code: WorkerCode, logs?: LogSink) => Promise<Record<string, unknown>>;
59
+ /**
60
+ * The Worker Loader binding (`worker_loaders` in wrangler config): runtime-loaded code,
61
+ * cached by id; the callback runs only when the id is not loaded yet.
62
+ */
63
+ export declare function workerLoader(load: ModuleLoader, opts?: {
64
+ classes?: ModuleLoader;
65
+ }): {
66
+ /** Compiles and runs code without the id cache (a fresh Worker per call). */
67
+ load(code: WorkerCode): {
68
+ getDurableObjectClass(name: string): import("../core/handles.js").ClassHandle;
69
+ /** Releases the loaded Worker: the id leaves the cache; a later get() loads again. */
70
+ dispose(): void;
71
+ getEntrypoint(name?: string, options?: {
72
+ props?: unknown;
73
+ }): {};
74
+ };
75
+ get(id: string, getCode: () => WorkerCode | Promise<WorkerCode>, cached?: boolean): {
76
+ getDurableObjectClass(name: string): import("../core/handles.js").ClassHandle;
77
+ /** Releases the loaded Worker: the id leaves the cache; a later get() loads again. */
78
+ dispose(): void;
79
+ getEntrypoint(name?: string, options?: {
80
+ props?: unknown;
81
+ }): {};
82
+ };
83
+ };