@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.
Files changed (82) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +235 -0
  3. package/dist/cjs/client.js +635 -0
  4. package/dist/cjs/client.js.map +1 -0
  5. package/dist/cjs/endpoints.js +10 -0
  6. package/dist/cjs/endpoints.js.map +1 -0
  7. package/dist/cjs/events.js +39 -0
  8. package/dist/cjs/events.js.map +1 -0
  9. package/dist/cjs/graphql.js +40 -0
  10. package/dist/cjs/graphql.js.map +1 -0
  11. package/dist/cjs/index.js +24 -0
  12. package/dist/cjs/index.js.map +1 -0
  13. package/dist/cjs/package.json +3 -0
  14. package/dist/cjs/rtcServers.js +35 -0
  15. package/dist/cjs/rtcServers.js.map +1 -0
  16. package/dist/cjs/sdp.js +37 -0
  17. package/dist/cjs/sdp.js.map +1 -0
  18. package/dist/cjs/signaling.js +146 -0
  19. package/dist/cjs/signaling.js.map +1 -0
  20. package/dist/cjs/tts.js +227 -0
  21. package/dist/cjs/tts.js.map +1 -0
  22. package/dist/cjs/types.js +26 -0
  23. package/dist/cjs/types.js.map +1 -0
  24. package/dist/cjs/upload.js +87 -0
  25. package/dist/cjs/upload.js.map +1 -0
  26. package/dist/client.d.ts +169 -0
  27. package/dist/client.d.ts.map +1 -0
  28. package/dist/client.js +631 -0
  29. package/dist/client.js.map +1 -0
  30. package/dist/convbased-sdk.global.js +1291 -0
  31. package/dist/endpoints.d.ts +3 -0
  32. package/dist/endpoints.d.ts.map +1 -0
  33. package/dist/endpoints.js +7 -0
  34. package/dist/endpoints.js.map +1 -0
  35. package/dist/events.d.ts +9 -0
  36. package/dist/events.d.ts.map +1 -0
  37. package/dist/events.js +35 -0
  38. package/dist/events.js.map +1 -0
  39. package/dist/graphql.d.ts +18 -0
  40. package/dist/graphql.d.ts.map +1 -0
  41. package/dist/graphql.js +37 -0
  42. package/dist/graphql.js.map +1 -0
  43. package/dist/index.d.ts +9 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +9 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/rtcServers.d.ts +13 -0
  48. package/dist/rtcServers.d.ts.map +1 -0
  49. package/dist/rtcServers.js +31 -0
  50. package/dist/rtcServers.js.map +1 -0
  51. package/dist/sdp.d.ts +6 -0
  52. package/dist/sdp.d.ts.map +1 -0
  53. package/dist/sdp.js +34 -0
  54. package/dist/sdp.js.map +1 -0
  55. package/dist/signaling.d.ts +33 -0
  56. package/dist/signaling.d.ts.map +1 -0
  57. package/dist/signaling.js +142 -0
  58. package/dist/signaling.js.map +1 -0
  59. package/dist/tts.d.ts +111 -0
  60. package/dist/tts.d.ts.map +1 -0
  61. package/dist/tts.js +223 -0
  62. package/dist/tts.js.map +1 -0
  63. package/dist/types.d.ts +194 -0
  64. package/dist/types.d.ts.map +1 -0
  65. package/dist/types.js +23 -0
  66. package/dist/types.js.map +1 -0
  67. package/dist/upload.d.ts +46 -0
  68. package/dist/upload.d.ts.map +1 -0
  69. package/dist/upload.js +82 -0
  70. package/dist/upload.js.map +1 -0
  71. package/package.json +57 -0
  72. package/src/client.ts +839 -0
  73. package/src/endpoints.ts +8 -0
  74. package/src/events.ts +38 -0
  75. package/src/graphql.ts +58 -0
  76. package/src/index.ts +50 -0
  77. package/src/rtcServers.ts +38 -0
  78. package/src/sdp.ts +45 -0
  79. package/src/signaling.ts +172 -0
  80. package/src/tts.ts +364 -0
  81. package/src/types.ts +201 -0
  82. package/src/upload.ts +132 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../../src/endpoints.ts"],"names":[],"mappings":";;;AAAA,wEAAwE;AACxE,4EAA4E;AAC5E,sEAAsE;AACtE,gDAAgD;AACnC,QAAA,qBAAqB,GACjC,yCAAyC,CAAC;AAC9B,QAAA,mBAAmB,GAC/B,yCAAyC,CAAC"}
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ // Minimal typed event emitter; we avoid pulling Node's EventEmitter so the
3
+ // SDK stays browser-first with no polyfill chain.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.TypedEmitter = void 0;
6
+ class TypedEmitter {
7
+ constructor() {
8
+ this.listeners = {};
9
+ }
10
+ on(event, fn) {
11
+ var _a;
12
+ ((_a = this.listeners)[event] ?? (_a[event] = new Set())).add(fn);
13
+ return () => this.off(event, fn);
14
+ }
15
+ off(event, fn) {
16
+ this.listeners[event]?.delete(fn);
17
+ }
18
+ emit(event, payload) {
19
+ const set = this.listeners[event];
20
+ if (!set)
21
+ return;
22
+ for (const fn of set) {
23
+ try {
24
+ fn(payload);
25
+ }
26
+ catch (e) {
27
+ // Listeners shouldn't crash the emitter.
28
+ console.error(`[convbased-sdk] listener for "${String(event)}" threw:`, e);
29
+ }
30
+ }
31
+ }
32
+ removeAllListeners() {
33
+ for (const key of Object.keys(this.listeners)) {
34
+ delete this.listeners[key];
35
+ }
36
+ }
37
+ }
38
+ exports.TypedEmitter = TypedEmitter;
39
+ //# 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,MAAa,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;AAhCD,oCAgCC"}
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ // Shared GraphQL transport for the Convbased service. Authentication mirrors
3
+ // the server middleware: `x-api-key: <key>` for API keys, or
4
+ // `Authorization: Bearer <jwt>` for access tokens.
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.graphqlRequest = graphqlRequest;
7
+ /**
8
+ * Issue a single GraphQL operation and return `data`. Throws on HTTP failure
9
+ * or when the response carries a non-empty `errors` array — the thrown
10
+ * `Error.message` is the first server-reported message (often an i18n key the
11
+ * caller can localize).
12
+ */
13
+ async function graphqlRequest(args) {
14
+ const headers = {
15
+ "content-type": "application/json",
16
+ };
17
+ if (args.apiKey)
18
+ headers["x-api-key"] = args.apiKey;
19
+ else if (args.accessToken) {
20
+ headers["authorization"] = `Bearer ${args.accessToken}`;
21
+ }
22
+ const res = await fetch(args.graphqlUrl, {
23
+ method: "POST",
24
+ headers,
25
+ body: JSON.stringify({ query: args.query, variables: args.variables }),
26
+ signal: args.signal,
27
+ });
28
+ if (!res.ok) {
29
+ throw new Error(`GraphQL request failed: HTTP ${res.status} ${res.statusText}`);
30
+ }
31
+ const json = (await res.json());
32
+ if (json.errors?.length) {
33
+ throw new Error(json.errors.map((e) => e.message).join("; "));
34
+ }
35
+ if (json.data === undefined || json.data === null) {
36
+ throw new Error("GraphQL response contained no data");
37
+ }
38
+ return json.data;
39
+ }
40
+ //# 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;;AAoBnD,wCAmCC;AAzCD;;;;;GAKG;AACI,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"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RTCStatusCode = exports.DEFAULT_GRAPHQL_URL = exports.DEFAULT_SIGNALING_URL = exports.DEFAULT_STUN_SERVERS = exports.fetchRTCServers = exports.applyOpusSdpOptions = exports.graphqlRequest = exports.putToPresigned = exports.requestAudioUpload = exports.uploadAudio = exports.TtsClient = exports.ConvbasedClient = void 0;
4
+ var client_js_1 = require("./client.js");
5
+ Object.defineProperty(exports, "ConvbasedClient", { enumerable: true, get: function () { return client_js_1.ConvbasedClient; } });
6
+ var tts_js_1 = require("./tts.js");
7
+ Object.defineProperty(exports, "TtsClient", { enumerable: true, get: function () { return tts_js_1.TtsClient; } });
8
+ var upload_js_1 = require("./upload.js");
9
+ Object.defineProperty(exports, "uploadAudio", { enumerable: true, get: function () { return upload_js_1.uploadAudio; } });
10
+ Object.defineProperty(exports, "requestAudioUpload", { enumerable: true, get: function () { return upload_js_1.requestAudioUpload; } });
11
+ Object.defineProperty(exports, "putToPresigned", { enumerable: true, get: function () { return upload_js_1.putToPresigned; } });
12
+ var graphql_js_1 = require("./graphql.js");
13
+ Object.defineProperty(exports, "graphqlRequest", { enumerable: true, get: function () { return graphql_js_1.graphqlRequest; } });
14
+ var sdp_js_1 = require("./sdp.js");
15
+ Object.defineProperty(exports, "applyOpusSdpOptions", { enumerable: true, get: function () { return sdp_js_1.applyOpusSdpOptions; } });
16
+ var rtcServers_js_1 = require("./rtcServers.js");
17
+ Object.defineProperty(exports, "fetchRTCServers", { enumerable: true, get: function () { return rtcServers_js_1.fetchRTCServers; } });
18
+ Object.defineProperty(exports, "DEFAULT_STUN_SERVERS", { enumerable: true, get: function () { return rtcServers_js_1.DEFAULT_STUN_SERVERS; } });
19
+ var endpoints_js_1 = require("./endpoints.js");
20
+ Object.defineProperty(exports, "DEFAULT_SIGNALING_URL", { enumerable: true, get: function () { return endpoints_js_1.DEFAULT_SIGNALING_URL; } });
21
+ Object.defineProperty(exports, "DEFAULT_GRAPHQL_URL", { enumerable: true, get: function () { return endpoints_js_1.DEFAULT_GRAPHQL_URL; } });
22
+ var types_js_1 = require("./types.js");
23
+ Object.defineProperty(exports, "RTCStatusCode", { enumerable: true, get: function () { return types_js_1.RTCStatusCode; } });
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,yCAOqB;AANpB,4GAAA,eAAe,OAAA;AAOhB,mCAUkB;AATjB,mGAAA,SAAS,OAAA;AAUV,yCAMqB;AALpB,wGAAA,WAAW,OAAA;AACX,+GAAA,kBAAkB,OAAA;AAClB,2GAAA,cAAc,OAAA;AAIf,2CAAgE;AAAvD,4GAAA,cAAc,OAAA;AACvB,mCAA+C;AAAtC,6GAAA,mBAAmB,OAAA;AAC5B,iDAGyB;AAFxB,gHAAA,eAAe,OAAA;AACf,qHAAA,oBAAoB,OAAA;AAErB,+CAGwB;AAFvB,qHAAA,qBAAqB,OAAA;AACrB,mHAAA,mBAAmB,OAAA;AAEpB,uCAaoB;AAZnB,yGAAA,aAAa,OAAA"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_STUN_SERVERS = void 0;
4
+ exports.fetchRTCServers = fetchRTCServers;
5
+ const graphql_js_1 = require("./graphql.js");
6
+ /**
7
+ * Fetch TURN credentials from the Convbased GraphQL service. The query matches
8
+ * the one used by Convbased-Web's `getRTCServers`. Authentication uses the
9
+ * same API key / access token passed to the SDK.
10
+ */
11
+ async function fetchRTCServers(args) {
12
+ const data = await (0, graphql_js_1.graphqlRequest)({
13
+ graphqlUrl: args.graphqlUrl,
14
+ apiKey: args.apiKey,
15
+ accessToken: args.accessToken,
16
+ signal: args.signal,
17
+ query: /* GraphQL */ `
18
+ query {
19
+ rtcServers {
20
+ urls
21
+ username
22
+ credential
23
+ }
24
+ }
25
+ `,
26
+ });
27
+ if (!data.rtcServers) {
28
+ throw new Error("rtcServers returned an empty payload");
29
+ }
30
+ return data.rtcServers;
31
+ }
32
+ exports.DEFAULT_STUN_SERVERS = [
33
+ { urls: ["stun:stun.l.google.com:19302"] },
34
+ ];
35
+ //# sourceMappingURL=rtcServers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rtcServers.js","sourceRoot":"","sources":["../../src/rtcServers.ts"],"names":[],"mappings":";;;AAQA,0CAyBC;AAjCD,6CAAgE;AAGhE;;;;GAIG;AACI,KAAK,UAAU,eAAe,CACpC,IAGC;IAED,MAAM,IAAI,GAAG,MAAM,IAAA,2BAAc,EAAoC;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;AAEY,QAAA,oBAAoB,GAAuB;IACvD,EAAE,IAAI,EAAE,CAAC,8BAA8B,CAAC,EAAE;CAC1C,CAAC"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ // SDP mangling helpers. Mirrors `setAudioParameters` in Convbased-Web — we
3
+ // rewrite the Opus `a=fmtp:` line so the offer requests our target bitrate,
4
+ // stereo mode, and inband FEC. The signaling node passes the SDP through to
5
+ // aiortc largely unchanged, so changes here directly shape the negotiated
6
+ // audio.
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.applyOpusSdpOptions = applyOpusSdpOptions;
9
+ function applyOpusSdpOptions(sdp, opts) {
10
+ const lines = sdp.split("\r\n");
11
+ let payloadType = null;
12
+ for (const line of lines) {
13
+ const match = line.match(/a=rtpmap:(\d+) opus\/48000\/2/);
14
+ if (match) {
15
+ payloadType = match[1];
16
+ break;
17
+ }
18
+ }
19
+ if (!payloadType)
20
+ return sdp;
21
+ let fmtpIndex = lines.findIndex((line) => line.startsWith(`a=fmtp:${payloadType}`));
22
+ if (fmtpIndex === -1) {
23
+ lines.push(`a=fmtp:${payloadType}`);
24
+ fmtpIndex = lines.length - 1;
25
+ }
26
+ let fmtp = lines[fmtpIndex];
27
+ fmtp = fmtp.replace(/;\s*stereo=\d/, "");
28
+ fmtp = fmtp.replace(/;\s*maxaveragebitrate=\d+/, "");
29
+ if (opts.stereo)
30
+ fmtp += "; stereo=1";
31
+ fmtp += `; maxaveragebitrate=${opts.bitrateKbps * 1000}`;
32
+ if (!fmtp.includes("useinbandfec=1"))
33
+ fmtp += "; useinbandfec=1";
34
+ lines[fmtpIndex] = fmtp;
35
+ return lines.join("\r\n");
36
+ }
37
+ //# sourceMappingURL=sdp.js.map
@@ -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,kDAiCC;AAjCD,SAAgB,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,146 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SignalingChannel = void 0;
4
+ /**
5
+ * Thin WebSocket wrapper for the Convbased signaling endpoint. Builds the URL
6
+ * (`${base}/signaling/ws?api_key=…`), waits for `open`, and exposes JSON
7
+ * send/recv plus a 10s keepalive ping to match the server's expectations.
8
+ */
9
+ class SignalingChannel {
10
+ constructor(opts) {
11
+ this.opts = opts;
12
+ this.ws = null;
13
+ this.pingTimer = null;
14
+ this.handlers = null;
15
+ }
16
+ get isOpen() {
17
+ return this.ws?.readyState === WebSocket.OPEN;
18
+ }
19
+ async connect(handlers) {
20
+ if (this.ws) {
21
+ throw new Error("SignalingChannel is already connected");
22
+ }
23
+ this.handlers = handlers;
24
+ const url = this.buildUrl();
25
+ this.opts.logger.debug?.("[convbased-sdk] connecting signaling:", url);
26
+ const ws = new WebSocket(url);
27
+ this.ws = ws;
28
+ await new Promise((resolve, reject) => {
29
+ const timeout = setTimeout(() => {
30
+ cleanup();
31
+ try {
32
+ ws.close();
33
+ }
34
+ catch {
35
+ /* ignore */
36
+ }
37
+ reject(new Error("Signaling WebSocket connect timeout"));
38
+ }, this.opts.connectTimeoutMs);
39
+ const onOpen = () => {
40
+ cleanup();
41
+ resolve();
42
+ };
43
+ const onError = (e) => {
44
+ cleanup();
45
+ reject(new Error(`Signaling WebSocket failed to open: ${describeEvent(e)}`));
46
+ };
47
+ const onClose = (e) => {
48
+ cleanup();
49
+ reject(new Error(`Signaling WebSocket closed before open (code=${e.code}, reason=${e.reason || "?"})`));
50
+ };
51
+ const cleanup = () => {
52
+ clearTimeout(timeout);
53
+ ws.removeEventListener("open", onOpen);
54
+ ws.removeEventListener("error", onError);
55
+ ws.removeEventListener("close", onClose);
56
+ };
57
+ ws.addEventListener("open", onOpen);
58
+ ws.addEventListener("error", onError);
59
+ ws.addEventListener("close", onClose);
60
+ });
61
+ ws.addEventListener("message", (e) => this.handleMessage(e));
62
+ ws.addEventListener("close", (e) => this.handleClose(e));
63
+ ws.addEventListener("error", (e) => this.handlers?.onError(e));
64
+ // The signaling server pings every 10s and expects us to keep the
65
+ // socket warm. We mirror that cadence rather than relying on TCP
66
+ // keepalive, which most browsers don't expose.
67
+ this.pingTimer = setInterval(() => {
68
+ if (this.isOpen)
69
+ this.send({ type: "ping" });
70
+ }, 10000);
71
+ }
72
+ send(msg) {
73
+ if (!this.isOpen) {
74
+ throw new Error("Signaling WebSocket is not open");
75
+ }
76
+ this.ws.send(JSON.stringify(msg));
77
+ }
78
+ close(code = 1000, reason = "client close") {
79
+ if (this.pingTimer) {
80
+ clearInterval(this.pingTimer);
81
+ this.pingTimer = null;
82
+ }
83
+ if (this.ws && this.ws.readyState <= WebSocket.OPEN) {
84
+ try {
85
+ this.ws.close(code, reason);
86
+ }
87
+ catch {
88
+ /* ignore */
89
+ }
90
+ }
91
+ this.ws = null;
92
+ }
93
+ handleMessage(event) {
94
+ if (typeof event.data !== "string")
95
+ return;
96
+ let parsed;
97
+ try {
98
+ parsed = JSON.parse(event.data);
99
+ }
100
+ catch (e) {
101
+ this.opts.logger.warn?.("[convbased-sdk] dropping non-JSON signaling frame:", event.data);
102
+ return;
103
+ }
104
+ this.handlers?.onMessage(parsed);
105
+ }
106
+ handleClose(event) {
107
+ if (this.pingTimer) {
108
+ clearInterval(this.pingTimer);
109
+ this.pingTimer = null;
110
+ }
111
+ this.handlers?.onClose(event);
112
+ }
113
+ buildUrl() {
114
+ // `signalingUrl` may be:
115
+ // - the full final URL ending in `/ws` (production default — used as-is)
116
+ // - a bare host (e.g. `ws://localhost:3010`) — we append `/signaling/ws`
117
+ // - something already containing `/signaling` — we append `/ws`
118
+ let base = this.opts.signalingUrl.trim();
119
+ if (base.endsWith("/"))
120
+ base = base.slice(0, -1);
121
+ let finalUrl;
122
+ if (/\/ws$/i.test(base)) {
123
+ finalUrl = base;
124
+ }
125
+ else if (/\/signaling$/i.test(base)) {
126
+ finalUrl = `${base}/ws`;
127
+ }
128
+ else {
129
+ finalUrl = `${base}/signaling/ws`;
130
+ }
131
+ const url = new URL(finalUrl);
132
+ if (this.opts.apiKey)
133
+ url.searchParams.set("api_key", this.opts.apiKey);
134
+ if (this.opts.accessToken && !this.opts.apiKey) {
135
+ url.searchParams.set("token", this.opts.accessToken);
136
+ }
137
+ return url.toString();
138
+ }
139
+ }
140
+ exports.SignalingChannel = SignalingChannel;
141
+ function describeEvent(e) {
142
+ if (e instanceof ErrorEvent && e.message)
143
+ return e.message;
144
+ return e.type || "unknown error";
145
+ }
146
+ //# sourceMappingURL=signaling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signaling.js","sourceRoot":"","sources":["../../src/signaling.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,227 @@
1
+ "use strict";
2
+ // Text-to-speech client for the Convbased IndexTTS2 service. This path is pure
3
+ // GraphQL — it does not touch WebRTC or the signaling socket. Synthesis is
4
+ // asynchronous: you submit a job, then poll until it reaches a terminal state.
5
+ //
6
+ // Typical flow:
7
+ // const tts = new TtsClient({ apiKey });
8
+ // const { key } = await tts.uploadReferenceAudio(file); // reference voice
9
+ // const result = await tts.synthesize({ referenceKey: key, text: "你好" });
10
+ // audio.src = result.url; // presigned, ~1h
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.TtsClient = void 0;
13
+ const endpoints_js_1 = require("./endpoints.js");
14
+ const graphql_js_1 = require("./graphql.js");
15
+ const upload_js_1 = require("./upload.js");
16
+ const JOB_FIELDS = /* GraphQL */ `
17
+ job_id
18
+ status
19
+ position
20
+ result {
21
+ key
22
+ url
23
+ token_count
24
+ audio_duration_sec
25
+ amount_charged
26
+ balance_after
27
+ }
28
+ error
29
+ `;
30
+ class TtsClient {
31
+ constructor(options) {
32
+ if (!options.apiKey && !options.accessToken) {
33
+ throw new Error("TtsClient requires either `apiKey` or `accessToken`");
34
+ }
35
+ this.graphqlUrl = options.graphqlUrl ?? endpoints_js_1.DEFAULT_GRAPHQL_URL;
36
+ this.apiKey = options.apiKey;
37
+ this.accessToken = options.accessToken;
38
+ const provided = options.logger ?? {};
39
+ this.logger = {
40
+ debug: provided.debug ?? (() => { }),
41
+ info: provided.info ?? (() => { }),
42
+ warn: provided.warn ?? console.warn.bind(console),
43
+ error: provided.error ?? console.error.bind(console),
44
+ };
45
+ }
46
+ /** Upload a reference-voice `Blob`/`File` and resolve its COS key. */
47
+ async uploadReferenceAudio(file, opts) {
48
+ return (0, upload_js_1.uploadAudio)({
49
+ graphqlUrl: this.graphqlUrl,
50
+ apiKey: this.apiKey,
51
+ accessToken: this.accessToken,
52
+ file,
53
+ filename: opts?.filename,
54
+ contentType: opts?.contentType,
55
+ signal: opts?.signal,
56
+ });
57
+ }
58
+ /** Current billing rule: `cost = max(tokens * pricePerToken, minCharge)`. */
59
+ async getPricing(signal) {
60
+ const data = await (0, graphql_js_1.graphqlRequest)({
61
+ graphqlUrl: this.graphqlUrl,
62
+ apiKey: this.apiKey,
63
+ accessToken: this.accessToken,
64
+ signal,
65
+ query: /* GraphQL */ `
66
+ query {
67
+ ttsPricing {
68
+ price_per_token
69
+ min_charge
70
+ }
71
+ }
72
+ `,
73
+ });
74
+ return {
75
+ pricePerToken: data.ttsPricing.price_per_token,
76
+ minCharge: data.ttsPricing.min_charge,
77
+ };
78
+ }
79
+ /** Enqueue a synthesis job; resolves immediately with the queued job. */
80
+ async submit(opts, signal) {
81
+ const data = await (0, graphql_js_1.graphqlRequest)({
82
+ graphqlUrl: this.graphqlUrl,
83
+ apiKey: this.apiKey,
84
+ accessToken: this.accessToken,
85
+ signal,
86
+ query: /* GraphQL */ `
87
+ mutation SubmitTts($input: SynthesizeTtsInput!) {
88
+ submitTts(input: $input) {
89
+ ${JOB_FIELDS}
90
+ }
91
+ }
92
+ `,
93
+ variables: {
94
+ input: {
95
+ reference_key: opts.referenceKey,
96
+ text: opts.text,
97
+ params: opts.params ?? null,
98
+ },
99
+ },
100
+ });
101
+ return toJob(data.submitTts);
102
+ }
103
+ /** Read the current status/result of a job. */
104
+ async getJob(jobId, signal) {
105
+ const data = await (0, graphql_js_1.graphqlRequest)({
106
+ graphqlUrl: this.graphqlUrl,
107
+ apiKey: this.apiKey,
108
+ accessToken: this.accessToken,
109
+ signal,
110
+ query: /* GraphQL */ `
111
+ query TtsJob($jobId: String!) {
112
+ ttsJob(jobId: $jobId) {
113
+ ${JOB_FIELDS}
114
+ }
115
+ }
116
+ `,
117
+ variables: { jobId },
118
+ });
119
+ return toJob(data.ttsJob);
120
+ }
121
+ /** Cancel a job. Only effective while it is still `queued`. */
122
+ async cancel(jobId, signal) {
123
+ const data = await (0, graphql_js_1.graphqlRequest)({
124
+ graphqlUrl: this.graphqlUrl,
125
+ apiKey: this.apiKey,
126
+ accessToken: this.accessToken,
127
+ signal,
128
+ query: /* GraphQL */ `
129
+ mutation CancelTtsJob($jobId: String!) {
130
+ cancelTtsJob(jobId: $jobId) {
131
+ ${JOB_FIELDS}
132
+ }
133
+ }
134
+ `,
135
+ variables: { jobId },
136
+ });
137
+ return toJob(data.cancelTtsJob);
138
+ }
139
+ /**
140
+ * One-call synthesis: (optionally upload the reference voice,) submit, then
141
+ * poll until the job finishes. Resolves with the `TtsResult` on success;
142
+ * rejects if the job fails/cancels, times out, or `signal` aborts.
143
+ */
144
+ async synthesize(opts) {
145
+ if (!opts.referenceKey && !opts.referenceAudio) {
146
+ throw new Error("synthesize() requires either `referenceKey` or `referenceAudio`");
147
+ }
148
+ const pollIntervalMs = opts.pollIntervalMs ?? 1500;
149
+ const timeoutMs = opts.timeoutMs ?? 300000;
150
+ const deadline = Date.now() + timeoutMs;
151
+ const referenceKey = opts.referenceKey ??
152
+ (await this.uploadReferenceAudio(opts.referenceAudio, {
153
+ signal: opts.signal,
154
+ })).key;
155
+ const submitted = await this.submit({ referenceKey, text: opts.text, params: opts.params }, opts.signal);
156
+ opts.onJob?.(submitted);
157
+ let job = submitted;
158
+ try {
159
+ while (job.status !== "done") {
160
+ if (opts.signal?.aborted) {
161
+ throw new DOMException("Aborted", "AbortError");
162
+ }
163
+ if (job.status === "failed") {
164
+ throw new Error(job.error || "TTS job failed");
165
+ }
166
+ if (job.status === "cancelled") {
167
+ throw new Error("TTS job was cancelled");
168
+ }
169
+ if (Date.now() > deadline) {
170
+ throw new Error(`Timed out waiting for TTS job ${job.jobId} after ${timeoutMs}ms`);
171
+ }
172
+ await delay(pollIntervalMs, opts.signal);
173
+ job = await this.getJob(job.jobId, opts.signal);
174
+ opts.onJob?.(job);
175
+ }
176
+ }
177
+ catch (err) {
178
+ // Best-effort: stop a still-queued job so we don't pay for a result
179
+ // nobody is waiting for.
180
+ if (opts.signal?.aborted) {
181
+ this.cancel(job.jobId).catch(() => { });
182
+ }
183
+ throw err;
184
+ }
185
+ if (!job.result) {
186
+ throw new Error("TTS job is done but carried no result");
187
+ }
188
+ return job.result;
189
+ }
190
+ }
191
+ exports.TtsClient = TtsClient;
192
+ function toJob(wire) {
193
+ return {
194
+ jobId: wire.job_id,
195
+ status: wire.status,
196
+ position: wire.position,
197
+ result: wire.result
198
+ ? {
199
+ key: wire.result.key,
200
+ url: wire.result.url,
201
+ tokenCount: wire.result.token_count,
202
+ audioDurationSec: wire.result.audio_duration_sec,
203
+ amountCharged: wire.result.amount_charged,
204
+ balanceAfter: wire.result.balance_after,
205
+ }
206
+ : null,
207
+ error: wire.error,
208
+ };
209
+ }
210
+ function delay(ms, signal) {
211
+ return new Promise((resolve, reject) => {
212
+ if (signal?.aborted) {
213
+ reject(new DOMException("Aborted", "AbortError"));
214
+ return;
215
+ }
216
+ const timer = setTimeout(() => {
217
+ signal?.removeEventListener("abort", onAbort);
218
+ resolve();
219
+ }, ms);
220
+ const onAbort = () => {
221
+ clearTimeout(timer);
222
+ reject(new DOMException("Aborted", "AbortError"));
223
+ };
224
+ signal?.addEventListener("abort", onAbort, { once: true });
225
+ });
226
+ }
227
+ //# sourceMappingURL=tts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tts.js","sourceRoot":"","sources":["../../src/tts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ // Wire-protocol types mirrored from ServerAPI / signaling.
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.RTCStatusCode = void 0;
5
+ var RTCStatusCode;
6
+ (function (RTCStatusCode) {
7
+ RTCStatusCode[RTCStatusCode["ERROR"] = 2000] = "ERROR";
8
+ RTCStatusCode[RTCStatusCode["GPU_INSUFFICIENT"] = 2001] = "GPU_INSUFFICIENT";
9
+ RTCStatusCode[RTCStatusCode["DUPLICATE_CONNECTION"] = 2002] = "DUPLICATE_CONNECTION";
10
+ RTCStatusCode[RTCStatusCode["MODEL_NOT_FOUND"] = 2003] = "MODEL_NOT_FOUND";
11
+ RTCStatusCode[RTCStatusCode["UNPAID_SERVICE"] = 2004] = "UNPAID_SERVICE";
12
+ RTCStatusCode[RTCStatusCode["REQUEST_TOO_FAST"] = 2005] = "REQUEST_TOO_FAST";
13
+ RTCStatusCode[RTCStatusCode["CONNECTED"] = 3000] = "CONNECTED";
14
+ RTCStatusCode[RTCStatusCode["REQUEST_RECEIVED"] = 3001] = "REQUEST_RECEIVED";
15
+ RTCStatusCode[RTCStatusCode["TRACK_READY"] = 3002] = "TRACK_READY";
16
+ RTCStatusCode[RTCStatusCode["RESPONSE_SENT"] = 3003] = "RESPONSE_SENT";
17
+ RTCStatusCode[RTCStatusCode["LOADING_MODEL"] = 3004] = "LOADING_MODEL";
18
+ RTCStatusCode[RTCStatusCode["SERVICE_READY"] = 3009] = "SERVICE_READY";
19
+ // File inference (voice-to-voice) task lifecycle codes.
20
+ RTCStatusCode[RTCStatusCode["TASK_PROGRESS"] = 3010] = "TASK_PROGRESS";
21
+ RTCStatusCode[RTCStatusCode["TASK_FINISHED"] = 3011] = "TASK_FINISHED";
22
+ RTCStatusCode[RTCStatusCode["TASK_ACK"] = 3012] = "TASK_ACK";
23
+ RTCStatusCode[RTCStatusCode["SHUTDOWN"] = 4000] = "SHUTDOWN";
24
+ RTCStatusCode[RTCStatusCode["SERVER_CLOSED"] = 5000] = "SERVER_CLOSED";
25
+ })(RTCStatusCode || (exports.RTCStatusCode = RTCStatusCode = {}));
26
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":";AAAA,2DAA2D;;;AA+E3D,IAAY,aAsBX;AAtBD,WAAY,aAAa;IACxB,sDAAY,CAAA;IACZ,4EAAuB,CAAA;IACvB,oFAA2B,CAAA;IAC3B,0EAAsB,CAAA;IACtB,wEAAqB,CAAA;IACrB,4EAAuB,CAAA;IAEvB,8DAAgB,CAAA;IAChB,4EAAuB,CAAA;IACvB,kEAAkB,CAAA;IAClB,sEAAoB,CAAA;IACpB,sEAAoB,CAAA;IACpB,sEAAoB,CAAA;IAEpB,wDAAwD;IACxD,sEAAoB,CAAA;IACpB,sEAAoB,CAAA;IACpB,4DAAe,CAAA;IAEf,4DAAe,CAAA;IACf,sEAAoB,CAAA;AACrB,CAAC,EAtBW,aAAa,6BAAb,aAAa,QAsBxB"}