@deadair/plugin-sdk 0.52.2 → 0.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -0
- package/dist/boundary.json.safe.d.ts +7 -4
- package/dist/boundary.json.safe.d.ts.map +1 -1
- package/dist/capabilities/analysis.d.ts +16 -1
- package/dist/capabilities/analysis.d.ts.map +1 -1
- package/dist/capabilities/lyrics.d.ts +17 -0
- package/dist/capabilities/lyrics.d.ts.map +1 -1
- package/dist/capabilities/music.provider.d.ts +51 -0
- package/dist/capabilities/music.provider.d.ts.map +1 -1
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -1
- package/dist/plugin.error.d.ts +14 -0
- package/dist/plugin.error.d.ts.map +1 -1
- package/dist/plugin.host.d.ts +29 -0
- package/dist/plugin.host.d.ts.map +1 -1
- package/dist/testing/fake.plugin.host.d.ts.map +1 -1
- package/dist/testing/index.js +5 -0
- package/dist/testing/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -287,6 +287,20 @@ Let these propagate unless you can do something better with them. The host
|
|
|
287
287
|
maps each one to a status and error code for the operator console, and
|
|
288
288
|
swallowing them turns a precise answer into a silent empty result.
|
|
289
289
|
|
|
290
|
+
When the upstream answers with a failure of its own, describe it on the error
|
|
291
|
+
rather than in a field you invent. `withUpstreamStatus` takes the HTTP status
|
|
292
|
+
and `withUpstreamCode` takes the service's own code, as it sent it, a number or
|
|
293
|
+
a string (Last.fm's `6`, Spotify's `reason`). Both reach the host's logs through
|
|
294
|
+
the invoker's wrapping, and neither is ever sent to a client. A subclass that
|
|
295
|
+
branches on the code reads `this.upstreamCode`; it must not declare a field of
|
|
296
|
+
that name, because the base class already owns it:
|
|
297
|
+
|
|
298
|
+
```ts
|
|
299
|
+
if (body.error !== undefined) {
|
|
300
|
+
throw new PluginError(body.message).withCode('not_found').withUpstreamStatus(response.status).withUpstreamCode(body.error);
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
290
304
|
## When the body should not arrive whole
|
|
291
305
|
|
|
292
306
|
Nothing special. `response.body` is a `ReadableStream<Uint8Array>` and you read
|
|
@@ -992,6 +1006,12 @@ end from the next line's start, and a blank timed line (which LRC uses to mark
|
|
|
992
1006
|
where singing stops) is kept as one. An `instrumental` answer is an answer: the
|
|
993
1007
|
host stops asking and treats the record as one nobody sings on.
|
|
994
1008
|
|
|
1009
|
+
**Set `words` on a line only when your source times its words.** Each piece is
|
|
1010
|
+
a word or syllable with the time it starts being sung, in order, and the pieces'
|
|
1011
|
+
texts joined must be the line's `text` exactly, spaces included: a reader lights
|
|
1012
|
+
a prefix of the line, so the host drops a line's words whole when they do not
|
|
1013
|
+
join up, go back in time, or number more than 200, and shows it as a line.
|
|
1014
|
+
|
|
995
1015
|
## Playing the station on a speaker
|
|
996
1016
|
|
|
997
1017
|
An `output` plugin puts the station on a Chromecast, a Sonos, a BluOS player or
|
|
@@ -1085,12 +1105,37 @@ ones it implements in `manifest.capabilities`:
|
|
|
1085
1105
|
fetcher a login and return the URL it gives you back; see _When your audio
|
|
1086
1106
|
needs a helper to fetch it_ above.
|
|
1087
1107
|
|
|
1108
|
+
**If fetching that URL takes longer than a download, say so with
|
|
1109
|
+
`fetchBudgetMs`.** The host allows 90 seconds, which suits every provider whose
|
|
1110
|
+
audio transfers — the Spotify shim measures a 320kbps Ogg at 664ms. It does not
|
|
1111
|
+
suit a source whose audio is PERFORMED rather than transferred: a record
|
|
1112
|
+
captured in real time takes its own duration to arrive, and cut off at 90
|
|
1113
|
+
seconds it looks like an upstream that hung. Send the worst honest case, in
|
|
1114
|
+
integer milliseconds; the host clamps it, never shortens its own floor, and a
|
|
1115
|
+
fetch that finishes early costs nothing. Do not reach for it because a provider
|
|
1116
|
+
is merely slow — a large number there only delays the retry that would have
|
|
1117
|
+
fixed it.
|
|
1118
|
+
|
|
1088
1119
|
This capability is a URL, not bytes. Audio that reaches the station as bytes
|
|
1089
1120
|
through Node is the exceptional path and always was, even now that
|
|
1090
1121
|
`response.body` makes it trivial: the audio consumer is Liquidsoap in a
|
|
1091
1122
|
sibling container, so a URL it can fetch is zero copies and a stream through
|
|
1092
1123
|
here is two.
|
|
1093
1124
|
|
|
1125
|
+
`reportPlayback` is the optional other half, for a service that expects
|
|
1126
|
+
the client that fetched a record to say it is being played. The host calls
|
|
1127
|
+
it with `started` when one of your records goes to air and `ended`, with the
|
|
1128
|
+
`elapsedMs` heard, when the next item does, from a job: late, retried on a
|
|
1129
|
+
thrown `PluginError`, and not guaranteed in order. Leave it out unless your
|
|
1130
|
+
upstream wants it. It is not a scrobble, which reports to somebody's
|
|
1131
|
+
listening history by title and artist; this carries the id you served.
|
|
1132
|
+
|
|
1133
|
+
A refusal that belongs to the ACCOUNT rather than the record, such as a
|
|
1134
|
+
stream already playing on another device or a spent quota, should be
|
|
1135
|
+
thrown as `unavailable` or `rate_limited` (with `retryAfterMs` when you
|
|
1136
|
+
know it). The host then puts that fetch off without counting it against
|
|
1137
|
+
the copy, where any other failure counts toward benching it.
|
|
1138
|
+
|
|
1094
1139
|
- **`steer`** — `enqueue`, `play`, `pause`, `skip`, `getPlaybackState`. The
|
|
1095
1140
|
provider owns the audio output and deadair only tells it what to do. Named
|
|
1096
1141
|
from the plugin's side on purpose: deadair's own `playout` module is the
|
|
@@ -44,18 +44,18 @@ import type { NarrationPart, NarrationPiece, NarrationPiecesQuery, NarrationSeri
|
|
|
44
44
|
import type { NewsFeedDescriptor, NewsItem, NewsQuery } from './capabilities/news.js';
|
|
45
45
|
import type { PodcastAudio, PodcastDirectoryEntry, PodcastDirectoryQuery, PodcastEpisode, PodcastEpisodesQuery, PodcastShow } from './capabilities/podcast.js';
|
|
46
46
|
import type { InboundMessage, MessagingAction, MessagingAnnounceTarget, MessagingButton, MessagingCommand, MessagingReceiveQuery, MessagingReceiveResult, MessagingSendResult, MessagingSender, OutboundMessage } from './capabilities/messaging.js';
|
|
47
|
-
import type { LyricLine, TrackLyrics } from './capabilities/lyrics.js';
|
|
47
|
+
import type { LyricLine, LyricWord, TrackLyrics } from './capabilities/lyrics.js';
|
|
48
48
|
import type { OutputDevice, OutputMetadata, OutputMetadataRequest, OutputPlayRequest, OutputStatus } from './capabilities/output.js';
|
|
49
49
|
import type { ScrobblePlay, ScrobbleRejection, ScrobbleResult } from './capabilities/scrobble.js';
|
|
50
50
|
import type { SearchQuery, SearchResult } from './capabilities/search.js';
|
|
51
51
|
import type { ArtistTrack, SimilarArtist } from './capabilities/similarity.js';
|
|
52
52
|
import type { WeatherConditions, WeatherDay, WeatherQuery, WeatherReading } from './capabilities/weather.js';
|
|
53
53
|
import type { AlbumEnrichment, AlbumRef, ArtistEnrichment, ArtistRef, ExternalId, ExternalLink, SourceDocument, TrackEnrichment, TrackRef } from './capabilities/enrichment.js';
|
|
54
|
-
import type { GetPlaylistTracksOptions, ListPlaylistsOptions, PlaybackState, ProviderPlaylist, ProviderStream, ProviderTrack, SearchTracksOptions } from './capabilities/music.provider.js';
|
|
54
|
+
import type { GetPlaylistTracksOptions, ListPlaylistsOptions, PlaybackReport, PlaybackState, ProviderPlaylist, ProviderStream, ProviderTrack, SearchTracksOptions } from './capabilities/music.provider.js';
|
|
55
55
|
import type { LlmMessage, LlmModelInfo, LlmRequest, LlmResult, LlmToolCall, LlmToolDeclaration, LlmUsage } from './capabilities/llm.js';
|
|
56
56
|
import type { SpeechLimits, SpeechRequest, SpeechVoice } from './capabilities/speech.js';
|
|
57
57
|
import type { ConfigField, ConfigFieldColumn, ConfigFieldOption, ConfigFieldPreset } from './plugin.config.fields.js';
|
|
58
|
-
import type { DiscoveredService, DiscoveryOptions, DiscoveryQuery, PlaylistTracksRequest, PluginSocketOptions, PluginTlsOptions, TrackFetchRequest, TrackFetchSession } from './plugin.host.js';
|
|
58
|
+
import type { DiscoveredService, DiscoveryOptions, DiscoveryQuery, PlayerFetchRequest, PlaylistTracksRequest, PluginSocketOptions, PluginTlsOptions, TrackFetchRequest, TrackFetchSession } from './plugin.host.js';
|
|
59
59
|
import type { PluginConnectionResult } from './plugin.lifecycle.js';
|
|
60
60
|
import type { PluginManifest } from './plugin.manifest.js';
|
|
61
61
|
import type { NetworkPermissionFromConfig, NetworkPermissionHost, PluginGrantRequest, PluginPermissions } from './plugin.permissions.js';
|
|
@@ -121,6 +121,7 @@ export type AssertAllBoundaryPayloadsAreJsonSafe = AssertAllTrue<{
|
|
|
121
121
|
ProviderStream: IsJsonSafe<ProviderStream>;
|
|
122
122
|
TrackFetchSession: IsJsonSafe<TrackFetchSession>;
|
|
123
123
|
TrackFetchRequest: IsJsonSafe<TrackFetchRequest>;
|
|
124
|
+
PlayerFetchRequest: IsJsonSafe<PlayerFetchRequest>;
|
|
124
125
|
PlaylistTracksRequest: IsJsonSafe<PlaylistTracksRequest>;
|
|
125
126
|
PluginSocketOptions: IsJsonSafe<PluginSocketOptions>;
|
|
126
127
|
PluginTlsOptions: IsJsonSafe<PluginTlsOptions>;
|
|
@@ -130,6 +131,7 @@ export type AssertAllBoundaryPayloadsAreJsonSafe = AssertAllTrue<{
|
|
|
130
131
|
SearchTracksOptions: IsJsonSafe<SearchTracksOptions>;
|
|
131
132
|
ListPlaylistsOptions: IsJsonSafe<ListPlaylistsOptions>;
|
|
132
133
|
GetPlaylistTracksOptions: IsJsonSafe<GetPlaylistTracksOptions>;
|
|
134
|
+
PlaybackReport: IsJsonSafe<PlaybackReport>;
|
|
133
135
|
PlaybackState: IsJsonSafe<PlaybackState>;
|
|
134
136
|
TrackRef: IsJsonSafe<TrackRef>;
|
|
135
137
|
ArtistRef: IsJsonSafe<ArtistRef>;
|
|
@@ -206,6 +208,7 @@ export type AssertAllBoundaryPayloadsAreJsonSafe = AssertAllTrue<{
|
|
|
206
208
|
OutputMetadataRequest: IsJsonSafe<OutputMetadataRequest>;
|
|
207
209
|
OutputStatus: IsJsonSafe<OutputStatus>;
|
|
208
210
|
LyricLine: IsJsonSafe<LyricLine>;
|
|
211
|
+
LyricWord: IsJsonSafe<LyricWord>;
|
|
209
212
|
TrackLyrics: IsJsonSafe<TrackLyrics>;
|
|
210
213
|
SpeechLimits: IsJsonSafe<SpeechLimits>;
|
|
211
214
|
}>;
|
|
@@ -214,7 +217,7 @@ export type AssertAllBoundaryPayloadsAreJsonSafe = AssertAllTrue<{
|
|
|
214
217
|
* registry-coverage test can compare it against what is actually exported
|
|
215
218
|
* from the boundary source files.
|
|
216
219
|
*/
|
|
217
|
-
export declare const JSON_SAFE_PAYLOAD_TYPES: readonly ["PluginConnectionResult", "PluginPermissions", "NetworkPermissionHost", "NetworkPermissionFromConfig", "PluginGrantRequest", "ConfigField", "ConfigFieldOption", "ConfigFieldColumn", "ConfigFieldPreset", "PluginManifest", "ProviderTrack", "ProviderPlaylist", "ProviderStream", "TrackFetchSession", "TrackFetchRequest", "PlaylistTracksRequest", "PluginSocketOptions", "PluginTlsOptions", "DiscoveryOptions", "DiscoveredService", "SearchTracksOptions", "ListPlaylistsOptions", "GetPlaylistTracksOptions", "PlaybackState", "TrackRef", "ArtistRef", "AlbumRef", "ExternalId", "ExternalLink", "SourceDocument", "TrackEnrichment", "ArtistEnrichment", "AlbumEnrichment", "SpeechRequest", "SpeechVoice", "LlmMessage", "LlmToolDeclaration", "LlmToolCall", "LlmUsage", "LlmRequest", "LlmResult", "LlmModelInfo", "AnalysisRef", "AudioJoin", "AudioOverlay", "AudioTranscode", "TrackCuePoints", "TrackLoudness", "TrackTaggedLoudness", "TrackAnalysis", "ChartDescriptor", "ChartQuery", "ChartEntry", "NewsFeedDescriptor", "NewsQuery", "NewsItem", "NarrationSeries", "NarrationPiece", "NarrationPart", "NarrationText", "NarrationPiecesQuery", "NarrationTextQuery", "PodcastShow", "PodcastAudio", "PodcastEpisode", "PodcastEpisodesQuery", "PodcastDirectoryQuery", "PodcastDirectoryEntry", "SimilarArtist", "ArtistTrack", "SearchQuery", "SearchResult", "WeatherQuery", "WeatherConditions", "WeatherDay", "WeatherReading", "AlmanacQuery", "AlmanacSubject", "AlmanacEntry", "AlmanacDay", "ScrobblePlay", "ScrobbleRejection", "ScrobbleResult", "MessagingSender", "MessagingAction", "MessagingButton", "InboundMessage", "MessagingReceiveQuery", "MessagingReceiveResult", "OutboundMessage", "MessagingSendResult", "MessagingAnnounceTarget", "MessagingCommand", "OutputDevice", "OutputMetadata", "OutputPlayRequest", "OutputMetadataRequest", "OutputStatus", "LyricLine", "TrackLyrics", "SpeechLimits"];
|
|
220
|
+
export declare const JSON_SAFE_PAYLOAD_TYPES: readonly ["PluginConnectionResult", "PluginPermissions", "NetworkPermissionHost", "NetworkPermissionFromConfig", "PluginGrantRequest", "ConfigField", "ConfigFieldOption", "ConfigFieldColumn", "ConfigFieldPreset", "PluginManifest", "ProviderTrack", "ProviderPlaylist", "ProviderStream", "TrackFetchSession", "TrackFetchRequest", "PlayerFetchRequest", "PlaylistTracksRequest", "PluginSocketOptions", "PluginTlsOptions", "DiscoveryOptions", "DiscoveredService", "SearchTracksOptions", "ListPlaylistsOptions", "GetPlaylistTracksOptions", "PlaybackReport", "PlaybackState", "TrackRef", "ArtistRef", "AlbumRef", "ExternalId", "ExternalLink", "SourceDocument", "TrackEnrichment", "ArtistEnrichment", "AlbumEnrichment", "SpeechRequest", "SpeechVoice", "LlmMessage", "LlmToolDeclaration", "LlmToolCall", "LlmUsage", "LlmRequest", "LlmResult", "LlmModelInfo", "AnalysisRef", "AudioJoin", "AudioOverlay", "AudioTranscode", "TrackCuePoints", "TrackLoudness", "TrackTaggedLoudness", "TrackAnalysis", "ChartDescriptor", "ChartQuery", "ChartEntry", "NewsFeedDescriptor", "NewsQuery", "NewsItem", "NarrationSeries", "NarrationPiece", "NarrationPart", "NarrationText", "NarrationPiecesQuery", "NarrationTextQuery", "PodcastShow", "PodcastAudio", "PodcastEpisode", "PodcastEpisodesQuery", "PodcastDirectoryQuery", "PodcastDirectoryEntry", "SimilarArtist", "ArtistTrack", "SearchQuery", "SearchResult", "WeatherQuery", "WeatherConditions", "WeatherDay", "WeatherReading", "AlmanacQuery", "AlmanacSubject", "AlmanacEntry", "AlmanacDay", "ScrobblePlay", "ScrobbleRejection", "ScrobbleResult", "MessagingSender", "MessagingAction", "MessagingButton", "InboundMessage", "MessagingReceiveQuery", "MessagingReceiveResult", "OutboundMessage", "MessagingSendResult", "MessagingAnnounceTarget", "MessagingCommand", "OutputDevice", "OutputMetadata", "OutputPlayRequest", "OutputMetadataRequest", "OutputStatus", "LyricLine", "LyricWord", "TrackLyrics", "SpeechLimits"];
|
|
218
221
|
/**
|
|
219
222
|
* Boundary interfaces that are deliberately NOT payloads: they describe
|
|
220
223
|
* methods, so they carry functions by definition and can never be JSON-safe.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boundary.json.safe.d.ts","sourceRoot":"","sources":["../src/boundary.json.safe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACxG,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjI,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACxF,OAAO,KAAK,EACR,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,aAAa,EACb,kBAAkB,EACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,kBAAkB,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,KAAK,EACR,YAAY,EACZ,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,oBAAoB,EACpB,WAAW,EACd,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EACR,cAAc,EACd,eAAe,EACf,uBAAuB,EACvB,eAAe,EACf,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,eAAe,EACf,eAAe,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"boundary.json.safe.d.ts","sourceRoot":"","sources":["../src/boundary.json.safe.ts"],"names":[],"mappings":"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"}
|
|
@@ -76,6 +76,19 @@ import type { PluginLifecycle } from '../plugin.lifecycle.js';
|
|
|
76
76
|
* drifted apart across an upgrade.
|
|
77
77
|
*/
|
|
78
78
|
export declare const ANALYSIS_SCHEMA_VERSION = 1;
|
|
79
|
+
/**
|
|
80
|
+
* Why a measurement failed, finer than the `upstream` code all three share, carried as a
|
|
81
|
+
* `PluginError`'s `upstreamCode`.
|
|
82
|
+
*
|
|
83
|
+
* The host retries them on different clocks, because they are facts about different things.
|
|
84
|
+
* `undecodable` is a property of the FILE, so retrying it soon is a full download and decode of the
|
|
85
|
+
* same bytes. `unfetchable` is a property of the binding or the moment (a provider was down, a signed
|
|
86
|
+
* url expired), and `truncated` is a fetch that happened to deliver some bytes. A failure without one
|
|
87
|
+
* of these is treated as `undecodable`.
|
|
88
|
+
*/
|
|
89
|
+
export declare const ANALYSIS_FAILURE_CODES: readonly ["unfetchable", "undecodable", "truncated"];
|
|
90
|
+
/** One of {@link ANALYSIS_FAILURE_CODES}. */
|
|
91
|
+
export type AnalysisFailureCode = (typeof ANALYSIS_FAILURE_CODES)[number];
|
|
79
92
|
/**
|
|
80
93
|
* How the host asks about one track.
|
|
81
94
|
*
|
|
@@ -323,7 +336,9 @@ export interface AnalysisProvider extends PluginLifecycle {
|
|
|
323
336
|
*
|
|
324
337
|
* @throws {PluginError} `config` when the plugin is not set up enough to try
|
|
325
338
|
* (no analyzer address), `upstream` when the audio could not be fetched or
|
|
326
|
-
* could not be decoded, `timeout` when the analyzer did not answer.
|
|
339
|
+
* could not be decoded, `timeout` when the analyzer did not answer. An `upstream`
|
|
340
|
+
* failure should carry which of {@link ANALYSIS_FAILURE_CODES} it was as its
|
|
341
|
+
* `upstreamCode`, so the host can retry it on the right clock.
|
|
327
342
|
*/
|
|
328
343
|
analyzeTrack(ref: AnalysisRef): Promise<TrackAnalysis>;
|
|
329
344
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../../src/capabilities/analysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IACxB;;;;;;OAMG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;;;;;;;;;OAWG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,cAAc;IAC3B,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IAEd;;;;;;OAMG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,aAAa;IAC1B;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,mBAAmB;IAChC;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC1B;;;;;;;;OAQG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;;;;;;;;;;;;;OAcG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;;;;;;;;;;;OAYG;IACH,IAAI,EAAE,cAAc,GAAG,aAAa,GAAG,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAErF;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,iDAAiD;AACjD,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACrD
|
|
1
|
+
{"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../../src/capabilities/analysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,sDAAuD,CAAC;AAE3F,6CAA6C;AAC7C,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IACxB;;;;;;OAMG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;;;;;;;;;OAWG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,cAAc;IAC3B,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IAEd;;;;;;OAMG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,aAAa;IAC1B;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,mBAAmB;IAChC;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC1B;;;;;;;;OAQG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;;;;;;;;;;;;;OAcG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;;;;;;;;;;;OAYG;IACH,IAAI,EAAE,cAAc,GAAG,aAAa,GAAG,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAErF;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,iDAAiD;AACjD,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACrD;;;;;;;;;;;;;;;;;OAiBG;IACH,YAAY,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CAC1D"}
|
|
@@ -36,6 +36,14 @@ import type { TrackRef } from './enrichment.js';
|
|
|
36
36
|
* client should throw rather than answer `{}`, because a refusal that reads as
|
|
37
37
|
* a miss is an empty library nobody is told about.
|
|
38
38
|
*/
|
|
39
|
+
/**
|
|
40
|
+
* One timed word, or syllable, inside a line: the stretch of the line that
|
|
41
|
+
* starts being sung at `atMs`, in milliseconds from the start of the recording.
|
|
42
|
+
*/
|
|
43
|
+
export interface LyricWord {
|
|
44
|
+
atMs: number;
|
|
45
|
+
text: string;
|
|
46
|
+
}
|
|
39
47
|
/**
|
|
40
48
|
* One timed line.
|
|
41
49
|
*
|
|
@@ -43,11 +51,20 @@ import type { TrackRef } from './enrichment.js';
|
|
|
43
51
|
* `endMs` is its end when the source publishes one; leave it unset rather than
|
|
44
52
|
* guessing, because the host derives an end from the next line's start and a
|
|
45
53
|
* guessed one would be believed.
|
|
54
|
+
*
|
|
55
|
+
* `words` is the line cut where the source timed it, when the source times
|
|
56
|
+
* words at all, and unset when it does not. The pieces are in order, their
|
|
57
|
+
* `atMs` never goes backwards, and their texts JOINED are exactly `text`,
|
|
58
|
+
* spaces included: a piece may be a whole word with the space after it, or a
|
|
59
|
+
* syllable with none, so a reader lights a prefix of the line rather than
|
|
60
|
+
* guessing where one word ends. The host drops a line's words whole when they
|
|
61
|
+
* break that rule, and the line is shown as a line.
|
|
46
62
|
*/
|
|
47
63
|
export interface LyricLine {
|
|
48
64
|
atMs: number;
|
|
49
65
|
endMs?: number;
|
|
50
66
|
text: string;
|
|
67
|
+
words?: LyricWord[];
|
|
51
68
|
}
|
|
52
69
|
/**
|
|
53
70
|
* What a source knows about one record's words. Return `{}` on no match.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lyrics.d.ts","sourceRoot":"","sources":["../../src/capabilities/lyrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH
|
|
1
|
+
{"version":3,"file":"lyrics.d.ts","sourceRoot":"","sources":["../../src/capabilities/lyrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH;;;GAGG;AACH,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,WAAW;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC3B;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB,kFAAkF;IAClF,SAAS,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CAClD"}
|
|
@@ -158,6 +158,24 @@ export interface ProviderStream {
|
|
|
158
158
|
expiresAt?: number;
|
|
159
159
|
/** e.g. `audio/mpeg`. */
|
|
160
160
|
mimeType?: string;
|
|
161
|
+
/**
|
|
162
|
+
* How long fetching this URL may reasonably take, in integer milliseconds.
|
|
163
|
+
*
|
|
164
|
+
* Absent means "as fast as a download", which is what every provider here was until now: the
|
|
165
|
+
* station allows 90 seconds and a 320kbps Ogg off the Spotify shim arrives in 664ms. Set it only
|
|
166
|
+
* when that assumption is wrong for a REASON the provider knows and the host cannot guess.
|
|
167
|
+
*
|
|
168
|
+
* The case it exists for is a source that plays in real time rather than transferring: audio
|
|
169
|
+
* that reaches the station by being performed into a capture, where a four-minute record takes
|
|
170
|
+
* four minutes and there is no faster path to it. Left unset, such a source is cut off mid-record
|
|
171
|
+
* by a timeout meant for a download, and the failure looks like an upstream that hung.
|
|
172
|
+
*
|
|
173
|
+
* It is a CEILING and not a promise. The host clamps it to a maximum of its own, and a fetch that
|
|
174
|
+
* finishes sooner costs nothing — so the number to send is how long this may honestly take at
|
|
175
|
+
* worst, not how long it usually takes. Sending a large number for a source that is merely slow
|
|
176
|
+
* buys nothing and delays the retry that would have fixed it.
|
|
177
|
+
*/
|
|
178
|
+
fetchBudgetMs?: number;
|
|
161
179
|
}
|
|
162
180
|
export interface SearchTracksOptions {
|
|
163
181
|
limit?: number;
|
|
@@ -240,6 +258,39 @@ export interface MusicProviderStream {
|
|
|
240
258
|
* available", skips the item, and holds nothing against the plugin.
|
|
241
259
|
*/
|
|
242
260
|
resolveStreamUrl?(trackId: string): Promise<ProviderStream | undefined>;
|
|
261
|
+
/**
|
|
262
|
+
* Hear that a copy you served went to air, or came off it.
|
|
263
|
+
*
|
|
264
|
+
* Some services expect the client that fetched a record to say it is being played, the way their
|
|
265
|
+
* own apps do, and an account that only ever fetches looks like nothing a listener would run.
|
|
266
|
+
* This is how a provider says so: the host calls it with `started` when one of YOUR records goes
|
|
267
|
+
* to air and `ended` when the next item does, and for nothing else's.
|
|
268
|
+
*
|
|
269
|
+
* Optional, and most providers should leave it out: a library server or a service that does not
|
|
270
|
+
* care has nothing to report. Called from a job rather than on the boundary itself, so it is late
|
|
271
|
+
* by however long the queue takes, may be retried, and the two events for one record are not
|
|
272
|
+
* guaranteed to arrive in order. Throw a `PluginError` for a failure worth retrying; anything that
|
|
273
|
+
* returns is taken as reported.
|
|
274
|
+
*
|
|
275
|
+
* It is NOT a scrobble. A scrobble reports listening to somebody's history and carries a title
|
|
276
|
+
* and an artist; this tells the service that served the bytes what became of them, and carries
|
|
277
|
+
* the id it served them under.
|
|
278
|
+
*/
|
|
279
|
+
reportPlayback?(trackId: string, report: PlaybackReport): Promise<void>;
|
|
280
|
+
}
|
|
281
|
+
/** What became of a served copy on air. Every field is JSON-safe. */
|
|
282
|
+
export interface PlaybackReport {
|
|
283
|
+
/** `started` when the record went to air, `ended` when the next item did. */
|
|
284
|
+
event: 'started' | 'ended';
|
|
285
|
+
/** When the record went to air, as Unix epoch MILLISECONDS. The same on both events for one play. */
|
|
286
|
+
startedAt: number;
|
|
287
|
+
/**
|
|
288
|
+
* How much of it went out, in integer milliseconds. On `ended` only.
|
|
289
|
+
*
|
|
290
|
+
* Wall time from going to air to the next item doing so, which is shorter than the record when
|
|
291
|
+
* it was cut short and may be a little longer than it across a crossfade.
|
|
292
|
+
*/
|
|
293
|
+
elapsedMs?: number;
|
|
243
294
|
}
|
|
244
295
|
export type PlaybackStatus = 'playing' | 'paused' | 'stopped';
|
|
245
296
|
export interface PlaybackState {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"music.provider.d.ts","sourceRoot":"","sources":["../../src/capabilities/music.provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,4FAA4F;AAC5F,MAAM,WAAW,aAAa;IAC1B,sDAAsD;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,qFAAqF;IACrF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uFAAuF;IACvF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kIAAkI;IAClI,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;;;OAgBG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;;;;OAiBG;IACH,QAAQ,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;CACnC;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,0BAA0B;AAClC,oDAAoD;AAClD,MAAM;AACR,8DAA8D;GAC5D,MAAM,CAAC;AAEb,MAAM,WAAW,gBAAgB;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;;;;;OAkBG;IACH,WAAW,CAAC,EAAE,0BAA0B,EAAE,CAAC;IAC3C;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,+DAA+D;AAC/D,MAAM,WAAW,cAAc;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"music.provider.d.ts","sourceRoot":"","sources":["../../src/capabilities/music.provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,4FAA4F;AAC5F,MAAM,WAAW,aAAa;IAC1B,sDAAsD;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,qFAAqF;IACrF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uFAAuF;IACvF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kIAAkI;IAClI,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;;;OAgBG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;;;;OAiBG;IACH,QAAQ,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;CACnC;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,0BAA0B;AAClC,oDAAoD;AAClD,MAAM;AACR,8DAA8D;GAC5D,MAAM,CAAC;AAEb,MAAM,WAAW,gBAAgB;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;;;;;OAkBG;IACH,WAAW,CAAC,EAAE,0BAA0B,EAAE,CAAC;IAC3C;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,+DAA+D;AAC/D,MAAM,WAAW,cAAc;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;;;;;;;;;OAgBG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,wBAAwB;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,yBAAyB;AACzB,MAAM,WAAW,oBAAoB;IACjC;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAErF,sEAAsE;IACtE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;IAE9D,aAAa,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAE3E,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAEpG;;;;;;;;;;;;;;OAcG;IACH,iBAAiB,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACvD;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,mBAAmB;IAChC;;;;;;;;;OASG;IACH,gBAAgB,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IAExE;;;;;;;;;;;;;;;;;OAiBG;IACH,cAAc,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3E;AAED,qEAAqE;AACrE,MAAM,WAAW,cAAc;IAC3B,6EAA6E;IAC7E,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC;IAC3B,qGAAqG;IACrG,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE9D,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,cAAc,CAAC;IACvB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IAC/B,oDAAoD;IACpD,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,uEAAuE;IACvE,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,gBAAgB,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;CAC9C;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IAC/B,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjE;AAED;;;GAGG;AACH,MAAM,WAAW,aAAc,SAAQ,oBAAoB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,kBAAkB;CAAG"}
|
package/dist/index.js
CHANGED
|
@@ -19,6 +19,7 @@ var JSON_SAFE_PAYLOAD_TYPES = [
|
|
|
19
19
|
"ProviderStream",
|
|
20
20
|
"TrackFetchSession",
|
|
21
21
|
"TrackFetchRequest",
|
|
22
|
+
"PlayerFetchRequest",
|
|
22
23
|
"PlaylistTracksRequest",
|
|
23
24
|
"PluginSocketOptions",
|
|
24
25
|
"PluginTlsOptions",
|
|
@@ -27,6 +28,7 @@ var JSON_SAFE_PAYLOAD_TYPES = [
|
|
|
27
28
|
"SearchTracksOptions",
|
|
28
29
|
"ListPlaylistsOptions",
|
|
29
30
|
"GetPlaylistTracksOptions",
|
|
31
|
+
"PlaybackReport",
|
|
30
32
|
"PlaybackState",
|
|
31
33
|
"TrackRef",
|
|
32
34
|
"ArtistRef",
|
|
@@ -103,6 +105,7 @@ var JSON_SAFE_PAYLOAD_TYPES = [
|
|
|
103
105
|
"OutputMetadataRequest",
|
|
104
106
|
"OutputStatus",
|
|
105
107
|
"LyricLine",
|
|
108
|
+
"LyricWord",
|
|
106
109
|
"TrackLyrics",
|
|
107
110
|
"SpeechLimits"
|
|
108
111
|
];
|
|
@@ -165,6 +168,11 @@ var BOUNDARY_LIVE_OBJECT_TYPES = [
|
|
|
165
168
|
|
|
166
169
|
// src/capabilities/analysis.ts
|
|
167
170
|
var ANALYSIS_SCHEMA_VERSION = 1;
|
|
171
|
+
var ANALYSIS_FAILURE_CODES = [
|
|
172
|
+
"unfetchable",
|
|
173
|
+
"undecodable",
|
|
174
|
+
"truncated"
|
|
175
|
+
];
|
|
168
176
|
|
|
169
177
|
// src/capabilities/enrichment.ts
|
|
170
178
|
var ENRICHMENT_MATCH_KEY_ISRC = "isrc";
|
|
@@ -226,6 +234,19 @@ var PluginError = class extends Error {
|
|
|
226
234
|
* Diagnostic only: the host never forwards it as its own response status.
|
|
227
235
|
*/
|
|
228
236
|
upstreamStatus;
|
|
237
|
+
/**
|
|
238
|
+
* The upstream's own code for what went wrong, as it sent it: Last.fm's
|
|
239
|
+
* error number, Spotify's `reason`, an analyzer's `unfetchable` against
|
|
240
|
+
* `undecodable`. Finer than {@link code}, which is the host's vocabulary
|
|
241
|
+
* and the only thing the host maps to a response.
|
|
242
|
+
*
|
|
243
|
+
* This is the one place for it. A subclass that wants to branch on its
|
|
244
|
+
* upstream's code reads it here rather than declaring a field of its own,
|
|
245
|
+
* so the code survives the invoker's wrapping and reaches the host's logs.
|
|
246
|
+
* A capability that reads it says which values it knows, and the host
|
|
247
|
+
* ignores one it does not.
|
|
248
|
+
*/
|
|
249
|
+
upstreamCode;
|
|
229
250
|
constructor(message, options) {
|
|
230
251
|
super(message, options);
|
|
231
252
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
@@ -251,6 +272,10 @@ var PluginError = class extends Error {
|
|
|
251
272
|
this.upstreamStatus = upstreamStatus;
|
|
252
273
|
return this;
|
|
253
274
|
}
|
|
275
|
+
withUpstreamCode(upstreamCode) {
|
|
276
|
+
this.upstreamCode = upstreamCode;
|
|
277
|
+
return this;
|
|
278
|
+
}
|
|
254
279
|
};
|
|
255
280
|
var isPluginError = /* @__PURE__ */ __name((error) => {
|
|
256
281
|
return error instanceof PluginError;
|
|
@@ -270,6 +295,8 @@ function toPluginError(error, fallback = "internal") {
|
|
|
270
295
|
}).withCode(known ? error.code : fallback);
|
|
271
296
|
if (typeof error.retryAfterMs === "number" && Number.isFinite(error.retryAfterMs)) adopted.withRetry(error.retryAfterMs);
|
|
272
297
|
if (typeof error.upstreamStatus === "number" && Number.isFinite(error.upstreamStatus)) adopted.withUpstreamStatus(error.upstreamStatus);
|
|
298
|
+
if (typeof error.upstreamCode === "string" && error.upstreamCode.length > 0) adopted.withUpstreamCode(error.upstreamCode.slice(0, 64));
|
|
299
|
+
if (typeof error.upstreamCode === "number" && Number.isFinite(error.upstreamCode)) adopted.withUpstreamCode(error.upstreamCode);
|
|
273
300
|
return adopted;
|
|
274
301
|
}
|
|
275
302
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1320,6 +1347,7 @@ var pluginManifestSchema = z3.object({
|
|
|
1320
1347
|
})
|
|
1321
1348
|
});
|
|
1322
1349
|
export {
|
|
1350
|
+
ANALYSIS_FAILURE_CODES,
|
|
1323
1351
|
ANALYSIS_SCHEMA_VERSION,
|
|
1324
1352
|
ARTICLE_MAX_CHARS,
|
|
1325
1353
|
BOUNDARY_LIVE_OBJECT_TYPES,
|