DEV Community

Rahul
Rahul

Posted on Fully Autonomous

CCIL Test Studio source 13: src/files.js

import { uid, timestamp } from './store.jsx';

const supported = ['pdf', 'docx', 'txt', 'md', 'sql'];
function deadline(promise, message, milliseconds = 10000) {
  return new Promise((resolve, reject) => {
    const timer = setTimeout(() => reject(new Error(message)), milliseconds);
    promise.then(value => { clearTimeout(timer); resolve(value); }, error => { clearTimeout(timer); reject(error); });
  });
}
function readFile(file) {
  if (typeof FileReader === 'undefined') return file.arrayBuffer();
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result);
    reader.onerror = () => reject(new Error('Could not read this file. Select it again.'));
    reader.onabort = () => reject(new Error('File reading was interrupted. Select it again.'));
    reader.readAsArrayBuffer(file);
  });
}
function openVault() {
  return new Promise((resolve, reject) => {
    let settled = false;
    const fail = message => { if (!settled) { settled = true; clearTimeout(timer); reject(new Error(message)); } };
    const timer = setTimeout(() => fail('File storage did not respond. Please try again.'), 10000);
    const request = indexedDB.open('ccil-local-files', 1);
    request.onupgradeneeded = () => { if (!request.result.objectStoreNames.contains('files')) request.result.createObjectStore('files'); };
    request.onsuccess = () => { if (settled) request.result.close(); else { settled = true; clearTimeout(timer); resolve(request.result); } };
    request.onerror = () => fail('File storage is unavailable. Please select the file again.');
    request.onblocked = () => fail('File storage is busy. Close other studio tabs and try again.');
  });
}
async function vault(mode, action) {
  const db = await openVault();
  try { await deadline(new Promise((resolve, reject) => { const transaction = db.transaction('files', mode); action(transaction.objectStore('files')); transaction.oncomplete = resolve; transaction.onerror = () => reject(new Error('Could not save this file. Please try again.')); transaction.onabort = () => reject(new Error('File saving was interrupted. Please try again.')); }), 'File saving did not finish. Please try again.'); } finally { db.close(); }
}
export async function stageFile(file, scope) {
  const extension = file.name.split('.').pop().toLowerCase();
  if (!supported.includes(extension)) throw new Error(`${file.name}: use PDF, DOCX, TXT, Markdown, or SQL.`);
  if (file.size > 50 * 1024 * 1024) throw new Error(`${file.name}: maximum file size is 50 MB.`);
  if (!file.size) throw new Error(`${file.name}: the file is empty.`);
  const id = uid('source');
  const buffer = await deadline(readFile(file), 'File reading did not finish. Please select it again.');
  const digest = await crypto.subtle.digest('SHA-256', buffer);
  const checksum = Array.from(new Uint8Array(digest)).map(b => b.toString(16).padStart(2, '0')).join('');
  const text = ['txt', 'md', 'sql'].includes(extension) ? new TextDecoder().decode(buffer).slice(0, 150000) : '';
  if (['txt', 'md', 'sql'].includes(extension) && !text.trim()) throw new Error(`${file.name}: no usable text was found.`);
  await vault('readwrite', store => store.put(file, id));
  return { id, name: file.name, kind: extension.toUpperCase(), size: `${(file.size / 1024).toFixed(1)} KB`, bytes: file.size, checksum, excerpt: text, revision: 1, status: 'Staged', synthetic: false, date: timestamp(), ...scope };
}
export async function openOriginal(document) {
  const db = await openVault();
  try {
    const file = await new Promise((resolve, reject) => { const request = db.transaction('files', 'readonly').objectStore('files').get(document.id); request.onsuccess = () => resolve(request.result); request.onerror = reject; });
    if (!file) throw new Error('The source file is unavailable in this browser. Reattach the original file.');
    const url = URL.createObjectURL(file); const a = window.document.createElement('a'); a.href = url; a.download = document.name; a.click(); setTimeout(() => URL.revokeObjectURL(url), 1000);
  } finally { db.close(); }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)