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 361 lines 13 kB view raw
1import { walk } from "@std/fs/walk"; 2 3const srcDir = new URL("../", import.meta.url).pathname; 4/** @type {Record<string, string>} */ 5const sources = {}; 6 7for await ( 8 const entry of walk(srcDir + "components", { match: [/element\.js$/] }) 9) { 10 const content = await Deno.readTextFile(entry.path); 11 const key = entry.path.slice(srcDir.length); 12 sources[key] = content; 13} 14 15export default { 16 sources, 17 18 artwork: [ 19 { 20 url: "components/artwork/audio-metadata/element.js", 21 title: "Audio Metadata", 22 desc: 23 "Extracts embedded artwork from audio files using the music-metadata library.", 24 }, 25 { 26 url: "components/artwork/input/element.js", 27 title: "Input", 28 desc: 29 "Fetches artwork by delegating to the configured input element's artwork method.", 30 }, 31 { 32 url: "components/artwork/last.fm/element.js", 33 title: "Last.fm", 34 desc: 35 "Fetches cover art from the Last.fm API using track artist and album tags.", 36 }, 37 { 38 url: "components/artwork/musicbrainz/element.js", 39 title: "MusicBrainz", 40 desc: 41 "Fetches cover art from MusicBrainz and the Cover Art Archive using track artist and album tags.", 42 }, 43 ], 44 45 configurators: [ 46 { 47 url: "components/configurator/artwork/element.js", 48 title: "Artwork", 49 desc: 50 "Takes artwork components as children and tries each in sequence, returning the first non-null result.", 51 }, 52 { 53 url: "components/configurator/input/element.js", 54 title: "Input", 55 desc: "Allows for multiple inputs to be used at once.", 56 }, 57 { 58 url: "components/configurator/metadata/element.js", 59 title: "Metadata", 60 desc: 61 "Takes metadata components as children and chains their patches in sequence.", 62 }, 63 { 64 url: "components/configurator/output/element.js", 65 title: "Output", 66 desc: 67 "Enables the user to configure a specific output. If no default output is set, it creates a temporary session by storing everything in memory.", 68 }, 69 { 70 url: "components/configurator/scrobbles/element.js", 71 title: "Scrobbles", 72 desc: "Configure multiple scrobblers (music trackers).", 73 }, 74 ], 75 76 engines: [ 77 { 78 url: "components/engine/audio/element.js", 79 title: "Audio", 80 desc: "Plays audio through audio elements.", 81 }, 82 { 83 url: "components/engine/queue/element.js", 84 title: "Queue", 85 desc: "A queue for tracks.", 86 }, 87 { 88 url: "components/engine/repeat-shuffle/element.js", 89 title: "Repeat & Shuffle", 90 desc: 91 "Signals synced with local storage (classified by group) that decide if audio should be repeated and if the queue should be shuffled when filling it.", 92 }, 93 { 94 url: "components/engine/scope/element.js", 95 title: "Scope", 96 desc: "Signals that could influence the scope of a set of tracks.", 97 }, 98 ], 99 100 input: [ 101 { 102 url: "components/input/dropbox/element.js", 103 title: "Dropbox", 104 desc: "Dropbox, using the Dropbox v2 HTTP API.", 105 }, 106 { 107 url: "components/input/ephemeral-cache/element.js", 108 title: "Ephemeral Cache", 109 desc: 110 "Ephemeral blobs stored in indexedDB, resolving creates temporary Blob URLs. Not responsible for storing blobs.", 111 }, 112 { 113 url: "components/input/https/element.js", 114 title: "HTTPS", 115 desc: "HTTPS URLs to audio files or streams.", 116 }, 117 { 118 url: "components/input/icecast/element.js", 119 title: "Icecast", 120 desc: 121 "Icecast internet radio streams. Fetches ICY metadata to populate track information.", 122 }, 123 { 124 url: "components/input/local/element.js", 125 title: "Local", 126 desc: 127 "Audio files or directories from your local device, using the browser's File System Access API.", 128 }, 129 { 130 url: "components/input/opensubsonic/element.js", 131 title: "Opensubsonic", 132 desc: "(Open)subsonic audio servers.", 133 }, 134 { 135 url: "components/input/s3/element.js", 136 title: "S3", 137 desc: 138 "AWS S3 and services that provide the same surface API such as Cloudflare R2.", 139 }, 140 { 141 url: "components/input/webdav/element.js", 142 title: "WebDAV", 143 desc: 144 "WebDAV servers. Depends on a service worker handling the `diffuse:basic-auth` query parameter and converting it to a `Authorization` header.", 145 }, 146 ], 147 148 metadata: [ 149 { 150 url: "components/metadata/audio-file/element.js", 151 title: "Audio File", 152 desc: 153 "Extracts tags and audio stats from audio files using the music-metadata library.", 154 }, 155 ], 156 157 orchestrators: [ 158 { 159 url: "components/orchestrator/artwork/element.js", 160 title: "Artwork", 161 desc: 162 "Fetches cover art for a given set of tracks, stored locally in indexedDB. Uses the artwork configurator to try each configured source in sequence.", 163 }, 164 { 165 url: "components/orchestrator/auto-queue/element.js", 166 title: "Automatic Queue", 167 desc: 168 "Fill the queue automatically with non-manual items (shuffled or regular, based on repeat-shuffle engine).", 169 }, 170 { 171 url: "components/orchestrator/controller/element.js", 172 title: "Controller", 173 desc: 174 "Provides commonly used computed signals derived from the audio engine, queue engine, and output. Exposes currentTrack(), isPlaying(), and references to the underlying engines.", 175 }, 176 { 177 url: "components/orchestrator/cover-groups/element.js", 178 title: "Cover Groups", 179 desc: "Groups tracks by cover art to form collections.", 180 }, 181 { 182 url: "components/orchestrator/favourites/element.js", 183 title: "Favourites", 184 desc: 185 "Mark tracks as favourites. Automatically creates an unordered 'Favourites' playlist.", 186 }, 187 { 188 url: "components/orchestrator/media-session/element.js", 189 title: "Media Session", 190 desc: 191 "Keeps the browser/os media session in sync with queue and audio state. Adds handlers for previous, next, seek to, etc.", 192 }, 193 { 194 url: "components/orchestrator/output/element.js", 195 title: "Output", 196 desc: 197 "A default output configuration. Contains all the outputs provided here along with the relevant transformers.", 198 }, 199 { 200 url: "components/orchestrator/path-collections/element.js", 201 title: "Path Collections", 202 desc: 203 "Wraps an output element to generate ephemeral playlists based on the first path segment of each track's URI. Ephemeral items are excluded from storage.", 204 }, 205 { 206 url: "components/orchestrator/process-tracks/element.js", 207 title: "Process Inputs Into Tracks", 208 desc: 209 "Whenever the cached tracks are initially loaded through the passed output element it will list tracks by using the passed input element. Afterwards it loops over all tracks and checks if metadata needs to be fetched. If anything has changed, it'll pass the results to the output element.", 210 }, 211 { 212 url: "components/orchestrator/queue-audio/element.js", 213 title: "Queue ⭤ Audio", 214 desc: "Connects the given queue engine to the given audio engine.", 215 }, 216 { 217 url: "components/orchestrator/scoped-tracks/element.js", 218 title: "Scoped Tracks", 219 desc: 220 "Watches the given output's tracks collection and runs them through a built-in search index. Can perform a search and other ways to reduce the scope of tracks based on the given scope engine. Provides a tracks signal similar to output.tracks.collection.", 221 }, 222 { 223 url: "components/orchestrator/scrobble-audio/element.js", 224 title: "Scrobble ⭤ Audio", 225 desc: 226 "Connects the audio engine with a scrobbler element. Calls nowPlaying when a track starts playing and scrobble once the user has listened long enough.", 227 }, 228 { 229 url: "components/orchestrator/sources/element.js", 230 title: "Sources", 231 desc: 232 "Monitor tracks from the given output to form a list of sources based on the input's sources return value.", 233 }, 234 ], 235 236 output: [ 237 { 238 url: "components/output/polymorphic/indexed-db/element.js", 239 title: "Polymorphic / IndexedDB", 240 desc: 241 "Stores output into the local indexedDB. Supports any type of data that indexedDB supports.", 242 }, 243 { 244 url: "components/output/bytes/s3/element.js", 245 title: "Bytes / S3", 246 desc: 247 "Store output data on AWS S3 or compatible services such as Cloudflare R2.", 248 }, 249 { 250 url: "components/output/raw/atproto/element.js", 251 title: "Raw / AT Protocol", 252 desc: 253 "Store your user data on the storage associated with your ATProtocol identity. Data is lexicon shaped by default so this element takes in that data directly without any transformations.", 254 }, 255 ], 256 257 supplements: [ 258 { 259 url: "components/supplement/last.fm/element.js", 260 title: "Last.fm Scrobbler", 261 desc: "Scrobbles track plays to Last.fm.", 262 }, 263 { 264 url: "components/supplement/listenbrainz/element.js", 265 title: "ListenBrainz Scrobbler", 266 desc: "Scrobbles track plays to ListenBrainz.", 267 todo: true, 268 }, 269 { 270 url: "components/supplement/rocksky/element.js", 271 title: "Rocksky Scrobbler", 272 desc: "Scrobbles track plays to Rocksky.", 273 todo: true, 274 }, 275 ], 276 277 transformers: [ 278 { 279 url: "components/transformer/output/bytes/automerge/element.js", 280 title: "Output / Bytes / Automerge", 281 desc: "Translate data to and from an Automerge CRDT.", 282 todo: true, 283 }, 284 { 285 url: "components/transformer/output/bytes/dasl-sync/element.js", 286 title: "Output / Bytes / DASL Sync", 287 desc: 288 "Syncs data between local and remote using CID-based diffing and performs union merges with tombstone tracking when both sides have diverged.", 289 }, 290 { 291 url: "components/transformer/output/bytes/json/element.js", 292 title: "Output / Bytes / JSON", 293 desc: "Raw data schema output to and from JSON Uint8Array.", 294 }, 295 { 296 url: "components/transformer/output/raw/atproto-sync/element.js", 297 title: "Output / Raw / AT Protocol Sync", 298 desc: 299 "Wraps an AT Protocol output with a local IndexedDB cache. Uses the repo revision to skip unnecessary fetches and performs union merges with tombstone tracking when both local and remote have diverged.", 300 }, 301 { 302 url: "components/transformer/output/refiner/default/element.js", 303 title: "Output / Refiner / Default", 304 desc: 305 "Removes output state that is not meant to be saved to storage, such as ephemeral tracks. Ideally part of every theme.", 306 }, 307 { 308 url: "components/transformer/output/refiner/initial-contents/element.js", 309 title: "Output / Refiner / Initial Contents", 310 desc: "Sets the initial contents for an output on first load.", 311 }, 312 { 313 url: 314 "components/transformer/output/refiner/passkey-encryption/element.js", 315 title: "Output / Refiner / Track URI Passkey", 316 desc: 317 "Encrypts track URIs using a passkey-derived PRF key. On read, decrypts encrypted:// URIs transparently; on write, re-encrypts all URIs before passing downstream.", 318 }, 319 { 320 url: "components/transformer/output/string/json/element.js", 321 title: "Output / String / JSON", 322 desc: "Raw data schema output to and from JSON UTF8 string.", 323 }, 324 ], 325 326 definitions: [ 327 { 328 url: "definitions/output/collaboration.json", 329 title: "Output / Collaboration", 330 desc: 331 "Represents a collaboration between multiple collaborators on a subject, such as a playlist.", 332 }, 333 { 334 url: "definitions/output/facet.json", 335 title: "Output / Facet", 336 desc: "Facet pointer or HTML snippet.", 337 }, 338 { 339 url: "definitions/output/playlistItem.json", 340 title: "Output / Playlist Item", 341 desc: 342 "Represents a single item in a playlist. Tracks are matched based on the given criteria. A playlist is formed by grouping items by their playlist property.", 343 }, 344 { 345 title: "Output / Progress", 346 desc: "Used to track progress of (long) audio playback.", 347 todo: true, 348 }, 349 { 350 url: "definitions/output/track.json", 351 title: "Output / Track", 352 desc: 353 "Represents audio that can be played, or a placeholder for a source of tracks. Contains a URI that will resolve to the audio.", 354 }, 355 { 356 url: "definitions/output/trackBundle.json", 357 title: "Output / Track Bundle", 358 desc: "A bundle of tracks.", 359 }, 360 ], 361};