add opfs and api link to it

This commit is contained in:
Stewart Allen 2026-01-29 16:03:00 -05:00
commit c7a6fe1920
2 changed files with 124 additions and 0 deletions

View file

@ -40,6 +40,8 @@ import { visuals } from './visuals.js';
import { widgets } from './widgets.js'; import { widgets } from './widgets.js';
import { workspace } from './workspace.js'; import { workspace } from './workspace.js';
import { OPFS } from '../../moto/opfs.js';
// environment setup // environment setup
let LOC = self.location, let LOC = self.location,
EVENT = broker, EVENT = broker,
@ -228,6 +230,7 @@ export const api = {
onkey(fn) { onkey(fn) {
api.feature.on_key2.push(fn); api.feature.on_key2.push(fn);
}, },
opfs: OPFS,
platform, platform,
process: processModule, process: processModule,
sdb: dataLocal, sdb: dataLocal,

121
src/moto/opfs.js Normal file
View file

@ -0,0 +1,121 @@
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
};