A music player that connects to your cloud/distributed storage.
1import { ostiary, rpc, workerProxy } from "~/common/worker.js";
2import { musicMetadataTags } from "~/components/metadata/common.js";
3
4/**
5 * @import {Track} from "~/definitions/types.d.ts"
6 * @import {ActionsWithTunnel, ProxiedActions} from "~/common/worker.d.ts"
7 * @import {InputActions} from "~/components/input/types.d.ts"
8 * @import {Actions} from "~/components/metadata/types.d.ts"
9 */
10
11////////////////////////////////////////////
12// ACTIONS
13////////////////////////////////////////////
14
15/**
16 * @type {ActionsWithTunnel<Actions>['patch']}
17 */
18export async function patch({ data: track, ports }) {
19 /** @type {ProxiedActions<InputActions>} */
20 const input = workerProxy(() => {
21 ports.input.start();
22 return ports.input;
23 });
24
25 const resGet = await input.resolve({ method: "GET", uri: track.uri });
26 if (!resGet) return track;
27
28 const resHead = "stream" in resGet
29 ? undefined
30 : await input.resolve({ method: "HEAD", uri: track.uri });
31
32 const { stats, tags } = await musicMetadataTags({
33 stream: "stream" in resGet ? resGet.stream : undefined,
34 mimeType: "stream" in resGet ? resGet.mimeType : undefined,
35 urls: "url" in resGet
36 ? {
37 get: resGet.url,
38 head: resHead && "url" in resHead ? resHead.url : resGet.url,
39 }
40 : undefined,
41 }).catch(/** @param {Error} err */ (err) => {
42 console.warn("audio-file metadata error", err);
43 return /** @type {import("./types.d.ts").Extraction} */ ({});
44 });
45
46 if (!tags && !stats) return track;
47
48 return {
49 ...track,
50 stats,
51 tags,
52 updatedAt: new Date().toISOString(),
53 };
54}
55
56////////////////////////////////////////////
57// ⚡️
58////////////////////////////////////////////
59
60ostiary((context) => {
61 rpc(context, { patch });
62});