gitx.do 0.1.0 → 0.1.2

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 (344) hide show
  1. package/README.md +40 -353
  2. package/dist/do/logger.d.ts +50 -0
  3. package/dist/do/logger.d.ts.map +1 -0
  4. package/dist/do/logger.js +122 -0
  5. package/dist/do/logger.js.map +1 -0
  6. package/dist/{durable-object → do}/schema.d.ts +3 -3
  7. package/dist/do/schema.d.ts.map +1 -0
  8. package/dist/{durable-object → do}/schema.js +4 -3
  9. package/dist/do/schema.js.map +1 -0
  10. package/dist/do/types.d.ts +267 -0
  11. package/dist/do/types.d.ts.map +1 -0
  12. package/dist/do/types.js +62 -0
  13. package/dist/do/types.js.map +1 -0
  14. package/dist/index.d.ts +15 -415
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +31 -483
  17. package/dist/index.js.map +1 -1
  18. package/package.json +13 -21
  19. package/dist/cli/commands/add.d.ts +0 -174
  20. package/dist/cli/commands/add.d.ts.map +0 -1
  21. package/dist/cli/commands/add.js +0 -131
  22. package/dist/cli/commands/add.js.map +0 -1
  23. package/dist/cli/commands/blame.d.ts +0 -259
  24. package/dist/cli/commands/blame.d.ts.map +0 -1
  25. package/dist/cli/commands/blame.js +0 -609
  26. package/dist/cli/commands/blame.js.map +0 -1
  27. package/dist/cli/commands/branch.d.ts +0 -249
  28. package/dist/cli/commands/branch.d.ts.map +0 -1
  29. package/dist/cli/commands/branch.js +0 -693
  30. package/dist/cli/commands/branch.js.map +0 -1
  31. package/dist/cli/commands/commit.d.ts +0 -182
  32. package/dist/cli/commands/commit.d.ts.map +0 -1
  33. package/dist/cli/commands/commit.js +0 -437
  34. package/dist/cli/commands/commit.js.map +0 -1
  35. package/dist/cli/commands/diff.d.ts +0 -464
  36. package/dist/cli/commands/diff.d.ts.map +0 -1
  37. package/dist/cli/commands/diff.js +0 -958
  38. package/dist/cli/commands/diff.js.map +0 -1
  39. package/dist/cli/commands/log.d.ts +0 -239
  40. package/dist/cli/commands/log.d.ts.map +0 -1
  41. package/dist/cli/commands/log.js +0 -535
  42. package/dist/cli/commands/log.js.map +0 -1
  43. package/dist/cli/commands/merge.d.ts +0 -106
  44. package/dist/cli/commands/merge.d.ts.map +0 -1
  45. package/dist/cli/commands/merge.js +0 -55
  46. package/dist/cli/commands/merge.js.map +0 -1
  47. package/dist/cli/commands/review.d.ts +0 -457
  48. package/dist/cli/commands/review.d.ts.map +0 -1
  49. package/dist/cli/commands/review.js +0 -533
  50. package/dist/cli/commands/review.js.map +0 -1
  51. package/dist/cli/commands/status.d.ts +0 -269
  52. package/dist/cli/commands/status.d.ts.map +0 -1
  53. package/dist/cli/commands/status.js +0 -493
  54. package/dist/cli/commands/status.js.map +0 -1
  55. package/dist/cli/commands/web.d.ts +0 -199
  56. package/dist/cli/commands/web.d.ts.map +0 -1
  57. package/dist/cli/commands/web.js +0 -696
  58. package/dist/cli/commands/web.js.map +0 -1
  59. package/dist/cli/fs-adapter.d.ts +0 -656
  60. package/dist/cli/fs-adapter.d.ts.map +0 -1
  61. package/dist/cli/fs-adapter.js +0 -1179
  62. package/dist/cli/fs-adapter.js.map +0 -1
  63. package/dist/cli/fsx-cli-adapter.d.ts +0 -359
  64. package/dist/cli/fsx-cli-adapter.d.ts.map +0 -1
  65. package/dist/cli/fsx-cli-adapter.js +0 -619
  66. package/dist/cli/fsx-cli-adapter.js.map +0 -1
  67. package/dist/cli/index.d.ts +0 -387
  68. package/dist/cli/index.d.ts.map +0 -1
  69. package/dist/cli/index.js +0 -523
  70. package/dist/cli/index.js.map +0 -1
  71. package/dist/cli/ui/components/DiffView.d.ts +0 -7
  72. package/dist/cli/ui/components/DiffView.d.ts.map +0 -1
  73. package/dist/cli/ui/components/DiffView.js +0 -11
  74. package/dist/cli/ui/components/DiffView.js.map +0 -1
  75. package/dist/cli/ui/components/ErrorDisplay.d.ts +0 -6
  76. package/dist/cli/ui/components/ErrorDisplay.d.ts.map +0 -1
  77. package/dist/cli/ui/components/ErrorDisplay.js +0 -11
  78. package/dist/cli/ui/components/ErrorDisplay.js.map +0 -1
  79. package/dist/cli/ui/components/FuzzySearch.d.ts +0 -9
  80. package/dist/cli/ui/components/FuzzySearch.d.ts.map +0 -1
  81. package/dist/cli/ui/components/FuzzySearch.js +0 -12
  82. package/dist/cli/ui/components/FuzzySearch.js.map +0 -1
  83. package/dist/cli/ui/components/LoadingSpinner.d.ts +0 -6
  84. package/dist/cli/ui/components/LoadingSpinner.d.ts.map +0 -1
  85. package/dist/cli/ui/components/LoadingSpinner.js +0 -10
  86. package/dist/cli/ui/components/LoadingSpinner.js.map +0 -1
  87. package/dist/cli/ui/components/NavigationList.d.ts +0 -9
  88. package/dist/cli/ui/components/NavigationList.d.ts.map +0 -1
  89. package/dist/cli/ui/components/NavigationList.js +0 -11
  90. package/dist/cli/ui/components/NavigationList.js.map +0 -1
  91. package/dist/cli/ui/components/ScrollableContent.d.ts +0 -8
  92. package/dist/cli/ui/components/ScrollableContent.d.ts.map +0 -1
  93. package/dist/cli/ui/components/ScrollableContent.js +0 -11
  94. package/dist/cli/ui/components/ScrollableContent.js.map +0 -1
  95. package/dist/cli/ui/components/index.d.ts +0 -7
  96. package/dist/cli/ui/components/index.d.ts.map +0 -1
  97. package/dist/cli/ui/components/index.js +0 -9
  98. package/dist/cli/ui/components/index.js.map +0 -1
  99. package/dist/cli/ui/terminal-ui.d.ts +0 -52
  100. package/dist/cli/ui/terminal-ui.d.ts.map +0 -1
  101. package/dist/cli/ui/terminal-ui.js +0 -121
  102. package/dist/cli/ui/terminal-ui.js.map +0 -1
  103. package/dist/do/BashModule.d.ts +0 -871
  104. package/dist/do/BashModule.d.ts.map +0 -1
  105. package/dist/do/BashModule.js +0 -1143
  106. package/dist/do/BashModule.js.map +0 -1
  107. package/dist/do/FsModule.d.ts +0 -601
  108. package/dist/do/FsModule.d.ts.map +0 -1
  109. package/dist/do/FsModule.js +0 -1120
  110. package/dist/do/FsModule.js.map +0 -1
  111. package/dist/do/GitModule.d.ts +0 -635
  112. package/dist/do/GitModule.d.ts.map +0 -1
  113. package/dist/do/GitModule.js +0 -781
  114. package/dist/do/GitModule.js.map +0 -1
  115. package/dist/do/GitRepoDO.d.ts +0 -281
  116. package/dist/do/GitRepoDO.d.ts.map +0 -1
  117. package/dist/do/GitRepoDO.js +0 -479
  118. package/dist/do/GitRepoDO.js.map +0 -1
  119. package/dist/do/bash-ast.d.ts +0 -246
  120. package/dist/do/bash-ast.d.ts.map +0 -1
  121. package/dist/do/bash-ast.js +0 -888
  122. package/dist/do/bash-ast.js.map +0 -1
  123. package/dist/do/container-executor.d.ts +0 -491
  124. package/dist/do/container-executor.d.ts.map +0 -1
  125. package/dist/do/container-executor.js +0 -730
  126. package/dist/do/container-executor.js.map +0 -1
  127. package/dist/do/index.d.ts +0 -53
  128. package/dist/do/index.d.ts.map +0 -1
  129. package/dist/do/index.js +0 -91
  130. package/dist/do/index.js.map +0 -1
  131. package/dist/do/tiered-storage.d.ts +0 -403
  132. package/dist/do/tiered-storage.d.ts.map +0 -1
  133. package/dist/do/tiered-storage.js +0 -689
  134. package/dist/do/tiered-storage.js.map +0 -1
  135. package/dist/do/withBash.d.ts +0 -231
  136. package/dist/do/withBash.d.ts.map +0 -1
  137. package/dist/do/withBash.js +0 -244
  138. package/dist/do/withBash.js.map +0 -1
  139. package/dist/do/withFs.d.ts +0 -237
  140. package/dist/do/withFs.d.ts.map +0 -1
  141. package/dist/do/withFs.js +0 -387
  142. package/dist/do/withFs.js.map +0 -1
  143. package/dist/do/withGit.d.ts +0 -180
  144. package/dist/do/withGit.d.ts.map +0 -1
  145. package/dist/do/withGit.js +0 -271
  146. package/dist/do/withGit.js.map +0 -1
  147. package/dist/durable-object/object-store.d.ts +0 -633
  148. package/dist/durable-object/object-store.d.ts.map +0 -1
  149. package/dist/durable-object/object-store.js +0 -1161
  150. package/dist/durable-object/object-store.js.map +0 -1
  151. package/dist/durable-object/schema.d.ts.map +0 -1
  152. package/dist/durable-object/schema.js.map +0 -1
  153. package/dist/durable-object/wal.d.ts +0 -416
  154. package/dist/durable-object/wal.d.ts.map +0 -1
  155. package/dist/durable-object/wal.js +0 -445
  156. package/dist/durable-object/wal.js.map +0 -1
  157. package/dist/mcp/adapter.d.ts +0 -772
  158. package/dist/mcp/adapter.d.ts.map +0 -1
  159. package/dist/mcp/adapter.js +0 -895
  160. package/dist/mcp/adapter.js.map +0 -1
  161. package/dist/mcp/sandbox/miniflare-evaluator.d.ts +0 -22
  162. package/dist/mcp/sandbox/miniflare-evaluator.d.ts.map +0 -1
  163. package/dist/mcp/sandbox/miniflare-evaluator.js +0 -140
  164. package/dist/mcp/sandbox/miniflare-evaluator.js.map +0 -1
  165. package/dist/mcp/sandbox/object-store-proxy.d.ts +0 -32
  166. package/dist/mcp/sandbox/object-store-proxy.d.ts.map +0 -1
  167. package/dist/mcp/sandbox/object-store-proxy.js +0 -30
  168. package/dist/mcp/sandbox/object-store-proxy.js.map +0 -1
  169. package/dist/mcp/sandbox/template.d.ts +0 -17
  170. package/dist/mcp/sandbox/template.d.ts.map +0 -1
  171. package/dist/mcp/sandbox/template.js +0 -71
  172. package/dist/mcp/sandbox/template.js.map +0 -1
  173. package/dist/mcp/sandbox.d.ts +0 -764
  174. package/dist/mcp/sandbox.d.ts.map +0 -1
  175. package/dist/mcp/sandbox.js +0 -1362
  176. package/dist/mcp/sandbox.js.map +0 -1
  177. package/dist/mcp/sdk-adapter.d.ts +0 -835
  178. package/dist/mcp/sdk-adapter.d.ts.map +0 -1
  179. package/dist/mcp/sdk-adapter.js +0 -974
  180. package/dist/mcp/sdk-adapter.js.map +0 -1
  181. package/dist/mcp/tools/do.d.ts +0 -32
  182. package/dist/mcp/tools/do.d.ts.map +0 -1
  183. package/dist/mcp/tools/do.js +0 -115
  184. package/dist/mcp/tools/do.js.map +0 -1
  185. package/dist/mcp/tools.d.ts +0 -548
  186. package/dist/mcp/tools.d.ts.map +0 -1
  187. package/dist/mcp/tools.js +0 -1934
  188. package/dist/mcp/tools.js.map +0 -1
  189. package/dist/ops/blame.d.ts +0 -551
  190. package/dist/ops/blame.d.ts.map +0 -1
  191. package/dist/ops/blame.js +0 -1037
  192. package/dist/ops/blame.js.map +0 -1
  193. package/dist/ops/branch.d.ts +0 -766
  194. package/dist/ops/branch.d.ts.map +0 -1
  195. package/dist/ops/branch.js +0 -950
  196. package/dist/ops/branch.js.map +0 -1
  197. package/dist/ops/commit-traversal.d.ts +0 -349
  198. package/dist/ops/commit-traversal.d.ts.map +0 -1
  199. package/dist/ops/commit-traversal.js +0 -821
  200. package/dist/ops/commit-traversal.js.map +0 -1
  201. package/dist/ops/commit.d.ts +0 -555
  202. package/dist/ops/commit.d.ts.map +0 -1
  203. package/dist/ops/commit.js +0 -826
  204. package/dist/ops/commit.js.map +0 -1
  205. package/dist/ops/merge-base.d.ts +0 -397
  206. package/dist/ops/merge-base.d.ts.map +0 -1
  207. package/dist/ops/merge-base.js +0 -691
  208. package/dist/ops/merge-base.js.map +0 -1
  209. package/dist/ops/merge.d.ts +0 -855
  210. package/dist/ops/merge.d.ts.map +0 -1
  211. package/dist/ops/merge.js +0 -1551
  212. package/dist/ops/merge.js.map +0 -1
  213. package/dist/ops/tag.d.ts +0 -247
  214. package/dist/ops/tag.d.ts.map +0 -1
  215. package/dist/ops/tag.js +0 -649
  216. package/dist/ops/tag.js.map +0 -1
  217. package/dist/ops/tree-builder.d.ts +0 -178
  218. package/dist/ops/tree-builder.d.ts.map +0 -1
  219. package/dist/ops/tree-builder.js +0 -271
  220. package/dist/ops/tree-builder.js.map +0 -1
  221. package/dist/ops/tree-diff.d.ts +0 -291
  222. package/dist/ops/tree-diff.d.ts.map +0 -1
  223. package/dist/ops/tree-diff.js +0 -705
  224. package/dist/ops/tree-diff.js.map +0 -1
  225. package/dist/pack/delta.d.ts +0 -248
  226. package/dist/pack/delta.d.ts.map +0 -1
  227. package/dist/pack/delta.js +0 -736
  228. package/dist/pack/delta.js.map +0 -1
  229. package/dist/pack/format.d.ts +0 -446
  230. package/dist/pack/format.d.ts.map +0 -1
  231. package/dist/pack/format.js +0 -572
  232. package/dist/pack/format.js.map +0 -1
  233. package/dist/pack/full-generation.d.ts +0 -612
  234. package/dist/pack/full-generation.d.ts.map +0 -1
  235. package/dist/pack/full-generation.js +0 -1378
  236. package/dist/pack/full-generation.js.map +0 -1
  237. package/dist/pack/generation.d.ts +0 -441
  238. package/dist/pack/generation.d.ts.map +0 -1
  239. package/dist/pack/generation.js +0 -707
  240. package/dist/pack/generation.js.map +0 -1
  241. package/dist/pack/index.d.ts +0 -502
  242. package/dist/pack/index.d.ts.map +0 -1
  243. package/dist/pack/index.js +0 -833
  244. package/dist/pack/index.js.map +0 -1
  245. package/dist/refs/branch.d.ts +0 -668
  246. package/dist/refs/branch.d.ts.map +0 -1
  247. package/dist/refs/branch.js +0 -897
  248. package/dist/refs/branch.js.map +0 -1
  249. package/dist/refs/storage.d.ts +0 -833
  250. package/dist/refs/storage.d.ts.map +0 -1
  251. package/dist/refs/storage.js +0 -1023
  252. package/dist/refs/storage.js.map +0 -1
  253. package/dist/refs/tag.d.ts +0 -860
  254. package/dist/refs/tag.d.ts.map +0 -1
  255. package/dist/refs/tag.js +0 -996
  256. package/dist/refs/tag.js.map +0 -1
  257. package/dist/storage/backend.d.ts +0 -425
  258. package/dist/storage/backend.d.ts.map +0 -1
  259. package/dist/storage/backend.js +0 -41
  260. package/dist/storage/backend.js.map +0 -1
  261. package/dist/storage/fsx-adapter.d.ts +0 -204
  262. package/dist/storage/fsx-adapter.d.ts.map +0 -1
  263. package/dist/storage/fsx-adapter.js +0 -470
  264. package/dist/storage/fsx-adapter.js.map +0 -1
  265. package/dist/storage/lru-cache.d.ts +0 -691
  266. package/dist/storage/lru-cache.d.ts.map +0 -1
  267. package/dist/storage/lru-cache.js +0 -813
  268. package/dist/storage/lru-cache.js.map +0 -1
  269. package/dist/storage/object-index.d.ts +0 -585
  270. package/dist/storage/object-index.d.ts.map +0 -1
  271. package/dist/storage/object-index.js +0 -532
  272. package/dist/storage/object-index.js.map +0 -1
  273. package/dist/storage/r2-pack.d.ts +0 -1257
  274. package/dist/storage/r2-pack.d.ts.map +0 -1
  275. package/dist/storage/r2-pack.js +0 -1770
  276. package/dist/storage/r2-pack.js.map +0 -1
  277. package/dist/tiered/cdc-pipeline.d.ts +0 -1888
  278. package/dist/tiered/cdc-pipeline.d.ts.map +0 -1
  279. package/dist/tiered/cdc-pipeline.js +0 -1880
  280. package/dist/tiered/cdc-pipeline.js.map +0 -1
  281. package/dist/tiered/migration.d.ts +0 -1104
  282. package/dist/tiered/migration.d.ts.map +0 -1
  283. package/dist/tiered/migration.js +0 -1214
  284. package/dist/tiered/migration.js.map +0 -1
  285. package/dist/tiered/parquet-writer.d.ts +0 -1145
  286. package/dist/tiered/parquet-writer.d.ts.map +0 -1
  287. package/dist/tiered/parquet-writer.js +0 -1183
  288. package/dist/tiered/parquet-writer.js.map +0 -1
  289. package/dist/tiered/read-path.d.ts +0 -835
  290. package/dist/tiered/read-path.d.ts.map +0 -1
  291. package/dist/tiered/read-path.js +0 -487
  292. package/dist/tiered/read-path.js.map +0 -1
  293. package/dist/types/capability.d.ts +0 -1385
  294. package/dist/types/capability.d.ts.map +0 -1
  295. package/dist/types/capability.js +0 -36
  296. package/dist/types/capability.js.map +0 -1
  297. package/dist/types/index.d.ts +0 -13
  298. package/dist/types/index.d.ts.map +0 -1
  299. package/dist/types/index.js +0 -18
  300. package/dist/types/index.js.map +0 -1
  301. package/dist/types/objects.d.ts +0 -692
  302. package/dist/types/objects.d.ts.map +0 -1
  303. package/dist/types/objects.js +0 -837
  304. package/dist/types/objects.js.map +0 -1
  305. package/dist/types/storage.d.ts +0 -603
  306. package/dist/types/storage.d.ts.map +0 -1
  307. package/dist/types/storage.js +0 -191
  308. package/dist/types/storage.js.map +0 -1
  309. package/dist/types/worker-loader.d.ts +0 -60
  310. package/dist/types/worker-loader.d.ts.map +0 -1
  311. package/dist/types/worker-loader.js +0 -62
  312. package/dist/types/worker-loader.js.map +0 -1
  313. package/dist/utils/hash.d.ts +0 -197
  314. package/dist/utils/hash.d.ts.map +0 -1
  315. package/dist/utils/hash.js +0 -268
  316. package/dist/utils/hash.js.map +0 -1
  317. package/dist/utils/sha1.d.ts +0 -290
  318. package/dist/utils/sha1.d.ts.map +0 -1
  319. package/dist/utils/sha1.js +0 -582
  320. package/dist/utils/sha1.js.map +0 -1
  321. package/dist/wire/capabilities.d.ts +0 -1044
  322. package/dist/wire/capabilities.d.ts.map +0 -1
  323. package/dist/wire/capabilities.js +0 -941
  324. package/dist/wire/capabilities.js.map +0 -1
  325. package/dist/wire/path-security.d.ts +0 -157
  326. package/dist/wire/path-security.d.ts.map +0 -1
  327. package/dist/wire/path-security.js +0 -307
  328. package/dist/wire/path-security.js.map +0 -1
  329. package/dist/wire/pkt-line.d.ts +0 -345
  330. package/dist/wire/pkt-line.d.ts.map +0 -1
  331. package/dist/wire/pkt-line.js +0 -381
  332. package/dist/wire/pkt-line.js.map +0 -1
  333. package/dist/wire/receive-pack.d.ts +0 -1059
  334. package/dist/wire/receive-pack.d.ts.map +0 -1
  335. package/dist/wire/receive-pack.js +0 -1414
  336. package/dist/wire/receive-pack.js.map +0 -1
  337. package/dist/wire/smart-http.d.ts +0 -799
  338. package/dist/wire/smart-http.d.ts.map +0 -1
  339. package/dist/wire/smart-http.js +0 -945
  340. package/dist/wire/smart-http.js.map +0 -1
  341. package/dist/wire/upload-pack.d.ts +0 -727
  342. package/dist/wire/upload-pack.d.ts.map +0 -1
  343. package/dist/wire/upload-pack.js +0 -1138
  344. package/dist/wire/upload-pack.js.map +0 -1
@@ -1,1257 +0,0 @@
1
- /**
2
- * @fileoverview R2 Packfile Storage Module
3
- *
4
- * This module manages Git packfiles stored in Cloudflare R2 object storage.
5
- * It provides comprehensive functionality for:
6
- *
7
- * - **Uploading and downloading packfiles** with their indices using atomic operations
8
- * - **Multi-pack index (MIDX)** for efficient object lookup across multiple packs
9
- * - **Concurrent access control** with distributed locking using R2 conditional writes
10
- * - **Pack verification** and integrity checks via SHA-1 checksums
11
- * - **Atomic uploads** using a manifest-based pattern to ensure data consistency
12
- *
13
- * The module implements Git's packfile format (version 2 and 3) and provides
14
- * both class-based (`R2PackStorage`) and standalone function APIs for flexibility.
15
- *
16
- * @module storage/r2-pack
17
- *
18
- * @example
19
- * ```typescript
20
- * // Using the class-based API
21
- * const storage = new R2PackStorage({
22
- * bucket: myR2Bucket,
23
- * prefix: 'repos/my-repo/',
24
- * cacheSize: 100,
25
- * cacheTTL: 3600
26
- * });
27
- *
28
- * // Upload a packfile
29
- * const result = await storage.uploadPackfile(packData, indexData);
30
- * console.log(`Uploaded pack: ${result.packId}`);
31
- *
32
- * // Download with verification
33
- * const download = await storage.downloadPackfile(result.packId, {
34
- * verify: true,
35
- * includeIndex: true
36
- * });
37
- * ```
38
- *
39
- * @example
40
- * ```typescript
41
- * // Using standalone functions
42
- * const result = await uploadPackfile(bucket, packData, indexData, {
43
- * prefix: 'repos/my-repo/'
44
- * });
45
- *
46
- * const packfiles = await listPackfiles(bucket, {
47
- * prefix: 'repos/my-repo/',
48
- * limit: 10
49
- * });
50
- * ```
51
- */
52
- /**
53
- * Configuration options for R2PackStorage.
54
- *
55
- * @description
56
- * Defines the configuration parameters for initializing an R2PackStorage instance.
57
- * The bucket is required, while other options have sensible defaults.
58
- *
59
- * @example
60
- * ```typescript
61
- * const options: R2PackStorageOptions = {
62
- * bucket: env.MY_R2_BUCKET,
63
- * prefix: 'git-objects/',
64
- * cacheSize: 200,
65
- * cacheTTL: 7200
66
- * };
67
- * ```
68
- */
69
- export interface R2PackStorageOptions {
70
- /**
71
- * R2 bucket instance for storage operations.
72
- * This is typically obtained from the Cloudflare Workers environment bindings.
73
- */
74
- bucket: R2Bucket;
75
- /**
76
- * Optional prefix for all keys in the bucket.
77
- * Use this to namespace packfiles for different repositories.
78
- * @example 'repos/my-repo/' or 'org/project/'
79
- */
80
- prefix?: string;
81
- /**
82
- * Maximum number of items to cache in memory.
83
- * Used for caching multi-pack index and other frequently accessed data.
84
- * @default 100
85
- */
86
- cacheSize?: number;
87
- /**
88
- * Cache TTL (Time To Live) in seconds.
89
- * Cached items will be invalidated after this duration.
90
- * @default 3600 (1 hour)
91
- */
92
- cacheTTL?: number;
93
- }
94
- /**
95
- * Result returned after successfully uploading a packfile.
96
- *
97
- * @description
98
- * Contains metadata about the uploaded packfile including its unique identifier,
99
- * size information, checksum for verification, and timestamp.
100
- *
101
- * @example
102
- * ```typescript
103
- * const result = await storage.uploadPackfile(packData, indexData);
104
- * console.log(`Pack ID: ${result.packId}`);
105
- * console.log(`Objects: ${result.objectCount}`);
106
- * console.log(`Size: ${result.packSize} bytes`);
107
- * ```
108
- */
109
- export interface PackfileUploadResult {
110
- /** Unique identifier for the packfile (format: 'pack-{hex}') */
111
- packId: string;
112
- /** Size of the pack file in bytes */
113
- packSize: number;
114
- /** Size of the index file in bytes */
115
- indexSize: number;
116
- /** SHA-1 checksum of the packfile for integrity verification */
117
- checksum: string;
118
- /** Number of objects contained in the packfile */
119
- objectCount: number;
120
- /** Timestamp when the packfile was uploaded */
121
- uploadedAt: Date;
122
- }
123
- /**
124
- * Metadata about a stored packfile.
125
- *
126
- * @description
127
- * Provides comprehensive metadata about a packfile stored in R2,
128
- * including size, object count, creation time, and checksum.
129
- *
130
- * @example
131
- * ```typescript
132
- * const metadata = await storage.getPackfileMetadata('pack-abc123');
133
- * if (metadata) {
134
- * console.log(`Created: ${metadata.createdAt}`);
135
- * console.log(`Objects: ${metadata.objectCount}`);
136
- * }
137
- * ```
138
- */
139
- export interface PackfileMetadata {
140
- /** Unique identifier for the packfile */
141
- packId: string;
142
- /** Size of the pack file in bytes */
143
- packSize: number;
144
- /** Size of the index file in bytes */
145
- indexSize: number;
146
- /** Number of objects in the packfile */
147
- objectCount: number;
148
- /** Timestamp when the packfile was created */
149
- createdAt: Date;
150
- /** SHA-1 checksum of the packfile */
151
- checksum: string;
152
- }
153
- /**
154
- * Options for downloading a packfile.
155
- *
156
- * @description
157
- * Configures the download behavior including whether to include the index,
158
- * request byte ranges for partial reads, verify checksums, or throw on missing packs.
159
- *
160
- * @example
161
- * ```typescript
162
- * // Download with index and verification
163
- * const result = await storage.downloadPackfile(packId, {
164
- * includeIndex: true,
165
- * verify: true
166
- * });
167
- *
168
- * // Partial download (first 1MB)
169
- * const partial = await storage.downloadPackfile(packId, {
170
- * byteRange: { start: 0, end: 1048575 }
171
- * });
172
- * ```
173
- */
174
- export interface DownloadPackfileOptions {
175
- /** Include the index file in the download */
176
- includeIndex?: boolean;
177
- /**
178
- * Byte range to download for partial reads.
179
- * Useful for streaming large packfiles or resuming interrupted downloads.
180
- */
181
- byteRange?: {
182
- start: number;
183
- end: number;
184
- };
185
- /**
186
- * Verify checksum on download.
187
- * When true, computes SHA-1 of downloaded data and compares with stored checksum.
188
- */
189
- verify?: boolean;
190
- /**
191
- * Throw if packfile not found.
192
- * When true, throws R2PackError instead of returning null.
193
- * @default false
194
- */
195
- required?: boolean;
196
- }
197
- /**
198
- * Result of downloading a packfile.
199
- *
200
- * @description
201
- * Contains the downloaded packfile data and optionally the index data
202
- * if `includeIndex` was specified in the download options.
203
- *
204
- * @example
205
- * ```typescript
206
- * const result = await storage.downloadPackfile(packId, { includeIndex: true });
207
- * if (result) {
208
- * console.log(`Pack size: ${result.packData.length}`);
209
- * if (result.indexData) {
210
- * console.log(`Index size: ${result.indexData.length}`);
211
- * }
212
- * }
213
- * ```
214
- */
215
- export interface DownloadPackfileResult {
216
- /** The packfile data as a Uint8Array */
217
- packData: Uint8Array;
218
- /** The index file data (only present if includeIndex was true) */
219
- indexData?: Uint8Array;
220
- /** Whether the checksum was verified (only present if verify was true) */
221
- verified?: boolean;
222
- }
223
- /**
224
- * Options for uploading a packfile.
225
- *
226
- * @description
227
- * Configures upload behavior including retry count and atomic upload settings.
228
- *
229
- * @example
230
- * ```typescript
231
- * const result = await storage.uploadPackfile(packData, indexData, {
232
- * retries: 5,
233
- * skipAtomic: false // Use atomic upload for safety
234
- * });
235
- * ```
236
- */
237
- export interface UploadPackfileOptions {
238
- /**
239
- * Number of retries on failure.
240
- * Each retry uses exponential backoff.
241
- */
242
- retries?: number;
243
- /**
244
- * Skip atomic upload pattern.
245
- * Use only for testing or migration scenarios where atomicity is not required.
246
- * @default false
247
- */
248
- skipAtomic?: boolean;
249
- }
250
- /**
251
- * Pack manifest for atomic uploads.
252
- *
253
- * @description
254
- * A manifest marks a pack as "complete" only after both pack and index are uploaded.
255
- * This ensures atomic uploads where partial uploads are detected and can be cleaned up.
256
- *
257
- * The upload process follows these steps:
258
- * 1. Upload pack and index to staging paths
259
- * 2. Create manifest in 'staging' status
260
- * 3. Copy from staging to final location
261
- * 4. Update manifest to 'complete' status
262
- * 5. Clean up staging files
263
- *
264
- * @example
265
- * ```typescript
266
- * const manifest = await storage.getPackManifest(packId);
267
- * if (manifest?.status === 'complete') {
268
- * console.log('Pack upload is complete and verified');
269
- * }
270
- * ```
271
- */
272
- export interface PackManifest {
273
- /** Version of the manifest format */
274
- version: number;
275
- /** Pack ID this manifest belongs to */
276
- packId: string;
277
- /** SHA-1 checksum of the pack file */
278
- packChecksum: string;
279
- /** SHA-1 checksum of the index file */
280
- indexChecksum: string;
281
- /** Size of the pack file in bytes */
282
- packSize: number;
283
- /** Size of the index file in bytes */
284
- indexSize: number;
285
- /** Number of objects in the packfile */
286
- objectCount: number;
287
- /** ISO 8601 timestamp when the pack was completed */
288
- completedAt: string;
289
- /**
290
- * Upload status.
291
- * - 'staging': Upload in progress
292
- * - 'complete': Upload finished and verified
293
- */
294
- status: 'staging' | 'complete';
295
- }
296
- /**
297
- * Entry in the multi-pack index (MIDX).
298
- *
299
- * @description
300
- * Represents a single object's location within the multi-pack index.
301
- * Used for efficient O(log n) binary search across all objects in all packs.
302
- *
303
- * @example
304
- * ```typescript
305
- * const entry = lookupObjectInMultiPack(midx, objectId);
306
- * if (entry) {
307
- * const packId = midx.packIds[entry.packIndex];
308
- * console.log(`Object found in pack ${packId} at offset ${entry.offset}`);
309
- * }
310
- * ```
311
- */
312
- export interface MultiPackIndexEntry {
313
- /** 40-character hex SHA-1 object ID */
314
- objectId: string;
315
- /** Index of the pack in the packIds array */
316
- packIndex: number;
317
- /** Byte offset within the pack file where the object data begins */
318
- offset: number;
319
- }
320
- /**
321
- * Multi-pack index (MIDX) structure.
322
- *
323
- * @description
324
- * Provides a single index across multiple pack files for efficient object lookup.
325
- * Entries are sorted by objectId to enable binary search.
326
- *
327
- * The MIDX format follows Git's multi-pack-index specification with:
328
- * - MIDX signature (4 bytes)
329
- * - Version number
330
- * - Pack ID list
331
- * - Sorted object entries
332
- * - Trailing checksum
333
- *
334
- * @example
335
- * ```typescript
336
- * const midx = await storage.getMultiPackIndex();
337
- * console.log(`Index contains ${midx.entries.length} objects across ${midx.packIds.length} packs`);
338
- * ```
339
- */
340
- export interface MultiPackIndex {
341
- /** Version of the multi-pack index format */
342
- version: number;
343
- /** Array of pack IDs included in this index */
344
- packIds: string[];
345
- /** Sorted entries for all objects across all packs */
346
- entries: MultiPackIndexEntry[];
347
- /** SHA-1 checksum of the index for integrity verification */
348
- checksum: Uint8Array;
349
- }
350
- /**
351
- * Handle for a distributed lock.
352
- *
353
- * @description
354
- * Contains all information needed to release or refresh a distributed lock.
355
- * Locks are implemented using R2 conditional writes (ETags) for atomicity.
356
- *
357
- * @example
358
- * ```typescript
359
- * const handle = await storage.acquireDistributedLock('my-resource', 30000);
360
- * if (handle) {
361
- * try {
362
- * // Do work while holding the lock
363
- * await storage.refreshDistributedLock(handle, 30000); // Extend TTL
364
- * } finally {
365
- * await storage.releaseDistributedLock(handle);
366
- * }
367
- * }
368
- * ```
369
- */
370
- export interface LockHandle {
371
- /** Resource identifier that is locked */
372
- resource: string;
373
- /** Unique lock ID for this holder (used for ownership verification) */
374
- lockId: string;
375
- /** ETag for conditional operations (ensures lock hasn't been modified) */
376
- etag: string;
377
- /** When the lock expires (milliseconds since epoch) */
378
- expiresAt: number;
379
- }
380
- /**
381
- * Content stored in a lock file.
382
- *
383
- * @description
384
- * The JSON content stored in the R2 lock file. Used for lock ownership
385
- * verification and debugging lock contention issues.
386
- */
387
- export interface LockFileContent {
388
- /** Unique lock ID for ownership verification */
389
- lockId: string;
390
- /** Resource being locked */
391
- resource: string;
392
- /** When the lock expires (milliseconds since epoch) */
393
- expiresAt: number;
394
- /** When the lock was acquired (milliseconds since epoch) */
395
- acquiredAt: number;
396
- /** Worker/process identifier for debugging lock contention */
397
- holder?: string;
398
- }
399
- /**
400
- * Lock on a packfile for write operations.
401
- *
402
- * @description
403
- * Provides methods to check lock status, release the lock, and optionally
404
- * refresh the lock's TTL. Used to prevent concurrent modifications to packfiles.
405
- *
406
- * @example
407
- * ```typescript
408
- * const lock = await storage.acquireLock(packId, { ttl: 60000 });
409
- * try {
410
- * // Perform operations on the packfile
411
- * if (!lock.isHeld()) {
412
- * throw new Error('Lock expired!');
413
- * }
414
- * } finally {
415
- * await lock.release();
416
- * }
417
- * ```
418
- */
419
- export interface PackLock {
420
- /** Pack ID that is locked */
421
- packId: string;
422
- /** Check if lock is still held (not expired and not released) */
423
- isHeld(): boolean;
424
- /** Release the lock, allowing other processes to acquire it */
425
- release(): Promise<void>;
426
- /**
427
- * Refresh the lock TTL.
428
- * @returns true if refresh succeeded, false if lock was lost
429
- */
430
- refresh?(): Promise<boolean>;
431
- /** Get the underlying distributed lock handle (for advanced use) */
432
- handle?: LockHandle;
433
- }
434
- /**
435
- * Options for acquiring a lock.
436
- *
437
- * @description
438
- * Configures lock acquisition behavior including timeout, TTL, and holder identification.
439
- *
440
- * @example
441
- * ```typescript
442
- * const lock = await storage.acquireLock(packId, {
443
- * timeout: 10000, // Wait up to 10 seconds
444
- * ttl: 30000, // Lock expires after 30 seconds
445
- * holder: 'worker-1'
446
- * });
447
- * ```
448
- */
449
- export interface AcquireLockOptions {
450
- /**
451
- * Timeout in milliseconds to wait for lock acquisition.
452
- * If 0, fails immediately if lock is held.
453
- * @default 0
454
- */
455
- timeout?: number;
456
- /**
457
- * TTL in milliseconds after which lock auto-expires.
458
- * Prevents deadlocks if the holder crashes.
459
- * @default 30000
460
- */
461
- ttl?: number;
462
- /** Worker/process identifier for debugging lock contention */
463
- holder?: string;
464
- }
465
- /**
466
- * Result of listing packfiles.
467
- *
468
- * @description
469
- * Contains the list of packfile metadata and an optional cursor for pagination.
470
- *
471
- * @example
472
- * ```typescript
473
- * let cursor: string | undefined;
474
- * do {
475
- * const result = await storage.listPackfiles({ limit: 10, cursor });
476
- * for (const pack of result.items) {
477
- * console.log(pack.packId);
478
- * }
479
- * cursor = result.cursor;
480
- * } while (cursor);
481
- * ```
482
- */
483
- export interface ListPackfilesResult {
484
- /** Array of packfile metadata */
485
- items: PackfileMetadata[];
486
- /** Cursor for fetching the next page of results */
487
- cursor?: string;
488
- }
489
- /**
490
- * Error thrown by R2 pack operations.
491
- *
492
- * @description
493
- * Custom error class for R2 packfile operations with error codes for
494
- * programmatic error handling.
495
- *
496
- * Error codes:
497
- * - `NOT_FOUND`: Packfile does not exist
498
- * - `LOCKED`: Packfile is locked by another process
499
- * - `INVALID_DATA`: Packfile format is invalid
500
- * - `CHECKSUM_MISMATCH`: Checksum verification failed
501
- * - `NETWORK_ERROR`: R2 network/connectivity issue
502
- *
503
- * @example
504
- * ```typescript
505
- * try {
506
- * await storage.downloadPackfile(packId, { required: true });
507
- * } catch (error) {
508
- * if (error instanceof R2PackError) {
509
- * switch (error.code) {
510
- * case 'NOT_FOUND':
511
- * console.log('Pack does not exist');
512
- * break;
513
- * case 'CHECKSUM_MISMATCH':
514
- * console.log('Pack is corrupted');
515
- * break;
516
- * }
517
- * }
518
- * }
519
- * ```
520
- */
521
- export declare class R2PackError extends Error {
522
- readonly code: 'NOT_FOUND' | 'LOCKED' | 'INVALID_DATA' | 'CHECKSUM_MISMATCH' | 'NETWORK_ERROR';
523
- readonly packId?: string | undefined;
524
- /**
525
- * Creates a new R2PackError.
526
- *
527
- * @param message - Human-readable error message
528
- * @param code - Error code for programmatic handling
529
- * @param packId - Optional pack ID related to the error
530
- */
531
- constructor(message: string, code: 'NOT_FOUND' | 'LOCKED' | 'INVALID_DATA' | 'CHECKSUM_MISMATCH' | 'NETWORK_ERROR', packId?: string | undefined);
532
- }
533
- /**
534
- * R2 Packfile Storage class.
535
- *
536
- * @description
537
- * Main class for managing Git packfiles in Cloudflare R2 object storage.
538
- * Provides methods for uploading, downloading, listing, and managing packfiles
539
- * with support for atomic uploads, distributed locking, and multi-pack indexing.
540
- *
541
- * @example
542
- * ```typescript
543
- * // Initialize storage
544
- * const storage = new R2PackStorage({
545
- * bucket: env.GIT_BUCKET,
546
- * prefix: 'repos/my-repo/',
547
- * cacheSize: 100,
548
- * cacheTTL: 3600
549
- * });
550
- *
551
- * // Upload a packfile atomically
552
- * const result = await storage.uploadPackfile(packData, indexData);
553
- *
554
- * // Download with verification
555
- * const download = await storage.downloadPackfile(result.packId, {
556
- * verify: true,
557
- * includeIndex: true
558
- * });
559
- *
560
- * // List all packfiles
561
- * const list = await storage.listPackfiles();
562
- *
563
- * // Acquire lock for write operations
564
- * const lock = await storage.acquireLock(packId, { ttl: 30000 });
565
- * try {
566
- * // Perform operations
567
- * } finally {
568
- * await lock.release();
569
- * }
570
- * ```
571
- */
572
- export declare class R2PackStorage {
573
- private _bucket;
574
- private _prefix;
575
- private _cacheTTL;
576
- private _midxCache;
577
- private _indexChecksums;
578
- /**
579
- * Creates a new R2PackStorage instance.
580
- *
581
- * @param options - Configuration options for the storage instance
582
- *
583
- * @example
584
- * ```typescript
585
- * const storage = new R2PackStorage({
586
- * bucket: env.MY_BUCKET,
587
- * prefix: 'repos/my-repo/',
588
- * cacheSize: 100,
589
- * cacheTTL: 3600
590
- * });
591
- * ```
592
- */
593
- constructor(options: R2PackStorageOptions);
594
- private _buildKey;
595
- /**
596
- * Uploads a packfile and its index to R2 atomically.
597
- *
598
- * @description
599
- * Uses a manifest-based pattern to ensure atomic uploads:
600
- * 1. Upload pack and index to staging paths
601
- * 2. Create manifest in 'staging' status
602
- * 3. Copy from staging to final location
603
- * 4. Update manifest to 'complete' status
604
- * 5. Clean up staging files
605
- *
606
- * If the process fails at any point, the pack is not considered complete
607
- * until a valid manifest with status 'complete' exists.
608
- *
609
- * @param packData - Raw packfile bytes (must have valid PACK signature)
610
- * @param indexData - Pack index file bytes
611
- * @param options - Optional upload configuration
612
- *
613
- * @returns Upload result with pack ID, sizes, checksum, and object count
614
- *
615
- * @throws {R2PackError} With code 'INVALID_DATA' if packfile is invalid
616
- * @throws {R2PackError} With code 'NETWORK_ERROR' if bucket is unavailable
617
- *
618
- * @example
619
- * ```typescript
620
- * const result = await storage.uploadPackfile(packData, indexData);
621
- * console.log(`Uploaded: ${result.packId}`);
622
- * console.log(`Objects: ${result.objectCount}`);
623
- * console.log(`Checksum: ${result.checksum}`);
624
- * ```
625
- */
626
- uploadPackfile(packData: Uint8Array, indexData: Uint8Array, options?: UploadPackfileOptions): Promise<PackfileUploadResult>;
627
- /**
628
- * Gets the manifest for a packfile.
629
- *
630
- * @description
631
- * Retrieves the manifest JSON that tracks the upload status of a packfile.
632
- * Returns null if no manifest exists (legacy packs or invalid pack ID).
633
- *
634
- * @param packId - Pack identifier to get manifest for
635
- * @returns Pack manifest or null if not found
636
- *
637
- * @example
638
- * ```typescript
639
- * const manifest = await storage.getPackManifest('pack-abc123');
640
- * if (manifest?.status === 'complete') {
641
- * console.log('Pack is ready for use');
642
- * } else {
643
- * console.log('Pack upload is incomplete');
644
- * }
645
- * ```
646
- */
647
- getPackManifest(packId: string): Promise<PackManifest | null>;
648
- /**
649
- * Checks if a packfile upload is complete.
650
- *
651
- * @description
652
- * A pack is considered complete if:
653
- * 1. It has a manifest with status 'complete', OR
654
- * 2. It was uploaded before the atomic upload feature (legacy packs without manifest)
655
- * AND both .pack and .idx files exist
656
- *
657
- * @param packId - Pack identifier to check
658
- * @returns true if pack is complete and ready for use
659
- *
660
- * @example
661
- * ```typescript
662
- * if (await storage.isPackComplete(packId)) {
663
- * const data = await storage.downloadPackfile(packId);
664
- * }
665
- * ```
666
- */
667
- isPackComplete(packId: string): Promise<boolean>;
668
- /**
669
- * Downloads a packfile from R2.
670
- *
671
- * @description
672
- * Downloads pack data with optional index file. Verifies pack completeness
673
- * before downloading and optionally verifies checksum integrity.
674
- *
675
- * @param packId - Pack identifier to download
676
- * @param options - Download options (includeIndex, verify, byteRange, required)
677
- *
678
- * @returns Download result with pack data, or null if not found (unless required=true)
679
- *
680
- * @throws {R2PackError} With code 'NOT_FOUND' if required=true and pack not found
681
- * @throws {R2PackError} With code 'CHECKSUM_MISMATCH' if verify=true and verification fails
682
- *
683
- * @example
684
- * ```typescript
685
- * // Basic download
686
- * const result = await storage.downloadPackfile(packId);
687
- *
688
- * // Download with verification and index
689
- * const verified = await storage.downloadPackfile(packId, {
690
- * verify: true,
691
- * includeIndex: true
692
- * });
693
- *
694
- * // Required download (throws if not found)
695
- * const required = await storage.downloadPackfile(packId, { required: true });
696
- * ```
697
- */
698
- downloadPackfile(packId: string, options?: DownloadPackfileOptions): Promise<DownloadPackfileResult | null>;
699
- /**
700
- * Gets metadata for a packfile.
701
- *
702
- * @description
703
- * Retrieves metadata about a packfile including size, object count,
704
- * creation time, and checksum without downloading the full pack.
705
- *
706
- * @param packId - Pack identifier to get metadata for
707
- * @returns Packfile metadata or null if not found
708
- *
709
- * @example
710
- * ```typescript
711
- * const metadata = await storage.getPackfileMetadata(packId);
712
- * if (metadata) {
713
- * console.log(`Size: ${metadata.packSize} bytes`);
714
- * console.log(`Objects: ${metadata.objectCount}`);
715
- * }
716
- * ```
717
- */
718
- getPackfileMetadata(packId: string): Promise<PackfileMetadata | null>;
719
- /**
720
- * Lists all packfiles in storage.
721
- *
722
- * @description
723
- * Returns a paginated list of packfile metadata. Use the cursor for
724
- * fetching subsequent pages of results.
725
- *
726
- * @param options - Pagination options (limit, cursor)
727
- * @returns List of packfile metadata with optional cursor for pagination
728
- *
729
- * @example
730
- * ```typescript
731
- * // List first 10 packfiles
732
- * const first = await storage.listPackfiles({ limit: 10 });
733
- *
734
- * // Get next page
735
- * if (first.cursor) {
736
- * const next = await storage.listPackfiles({ limit: 10, cursor: first.cursor });
737
- * }
738
- * ```
739
- */
740
- listPackfiles(options?: {
741
- limit?: number;
742
- cursor?: string;
743
- }): Promise<ListPackfilesResult & PackfileMetadata[]>;
744
- /**
745
- * Deletes a packfile, its index, and manifest.
746
- *
747
- * @description
748
- * Removes all files associated with a packfile and updates the
749
- * multi-pack index if needed.
750
- *
751
- * @param packId - Pack identifier to delete
752
- * @returns true if pack was deleted, false if it didn't exist
753
- *
754
- * @example
755
- * ```typescript
756
- * if (await storage.deletePackfile(packId)) {
757
- * console.log('Pack deleted successfully');
758
- * } else {
759
- * console.log('Pack not found');
760
- * }
761
- * ```
762
- */
763
- deletePackfile(packId: string): Promise<boolean>;
764
- /**
765
- * Downloads just the index file for a packfile.
766
- *
767
- * @description
768
- * Retrieves only the pack index file, useful for object lookups
769
- * without downloading the full packfile.
770
- *
771
- * @param packId - Pack identifier to download index for
772
- * @returns Index data or null if not found
773
- *
774
- * @example
775
- * ```typescript
776
- * const indexData = await storage.downloadIndex(packId);
777
- * if (indexData) {
778
- * // Parse and use the index
779
- * }
780
- * ```
781
- */
782
- downloadIndex(packId: string): Promise<Uint8Array | null>;
783
- /**
784
- * Uploads a new index for an existing packfile.
785
- *
786
- * @description
787
- * Replaces the index file for an existing packfile. Useful for
788
- * regenerating corrupted indices or updating index format.
789
- *
790
- * @param packId - Pack identifier to upload index for
791
- * @param indexData - New index file data
792
- *
793
- * @throws {R2PackError} With code 'NOT_FOUND' if packfile doesn't exist
794
- *
795
- * @example
796
- * ```typescript
797
- * const newIndex = generatePackIndex(packData);
798
- * await storage.uploadIndex(packId, newIndex);
799
- * ```
800
- */
801
- uploadIndex(packId: string, indexData: Uint8Array): Promise<void>;
802
- /**
803
- * Verifies that an index matches its packfile.
804
- *
805
- * @description
806
- * Compares the current index checksum against the stored checksum
807
- * to detect corruption or tampering.
808
- *
809
- * @param packId - Pack identifier to verify index for
810
- * @returns true if index is valid, false if missing or corrupted
811
- *
812
- * @example
813
- * ```typescript
814
- * if (await storage.verifyIndex(packId)) {
815
- * console.log('Index is valid');
816
- * } else {
817
- * console.log('Index needs to be regenerated');
818
- * }
819
- * ```
820
- */
821
- verifyIndex(packId: string): Promise<boolean>;
822
- /**
823
- * Cleans up orphaned staging files.
824
- *
825
- * @description
826
- * This should be called on startup to clean up any staging files
827
- * left behind by failed uploads. It will:
828
- * 1. List all files in the staging directory
829
- * 2. For each pack ID found, check if it has a complete manifest
830
- * 3. If not complete, delete the staging files and any partial final files
831
- *
832
- * @returns Array of pack IDs that were cleaned up
833
- *
834
- * @example
835
- * ```typescript
836
- * // Call on worker startup
837
- * const cleaned = await storage.cleanupOrphanedStagingFiles();
838
- * if (cleaned.length > 0) {
839
- * console.log(`Cleaned up ${cleaned.length} orphaned uploads`);
840
- * }
841
- * ```
842
- */
843
- cleanupOrphanedStagingFiles(): Promise<string[]>;
844
- /**
845
- * Rebuilds the multi-pack index from all packfiles.
846
- *
847
- * @description
848
- * Creates a new MIDX by scanning all packfiles and building a sorted
849
- * index of all objects. Call this after adding or removing packs.
850
- *
851
- * @example
852
- * ```typescript
853
- * await storage.rebuildMultiPackIndex();
854
- * const midx = await storage.getMultiPackIndex();
855
- * console.log(`Indexed ${midx.entries.length} objects`);
856
- * ```
857
- */
858
- rebuildMultiPackIndex(): Promise<void>;
859
- /**
860
- * Gets the current multi-pack index.
861
- *
862
- * @description
863
- * Returns the MIDX from cache if available and not expired,
864
- * otherwise fetches from R2. Returns an empty index if none exists.
865
- *
866
- * @returns Current multi-pack index
867
- *
868
- * @example
869
- * ```typescript
870
- * const midx = await storage.getMultiPackIndex();
871
- * const entry = lookupObjectInMultiPack(midx, objectSha);
872
- * if (entry) {
873
- * const packId = midx.packIds[entry.packIndex];
874
- * console.log(`Object is in pack ${packId}`);
875
- * }
876
- * ```
877
- */
878
- getMultiPackIndex(): Promise<MultiPackIndex>;
879
- /**
880
- * Acquires a distributed lock on a resource using R2 conditional writes.
881
- *
882
- * @description
883
- * Uses R2's conditional write feature (ETags) to implement distributed locking.
884
- * Locks automatically expire after the TTL to prevent deadlocks.
885
- *
886
- * @param resource - Resource identifier to lock
887
- * @param ttlMs - Time-to-live in milliseconds
888
- * @param holder - Optional identifier for the lock holder (for debugging)
889
- *
890
- * @returns LockHandle if acquired, null if lock is held by another process
891
- *
892
- * @example
893
- * ```typescript
894
- * const handle = await storage.acquireDistributedLock('my-resource', 30000, 'worker-1');
895
- * if (handle) {
896
- * try {
897
- * // Do work while holding the lock
898
- * } finally {
899
- * await storage.releaseDistributedLock(handle);
900
- * }
901
- * } else {
902
- * console.log('Could not acquire lock - resource is busy');
903
- * }
904
- * ```
905
- */
906
- acquireDistributedLock(resource: string, ttlMs?: number, holder?: string): Promise<LockHandle | null>;
907
- /**
908
- * Releases a distributed lock.
909
- *
910
- * @description
911
- * Releases the lock only if the caller still owns it (verified by lockId).
912
- * Safe to call even if lock has expired or been taken by another process.
913
- *
914
- * @param handle - Lock handle returned from acquireDistributedLock
915
- *
916
- * @example
917
- * ```typescript
918
- * const handle = await storage.acquireDistributedLock('resource');
919
- * if (handle) {
920
- * try {
921
- * // Do work
922
- * } finally {
923
- * await storage.releaseDistributedLock(handle);
924
- * }
925
- * }
926
- * ```
927
- */
928
- releaseDistributedLock(handle: LockHandle): Promise<void>;
929
- /**
930
- * Refreshes a distributed lock to extend its TTL.
931
- *
932
- * @description
933
- * Extends the lock's expiration time. Useful for long-running operations
934
- * that need to hold the lock longer than the original TTL.
935
- *
936
- * @param handle - Lock handle to refresh
937
- * @param ttlMs - New TTL in milliseconds
938
- *
939
- * @returns true if refresh succeeded, false if lock was lost
940
- *
941
- * @example
942
- * ```typescript
943
- * const handle = await storage.acquireDistributedLock('resource', 30000);
944
- * if (handle) {
945
- * // Do some work...
946
- *
947
- * // Extend the lock for another 30 seconds
948
- * if (await storage.refreshDistributedLock(handle, 30000)) {
949
- * // Continue working
950
- * } else {
951
- * // Lock was lost, abort operation
952
- * }
953
- * }
954
- * ```
955
- */
956
- refreshDistributedLock(handle: LockHandle, ttlMs?: number): Promise<boolean>;
957
- /**
958
- * Cleans up expired locks from R2 storage.
959
- *
960
- * @description
961
- * Scans all lock files and removes those that have expired.
962
- * This should be called periodically to remove stale lock files
963
- * left by crashed processes.
964
- *
965
- * @returns Number of locks cleaned up
966
- *
967
- * @example
968
- * ```typescript
969
- * // Run periodically (e.g., every 5 minutes)
970
- * const cleaned = await storage.cleanupExpiredLocks();
971
- * console.log(`Cleaned up ${cleaned} expired locks`);
972
- * ```
973
- */
974
- cleanupExpiredLocks(): Promise<number>;
975
- /**
976
- * Acquires a lock on a packfile (backward-compatible wrapper).
977
- *
978
- * @description
979
- * High-level API for acquiring a pack lock with optional timeout.
980
- * Uses distributed locking with R2 conditional writes internally.
981
- *
982
- * @param packId - Pack identifier to lock
983
- * @param options - Lock acquisition options
984
- *
985
- * @returns PackLock interface for managing the lock
986
- *
987
- * @throws {R2PackError} With code 'LOCKED' if lock cannot be acquired
988
- *
989
- * @example
990
- * ```typescript
991
- * const lock = await storage.acquireLock(packId, {
992
- * timeout: 10000,
993
- * ttl: 30000,
994
- * holder: 'my-worker'
995
- * });
996
- *
997
- * try {
998
- * // Perform pack operations
999
- * if (lock.refresh) {
1000
- * await lock.refresh(); // Extend lock if needed
1001
- * }
1002
- * } finally {
1003
- * await lock.release();
1004
- * }
1005
- * ```
1006
- */
1007
- acquireLock(packId: string, options?: AcquireLockOptions): Promise<PackLock>;
1008
- }
1009
- /**
1010
- * Uploads a packfile to R2.
1011
- *
1012
- * @description
1013
- * Standalone function for uploading a packfile. Creates a temporary
1014
- * R2PackStorage instance internally.
1015
- *
1016
- * @param bucket - R2 bucket instance
1017
- * @param packData - Raw packfile bytes
1018
- * @param indexData - Pack index file bytes
1019
- * @param options - Optional configuration including prefix
1020
- *
1021
- * @returns Upload result with pack ID, sizes, and checksum
1022
- *
1023
- * @throws {R2PackError} If packfile is invalid or upload fails
1024
- *
1025
- * @example
1026
- * ```typescript
1027
- * const result = await uploadPackfile(bucket, packData, indexData, {
1028
- * prefix: 'repos/my-repo/'
1029
- * });
1030
- * console.log(`Uploaded: ${result.packId}`);
1031
- * ```
1032
- */
1033
- export declare function uploadPackfile(bucket: R2Bucket, packData: Uint8Array, indexData: Uint8Array, options?: {
1034
- prefix?: string;
1035
- }): Promise<PackfileUploadResult>;
1036
- /**
1037
- * Downloads a packfile from R2.
1038
- *
1039
- * @description
1040
- * Standalone function for downloading a packfile. Creates a temporary
1041
- * R2PackStorage instance internally.
1042
- *
1043
- * @param bucket - R2 bucket instance
1044
- * @param packId - Pack identifier to download
1045
- * @param options - Download options and prefix
1046
- *
1047
- * @returns Download result or null if not found
1048
- *
1049
- * @throws {R2PackError} If required=true and pack not found, or verification fails
1050
- *
1051
- * @example
1052
- * ```typescript
1053
- * const result = await downloadPackfile(bucket, packId, {
1054
- * prefix: 'repos/my-repo/',
1055
- * verify: true
1056
- * });
1057
- * ```
1058
- */
1059
- export declare function downloadPackfile(bucket: R2Bucket, packId: string, options?: DownloadPackfileOptions & {
1060
- prefix?: string;
1061
- }): Promise<DownloadPackfileResult | null>;
1062
- /**
1063
- * Gets packfile metadata.
1064
- *
1065
- * @description
1066
- * Standalone function for retrieving packfile metadata without downloading
1067
- * the full pack.
1068
- *
1069
- * @param bucket - R2 bucket instance
1070
- * @param packId - Pack identifier
1071
- * @param options - Optional prefix configuration
1072
- *
1073
- * @returns Packfile metadata or null if not found
1074
- *
1075
- * @example
1076
- * ```typescript
1077
- * const metadata = await getPackfileMetadata(bucket, packId);
1078
- * if (metadata) {
1079
- * console.log(`Objects: ${metadata.objectCount}`);
1080
- * }
1081
- * ```
1082
- */
1083
- export declare function getPackfileMetadata(bucket: R2Bucket, packId: string, options?: {
1084
- prefix?: string;
1085
- }): Promise<PackfileMetadata | null>;
1086
- /**
1087
- * Lists all packfiles.
1088
- *
1089
- * @description
1090
- * Standalone function for listing packfiles with pagination support.
1091
- *
1092
- * @param bucket - R2 bucket instance
1093
- * @param options - Prefix and pagination options
1094
- *
1095
- * @returns Array of packfile metadata
1096
- *
1097
- * @example
1098
- * ```typescript
1099
- * const packs = await listPackfiles(bucket, {
1100
- * prefix: 'repos/my-repo/',
1101
- * limit: 50
1102
- * });
1103
- * ```
1104
- */
1105
- export declare function listPackfiles(bucket: R2Bucket, options?: {
1106
- prefix?: string;
1107
- limit?: number;
1108
- cursor?: string;
1109
- }): Promise<PackfileMetadata[]>;
1110
- /**
1111
- * Deletes a packfile.
1112
- *
1113
- * @description
1114
- * Standalone function for deleting a packfile and its associated files.
1115
- *
1116
- * @param bucket - R2 bucket instance
1117
- * @param packId - Pack identifier to delete
1118
- * @param options - Optional prefix configuration
1119
- *
1120
- * @returns true if deleted, false if not found
1121
- *
1122
- * @example
1123
- * ```typescript
1124
- * if (await deletePackfile(bucket, packId)) {
1125
- * console.log('Deleted');
1126
- * }
1127
- * ```
1128
- */
1129
- export declare function deletePackfile(bucket: R2Bucket, packId: string, options?: {
1130
- prefix?: string;
1131
- }): Promise<boolean>;
1132
- /**
1133
- * Creates a multi-pack index from all packfiles in the bucket.
1134
- *
1135
- * @description
1136
- * Standalone function that rebuilds the MIDX and returns the result.
1137
- *
1138
- * @param bucket - R2 bucket instance
1139
- * @param options - Optional prefix configuration
1140
- *
1141
- * @returns The newly created multi-pack index
1142
- *
1143
- * @example
1144
- * ```typescript
1145
- * const midx = await createMultiPackIndex(bucket, { prefix: 'repos/my-repo/' });
1146
- * console.log(`Indexed ${midx.entries.length} objects`);
1147
- * ```
1148
- */
1149
- export declare function createMultiPackIndex(bucket: R2Bucket, options?: {
1150
- prefix?: string;
1151
- }): Promise<MultiPackIndex>;
1152
- /**
1153
- * Parses a multi-pack index from raw bytes.
1154
- *
1155
- * @description
1156
- * Deserializes the binary MIDX format into a MultiPackIndex structure.
1157
- * Validates the signature and format.
1158
- *
1159
- * @param data - Raw MIDX bytes
1160
- * @returns Parsed multi-pack index
1161
- *
1162
- * @throws {R2PackError} With code 'INVALID_DATA' if format is invalid
1163
- *
1164
- * @example
1165
- * ```typescript
1166
- * const midxData = await bucket.get('packs/multi-pack-index');
1167
- * if (midxData) {
1168
- * const midx = parseMultiPackIndex(new Uint8Array(await midxData.arrayBuffer()));
1169
- * console.log(`Contains ${midx.entries.length} objects`);
1170
- * }
1171
- * ```
1172
- */
1173
- export declare function parseMultiPackIndex(data: Uint8Array): MultiPackIndex;
1174
- /**
1175
- * Looks up an object in the multi-pack index using binary search.
1176
- *
1177
- * @description
1178
- * Efficiently finds an object's location across all packs using O(log n)
1179
- * binary search on the sorted entries.
1180
- *
1181
- * @param midx - Multi-pack index to search
1182
- * @param objectId - 40-character hex SHA-1 object ID to find
1183
- *
1184
- * @returns Entry with pack index and offset, or null if not found
1185
- *
1186
- * @example
1187
- * ```typescript
1188
- * const midx = await storage.getMultiPackIndex();
1189
- * const entry = lookupObjectInMultiPack(midx, 'abc123...');
1190
- * if (entry) {
1191
- * const packId = midx.packIds[entry.packIndex];
1192
- * const offset = entry.offset;
1193
- * console.log(`Found in ${packId} at offset ${offset}`);
1194
- * }
1195
- * ```
1196
- */
1197
- export declare function lookupObjectInMultiPack(midx: MultiPackIndex, objectId: string): MultiPackIndexEntry | null;
1198
- /**
1199
- * Acquires a lock on a packfile.
1200
- *
1201
- * @description
1202
- * Standalone function for acquiring a pack lock using distributed locking.
1203
- *
1204
- * @param bucket - R2 bucket instance
1205
- * @param packId - Pack identifier to lock
1206
- * @param options - Lock options and prefix
1207
- *
1208
- * @returns PackLock interface for managing the lock
1209
- *
1210
- * @throws {R2PackError} With code 'LOCKED' if lock cannot be acquired
1211
- *
1212
- * @example
1213
- * ```typescript
1214
- * const lock = await acquirePackLock(bucket, packId, {
1215
- * prefix: 'repos/my-repo/',
1216
- * timeout: 10000,
1217
- * ttl: 30000
1218
- * });
1219
- *
1220
- * try {
1221
- * // Do work
1222
- * } finally {
1223
- * await lock.release();
1224
- * }
1225
- * ```
1226
- */
1227
- export declare function acquirePackLock(bucket: R2Bucket, packId: string, options?: AcquireLockOptions & {
1228
- prefix?: string;
1229
- }): Promise<PackLock>;
1230
- /**
1231
- * Releases a lock on a packfile.
1232
- *
1233
- * @description
1234
- * Standalone function for releasing a pack lock.
1235
- *
1236
- * Note: This function requires a valid PackLock with a handle to properly
1237
- * release distributed locks. For best results, use the lock.release() method
1238
- * on the PackLock object returned from acquirePackLock.
1239
- *
1240
- * @param bucket - R2 bucket instance
1241
- * @param packId - Pack identifier to unlock
1242
- * @param options - Optional prefix configuration
1243
- *
1244
- * @example
1245
- * ```typescript
1246
- * // Preferred: use lock.release()
1247
- * const lock = await acquirePackLock(bucket, packId);
1248
- * await lock.release();
1249
- *
1250
- * // Alternative: use standalone function (less safe)
1251
- * await releasePackLock(bucket, packId);
1252
- * ```
1253
- */
1254
- export declare function releasePackLock(bucket: R2Bucket, packId: string, options?: {
1255
- prefix?: string;
1256
- }): Promise<void>;
1257
- //# sourceMappingURL=r2-pack.d.ts.map