@convbased/sdk 0.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/LICENSE +21 -0
- package/README.md +235 -0
- package/dist/cjs/client.js +635 -0
- package/dist/cjs/client.js.map +1 -0
- package/dist/cjs/endpoints.js +10 -0
- package/dist/cjs/endpoints.js.map +1 -0
- package/dist/cjs/events.js +39 -0
- package/dist/cjs/events.js.map +1 -0
- package/dist/cjs/graphql.js +40 -0
- package/dist/cjs/graphql.js.map +1 -0
- package/dist/cjs/index.js +24 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/rtcServers.js +35 -0
- package/dist/cjs/rtcServers.js.map +1 -0
- package/dist/cjs/sdp.js +37 -0
- package/dist/cjs/sdp.js.map +1 -0
- package/dist/cjs/signaling.js +146 -0
- package/dist/cjs/signaling.js.map +1 -0
- package/dist/cjs/tts.js +227 -0
- package/dist/cjs/tts.js.map +1 -0
- package/dist/cjs/types.js +26 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/upload.js +87 -0
- package/dist/cjs/upload.js.map +1 -0
- package/dist/client.d.ts +169 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +631 -0
- package/dist/client.js.map +1 -0
- package/dist/convbased-sdk.global.js +1291 -0
- package/dist/endpoints.d.ts +3 -0
- package/dist/endpoints.d.ts.map +1 -0
- package/dist/endpoints.js +7 -0
- package/dist/endpoints.js.map +1 -0
- package/dist/events.d.ts +9 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +35 -0
- package/dist/events.js.map +1 -0
- package/dist/graphql.d.ts +18 -0
- package/dist/graphql.d.ts.map +1 -0
- package/dist/graphql.js +37 -0
- package/dist/graphql.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/rtcServers.d.ts +13 -0
- package/dist/rtcServers.d.ts.map +1 -0
- package/dist/rtcServers.js +31 -0
- package/dist/rtcServers.js.map +1 -0
- package/dist/sdp.d.ts +6 -0
- package/dist/sdp.d.ts.map +1 -0
- package/dist/sdp.js +34 -0
- package/dist/sdp.js.map +1 -0
- package/dist/signaling.d.ts +33 -0
- package/dist/signaling.d.ts.map +1 -0
- package/dist/signaling.js +142 -0
- package/dist/signaling.js.map +1 -0
- package/dist/tts.d.ts +111 -0
- package/dist/tts.d.ts.map +1 -0
- package/dist/tts.js +223 -0
- package/dist/tts.js.map +1 -0
- package/dist/types.d.ts +194 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +23 -0
- package/dist/types.js.map +1 -0
- package/dist/upload.d.ts +46 -0
- package/dist/upload.d.ts.map +1 -0
- package/dist/upload.js +82 -0
- package/dist/upload.js.map +1 -0
- package/package.json +57 -0
- package/src/client.ts +839 -0
- package/src/endpoints.ts +8 -0
- package/src/events.ts +38 -0
- package/src/graphql.ts +58 -0
- package/src/index.ts +50 -0
- package/src/rtcServers.ts +38 -0
- package/src/sdp.ts +45 -0
- package/src/signaling.ts +172 -0
- package/src/tts.ts +364 -0
- package/src/types.ts +201 -0
- package/src/upload.ts +132 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../src/endpoints.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,qBAAqB,4CACQ,CAAC;AAC3C,eAAO,MAAM,mBAAmB,4CACU,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Production endpoints baked into the SDK. These mirror Convbased-Web's
|
|
2
|
+
// `.env` (VITE_WS_ENDPOINT / VITE_API_BASE_URL) and are considered stable —
|
|
3
|
+
// they're consumed by every Convbased client today. Override only for
|
|
4
|
+
// self-hosted deployments or local development.
|
|
5
|
+
export const DEFAULT_SIGNALING_URL = "wss://api.weights.chat/api/signaling/ws";
|
|
6
|
+
export const DEFAULT_GRAPHQL_URL = "https://api.weights.chat/api/v1/graphql";
|
|
7
|
+
//# sourceMappingURL=endpoints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../src/endpoints.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,4EAA4E;AAC5E,sEAAsE;AACtE,gDAAgD;AAChD,MAAM,CAAC,MAAM,qBAAqB,GACjC,yCAAyC,CAAC;AAC3C,MAAM,CAAC,MAAM,mBAAmB,GAC/B,yCAAyC,CAAC"}
|
package/dist/events.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type Listener<T> = (payload: T) => void;
|
|
2
|
+
export declare class TypedEmitter<TEvents extends Record<string, unknown>> {
|
|
3
|
+
private readonly listeners;
|
|
4
|
+
on<K extends keyof TEvents>(event: K, fn: Listener<TEvents[K]>): () => void;
|
|
5
|
+
off<K extends keyof TEvents>(event: K, fn: Listener<TEvents[K]>): void;
|
|
6
|
+
emit<K extends keyof TEvents>(event: K, payload: TEvents[K]): void;
|
|
7
|
+
removeAllListeners(): void;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,CAAC;AAE/C,qBAAa,YAAY,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAChE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAEnB;IAEP,EAAE,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAK3E,GAAG,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAItE,IAAI,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI;IAalE,kBAAkB,IAAI,IAAI;CAK1B"}
|
package/dist/events.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Minimal typed event emitter; we avoid pulling Node's EventEmitter so the
|
|
2
|
+
// SDK stays browser-first with no polyfill chain.
|
|
3
|
+
export class TypedEmitter {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.listeners = {};
|
|
6
|
+
}
|
|
7
|
+
on(event, fn) {
|
|
8
|
+
var _a;
|
|
9
|
+
((_a = this.listeners)[event] ?? (_a[event] = new Set())).add(fn);
|
|
10
|
+
return () => this.off(event, fn);
|
|
11
|
+
}
|
|
12
|
+
off(event, fn) {
|
|
13
|
+
this.listeners[event]?.delete(fn);
|
|
14
|
+
}
|
|
15
|
+
emit(event, payload) {
|
|
16
|
+
const set = this.listeners[event];
|
|
17
|
+
if (!set)
|
|
18
|
+
return;
|
|
19
|
+
for (const fn of set) {
|
|
20
|
+
try {
|
|
21
|
+
fn(payload);
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
// Listeners shouldn't crash the emitter.
|
|
25
|
+
console.error(`[convbased-sdk] listener for "${String(event)}" threw:`, e);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
removeAllListeners() {
|
|
30
|
+
for (const key of Object.keys(this.listeners)) {
|
|
31
|
+
delete this.listeners[key];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,kDAAkD;AAIlD,MAAM,OAAO,YAAY;IAAzB;QACkB,cAAS,GAEtB,EAAE,CAAC;IA6BR,CAAC;IA3BA,EAAE,CAA0B,KAAQ,EAAE,EAAwB;;QAC7D,OAAC,IAAI,CAAC,SAAS,EAAC,KAAK,SAAL,KAAK,IAAM,IAAI,GAAG,EAAE,EAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9C,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,GAAG,CAA0B,KAAQ,EAAE,EAAwB;QAC9D,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,IAAI,CAA0B,KAAQ,EAAE,OAAmB;QAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACtB,IAAI,CAAC;gBACJ,EAAE,CAAC,OAAO,CAAC,CAAC;YACb,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACZ,yCAAyC;gBACzC,OAAO,CAAC,KAAK,CAAC,iCAAiC,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;YAC5E,CAAC;QACF,CAAC;IACF,CAAC;IAED,kBAAkB;QACjB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAC/C,OAAO,IAAI,CAAC,SAAS,CAAC,GAAoB,CAAC,CAAC;QAC7C,CAAC;IACF,CAAC;CACD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface GraphQLAuth {
|
|
2
|
+
apiKey?: string;
|
|
3
|
+
accessToken?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface GraphQLRequestArgs<V> extends GraphQLAuth {
|
|
6
|
+
graphqlUrl: string;
|
|
7
|
+
query: string;
|
|
8
|
+
variables?: V;
|
|
9
|
+
signal?: AbortSignal;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Issue a single GraphQL operation and return `data`. Throws on HTTP failure
|
|
13
|
+
* or when the response carries a non-empty `errors` array — the thrown
|
|
14
|
+
* `Error.message` is the first server-reported message (often an i18n key the
|
|
15
|
+
* caller can localize).
|
|
16
|
+
*/
|
|
17
|
+
export declare function graphqlRequest<T, V = Record<string, unknown>>(args: GraphQLRequestArgs<V>): Promise<T>;
|
|
18
|
+
//# sourceMappingURL=graphql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql.d.ts","sourceRoot":"","sources":["../src/graphql.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC,CAAE,SAAQ,WAAW;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,CAAC,CAAC;IACd,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClE,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,GACzB,OAAO,CAAC,CAAC,CAAC,CAiCZ"}
|
package/dist/graphql.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Shared GraphQL transport for the Convbased service. Authentication mirrors
|
|
2
|
+
// the server middleware: `x-api-key: <key>` for API keys, or
|
|
3
|
+
// `Authorization: Bearer <jwt>` for access tokens.
|
|
4
|
+
/**
|
|
5
|
+
* Issue a single GraphQL operation and return `data`. Throws on HTTP failure
|
|
6
|
+
* or when the response carries a non-empty `errors` array — the thrown
|
|
7
|
+
* `Error.message` is the first server-reported message (often an i18n key the
|
|
8
|
+
* caller can localize).
|
|
9
|
+
*/
|
|
10
|
+
export async function graphqlRequest(args) {
|
|
11
|
+
const headers = {
|
|
12
|
+
"content-type": "application/json",
|
|
13
|
+
};
|
|
14
|
+
if (args.apiKey)
|
|
15
|
+
headers["x-api-key"] = args.apiKey;
|
|
16
|
+
else if (args.accessToken) {
|
|
17
|
+
headers["authorization"] = `Bearer ${args.accessToken}`;
|
|
18
|
+
}
|
|
19
|
+
const res = await fetch(args.graphqlUrl, {
|
|
20
|
+
method: "POST",
|
|
21
|
+
headers,
|
|
22
|
+
body: JSON.stringify({ query: args.query, variables: args.variables }),
|
|
23
|
+
signal: args.signal,
|
|
24
|
+
});
|
|
25
|
+
if (!res.ok) {
|
|
26
|
+
throw new Error(`GraphQL request failed: HTTP ${res.status} ${res.statusText}`);
|
|
27
|
+
}
|
|
28
|
+
const json = (await res.json());
|
|
29
|
+
if (json.errors?.length) {
|
|
30
|
+
throw new Error(json.errors.map((e) => e.message).join("; "));
|
|
31
|
+
}
|
|
32
|
+
if (json.data === undefined || json.data === null) {
|
|
33
|
+
throw new Error("GraphQL response contained no data");
|
|
34
|
+
}
|
|
35
|
+
return json.data;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=graphql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql.js","sourceRoot":"","sources":["../src/graphql.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,6DAA6D;AAC7D,mDAAmD;AAcnD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CACnC,IAA2B;IAE3B,MAAM,OAAO,GAA2B;QACvC,cAAc,EAAE,kBAAkB;KAClC,CAAC;IACF,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;SAC/C,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QAC3B,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,WAAW,EAAE,CAAC;IACzD,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE;QACxC,MAAM,EAAE,MAAM;QACd,OAAO;QACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;QACtE,MAAM,EAAE,IAAI,CAAC,MAAM;KACnB,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACd,gCAAgC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CAC9D,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAG7B,CAAC;IACF,IAAI,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC;AAClB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { ConvbasedClient, type TaskAckEvent, type TaskProgressEvent, type TaskFinishedEvent, type StartTaskOptions, type RunFileInferenceOptions, } from "./client.js";
|
|
2
|
+
export { TtsClient, type TtsClientOptions, type TtsParams, type TtsJob, type TtsJobStatus, type TtsResult, type TtsPricing, type SubmitTtsOptions, type SynthesizeOptions, } from "./tts.js";
|
|
3
|
+
export { uploadAudio, requestAudioUpload, putToPresigned, type PresignedUpload, type HeaderKV, } from "./upload.js";
|
|
4
|
+
export { graphqlRequest, type GraphQLAuth } from "./graphql.js";
|
|
5
|
+
export { applyOpusSdpOptions } from "./sdp.js";
|
|
6
|
+
export { fetchRTCServers, DEFAULT_STUN_SERVERS, } from "./rtcServers.js";
|
|
7
|
+
export { DEFAULT_SIGNALING_URL, DEFAULT_GRAPHQL_URL, } from "./endpoints.js";
|
|
8
|
+
export { RTCStatusCode, type ConnectOptions, type ConnectionState, type ConnectionStats, type ConvbasedClientOptions, type FileInferencePreferences, type IncomingMessage, type OutgoingMessage, type RTCPreferences, type RTCServersConfig, type ServerMessageEvent, type TaskStatus, } from "./types.js";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,eAAe,EACf,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,GAC5B,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,SAAS,EACT,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,GACtB,MAAM,UAAU,CAAC;AAClB,OAAO,EACN,WAAW,EACX,kBAAkB,EAClB,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,QAAQ,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EACN,eAAe,EACf,oBAAoB,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,qBAAqB,EACrB,mBAAmB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,aAAa,EACb,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,UAAU,GACf,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { ConvbasedClient, } from "./client.js";
|
|
2
|
+
export { TtsClient, } from "./tts.js";
|
|
3
|
+
export { uploadAudio, requestAudioUpload, putToPresigned, } from "./upload.js";
|
|
4
|
+
export { graphqlRequest } from "./graphql.js";
|
|
5
|
+
export { applyOpusSdpOptions } from "./sdp.js";
|
|
6
|
+
export { fetchRTCServers, DEFAULT_STUN_SERVERS, } from "./rtcServers.js";
|
|
7
|
+
export { DEFAULT_SIGNALING_URL, DEFAULT_GRAPHQL_URL, } from "./endpoints.js";
|
|
8
|
+
export { RTCStatusCode, } from "./types.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,eAAe,GAMf,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,SAAS,GAST,MAAM,UAAU,CAAC;AAClB,OAAO,EACN,WAAW,EACX,kBAAkB,EAClB,cAAc,GAGd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAoB,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EACN,eAAe,EACf,oBAAoB,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,qBAAqB,EACrB,mBAAmB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,aAAa,GAYb,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type GraphQLAuth } from "./graphql.js";
|
|
2
|
+
import type { RTCServersConfig } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Fetch TURN credentials from the Convbased GraphQL service. The query matches
|
|
5
|
+
* the one used by Convbased-Web's `getRTCServers`. Authentication uses the
|
|
6
|
+
* same API key / access token passed to the SDK.
|
|
7
|
+
*/
|
|
8
|
+
export declare function fetchRTCServers(args: GraphQLAuth & {
|
|
9
|
+
graphqlUrl: string;
|
|
10
|
+
signal?: AbortSignal;
|
|
11
|
+
}): Promise<RTCServersConfig>;
|
|
12
|
+
export declare const DEFAULT_STUN_SERVERS: RTCServersConfig[];
|
|
13
|
+
//# sourceMappingURL=rtcServers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rtcServers.d.ts","sourceRoot":"","sources":["../src/rtcServers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;;;GAIG;AACH,wBAAsB,eAAe,CACpC,IAAI,EAAE,WAAW,GAAG;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB,GACC,OAAO,CAAC,gBAAgB,CAAC,CAoB3B;AAED,eAAO,MAAM,oBAAoB,EAAE,gBAAgB,EAElD,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { graphqlRequest } from "./graphql.js";
|
|
2
|
+
/**
|
|
3
|
+
* Fetch TURN credentials from the Convbased GraphQL service. The query matches
|
|
4
|
+
* the one used by Convbased-Web's `getRTCServers`. Authentication uses the
|
|
5
|
+
* same API key / access token passed to the SDK.
|
|
6
|
+
*/
|
|
7
|
+
export async function fetchRTCServers(args) {
|
|
8
|
+
const data = await graphqlRequest({
|
|
9
|
+
graphqlUrl: args.graphqlUrl,
|
|
10
|
+
apiKey: args.apiKey,
|
|
11
|
+
accessToken: args.accessToken,
|
|
12
|
+
signal: args.signal,
|
|
13
|
+
query: /* GraphQL */ `
|
|
14
|
+
query {
|
|
15
|
+
rtcServers {
|
|
16
|
+
urls
|
|
17
|
+
username
|
|
18
|
+
credential
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
`,
|
|
22
|
+
});
|
|
23
|
+
if (!data.rtcServers) {
|
|
24
|
+
throw new Error("rtcServers returned an empty payload");
|
|
25
|
+
}
|
|
26
|
+
return data.rtcServers;
|
|
27
|
+
}
|
|
28
|
+
export const DEFAULT_STUN_SERVERS = [
|
|
29
|
+
{ urls: ["stun:stun.l.google.com:19302"] },
|
|
30
|
+
];
|
|
31
|
+
//# sourceMappingURL=rtcServers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rtcServers.js","sourceRoot":"","sources":["../src/rtcServers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAoB,MAAM,cAAc,CAAC;AAGhE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACpC,IAGC;IAED,MAAM,IAAI,GAAG,MAAM,cAAc,CAAoC;QACpE,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,KAAK,EAAE,aAAa,CAAC;;;;;;;;GAQpB;KACD,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,IAAI,CAAC,UAAU,CAAC;AACxB,CAAC;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAuB;IACvD,EAAE,IAAI,EAAE,CAAC,8BAA8B,CAAC,EAAE;CAC1C,CAAC"}
|
package/dist/sdp.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdp.d.ts","sourceRoot":"","sources":["../src/sdp.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,cAAc;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,CAiC7E"}
|
package/dist/sdp.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// SDP mangling helpers. Mirrors `setAudioParameters` in Convbased-Web — we
|
|
2
|
+
// rewrite the Opus `a=fmtp:` line so the offer requests our target bitrate,
|
|
3
|
+
// stereo mode, and inband FEC. The signaling node passes the SDP through to
|
|
4
|
+
// aiortc largely unchanged, so changes here directly shape the negotiated
|
|
5
|
+
// audio.
|
|
6
|
+
export function applyOpusSdpOptions(sdp, opts) {
|
|
7
|
+
const lines = sdp.split("\r\n");
|
|
8
|
+
let payloadType = null;
|
|
9
|
+
for (const line of lines) {
|
|
10
|
+
const match = line.match(/a=rtpmap:(\d+) opus\/48000\/2/);
|
|
11
|
+
if (match) {
|
|
12
|
+
payloadType = match[1];
|
|
13
|
+
break;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
if (!payloadType)
|
|
17
|
+
return sdp;
|
|
18
|
+
let fmtpIndex = lines.findIndex((line) => line.startsWith(`a=fmtp:${payloadType}`));
|
|
19
|
+
if (fmtpIndex === -1) {
|
|
20
|
+
lines.push(`a=fmtp:${payloadType}`);
|
|
21
|
+
fmtpIndex = lines.length - 1;
|
|
22
|
+
}
|
|
23
|
+
let fmtp = lines[fmtpIndex];
|
|
24
|
+
fmtp = fmtp.replace(/;\s*stereo=\d/, "");
|
|
25
|
+
fmtp = fmtp.replace(/;\s*maxaveragebitrate=\d+/, "");
|
|
26
|
+
if (opts.stereo)
|
|
27
|
+
fmtp += "; stereo=1";
|
|
28
|
+
fmtp += `; maxaveragebitrate=${opts.bitrateKbps * 1000}`;
|
|
29
|
+
if (!fmtp.includes("useinbandfec=1"))
|
|
30
|
+
fmtp += "; useinbandfec=1";
|
|
31
|
+
lines[fmtpIndex] = fmtp;
|
|
32
|
+
return lines.join("\r\n");
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=sdp.js.map
|
package/dist/sdp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdp.js","sourceRoot":"","sources":["../src/sdp.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,4EAA4E;AAC5E,4EAA4E;AAC5E,0EAA0E;AAC1E,SAAS;AAOT,MAAM,UAAU,mBAAmB,CAAC,GAAW,EAAE,IAAoB;IACpE,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAChC,IAAI,WAAW,GAAkB,IAAI,CAAC;IAEtC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAC1D,IAAI,KAAK,EAAE,CAAC;YACX,WAAW,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;YACxB,MAAM;QACP,CAAC;IACF,CAAC;IAED,IAAI,CAAC,WAAW;QAAE,OAAO,GAAG,CAAC;IAE7B,IAAI,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CACxC,IAAI,CAAC,UAAU,CAAC,UAAU,WAAW,EAAE,CAAC,CACxC,CAAC;IAEF,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,UAAU,WAAW,EAAE,CAAC,CAAC;QACpC,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI,IAAI,GAAG,KAAK,CAAC,SAAS,CAAE,CAAC;IAC7B,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IACzC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;IAErD,IAAI,IAAI,CAAC,MAAM;QAAE,IAAI,IAAI,YAAY,CAAC;IACtC,IAAI,IAAI,uBAAuB,IAAI,CAAC,WAAW,GAAG,IAAI,EAAE,CAAC;IACzD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAAE,IAAI,IAAI,kBAAkB,CAAC;IAEjE,KAAK,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;IACxB,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { IncomingMessage, OutgoingMessage } from "./types.js";
|
|
2
|
+
export interface SignalingChannelOptions {
|
|
3
|
+
signalingUrl: string;
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
accessToken?: string;
|
|
6
|
+
connectTimeoutMs: number;
|
|
7
|
+
logger: Pick<Console, "debug" | "info" | "warn" | "error">;
|
|
8
|
+
}
|
|
9
|
+
export interface SignalingHandlers {
|
|
10
|
+
onMessage: (msg: IncomingMessage) => void;
|
|
11
|
+
onClose: (event: CloseEvent) => void;
|
|
12
|
+
onError: (event: Event) => void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Thin WebSocket wrapper for the Convbased signaling endpoint. Builds the URL
|
|
16
|
+
* (`${base}/signaling/ws?api_key=…`), waits for `open`, and exposes JSON
|
|
17
|
+
* send/recv plus a 10s keepalive ping to match the server's expectations.
|
|
18
|
+
*/
|
|
19
|
+
export declare class SignalingChannel {
|
|
20
|
+
private readonly opts;
|
|
21
|
+
private ws;
|
|
22
|
+
private pingTimer;
|
|
23
|
+
private handlers;
|
|
24
|
+
constructor(opts: SignalingChannelOptions);
|
|
25
|
+
get isOpen(): boolean;
|
|
26
|
+
connect(handlers: SignalingHandlers): Promise<void>;
|
|
27
|
+
send(msg: OutgoingMessage): void;
|
|
28
|
+
close(code?: number, reason?: string): void;
|
|
29
|
+
private handleMessage;
|
|
30
|
+
private handleClose;
|
|
31
|
+
private buildUrl;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=signaling.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signaling.d.ts","sourceRoot":"","sources":["../src/signaling.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEnE,MAAM,WAAW,uBAAuB;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,iBAAiB;IACjC,SAAS,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,IAAI,CAAC;IAC1C,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACrC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAChC;AAED;;;;GAIG;AACH,qBAAa,gBAAgB;IAKhB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAJjC,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,SAAS,CAA+C;IAChE,OAAO,CAAC,QAAQ,CAAkC;gBAErB,IAAI,EAAE,uBAAuB;IAE1D,IAAI,MAAM,IAAI,OAAO,CAEpB;IAEK,OAAO,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAiEzD,IAAI,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IAOhC,KAAK,CAAC,IAAI,SAAO,EAAE,MAAM,SAAiB,GAAG,IAAI;IAejD,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,QAAQ;CAwBhB"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin WebSocket wrapper for the Convbased signaling endpoint. Builds the URL
|
|
3
|
+
* (`${base}/signaling/ws?api_key=…`), waits for `open`, and exposes JSON
|
|
4
|
+
* send/recv plus a 10s keepalive ping to match the server's expectations.
|
|
5
|
+
*/
|
|
6
|
+
export class SignalingChannel {
|
|
7
|
+
constructor(opts) {
|
|
8
|
+
this.opts = opts;
|
|
9
|
+
this.ws = null;
|
|
10
|
+
this.pingTimer = null;
|
|
11
|
+
this.handlers = null;
|
|
12
|
+
}
|
|
13
|
+
get isOpen() {
|
|
14
|
+
return this.ws?.readyState === WebSocket.OPEN;
|
|
15
|
+
}
|
|
16
|
+
async connect(handlers) {
|
|
17
|
+
if (this.ws) {
|
|
18
|
+
throw new Error("SignalingChannel is already connected");
|
|
19
|
+
}
|
|
20
|
+
this.handlers = handlers;
|
|
21
|
+
const url = this.buildUrl();
|
|
22
|
+
this.opts.logger.debug?.("[convbased-sdk] connecting signaling:", url);
|
|
23
|
+
const ws = new WebSocket(url);
|
|
24
|
+
this.ws = ws;
|
|
25
|
+
await new Promise((resolve, reject) => {
|
|
26
|
+
const timeout = setTimeout(() => {
|
|
27
|
+
cleanup();
|
|
28
|
+
try {
|
|
29
|
+
ws.close();
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
/* ignore */
|
|
33
|
+
}
|
|
34
|
+
reject(new Error("Signaling WebSocket connect timeout"));
|
|
35
|
+
}, this.opts.connectTimeoutMs);
|
|
36
|
+
const onOpen = () => {
|
|
37
|
+
cleanup();
|
|
38
|
+
resolve();
|
|
39
|
+
};
|
|
40
|
+
const onError = (e) => {
|
|
41
|
+
cleanup();
|
|
42
|
+
reject(new Error(`Signaling WebSocket failed to open: ${describeEvent(e)}`));
|
|
43
|
+
};
|
|
44
|
+
const onClose = (e) => {
|
|
45
|
+
cleanup();
|
|
46
|
+
reject(new Error(`Signaling WebSocket closed before open (code=${e.code}, reason=${e.reason || "?"})`));
|
|
47
|
+
};
|
|
48
|
+
const cleanup = () => {
|
|
49
|
+
clearTimeout(timeout);
|
|
50
|
+
ws.removeEventListener("open", onOpen);
|
|
51
|
+
ws.removeEventListener("error", onError);
|
|
52
|
+
ws.removeEventListener("close", onClose);
|
|
53
|
+
};
|
|
54
|
+
ws.addEventListener("open", onOpen);
|
|
55
|
+
ws.addEventListener("error", onError);
|
|
56
|
+
ws.addEventListener("close", onClose);
|
|
57
|
+
});
|
|
58
|
+
ws.addEventListener("message", (e) => this.handleMessage(e));
|
|
59
|
+
ws.addEventListener("close", (e) => this.handleClose(e));
|
|
60
|
+
ws.addEventListener("error", (e) => this.handlers?.onError(e));
|
|
61
|
+
// The signaling server pings every 10s and expects us to keep the
|
|
62
|
+
// socket warm. We mirror that cadence rather than relying on TCP
|
|
63
|
+
// keepalive, which most browsers don't expose.
|
|
64
|
+
this.pingTimer = setInterval(() => {
|
|
65
|
+
if (this.isOpen)
|
|
66
|
+
this.send({ type: "ping" });
|
|
67
|
+
}, 10000);
|
|
68
|
+
}
|
|
69
|
+
send(msg) {
|
|
70
|
+
if (!this.isOpen) {
|
|
71
|
+
throw new Error("Signaling WebSocket is not open");
|
|
72
|
+
}
|
|
73
|
+
this.ws.send(JSON.stringify(msg));
|
|
74
|
+
}
|
|
75
|
+
close(code = 1000, reason = "client close") {
|
|
76
|
+
if (this.pingTimer) {
|
|
77
|
+
clearInterval(this.pingTimer);
|
|
78
|
+
this.pingTimer = null;
|
|
79
|
+
}
|
|
80
|
+
if (this.ws && this.ws.readyState <= WebSocket.OPEN) {
|
|
81
|
+
try {
|
|
82
|
+
this.ws.close(code, reason);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
/* ignore */
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
this.ws = null;
|
|
89
|
+
}
|
|
90
|
+
handleMessage(event) {
|
|
91
|
+
if (typeof event.data !== "string")
|
|
92
|
+
return;
|
|
93
|
+
let parsed;
|
|
94
|
+
try {
|
|
95
|
+
parsed = JSON.parse(event.data);
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
this.opts.logger.warn?.("[convbased-sdk] dropping non-JSON signaling frame:", event.data);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
this.handlers?.onMessage(parsed);
|
|
102
|
+
}
|
|
103
|
+
handleClose(event) {
|
|
104
|
+
if (this.pingTimer) {
|
|
105
|
+
clearInterval(this.pingTimer);
|
|
106
|
+
this.pingTimer = null;
|
|
107
|
+
}
|
|
108
|
+
this.handlers?.onClose(event);
|
|
109
|
+
}
|
|
110
|
+
buildUrl() {
|
|
111
|
+
// `signalingUrl` may be:
|
|
112
|
+
// - the full final URL ending in `/ws` (production default — used as-is)
|
|
113
|
+
// - a bare host (e.g. `ws://localhost:3010`) — we append `/signaling/ws`
|
|
114
|
+
// - something already containing `/signaling` — we append `/ws`
|
|
115
|
+
let base = this.opts.signalingUrl.trim();
|
|
116
|
+
if (base.endsWith("/"))
|
|
117
|
+
base = base.slice(0, -1);
|
|
118
|
+
let finalUrl;
|
|
119
|
+
if (/\/ws$/i.test(base)) {
|
|
120
|
+
finalUrl = base;
|
|
121
|
+
}
|
|
122
|
+
else if (/\/signaling$/i.test(base)) {
|
|
123
|
+
finalUrl = `${base}/ws`;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
finalUrl = `${base}/signaling/ws`;
|
|
127
|
+
}
|
|
128
|
+
const url = new URL(finalUrl);
|
|
129
|
+
if (this.opts.apiKey)
|
|
130
|
+
url.searchParams.set("api_key", this.opts.apiKey);
|
|
131
|
+
if (this.opts.accessToken && !this.opts.apiKey) {
|
|
132
|
+
url.searchParams.set("token", this.opts.accessToken);
|
|
133
|
+
}
|
|
134
|
+
return url.toString();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function describeEvent(e) {
|
|
138
|
+
if (e instanceof ErrorEvent && e.message)
|
|
139
|
+
return e.message;
|
|
140
|
+
return e.type || "unknown error";
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=signaling.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signaling.js","sourceRoot":"","sources":["../src/signaling.ts"],"names":[],"mappings":"AAgBA;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IAK5B,YAA6B,IAA6B;QAA7B,SAAI,GAAJ,IAAI,CAAyB;QAJlD,OAAE,GAAqB,IAAI,CAAC;QAC5B,cAAS,GAA0C,IAAI,CAAC;QACxD,aAAQ,GAA6B,IAAI,CAAC;IAEW,CAAC;IAE9D,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,EAAE,EAAE,UAAU,KAAK,SAAS,CAAC,IAAI,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,QAA2B;QACxC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAEzB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,uCAAuC,EAAE,GAAG,CAAC,CAAC;QACvE,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QAEb,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC/B,OAAO,EAAE,CAAC;gBACV,IAAI,CAAC;oBACJ,EAAE,CAAC,KAAK,EAAE,CAAC;gBACZ,CAAC;gBAAC,MAAM,CAAC;oBACR,YAAY;gBACb,CAAC;gBACD,MAAM,CAAC,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC,CAAC;YAC1D,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAE/B,MAAM,MAAM,GAAG,GAAG,EAAE;gBACnB,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,CAAC;YACX,CAAC,CAAC;YACF,MAAM,OAAO,GAAG,CAAC,CAAQ,EAAE,EAAE;gBAC5B,OAAO,EAAE,CAAC;gBACV,MAAM,CACL,IAAI,KAAK,CACR,uCAAuC,aAAa,CAAC,CAAC,CAAC,EAAE,CACzD,CACD,CAAC;YACH,CAAC,CAAC;YACF,MAAM,OAAO,GAAG,CAAC,CAAa,EAAE,EAAE;gBACjC,OAAO,EAAE,CAAC;gBACV,MAAM,CACL,IAAI,KAAK,CACR,gDAAgD,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,MAAM,IAAI,GAAG,GAAG,CACpF,CACD,CAAC;YACH,CAAC,CAAC;YACF,MAAM,OAAO,GAAG,GAAG,EAAE;gBACpB,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,EAAE,CAAC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBACvC,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBACzC,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC1C,CAAC,CAAC;YACF,EAAE,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACpC,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACtC,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7D,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAE/D,kEAAkE;QAClE,iEAAiE;QACjE,+CAA+C;QAC/C,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;YACjC,IAAI,IAAI,CAAC,MAAM;gBAAE,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9C,CAAC,EAAE,KAAM,CAAC,CAAC;IACZ,CAAC;IAED,IAAI,CAAC,GAAoB;QACxB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,CAAC,EAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,IAAI,GAAG,IAAI,EAAE,MAAM,GAAG,cAAc;QACzC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACvB,CAAC;QACD,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC;YACrD,IAAI,CAAC;gBACJ,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC7B,CAAC;YAAC,MAAM,CAAC;gBACR,YAAY;YACb,CAAC;QACF,CAAC;QACD,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;IAChB,CAAC;IAEO,aAAa,CAAC,KAAmB;QACxC,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO;QAC3C,IAAI,MAAuB,CAAC;QAC5B,IAAI,CAAC;YACJ,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAoB,CAAC;QACpD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACZ,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CACtB,oDAAoD,EACpD,KAAK,CAAC,IAAI,CACV,CAAC;YACF,OAAO;QACR,CAAC;QACD,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAEO,WAAW,CAAC,KAAiB;QACpC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAEO,QAAQ;QACf,yBAAyB;QACzB,2EAA2E;QAC3E,2EAA2E;QAC3E,kEAAkE;QAClE,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAEjD,IAAI,QAAgB,CAAC;QACrB,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,QAAQ,GAAG,IAAI,CAAC;QACjB,CAAC;aAAM,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,QAAQ,GAAG,GAAG,IAAI,KAAK,CAAC;QACzB,CAAC;aAAM,CAAC;YACP,QAAQ,GAAG,GAAG,IAAI,eAAe,CAAC;QACnC,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxE,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAChD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;IACvB,CAAC;CACD;AAED,SAAS,aAAa,CAAC,CAAQ;IAC9B,IAAI,CAAC,YAAY,UAAU,IAAI,CAAC,CAAC,OAAO;QAAE,OAAO,CAAC,CAAC,OAAO,CAAC;IAC3D,OAAO,CAAC,CAAC,IAAI,IAAI,eAAe,CAAC;AAClC,CAAC"}
|
package/dist/tts.d.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/** Optional emotion / sampling controls forwarded verbatim to IndexTTS2. */
|
|
2
|
+
export interface TtsParams {
|
|
3
|
+
emo_alpha?: number;
|
|
4
|
+
emo_vector?: number[];
|
|
5
|
+
use_emo_text?: boolean;
|
|
6
|
+
emo_text?: string;
|
|
7
|
+
temperature?: number;
|
|
8
|
+
top_p?: number;
|
|
9
|
+
top_k?: number;
|
|
10
|
+
}
|
|
11
|
+
export type TtsJobStatus = "queued" | "warming" | "processing" | "done" | "failed" | "cancelled";
|
|
12
|
+
export interface TtsResult {
|
|
13
|
+
/** COS key of the synthesized audio. */
|
|
14
|
+
key: string;
|
|
15
|
+
/** Presigned URL of the synthesized audio (valid ~1h), or null if unsigned. */
|
|
16
|
+
url: string | null;
|
|
17
|
+
/** Input-text token count the charge was based on. */
|
|
18
|
+
tokenCount: number;
|
|
19
|
+
/** Duration of the synthesized audio, in seconds. */
|
|
20
|
+
audioDurationSec: number;
|
|
21
|
+
/** Amount deducted from the wallet for this synthesis. */
|
|
22
|
+
amountCharged: number;
|
|
23
|
+
/** Wallet balance after the deduction. */
|
|
24
|
+
balanceAfter: number;
|
|
25
|
+
}
|
|
26
|
+
export interface TtsJob {
|
|
27
|
+
jobId: string;
|
|
28
|
+
status: TtsJobStatus;
|
|
29
|
+
/** 1-based queue position while `queued`; 0 otherwise. */
|
|
30
|
+
position: number;
|
|
31
|
+
/** Result, populated once `status === "done"`. */
|
|
32
|
+
result: TtsResult | null;
|
|
33
|
+
/** Server-reported error key when `status === "failed"`. */
|
|
34
|
+
error: string | null;
|
|
35
|
+
}
|
|
36
|
+
export interface TtsPricing {
|
|
37
|
+
/** Price charged per input-text token. */
|
|
38
|
+
pricePerToken: number;
|
|
39
|
+
/** Minimum charge applied to any single synthesis. */
|
|
40
|
+
minCharge: number;
|
|
41
|
+
}
|
|
42
|
+
export interface TtsClientOptions {
|
|
43
|
+
/** Convbased API key. Required unless `accessToken` is provided. */
|
|
44
|
+
apiKey?: string;
|
|
45
|
+
/** Short-lived JWT access token (alternative to `apiKey`). */
|
|
46
|
+
accessToken?: string;
|
|
47
|
+
/**
|
|
48
|
+
* GraphQL endpoint. Defaults to the production Convbased endpoint
|
|
49
|
+
* (`https://api.weights.chat/api/v1/graphql`). Override for self-hosted
|
|
50
|
+
* deployments.
|
|
51
|
+
*/
|
|
52
|
+
graphqlUrl?: string;
|
|
53
|
+
/** Optional logger; defaults to `console` for warn/error only. */
|
|
54
|
+
logger?: Partial<Pick<Console, "debug" | "info" | "warn" | "error">>;
|
|
55
|
+
}
|
|
56
|
+
export interface SubmitTtsOptions {
|
|
57
|
+
/** COS key of an already-uploaded reference voice (see `uploadReferenceAudio`). */
|
|
58
|
+
referenceKey: string;
|
|
59
|
+
/** Text to synthesize. */
|
|
60
|
+
text: string;
|
|
61
|
+
/** Optional emotion / sampling controls. */
|
|
62
|
+
params?: TtsParams;
|
|
63
|
+
}
|
|
64
|
+
export interface SynthesizeOptions {
|
|
65
|
+
/** COS key of an already-uploaded reference voice. Provide this or `referenceAudio`. */
|
|
66
|
+
referenceKey?: string;
|
|
67
|
+
/** A reference-voice `Blob`/`File` to upload first. Provide this or `referenceKey`. */
|
|
68
|
+
referenceAudio?: Blob;
|
|
69
|
+
/** Text to synthesize. */
|
|
70
|
+
text: string;
|
|
71
|
+
/** Optional emotion / sampling controls. */
|
|
72
|
+
params?: TtsParams;
|
|
73
|
+
/** Poll interval while waiting for the job, in ms. Default 1500. */
|
|
74
|
+
pollIntervalMs?: number;
|
|
75
|
+
/** Give up waiting after this many ms. Default 300_000 (5 min). */
|
|
76
|
+
timeoutMs?: number;
|
|
77
|
+
/** Abort the wait (and cancel the job if still queued). */
|
|
78
|
+
signal?: AbortSignal;
|
|
79
|
+
/** Called on every poll with the latest job snapshot (queue position, status…). */
|
|
80
|
+
onJob?: (job: TtsJob) => void;
|
|
81
|
+
}
|
|
82
|
+
export declare class TtsClient {
|
|
83
|
+
private readonly graphqlUrl;
|
|
84
|
+
private readonly apiKey?;
|
|
85
|
+
private readonly accessToken?;
|
|
86
|
+
private readonly logger;
|
|
87
|
+
constructor(options: TtsClientOptions);
|
|
88
|
+
/** Upload a reference-voice `Blob`/`File` and resolve its COS key. */
|
|
89
|
+
uploadReferenceAudio(file: Blob, opts?: {
|
|
90
|
+
filename?: string;
|
|
91
|
+
contentType?: string;
|
|
92
|
+
signal?: AbortSignal;
|
|
93
|
+
}): Promise<{
|
|
94
|
+
key: string;
|
|
95
|
+
}>;
|
|
96
|
+
/** Current billing rule: `cost = max(tokens * pricePerToken, minCharge)`. */
|
|
97
|
+
getPricing(signal?: AbortSignal): Promise<TtsPricing>;
|
|
98
|
+
/** Enqueue a synthesis job; resolves immediately with the queued job. */
|
|
99
|
+
submit(opts: SubmitTtsOptions, signal?: AbortSignal): Promise<TtsJob>;
|
|
100
|
+
/** Read the current status/result of a job. */
|
|
101
|
+
getJob(jobId: string, signal?: AbortSignal): Promise<TtsJob>;
|
|
102
|
+
/** Cancel a job. Only effective while it is still `queued`. */
|
|
103
|
+
cancel(jobId: string, signal?: AbortSignal): Promise<TtsJob>;
|
|
104
|
+
/**
|
|
105
|
+
* One-call synthesis: (optionally upload the reference voice,) submit, then
|
|
106
|
+
* poll until the job finishes. Resolves with the `TtsResult` on success;
|
|
107
|
+
* rejects if the job fails/cancels, times out, or `signal` aborts.
|
|
108
|
+
*/
|
|
109
|
+
synthesize(opts: SynthesizeOptions): Promise<TtsResult>;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=tts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tts.d.ts","sourceRoot":"","sources":["../src/tts.ts"],"names":[],"mappings":"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"}
|