30 lines
2.2 KiB
TypeScript
30 lines
2.2 KiB
TypeScript
/**
|
||
* 专用 Worker 内的摘要算法选择:小于等于64MiB可用原生 SubtleCrypto,较大文件分块流式 SHA。
|
||
* 整缓冲读取只允许发生在 Worker,取消由宿主终止该请求的 Worker;本函数不访问存储或文档。
|
||
*/
|
||
import {fault} from '../canvas-core/values.ts';
|
||
import {importSourceDigest} from './import-integrity.ts';
|
||
|
||
// Each of the browser pool's two active Workers admits at most 64 MiB; larger inputs stream.
|
||
/** 单任务 native 缓冲阈值,不是整个应用内存硬上限;总并发由外部 pool 决定。 */
|
||
export const nativeDigestByteLimit=64*1024*1024;
|
||
|
||
/** Dedicated Worker only: whole-buffer native hashing never moves onto the UI thread.
|
||
* The host still owns cancellation by terminating the request's Worker. */
|
||
/** 验证 Blob,SubtleCrypto 存在且大小 ≤64MiB 时读取整个 ArrayBuffer 做 SHA-256,否则流式计算。
|
||
* 原生读/算失败直接传播,不自动切到流式重试;注入 subtle 应遵守原生 digest 的 ArrayBuffer 合同。
|
||
* 本函数无 signal,取消靠宿主终止 Worker;代码本身不检测当前线程,Worker 限制由装配调用方遵守。
|
||
* 阈值只限制此输入的整缓冲分配,未计 Blob/原生算法内部内存及其它并发 Worker。 */
|
||
export async function digestWorkerSource(bytes:Blob,subtle:Pick<SubtleCrypto,'digest'>|null|undefined=globalThis.crypto?.subtle):Promise<string>{
|
||
if(!(bytes instanceof Blob))throw fault('invalid_digest_input');
|
||
// native digest 必须返回32字节;输出固定64字符十六进制,不接受变长响应。
|
||
if(subtle&&bytes.size<=nativeDigestByteLimit){
|
||
const input=await bytes.arrayBuffer(),digest=await subtle.digest('SHA-256',input);
|
||
if(digest.byteLength!==32)throw fault('invalid_digest_response');
|
||
return [...new Uint8Array(digest)].map(value=>value.toString(16).padStart(2,'0')).join('');
|
||
}
|
||
// 每块 1MiB,块间 yieldTask 仅完成一个 Promise 微任务,不保证 Worker 消息队列获得宏任务机会。
|
||
// UI fallback 用 importSourceDigest 默认定时器让出;不要把这里的微任务策略移作 UI 响应性承诺。
|
||
return importSourceDigest(bytes,undefined,{chunkBytes:1024*1024,yieldTask:()=>Promise.resolve()});
|
||
}
|