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

feat: json string output transformer

+85 -41
+4
_config.ts
··· 58 58 ), 59 59 ); 60 60 61 + // DEFINITIONS 62 + 63 + site.add("/definitions"); 64 + 61 65 // MISC 62 66 63 67 site.use(sourceMaps());
-17
src/common/element.d.ts
··· 10 10 ...values: unknown[] 11 11 ) => string; 12 12 13 - type MorphOptions = { 14 - getNodeKey?: (node: Node) => unknown; 15 - onBeforeNodeAdded?: (node: Node) => false | Node; 16 - onNodeAdded?: (node: Node) => void; 17 - onBeforeElUpdated?: (fromEl: HTMLElement, toEl: HTMLElement) => boolean; 18 - onElUpdated?: (el: HTMLElement) => void; 19 - onBeforeNodeDiscarded?: (node: Node) => boolean; 20 - onNodeDiscarded?: (node: Node) => void; 21 - onBeforeElChildrenUpdated?: ( 22 - fromEl: HTMLElement, 23 - toEl: HTMLElement, 24 - ) => boolean; 25 - skipFromChildren?: (fromEl: HTMLElement) => boolean; 26 - addChild?: (parent: HTMLElement, child: HTMLElement) => void; 27 - childrenOnly?: boolean; 28 - }; 29 - 30 13 export type RenderArg<State = undefined> = { 31 14 html: HtmlTagFunction; 32 15 state: State;
+1 -1
src/common/element.js
··· 4 4 import { define, use } from "@common/worker.js"; 5 5 6 6 /** 7 - * @import {BroadcastingStatus, FnParams, FnReturn, HtmlTagFunction, MorphOptions} from "./element.d.ts" 7 + * @import {BroadcastingStatus, FnParams, FnReturn} from "./element.d.ts" 8 8 * @import {Signal} from "./signal.d.ts" 9 9 */ 10 10
+1 -1
src/components/orchestrator/process-tracks/element.js
··· 24 24 /** @type {InputElement} */ 25 25 this.input = query(this, "input-selector"); 26 26 27 - /** @type {OutputElement} */ 27 + /** @type {OutputElement<Track[]>} */ 28 28 this.output = query(this, "output-selector"); 29 29 30 30 /** @type {import("@components/processor/metadata/element.js").CLASS} */
+1 -1
src/components/orchestrator/queue-tracks/element.js
··· 22 22 /** @type {InputElement} */ 23 23 this.input = query(this, "input-selector"); 24 24 25 - /** @type {OutputElement} */ 25 + /** @type {OutputElement<Track[]>} */ 26 26 this.output = query(this, "output-selector"); 27 27 28 28 /** @type {import("@components/engine/queue/element.js").CLASS} */
+1 -1
src/components/orchestrator/search-tracks/element.js
··· 21 21 /** @type {InputElement} */ 22 22 this.input = query(this, "input-selector"); 23 23 24 - /** @type {OutputElement} */ 24 + /** @type {OutputElement<Track[]>} */ 25 25 this.output = query(this, "output-selector"); 26 26 27 27 /** @type {import("@components/processor/search/element.js").CLASS} */
+1 -8
src/components/output/types.d.ts
··· 1 1 import type { SignalReader } from "@common/signal.d.ts"; 2 - import type { Track } from "@common/types.d.ts"; 3 2 4 - // TODO: Do we need this? 5 - // 6 - // export interface Output<S = TrackStats, T = TrackTags> { 7 - // tracks: Track<S, T>[]; 8 - // } 9 - 10 - export type OutputElement = HTMLElement & OutputManager<Track[]>; 3 + export type OutputElement<Tracks> = HTMLElement & OutputManager<Tracks>; 11 4 12 5 export type OutputManager<Tracks> = { 13 6 tracks: {
+61
src/components/transformer/output/string/json/element.js
··· 1 + import { DiffuseElement, query } from "@common/element.js"; 2 + import { computed } from "@common/signal.js"; 3 + 4 + /** 5 + * @import { OutputElement, OutputManager } from "../../../../output/types.d.ts" 6 + * @import { Track } from "@common/types.d.ts" 7 + */ 8 + 9 + class JsonStringOutputTransformer extends DiffuseElement { 10 + constructor() { 11 + super(); 12 + 13 + /** @type {OutputElement<string>} */ 14 + this.output = query(this, "output-selector"); 15 + 16 + /** @type {OutputManager<Track[]>} */ 17 + const manager = { 18 + tracks: { 19 + collection: computed(() => { 20 + const json = this.output.tracks?.collection() || []; 21 + 22 + // In addition to the above, Some polymorphic outputs 23 + // use an empty array as the default return value. 24 + if (Array.isArray(json)) return json; 25 + 26 + // Try parsing JSON 27 + try { 28 + return JSON.parse(json); 29 + } catch (err) { 30 + console.error( 31 + "components/transformer/output/string/json: Failed to parse JSON", 32 + ); 33 + return []; 34 + } 35 + }), 36 + reload: () => this.output.tracks.reload(), 37 + save: async (newTracks) => { 38 + const json = JSON.stringify(newTracks); 39 + 40 + await customElements.whenDefined(this.output.localName); 41 + await this.output.tracks.save(json); 42 + }, 43 + state: () => this.output.tracks.state(), 44 + }, 45 + }; 46 + 47 + // Assign manager properties to class 48 + this.tracks = manager.tracks; 49 + } 50 + } 51 + 52 + export default JsonStringOutputTransformer; 53 + 54 + //////////////////////////////////////////// 55 + // REGISTER 56 + //////////////////////////////////////////// 57 + 58 + export const CLASS = JsonStringOutputTransformer; 59 + export const NAME = "dtos-json"; 60 + 61 + customElements.define(NAME, CLASS);
+1 -1
src/definitions/index.ts
··· 1 - export * as ShDiffuseOutputTracks from "./types/sh/diffuse/output/tracks.js"; 1 + export * as ShDiffuseOutputTracks from "./types/sh/diffuse/output/tracks.ts";
+4 -5
src/index.vto
··· 80 80 todo: true 81 81 82 82 transformers: 83 - - url: "components/transformer/output/bytes/cambria/element.js" 84 - title: "Output / Bytes / Cambria lenses" 83 + - title: "Output / Bytes / Cambria lenses" 85 84 desc: "Uses the Cambria library to seamlessly translate between data schemas so that no data migration is needed." 86 85 todo: true 87 86 - title: "Output / Bytes / JSON" ··· 89 88 todo: true 90 89 - title: "Output / String / JSON" 91 90 desc: "Raw data schema output ⇄ JSON UTF8 string." 92 - todo: true 91 + url: "components/transformer/output/string/json/element.js" 93 92 94 93 # DEFINITIONS 95 94 ··· 105 104 todo: true 106 105 - title: "Output / Tracks" 107 106 desc: "Represents audio that can be played, or a placeholder for a source of tracks. Contains a URI that will resolve to the audio. This object may be cached if convenient." 108 - todo: true 107 + url: "definitions/output/tracks.json" 109 108 110 109 --- 111 110 <link rel="stylesheet" href="index.css" /> ··· 233 232 234 233 <p>All of the elements here are built with these data definitions in mind. That said, you can mix elements that use different definitions; you just have to put a transformer between them in order to translate between them.</p> 235 234 236 - {{ await comp.list({ items: schemas }) }} 235 + {{ await comp.list({ items: definitions }) }} 237 236 </section> 238 237 239 238 <!-- DEMOS -->
+1 -1
src/themes/webamp/browser/element.js
··· 16 16 /** @type {InputElement} */ 17 17 this.input = query(this, "input-selector"); 18 18 19 - /** @type {OutputElement} */ 19 + /** @type {OutputElement<Track[]>} */ 20 20 this.output = query(this, "output-selector"); 21 21 22 22 /** @type {import("@components/engine/queue/element.js").CLASS} */
+1
src/themes/webamp/index.js
··· 2 2 import "@components/orchestrator/queue-tracks/element.js"; 3 3 import "@components/output/polymorphic/indexed-db/element.js"; 4 4 import "@components/processor/metadata/element.js"; 5 + import "@components/transformer/output/string/json/element.js"; 5 6 6 7 import * as Input from "@components/input/opensubsonic/element.js"; 7 8 import * as Queue from "@components/engine/queue/element.js";
+8 -5
src/themes/webamp/index.vto
··· 36 36 <span slot="title">Browse collection</span> 37 37 <dtw-browser 38 38 input-selector="di-opensubsonic" 39 - output-selector="dop-indexed-db" 39 + output-selector="#output" 40 40 queue-selector="de-queue" 41 41 ></dtw-browser> 42 42 </dtw-window> ··· 75 75 COMPONENTS 76 76 77 77 --> 78 - <de-queue fill-size="5"></de-queue> 78 + <de-queue fill-size="10"></de-queue> 79 79 80 - <!-- Inputs, Outputs, Processors & Transformers --> 80 + <!-- Inputs, Output & Processors --> 81 81 <di-opensubsonic></di-opensubsonic> 82 82 <dop-indexed-db></dop-indexed-db> 83 83 <dp-metadata></dp-metadata> 84 84 85 + <!-- Transformers --> 86 + <dtos-json id="output" output-selector="dop-indexed-db"></dtos-json> 87 + 85 88 <!-- Orchestrators --> 86 89 <do-process-tracks 87 90 input-selector="di-opensubsonic" 88 91 metadata-processor-selector="dp-metadata" 89 - output-selector="dop-indexed-db" 92 + output-selector="#output" 90 93 ></do-process-tracks> 91 94 92 95 <do-queue-tracks 93 96 input-selector="di-opensubsonic" 94 - output-selector="dop-indexed-db" 97 + output-selector="#output" 95 98 queue-engine-selector="de-queue" 96 99 ></do-queue-tracks> 97 100