Skip to content
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

Deep file read #258

Open
WORMSS opened this issue Dec 21, 2020 · 1 comment
Open

Deep file read #258

WORMSS opened this issue Dec 21, 2020 · 1 comment

Comments

@WORMSS
Copy link

WORMSS commented Dec 21, 2020

My first test of this api, I hit wanting to get deep files immediately. Wanting to do something as simple as

/*
I've removed await/.then() for simplicity sake

[
    "./possibly/deep/directory/of/unknown/depth.json",
    "./possibly/deep/directory/of/unknown/depth/even/deeper.json",
    "./some/other/folder/somewhere.json"
]
*/
const filesToProcess = JSON.parse(    folderHandler.getFileHandler("processMe.json").getFile().text()    );

for ( const filePath of filesToProcess ) {
  // "./possibly/deep/directory/of/unknown/depth.json"
  const fileContent = JSON.parse(    folderHandler.getFileHandler(filePath).getFile().text()    );
  doSomethingWith(fileContent);
}

But I ended up having to use the code below,
This is with some caching map, because I didn't want to have to build up the promises of each of the ./possibly/deep/directory/of/unknown/ folder each and every time.

const cache: Map<string, FileSystemDirectoryHandle>= new Map();
const filesToProcess = JSON.parse(    folderHandler.getFileHandler("processMe.json").getFile().text()    );

for ( const filePath of filesToProcess ) {
  // "./possibly/deep/directory/of/unknown/depth.json"
  const fileContent = await readFile(files, rootFolderHandler, cache);
  doSomethingWith(fileContent);
}


async function readFile(
  path: string, // "./possibly/deep/directory/of/unknown/depth.json"
  rootFolderHandler: FileSystemDirectoryHandle,
  cache: Map<string, FileSystemDirectoryHandle>,
): Promise<any> {
  const { folderParts, filename } = getPathParts(path);
  const folder = await getFolder(rootFolderHandler, folderParts, cache);
  return loadJson(folder.getFileHandle(filename));
}

function getPathParts(path: string): PathParts {
  const folderParts = path.split(/\/|\\/g).filter((p) => p !== '.');
  const filename = folderParts.pop()!; // assuming the file name is the last part.
  return {
    folderParts,
    filename,
  };
}

async function getFolder(
  rootFolder: FileSystemDirectoryHandle,
  parts: string[],
  cache: Map<string, FileSystemDirectoryHandle>,
): Promise<FileSystemDirectoryHandle> {
  let currentFolder = rootFolder;
  for (let i = 0; i < parts.length; i++) {
    const folderName = parts[i];
    const path = parts.slice(0, i + 1).join('/');
    let pathFolder = cache.get(path);
    if (!pathFolder) {
      pathFolder = await currentFolder.getDirectoryHandle(folderName); // this is the part that builds up over and over
      cache.set(path, pathFolder); // cache so we don't have to do the await over and over again for same folders.
    }
    currentFolder = pathFolder;
  }
  return currentFolder;
}

function loadJson(file: Promise<FileSystemFileHandle>): Promise<any> {
  return file
    .then((fh) => fh.getFile())
    .then((f) => f.text())
    .then(JSON.parse);
}

This type of stuff would be great if it was just internal.
I am 100% confident javascript engine devs could do this stuff 1000% better than my late night botching attempt and I am sure I will not be the only person that would want to do this, especially if the first ever thing I wanted to do, needed it.

@WORMSS
Copy link
Author

WORMSS commented Dec 21, 2020

Just noticed this was a tiny bullet point on #22 but was buried at the end of the list of other things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant