Experiment to rebuild Diffuse using web applets.
1<script>
2 import type { Actions } from "@scripts/output/native-fs/worker";
3 import * as IDB from "idb-keyval";
4 import type * as FSA from "wicg-file-system-access";
5
6 import type { ManagedOutput, Track } from "@applets/core/types";
7 import { register } from "@scripts/applet/common";
8 import { INITIAL_MANAGED_OUTPUT, outputManager } from "@scripts/output/common";
9 import { endpoint, SharedWorker, transfer } from "@scripts/common";
10 import { IDB_DEVICE_KEY } from "@scripts/output/native-fs/constants";
11 import manifest from "./_manifest.json";
12
13 ////////////////////////////////////////////
14 // SETUP
15 ////////////////////////////////////////////
16 const worker = endpoint<Actions>(
17 new SharedWorker(new URL("../../../scripts/output/native-fs/worker", import.meta.url), {
18 type: "module",
19 name: manifest.name,
20 }).port,
21 );
22
23 // Register applet
24 const context = register<ManagedOutput>();
25
26 // Initial state
27 context.data = INITIAL_MANAGED_OUTPUT;
28
29 // Output manager
30 const manager = outputManager({
31 context,
32
33 async init() {
34 return !!(await IDB.get(IDB_DEVICE_KEY));
35 },
36
37 tracks: {
38 async get() {
39 return worker.getTracks();
40 },
41
42 async put(tracks: Track[]) {
43 return worker.putTracks(transfer(tracks));
44 },
45 },
46 });
47
48 ////////////////////////////////////////////
49 // ACTIONS
50 ////////////////////////////////////////////
51 async function mount() {
52 if (!("showDirectoryPicker" in self)) {
53 throw new Error("[user] The File System Access API is not supported on this platform.");
54 }
55
56 const existingHandle = await IDB.get(IDB_DEVICE_KEY);
57 if (!existingHandle) {
58 const directoryHandle = await self.showDirectoryPicker();
59 await IDB.set(IDB_DEVICE_KEY, directoryHandle);
60 await directoryHandle.requestPermission({ mode: "readwrite" });
61 await manager.load();
62 }
63 }
64
65 async function unmount() {
66 try {
67 await IDB.del(IDB_DEVICE_KEY);
68 } catch (err) {}
69 }
70
71 context.setActionHandler("tracks", manager.tracks);
72
73 context.setActionHandler("mount", mount);
74 context.setActionHandler("unmount", unmount);
75</script>