-
Notifications
You must be signed in to change notification settings - Fork 275
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support mounting local directories in the browser via Filesystem API #196
Comments
The File System Access API can read local files and directories, and even exposes a // const dirHandle = await window.showDirectoryPicker();
(async function() {
const fileHandle = await window.showOpenFilePicker();
const dirHandle = await window.showDirectoryPicker();
var blob = new Blob([
`
self.onmessage = function(e) {
console.log(e.data);
};
// Rest of your worker code goes here.
`
], { type: "text/javascript" })
// Sync methods can only be used in web workers on https sites
var worker = new Worker(window.URL.createObjectURL(blob));
worker.onmessage = function(e) {
console.log("Received: " + e.data);
}
worker.postMessage(fileHandle);
worker.postMessage(dirHandle);
})() More about synchronous methods. Also, WHATWG Spec. I also found an Emscripten PR that proposes a |
A mapping of Emscripten concepts to FS API concepts:
|
Until we can support local filesystem as Emscripten FS, there could be a “refresh” button that brings all the files from local directory into Playground. It could stat them and load just the updated ones. There could be a “update every 1s” checkbox. it’s similar to the explorations in #19 |
Here’s some code from ChatGPT that could make a good starting point: —- Write a TypeScript function that uses the Filesystem API in the browser to read a file tree from the local filesystem into a JavaScript object. Each file name should be a key, its contents should be the value, and directories should be represented as nested objects. Parallelize up to 20 filesystem api operations. type FileTree = {
[fileName: string]: string | FileTree;
};
async function readFile(file: File): Promise<string> {
const text = await file.text();
return text;
}
const MAX_CONCURRENT_OPERATIONS = 20;
async function readDirectory(directory: any): Promise<FileTree> {
let result: FileTree = {};
let operations: Promise<any>[] = [];
for await (const entry of directory.values()) {
const operation = (async () => {
if (entry.kind === 'file') {
const file = await entry.getFile();
const text = await readFile(file);
result[entry.name] = text;
} else if (entry.kind === 'directory') {
const nestedDirectory = await entry.getDirectory();
result[entry.name] = await readDirectory(nestedDirectory);
}
})();
operations.push(operation);
// If we've hit the limit, wait for one to complete before starting a new one
if (operations.length >= MAX_CONCURRENT_OPERATIONS) {
await Promise.race(operations).then(() => {
operations = operations.filter(op => op !== operation);
});
}
}
// Wait for all operations to complete
await Promise.all(operations);
return result;
}
async function readFileTree(rootDirectory: any): Promise<FileTree> {
const fileTree = await readDirectory(rootDirectory);
return fileTree;
} Usage: async function main() {
try {
// Request a handle to the directory from the user
const rootDirectory = await window.showDirectoryPicker();
// Read the file tree
const fileTree = await readFileTree(rootDirectory);
// Do something with the file tree
console.log(fileTree);
} catch (error) {
console.error('Failed to read file tree:', error);
}
}
// Call the main function when the user clicks a button, for example
document.getElementById('readFilesButton').addEventListener('click', main); It could fit the |
Related Emscripten PR: Add support for read/seek on files in the native file system |
Basic support with manual "sync" button was added in #548 |
https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API would make for a 0 to WordPress dev env in 30 seconds. Also, debugging WordPress in Playground would get much easier.
The text was updated successfully, but these errors were encountered: