@nuclearplayer/plugin-sdk 0.0.14 → 1.0.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.
Files changed (3) hide show
  1. package/dist/index.d.ts +190 -13
  2. package/dist/index.js +212 -34
  3. 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,29 @@ export declare type EnumWidget = {
97
99
  type: 'radio';
98
100
  };
99
101
 
102
+ export declare type FetchFunction = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
103
+
104
+ export declare class HttpAPI {
105
+ readonly fetch: FetchFunction;
106
+ constructor(host?: HttpHost);
107
+ }
108
+
109
+ export declare type HttpHost = {
110
+ fetch: (url: string, init?: HttpRequestInit) => Promise<HttpResponseData>;
111
+ };
112
+
113
+ export declare type HttpRequestInit = {
114
+ method?: string;
115
+ headers?: Record<string, string>;
116
+ body?: string;
117
+ };
118
+
119
+ export declare type HttpResponseData = {
120
+ status: number;
121
+ headers: Record<string, string>;
122
+ body: string;
123
+ };
124
+
100
125
  export declare type LoadedPlugin = {
101
126
  metadata: PluginMetadata;
102
127
  instance: NuclearPlugin;
@@ -114,9 +139,30 @@ export declare type LocalFileInfo = {
114
139
  scannedAtIso?: string;
115
140
  };
116
141
 
142
+ declare class MetadataAPI {
143
+ #private;
144
+ constructor(host?: MetadataHost);
145
+ search(params: SearchParams, providerId?: string): Promise<SearchResults>;
146
+ fetchArtistDetails(artistId: string, providerId?: string): Promise<Artist>;
147
+ fetchArtistAlbums(artistId: string, providerId?: string): Promise<AlbumRef[]>;
148
+ fetchArtistTopTracks(artistId: string, providerId?: string): Promise<TrackRef[]>;
149
+ fetchArtistRelatedArtists(artistId: string, providerId?: string): Promise<ArtistRef[]>;
150
+ fetchAlbumDetails(albumId: string, providerId?: string): Promise<Album>;
151
+ }
152
+
153
+ export declare type MetadataHost = {
154
+ search: (params: SearchParams, providerId?: string) => Promise<SearchResults>;
155
+ fetchArtistDetails: (artistId: string, providerId?: string) => Promise<Artist>;
156
+ fetchArtistAlbums: (artistId: string, providerId?: string) => Promise<AlbumRef[]>;
157
+ fetchArtistTopTracks: (artistId: string, providerId?: string) => Promise<TrackRef[]>;
158
+ fetchArtistRelatedArtists: (artistId: string, providerId?: string) => Promise<ArtistRef[]>;
159
+ fetchAlbumDetails: (albumId: string, providerId?: string) => Promise<Album>;
160
+ };
161
+
117
162
  export declare type MetadataProvider = ProviderDescriptor<'metadata'> & {
118
163
  searchCapabilities?: SearchCapability[];
119
164
  artistMetadataCapabilities?: ArtistMetadataCapability[];
165
+ albumMetadataCapabilities?: AlbumMetadataCapability[];
120
166
  search?: (params: SearchParams) => Promise<SearchResults>;
121
167
  searchArtists?: (params: Omit<SearchParams, 'types'>) => Promise<ArtistRef[]>;
122
168
  searchAlbums?: (params: Omit<SearchParams, 'types'>) => Promise<AlbumRef[]>;
@@ -136,17 +182,27 @@ export declare class MissingCapabilityError extends Error {
136
182
  export declare class NuclearAPI {
137
183
  readonly Settings: Settings;
138
184
  readonly Providers: Providers;
185
+ readonly Queue: QueueAPI;
186
+ readonly Streaming: StreamingAPI;
187
+ readonly Metadata: MetadataAPI;
188
+ readonly Http: HttpAPI;
189
+ readonly Ytdlp: YtdlpAPI;
139
190
  constructor(opts?: {
140
191
  settingsHost?: SettingsHost;
141
192
  providersHost?: ProvidersHost;
193
+ queueHost?: QueueHost;
194
+ streamingHost?: StreamingHost;
195
+ metadataHost?: MetadataHost;
196
+ httpHost?: HttpHost;
197
+ ytdlpHost?: YtdlpHost;
142
198
  });
143
199
  }
144
200
 
145
201
  export declare type NuclearPlugin = {
146
202
  onLoad?(api: NuclearPluginAPI): void | Promise<void>;
147
- onUnload?(): void | Promise<void>;
203
+ onUnload?(api: NuclearPluginAPI): void | Promise<void>;
148
204
  onEnable?(api: NuclearPluginAPI): void | Promise<void>;
149
- onDisable?(): void | Promise<void>;
205
+ onDisable?(api: NuclearPluginAPI): void | Promise<void>;
150
206
  };
151
207
 
152
208
  export declare class NuclearPluginAPI extends NuclearAPI {
@@ -273,18 +329,76 @@ export declare type ProvidersHost = {
273
329
  clear(): void;
274
330
  };
275
331
 
332
+ export declare type Queue = {
333
+ items: QueueItem[];
334
+ currentIndex: number;
335
+ repeatMode: RepeatMode;
336
+ shuffleEnabled: boolean;
337
+ };
338
+
339
+ declare class QueueAPI {
340
+ #private;
341
+ constructor(host?: QueueHost);
342
+ getQueue(): Promise<Queue>;
343
+ getCurrentItem(): Promise<QueueItem | undefined>;
344
+ addToQueue(tracks: Track[]): Promise<void>;
345
+ addNext(tracks: Track[]): Promise<void>;
346
+ addAt(tracks: Track[], index: number): Promise<void>;
347
+ removeByIds(ids: string[]): Promise<void>;
348
+ removeByIndices(indices: number[]): Promise<void>;
349
+ clearQueue(): Promise<void>;
350
+ reorder(fromIndex: number, toIndex: number): Promise<void>;
351
+ updateItemState(id: string, updates: QueueItemStateUpdate): Promise<void>;
352
+ goToNext(): Promise<void>;
353
+ goToPrevious(): Promise<void>;
354
+ goToIndex(index: number): Promise<void>;
355
+ goToId(id: string): Promise<void>;
356
+ setRepeatMode(mode: RepeatMode): Promise<void>;
357
+ setShuffleEnabled(enabled: boolean): Promise<void>;
358
+ subscribe(listener: (queue: Queue) => void): () => void;
359
+ subscribeToCurrentItem(listener: (item: QueueItem | undefined) => void): () => void;
360
+ }
361
+
362
+ export declare type QueueHost = {
363
+ getQueue: () => Promise<Queue>;
364
+ getCurrentItem: () => Promise<QueueItem | undefined>;
365
+ addToQueue: (tracks: Track[]) => Promise<void>;
366
+ addNext: (tracks: Track[]) => Promise<void>;
367
+ addAt: (tracks: Track[], index: number) => Promise<void>;
368
+ removeByIds: (ids: string[]) => Promise<void>;
369
+ removeByIndices: (indices: number[]) => Promise<void>;
370
+ clearQueue: () => Promise<void>;
371
+ reorder: (fromIndex: number, toIndex: number) => Promise<void>;
372
+ updateItemState: (id: string, updates: QueueItemStateUpdate) => Promise<void>;
373
+ goToNext: () => Promise<void>;
374
+ goToPrevious: () => Promise<void>;
375
+ goToIndex: (index: number) => Promise<void>;
376
+ goToId: (id: string) => Promise<void>;
377
+ setRepeatMode: (mode: RepeatMode) => Promise<void>;
378
+ setShuffleEnabled: (enabled: boolean) => Promise<void>;
379
+ subscribe: (listener: QueueListener) => () => void;
380
+ subscribeToCurrentItem: (listener: QueueItemListener) => () => void;
381
+ };
382
+
276
383
  export declare type QueueItem = {
277
384
  id: string;
278
- title: string;
279
- artists: ArtistCredit[];
280
- album?: string;
281
- durationMs?: number;
282
- artwork?: ArtworkSet;
283
- note?: string;
284
- addedAtIso?: string;
285
- source: ProviderRef;
385
+ track: Track;
386
+ status: 'idle' | 'loading' | 'success' | 'error';
387
+ error?: string;
388
+ addedAtIso: string;
286
389
  };
287
390
 
391
+ export declare type QueueItemListener = (item: QueueItem | undefined) => void;
392
+
393
+ export declare type QueueItemStateUpdate = Partial<{
394
+ status: QueueItem['status'];
395
+ error: QueueItem['error'];
396
+ }>;
397
+
398
+ export declare type QueueListener = (queue: Queue) => void;
399
+
400
+ export declare type RepeatMode = 'off' | 'all' | 'one';
401
+
288
402
  export declare type SearchCapability = SearchCategory | 'unified';
289
403
 
290
404
  export declare type SearchCategory = 'artists' | 'albums' | 'tracks' | 'playlists';
@@ -309,14 +423,14 @@ export declare type SettingDefinition = BooleanSettingDefinition | NumberSetting
309
423
  declare class Settings {
310
424
  #private;
311
425
  constructor(host?: SettingsHost);
312
- register(defs: SettingDefinition[], source: SettingSource): Promise<SettingsRegistrationResult>;
426
+ register(defs: SettingDefinition[]): Promise<SettingsRegistrationResult>;
313
427
  get<T extends SettingValue = SettingValue>(id: string): Promise<T | undefined>;
314
428
  set<T extends SettingValue = SettingValue>(id: string, value: T): Promise<void>;
315
429
  subscribe<T extends SettingValue = SettingValue>(id: string, listener: (value: T | undefined) => void): () => void;
316
430
  }
317
431
 
318
432
  export declare type SettingsHost = {
319
- register(defs: SettingDefinition[], source: SettingSource): Promise<SettingsRegistrationResult>;
433
+ register(defs: SettingDefinition[]): Promise<SettingsRegistrationResult>;
320
434
  get<T extends SettingValue = SettingValue>(id: string): Promise<T | undefined>;
321
435
  set<T extends SettingValue = SettingValue>(id: string, value: T): Promise<void>;
322
436
  subscribe<T extends SettingValue = SettingValue>(id: string, listener: (value: T | undefined) => void): () => void;
@@ -353,6 +467,43 @@ export declare type Stream = {
353
467
  source: ProviderRef;
354
468
  };
355
469
 
470
+ export declare type StreamCandidate = {
471
+ id: string;
472
+ title: string;
473
+ durationMs?: number;
474
+ thumbnail?: string;
475
+ stream?: Stream;
476
+ lastResolvedAtIso?: string;
477
+ failed: boolean;
478
+ source: ProviderRef;
479
+ };
480
+
481
+ declare class StreamingAPI {
482
+ #private;
483
+ constructor(host?: StreamingHost);
484
+ resolveCandidatesForTrack(track: Track): Promise<StreamResolutionResult>;
485
+ resolveStreamForCandidate(candidate: StreamCandidate): Promise<StreamCandidate | undefined>;
486
+ }
487
+
488
+ export declare type StreamingHost = {
489
+ resolveCandidatesForTrack: (track: Track) => Promise<StreamResolutionResult>;
490
+ resolveStreamForCandidate: (candidate: StreamCandidate) => Promise<StreamCandidate | undefined>;
491
+ };
492
+
493
+ export declare type StreamingProvider = ProviderDescriptor<'streaming'> & {
494
+ searchForTrack: (artist: string, title: string, album?: string) => Promise<StreamCandidate[]>;
495
+ getStreamUrl: (candidateId: string) => Promise<Stream>;
496
+ supportsLocalFiles?: boolean;
497
+ };
498
+
499
+ export declare type StreamResolutionResult = {
500
+ success: true;
501
+ candidates: StreamCandidate[];
502
+ } | {
503
+ success: false;
504
+ error: string;
505
+ };
506
+
356
507
  export declare type StringFormat = 'text' | 'url' | 'path' | 'token' | 'language';
357
508
 
358
509
  export declare type StringSettingDefinition = {
@@ -394,7 +545,7 @@ export declare type Track = {
394
545
  tags?: string[];
395
546
  source: ProviderRef;
396
547
  localFile?: LocalFileInfo;
397
- streams?: Stream[];
548
+ streamCandidates?: StreamCandidate[];
398
549
  };
399
550
 
400
551
  export declare type TrackRef = {
@@ -406,4 +557,30 @@ export declare type TrackRef = {
406
557
 
407
558
  export declare const useSetting: <T extends SettingValue = SettingValue>(host: SettingsHost | undefined, id: string) => readonly [T | undefined, (nextValue: T) => void];
408
559
 
560
+ export declare class YtdlpAPI {
561
+ private host?;
562
+ constructor(host?: YtdlpHost);
563
+ get available(): boolean;
564
+ search(query: string, maxResults?: number): Promise<YtdlpSearchResult[]>;
565
+ getStream(videoId: string): Promise<YtdlpStreamInfo>;
566
+ }
567
+
568
+ export declare type YtdlpHost = {
569
+ search: (query: string, maxResults?: number) => Promise<YtdlpSearchResult[]>;
570
+ getStream: (videoId: string) => Promise<YtdlpStreamInfo>;
571
+ };
572
+
573
+ export declare type YtdlpSearchResult = {
574
+ id: string;
575
+ title: string;
576
+ duration: number | null;
577
+ thumbnail: string | null;
578
+ };
579
+
580
+ export declare type YtdlpStreamInfo = {
581
+ stream_url: string;
582
+ duration: number | null;
583
+ title: string | null;
584
+ };
585
+
409
586
  export { }
package/dist/index.js CHANGED
@@ -1,5 +1,72 @@
1
- import { useState as g, useEffect as f, useMemo as b } from "react";
1
+ import { useState as l, useEffect as f, useMemo as g } from "react";
2
+ const b = (s) => {
3
+ if (s instanceof Headers) {
4
+ const t = {};
5
+ return s.forEach((e, r) => {
6
+ t[r] = e;
7
+ }), t;
8
+ }
9
+ return Array.isArray(s) ? Object.fromEntries(s) : s;
10
+ };
11
+ function m(s) {
12
+ return async (t, e) => {
13
+ const r = String(t instanceof Request ? t.url : t), a = e?.headers ? b(e.headers) : void 0, o = typeof e?.body == "string" ? e.body : void 0, u = await s.fetch(r, {
14
+ method: e?.method,
15
+ headers: a,
16
+ body: o
17
+ });
18
+ return new Response(u.body, {
19
+ status: u.status,
20
+ headers: new Headers(u.headers)
21
+ });
22
+ };
23
+ }
24
+ const A = {
25
+ fetch: async () => ({
26
+ status: 501,
27
+ headers: {},
28
+ body: "HTTP host not configured"
29
+ })
30
+ };
2
31
  class p {
32
+ fetch;
33
+ constructor(t) {
34
+ this.fetch = m(t ?? A);
35
+ }
36
+ }
37
+ class v {
38
+ #e;
39
+ constructor(t) {
40
+ this.#e = t;
41
+ }
42
+ #t(t) {
43
+ const e = this.#e;
44
+ if (!e)
45
+ throw new Error("Metadata host not available");
46
+ return t(e);
47
+ }
48
+ search(t, e) {
49
+ return this.#t((r) => r.search(t, e));
50
+ }
51
+ fetchArtistDetails(t, e) {
52
+ return this.#t((r) => r.fetchArtistDetails(t, e));
53
+ }
54
+ fetchArtistAlbums(t, e) {
55
+ return this.#t((r) => r.fetchArtistAlbums(t, e));
56
+ }
57
+ fetchArtistTopTracks(t, e) {
58
+ return this.#t((r) => r.fetchArtistTopTracks(t, e));
59
+ }
60
+ fetchArtistRelatedArtists(t, e) {
61
+ return this.#t(
62
+ (r) => r.fetchArtistRelatedArtists(t, e)
63
+ );
64
+ }
65
+ fetchAlbumDetails(t, e) {
66
+ return this.#t((r) => r.fetchAlbumDetails(t, e));
67
+ }
68
+ }
69
+ class w {
3
70
  #e;
4
71
  constructor(t) {
5
72
  this.#e = t;
@@ -23,7 +90,73 @@ class p {
23
90
  return this.#t((e) => e.get(t));
24
91
  }
25
92
  }
26
- class d {
93
+ class I {
94
+ #e;
95
+ constructor(t) {
96
+ this.#e = t;
97
+ }
98
+ #t(t) {
99
+ const e = this.#e;
100
+ if (!e)
101
+ throw new Error("Queue host not available");
102
+ return t(e);
103
+ }
104
+ getQueue() {
105
+ return this.#t((t) => t.getQueue());
106
+ }
107
+ getCurrentItem() {
108
+ return this.#t((t) => t.getCurrentItem());
109
+ }
110
+ addToQueue(t) {
111
+ return this.#t((e) => e.addToQueue(t));
112
+ }
113
+ addNext(t) {
114
+ return this.#t((e) => e.addNext(t));
115
+ }
116
+ addAt(t, e) {
117
+ return this.#t((r) => r.addAt(t, e));
118
+ }
119
+ removeByIds(t) {
120
+ return this.#t((e) => e.removeByIds(t));
121
+ }
122
+ removeByIndices(t) {
123
+ return this.#t((e) => e.removeByIndices(t));
124
+ }
125
+ clearQueue() {
126
+ return this.#t((t) => t.clearQueue());
127
+ }
128
+ reorder(t, e) {
129
+ return this.#t((r) => r.reorder(t, e));
130
+ }
131
+ updateItemState(t, e) {
132
+ return this.#t((r) => r.updateItemState(t, e));
133
+ }
134
+ goToNext() {
135
+ return this.#t((t) => t.goToNext());
136
+ }
137
+ goToPrevious() {
138
+ return this.#t((t) => t.goToPrevious());
139
+ }
140
+ goToIndex(t) {
141
+ return this.#t((e) => e.goToIndex(t));
142
+ }
143
+ goToId(t) {
144
+ return this.#t((e) => e.goToId(t));
145
+ }
146
+ setRepeatMode(t) {
147
+ return this.#t((e) => e.setRepeatMode(t));
148
+ }
149
+ setShuffleEnabled(t) {
150
+ return this.#t((e) => e.setShuffleEnabled(t));
151
+ }
152
+ subscribe(t) {
153
+ return this.#t((e) => e.subscribe(t));
154
+ }
155
+ subscribeToCurrentItem(t) {
156
+ return this.#t((e) => e.subscribeToCurrentItem(t));
157
+ }
158
+ }
159
+ class T {
27
160
  #e;
28
161
  constructor(t) {
29
162
  this.#e = t;
@@ -34,64 +167,107 @@ class d {
34
167
  throw new Error("Settings host not available");
35
168
  return t(e);
36
169
  }
37
- register(t, e) {
38
- return this.#t((i) => i.register(t, e));
170
+ register(t) {
171
+ return this.#t((e) => e.register(t));
39
172
  }
40
173
  get(t) {
41
174
  return this.#t((e) => e.get(t));
42
175
  }
43
176
  set(t, e) {
44
- return this.#t((i) => i.set(t, e));
177
+ return this.#t((r) => r.set(t, e));
45
178
  }
46
179
  subscribe(t, e) {
47
- return this.#t((i) => i.subscribe(t, e));
180
+ return this.#t((r) => r.subscribe(t, e));
48
181
  }
49
182
  }
50
- class v {
183
+ class y {
184
+ #e;
185
+ constructor(t) {
186
+ this.#e = t;
187
+ }
188
+ #t(t) {
189
+ const e = this.#e;
190
+ if (!e)
191
+ throw new Error("Streaming host not available");
192
+ return t(e);
193
+ }
194
+ resolveCandidatesForTrack(t) {
195
+ return this.#t((e) => e.resolveCandidatesForTrack(t));
196
+ }
197
+ resolveStreamForCandidate(t) {
198
+ return this.#t((e) => e.resolveStreamForCandidate(t));
199
+ }
200
+ }
201
+ class H {
202
+ host;
203
+ constructor(t) {
204
+ this.host = t;
205
+ }
206
+ get available() {
207
+ return !!this.host;
208
+ }
209
+ async search(t, e) {
210
+ if (!this.host)
211
+ throw new Error("YtdlpAPI: No host configured");
212
+ return this.host.search(t, e);
213
+ }
214
+ async getStream(t) {
215
+ if (!this.host)
216
+ throw new Error("YtdlpAPI: No host configured");
217
+ return this.host.getStream(t);
218
+ }
219
+ }
220
+ class S {
51
221
  Settings;
52
222
  Providers;
223
+ Queue;
224
+ Streaming;
225
+ Metadata;
226
+ Http;
227
+ Ytdlp;
228
+ // All these are optional so we don't have to provide all of them in tests
53
229
  constructor(t) {
54
- this.Settings = new d(t?.settingsHost), this.Providers = new p(t?.providersHost);
230
+ this.Settings = new T(t?.settingsHost), this.Providers = new w(t?.providersHost), this.Queue = new I(t?.queueHost), this.Streaming = new y(t?.streamingHost), this.Metadata = new v(t?.metadataHost), this.Http = new p(t?.httpHost), this.Ytdlp = new H(t?.ytdlpHost);
55
231
  }
56
232
  }
57
- class w extends v {
233
+ class P extends S {
58
234
  }
59
235
  class M extends Error {
60
236
  constructor(t) {
61
237
  super(`Missing capability: ${t}`), this.name = "MissingCapabilityError";
62
238
  }
63
239
  }
64
- const A = (s, t) => {
65
- const [e, i] = g(void 0);
240
+ const C = (s, t) => {
241
+ const [e, r] = l(void 0);
66
242
  f(() => {
67
243
  if (!s)
68
244
  return;
69
- let u = !0, c = !1;
70
- const r = s.subscribe(t, (n) => {
71
- u && (c = !0, i(n));
245
+ let o = !0, u = !1;
246
+ const i = s.subscribe(t, (n) => {
247
+ o && (u = !0, r(n));
72
248
  });
73
249
  return s.get(t).then((n) => {
74
- u && (c || i(n));
250
+ o && (u || r(n));
75
251
  }), () => {
76
- u = !1, r && r();
252
+ o = !1, i && i();
77
253
  };
78
254
  }, [t, s]);
79
- const o = b(
80
- () => (u) => {
81
- s && s.set(t, u);
255
+ const a = g(
256
+ () => (o) => {
257
+ s && s.set(t, o);
82
258
  },
83
259
  [t, s]
84
260
  );
85
- return [e, o];
261
+ return [e, a];
86
262
  };
87
- function E(s, t, e) {
263
+ function R(s, t, e) {
88
264
  if (!s?.items?.length)
89
265
  return;
90
- const i = s.items.filter((r) => !(r.purpose && r.purpose !== t || !r.url));
91
- if (!i.length)
266
+ const r = s.items.filter((i) => !(i.purpose && i.purpose !== t || !i.url));
267
+ if (!r.length)
92
268
  return s.items[0];
93
- const o = (r) => !r.width || !r.height ? 1 : r.width / r.height, c = ((r) => {
94
- switch (r) {
269
+ const a = (i) => !i.width || !i.height ? 1 : i.width / i.height, u = ((i) => {
270
+ switch (i) {
95
271
  case "avatar":
96
272
  case "thumbnail":
97
273
  return 1;
@@ -103,18 +279,20 @@ function E(s, t, e) {
103
279
  return 1;
104
280
  }
105
281
  })(t);
106
- return i.map((r) => {
107
- const n = Math.min(r.width || 0, r.height || 0), a = Math.abs(o(r) - c), h = Math.abs(n - e), l = n < e ? e / n : 1;
282
+ return r.map((i) => {
283
+ const n = Math.min(i.width || 0, i.height || 0), h = Math.abs(a(i) - u), c = Math.abs(n - e), d = n < e ? e / n : 1;
108
284
  return {
109
- artwork: r,
110
- score: (l > 1.5 ? -1e3 : 0) + -a * 50 + -h * 0.1
285
+ artwork: i,
286
+ score: (d > 1.5 ? -1e3 : 0) + -h * 50 + -c * 0.1
111
287
  };
112
- }).sort((r, n) => n.score - r.score)[0]?.artwork;
288
+ }).sort((i, n) => n.score - i.score)[0]?.artwork;
113
289
  }
114
290
  export {
291
+ p as HttpAPI,
115
292
  M as MissingCapabilityError,
116
- v as NuclearAPI,
117
- w as NuclearPluginAPI,
118
- E as pickArtwork,
119
- A as useSetting
293
+ S as NuclearAPI,
294
+ P as NuclearPluginAPI,
295
+ H as YtdlpAPI,
296
+ R as pickArtwork,
297
+ C as useSetting
120
298
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuclearplayer/plugin-sdk",
3
- "version": "0.0.14",
3
+ "version": "1.0.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.9",
42
- "@nuclearplayer/tailwind-config": "0.0.9"
41
+ "@nuclearplayer/tailwind-config": "0.0.10",
42
+ "@nuclearplayer/eslint-config": "0.0.10"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "react": "^18.3.1"