(
url: string,
)
| 261 | } |
| 262 | |
| 263 | private async resolveHashDescriptor( |
| 264 | url: string, |
| 265 | ): Promise<CrossOriginHashDescriptor | null> { |
| 266 | const cached = this.hashCache.get(url); |
| 267 | if (cached) { |
| 268 | return cached; |
| 269 | } |
| 270 | // Check persistent store before falling back to network-based hash extraction. |
| 271 | // This covers non-LFS files (JSON configs, tokenizers) and non-HuggingFace URLs |
| 272 | // (e.g. GitHub raw .wasm files) whose hashes were computed from blob content on a |
| 273 | // previous visit and persisted to the Cache API. |
| 274 | const persisted = await this.loadPersistedHashEntry(url); |
| 275 | if (persisted) { |
| 276 | this.hashCache.set(url, persisted); |
| 277 | return persisted; |
| 278 | } |
| 279 | const hashValue = await this.getFileHash(url); |
| 280 | if (!hashValue) { |
| 281 | return null; |
| 282 | } |
| 283 | const descriptor: CrossOriginHashDescriptor = { |
| 284 | algorithm: HASH_ALGORITHM, |
| 285 | value: hashValue, |
| 286 | }; |
| 287 | this.hashCache.set(url, descriptor); |
| 288 | // Persist pointer-derived hashes so subsequent visits skip the LFS pointer |
| 289 | // network request (especially important for models with many shards). |
| 290 | await this.persistHashEntry(url, descriptor); |
| 291 | return descriptor; |
| 292 | } |
| 293 | |
| 294 | private async getFileHash(url: string): Promise<string | null> { |
| 295 | if (/\/resolve\//.test(url)) { |
no test coverage detected