A music player that connects to your cloud/distributed storage.
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

chore: no interactions with elements in constructors

+63 -60
-4
src/components/input/opensubsonic/element.js
··· 12 12 13 13 /** 14 14 * @implements {ProxiedActions<InputActions>} 15 - * @implements {PortProviderMethod} 16 15 */ 17 16 class OpensubsonicInput extends DiffuseElement { 18 17 static NAME = "diffuse/input/opensubsonic"; ··· 29 28 this.groupConsult = p.groupConsult; 30 29 this.list = p.list; 31 30 this.resolve = p.resolve; 32 - 33 - // Provide a channel to a worker 34 - this.port = portProvider(this.workerLink); 35 31 } 36 32 } 37 33
-4
src/components/input/s3/element.js
··· 12 12 13 13 /** 14 14 * @implements {ProxiedActions<InputActions>} 15 - * @implements {PortProviderMethod} 16 15 */ 17 16 class S3Input extends DiffuseElement { 18 17 static NAME = "diffuse/input/s3"; ··· 31 30 this.resolve = p.resolve; 32 31 33 32 this.demo = p.demo; 34 - 35 - // Provide a channel to the worker 36 - this.port = portProvider(this.workerLink); 37 33 } 38 34 } 39 35
+30 -19
src/components/orchestrator/process-tracks/element.js
··· 21 21 * from the assigned output element. 22 22 */ 23 23 class ProcessTracksOrchestrator extends DiffuseElement { 24 - #external; 24 + /** @type {Promise<{ input: ReturnType<portProvider>; metadataProcessor: ReturnType<portProvider> } | undefined> | undefined} */ 25 + #external = undefined; 25 26 #process; 26 27 27 28 static NAME = "diffuse/orchestrator/process-tracks"; ··· 30 31 constructor() { 31 32 super(); 32 33 33 - /** @type {InputElement} */ 34 - this.input = query(this, "input-selector"); 35 - 36 - /** @type {OutputElement<Track[]>} */ 37 - this.output = query(this, "output-selector"); 38 - 39 - /** @type {import("@components/processor/metadata/element.js").CLASS} */ 40 - this.metadataProcessor = query(this, "metadata-processor-selector"); 41 - 42 - // Create new workers specially for track processing 43 - this.#external = Promise.all([ 44 - customElements.whenDefined(this.input.localName), 45 - customElements.whenDefined(this.metadataProcessor.localName), 46 - ]).then(() => ({ 47 - input: portProvider(this.input.workerLink), 48 - metadataProcessor: portProvider(this.metadataProcessor.workerLink), 49 - })); 50 - 51 34 /** @type {ProxiedActions<Actions>} */ 52 35 const p = workerProxy(this.workerLink); 53 36 ··· 70 53 async connectedCallback() { 71 54 super.connectedCallback(); 72 55 56 + /** @type {InputElement} */ 57 + this.input = query(this, "input-selector"); 58 + 59 + /** @type {OutputElement<Track[]>} */ 60 + this.output = query(this, "output-selector"); 61 + 62 + /** @type {import("@components/processor/metadata/element.js").CLASS} */ 63 + this.metadataProcessor = query(this, "metadata-processor-selector"); 64 + 65 + // Create new workers specially for track processing 66 + this.#external = Promise.all([ 67 + customElements.whenDefined(this.input.localName), 68 + customElements.whenDefined(this.metadataProcessor.localName), 69 + ]).then(() => { 70 + if (!this.input) return undefined; 71 + if (!this.metadataProcessor) return undefined; 72 + 73 + return { 74 + input: portProvider(this.input.workerLink), 75 + metadataProcessor: portProvider(this.metadataProcessor.workerLink), 76 + }; 77 + }); 78 + 73 79 // Wait until defined 74 80 await customElements.whenDefined(this.output.localName); 75 81 76 82 // Process whenever tracks are initially loaded 77 83 this.effect(() => { 84 + if (!this.output) return; 85 + 78 86 const state = this.output.tracks.state(); 79 87 if (state !== "loaded") return; 80 88 ··· 86 94 87 95 async process() { 88 96 const ext = await this.#external; 97 + 98 + if (!ext) return; 99 + if (!this.output) return; 89 100 90 101 // Start 91 102 this.#isProcessing.value = true;
+12 -11
src/components/orchestrator/queue-audio/element.js
··· 17 17 * shift the queue if needed. 18 18 */ 19 19 class QueueAudioOrchestrator extends DiffuseElement { 20 - constructor() { 21 - super(); 20 + /** 21 + * @override 22 + */ 23 + async connectedCallback() { 24 + super.connectedCallback(); 22 25 23 26 /** @type {InputElement} */ 24 27 this.input = query(this, "input-selector"); ··· 28 31 29 32 /** @type {import("@components/engine/queue/element.js").CLASS} */ 30 33 this.queue = query(this, "queue-engine-selector"); 31 - } 32 - 33 - // LIFECYCLE 34 - 35 - /** 36 - * @override 37 - */ 38 - async connectedCallback() { 39 - super.connectedCallback(); 40 34 41 35 // Wait until defined 42 36 await customElements.whenDefined(this.audio.localName); ··· 51 45 // 🛠️ 52 46 53 47 async monitorActiveQueueItem() { 48 + if (!this.audio) return; 49 + if (!this.input) return; 50 + if (!this.queue) return; 51 + 54 52 const activeTrack = this.queue.now(); 55 53 const isPlaying = untracked(this.audio.isPlaying); 56 54 ··· 85 83 } 86 84 87 85 async monitorAudioEnd() { 86 + if (!this.audio) return; 87 + if (!this.queue) return; 88 + 88 89 if (this.audio.hasEnded()) await this.queue.shift(); 89 90 } 90 91 }
+11 -11
src/components/orchestrator/queue-tracks/element.js
··· 17 17 * or the tracks collection changes. 18 18 */ 19 19 class QueueTracksOrchestrator extends DiffuseElement { 20 - constructor() { 21 - super(); 20 + /** 21 + * @override 22 + */ 23 + async connectedCallback() { 24 + super.connectedCallback(); 22 25 23 26 /** @type {InputElement} */ 24 27 this.input = query(this, "input-selector"); ··· 28 31 29 32 /** @type {import("@components/engine/queue/element.js").CLASS} */ 30 33 this.queue = query(this, "queue-engine-selector"); 31 - } 32 - 33 - // LIFECYCLE 34 - 35 - /** 36 - * @override 37 - */ 38 - async connectedCallback() { 39 - super.connectedCallback(); 40 34 41 35 // When defined 42 36 await customElements.whenDefined(this.input.localName); ··· 44 38 45 39 // Watch tracks collection 46 40 this.effect(() => { 41 + if (!this.output) return; 42 + 47 43 const tracks = this.output.tracks.collection().filter((t) => 48 44 t.kind !== "placeholder" 49 45 ); ··· 58 54 * @param {Track[]} cachedTracks 59 55 */ 60 56 async poolAvailable(cachedTracks) { 57 + if (!this.input) return; 58 + if (!this.output) return; 59 + if (!this.queue) return; 60 + 61 61 const groups = await this.input.groupConsult(cachedTracks); 62 62 63 63 /** @type {Track[]} */
+10 -11
src/components/orchestrator/search-tracks/element.js
··· 16 16 * or the tracks collection changes. 17 17 */ 18 18 class SearchTracksOrchestrator extends DiffuseElement { 19 - constructor() { 20 - super(); 19 + /** 20 + * @override 21 + */ 22 + async connectedCallback() { 23 + super.connectedCallback(); 21 24 22 25 /** @type {InputElement} */ 23 26 this.input = query(this, "input-selector"); ··· 27 30 28 31 /** @type {import("@components/processor/search/element.js").CLASS} */ 29 32 this.search = query(this, "search-processor-selector"); 30 - } 31 - 32 - // LIFECYCLE 33 - 34 - /** 35 - * @override 36 - */ 37 - async connectedCallback() { 38 - super.connectedCallback(); 39 33 40 34 // When defined 41 35 await customElements.whenDefined(this.output.localName); 42 36 43 37 // Watch tracks collection 44 38 this.effect(() => { 39 + if (!this.output) return; 40 + 45 41 const tracks = this.output.tracks.collection().filter((t) => 46 42 t.kind !== "placeholder" 47 43 ); ··· 56 52 * @param {Track[]} cachedTracks 57 53 */ 58 54 async supplyAvailable(cachedTracks) { 55 + if (!this.input) return; 56 + if (!this.search) return; 57 + 59 58 const groups = await this.input.groupConsult(cachedTracks); 60 59 61 60 /** @type {Track[]} */