A music player that connects to your cloud/distributed storage.
at v4 2.7 kB view raw
1import { BroadcastableDiffuseElement, query } from "@common/element.js"; 2import { untracked } from "@common/signal.js"; 3 4/** 5 * @import {Track} from "@definitions/types.d.ts" 6 * @import {ProxiedActions} from "@common/worker.d.ts" 7 * @import {InputElement} from "@components/input/types.d.ts" 8 * @import {OutputElement} from "@components/output/types.d.ts" 9 * 10 * @import {Actions} from "./types.d.ts" 11 */ 12 13//////////////////////////////////////////// 14// ELEMENT 15//////////////////////////////////////////// 16 17/** 18 * Update the queue pool whenever 19 * tracks have been loaded, 20 * or the tracks collection changes. 21 */ 22class QueueTracksOrchestrator extends BroadcastableDiffuseElement { 23 static NAME = "diffuse/orchestrator/queue-tracks"; 24 static WORKER_URL = "components/orchestrator/queue-tracks/worker.js"; 25 26 /** @type {ProxiedActions<Actions>} */ 27 #proxy; 28 29 constructor() { 30 super(); 31 this.#proxy = this.workerProxy({ 32 forceNew: { 33 dependencies: { 34 input: true, 35 }, 36 }, 37 }); 38 } 39 40 // LIFECYCLE 41 42 /** 43 * @override 44 */ 45 async connectedCallback() { 46 // Broadcast if needed 47 if (this.hasAttribute("group")) { 48 this.broadcast(this.nameWithGroup, {}); 49 } 50 51 // Super 52 super.connectedCallback(); 53 54 /** @type {InputElement} */ 55 const input = query(this, "input-selector"); 56 57 /** @type {OutputElement<Track[]>} */ 58 const output = query(this, "output-selector"); 59 60 /** @type {import("@components/engine/queue/element.js").CLASS} */ 61 const queue = query(this, "queue-engine-selector"); 62 63 // Assign to self 64 this.input = input; 65 this.output = output; 66 this.queue = queue; 67 68 // When defined 69 await customElements.whenDefined(this.input.localName); 70 await customElements.whenDefined(this.output.localName); 71 await customElements.whenDefined(this.queue.localName); 72 73 // Watch tracks collection 74 this.effect(() => { 75 const tracks = output.tracks.collection(); 76 77 this.isLeader().then((isLeader) => { 78 if (!isLeader) return; 79 untracked(() => this.#proxy.poolAvailable(tracks)); 80 }); 81 }); 82 83 // 🌸 84 } 85 86 // WORKERS 87 88 /** 89 * @override 90 */ 91 dependencies() { 92 if (!this.input) throw new Error("Input element not defined yet"); 93 if (!this.queue) throw new Error("Queue element not defined yet"); 94 95 return { 96 input: this.input, 97 queue: this.queue, 98 }; 99 } 100} 101 102export default QueueTracksOrchestrator; 103 104//////////////////////////////////////////// 105// REGISTER 106//////////////////////////////////////////// 107 108export const CLASS = QueueTracksOrchestrator; 109export const NAME = "do-queue-tracks"; 110 111customElements.define(NAME, QueueTracksOrchestrator);