@discord-player/plugin-host 8.0.0-dev.1 → 8.0.0-dev.3
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 +92 -28
- package/dist/compat/base-extractor.d.ts +6 -0
- package/dist/compat/base-extractor.js.map +1 -1
- package/dist/compat/extractor-execution-context.js.map +1 -1
- package/dist/compat/extractor-plugin.js +107 -75
- package/dist/compat/extractor-plugin.js.map +1 -1
- package/dist/compat/utils.js.map +1 -1
- package/dist/errors.d.ts +15 -2
- package/dist/errors.js +17 -2
- package/dist/errors.js.map +1 -1
- package/dist/host.js +81 -20
- package/dist/host.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/legacy-player.d.ts +1 -1
- package/dist/lyrics.d.ts +56 -0
- package/dist/lyrics.js +110 -0
- package/dist/lyrics.js.map +1 -0
- package/dist/media.js.map +1 -1
- package/dist/plugins/execution-options.d.ts +4 -0
- package/dist/plugins/operation-dispatch.js +43 -6
- package/dist/plugins/operation-dispatch.js.map +1 -1
- package/dist/plugins/plugin-error.js.map +1 -1
- package/dist/plugins/registry-internals.d.ts +5 -3
- package/dist/plugins/registry.d.ts +103 -5
- package/dist/plugins/registry.js +403 -24
- package/dist/plugins/registry.js.map +1 -1
- package/dist/plugins/stream-resolver.js +39 -3
- package/dist/plugins/stream-resolver.js.map +1 -1
- package/dist/plugins/types.d.ts +62 -25
- package/dist/plugins/types.js.map +1 -1
- package/dist/protocol.d.ts +35 -0
- package/dist/protocol.js.map +1 -1
- package/dist/providers/lrclib.d.ts +120 -0
- package/dist/providers/lrclib.js +183 -0
- package/dist/providers/lrclib.js.map +1 -0
- package/dist/remote.d.ts +29 -0
- package/dist/remote.js +142 -0
- package/dist/remote.js.map +1 -0
- package/dist/runtime.d.ts +0 -8
- package/dist/runtime.js +55 -44
- package/dist/runtime.js.map +1 -1
- package/dist/structures/search-result.js.map +1 -1
- package/dist/structures/track-types.d.ts +7 -3
- package/dist/structures/track.d.ts +4 -11
- package/dist/structures/track.js +8 -10
- package/dist/structures/track.js.map +1 -1
- package/dist/types.d.ts +2 -4
- package/dist/utils/legacy-serialization-schemas.d.ts +10 -0
- package/dist/utils/serialization-schemas.d.ts +15 -0
- package/dist/utils/serialization-schemas.js +1 -0
- package/dist/utils/serialization-schemas.js.map +1 -1
- package/dist/utils/serialization.js.map +1 -1
- package/docs/remedia-contract.md +9 -8
- package/package.json +3 -3
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { definePlugin } from '../plugins/types.js';
|
|
2
|
+
import { parseLyrics } from '../lyrics.js';
|
|
3
|
+
function toSnakeCase(params) {
|
|
4
|
+
const result = new URLSearchParams();
|
|
5
|
+
for (const [key, value] of Object.entries(params)) {
|
|
6
|
+
if (value === undefined || value === null || value === '')
|
|
7
|
+
continue;
|
|
8
|
+
const snake = key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
9
|
+
result.set(snake, String(value));
|
|
10
|
+
}
|
|
11
|
+
return result;
|
|
12
|
+
}
|
|
13
|
+
function delayWait(ms, signal) {
|
|
14
|
+
signal?.throwIfAborted();
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
const abort = () => {
|
|
17
|
+
clearTimeout(timer);
|
|
18
|
+
reject(signal?.reason);
|
|
19
|
+
};
|
|
20
|
+
const timer = setTimeout(() => {
|
|
21
|
+
signal?.removeEventListener('abort', abort);
|
|
22
|
+
resolve();
|
|
23
|
+
}, ms);
|
|
24
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/** LRCLIB API client with serialized requests and bounded retries. */
|
|
28
|
+
export class LrcLib {
|
|
29
|
+
player;
|
|
30
|
+
/** Base API URL. */
|
|
31
|
+
api = 'https://lrclib.net/api';
|
|
32
|
+
/** Request timeout in milliseconds. */
|
|
33
|
+
timeout = 15_000;
|
|
34
|
+
/** Maximum retry count for rate limits and server errors. */
|
|
35
|
+
retryLimit = 5;
|
|
36
|
+
#tail = Promise.resolve();
|
|
37
|
+
/**
|
|
38
|
+
* Create an LRCLIB client owned by one Player.
|
|
39
|
+
* @param player Player used to identify requests and publish debug messages.
|
|
40
|
+
*/
|
|
41
|
+
constructor(
|
|
42
|
+
/** Player used to identify requests and publish debug messages. */
|
|
43
|
+
player) {
|
|
44
|
+
this.player = player;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Set the request timeout.
|
|
48
|
+
* @param timeout Positive request timeout in milliseconds.
|
|
49
|
+
*/
|
|
50
|
+
setRequestTimeout(
|
|
51
|
+
/** Timeout in milliseconds. */
|
|
52
|
+
timeout) {
|
|
53
|
+
if (!Number.isFinite(timeout) || timeout <= 0)
|
|
54
|
+
throw new RangeError('Request timeout must be a positive finite number.');
|
|
55
|
+
this.timeout = timeout;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Set the maximum retry count.
|
|
59
|
+
* @param limit Non-negative retry count for rate limits and server errors.
|
|
60
|
+
*/
|
|
61
|
+
setRetryLimit(
|
|
62
|
+
/** Non-negative retry count. */
|
|
63
|
+
limit) {
|
|
64
|
+
if (!Number.isInteger(limit) || limit < 0)
|
|
65
|
+
throw new RangeError('Retry limit must be a non-negative integer.');
|
|
66
|
+
this.retryLimit = limit;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get lyrics by exact track metadata.
|
|
70
|
+
* @param params Track title, artist, album, and optional duration.
|
|
71
|
+
*/
|
|
72
|
+
get(
|
|
73
|
+
/** Exact lookup metadata. */
|
|
74
|
+
params) {
|
|
75
|
+
return this.request(`get?${toSnakeCase(params)}`);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Get lyrics by LRCLIB record ID.
|
|
79
|
+
* @param id Numeric LRCLIB record ID.
|
|
80
|
+
*/
|
|
81
|
+
getById(
|
|
82
|
+
/** Numeric LRCLIB record ID. */
|
|
83
|
+
id) {
|
|
84
|
+
return this.request(`get/${id}`);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get cached lyrics by exact track metadata.
|
|
88
|
+
* @param params Track title, artist, album, and optional duration.
|
|
89
|
+
*/
|
|
90
|
+
getCached(
|
|
91
|
+
/** Exact lookup metadata. */
|
|
92
|
+
params) {
|
|
93
|
+
return this.request(`get-cached?${toSnakeCase(params)}`);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Search LRCLIB for matching lyric records.
|
|
97
|
+
* @param params Free-form query or track and artist metadata.
|
|
98
|
+
*/
|
|
99
|
+
search(
|
|
100
|
+
/** Search query or track and artist metadata. */
|
|
101
|
+
params) {
|
|
102
|
+
if (!params.q && !params.trackName)
|
|
103
|
+
throw new TypeError('Provide either q or trackName when searching lyrics.');
|
|
104
|
+
return this.request(`search?${toSnakeCase(params)}`);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Send one serialized request to LRCLIB.
|
|
108
|
+
* @param path API path, with or without a leading slash.
|
|
109
|
+
* @param options Additional fetch options merged with the default GET request.
|
|
110
|
+
* @returns Parsed JSON response.
|
|
111
|
+
*/
|
|
112
|
+
async request(
|
|
113
|
+
/** API path, with or without a leading slash. */
|
|
114
|
+
path,
|
|
115
|
+
/** Additional fetch options merged with the default GET request. */
|
|
116
|
+
options = {}) {
|
|
117
|
+
let release;
|
|
118
|
+
const turn = new Promise((resolve) => {
|
|
119
|
+
release = resolve;
|
|
120
|
+
});
|
|
121
|
+
const previous = this.#tail;
|
|
122
|
+
this.#tail = previous.then(() => turn);
|
|
123
|
+
await previous;
|
|
124
|
+
try {
|
|
125
|
+
const url = `${this.api}${path.startsWith('/') ? path : `/${path}`}`;
|
|
126
|
+
this.player.debug(`[LrcLib] Requesting ${path}`);
|
|
127
|
+
for (let attempt = 0;; attempt++) {
|
|
128
|
+
const response = await fetch(url, {
|
|
129
|
+
method: 'GET',
|
|
130
|
+
redirect: 'follow',
|
|
131
|
+
...options,
|
|
132
|
+
signal: options.signal ?? AbortSignal.timeout(this.timeout),
|
|
133
|
+
headers: {
|
|
134
|
+
'User-Agent': `Discord-Player/${this.player.version}`,
|
|
135
|
+
'Content-Type': 'application/json',
|
|
136
|
+
...options.headers,
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
if (response.ok)
|
|
140
|
+
return (await response.json());
|
|
141
|
+
if ((response.status === 429 || response.status >= 500) && attempt < this.retryLimit) {
|
|
142
|
+
const retryAfter = Number(response.headers.get('retry-after'));
|
|
143
|
+
const delay = Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter * 1000 : Math.min(250 * 2 ** attempt, 4000);
|
|
144
|
+
await delayWait(delay, options.signal);
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
throw new Error(`LRCLIB request failed with HTTP ${response.status} ${response.statusText}.`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
release();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/** Optional LRCLIB provider. No provider is installed by constructing a Player. */
|
|
156
|
+
export const lrclibPlugin = definePlugin({
|
|
157
|
+
id: 'org.lrclib',
|
|
158
|
+
setup(ctx) {
|
|
159
|
+
const client = new LrcLib({ version: 'plugin-host', debug: (message) => ctx.player.debug(message) });
|
|
160
|
+
ctx.on('lyrics.search', async ({ input }, { signal }) => {
|
|
161
|
+
const params = typeof input === 'string' ? { q: input } : { trackName: input.title, artistName: input.author };
|
|
162
|
+
const records = await client.request(`search?${toSnakeCase(params)}`, {
|
|
163
|
+
signal: AbortSignal.any([signal, AbortSignal.timeout(client.timeout)]),
|
|
164
|
+
});
|
|
165
|
+
return records.map((record) => ({
|
|
166
|
+
plain: record.plainLyrics
|
|
167
|
+
? { available: true, text: record.plainLyrics }
|
|
168
|
+
: { available: false },
|
|
169
|
+
synced: record.syncedLyrics
|
|
170
|
+
? { available: true, lines: parseLyrics(record.syncedLyrics) }
|
|
171
|
+
: { available: false },
|
|
172
|
+
metadata: {
|
|
173
|
+
id: record.id,
|
|
174
|
+
trackName: record.trackName,
|
|
175
|
+
artistName: record.artistName,
|
|
176
|
+
albumName: record.albumName,
|
|
177
|
+
instrumental: record.instrumental,
|
|
178
|
+
},
|
|
179
|
+
}));
|
|
180
|
+
});
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
//# sourceMappingURL=lrclib.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lrclib.js","sourceRoot":"","sources":["../../src/providers/lrclib.ts"],"names":[],"mappings":"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"}
|
package/dist/remote.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { OperationName } from './plugins/types.js';
|
|
2
|
+
/** Existing standalone HTTP deployment. Authentication stays outside Track metadata. */
|
|
3
|
+
export interface RemotePluginHostOptions {
|
|
4
|
+
/** Stable deployment identity matching the audio node's configured host. */
|
|
5
|
+
hostId: string;
|
|
6
|
+
/** HTTP(S) origin without embedded credentials. */
|
|
7
|
+
url: string;
|
|
8
|
+
/** Optional bearer credential. */
|
|
9
|
+
token?: string;
|
|
10
|
+
/** Bounded discovery and execution deadline, default 15000ms. */
|
|
11
|
+
timeoutMs?: number;
|
|
12
|
+
}
|
|
13
|
+
/** Advertised provider capabilities from a standalone host. */
|
|
14
|
+
export interface RemoteProvider {
|
|
15
|
+
/** Actual provider identity, separate from deployment identity. */
|
|
16
|
+
id: string;
|
|
17
|
+
/** Implemented operation names. */
|
|
18
|
+
operations: OperationName[];
|
|
19
|
+
/** Registered source protocols. */
|
|
20
|
+
protocols: string[];
|
|
21
|
+
/** Advertised operation priorities, applied unless the client descriptor overrides them. */
|
|
22
|
+
priorities?: Partial<Record<OperationName, number>>;
|
|
23
|
+
}
|
|
24
|
+
/** Validate live advertised capabilities; no plugin is installed on the remote server.
|
|
25
|
+
* @param host Existing standalone deployment.
|
|
26
|
+
* @param signal Registration lifetime.
|
|
27
|
+
* @returns Actual remote provider declarations.
|
|
28
|
+
*/
|
|
29
|
+
export declare function discoverRemote(host: RemotePluginHostOptions, signal: AbortSignal): Promise<RemoteProvider[]>;
|
package/dist/remote.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { lyricsResultSchema } from './lyrics.js';
|
|
3
|
+
import { deserializeSourceResult, serializeSourceTrack, } from './protocol.js';
|
|
4
|
+
import { Track } from './structures/track.js';
|
|
5
|
+
/** Fetch one authenticated metadata response through the current HTTP boundary.
|
|
6
|
+
* @internal
|
|
7
|
+
* @param host Existing deployment.
|
|
8
|
+
* @param path Discovery or execution path.
|
|
9
|
+
* @param signal Request cancellation.
|
|
10
|
+
* @param body Optional serialized execution request.
|
|
11
|
+
* @returns Parsed metadata; operational failures reject.
|
|
12
|
+
*/
|
|
13
|
+
export async function remoteMetadata(host, path, signal, body) {
|
|
14
|
+
const url = new URL(host.url);
|
|
15
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/.test(host.hostId) ||
|
|
16
|
+
!['http:', 'https:'].includes(url.protocol) ||
|
|
17
|
+
url.username ||
|
|
18
|
+
url.password ||
|
|
19
|
+
url.pathname !== '/' ||
|
|
20
|
+
url.search ||
|
|
21
|
+
url.hash)
|
|
22
|
+
throw new TypeError('Source host requires a stable ID and an HTTP(S) origin without credentials');
|
|
23
|
+
if (!Number.isSafeInteger(host.timeoutMs ?? 15000) || (host.timeoutMs ?? 15000) < 1)
|
|
24
|
+
throw new RangeError('Source host timeout must be a positive safe integer');
|
|
25
|
+
const response = await fetch(`${url.origin}${path}`, {
|
|
26
|
+
method: body === undefined ? 'GET' : 'POST',
|
|
27
|
+
redirect: 'error',
|
|
28
|
+
signal: AbortSignal.any([signal, AbortSignal.timeout(host.timeoutMs ?? 15000)]),
|
|
29
|
+
headers: { 'content-type': 'application/json', ...(host.token ? { authorization: `Bearer ${host.token}` } : {}) },
|
|
30
|
+
...(body === undefined ? {} : { body: JSON.stringify(body) }),
|
|
31
|
+
});
|
|
32
|
+
if (!response.ok)
|
|
33
|
+
throw new Error(`Source host ${host.hostId}: metadata request failed (HTTP ${response.status})`);
|
|
34
|
+
return response.json();
|
|
35
|
+
}
|
|
36
|
+
/** Validate live advertised capabilities; no plugin is installed on the remote server.
|
|
37
|
+
* @param host Existing standalone deployment.
|
|
38
|
+
* @param signal Registration lifetime.
|
|
39
|
+
* @returns Actual remote provider declarations.
|
|
40
|
+
*/
|
|
41
|
+
export async function discoverRemote(host, signal) {
|
|
42
|
+
const manifest = await remoteMetadata(host, '/.well-known/remedia', signal);
|
|
43
|
+
if (!manifest ||
|
|
44
|
+
typeof manifest !== 'object' ||
|
|
45
|
+
!('protocolVersion' in manifest) ||
|
|
46
|
+
manifest.protocolVersion !== 1 ||
|
|
47
|
+
!('providers' in manifest) ||
|
|
48
|
+
!Array.isArray(manifest.providers))
|
|
49
|
+
throw new Error(`Source host ${host.hostId}: incompatible metadata manifest`);
|
|
50
|
+
if (!('hostId' in manifest) || manifest.hostId !== host.hostId)
|
|
51
|
+
throw new Error(`Source host ${host.hostId}: deployment identity does not match advertised host`);
|
|
52
|
+
return manifest.providers.map((provider) => {
|
|
53
|
+
if (!provider ||
|
|
54
|
+
typeof provider.id !== 'string' ||
|
|
55
|
+
!Array.isArray(provider.operations) ||
|
|
56
|
+
!provider.operations.every((name) => typeof name === 'string') ||
|
|
57
|
+
!Array.isArray(provider.protocols) ||
|
|
58
|
+
!provider.protocols.every((name) => typeof name === 'string'))
|
|
59
|
+
throw new TypeError('Invalid remote provider manifest');
|
|
60
|
+
if (provider.priorities !== undefined)
|
|
61
|
+
z.record(z.string(), z.number()).parse(provider.priorities);
|
|
62
|
+
return provider;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/** Register remote metadata operations into the ordinary capability registry.
|
|
66
|
+
* @internal
|
|
67
|
+
* @param ctx Registration owner.
|
|
68
|
+
* @param providerId Actual remote provider ID.
|
|
69
|
+
* @param host Existing deployment configuration.
|
|
70
|
+
* @param advertised Already validated discovery for a bulk host registration.
|
|
71
|
+
*/
|
|
72
|
+
export async function registerRemote(ctx, providerId, host, advertised) {
|
|
73
|
+
const provider = (advertised ?? (await discoverRemote(host, ctx.signal))).find((item) => item.id === providerId);
|
|
74
|
+
if (!provider)
|
|
75
|
+
throw new Error(`Source host ${host.hostId}: provider ${providerId} is not advertised`);
|
|
76
|
+
const execute = async (request, signal) => {
|
|
77
|
+
const envelope = await remoteMetadata(host, '/remedia/v1/execute', signal, {
|
|
78
|
+
pluginId: 'discord-player.source',
|
|
79
|
+
operation: 'metadata.execute',
|
|
80
|
+
input: request,
|
|
81
|
+
});
|
|
82
|
+
if (!envelope ||
|
|
83
|
+
typeof envelope !== 'object' ||
|
|
84
|
+
!('handled' in envelope) ||
|
|
85
|
+
envelope.handled !== true ||
|
|
86
|
+
!('result' in envelope))
|
|
87
|
+
throw new Error(`Source host ${host.hostId}: invalid metadata response`);
|
|
88
|
+
return envelope.result;
|
|
89
|
+
};
|
|
90
|
+
const portableQuery = (input) => {
|
|
91
|
+
const original = input.options ?? {};
|
|
92
|
+
return {
|
|
93
|
+
...input,
|
|
94
|
+
options: {
|
|
95
|
+
limit: original.limit,
|
|
96
|
+
blockExtractors: original.blockExtractors,
|
|
97
|
+
requestedBy: typeof original.requestedBy === 'object' ? original.requestedBy?.id : original.requestedBy,
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
if (provider.operations.includes('search.query.match')) {
|
|
102
|
+
ctx.on('search.query.match', async (input, { signal }) => {
|
|
103
|
+
const result = await execute({ providerId, operation: 'search.query.match', input: portableQuery(input) }, signal);
|
|
104
|
+
const matches = z
|
|
105
|
+
.array(z.object({ score: z.number(), pluginId: z.string().optional() }).nullable())
|
|
106
|
+
.parse(result);
|
|
107
|
+
return matches.find((match) => match !== null && match.score >= 0) ?? null;
|
|
108
|
+
}, { protocols: provider.protocols, priority: provider.priorities?.['search.query.match'] });
|
|
109
|
+
}
|
|
110
|
+
if (provider.operations.includes('search.query.resolve')) {
|
|
111
|
+
ctx.on('search.query.resolve', async (input, { signal }) => {
|
|
112
|
+
const result = deserializeSourceResult((await execute({ providerId, operation: 'search.query.resolve', input: portableQuery(input) }, signal)));
|
|
113
|
+
for (const track of result.tracks)
|
|
114
|
+
if (track.sourceReference?.pluginId !== providerId || track.sourceReference.hostId !== host.hostId)
|
|
115
|
+
throw new Error('Remote Track provider or deployment identity does not match its registration');
|
|
116
|
+
return result;
|
|
117
|
+
}, { protocols: provider.protocols, priority: provider.priorities?.['search.query.resolve'] });
|
|
118
|
+
}
|
|
119
|
+
if (provider.operations.includes('track.related')) {
|
|
120
|
+
ctx.on('track.related', async ({ track }, { signal }) => {
|
|
121
|
+
const result = await execute({ providerId, operation: 'track.related', input: { track: serializeSourceTrack(track) } }, signal);
|
|
122
|
+
return deserializeSourceResult(result);
|
|
123
|
+
}, { priority: provider.priorities?.['track.related'] });
|
|
124
|
+
}
|
|
125
|
+
if (provider.operations.includes('lyrics.search')) {
|
|
126
|
+
ctx.on('lyrics.search', async ({ input }, { signal }) => {
|
|
127
|
+
const result = await execute({
|
|
128
|
+
providerId,
|
|
129
|
+
operation: 'lyrics.search',
|
|
130
|
+
input: { input: input instanceof Track ? input.serialize() : input },
|
|
131
|
+
}, signal);
|
|
132
|
+
const groups = z.array(z.array(lyricsResultSchema).nullable()).parse(result);
|
|
133
|
+
return groups
|
|
134
|
+
.flatMap((group) => group ?? [])
|
|
135
|
+
.map((record) => ({
|
|
136
|
+
...record,
|
|
137
|
+
provider: { pluginId: providerId, hostId: host.hostId, data: record.provider?.data ?? null },
|
|
138
|
+
}));
|
|
139
|
+
}, { priority: provider.priorities?.['lyrics.search'] });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=remote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote.js","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime.d.ts
CHANGED
|
@@ -30,20 +30,12 @@ export declare class SourcePluginRuntime extends SafeEventEmitter<SourceRuntimeE
|
|
|
30
30
|
* @param options Source settings and optional embedding context.
|
|
31
31
|
*/
|
|
32
32
|
constructor(options?: SourcePluginRuntimeOptions);
|
|
33
|
-
/** Queue orchestration requires an actual DiscordPlayer. */
|
|
34
|
-
get queues(): never;
|
|
35
|
-
/** Voice nodes require an actual DiscordPlayer. */
|
|
36
|
-
get nodes(): never;
|
|
37
|
-
/** Audio clients are unavailable in standalone source execution. */
|
|
38
|
-
get remedia(): never;
|
|
39
33
|
/** Required audio access is unavailable in standalone execution. */
|
|
40
34
|
getRemedia(): RemediaClient;
|
|
41
35
|
/** Optional audio access returns null.
|
|
42
36
|
* @param throwOnMissing Optional lookup flag.
|
|
43
37
|
*/
|
|
44
38
|
getRemedia(throwOnMissing: false): RemediaClient | null;
|
|
45
|
-
/** Playback is outside the source compatibility API. */
|
|
46
|
-
play(): never;
|
|
47
39
|
/** Emit a source diagnostic.
|
|
48
40
|
* @param message Diagnostic text.
|
|
49
41
|
*/
|
package/dist/runtime.js
CHANGED
|
@@ -24,27 +24,11 @@ export class SourcePluginRuntime extends SafeEventEmitter {
|
|
|
24
24
|
this.plugins = new PluginRegistry(this.player, () => this.options.blockExtractors ?? [], options.hostId);
|
|
25
25
|
this.extractors = new ExtractorExecutionContext(this.player);
|
|
26
26
|
}
|
|
27
|
-
/** Queue orchestration requires an actual DiscordPlayer. */
|
|
28
|
-
get queues() {
|
|
29
|
-
throw new Error('SourcePluginRuntime does not provide queues; use DiscordPlayer for playback');
|
|
30
|
-
}
|
|
31
|
-
/** Voice nodes require an actual DiscordPlayer. */
|
|
32
|
-
get nodes() {
|
|
33
|
-
throw new Error('SourcePluginRuntime does not provide voice nodes; use DiscordPlayer for playback');
|
|
34
|
-
}
|
|
35
|
-
/** Audio clients are unavailable in standalone source execution. */
|
|
36
|
-
get remedia() {
|
|
37
|
-
throw new Error('SourcePluginRuntime does not initialize a Remedia audio client');
|
|
38
|
-
}
|
|
39
27
|
getRemedia(throwOnMissing = true) {
|
|
40
28
|
if (throwOnMissing)
|
|
41
29
|
throw new Error('SourcePluginRuntime does not initialize an audio client; use DiscordPlayer');
|
|
42
30
|
return null;
|
|
43
31
|
}
|
|
44
|
-
/** Playback is outside the source compatibility API. */
|
|
45
|
-
play() {
|
|
46
|
-
throw new Error('SourcePluginRuntime cannot play audio; use DiscordPlayer');
|
|
47
|
-
}
|
|
48
32
|
/** Emit a source diagnostic.
|
|
49
33
|
* @param message Diagnostic text.
|
|
50
34
|
*/
|
|
@@ -74,45 +58,72 @@ export class SourcePluginRuntime extends SafeEventEmitter {
|
|
|
74
58
|
return new SearchResult({ tracks: query.tracks, playlist: query });
|
|
75
59
|
}
|
|
76
60
|
const blocked = [...(this.options.blockExtractors ?? []), ...(options.blockExtractors ?? [])];
|
|
77
|
-
const target = options.pluginId ?? (options.searchEngine?.startsWith('ext:') ? options.searchEngine.slice(4) : undefined);
|
|
78
61
|
await this.plugins.ready();
|
|
79
|
-
const
|
|
62
|
+
const engine = options.searchEngine;
|
|
63
|
+
const legacy = engine?.startsWith('ext:') ? engine.slice(4) : undefined;
|
|
64
|
+
if (legacy !== undefined && !this.extractors.get(legacy))
|
|
65
|
+
throw new Error(`Legacy extractor ${legacy} is not registered`);
|
|
66
|
+
const target = legacy ?? (engine && this.plugins.has(engine) ? engine : undefined);
|
|
67
|
+
const prefix = options.resolveCustomProtocols !== false && !/^(?:https?|file):/i.test(query) && !/^[a-z]:/i.test(query)
|
|
68
|
+
? /^([a-z][a-z0-9+.-]*):(?:\/\/)?(.*)$/is.exec(query)
|
|
69
|
+
: null;
|
|
80
70
|
const protocol = prefix && this.plugins.supportsProtocol(prefix[1], { pluginId: target, blocked }) ? prefix[1] : undefined;
|
|
81
|
-
const
|
|
71
|
+
const providerHint = target ? undefined : engine;
|
|
72
|
+
let input = {
|
|
82
73
|
query: protocol ? prefix[2] : query,
|
|
83
74
|
protocol,
|
|
75
|
+
providerHint,
|
|
84
76
|
options: {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
77
|
+
requestedBy: options.requestedBy,
|
|
78
|
+
requestOptions: options.requestOptions,
|
|
79
|
+
limit: options.limit,
|
|
80
|
+
blockExtractors: options.blockExtractors,
|
|
89
81
|
},
|
|
90
82
|
};
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (!match?.pluginId) {
|
|
97
|
-
return SearchResult.empty();
|
|
98
|
-
}
|
|
99
|
-
const result = await this.plugins.execute('search.query.resolve', input, {
|
|
100
|
-
...execution,
|
|
101
|
-
pluginId: match.pluginId,
|
|
102
|
-
});
|
|
103
|
-
if (!result) {
|
|
104
|
-
return SearchResult.empty();
|
|
83
|
+
if (this.plugins.hasCapability('search.beforeQuery')) {
|
|
84
|
+
const transformed = await this.plugins.execute('search.beforeQuery', input, { signal: options.signal });
|
|
85
|
+
if (!transformed || typeof transformed.query !== 'string')
|
|
86
|
+
throw new TypeError('search.beforeQuery requires a string query.');
|
|
87
|
+
input = { ...input, ...transformed };
|
|
105
88
|
}
|
|
106
|
-
|
|
107
|
-
|
|
89
|
+
const execution = { signal: options.signal, blocked, pluginId: target, hostId: options.hostId };
|
|
90
|
+
const matches = target
|
|
91
|
+
? [{ pluginId: target, score: 0, hostId: options.hostId }]
|
|
92
|
+
: protocol
|
|
93
|
+
? this.plugins.protocolMatches(protocol, execution)
|
|
94
|
+
: await this.plugins.execute('search.query.match', input, execution);
|
|
95
|
+
for (const match of matches) {
|
|
96
|
+
if (!match?.pluginId || match.score < 0)
|
|
97
|
+
continue;
|
|
98
|
+
const result = await this.plugins.execute('search.query.resolve', input, {
|
|
99
|
+
...execution,
|
|
108
100
|
pluginId: match.pluginId,
|
|
109
|
-
|
|
110
|
-
};
|
|
111
|
-
if (
|
|
112
|
-
|
|
101
|
+
hostId: match.hostId ?? (target ? options.hostId : null),
|
|
102
|
+
});
|
|
103
|
+
if (!result?.tracks.length) {
|
|
104
|
+
if (target)
|
|
105
|
+
break;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
for (const track of result.tracks) {
|
|
109
|
+
track.sourceReference ??= {
|
|
110
|
+
pluginId: match.pluginId,
|
|
111
|
+
...(match.hostId ? { hostId: match.hostId } : {}),
|
|
112
|
+
data: { url: track.url },
|
|
113
|
+
};
|
|
114
|
+
if (options.requestedBy !== undefined)
|
|
115
|
+
track.requestedBy = options.requestedBy;
|
|
113
116
|
}
|
|
117
|
+
const transformed = this.plugins.hasCapability('search.afterResults')
|
|
118
|
+
? await this.plugins.execute('search.afterResults', result, { signal: options.signal })
|
|
119
|
+
: result;
|
|
120
|
+
if (!transformed ||
|
|
121
|
+
!Array.isArray(transformed.tracks) ||
|
|
122
|
+
!transformed.tracks.every((track) => track instanceof Track))
|
|
123
|
+
throw new TypeError('search.afterResults requires Track instances.');
|
|
124
|
+
return new SearchResult(transformed);
|
|
114
125
|
}
|
|
115
|
-
return
|
|
126
|
+
return SearchResult.empty();
|
|
116
127
|
}
|
|
117
128
|
}
|
|
118
129
|
//# sourceMappingURL=runtime.js.map
|
package/dist/runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-result.js","sourceRoot":"","sources":["../../src/structures/search-result.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"search-result.js","sourceRoot":"","sources":["../../src/structures/search-result.ts"],"names":[],"mappings":"AAYA,oEAAoE;AACpE,MAAM,OAAO,YAAY;IAWa,IAAI;IAVxC,+CAA+C;IAC/B,MAAM,CAAU;IAEhC,kEAAkE;IAClD,QAAQ,CAAkB;IAE1C;;;OAGG;IACH,YAAoC,IAAsB;oBAAtB,IAAI;QACtC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAChC,CAAC;IAED,6EAA6E;IACtE,MAAM,CAAC,KAAK;QACjB,OAAO,IAAI,YAAY,CAAC;YACtB,MAAM,EAAE,EAAE;YACV,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;IACL,CAAC;IAED,8CAA8C;IACvC,OAAO;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;IAClC,CAAC;IAQM,KAAK,CAAC,KAAc;QACzB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QAChC,CAAC;QAED,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACrC,CAAC;CACF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SearchQueryType } from '../compat/query-types.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ProviderReference } from '../plugins/types.js';
|
|
3
3
|
import type { JSONValue, SerializedEntity, SERIALIZATION_SCHEMA_VERSION } from '../utils/serialization.js';
|
|
4
4
|
import type { Playlist, PlaylistData, PlaylistJSON } from './playlist.js';
|
|
5
5
|
/** Name or identifier for a Track's source integration. */
|
|
@@ -13,7 +13,9 @@ export type TrackRequester = string | {
|
|
|
13
13
|
/** Public metadata and optional portable source identity. */
|
|
14
14
|
export interface TrackData<Metadata = unknown> {
|
|
15
15
|
/** Portable provider payload; exclude secrets and live resources. */
|
|
16
|
-
sourceReference?:
|
|
16
|
+
sourceReference?: ProviderReference;
|
|
17
|
+
/** Optional portable lyrics provider affinity. */
|
|
18
|
+
lyricsReference?: ProviderReference;
|
|
17
19
|
/** Process-local legacy data, never persisted. */
|
|
18
20
|
raw?: Record<string, any>;
|
|
19
21
|
/** Legacy source location or engine object, never persisted. */
|
|
@@ -92,7 +94,9 @@ export interface TrackJSON<Metadata = unknown> extends TrackData<Metadata> {
|
|
|
92
94
|
/** Public Track fields stored by the versioned persistence format. */
|
|
93
95
|
export type SerializedTrackData = {
|
|
94
96
|
/** Optional provider identity, absent in older version 1 payloads. */
|
|
95
|
-
sourceReference?:
|
|
97
|
+
sourceReference?: ProviderReference;
|
|
98
|
+
/** Optional portable lyrics provider affinity. */
|
|
99
|
+
lyricsReference?: ProviderReference;
|
|
96
100
|
/** Stable Track identifier. */
|
|
97
101
|
id: string;
|
|
98
102
|
/** Display title. */
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { TrackData, TrackJSON, TrackRequester, TrackSource, SerializedTrack } from './track-types.js';
|
|
2
2
|
import type { LegacyPlayerContext } from '../legacy-player.js';
|
|
3
3
|
import type { BaseExtractor, SearchQueryType } from '../compat/extractors.js';
|
|
4
|
-
import type {
|
|
5
|
-
import type { MediaSource } from '@remedia/client';
|
|
4
|
+
import type { ProviderReference } from '../plugins/types.js';
|
|
6
5
|
import { type Serializable } from '../utils/serialization.js';
|
|
7
6
|
import { Playlist } from './playlist.js';
|
|
8
7
|
export type * from './track-types.js';
|
|
@@ -33,7 +32,9 @@ export declare class Track<Metadata = unknown> implements Serializable<Serialize
|
|
|
33
32
|
/** Playlist containing this track, when present. */
|
|
34
33
|
playlist: Playlist | null;
|
|
35
34
|
/** Portable source identity used by the plugin host. */
|
|
36
|
-
sourceReference?:
|
|
35
|
+
sourceReference?: ProviderReference;
|
|
36
|
+
/** Optional portable lyrics provider affinity. */
|
|
37
|
+
lyricsReference?: ProviderReference;
|
|
37
38
|
/** Opaque, expiring host state hint. Excluded from toJSON() and serialize(); retain only in memory. */
|
|
38
39
|
sourceState?: string;
|
|
39
40
|
/** Process-local v7 raw payload. Never serialized. */
|
|
@@ -100,14 +101,6 @@ export declare class Track<Metadata = unknown> implements Serializable<Serialize
|
|
|
100
101
|
* @returns The same Track reference with a different metadata type.
|
|
101
102
|
*/
|
|
102
103
|
asMetadata<NewMetadata>(): Track<NewMetadata>;
|
|
103
|
-
/** Deprecated compatibility stub. Playback resolves sources through player.plugins.
|
|
104
|
-
* @param options Unused cancellation options.
|
|
105
|
-
* @returns Always rejects; register a source plugin instead.
|
|
106
|
-
* @deprecated Use player.plugins.resolveStream(track).
|
|
107
|
-
*/
|
|
108
|
-
getStreamableSource(options?: {
|
|
109
|
-
signal?: AbortSignal;
|
|
110
|
-
}): Promise<MediaSource>;
|
|
111
104
|
/** Format the Track as `title by author`, omitting the author when empty. */
|
|
112
105
|
toString(): string;
|
|
113
106
|
/** Format the Track title as a Markdown hyperlink to its source URL. */
|