UNPKG

@livestore/sqlite-wasm

Version:

55 lines 2.61 kB
import * as VFS from '@livestore/wa-sqlite/src/VFS.js'; const SECTOR_SIZE = 4096; const HEADER_MAX_PATH_SIZE = 512; const HEADER_FLAGS_SIZE = 4; const HEADER_DIGEST_SIZE = 8; const HEADER_CORPUS_SIZE = HEADER_MAX_PATH_SIZE + HEADER_FLAGS_SIZE; const HEADER_OFFSET_FLAGS = HEADER_MAX_PATH_SIZE; const HEADER_OFFSET_DIGEST = HEADER_CORPUS_SIZE; export const HEADER_OFFSET_DATA = SECTOR_SIZE; const PERSISTENT_FILE_TYPES = VFS.SQLITE_OPEN_MAIN_DB | VFS.SQLITE_OPEN_MAIN_JOURNAL | VFS.SQLITE_OPEN_SUPER_JOURNAL | VFS.SQLITE_OPEN_WAL; const textDecoder = new TextDecoder(); export const decodeSAHPoolFilename = async (file) => { // Read the path and digest of the path from the file. const corpus = new Uint8Array(await file.slice(0, HEADER_CORPUS_SIZE).arrayBuffer()); // Delete files not expected to be present. const dataView = new DataView(corpus.buffer, corpus.byteOffset); const flags = dataView.getUint32(HEADER_OFFSET_FLAGS); if (corpus[0] && (flags & VFS.SQLITE_OPEN_DELETEONCLOSE || (flags & PERSISTENT_FILE_TYPES) === 0)) { console.warn(`Remove file with unexpected flags ${flags.toString(16)}`); return ''; } const fileDigest = new Uint32Array(await file.slice(HEADER_OFFSET_DIGEST, HEADER_OFFSET_DIGEST + HEADER_DIGEST_SIZE).arrayBuffer()); // Verify the digest. const computedDigest = computeDigest(corpus); if (fileDigest.every((value, i) => value === computedDigest[i])) { // Good digest. Decode the null-terminated path string. const pathBytes = corpus.indexOf(0); if (pathBytes === 0) { // Note: We can't truncate the file here as File objects are read-only // console.warn('Unassociated file detected') } return textDecoder.decode(corpus.subarray(0, pathBytes)); } else { // Bad digest. Repair this header. console.warn('Disassociating file with bad digest.'); return ''; } }; const computeDigest = (corpus) => { if (!corpus[0]) { // Optimization for deleted file. return new Uint32Array([0xfe_cc_5f_80, 0xac_ce_c0_37]); } let h1 = 0xde_ad_be_ef; let h2 = 0x41_c6_ce_57; for (const value of corpus) { h1 = Math.imul(h1 ^ value, 2_654_435_761); h2 = Math.imul(h2 ^ value, 1_597_334_677); } h1 = Math.imul(h1 ^ (h1 >>> 16), 2_246_822_507) ^ Math.imul(h2 ^ (h2 >>> 13), 3_266_489_909); h2 = Math.imul(h2 ^ (h2 >>> 16), 2_246_822_507) ^ Math.imul(h1 ^ (h1 >>> 13), 3_266_489_909); return new Uint32Array([h1 >>> 0, h2 >>> 0]); }; //# sourceMappingURL=opfs-sah-pool.js.map