diff --git a/src/expo-updates/expo-updates.service.ts b/src/expo-updates/expo-updates.service.ts index cf0b021..00942b7 100644 --- a/src/expo-updates/expo-updates.service.ts +++ b/src/expo-updates/expo-updates.service.ts @@ -177,11 +177,12 @@ export class ExpoUpdatesService { responseType: 'arraybuffer', timeout: 30000, }); - const hash = crypto.createHash('sha256').update(response.data).digest('base64url'); + const hash = crypto.createHash('sha256').update(Buffer.from(response.data)).digest('base64url'); // 缓存 hash this.hashCache.set(cacheKey, { hash, timestamp: Date.now() }); + logger.debug(`Calculated hash for ${url}: ${hash}`); return hash; } catch (error) { logger.error(`Failed to calculate hash for ${url}: ${error.message}`); @@ -202,23 +203,31 @@ export class ExpoUpdatesService { } const assetList = Array.from(uniqueAssets.values()); + logger.info(`Building ${assetList.length} unique assets`); - // 并行计算所有 asset 的 hash - const results = await Promise.all( - assetList.map(async (asset) => { - const url = baseUrl + asset.path; - const key = asset.path.split('/').pop() || ''; // 使用文件名作为 key - const hash = await this.calculateFileHash(url); - - return { - hash, - key, - contentType: this.getContentType(asset.ext), - fileExtension: `.${asset.ext}`, - url, - }; - }) - ); + // 分批并行计算(每批10个,避免并发过多) + const batchSize = 10; + const results: AssetMetadata[] = []; + + for (let i = 0; i < assetList.length; i += batchSize) { + const batch = assetList.slice(i, i + batchSize); + const batchResults = await Promise.all( + batch.map(async (asset) => { + const url = baseUrl + asset.path; + const key = asset.path.split('/').pop() || ''; // 使用文件名作为 key + const hash = await this.calculateFileHash(url); + + return { + hash, + key, + contentType: this.getContentType(asset.ext), + fileExtension: `.${asset.ext}`, + url, + }; + }) + ); + results.push(...batchResults); + } return results; }