Files
Endoleap/src/lib/canvas-runtime/digest-worker-source.ts
T

30 lines
2.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 专用 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()});
}