1import { computed } from "@common/signal.js";
2import { OutputTransformer } from "../../base.js";
3
4/**
5 * @import { OutputManagerDeputy } from "@components/output/types.d.ts"
6 * @import { Facet, Playlist, Theme, Track } from "@definitions/types.d.ts"
7 */
8
9/**
10 * @extends {OutputTransformer<Uint8Array>}
11 */
12class JsonStringOutputTransformer extends OutputTransformer {
13 constructor() {
14 super();
15
16 const base = this.base();
17
18 /** @type {OutputManagerDeputy} */
19 const manager = {
20 facets: {
21 ...base.facets,
22 collection: computed(() => {
23 const data = base.facets.collection();
24 /** @type {Facet[]} */
25 const c = parseArray(data);
26 return c;
27 }),
28 save: async (newFacets) => {
29 const json = JSON.stringify(newFacets);
30 const encoder = new TextEncoder();
31 const bytes = encoder.encode(json);
32 await base.facets.save(bytes);
33 },
34 },
35 playlists: {
36 ...base.playlists,
37 collection: computed(() => {
38 const data = base.playlists.collection();
39 /** @type {Playlist[]} */
40 const c = parseArray(data);
41 return c;
42 }),
43 save: async (newPlaylists) => {
44 const json = JSON.stringify(newPlaylists);
45 const encoder = new TextEncoder();
46 const bytes = encoder.encode(json);
47 await base.playlists.save(bytes);
48 },
49 },
50 themes: {
51 ...base.themes,
52 collection: computed(() => {
53 const data = base.themes.collection();
54 /** @type {Theme[]} */
55 const c = parseArray(data);
56 return c;
57 }),
58 save: async (newThemes) => {
59 const json = JSON.stringify(newThemes);
60 const encoder = new TextEncoder();
61 const bytes = encoder.encode(json);
62 await base.themes.save(bytes);
63 },
64 },
65 tracks: {
66 ...base.tracks,
67 collection: computed(() => {
68 const data = base.tracks.collection();
69 /** @type {Track[]} */
70 const c = parseArray(data);
71 return c;
72 }),
73 save: async (newTracks) => {
74 const json = JSON.stringify(newTracks);
75 const encoder = new TextEncoder();
76 const bytes = encoder.encode(json);
77 await base.tracks.save(bytes);
78 },
79 },
80 };
81
82 // Assign manager properties to class
83 this.facets = manager.facets;
84 this.playlists = manager.playlists;
85 this.themes = manager.themes;
86 this.tracks = manager.tracks;
87 }
88}
89
90/**
91 * @param {Uint8Array | string | undefined} data
92 */
93function parseArray(data) {
94 let json;
95
96 if (data instanceof Uint8Array) {
97 const decoder = new TextDecoder();
98 json = decoder.decode(data);
99 } else if (data === undefined) {
100 return [];
101 } else {
102 json = data;
103 }
104
105 try {
106 return JSON.parse(json);
107 } catch (err) {
108 console.error(err);
109 return [];
110 }
111}
112
113export default JsonStringOutputTransformer;
114
115////////////////////////////////////////////
116// REGISTER
117////////////////////////////////////////////
118
119export const CLASS = JsonStringOutputTransformer;
120export const NAME = "dtos-json";
121
122customElements.define(NAME, CLASS);