Experiment to rebuild Diffuse using web applets.

fix: s3 issue and add demo page

Changed files
+85 -4
src
pages
demo
s3-tracks
input
scripts
input
+59
src/pages/demo/s3-tracks/index.astro
··· 1 + --- 2 + import Page from "../../../layouts/page.astro"; 3 + import "@styles/pico.scss"; 4 + --- 5 + 6 + <Page title="Diffuse"> 7 + <main class="container"> 8 + <h1>Add sample S3 bucket to inputs</h1> 9 + 10 + <p> 11 + Clicking the button below will add some sample music, which you can then play using the 12 + various <a href="/#themes" target="_blank">themes, abstractions and constituents</a>. 13 + 14 + <br /> 15 + <br /> 16 + 17 + <button>Add sample content</button> 18 + </p> 19 + </main> 20 + 21 + <style is:global> 22 + iframe { 23 + display: none; 24 + } 25 + </style> 26 + 27 + <script> 28 + import { applet } from "@scripts/applet/common"; 29 + import type { Bucket } from "@scripts/input/s3/types"; 30 + 31 + document.querySelector("button")?.addEventListener("click", clickHandler); 32 + 33 + async function clickHandler() { 34 + const p = document.body.querySelector("p"); 35 + const s3 = await applet("/input/s3"); 36 + 37 + // Credentials are read-only, no worries. 38 + const bucket: Bucket = { 39 + accessKey: "AKIA6OQ3EVMAXVCDQH6B", 40 + bucketName: "ongaku-ryoho-demo", 41 + host: "s3.amazonaws.com", 42 + path: "/", 43 + region: "us-east-1", 44 + secretKey: "gHOBGGG55iw4kDCn7cZTIa5SP4YZzDFDsBqBab82", 45 + }; 46 + 47 + await s3.sendAction("mount", bucket, { timeoutDuration: 60000 }); 48 + 49 + // Finished 50 + if (p) 51 + p.innerHTML = ` 52 + Content added! Try it out using the <a href="/constituent/blur/artwork-controller/" target="_blank">blur artwork controller</a> or any other <a href="/#themes" target="_blank">theme, abstraction or constituent</a>. 53 + `; 54 + 55 + // Additionally process inputs automatically 56 + applet("/orchestrator/process-tracks"); 57 + } 58 + </script> 59 + </Page>
+12
src/pages/index.astro
··· 65 65 { url: "processor/metadata/", title: "Metadata retrieval" }, 66 66 { url: "processor/search/", title: "Search" }, 67 67 ]; 68 + 69 + // Demos 70 + const demos = [{ url: "demo/s3-tracks/", title: "Add sample S3 music" }]; 68 71 --- 69 72 70 73 <Page title="Diffuse"> ··· 199 202 200 203 <Applet title="Supplements" list={[]}>Additional applets, such as scrobblers.</Applet> 201 204 </div> 205 + </section> 206 + 207 + <!-- DEMOS --> 208 + <section> 209 + <h2 id="demos">Demos</h2> 210 + 211 + <p>Just some utility web pages to help demo the system.</p> 212 + 213 + <List items={demos} /> 202 214 </section> 203 215 204 216 <!-- BUILD YOUR OWN -->
+13 -3
src/pages/input/s3/_applet.astro
··· 37 37 </style> 38 38 39 39 <script> 40 + import type { Track } from "@applets/core/types.d.ts"; 40 41 import type { Tasks } from "@scripts/input/s3/worker"; 41 - import type { Track } from "@applets/core/types.d.ts"; 42 + import type { Bucket } from "@scripts/input/s3/types"; 42 43 import { register } from "@scripts/applet/common"; 43 - import { endpoint, inIframe, SharedWorker, transfer } from "@scripts/common"; 44 + import { endpoint, inIframe, transfer } from "@scripts/common"; 44 45 import manifest from "./_manifest.json"; 46 + import { bucketId, loadBuckets, saveBuckets } from "@scripts/input/s3/common"; 45 47 46 48 //////////////////////////////////////////// 47 49 // SETUP ··· 80 82 return await worker.resolve(args); 81 83 }; 82 84 83 - const mount = async () => {}; 85 + const mount = async (bucket: Bucket) => { 86 + // NOTE: This may, or may not, be a good idea. 87 + const buckets = await loadBuckets(); 88 + const id = bucketId(bucket); 89 + 90 + if (!buckets[id]) { 91 + await saveBuckets({ ...buckets, [bucketId(bucket)]: bucket }); 92 + } 93 + }; 84 94 85 95 const unmount = async () => {}; 86 96
+1 -1
src/scripts/input/s3/worker.ts
··· 96 96 return list 97 97 .filter((l) => isAudioFile(l.key)) 98 98 .map((l) => { 99 - const cachedTrack = cache[bid][l.key]; 99 + const cachedTrack = cache[bid]?.[l.key]; 100 100 101 101 const id = cachedTrack?.id || crypto.randomUUID(); 102 102 const stats = cachedTrack?.stats;