Experiment to rebuild Diffuse using web applets.
at s3 98 lines 2.6 kB view raw
1<script> 2 import { applets } from "@web-applets/sdk"; 3 4 import type { Output, Track, TrackStats, TrackTags } from "@applets/core/types.d.ts"; 5 import { applet, waitUntilAppletIsReady } from "@scripts/theme"; 6 7 //////////////////////////////////////////// 8 // SETUP 9 //////////////////////////////////////////// 10 const context = applets.register<{ ready: boolean }>(); 11 12 // Initial data 13 context.data = { 14 ready: false, 15 }; 16 17 // Applet connections 18 const configurator = { 19 input: await applet("../../configurator/input", { context: self.top || self.parent }), 20 }; 21 22 const orchestrator = { 23 output: await applet<Output>("../../orchestrator/output-management", { 24 context: self.parent, 25 }), 26 }; 27 28 const processor = { 29 metadataFetcher: await applet("../../processor/metadata-fetcher", { context: self.parent }), 30 }; 31 32 // 🚀 33 process(); 34 35 //////////////////////////////////////////// 36 // ACTIONS 37 //////////////////////////////////////////// 38 context.setActionHandler("process", process); 39 40 async function process() { 41 await waitUntilAppletIsReady(configurator.input); 42 43 const cachedTracks = orchestrator.output.data.tracks; 44 const tracks = await configurator.input.sendAction<Track[]>("list", cachedTracks, { 45 timeoutDuration: 60000 * 60 * 24, 46 }); 47 48 // Process 49 const tracksWithMetadata = await tracks.reduce( 50 async (promise: Promise<Track[]>, track: Track) => { 51 const acc = await promise; 52 53 if (track.tags) return [...acc, track]; 54 55 const getURL = await configurator.input.sendAction<string | undefined>( 56 "resolve", 57 { method: "GET", uri: track.uri }, 58 { 59 timeoutDuration: 60000, 60 }, 61 ); 62 63 if (!getURL) return acc; 64 65 // TODO: Do we need to pass the HEAD URL too? 66 const meta = await processor.metadataFetcher.sendAction("extract", getURL, { 67 timeoutDuration: 60000, 68 }); 69 70 const stats: TrackStats = { 71 duration: meta.format.duration, 72 }; 73 74 const tags: TrackTags = { 75 album: meta.common.album, 76 artist: meta.common.artist, 77 title: meta.common.title, 78 }; 79 80 return [...acc, { ...track, stats, tags }]; 81 }, 82 Promise.resolve([]), 83 ); 84 85 // Save 86 await orchestrator.output.sendAction("tracks", tracksWithMetadata, { 87 timeoutDuration: 60000 * 2, 88 }); 89 90 // Log 91 console.log("🪵 Processing completed"); 92 } 93 94 //////////////////////////////////////////// 95 // 🚦 96 //////////////////////////////////////////// 97 context.data = { ready: true }; 98</script>