deno-musings/transpiler/walker.html

150 lines
4.2 KiB
HTML

<html>
<head></head>
<body>
<button id="open">open</button>
<script type="module">
import { openDB } from "https://esm.sh/idb@8.0.0";
async function initDB() {
const db = await openDB('file-handles', 1, {
upgrade(db) {
if (!db.objectStoreNames.contains('handles')) {
db.createObjectStore('handles');
}
},
});
return db;
}
async function storeHandle(handle) {
const db = await initDB();
await db.put('handles', handle, 'directory');
}
async function getStoredHandle() {
const db = await initDB();
const handle = await db.get('handles', 'directory');
return handle;
}
async function verifyPermission(handle, readWrite) {
const options = {};
if (readWrite) {
options.mode = 'readwrite';
}
if ((await handle.queryPermission(options)) === 'granted') {
return true;
}
if ((await handle.requestPermission(options)) === 'granted') {
return true;
}
return false;
}
async function init() {
let handle = await getStoredHandle();
if (handle) {
const hasPermission = await verifyPermission(handle, true);
if (!hasPermission) {
handle = null;
}
}
if (!handle) {
handle = await globalThis.showDirectoryPicker();
await storeHandle(handle);
}
console.log('Directory handle:', handle);
return handle;
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// Function to walk through the directory and update file handles
async function updateFileHandles(dirHandle, extension, path = "", map) {
for await (const entry of dirHandle.values()) {
if (entry.kind === 'file' && entry.name.endsWith(extension)) {
const file = await entry.getFile();
const fullPath = path + entry.name;
if (!map.has(dirHandle)) {
map.set(dirHandle, new Set());
}
map.get(dirHandle).add(fullPath);
} else if (entry.kind === 'directory') {
await updateFileHandles(entry, extension, path + entry.name + "/", map); // Recursively check subdirectories
}
}
}
// Function to check modified dates of known file handles
async function checkModifiedDates(map, date) {
const focusFiles = [];
for (const [dirHandle, filenames] of map.entries()) {
for (const filename of filenames) {
try
{
const fileHandle = await dirHandle.getFileHandle(filename.split('/').pop());
const file = await fileHandle.getFile();
if (file.lastModified > date.getTime()) {
focusFiles.push({ file, fullPath: filename });
}
}
catch(e)
{
console.log("file deleted?", filename);
filenames.delete(filename);
}
}
}
return focusFiles;
}
// Main function to set up the intervals
async function main() {
//const dirHandle = await window.showDirectoryPicker();
const dirHandle = await init();
const extension = '.html'; // Change this to the desired file extension
let fileHandlesMap = new Map();
let lastCheckTime = new Date().getTime();
const CoarseCheck = async () => {
console.log("=========== coarse check ==================");
fileHandlesMap = new Map();
await updateFileHandles(dirHandle, extension, "", fileHandlesMap);
};
const FineCheck =async()=>{
console.log("---- fine check ----")
const focusFiles = await checkModifiedDates(fileHandlesMap, new Date(lastCheckTime));
if (focusFiles.length) {
console.log("Updated files:", focusFiles);
// Open the updated files or handle them as needed
}
lastCheckTime = new Date().getTime();
}
let count = 0;
const Loop =async()=>
{
if (count === 0) {
await CoarseCheck();
}
await FineCheck();
count += 1;
count %= 10;
setTimeout(Loop, 1000);
}
Loop();
}
document.getElementById("open").addEventListener("click", main);
</script>
</body>
</html>