Experiment to rebuild Diffuse using web applets.
1<script>
2 import * as IDB from "idb-keyval";
3 import { applets } from "@web-applets/sdk";
4 import { type FileSystemDirectoryHandle, showDirectoryPicker } from "native-file-system-adapter";
5
6 import type { OutputGetter, OutputSetter } from "@applets/core/types.d.ts";
7
8 ////////////////////////////////////////////
9 // SETUP
10 ////////////////////////////////////////////
11 const IDB_PREFIX = "@applets/output/native-fs";
12 const IDB_DEVICE_KEY = `${IDB_PREFIX}/device`;
13
14 const context = applets.register();
15
16 ////////////////////////////////////////////
17 // ACTIONS
18 ////////////////////////////////////////////
19 const get: OutputGetter = async ({ name }) => {
20 const handle: FileSystemDirectoryHandle | null = (await IDB.get(IDB_DEVICE_KEY)) ?? null;
21 if (!handle) throw new Error("Storage not configured properly, handle not found.");
22
23 try {
24 const fileHandle = await handle.getFileHandle(name);
25 const file = await fileHandle.getFile();
26 const data = await file.bytes();
27 return data;
28 } catch (err) {
29 return undefined;
30 }
31 };
32
33 const put: OutputSetter = async ({ data, name }) => {
34 const handle: FileSystemDirectoryHandle | null = (await IDB.get(IDB_DEVICE_KEY)) ?? null;
35 if (!handle) throw new Error("Storage not configured properly, handle not found.");
36 const fileHandle = await handle.getFileHandle(name, { create: true });
37 const stream = await fileHandle.createWritable();
38 await stream.write(data);
39 await stream.close();
40 };
41
42 const mount = async () => {
43 const existingHandle = await IDB.get(IDB_DEVICE_KEY);
44 if (!existingHandle) {
45 const directoryHandle = await showDirectoryPicker();
46 await IDB.set(IDB_DEVICE_KEY, directoryHandle);
47 await directoryHandle.requestPermission({ mode: "readwrite" });
48 }
49 };
50
51 const unmount = async () => {
52 try {
53 await IDB.del(IDB_DEVICE_KEY);
54 } catch (err) {}
55 };
56
57 context.setActionHandler("get", get);
58 context.setActionHandler("put", put);
59 context.setActionHandler("mount", mount);
60 context.setActionHandler("unmount", unmount);
61</script>