A music player that connects to your cloud/distributed storage.
at v4 116 lines 3.3 kB view raw
1import { DiffuseElement, query } from "@common/element.js"; 2import { computed, signal } from "@common/signal.js"; 3 4/** 5 * @import { OutputElement, OutputManagerDeputy } from "../../output/types.d.ts" 6 */ 7 8/** 9 * @template [T=null] 10 */ 11export class OutputTransformer extends DiffuseElement { 12 // SIGNALS 13 14 #output = signal(/** @type {OutputElement<T> | undefined} */ (undefined)); 15 #outputWhenDefined = Promise.withResolvers(); 16 17 output = { 18 whenDefined: this.#outputWhenDefined.promise, 19 signal: this.#output.get, 20 }; 21 22 // LIFECYCLE 23 24 /** 25 * @override 26 */ 27 connectedCallback() { 28 super.connectedCallback(); 29 30 /** @type {OutputElement<T>} */ 31 const output = query(this, "output-selector"); 32 33 // When defined 34 customElements.whenDefined(output.localName).then(() => { 35 this.#output.value = output; 36 this.#outputWhenDefined.resolve(null); 37 }); 38 } 39 40 // MANAGER 41 42 base() { 43 /** @type {OutputManagerDeputy<T | undefined>} */ 44 const m = { 45 facets: { 46 collection: computed(() => { 47 return this.output.signal()?.facets?.collection(); 48 }), 49 reload: () => { 50 return this.output.signal()?.facets?.reload() ?? 51 Promise.resolve(); 52 }, 53 save: async (newFacets) => { 54 if (newFacets === undefined) return; 55 await this.output.whenDefined; 56 await this.output.signal()?.facets.save(newFacets); 57 }, 58 state: computed(() => { 59 return this.output.signal()?.facets.state() ?? "sleeping"; 60 }), 61 }, 62 playlists: { 63 collection: computed(() => { 64 return this.output.signal()?.playlists?.collection(); 65 }), 66 reload: () => { 67 return this.output.signal()?.playlists?.reload() ?? 68 Promise.resolve(); 69 }, 70 save: async (newPlaylists) => { 71 if (newPlaylists === undefined) return; 72 await this.output.whenDefined; 73 await this.output.signal()?.playlists.save(newPlaylists); 74 }, 75 state: computed(() => { 76 return this.output.signal()?.playlists.state() ?? "sleeping"; 77 }), 78 }, 79 themes: { 80 collection: computed(() => { 81 return this.output.signal()?.themes?.collection(); 82 }), 83 reload: () => { 84 return this.output.signal()?.themes?.reload() ?? 85 Promise.resolve(); 86 }, 87 save: async (newThemes) => { 88 if (newThemes === undefined) return; 89 await this.output.whenDefined; 90 await this.output.signal()?.themes.save(newThemes); 91 }, 92 state: computed(() => { 93 return this.output.signal()?.themes.state() ?? "sleeping"; 94 }), 95 }, 96 tracks: { 97 collection: computed(() => { 98 return this.output.signal()?.tracks?.collection(); 99 }), 100 reload: () => { 101 return this.output.signal()?.tracks?.reload() ?? Promise.resolve(); 102 }, 103 save: async (newTracks) => { 104 if (newTracks === undefined) return; 105 await this.output.whenDefined; 106 await this.output.signal()?.tracks.save(newTracks); 107 }, 108 state: computed(() => { 109 return this.output.signal()?.tracks.state() ?? "sleeping"; 110 }), 111 }, 112 }; 113 114 return m; 115 } 116}