gitx.do 0.0.1 → 0.0.3

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 (237) hide show
  1. package/dist/cli/commands/blame.d.ts +259 -0
  2. package/dist/cli/commands/blame.d.ts.map +1 -0
  3. package/dist/cli/commands/blame.js +609 -0
  4. package/dist/cli/commands/blame.js.map +1 -0
  5. package/dist/cli/commands/branch.d.ts +249 -0
  6. package/dist/cli/commands/branch.d.ts.map +1 -0
  7. package/dist/cli/commands/branch.js +693 -0
  8. package/dist/cli/commands/branch.js.map +1 -0
  9. package/dist/cli/commands/commit.d.ts +182 -0
  10. package/dist/cli/commands/commit.d.ts.map +1 -0
  11. package/dist/cli/commands/commit.js +437 -0
  12. package/dist/cli/commands/commit.js.map +1 -0
  13. package/dist/cli/commands/diff.d.ts +464 -0
  14. package/dist/cli/commands/diff.d.ts.map +1 -0
  15. package/dist/cli/commands/diff.js +958 -0
  16. package/dist/cli/commands/diff.js.map +1 -0
  17. package/dist/cli/commands/log.d.ts +239 -0
  18. package/dist/cli/commands/log.d.ts.map +1 -0
  19. package/dist/cli/commands/log.js +535 -0
  20. package/dist/cli/commands/log.js.map +1 -0
  21. package/dist/cli/commands/review.d.ts +457 -0
  22. package/dist/cli/commands/review.d.ts.map +1 -0
  23. package/dist/cli/commands/review.js +533 -0
  24. package/dist/cli/commands/review.js.map +1 -0
  25. package/dist/cli/commands/status.d.ts +269 -0
  26. package/dist/cli/commands/status.d.ts.map +1 -0
  27. package/dist/cli/commands/status.js +493 -0
  28. package/dist/cli/commands/status.js.map +1 -0
  29. package/dist/cli/commands/web.d.ts +199 -0
  30. package/dist/cli/commands/web.d.ts.map +1 -0
  31. package/dist/cli/commands/web.js +696 -0
  32. package/dist/cli/commands/web.js.map +1 -0
  33. package/dist/cli/fs-adapter.d.ts +656 -0
  34. package/dist/cli/fs-adapter.d.ts.map +1 -0
  35. package/dist/cli/fs-adapter.js +1179 -0
  36. package/dist/cli/fs-adapter.js.map +1 -0
  37. package/dist/cli/index.d.ts +387 -0
  38. package/dist/cli/index.d.ts.map +1 -0
  39. package/dist/cli/index.js +523 -0
  40. package/dist/cli/index.js.map +1 -0
  41. package/dist/cli/ui/components/DiffView.d.ts +7 -0
  42. package/dist/cli/ui/components/DiffView.d.ts.map +1 -0
  43. package/dist/cli/ui/components/DiffView.js +11 -0
  44. package/dist/cli/ui/components/DiffView.js.map +1 -0
  45. package/dist/cli/ui/components/ErrorDisplay.d.ts +6 -0
  46. package/dist/cli/ui/components/ErrorDisplay.d.ts.map +1 -0
  47. package/dist/cli/ui/components/ErrorDisplay.js +11 -0
  48. package/dist/cli/ui/components/ErrorDisplay.js.map +1 -0
  49. package/dist/cli/ui/components/FuzzySearch.d.ts +9 -0
  50. package/dist/cli/ui/components/FuzzySearch.d.ts.map +1 -0
  51. package/dist/cli/ui/components/FuzzySearch.js +12 -0
  52. package/dist/cli/ui/components/FuzzySearch.js.map +1 -0
  53. package/dist/cli/ui/components/LoadingSpinner.d.ts +6 -0
  54. package/dist/cli/ui/components/LoadingSpinner.d.ts.map +1 -0
  55. package/dist/cli/ui/components/LoadingSpinner.js +10 -0
  56. package/dist/cli/ui/components/LoadingSpinner.js.map +1 -0
  57. package/dist/cli/ui/components/NavigationList.d.ts +9 -0
  58. package/dist/cli/ui/components/NavigationList.d.ts.map +1 -0
  59. package/dist/cli/ui/components/NavigationList.js +11 -0
  60. package/dist/cli/ui/components/NavigationList.js.map +1 -0
  61. package/dist/cli/ui/components/ScrollableContent.d.ts +8 -0
  62. package/dist/cli/ui/components/ScrollableContent.d.ts.map +1 -0
  63. package/dist/cli/ui/components/ScrollableContent.js +11 -0
  64. package/dist/cli/ui/components/ScrollableContent.js.map +1 -0
  65. package/dist/cli/ui/components/index.d.ts +7 -0
  66. package/dist/cli/ui/components/index.d.ts.map +1 -0
  67. package/dist/cli/ui/components/index.js +9 -0
  68. package/dist/cli/ui/components/index.js.map +1 -0
  69. package/dist/cli/ui/terminal-ui.d.ts +52 -0
  70. package/dist/cli/ui/terminal-ui.d.ts.map +1 -0
  71. package/dist/cli/ui/terminal-ui.js +121 -0
  72. package/dist/cli/ui/terminal-ui.js.map +1 -0
  73. package/dist/durable-object/object-store.d.ts +401 -23
  74. package/dist/durable-object/object-store.d.ts.map +1 -1
  75. package/dist/durable-object/object-store.js +414 -25
  76. package/dist/durable-object/object-store.js.map +1 -1
  77. package/dist/durable-object/schema.d.ts +188 -0
  78. package/dist/durable-object/schema.d.ts.map +1 -1
  79. package/dist/durable-object/schema.js +160 -0
  80. package/dist/durable-object/schema.js.map +1 -1
  81. package/dist/durable-object/wal.d.ts +336 -31
  82. package/dist/durable-object/wal.d.ts.map +1 -1
  83. package/dist/durable-object/wal.js +272 -27
  84. package/dist/durable-object/wal.js.map +1 -1
  85. package/dist/index.d.ts +379 -3
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +379 -7
  88. package/dist/index.js.map +1 -1
  89. package/dist/mcp/adapter.d.ts +579 -38
  90. package/dist/mcp/adapter.d.ts.map +1 -1
  91. package/dist/mcp/adapter.js +426 -33
  92. package/dist/mcp/adapter.js.map +1 -1
  93. package/dist/mcp/sandbox.d.ts +532 -29
  94. package/dist/mcp/sandbox.d.ts.map +1 -1
  95. package/dist/mcp/sandbox.js +389 -22
  96. package/dist/mcp/sandbox.js.map +1 -1
  97. package/dist/mcp/sdk-adapter.d.ts +478 -56
  98. package/dist/mcp/sdk-adapter.d.ts.map +1 -1
  99. package/dist/mcp/sdk-adapter.js +346 -44
  100. package/dist/mcp/sdk-adapter.js.map +1 -1
  101. package/dist/mcp/tools.d.ts +445 -30
  102. package/dist/mcp/tools.d.ts.map +1 -1
  103. package/dist/mcp/tools.js +363 -33
  104. package/dist/mcp/tools.js.map +1 -1
  105. package/dist/ops/blame.d.ts +424 -21
  106. package/dist/ops/blame.d.ts.map +1 -1
  107. package/dist/ops/blame.js +303 -20
  108. package/dist/ops/blame.js.map +1 -1
  109. package/dist/ops/branch.d.ts +583 -32
  110. package/dist/ops/branch.d.ts.map +1 -1
  111. package/dist/ops/branch.js +365 -23
  112. package/dist/ops/branch.js.map +1 -1
  113. package/dist/ops/commit-traversal.d.ts +164 -24
  114. package/dist/ops/commit-traversal.d.ts.map +1 -1
  115. package/dist/ops/commit-traversal.js +68 -2
  116. package/dist/ops/commit-traversal.js.map +1 -1
  117. package/dist/ops/commit.d.ts +387 -53
  118. package/dist/ops/commit.d.ts.map +1 -1
  119. package/dist/ops/commit.js +249 -29
  120. package/dist/ops/commit.js.map +1 -1
  121. package/dist/ops/merge-base.d.ts +195 -21
  122. package/dist/ops/merge-base.d.ts.map +1 -1
  123. package/dist/ops/merge-base.js +122 -12
  124. package/dist/ops/merge-base.js.map +1 -1
  125. package/dist/ops/merge.d.ts +600 -130
  126. package/dist/ops/merge.d.ts.map +1 -1
  127. package/dist/ops/merge.js +408 -60
  128. package/dist/ops/merge.js.map +1 -1
  129. package/dist/ops/tag.d.ts +67 -2
  130. package/dist/ops/tag.d.ts.map +1 -1
  131. package/dist/ops/tag.js +42 -1
  132. package/dist/ops/tag.js.map +1 -1
  133. package/dist/ops/tree-builder.d.ts +102 -6
  134. package/dist/ops/tree-builder.d.ts.map +1 -1
  135. package/dist/ops/tree-builder.js +30 -5
  136. package/dist/ops/tree-builder.js.map +1 -1
  137. package/dist/ops/tree-diff.d.ts +50 -2
  138. package/dist/ops/tree-diff.d.ts.map +1 -1
  139. package/dist/ops/tree-diff.js +50 -2
  140. package/dist/ops/tree-diff.js.map +1 -1
  141. package/dist/pack/delta.d.ts +211 -39
  142. package/dist/pack/delta.d.ts.map +1 -1
  143. package/dist/pack/delta.js +232 -46
  144. package/dist/pack/delta.js.map +1 -1
  145. package/dist/pack/format.d.ts +390 -28
  146. package/dist/pack/format.d.ts.map +1 -1
  147. package/dist/pack/format.js +344 -33
  148. package/dist/pack/format.js.map +1 -1
  149. package/dist/pack/full-generation.d.ts +313 -28
  150. package/dist/pack/full-generation.d.ts.map +1 -1
  151. package/dist/pack/full-generation.js +238 -19
  152. package/dist/pack/full-generation.js.map +1 -1
  153. package/dist/pack/generation.d.ts +346 -23
  154. package/dist/pack/generation.d.ts.map +1 -1
  155. package/dist/pack/generation.js +269 -21
  156. package/dist/pack/generation.js.map +1 -1
  157. package/dist/pack/index.d.ts +407 -86
  158. package/dist/pack/index.d.ts.map +1 -1
  159. package/dist/pack/index.js +351 -70
  160. package/dist/pack/index.js.map +1 -1
  161. package/dist/refs/branch.d.ts +517 -71
  162. package/dist/refs/branch.d.ts.map +1 -1
  163. package/dist/refs/branch.js +410 -26
  164. package/dist/refs/branch.js.map +1 -1
  165. package/dist/refs/storage.d.ts +610 -57
  166. package/dist/refs/storage.d.ts.map +1 -1
  167. package/dist/refs/storage.js +481 -29
  168. package/dist/refs/storage.js.map +1 -1
  169. package/dist/refs/tag.d.ts +677 -67
  170. package/dist/refs/tag.d.ts.map +1 -1
  171. package/dist/refs/tag.js +497 -30
  172. package/dist/refs/tag.js.map +1 -1
  173. package/dist/storage/lru-cache.d.ts +556 -53
  174. package/dist/storage/lru-cache.d.ts.map +1 -1
  175. package/dist/storage/lru-cache.js +439 -36
  176. package/dist/storage/lru-cache.js.map +1 -1
  177. package/dist/storage/object-index.d.ts +483 -38
  178. package/dist/storage/object-index.d.ts.map +1 -1
  179. package/dist/storage/object-index.js +388 -22
  180. package/dist/storage/object-index.js.map +1 -1
  181. package/dist/storage/r2-pack.d.ts +957 -94
  182. package/dist/storage/r2-pack.d.ts.map +1 -1
  183. package/dist/storage/r2-pack.js +756 -48
  184. package/dist/storage/r2-pack.js.map +1 -1
  185. package/dist/tiered/cdc-pipeline.d.ts +1610 -38
  186. package/dist/tiered/cdc-pipeline.d.ts.map +1 -1
  187. package/dist/tiered/cdc-pipeline.js +1131 -22
  188. package/dist/tiered/cdc-pipeline.js.map +1 -1
  189. package/dist/tiered/migration.d.ts +903 -41
  190. package/dist/tiered/migration.d.ts.map +1 -1
  191. package/dist/tiered/migration.js +646 -24
  192. package/dist/tiered/migration.js.map +1 -1
  193. package/dist/tiered/parquet-writer.d.ts +944 -47
  194. package/dist/tiered/parquet-writer.d.ts.map +1 -1
  195. package/dist/tiered/parquet-writer.js +667 -39
  196. package/dist/tiered/parquet-writer.js.map +1 -1
  197. package/dist/tiered/read-path.d.ts +728 -34
  198. package/dist/tiered/read-path.d.ts.map +1 -1
  199. package/dist/tiered/read-path.js +310 -27
  200. package/dist/tiered/read-path.js.map +1 -1
  201. package/dist/types/objects.d.ts +457 -0
  202. package/dist/types/objects.d.ts.map +1 -1
  203. package/dist/types/objects.js +305 -4
  204. package/dist/types/objects.js.map +1 -1
  205. package/dist/types/storage.d.ts +407 -35
  206. package/dist/types/storage.d.ts.map +1 -1
  207. package/dist/types/storage.js +27 -3
  208. package/dist/types/storage.js.map +1 -1
  209. package/dist/utils/hash.d.ts +133 -12
  210. package/dist/utils/hash.d.ts.map +1 -1
  211. package/dist/utils/hash.js +133 -12
  212. package/dist/utils/hash.js.map +1 -1
  213. package/dist/utils/sha1.d.ts +102 -9
  214. package/dist/utils/sha1.d.ts.map +1 -1
  215. package/dist/utils/sha1.js +114 -11
  216. package/dist/utils/sha1.js.map +1 -1
  217. package/dist/wire/capabilities.d.ts +896 -88
  218. package/dist/wire/capabilities.d.ts.map +1 -1
  219. package/dist/wire/capabilities.js +566 -62
  220. package/dist/wire/capabilities.js.map +1 -1
  221. package/dist/wire/pkt-line.d.ts +293 -15
  222. package/dist/wire/pkt-line.d.ts.map +1 -1
  223. package/dist/wire/pkt-line.js +251 -15
  224. package/dist/wire/pkt-line.js.map +1 -1
  225. package/dist/wire/receive-pack.d.ts +814 -64
  226. package/dist/wire/receive-pack.d.ts.map +1 -1
  227. package/dist/wire/receive-pack.js +542 -41
  228. package/dist/wire/receive-pack.js.map +1 -1
  229. package/dist/wire/smart-http.d.ts +575 -97
  230. package/dist/wire/smart-http.d.ts.map +1 -1
  231. package/dist/wire/smart-http.js +337 -46
  232. package/dist/wire/smart-http.js.map +1 -1
  233. package/dist/wire/upload-pack.d.ts +492 -98
  234. package/dist/wire/upload-pack.d.ts.map +1 -1
  235. package/dist/wire/upload-pack.js +347 -59
  236. package/dist/wire/upload-pack.js.map +1 -1
  237. package/package.json +10 -2
@@ -1,87 +1,554 @@
1
1
  /**
2
- * Tiered Read Path
2
+ * @fileoverview Tiered Read Path Module
3
3
  *
4
- * Implements reading objects from the multi-tier storage system:
5
- * - Hot tier: Durable Object SQLite (fastest, local)
6
- * - Warm tier: R2 object storage (medium latency, packed objects)
7
- * - Cold tier: Analytics/Parquet (highest latency, cold storage)
4
+ * @description
5
+ * Implements reading objects from a multi-tier storage system designed for
6
+ * Git object storage. The tiered approach optimizes for both performance and
7
+ * cost by organizing data across multiple storage layers with different
8
+ * characteristics:
8
9
  *
9
- * Features:
10
- * - Tier fallback on miss
11
- * - Cache promotion (read-through caching)
12
- * - Configurable promotion policies
10
+ * **Storage Tiers:**
11
+ * - **Hot tier**: Durable Object SQLite (fastest, local, highest cost)
12
+ * - **Warm tier**: R2 object storage (medium latency, packed objects)
13
+ * - **Cold tier**: Analytics/Parquet (highest latency, lowest cost)
13
14
  *
14
- * gitdo-aaw: Tiered read path implementation
15
+ * **Features:**
16
+ * - Automatic tier fallback on cache miss
17
+ * - Read-through caching with promotion to hotter tiers
18
+ * - Configurable promotion policies (aggressive, conservative, none)
19
+ * - Latency tracking for performance monitoring
20
+ *
21
+ * **Architecture:**
22
+ * The TieredReader orchestrates reads across all tiers, attempting to serve
23
+ * data from the fastest available tier while optionally promoting frequently
24
+ * accessed objects to faster tiers.
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * // Create a tiered reader with all backends
29
+ * const reader = new TieredReader(
30
+ * hotBackend,
31
+ * warmBackend,
32
+ * coldBackend,
33
+ * {
34
+ * hot: { enabled: true, maxSize: 1024 * 1024 },
35
+ * warm: { enabled: true },
36
+ * cold: { enabled: true },
37
+ * promotionPolicy: 'aggressive'
38
+ * }
39
+ * )
40
+ *
41
+ * // Read an object - will try hot -> warm -> cold
42
+ * const result = await reader.read('abc123...')
43
+ * if (result.object) {
44
+ * console.log(`Found in ${result.tier} tier`)
45
+ * console.log(`Latency: ${result.latencyMs}ms`)
46
+ * if (result.promoted) {
47
+ * console.log('Object was promoted to hot tier')
48
+ * }
49
+ * }
50
+ * ```
51
+ *
52
+ * @module tiered/read-path
53
+ * @see {@link TieredReader} - Main implementation class
54
+ * @see {@link TieredStorageConfig} - Configuration options
15
55
  */
16
56
  import { ObjectType } from '../types/objects';
17
57
  /**
18
- * Stored object representation
58
+ * Represents a Git object stored in the tiered storage system.
59
+ *
60
+ * @description
61
+ * StoredObject is the common representation of a Git object across all storage
62
+ * tiers. It contains the object's content, metadata, and timing information
63
+ * needed for cache management and analytics.
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * const blobObject: StoredObject = {
68
+ * sha: 'a1b2c3d4e5f6...',
69
+ * type: 'blob',
70
+ * size: 1024,
71
+ * data: new Uint8Array([...]),
72
+ * createdAt: Date.now()
73
+ * }
74
+ * ```
75
+ *
76
+ * @interface StoredObject
19
77
  */
20
78
  export interface StoredObject {
79
+ /**
80
+ * SHA-1 hash of the object content.
81
+ * Must be a 40-character hexadecimal string.
82
+ *
83
+ * @example 'a1b2c3d4e5f678901234567890abcdef12345678'
84
+ */
21
85
  sha: string;
86
+ /**
87
+ * Git object type (blob, tree, commit, or tag).
88
+ *
89
+ * @see {@link ObjectType}
90
+ */
22
91
  type: ObjectType;
92
+ /**
93
+ * Size of the uncompressed object data in bytes.
94
+ */
23
95
  size: number;
96
+ /**
97
+ * Raw object data as a byte array.
98
+ * This is the uncompressed content of the Git object.
99
+ */
24
100
  data: Uint8Array;
101
+ /**
102
+ * Unix timestamp (milliseconds) when the object was first stored.
103
+ * Used for TTL calculations and analytics.
104
+ */
25
105
  createdAt: number;
26
106
  }
27
107
  /**
28
- * Configuration for a single tier
108
+ * Configuration options for a single storage tier.
109
+ *
110
+ * @description
111
+ * Each tier can be individually enabled/disabled and configured with
112
+ * size limits and TTL (time-to-live) settings. This allows fine-grained
113
+ * control over which objects are stored in each tier.
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * // Hot tier with size limit and TTL
118
+ * const hotConfig: TierConfig = {
119
+ * enabled: true,
120
+ * maxSize: 1024 * 1024, // 1MB max object size
121
+ * ttl: 3600 * 1000 // 1 hour TTL
122
+ * }
123
+ *
124
+ * // Disabled tier
125
+ * const disabledConfig: TierConfig = {
126
+ * enabled: false
127
+ * }
128
+ * ```
129
+ *
130
+ * @interface TierConfig
29
131
  */
30
132
  export interface TierConfig {
133
+ /**
134
+ * Whether this tier is enabled for reads and writes.
135
+ * Disabled tiers are skipped during read operations.
136
+ */
31
137
  enabled: boolean;
138
+ /**
139
+ * Maximum object size in bytes that can be stored in this tier.
140
+ * Objects larger than this size will not be promoted to this tier.
141
+ * If undefined, no size limit is enforced.
142
+ *
143
+ * @example 1048576 // 1MB
144
+ */
32
145
  maxSize?: number;
146
+ /**
147
+ * Time-to-live in milliseconds for objects in this tier.
148
+ * Objects older than TTL may be evicted or migrated to colder tiers.
149
+ * If undefined, objects persist indefinitely.
150
+ *
151
+ * @example 3600000 // 1 hour
152
+ */
33
153
  ttl?: number;
34
154
  }
35
155
  /**
36
- * Configuration for the tiered storage system
156
+ * Complete configuration for the tiered storage system.
157
+ *
158
+ * @description
159
+ * Defines the behavior of all three storage tiers (hot, warm, cold) and
160
+ * the promotion policy that determines when objects are moved to faster tiers.
161
+ *
162
+ * **Promotion Policies:**
163
+ * - `aggressive`: Immediately promote objects to hot tier on first access
164
+ * - `conservative`: Only promote on repeated access (not yet implemented)
165
+ * - `none`: Never automatically promote objects
166
+ *
167
+ * @example
168
+ * ```typescript
169
+ * const config: TieredStorageConfig = {
170
+ * hot: {
171
+ * enabled: true,
172
+ * maxSize: 1024 * 1024, // 1MB max
173
+ * ttl: 3600 * 1000 // 1 hour
174
+ * },
175
+ * warm: {
176
+ * enabled: true,
177
+ * maxSize: 10 * 1024 * 1024 // 10MB max
178
+ * },
179
+ * cold: {
180
+ * enabled: true
181
+ * // No size limit for cold storage
182
+ * },
183
+ * promotionPolicy: 'aggressive'
184
+ * }
185
+ * ```
186
+ *
187
+ * @interface TieredStorageConfig
37
188
  */
38
189
  export interface TieredStorageConfig {
190
+ /**
191
+ * Configuration for the hot tier (Durable Object SQLite).
192
+ * Hot tier provides the fastest access but has limited capacity.
193
+ */
39
194
  hot: TierConfig;
195
+ /**
196
+ * Configuration for the warm tier (R2 object storage).
197
+ * Warm tier provides moderate latency with larger capacity.
198
+ */
40
199
  warm: TierConfig;
200
+ /**
201
+ * Configuration for the cold tier (Analytics/Parquet).
202
+ * Cold tier provides lowest cost storage for archival.
203
+ */
41
204
  cold: TierConfig;
205
+ /**
206
+ * Policy for promoting objects to hotter tiers.
207
+ *
208
+ * - `aggressive`: Promote on first read from colder tier
209
+ * - `conservative`: Promote only on repeated access
210
+ * - `none`: Never automatically promote
211
+ */
42
212
  promotionPolicy: 'aggressive' | 'conservative' | 'none';
43
213
  }
44
214
  /**
45
- * Result of a read operation
215
+ * Result of a read operation from the tiered storage system.
216
+ *
217
+ * @description
218
+ * ReadResult provides complete information about a read operation, including
219
+ * the retrieved object (if found), which tier served the request, whether
220
+ * the object was promoted, and latency metrics.
221
+ *
222
+ * @example
223
+ * ```typescript
224
+ * const result = await reader.read(sha)
225
+ *
226
+ * if (result.object) {
227
+ * console.log(`Object found in ${result.tier} tier`)
228
+ * console.log(`Size: ${result.object.size} bytes`)
229
+ * console.log(`Latency: ${result.latencyMs}ms`)
230
+ *
231
+ * if (result.promoted) {
232
+ * console.log('Object was promoted to hot tier for faster future access')
233
+ * }
234
+ * } else {
235
+ * console.log('Object not found in any tier')
236
+ * console.log(`Search took ${result.latencyMs}ms`)
237
+ * }
238
+ * ```
239
+ *
240
+ * @interface ReadResult
46
241
  */
47
242
  export interface ReadResult {
243
+ /**
244
+ * The retrieved object, or null if not found in any tier.
245
+ */
48
246
  object: StoredObject | null;
247
+ /**
248
+ * The tier that served the request, or null if object was not found.
249
+ */
49
250
  tier: 'hot' | 'warm' | 'cold' | null;
251
+ /**
252
+ * Whether the object was promoted to a hotter tier during this read.
253
+ * Only true if the object was found in warm/cold tier and successfully
254
+ * copied to the hot tier.
255
+ */
50
256
  promoted: boolean;
257
+ /**
258
+ * Total latency of the read operation in milliseconds.
259
+ * Includes time spent checking all tiers and any promotion overhead.
260
+ */
51
261
  latencyMs: number;
52
262
  }
53
263
  /**
54
- * Interface for the tiered object store
264
+ * Interface for the tiered object store.
265
+ *
266
+ * @description
267
+ * Defines the public API for interacting with the tiered storage system.
268
+ * Implementations must provide methods for reading from any tier,
269
+ * manual promotion, and configuration access.
270
+ *
271
+ * @example
272
+ * ```typescript
273
+ * class MyTieredStore implements TieredObjectStore {
274
+ * async read(sha: string): Promise<ReadResult> {
275
+ * // Implementation
276
+ * }
277
+ * // ... other methods
278
+ * }
279
+ * ```
280
+ *
281
+ * @interface TieredObjectStore
55
282
  */
56
283
  export interface TieredObjectStore {
284
+ /**
285
+ * Reads an object from the tiered storage system.
286
+ *
287
+ * @description
288
+ * Attempts to read the object from each enabled tier in order
289
+ * (hot -> warm -> cold), returning as soon as the object is found.
290
+ * May promote the object to the hot tier based on the promotion policy.
291
+ *
292
+ * @param sha - The 40-character SHA-1 hash of the object to read
293
+ * @returns Promise resolving to the read result
294
+ *
295
+ * @example
296
+ * ```typescript
297
+ * const result = await store.read('abc123...')
298
+ * if (result.object) {
299
+ * // Process the object data
300
+ * }
301
+ * ```
302
+ */
57
303
  read(sha: string): Promise<ReadResult>;
304
+ /**
305
+ * Reads an object directly from the hot tier only.
306
+ *
307
+ * @description
308
+ * Bypasses the tier fallback logic to read directly from the hot tier.
309
+ * Useful for checking if an object is already cached.
310
+ *
311
+ * @param sha - The 40-character SHA-1 hash of the object
312
+ * @returns Promise resolving to the object or null if not in hot tier
313
+ */
58
314
  readFromHot(sha: string): Promise<StoredObject | null>;
315
+ /**
316
+ * Reads an object directly from the warm tier only.
317
+ *
318
+ * @description
319
+ * Bypasses the tier fallback logic to read directly from the warm tier.
320
+ * Does not trigger promotion to the hot tier.
321
+ *
322
+ * @param sha - The 40-character SHA-1 hash of the object
323
+ * @returns Promise resolving to the object or null if not in warm tier
324
+ */
59
325
  readFromWarm(sha: string): Promise<StoredObject | null>;
326
+ /**
327
+ * Reads an object directly from the cold tier only.
328
+ *
329
+ * @description
330
+ * Bypasses the tier fallback logic to read directly from the cold tier.
331
+ * Does not trigger promotion to hotter tiers.
332
+ *
333
+ * @param sha - The 40-character SHA-1 hash of the object
334
+ * @returns Promise resolving to the object or null if not in cold tier
335
+ */
60
336
  readFromCold(sha: string): Promise<StoredObject | null>;
337
+ /**
338
+ * Manually promotes an object to the hot tier.
339
+ *
340
+ * @description
341
+ * Copies the provided object to the hot tier storage. This is useful for
342
+ * pre-warming the cache or manually controlling tier placement.
343
+ *
344
+ * @param sha - The 40-character SHA-1 hash of the object
345
+ * @param object - The complete stored object to promote
346
+ * @returns Promise that resolves when promotion is complete
347
+ *
348
+ * @example
349
+ * ```typescript
350
+ * // Pre-warm the cache with frequently accessed objects
351
+ * for (const obj of frequentObjects) {
352
+ * await store.promoteToHot(obj.sha, obj)
353
+ * }
354
+ * ```
355
+ */
61
356
  promoteToHot(sha: string, object: StoredObject): Promise<void>;
357
+ /**
358
+ * Returns the current storage configuration.
359
+ *
360
+ * @returns The tiered storage configuration
361
+ */
62
362
  getConfig(): TieredStorageConfig;
63
363
  }
64
364
  /**
65
- * Hot tier backend interface (Durable Object SQLite)
365
+ * Backend interface for the hot tier (Durable Object SQLite).
366
+ *
367
+ * @description
368
+ * The hot tier backend provides fast, local storage using Durable Object
369
+ * SQLite. It supports full CRUD operations for Git objects.
370
+ *
371
+ * @example
372
+ * ```typescript
373
+ * class SqliteHotBackend implements HotTierBackend {
374
+ * async get(sha: string): Promise<StoredObject | null> {
375
+ * const row = await this.db.get('SELECT * FROM objects WHERE sha = ?', sha)
376
+ * return row ? this.rowToObject(row) : null
377
+ * }
378
+ *
379
+ * async put(sha: string, object: StoredObject): Promise<void> {
380
+ * await this.db.run(
381
+ * 'INSERT OR REPLACE INTO objects VALUES (?, ?, ?, ?, ?)',
382
+ * sha, object.type, object.size, object.data, object.createdAt
383
+ * )
384
+ * }
385
+ *
386
+ * async delete(sha: string): Promise<boolean> {
387
+ * const result = await this.db.run('DELETE FROM objects WHERE sha = ?', sha)
388
+ * return result.changes > 0
389
+ * }
390
+ *
391
+ * async has(sha: string): Promise<boolean> {
392
+ * const row = await this.db.get('SELECT 1 FROM objects WHERE sha = ?', sha)
393
+ * return !!row
394
+ * }
395
+ * }
396
+ * ```
397
+ *
398
+ * @interface HotTierBackend
66
399
  */
67
400
  export interface HotTierBackend {
401
+ /**
402
+ * Retrieves an object from the hot tier.
403
+ *
404
+ * @param sha - The 40-character SHA-1 hash of the object
405
+ * @returns Promise resolving to the object or null if not found
406
+ */
68
407
  get(sha: string): Promise<StoredObject | null>;
408
+ /**
409
+ * Stores an object in the hot tier.
410
+ *
411
+ * @param sha - The 40-character SHA-1 hash of the object
412
+ * @param object - The complete stored object to write
413
+ * @returns Promise that resolves when the write is complete
414
+ */
69
415
  put(sha: string, object: StoredObject): Promise<void>;
416
+ /**
417
+ * Deletes an object from the hot tier.
418
+ *
419
+ * @param sha - The 40-character SHA-1 hash of the object
420
+ * @returns Promise resolving to true if object was deleted, false if not found
421
+ */
70
422
  delete(sha: string): Promise<boolean>;
423
+ /**
424
+ * Checks if an object exists in the hot tier.
425
+ *
426
+ * @param sha - The 40-character SHA-1 hash of the object
427
+ * @returns Promise resolving to true if object exists
428
+ */
71
429
  has(sha: string): Promise<boolean>;
72
430
  }
73
431
  /**
74
- * Warm tier backend interface (R2 object storage)
432
+ * Backend interface for the warm tier (R2 object storage).
433
+ *
434
+ * @description
435
+ * The warm tier backend provides access to objects stored in R2, either
436
+ * as individual objects or within packfiles. Packfile access allows
437
+ * efficient retrieval of objects that have been packed together.
438
+ *
439
+ * @example
440
+ * ```typescript
441
+ * class R2WarmBackend implements WarmTierBackend {
442
+ * async get(sha: string): Promise<StoredObject | null> {
443
+ * // Try direct object first
444
+ * const obj = await this.r2.get(`objects/${sha}`)
445
+ * if (obj) return this.parseObject(obj)
446
+ *
447
+ * // Fall back to pack lookup
448
+ * const location = await this.index.findInPack(sha)
449
+ * if (location) {
450
+ * return this.getFromPack(location.packId, location.offset)
451
+ * }
452
+ * return null
453
+ * }
454
+ *
455
+ * async getFromPack(packId: string, offset: number): Promise<StoredObject | null> {
456
+ * const pack = await this.r2.get(`packs/${packId}`)
457
+ * return pack ? this.extractFromPack(pack, offset) : null
458
+ * }
459
+ * }
460
+ * ```
461
+ *
462
+ * @interface WarmTierBackend
75
463
  */
76
464
  export interface WarmTierBackend {
465
+ /**
466
+ * Retrieves an object from the warm tier.
467
+ *
468
+ * @description
469
+ * May retrieve the object either directly or from a packfile,
470
+ * depending on how it was stored.
471
+ *
472
+ * @param sha - The 40-character SHA-1 hash of the object
473
+ * @returns Promise resolving to the object or null if not found
474
+ */
77
475
  get(sha: string): Promise<StoredObject | null>;
476
+ /**
477
+ * Retrieves an object from a specific packfile at a given offset.
478
+ *
479
+ * @description
480
+ * Used when the exact location of an object within a packfile is known,
481
+ * typically from an index lookup.
482
+ *
483
+ * @param packId - The identifier of the packfile
484
+ * @param offset - Byte offset of the object within the pack
485
+ * @returns Promise resolving to the object or null if not found
486
+ */
78
487
  getFromPack(packId: string, offset: number): Promise<StoredObject | null>;
79
488
  }
80
489
  /**
81
- * Cold tier backend interface (Analytics/Parquet)
490
+ * Backend interface for the cold tier (Analytics/Parquet).
491
+ *
492
+ * @description
493
+ * The cold tier backend provides access to objects stored in analytical
494
+ * formats like Parquet. It supports both direct lookups and filtered
495
+ * queries for analytics purposes.
496
+ *
497
+ * @example
498
+ * ```typescript
499
+ * class ParquetColdBackend implements ColdTierBackend {
500
+ * async get(sha: string): Promise<StoredObject | null> {
501
+ * const rows = await this.parquet.query(`
502
+ * SELECT * FROM objects WHERE sha = '${sha}'
503
+ * `)
504
+ * return rows[0] ? this.rowToObject(rows[0]) : null
505
+ * }
506
+ *
507
+ * async query(filter: { type?: ObjectType }): Promise<StoredObject[]> {
508
+ * const conditions = []
509
+ * if (filter.type) conditions.push(`type = '${filter.type}'`)
510
+ * if (filter.minSize) conditions.push(`size >= ${filter.minSize}`)
511
+ *
512
+ * const sql = `SELECT * FROM objects WHERE ${conditions.join(' AND ')}`
513
+ * const rows = await this.parquet.query(sql)
514
+ * return rows.map(this.rowToObject)
515
+ * }
516
+ * }
517
+ * ```
518
+ *
519
+ * @interface ColdTierBackend
82
520
  */
83
521
  export interface ColdTierBackend {
522
+ /**
523
+ * Retrieves an object from the cold tier by SHA.
524
+ *
525
+ * @param sha - The 40-character SHA-1 hash of the object
526
+ * @returns Promise resolving to the object or null if not found
527
+ */
84
528
  get(sha: string): Promise<StoredObject | null>;
529
+ /**
530
+ * Queries the cold tier for objects matching the given filter.
531
+ *
532
+ * @description
533
+ * Performs a filtered query against the analytical storage, returning
534
+ * all objects that match the specified criteria. Useful for analytics
535
+ * and batch processing operations.
536
+ *
537
+ * @param filter - Filter criteria for the query
538
+ * @param filter.type - Filter by Git object type
539
+ * @param filter.minSize - Minimum object size in bytes
540
+ * @param filter.maxSize - Maximum object size in bytes
541
+ * @returns Promise resolving to array of matching objects
542
+ *
543
+ * @example
544
+ * ```typescript
545
+ * // Find all large blobs
546
+ * const largeBlobs = await coldBackend.query({
547
+ * type: 'blob',
548
+ * minSize: 1024 * 1024 // > 1MB
549
+ * })
550
+ * ```
551
+ */
85
552
  query(filter: {
86
553
  type?: ObjectType;
87
554
  minSize?: number;
@@ -89,51 +556,278 @@ export interface ColdTierBackend {
89
556
  }): Promise<StoredObject[]>;
90
557
  }
91
558
  /**
92
- * TieredReader - Main implementation of the tiered read path
559
+ * TieredReader - Main implementation of the tiered read path.
560
+ *
561
+ * @description
562
+ * TieredReader orchestrates reads across multiple storage tiers (hot, warm, cold),
563
+ * implementing automatic fallback and optional promotion to hotter tiers. It provides
564
+ * a unified interface for reading Git objects regardless of which tier they reside in.
565
+ *
566
+ * **Read Algorithm:**
567
+ * 1. Validate the SHA-1 hash
568
+ * 2. If hot tier enabled, attempt to read from hot tier
569
+ * 3. If not found and warm tier enabled, attempt warm tier
570
+ * 4. If not found and cold tier enabled, attempt cold tier
571
+ * 5. If found in warm/cold, optionally promote to hot tier
572
+ * 6. Return result with object, source tier, and metrics
573
+ *
574
+ * **Promotion Policies:**
575
+ * - `aggressive`: Immediately promote any object read from warm/cold to hot
576
+ * - `conservative`: Reserved for future implementation (repeated access tracking)
577
+ * - `none`: Never automatically promote objects
93
578
  *
94
- * Reads objects from multiple storage tiers with fallback logic
95
- * and optional promotion to hotter tiers.
579
+ * **Error Handling:**
580
+ * Individual tier failures are silently caught and the next tier is tried.
581
+ * This ensures graceful degradation when a tier is temporarily unavailable.
582
+ *
583
+ * @example
584
+ * ```typescript
585
+ * // Create backends for each tier
586
+ * const hotBackend = new SqliteHotBackend(db)
587
+ * const warmBackend = new R2WarmBackend(r2)
588
+ * const coldBackend = new ParquetColdBackend(parquet)
589
+ *
590
+ * // Configure the tiered storage
591
+ * const config: TieredStorageConfig = {
592
+ * hot: { enabled: true, maxSize: 1024 * 1024 },
593
+ * warm: { enabled: true },
594
+ * cold: { enabled: true },
595
+ * promotionPolicy: 'aggressive'
596
+ * }
597
+ *
598
+ * // Create the reader
599
+ * const reader = new TieredReader(hotBackend, warmBackend, coldBackend, config)
600
+ *
601
+ * // Read an object
602
+ * const result = await reader.read('a1b2c3d4e5f678901234567890abcdef12345678')
603
+ *
604
+ * if (result.object) {
605
+ * console.log(`Object type: ${result.object.type}`)
606
+ * console.log(`Size: ${result.object.size} bytes`)
607
+ * console.log(`Served from: ${result.tier} tier`)
608
+ * console.log(`Latency: ${result.latencyMs}ms`)
609
+ *
610
+ * if (result.promoted) {
611
+ * console.log('Object was promoted to hot tier')
612
+ * }
613
+ * } else {
614
+ * console.log('Object not found in any tier')
615
+ * }
616
+ *
617
+ * // Direct tier access
618
+ * const hotOnly = await reader.readFromHot(sha)
619
+ * const warmOnly = await reader.readFromWarm(sha)
620
+ * const coldOnly = await reader.readFromCold(sha)
621
+ *
622
+ * // Manual promotion
623
+ * if (warmOnly) {
624
+ * await reader.promoteToHot(sha, warmOnly)
625
+ * }
626
+ * ```
627
+ *
628
+ * @class TieredReader
629
+ * @implements {TieredObjectStore}
96
630
  */
97
631
  export declare class TieredReader implements TieredObjectStore {
632
+ /**
633
+ * Backend for the hot storage tier (Durable Object SQLite).
634
+ * @private
635
+ */
98
636
  private hotBackend;
637
+ /**
638
+ * Backend for the warm storage tier (R2 object storage).
639
+ * @private
640
+ */
99
641
  private warmBackend;
642
+ /**
643
+ * Backend for the cold storage tier (Analytics/Parquet).
644
+ * @private
645
+ */
100
646
  private coldBackend;
647
+ /**
648
+ * Configuration for all tiers and promotion policy.
649
+ * @private
650
+ */
101
651
  private config;
652
+ /**
653
+ * Creates a new TieredReader instance.
654
+ *
655
+ * @param hotBackend - Backend for the hot tier (Durable Object SQLite)
656
+ * @param warmBackend - Backend for the warm tier (R2)
657
+ * @param coldBackend - Backend for the cold tier (Parquet)
658
+ * @param config - Configuration for all tiers and promotion policy
659
+ *
660
+ * @example
661
+ * ```typescript
662
+ * const reader = new TieredReader(
663
+ * hotBackend,
664
+ * warmBackend,
665
+ * coldBackend,
666
+ * {
667
+ * hot: { enabled: true, maxSize: 1024 * 1024 },
668
+ * warm: { enabled: true },
669
+ * cold: { enabled: true },
670
+ * promotionPolicy: 'aggressive'
671
+ * }
672
+ * )
673
+ * ```
674
+ */
102
675
  constructor(hotBackend: HotTierBackend, warmBackend: WarmTierBackend, coldBackend: ColdTierBackend, config: TieredStorageConfig);
103
676
  /**
104
- * Read an object from the tiered storage system
677
+ * Reads an object from the tiered storage system.
678
+ *
679
+ * @description
680
+ * Attempts to read the object from each enabled tier in order
681
+ * (hot -> warm -> cold), returning as soon as the object is found.
682
+ * Objects found in warm or cold tiers may be promoted to hot tier
683
+ * based on the configured promotion policy.
105
684
  *
106
- * Tries each enabled tier in order: hot -> warm -> cold
107
- * Promotes objects to hot tier based on promotion policy
685
+ * **Invalid SHA Handling:**
686
+ * If the SHA is invalid (not 40 hex characters), returns immediately
687
+ * with null object and no tier lookup is performed.
688
+ *
689
+ * **Error Handling:**
690
+ * If a tier fails (throws an error), the error is caught silently
691
+ * and the next tier is attempted. This provides graceful degradation.
692
+ *
693
+ * @param sha - The 40-character SHA-1 hash of the object to read
694
+ * @returns Promise resolving to the read result with object, tier, and metrics
695
+ *
696
+ * @example
697
+ * ```typescript
698
+ * const result = await reader.read('a1b2c3d4e5f678901234567890abcdef12345678')
699
+ *
700
+ * if (result.object) {
701
+ * // Object found
702
+ * console.log(`Type: ${result.object.type}`)
703
+ * console.log(`Tier: ${result.tier}`)
704
+ * console.log(`Promoted: ${result.promoted}`)
705
+ * } else {
706
+ * // Object not found
707
+ * console.log(`Search took ${result.latencyMs}ms`)
708
+ * }
709
+ * ```
108
710
  */
109
711
  read(sha: string): Promise<ReadResult>;
110
712
  /**
111
- * Read an object directly from the hot tier
713
+ * Reads an object directly from the hot tier only.
714
+ *
715
+ * @description
716
+ * Bypasses the tier fallback logic to read directly from the hot tier.
717
+ * Useful for checking if an object is already in the hot cache.
718
+ * Errors are caught and null is returned.
719
+ *
720
+ * @param sha - The 40-character SHA-1 hash of the object
721
+ * @returns Promise resolving to the object or null if not in hot tier
722
+ *
723
+ * @example
724
+ * ```typescript
725
+ * const cached = await reader.readFromHot(sha)
726
+ * if (cached) {
727
+ * console.log('Object is in hot cache')
728
+ * } else {
729
+ * console.log('Object not in hot cache')
730
+ * }
731
+ * ```
112
732
  */
113
733
  readFromHot(sha: string): Promise<StoredObject | null>;
114
734
  /**
115
- * Read an object directly from the warm tier
735
+ * Reads an object directly from the warm tier only.
736
+ *
737
+ * @description
738
+ * Bypasses the tier fallback logic to read directly from the warm tier.
739
+ * Does not trigger automatic promotion to hot tier.
740
+ * Errors are caught and null is returned.
741
+ *
742
+ * @param sha - The 40-character SHA-1 hash of the object
743
+ * @returns Promise resolving to the object or null if not in warm tier
744
+ *
745
+ * @example
746
+ * ```typescript
747
+ * const warm = await reader.readFromWarm(sha)
748
+ * if (warm) {
749
+ * // Manually promote if desired
750
+ * await reader.promoteToHot(sha, warm)
751
+ * }
752
+ * ```
116
753
  */
117
754
  readFromWarm(sha: string): Promise<StoredObject | null>;
118
755
  /**
119
- * Read an object directly from the cold tier
756
+ * Reads an object directly from the cold tier only.
757
+ *
758
+ * @description
759
+ * Bypasses the tier fallback logic to read directly from the cold tier.
760
+ * Does not trigger automatic promotion to hotter tiers.
761
+ * Errors are caught and null is returned.
762
+ *
763
+ * @param sha - The 40-character SHA-1 hash of the object
764
+ * @returns Promise resolving to the object or null if not in cold tier
765
+ *
766
+ * @example
767
+ * ```typescript
768
+ * const cold = await reader.readFromCold(sha)
769
+ * if (cold) {
770
+ * console.log(`Found in cold storage, created at: ${cold.createdAt}`)
771
+ * }
772
+ * ```
120
773
  */
121
774
  readFromCold(sha: string): Promise<StoredObject | null>;
122
775
  /**
123
- * Manually promote an object to the hot tier
776
+ * Manually promotes an object to the hot tier.
777
+ *
778
+ * @description
779
+ * Copies the provided object to the hot tier storage. This is useful for
780
+ * pre-warming the cache or manually controlling tier placement. No size
781
+ * or policy checks are performed - the object is always written.
782
+ *
783
+ * @param sha - The 40-character SHA-1 hash of the object
784
+ * @param object - The complete stored object to promote
785
+ * @returns Promise that resolves when promotion is complete
786
+ * @throws Error if the hot tier write fails
787
+ *
788
+ * @example
789
+ * ```typescript
790
+ * // Pre-warm the hot cache
791
+ * const objects = await reader.query({ type: 'commit' })
792
+ * for (const obj of objects) {
793
+ * await reader.promoteToHot(obj.sha, obj)
794
+ * }
795
+ * ```
124
796
  */
125
797
  promoteToHot(sha: string, object: StoredObject): Promise<void>;
126
798
  /**
127
- * Get the current configuration
799
+ * Returns the current storage configuration.
800
+ *
801
+ * @description
802
+ * Returns the configuration object passed to the constructor.
803
+ * Useful for inspecting current settings or debugging.
804
+ *
805
+ * @returns The tiered storage configuration
806
+ *
807
+ * @example
808
+ * ```typescript
809
+ * const config = reader.getConfig()
810
+ * console.log(`Promotion policy: ${config.promotionPolicy}`)
811
+ * console.log(`Hot tier enabled: ${config.hot.enabled}`)
812
+ * ```
128
813
  */
129
814
  getConfig(): TieredStorageConfig;
130
815
  /**
131
- * Try to promote an object to the hot tier based on policy
816
+ * Attempts to promote an object to the hot tier based on policy.
817
+ *
818
+ * @description
819
+ * Called internally when an object is found in warm or cold tier.
820
+ * Decides whether to promote based on:
821
+ * 1. Hot tier being enabled
822
+ * 2. Promotion policy (aggressive promotes, conservative/none don't)
823
+ * 3. Object size being within hot tier's maxSize limit
824
+ *
825
+ * @param sha - The object's SHA-1 hash
826
+ * @param object - The object to potentially promote
827
+ * @param _sourceTier - The tier the object was read from (for future use)
828
+ * @returns true if promotion was successful, false otherwise
132
829
  *
133
- * @param sha - The object's SHA
134
- * @param object - The object to promote
135
- * @param sourceTier - The tier the object was read from
136
- * @returns true if promotion was successful
830
+ * @private
137
831
  */
138
832
  private tryPromote;
139
833
  }