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

Configure Feed

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

at v4 107 lines 3.0 kB view raw
1import { BroadcastableDiffuseElement, 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 BroadcastableDiffuseElement { 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>} */ 44 const m = { 45 facets: { 46 collection: computed(() => { 47 return this.output.signal()?.facets?.collection() ?? 48 { state: "loading" }; 49 }), 50 reload: () => { 51 return this.output.signal()?.facets?.reload() ?? 52 Promise.resolve(); 53 }, 54 save: async (newFacets) => { 55 await this.output.whenDefined; 56 await this.output.signal()?.facets.save(newFacets); 57 }, 58 }, 59 playlistItems: { 60 collection: computed(() => { 61 return this.output.signal()?.playlistItems?.collection() ?? 62 { state: "loading" }; 63 }), 64 reload: () => { 65 return this.output.signal()?.playlistItems?.reload() ?? 66 Promise.resolve(); 67 }, 68 save: async (newPlaylistItems) => { 69 await this.output.whenDefined; 70 await this.output.signal()?.playlistItems.save(newPlaylistItems); 71 }, 72 }, 73 settings: { 74 collection: computed(() => { 75 return this.output.signal()?.settings?.collection() ?? 76 { state: "loading" }; 77 }), 78 reload: () => { 79 return this.output.signal()?.settings?.reload() ?? 80 Promise.resolve(); 81 }, 82 save: async (newSettings) => { 83 await this.output.whenDefined; 84 await this.output.signal()?.settings.save(newSettings); 85 }, 86 }, 87 tracks: { 88 collection: computed(() => { 89 return this.output.signal()?.tracks?.collection() ?? 90 { state: "loading" }; 91 }), 92 reload: () => { 93 return this.output.signal()?.tracks?.reload() ?? Promise.resolve(); 94 }, 95 save: async (newTracks) => { 96 await this.output.whenDefined; 97 await this.output.signal()?.tracks.save(newTracks); 98 }, 99 }, 100 101 // Other non-data related state 102 ready: computed(() => this.output.signal()?.ready() ?? false), 103 }; 104 105 return m; 106 } 107}