From ad14fec83f4a1033315f5bcaa98f36aebcc5d8f6 Mon Sep 17 00:00:00 2001 From: Steven Vandevelde Date: Fri, 30 May 2025 00:38:52 +0200 Subject: [PATCH] feat: include expire timestamp in uri resolving result --- src/pages/configurator/input/_manifest.json | 2 +- src/pages/core/types.d.ts | 2 + src/pages/input/native-fs/_applet.astro | 2 +- src/pages/input/native-fs/_manifest.json | 2 +- src/pages/input/s3/_applet.astro | 5 ++- src/pages/input/s3/_manifest.json | 2 +- .../orchestrator/input-cache/_applet.astro | 10 ++--- .../orchestrator/single-queue/_applet.astro | 38 +++++++++++++------ .../orchestrator/single-queue/_manifest.json | 7 +++- src/scripts/themes/webamp/index.ts | 10 ++--- 10 files changed, 52 insertions(+), 28 deletions(-) diff --git a/src/pages/configurator/input/_manifest.json b/src/pages/configurator/input/_manifest.json index b8c127d..35d5a85 100644 --- a/src/pages/configurator/input/_manifest.json +++ b/src/pages/configurator/input/_manifest.json @@ -24,7 +24,7 @@ }, "resolve": { "title": "Resolve", - "description": "Potentially translates a track uri with a matching scheme into a URL pointing at the audio bytes. If it can be resolved that is, otherwise you'll get `undefined`.", + "description": "Potentially translates a track uri with a matching scheme into a URL pointing at the audio bytes or an audio stream. If it can be resolved that is, otherwise you'll get `undefined`.", "params_schema": { "type": "object", "properties": { diff --git a/src/pages/core/types.d.ts b/src/pages/core/types.d.ts index 30857be..34a6520 100644 --- a/src/pages/core/types.d.ts +++ b/src/pages/core/types.d.ts @@ -9,6 +9,8 @@ export type OutputSetter = ({ data, name }: { data: Uint8Array; name: string }) /* TRACKS */ +export type ResolvedUri = undefined | { url: string; expiresAt: number }; // TODO: Streams? + export interface Track { id: string; diff --git a/src/pages/input/native-fs/_applet.astro b/src/pages/input/native-fs/_applet.astro index 053e884..f8c7b58 100644 --- a/src/pages/input/native-fs/_applet.astro +++ b/src/pages/input/native-fs/_applet.astro @@ -198,7 +198,7 @@ const file = await fileHandle.getFile(); const url = URL.createObjectURL(file); - return url; + return { expiresAt: Infinity, url }; }; const mount = async () => { diff --git a/src/pages/input/native-fs/_manifest.json b/src/pages/input/native-fs/_manifest.json index e4209b1..a5a6ff6 100644 --- a/src/pages/input/native-fs/_manifest.json +++ b/src/pages/input/native-fs/_manifest.json @@ -27,7 +27,7 @@ }, "resolve": { "title": "Resolve", - "description": "Potentially translates a track uri with a matching scheme into a URL pointing at the audio bytes. If it can be resolved that is, otherwise you'll get `undefined`. Use the `consult` action to get a more detailed answer.", + "description": "Potentially translates a track uri with a matching scheme into a URL pointing at the audio bytes or an audio stream. If it can be resolved that is, otherwise you'll get `undefined`. Use the `consult` action to get a more detailed answer.", "params_schema": { "type": "object", "properties": { diff --git a/src/pages/input/s3/_applet.astro b/src/pages/input/s3/_applet.astro index 32aae3e..75b6741 100644 --- a/src/pages/input/s3/_applet.astro +++ b/src/pages/input/s3/_applet.astro @@ -266,8 +266,11 @@ bucket.path.replace(/\/$/, "") + URI.unescapeComponent(parsedURI.path || "") ).replace(/^\//, ""); + const expiresInSeconds = 60 * 60 * 24 * 7; // 7 days + const expiresAtSeconds = Math.round(Date.now() / 1000) + expiresInSeconds; const url = await client.getPresignedUrl(method.toUpperCase() as any, path); - return url; + + return { expiresAt: expiresAtSeconds, url }; }; const mount = async () => {}; diff --git a/src/pages/input/s3/_manifest.json b/src/pages/input/s3/_manifest.json index ab92186..f79b7c9 100644 --- a/src/pages/input/s3/_manifest.json +++ b/src/pages/input/s3/_manifest.json @@ -34,7 +34,7 @@ }, "resolve": { "title": "Resolve", - "description": "Potentially translates a track uri with a matching scheme into a URL pointing at the audio bytes. If it can be resolved that is, otherwise you'll get `undefined`. Use the `consult` action to get a more detailed answer.", + "description": "Potentially translates a track uri with a matching scheme into a URL pointing at the audio bytes or an audio stream. If it can be resolved that is, otherwise you'll get `undefined`. Use the `consult` action to get a more detailed answer.", "params_schema": { "type": "object", "properties": { diff --git a/src/pages/orchestrator/input-cache/_applet.astro b/src/pages/orchestrator/input-cache/_applet.astro index d67f737..19bf23c 100644 --- a/src/pages/orchestrator/input-cache/_applet.astro +++ b/src/pages/orchestrator/input-cache/_applet.astro @@ -1,7 +1,7 @@ diff --git a/src/pages/orchestrator/single-queue/_manifest.json b/src/pages/orchestrator/single-queue/_manifest.json index a178c18..6066e3d 100644 --- a/src/pages/orchestrator/single-queue/_manifest.json +++ b/src/pages/orchestrator/single-queue/_manifest.json @@ -5,7 +5,12 @@ "actions": { "fill": { "title": "Fill", - "description": "Fill up the queue." + "description": "Fill up the queue.", + "params_schema": { + "type": "array", + "items": { "type": "object" }, + "description": "Array of tracks to be used to fill up the queue." + } } } } diff --git a/src/scripts/themes/webamp/index.ts b/src/scripts/themes/webamp/index.ts index c6048e8..bc62c37 100644 --- a/src/scripts/themes/webamp/index.ts +++ b/src/scripts/themes/webamp/index.ts @@ -1,8 +1,8 @@ import Webamp from "webamp"; import { URLTrack } from "webamp"; -import type { Output, Track } from "@applets/core/types.d.ts"; -import { applet, waitUntilAppletIsReady } from "../../theme.ts"; +import type { ResolvedUri, Track } from "@applets/core/types.d.ts"; +import { applet } from "../../theme.ts"; //////////////////////////////////////////// // 🎨 Styles @@ -55,7 +55,7 @@ async function loadTracks(): Promise { // TODO: Ideally the URL should only be resolved when needed, // but webamp doesn't allow for that. // Maybe you could work around it with a service worker. - const url = await configurator.input.sendAction( + const resGet = await configurator.input.sendAction( "resolve", { method: "GET", uri: track.uri }, { @@ -63,10 +63,10 @@ async function loadTracks(): Promise { }, ); - if (!url) return acc; + if (!resGet) return acc; const urlTrack: URLTrack = { - url, + url: resGet.url, metaData: { title: track.tags?.title || "", artist: track.tags?.artist || "", -- knotmirror 0.0.1