@nuclearplayer/plugin-sdk 0.0.14 → 1.1.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/dist/index.d.ts +239 -13
- package/dist/index.js +265 -35
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export declare type Album = {
|
|
|
11
11
|
source: ProviderRef;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
+
export declare type AlbumMetadataCapability = 'albumDetails';
|
|
15
|
+
|
|
14
16
|
export declare type AlbumRef = {
|
|
15
17
|
title: string;
|
|
16
18
|
artists?: ArtistRef[];
|
|
@@ -97,6 +99,76 @@ export declare type EnumWidget = {
|
|
|
97
99
|
type: 'radio';
|
|
98
100
|
};
|
|
99
101
|
|
|
102
|
+
export declare type FavoriteEntry<T> = {
|
|
103
|
+
ref: T;
|
|
104
|
+
addedAtIso: string;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export declare class FavoritesAPI {
|
|
108
|
+
#private;
|
|
109
|
+
constructor(host?: FavoritesHost);
|
|
110
|
+
getTracks(): Promise<FavoriteEntry<Track>[]>;
|
|
111
|
+
getAlbums(): Promise<FavoriteEntry<AlbumRef>[]>;
|
|
112
|
+
getArtists(): Promise<FavoriteEntry<ArtistRef>[]>;
|
|
113
|
+
addTrack(track: Track): Promise<void>;
|
|
114
|
+
removeTrack(source: ProviderRef): Promise<void>;
|
|
115
|
+
isTrackFavorite(source: ProviderRef): Promise<boolean>;
|
|
116
|
+
addAlbum(ref: AlbumRef): Promise<void>;
|
|
117
|
+
removeAlbum(source: ProviderRef): Promise<void>;
|
|
118
|
+
isAlbumFavorite(source: ProviderRef): Promise<boolean>;
|
|
119
|
+
addArtist(ref: ArtistRef): Promise<void>;
|
|
120
|
+
removeArtist(source: ProviderRef): Promise<void>;
|
|
121
|
+
isArtistFavorite(source: ProviderRef): Promise<boolean>;
|
|
122
|
+
subscribe(listener: FavoritesListener): () => void;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export declare type FavoritesData = {
|
|
126
|
+
tracks: FavoriteEntry<Track>[];
|
|
127
|
+
albums: FavoriteEntry<AlbumRef>[];
|
|
128
|
+
artists: FavoriteEntry<ArtistRef>[];
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export declare type FavoritesHost = {
|
|
132
|
+
getTracks: () => Promise<FavoriteEntry<Track>[]>;
|
|
133
|
+
getAlbums: () => Promise<FavoriteEntry<AlbumRef>[]>;
|
|
134
|
+
getArtists: () => Promise<FavoriteEntry<ArtistRef>[]>;
|
|
135
|
+
addTrack: (track: Track) => Promise<void>;
|
|
136
|
+
removeTrack: (source: ProviderRef) => Promise<void>;
|
|
137
|
+
isTrackFavorite: (source: ProviderRef) => Promise<boolean>;
|
|
138
|
+
addAlbum: (ref: AlbumRef) => Promise<void>;
|
|
139
|
+
removeAlbum: (source: ProviderRef) => Promise<void>;
|
|
140
|
+
isAlbumFavorite: (source: ProviderRef) => Promise<boolean>;
|
|
141
|
+
addArtist: (ref: ArtistRef) => Promise<void>;
|
|
142
|
+
removeArtist: (source: ProviderRef) => Promise<void>;
|
|
143
|
+
isArtistFavorite: (source: ProviderRef) => Promise<boolean>;
|
|
144
|
+
subscribe: (listener: FavoritesListener) => () => void;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export declare type FavoritesListener = (favorites: FavoritesData) => void;
|
|
148
|
+
|
|
149
|
+
export declare type FetchFunction = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
150
|
+
|
|
151
|
+
export declare class HttpAPI {
|
|
152
|
+
readonly fetch: FetchFunction;
|
|
153
|
+
constructor(host?: HttpHost);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export declare type HttpHost = {
|
|
157
|
+
fetch: (url: string, init?: HttpRequestInit) => Promise<HttpResponseData>;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
export declare type HttpRequestInit = {
|
|
161
|
+
method?: string;
|
|
162
|
+
headers?: Record<string, string>;
|
|
163
|
+
body?: string;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
export declare type HttpResponseData = {
|
|
167
|
+
status: number;
|
|
168
|
+
headers: Record<string, string>;
|
|
169
|
+
body: string;
|
|
170
|
+
};
|
|
171
|
+
|
|
100
172
|
export declare type LoadedPlugin = {
|
|
101
173
|
metadata: PluginMetadata;
|
|
102
174
|
instance: NuclearPlugin;
|
|
@@ -114,9 +186,30 @@ export declare type LocalFileInfo = {
|
|
|
114
186
|
scannedAtIso?: string;
|
|
115
187
|
};
|
|
116
188
|
|
|
189
|
+
declare class MetadataAPI {
|
|
190
|
+
#private;
|
|
191
|
+
constructor(host?: MetadataHost);
|
|
192
|
+
search(params: SearchParams, providerId?: string): Promise<SearchResults>;
|
|
193
|
+
fetchArtistDetails(artistId: string, providerId?: string): Promise<Artist>;
|
|
194
|
+
fetchArtistAlbums(artistId: string, providerId?: string): Promise<AlbumRef[]>;
|
|
195
|
+
fetchArtistTopTracks(artistId: string, providerId?: string): Promise<TrackRef[]>;
|
|
196
|
+
fetchArtistRelatedArtists(artistId: string, providerId?: string): Promise<ArtistRef[]>;
|
|
197
|
+
fetchAlbumDetails(albumId: string, providerId?: string): Promise<Album>;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export declare type MetadataHost = {
|
|
201
|
+
search: (params: SearchParams, providerId?: string) => Promise<SearchResults>;
|
|
202
|
+
fetchArtistDetails: (artistId: string, providerId?: string) => Promise<Artist>;
|
|
203
|
+
fetchArtistAlbums: (artistId: string, providerId?: string) => Promise<AlbumRef[]>;
|
|
204
|
+
fetchArtistTopTracks: (artistId: string, providerId?: string) => Promise<TrackRef[]>;
|
|
205
|
+
fetchArtistRelatedArtists: (artistId: string, providerId?: string) => Promise<ArtistRef[]>;
|
|
206
|
+
fetchAlbumDetails: (albumId: string, providerId?: string) => Promise<Album>;
|
|
207
|
+
};
|
|
208
|
+
|
|
117
209
|
export declare type MetadataProvider = ProviderDescriptor<'metadata'> & {
|
|
118
210
|
searchCapabilities?: SearchCapability[];
|
|
119
211
|
artistMetadataCapabilities?: ArtistMetadataCapability[];
|
|
212
|
+
albumMetadataCapabilities?: AlbumMetadataCapability[];
|
|
120
213
|
search?: (params: SearchParams) => Promise<SearchResults>;
|
|
121
214
|
searchArtists?: (params: Omit<SearchParams, 'types'>) => Promise<ArtistRef[]>;
|
|
122
215
|
searchAlbums?: (params: Omit<SearchParams, 'types'>) => Promise<AlbumRef[]>;
|
|
@@ -136,17 +229,29 @@ export declare class MissingCapabilityError extends Error {
|
|
|
136
229
|
export declare class NuclearAPI {
|
|
137
230
|
readonly Settings: Settings;
|
|
138
231
|
readonly Providers: Providers;
|
|
232
|
+
readonly Queue: QueueAPI;
|
|
233
|
+
readonly Streaming: StreamingAPI;
|
|
234
|
+
readonly Metadata: MetadataAPI;
|
|
235
|
+
readonly Http: HttpAPI;
|
|
236
|
+
readonly Ytdlp: YtdlpAPI;
|
|
237
|
+
readonly Favorites: FavoritesAPI;
|
|
139
238
|
constructor(opts?: {
|
|
140
239
|
settingsHost?: SettingsHost;
|
|
141
240
|
providersHost?: ProvidersHost;
|
|
241
|
+
queueHost?: QueueHost;
|
|
242
|
+
streamingHost?: StreamingHost;
|
|
243
|
+
metadataHost?: MetadataHost;
|
|
244
|
+
httpHost?: HttpHost;
|
|
245
|
+
ytdlpHost?: YtdlpHost;
|
|
246
|
+
favoritesHost?: FavoritesHost;
|
|
142
247
|
});
|
|
143
248
|
}
|
|
144
249
|
|
|
145
250
|
export declare type NuclearPlugin = {
|
|
146
251
|
onLoad?(api: NuclearPluginAPI): void | Promise<void>;
|
|
147
|
-
onUnload?(): void | Promise<void>;
|
|
252
|
+
onUnload?(api: NuclearPluginAPI): void | Promise<void>;
|
|
148
253
|
onEnable?(api: NuclearPluginAPI): void | Promise<void>;
|
|
149
|
-
onDisable?(): void | Promise<void>;
|
|
254
|
+
onDisable?(api: NuclearPluginAPI): void | Promise<void>;
|
|
150
255
|
};
|
|
151
256
|
|
|
152
257
|
export declare class NuclearPluginAPI extends NuclearAPI {
|
|
@@ -273,18 +378,76 @@ export declare type ProvidersHost = {
|
|
|
273
378
|
clear(): void;
|
|
274
379
|
};
|
|
275
380
|
|
|
381
|
+
export declare type Queue = {
|
|
382
|
+
items: QueueItem[];
|
|
383
|
+
currentIndex: number;
|
|
384
|
+
repeatMode: RepeatMode;
|
|
385
|
+
shuffleEnabled: boolean;
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
declare class QueueAPI {
|
|
389
|
+
#private;
|
|
390
|
+
constructor(host?: QueueHost);
|
|
391
|
+
getQueue(): Promise<Queue>;
|
|
392
|
+
getCurrentItem(): Promise<QueueItem | undefined>;
|
|
393
|
+
addToQueue(tracks: Track[]): Promise<void>;
|
|
394
|
+
addNext(tracks: Track[]): Promise<void>;
|
|
395
|
+
addAt(tracks: Track[], index: number): Promise<void>;
|
|
396
|
+
removeByIds(ids: string[]): Promise<void>;
|
|
397
|
+
removeByIndices(indices: number[]): Promise<void>;
|
|
398
|
+
clearQueue(): Promise<void>;
|
|
399
|
+
reorder(fromIndex: number, toIndex: number): Promise<void>;
|
|
400
|
+
updateItemState(id: string, updates: QueueItemStateUpdate): Promise<void>;
|
|
401
|
+
goToNext(): Promise<void>;
|
|
402
|
+
goToPrevious(): Promise<void>;
|
|
403
|
+
goToIndex(index: number): Promise<void>;
|
|
404
|
+
goToId(id: string): Promise<void>;
|
|
405
|
+
setRepeatMode(mode: RepeatMode): Promise<void>;
|
|
406
|
+
setShuffleEnabled(enabled: boolean): Promise<void>;
|
|
407
|
+
subscribe(listener: (queue: Queue) => void): () => void;
|
|
408
|
+
subscribeToCurrentItem(listener: (item: QueueItem | undefined) => void): () => void;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
export declare type QueueHost = {
|
|
412
|
+
getQueue: () => Promise<Queue>;
|
|
413
|
+
getCurrentItem: () => Promise<QueueItem | undefined>;
|
|
414
|
+
addToQueue: (tracks: Track[]) => Promise<void>;
|
|
415
|
+
addNext: (tracks: Track[]) => Promise<void>;
|
|
416
|
+
addAt: (tracks: Track[], index: number) => Promise<void>;
|
|
417
|
+
removeByIds: (ids: string[]) => Promise<void>;
|
|
418
|
+
removeByIndices: (indices: number[]) => Promise<void>;
|
|
419
|
+
clearQueue: () => Promise<void>;
|
|
420
|
+
reorder: (fromIndex: number, toIndex: number) => Promise<void>;
|
|
421
|
+
updateItemState: (id: string, updates: QueueItemStateUpdate) => Promise<void>;
|
|
422
|
+
goToNext: () => Promise<void>;
|
|
423
|
+
goToPrevious: () => Promise<void>;
|
|
424
|
+
goToIndex: (index: number) => Promise<void>;
|
|
425
|
+
goToId: (id: string) => Promise<void>;
|
|
426
|
+
setRepeatMode: (mode: RepeatMode) => Promise<void>;
|
|
427
|
+
setShuffleEnabled: (enabled: boolean) => Promise<void>;
|
|
428
|
+
subscribe: (listener: QueueListener) => () => void;
|
|
429
|
+
subscribeToCurrentItem: (listener: QueueItemListener) => () => void;
|
|
430
|
+
};
|
|
431
|
+
|
|
276
432
|
export declare type QueueItem = {
|
|
277
433
|
id: string;
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
artwork?: ArtworkSet;
|
|
283
|
-
note?: string;
|
|
284
|
-
addedAtIso?: string;
|
|
285
|
-
source: ProviderRef;
|
|
434
|
+
track: Track;
|
|
435
|
+
status: 'idle' | 'loading' | 'success' | 'error';
|
|
436
|
+
error?: string;
|
|
437
|
+
addedAtIso: string;
|
|
286
438
|
};
|
|
287
439
|
|
|
440
|
+
export declare type QueueItemListener = (item: QueueItem | undefined) => void;
|
|
441
|
+
|
|
442
|
+
export declare type QueueItemStateUpdate = Partial<{
|
|
443
|
+
status: QueueItem['status'];
|
|
444
|
+
error: QueueItem['error'];
|
|
445
|
+
}>;
|
|
446
|
+
|
|
447
|
+
export declare type QueueListener = (queue: Queue) => void;
|
|
448
|
+
|
|
449
|
+
export declare type RepeatMode = 'off' | 'all' | 'one';
|
|
450
|
+
|
|
288
451
|
export declare type SearchCapability = SearchCategory | 'unified';
|
|
289
452
|
|
|
290
453
|
export declare type SearchCategory = 'artists' | 'albums' | 'tracks' | 'playlists';
|
|
@@ -309,14 +472,14 @@ export declare type SettingDefinition = BooleanSettingDefinition | NumberSetting
|
|
|
309
472
|
declare class Settings {
|
|
310
473
|
#private;
|
|
311
474
|
constructor(host?: SettingsHost);
|
|
312
|
-
register(defs: SettingDefinition[]
|
|
475
|
+
register(defs: SettingDefinition[]): Promise<SettingsRegistrationResult>;
|
|
313
476
|
get<T extends SettingValue = SettingValue>(id: string): Promise<T | undefined>;
|
|
314
477
|
set<T extends SettingValue = SettingValue>(id: string, value: T): Promise<void>;
|
|
315
478
|
subscribe<T extends SettingValue = SettingValue>(id: string, listener: (value: T | undefined) => void): () => void;
|
|
316
479
|
}
|
|
317
480
|
|
|
318
481
|
export declare type SettingsHost = {
|
|
319
|
-
register(defs: SettingDefinition[]
|
|
482
|
+
register(defs: SettingDefinition[]): Promise<SettingsRegistrationResult>;
|
|
320
483
|
get<T extends SettingValue = SettingValue>(id: string): Promise<T | undefined>;
|
|
321
484
|
set<T extends SettingValue = SettingValue>(id: string, value: T): Promise<void>;
|
|
322
485
|
subscribe<T extends SettingValue = SettingValue>(id: string, listener: (value: T | undefined) => void): () => void;
|
|
@@ -353,6 +516,43 @@ export declare type Stream = {
|
|
|
353
516
|
source: ProviderRef;
|
|
354
517
|
};
|
|
355
518
|
|
|
519
|
+
export declare type StreamCandidate = {
|
|
520
|
+
id: string;
|
|
521
|
+
title: string;
|
|
522
|
+
durationMs?: number;
|
|
523
|
+
thumbnail?: string;
|
|
524
|
+
stream?: Stream;
|
|
525
|
+
lastResolvedAtIso?: string;
|
|
526
|
+
failed: boolean;
|
|
527
|
+
source: ProviderRef;
|
|
528
|
+
};
|
|
529
|
+
|
|
530
|
+
declare class StreamingAPI {
|
|
531
|
+
#private;
|
|
532
|
+
constructor(host?: StreamingHost);
|
|
533
|
+
resolveCandidatesForTrack(track: Track): Promise<StreamResolutionResult>;
|
|
534
|
+
resolveStreamForCandidate(candidate: StreamCandidate): Promise<StreamCandidate | undefined>;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
export declare type StreamingHost = {
|
|
538
|
+
resolveCandidatesForTrack: (track: Track) => Promise<StreamResolutionResult>;
|
|
539
|
+
resolveStreamForCandidate: (candidate: StreamCandidate) => Promise<StreamCandidate | undefined>;
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
export declare type StreamingProvider = ProviderDescriptor<'streaming'> & {
|
|
543
|
+
searchForTrack: (artist: string, title: string, album?: string) => Promise<StreamCandidate[]>;
|
|
544
|
+
getStreamUrl: (candidateId: string) => Promise<Stream>;
|
|
545
|
+
supportsLocalFiles?: boolean;
|
|
546
|
+
};
|
|
547
|
+
|
|
548
|
+
export declare type StreamResolutionResult = {
|
|
549
|
+
success: true;
|
|
550
|
+
candidates: StreamCandidate[];
|
|
551
|
+
} | {
|
|
552
|
+
success: false;
|
|
553
|
+
error: string;
|
|
554
|
+
};
|
|
555
|
+
|
|
356
556
|
export declare type StringFormat = 'text' | 'url' | 'path' | 'token' | 'language';
|
|
357
557
|
|
|
358
558
|
export declare type StringSettingDefinition = {
|
|
@@ -394,7 +594,7 @@ export declare type Track = {
|
|
|
394
594
|
tags?: string[];
|
|
395
595
|
source: ProviderRef;
|
|
396
596
|
localFile?: LocalFileInfo;
|
|
397
|
-
|
|
597
|
+
streamCandidates?: StreamCandidate[];
|
|
398
598
|
};
|
|
399
599
|
|
|
400
600
|
export declare type TrackRef = {
|
|
@@ -406,4 +606,30 @@ export declare type TrackRef = {
|
|
|
406
606
|
|
|
407
607
|
export declare const useSetting: <T extends SettingValue = SettingValue>(host: SettingsHost | undefined, id: string) => readonly [T | undefined, (nextValue: T) => void];
|
|
408
608
|
|
|
609
|
+
export declare class YtdlpAPI {
|
|
610
|
+
private host?;
|
|
611
|
+
constructor(host?: YtdlpHost);
|
|
612
|
+
get available(): boolean;
|
|
613
|
+
search(query: string, maxResults?: number): Promise<YtdlpSearchResult[]>;
|
|
614
|
+
getStream(videoId: string): Promise<YtdlpStreamInfo>;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
export declare type YtdlpHost = {
|
|
618
|
+
search: (query: string, maxResults?: number) => Promise<YtdlpSearchResult[]>;
|
|
619
|
+
getStream: (videoId: string) => Promise<YtdlpStreamInfo>;
|
|
620
|
+
};
|
|
621
|
+
|
|
622
|
+
export declare type YtdlpSearchResult = {
|
|
623
|
+
id: string;
|
|
624
|
+
title: string;
|
|
625
|
+
duration: number | null;
|
|
626
|
+
thumbnail: string | null;
|
|
627
|
+
};
|
|
628
|
+
|
|
629
|
+
export declare type YtdlpStreamInfo = {
|
|
630
|
+
stream_url: string;
|
|
631
|
+
duration: number | null;
|
|
632
|
+
title: string | null;
|
|
633
|
+
};
|
|
634
|
+
|
|
409
635
|
export { }
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,122 @@
|
|
|
1
|
-
import { useState as
|
|
1
|
+
import { useState as l, useEffect as f, useMemo as g } from "react";
|
|
2
|
+
class b {
|
|
3
|
+
#e;
|
|
4
|
+
constructor(t) {
|
|
5
|
+
this.#e = t;
|
|
6
|
+
}
|
|
7
|
+
#t(t) {
|
|
8
|
+
const e = this.#e;
|
|
9
|
+
if (!e)
|
|
10
|
+
throw new Error("Favorites host not available");
|
|
11
|
+
return t(e);
|
|
12
|
+
}
|
|
13
|
+
getTracks() {
|
|
14
|
+
return this.#t((t) => t.getTracks());
|
|
15
|
+
}
|
|
16
|
+
getAlbums() {
|
|
17
|
+
return this.#t((t) => t.getAlbums());
|
|
18
|
+
}
|
|
19
|
+
getArtists() {
|
|
20
|
+
return this.#t((t) => t.getArtists());
|
|
21
|
+
}
|
|
22
|
+
addTrack(t) {
|
|
23
|
+
return this.#t((e) => e.addTrack(t));
|
|
24
|
+
}
|
|
25
|
+
removeTrack(t) {
|
|
26
|
+
return this.#t((e) => e.removeTrack(t));
|
|
27
|
+
}
|
|
28
|
+
isTrackFavorite(t) {
|
|
29
|
+
return this.#t((e) => e.isTrackFavorite(t));
|
|
30
|
+
}
|
|
31
|
+
addAlbum(t) {
|
|
32
|
+
return this.#t((e) => e.addAlbum(t));
|
|
33
|
+
}
|
|
34
|
+
removeAlbum(t) {
|
|
35
|
+
return this.#t((e) => e.removeAlbum(t));
|
|
36
|
+
}
|
|
37
|
+
isAlbumFavorite(t) {
|
|
38
|
+
return this.#t((e) => e.isAlbumFavorite(t));
|
|
39
|
+
}
|
|
40
|
+
addArtist(t) {
|
|
41
|
+
return this.#t((e) => e.addArtist(t));
|
|
42
|
+
}
|
|
43
|
+
removeArtist(t) {
|
|
44
|
+
return this.#t((e) => e.removeArtist(t));
|
|
45
|
+
}
|
|
46
|
+
isArtistFavorite(t) {
|
|
47
|
+
return this.#t((e) => e.isArtistFavorite(t));
|
|
48
|
+
}
|
|
49
|
+
subscribe(t) {
|
|
50
|
+
return this.#t((e) => e.subscribe(t));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const m = (s) => {
|
|
54
|
+
if (s instanceof Headers) {
|
|
55
|
+
const t = {};
|
|
56
|
+
return s.forEach((e, r) => {
|
|
57
|
+
t[r] = e;
|
|
58
|
+
}), t;
|
|
59
|
+
}
|
|
60
|
+
return Array.isArray(s) ? Object.fromEntries(s) : s;
|
|
61
|
+
};
|
|
62
|
+
function A(s) {
|
|
63
|
+
return async (t, e) => {
|
|
64
|
+
const r = String(t instanceof Request ? t.url : t), a = e?.headers ? m(e.headers) : void 0, n = typeof e?.body == "string" ? e.body : void 0, u = await s.fetch(r, {
|
|
65
|
+
method: e?.method,
|
|
66
|
+
headers: a,
|
|
67
|
+
body: n
|
|
68
|
+
});
|
|
69
|
+
return new Response(u.body, {
|
|
70
|
+
status: u.status,
|
|
71
|
+
headers: new Headers(u.headers)
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const v = {
|
|
76
|
+
fetch: async () => ({
|
|
77
|
+
status: 501,
|
|
78
|
+
headers: {},
|
|
79
|
+
body: "HTTP host not configured"
|
|
80
|
+
})
|
|
81
|
+
};
|
|
82
|
+
class w {
|
|
83
|
+
fetch;
|
|
84
|
+
constructor(t) {
|
|
85
|
+
this.fetch = A(t ?? v);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
class T {
|
|
89
|
+
#e;
|
|
90
|
+
constructor(t) {
|
|
91
|
+
this.#e = t;
|
|
92
|
+
}
|
|
93
|
+
#t(t) {
|
|
94
|
+
const e = this.#e;
|
|
95
|
+
if (!e)
|
|
96
|
+
throw new Error("Metadata host not available");
|
|
97
|
+
return t(e);
|
|
98
|
+
}
|
|
99
|
+
search(t, e) {
|
|
100
|
+
return this.#t((r) => r.search(t, e));
|
|
101
|
+
}
|
|
102
|
+
fetchArtistDetails(t, e) {
|
|
103
|
+
return this.#t((r) => r.fetchArtistDetails(t, e));
|
|
104
|
+
}
|
|
105
|
+
fetchArtistAlbums(t, e) {
|
|
106
|
+
return this.#t((r) => r.fetchArtistAlbums(t, e));
|
|
107
|
+
}
|
|
108
|
+
fetchArtistTopTracks(t, e) {
|
|
109
|
+
return this.#t((r) => r.fetchArtistTopTracks(t, e));
|
|
110
|
+
}
|
|
111
|
+
fetchArtistRelatedArtists(t, e) {
|
|
112
|
+
return this.#t(
|
|
113
|
+
(r) => r.fetchArtistRelatedArtists(t, e)
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
fetchAlbumDetails(t, e) {
|
|
117
|
+
return this.#t((r) => r.fetchAlbumDetails(t, e));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
2
120
|
class p {
|
|
3
121
|
#e;
|
|
4
122
|
constructor(t) {
|
|
@@ -23,7 +141,73 @@ class p {
|
|
|
23
141
|
return this.#t((e) => e.get(t));
|
|
24
142
|
}
|
|
25
143
|
}
|
|
26
|
-
class
|
|
144
|
+
class I {
|
|
145
|
+
#e;
|
|
146
|
+
constructor(t) {
|
|
147
|
+
this.#e = t;
|
|
148
|
+
}
|
|
149
|
+
#t(t) {
|
|
150
|
+
const e = this.#e;
|
|
151
|
+
if (!e)
|
|
152
|
+
throw new Error("Queue host not available");
|
|
153
|
+
return t(e);
|
|
154
|
+
}
|
|
155
|
+
getQueue() {
|
|
156
|
+
return this.#t((t) => t.getQueue());
|
|
157
|
+
}
|
|
158
|
+
getCurrentItem() {
|
|
159
|
+
return this.#t((t) => t.getCurrentItem());
|
|
160
|
+
}
|
|
161
|
+
addToQueue(t) {
|
|
162
|
+
return this.#t((e) => e.addToQueue(t));
|
|
163
|
+
}
|
|
164
|
+
addNext(t) {
|
|
165
|
+
return this.#t((e) => e.addNext(t));
|
|
166
|
+
}
|
|
167
|
+
addAt(t, e) {
|
|
168
|
+
return this.#t((r) => r.addAt(t, e));
|
|
169
|
+
}
|
|
170
|
+
removeByIds(t) {
|
|
171
|
+
return this.#t((e) => e.removeByIds(t));
|
|
172
|
+
}
|
|
173
|
+
removeByIndices(t) {
|
|
174
|
+
return this.#t((e) => e.removeByIndices(t));
|
|
175
|
+
}
|
|
176
|
+
clearQueue() {
|
|
177
|
+
return this.#t((t) => t.clearQueue());
|
|
178
|
+
}
|
|
179
|
+
reorder(t, e) {
|
|
180
|
+
return this.#t((r) => r.reorder(t, e));
|
|
181
|
+
}
|
|
182
|
+
updateItemState(t, e) {
|
|
183
|
+
return this.#t((r) => r.updateItemState(t, e));
|
|
184
|
+
}
|
|
185
|
+
goToNext() {
|
|
186
|
+
return this.#t((t) => t.goToNext());
|
|
187
|
+
}
|
|
188
|
+
goToPrevious() {
|
|
189
|
+
return this.#t((t) => t.goToPrevious());
|
|
190
|
+
}
|
|
191
|
+
goToIndex(t) {
|
|
192
|
+
return this.#t((e) => e.goToIndex(t));
|
|
193
|
+
}
|
|
194
|
+
goToId(t) {
|
|
195
|
+
return this.#t((e) => e.goToId(t));
|
|
196
|
+
}
|
|
197
|
+
setRepeatMode(t) {
|
|
198
|
+
return this.#t((e) => e.setRepeatMode(t));
|
|
199
|
+
}
|
|
200
|
+
setShuffleEnabled(t) {
|
|
201
|
+
return this.#t((e) => e.setShuffleEnabled(t));
|
|
202
|
+
}
|
|
203
|
+
subscribe(t) {
|
|
204
|
+
return this.#t((e) => e.subscribe(t));
|
|
205
|
+
}
|
|
206
|
+
subscribeToCurrentItem(t) {
|
|
207
|
+
return this.#t((e) => e.subscribeToCurrentItem(t));
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
class H {
|
|
27
211
|
#e;
|
|
28
212
|
constructor(t) {
|
|
29
213
|
this.#e = t;
|
|
@@ -34,64 +218,107 @@ class d {
|
|
|
34
218
|
throw new Error("Settings host not available");
|
|
35
219
|
return t(e);
|
|
36
220
|
}
|
|
37
|
-
register(t
|
|
38
|
-
return this.#t((
|
|
221
|
+
register(t) {
|
|
222
|
+
return this.#t((e) => e.register(t));
|
|
39
223
|
}
|
|
40
224
|
get(t) {
|
|
41
225
|
return this.#t((e) => e.get(t));
|
|
42
226
|
}
|
|
43
227
|
set(t, e) {
|
|
44
|
-
return this.#t((
|
|
228
|
+
return this.#t((r) => r.set(t, e));
|
|
45
229
|
}
|
|
46
230
|
subscribe(t, e) {
|
|
47
|
-
return this.#t((
|
|
231
|
+
return this.#t((r) => r.subscribe(t, e));
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
class y {
|
|
235
|
+
#e;
|
|
236
|
+
constructor(t) {
|
|
237
|
+
this.#e = t;
|
|
238
|
+
}
|
|
239
|
+
#t(t) {
|
|
240
|
+
const e = this.#e;
|
|
241
|
+
if (!e)
|
|
242
|
+
throw new Error("Streaming host not available");
|
|
243
|
+
return t(e);
|
|
244
|
+
}
|
|
245
|
+
resolveCandidatesForTrack(t) {
|
|
246
|
+
return this.#t((e) => e.resolveCandidatesForTrack(t));
|
|
247
|
+
}
|
|
248
|
+
resolveStreamForCandidate(t) {
|
|
249
|
+
return this.#t((e) => e.resolveStreamForCandidate(t));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
class S {
|
|
253
|
+
host;
|
|
254
|
+
constructor(t) {
|
|
255
|
+
this.host = t;
|
|
256
|
+
}
|
|
257
|
+
get available() {
|
|
258
|
+
return !!this.host;
|
|
259
|
+
}
|
|
260
|
+
async search(t, e) {
|
|
261
|
+
if (!this.host)
|
|
262
|
+
throw new Error("YtdlpAPI: No host configured");
|
|
263
|
+
return this.host.search(t, e);
|
|
264
|
+
}
|
|
265
|
+
async getStream(t) {
|
|
266
|
+
if (!this.host)
|
|
267
|
+
throw new Error("YtdlpAPI: No host configured");
|
|
268
|
+
return this.host.getStream(t);
|
|
48
269
|
}
|
|
49
270
|
}
|
|
50
|
-
class
|
|
271
|
+
class F {
|
|
51
272
|
Settings;
|
|
52
273
|
Providers;
|
|
274
|
+
Queue;
|
|
275
|
+
Streaming;
|
|
276
|
+
Metadata;
|
|
277
|
+
Http;
|
|
278
|
+
Ytdlp;
|
|
279
|
+
Favorites;
|
|
53
280
|
constructor(t) {
|
|
54
|
-
this.Settings = new
|
|
281
|
+
this.Settings = new H(t?.settingsHost), this.Providers = new p(t?.providersHost), this.Queue = new I(t?.queueHost), this.Streaming = new y(t?.streamingHost), this.Metadata = new T(t?.metadataHost), this.Http = new w(t?.httpHost), this.Ytdlp = new S(t?.ytdlpHost), this.Favorites = new b(t?.favoritesHost);
|
|
55
282
|
}
|
|
56
283
|
}
|
|
57
|
-
class
|
|
284
|
+
class P extends F {
|
|
58
285
|
}
|
|
59
286
|
class M extends Error {
|
|
60
287
|
constructor(t) {
|
|
61
288
|
super(`Missing capability: ${t}`), this.name = "MissingCapabilityError";
|
|
62
289
|
}
|
|
63
290
|
}
|
|
64
|
-
const
|
|
65
|
-
const [e,
|
|
291
|
+
const C = (s, t) => {
|
|
292
|
+
const [e, r] = l(void 0);
|
|
66
293
|
f(() => {
|
|
67
294
|
if (!s)
|
|
68
295
|
return;
|
|
69
|
-
let
|
|
70
|
-
const
|
|
71
|
-
|
|
296
|
+
let n = !0, u = !1;
|
|
297
|
+
const i = s.subscribe(t, (o) => {
|
|
298
|
+
n && (u = !0, r(o));
|
|
72
299
|
});
|
|
73
|
-
return s.get(t).then((
|
|
74
|
-
|
|
300
|
+
return s.get(t).then((o) => {
|
|
301
|
+
n && (u || r(o));
|
|
75
302
|
}), () => {
|
|
76
|
-
|
|
303
|
+
n = !1, i && i();
|
|
77
304
|
};
|
|
78
305
|
}, [t, s]);
|
|
79
|
-
const
|
|
80
|
-
() => (
|
|
81
|
-
s && s.set(t,
|
|
306
|
+
const a = g(
|
|
307
|
+
() => (n) => {
|
|
308
|
+
s && s.set(t, n);
|
|
82
309
|
},
|
|
83
310
|
[t, s]
|
|
84
311
|
);
|
|
85
|
-
return [e,
|
|
312
|
+
return [e, a];
|
|
86
313
|
};
|
|
87
|
-
function
|
|
314
|
+
function R(s, t, e) {
|
|
88
315
|
if (!s?.items?.length)
|
|
89
316
|
return;
|
|
90
|
-
const
|
|
91
|
-
if (!
|
|
317
|
+
const r = s.items.filter((i) => !(i.purpose && i.purpose !== t || !i.url));
|
|
318
|
+
if (!r.length)
|
|
92
319
|
return s.items[0];
|
|
93
|
-
const
|
|
94
|
-
switch (
|
|
320
|
+
const a = (i) => !i.width || !i.height ? 1 : i.width / i.height, u = ((i) => {
|
|
321
|
+
switch (i) {
|
|
95
322
|
case "avatar":
|
|
96
323
|
case "thumbnail":
|
|
97
324
|
return 1;
|
|
@@ -103,18 +330,21 @@ function E(s, t, e) {
|
|
|
103
330
|
return 1;
|
|
104
331
|
}
|
|
105
332
|
})(t);
|
|
106
|
-
return
|
|
107
|
-
const
|
|
333
|
+
return r.map((i) => {
|
|
334
|
+
const o = Math.min(i.width || 0, i.height || 0), h = Math.abs(a(i) - u), c = Math.abs(o - e), d = o < e ? e / o : 1;
|
|
108
335
|
return {
|
|
109
|
-
artwork:
|
|
110
|
-
score: (
|
|
336
|
+
artwork: i,
|
|
337
|
+
score: (d > 1.5 ? -1e3 : 0) + -h * 50 + -c * 0.1
|
|
111
338
|
};
|
|
112
|
-
}).sort((
|
|
339
|
+
}).sort((i, o) => o.score - i.score)[0]?.artwork;
|
|
113
340
|
}
|
|
114
341
|
export {
|
|
342
|
+
b as FavoritesAPI,
|
|
343
|
+
w as HttpAPI,
|
|
115
344
|
M as MissingCapabilityError,
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
345
|
+
F as NuclearAPI,
|
|
346
|
+
P as NuclearPluginAPI,
|
|
347
|
+
S as YtdlpAPI,
|
|
348
|
+
R as pickArtwork,
|
|
349
|
+
C as useSetting
|
|
120
350
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuclearplayer/plugin-sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Plugin SDK for Nuclear music player",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"vite": "^7.1.3",
|
|
39
39
|
"vite-plugin-dts": "^4.5.4",
|
|
40
40
|
"vitest": "^3.2.4",
|
|
41
|
-
"@nuclearplayer/eslint-config": "0.0.
|
|
42
|
-
"@nuclearplayer/tailwind-config": "0.0.
|
|
41
|
+
"@nuclearplayer/eslint-config": "0.0.10",
|
|
42
|
+
"@nuclearplayer/tailwind-config": "0.0.10"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"react": "^18.3.1"
|