18 lines
1.5 KiB
TypeScript
18 lines
1.5 KiB
TypeScript
/**
|
|
* 完整导入源的增量 SHA256:有界 Blob 分块读取,不把全文件放进 UI ArrayBuffer。
|
|
* 摘要是源完整性/稳定身份依据,不证明该文件有权限、schema 正确或所有记录已加入画布。
|
|
*/
|
|
import { fault } from '../canvas-core/values.ts';
|
|
import {createSha256} from './sha256.ts';
|
|
/** Complete-source SHA-256, with bounded chunk memory and cooperative fallback scheduling. */
|
|
/** 默认64KiB分块(配置上限4MiB),每块读前/读后检查取消,并在块间合作让出。 */
|
|
export async function importSourceDigest(bytes:Blob,signal?:AbortSignal,options:{chunkBytes?:number;yieldTask?:()=>Promise<void>}={}):Promise<string>{
|
|
const chunk=options.chunkBytes??64*1024,yieldTask=options.yieldTask??(()=>new Promise<void>(resolve=>setTimeout(resolve,0)));
|
|
if(!(bytes instanceof Blob)||!Number.isSafeInteger(chunk)||chunk<1||chunk>4*1024*1024)throw fault('invalid_digest_input');
|
|
/** 读/计算/让出边界统一检查 signal;异步读取即使无法中止,迟到字节也不再参与有效结果。 */
|
|
const check=()=>{if(signal?.aborted)throw fault('import_aborted');};check();const hash=createSha256();
|
|
// 更新增量状态后释放对本块的局部引用;空文件直接 hex 得到标准空输入摘要。
|
|
for(let cursor=0;cursor<bytes.size;cursor+=chunk){check();const part=await bytes.slice(cursor,cursor+chunk).arrayBuffer();check();hash.update(new Uint8Array(part));if(cursor+chunk<bytes.size){await yieldTask();check();}}
|
|
check();return hash.hex();
|
|
}
|