Experiment to rebuild Diffuse using web applets.
1import type { ManagedOutput, Track } from "@applets/core/types";
2import type { BroadcastedApplet } from "@scripts/applet/common";
3
4export const INITIAL_MANAGED_OUTPUT: ManagedOutput = {
5 tracks: {
6 cacheId: crypto.randomUUID(),
7 state: "loading",
8 collection: [],
9 },
10};
11
12export function outputManager<DataType>(args: {
13 context: BroadcastedApplet<DataType>;
14 /* Indicate if the initial data loader may proceed. */
15 init?: () => Promise<boolean>;
16 tracks: {
17 get(): Promise<Track[]>;
18 put(tracks: Track[]): Promise<void>;
19 };
20}) {
21 const { context } = args;
22
23 // Initial data loader
24 async function load() {
25 await context.settled();
26
27 if (!context.isMainInstance()) return;
28 if (args.init && (await args.init()) === false) return;
29
30 const collection = await tracks();
31
32 context.data = {
33 ...context.data,
34 tracks: {
35 cacheId: crypto.randomUUID(),
36 state: "loaded",
37 collection,
38 },
39 };
40 }
41
42 load();
43
44 async function tracks(): Promise<Track[]>;
45 async function tracks(tracks: Track[]): Promise<void>;
46 async function tracks(tracks?: Track[]): Promise<Track[] | void> {
47 if (tracks) {
48 // PUT
49 context.data = {
50 ...context.data,
51 tracks: {
52 cacheId: crypto.randomUUID(),
53 state: "loaded",
54 collection: tracks,
55 },
56 };
57
58 await args.tracks.put(tracks);
59 } else {
60 // GET
61 return await args.tracks.get();
62 }
63 }
64
65 return {
66 load,
67 tracks,
68 };
69}