121 lines
2.8 KiB
JavaScript
121 lines
2.8 KiB
JavaScript
const root = await navigator.storage?.getDirectory();
|
|
|
|
function resolvePath(path) {
|
|
if (!path) {
|
|
return [];
|
|
} else if (typeof path === 'string') {
|
|
path = path.trim();
|
|
while (path.charAt(0) === '/') {
|
|
path = path.substring(1);
|
|
}
|
|
return path.length ? path.split('/') : [];
|
|
} else if (Array.isArray(path)) {
|
|
return path;
|
|
} else {
|
|
throw "invalid path value";
|
|
}
|
|
}
|
|
|
|
export async function dirHandle(path, options = { create: true }) {
|
|
path = resolvePath(path);
|
|
if (path.length === 0) {
|
|
return root;
|
|
}
|
|
let dir = root;
|
|
for (let tok of path) {
|
|
try {
|
|
dir = await dir.getDirectoryHandle(tok, options);
|
|
} catch (error) {
|
|
if (options.report) {
|
|
console.log({ path, error });
|
|
}
|
|
return undefined;
|
|
}
|
|
}
|
|
return dir;
|
|
}
|
|
|
|
export async function fileHandle(path, options = { create: false }) {
|
|
path = resolvePath(path);
|
|
if (path.length === 0) {
|
|
return undefined;
|
|
}
|
|
let target = path.pop();
|
|
let dir = await dirHandle(path);
|
|
return dir.getFileHandle(target, options);
|
|
}
|
|
|
|
export async function clear() {
|
|
for await (let name of root.keys()) {
|
|
await root.removeEntry(name, { recursive: true });
|
|
}
|
|
}
|
|
|
|
export async function remove(path) {
|
|
path = resolvePath(path);
|
|
if (path.length === 0) {
|
|
return clear();
|
|
}
|
|
let target = path.pop();
|
|
let dir = await dirHandle(path);
|
|
console.log({ dir, target });
|
|
await dir.removeEntry(target, { recursive: true });
|
|
}
|
|
|
|
export async function entries(path) {
|
|
return (await dirHandle(path)).entries();
|
|
}
|
|
|
|
export async function values(path) {
|
|
return (await dirHandle(path)).values();
|
|
}
|
|
|
|
export async function keys(path) {
|
|
return (await dirHandle(path)).keys();
|
|
}
|
|
|
|
export async function tree(path) {
|
|
path = resolvePath(path);
|
|
let dir = await dirHandle(path);
|
|
return treeFrom(dir, path, []);
|
|
}
|
|
|
|
async function treeFrom(dir, path, list) {
|
|
let entries = await dir.entries()
|
|
for await (let [ name, handle ] of entries) {
|
|
path.push(name);
|
|
if (handle.kind === 'directory') {
|
|
await treeFrom(handle, path, list);
|
|
} else {
|
|
list.push(path.join('/'));
|
|
}
|
|
path.pop();
|
|
}
|
|
return list;
|
|
}
|
|
|
|
export async function getText(path) {
|
|
let handle = await fileHandle(path);
|
|
let file = await handle.getFile();
|
|
return file.text();
|
|
}
|
|
|
|
export async function putText(path, text) {
|
|
let handle = await fileHandle(path, { create: true });
|
|
let stream = await handle.createWritable();
|
|
await stream.write(text);
|
|
return stream.close();
|
|
}
|
|
|
|
export const OPFS = {
|
|
dirHandle,
|
|
fileHandle,
|
|
entries,
|
|
keys,
|
|
values,
|
|
tree,
|
|
clear,
|
|
remove,
|
|
getText,
|
|
putText
|
|
};
|