restream-sdk 0.1.2 → 0.1.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "restream-sdk",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Plug-and-play headless React hooks to add multi-platform restreaming (connect socials, go live, live chat + viewers) with zero client backend.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/core.js CHANGED
@@ -4,7 +4,7 @@
4
4
  // (publisherSessionId) is produced by the client's existing stream and passed
5
5
  // into goLive() — this module never captures or publishes media itself.
6
6
 
7
- export const PLATFORMS = ["twitch", "kick", "youtube", "facebook", "instagram"];
7
+ export const PLATFORMS = ["twitch", "kick", "youtube", "facebook", "instagram", "tiktok"];
8
8
 
9
9
  const TERMINAL_STATUS = new Set(["stopped", "failed", "ended", "error", "completed"]);
10
10
 
@@ -129,12 +129,30 @@ export class RestreamStudio extends EventTarget {
129
129
  return this.connections;
130
130
  }
131
131
 
132
+ /** Ask the backend which OAuth platforms are configured for this client. */
133
+ async listOAuthPlatforms() {
134
+ return this._req("GET", `/api/v1/connect/platforms${this._userQuery()}`);
135
+ }
136
+
137
+ /**
138
+ * List the channels the user connected inside their Restream account (the
139
+ * platforms Restream fans out to, e.g. TikTok). Requires a connected Restream
140
+ * account. Returns [{ id, platform, displayName, url, active }]; pass the chosen
141
+ * ids to goLive({ destinations: ["restream"], restreamChannels: [...] }).
142
+ */
143
+ async listRestreamChannels() {
144
+ const r = await this._req("GET", `/api/v1/connect/restream/channels${this._userQuery()}`);
145
+ return r?.channels || [];
146
+ }
147
+
132
148
  /** Open the hosted OAuth popup for a platform; resolves when connected (or the popup closes). */
133
149
  async connect(platform) {
134
- const q = await this._authQuery();
135
- const url = `${this.apiBase}/api/v1/connect/${platform}/start?${new URLSearchParams(q)}`;
136
- const popup = window.open(url, "restream_connect", "width=560,height=760");
150
+ // Open the popup synchronously, inside the click's user-activation window —
151
+ // any await before window.open consumes the gesture and the browser blocks it.
152
+ const popup = window.open("", "restream_connect", "width=560,height=760");
137
153
  if (!popup) throw new Error("popup blocked — allow popups to connect accounts");
154
+ const q = await this._authQuery();
155
+ popup.location = `${this.apiBase}/api/v1/connect/${platform}/start?${new URLSearchParams(q)}`;
138
156
  return new Promise((resolve, reject) => {
139
157
  const cleanup = () => {
140
158
  window.removeEventListener("message", onMsg);
@@ -173,7 +191,7 @@ export class RestreamStudio extends EventTarget {
173
191
  * @param {boolean} [opts.recording]
174
192
  * @param {string[]} [opts.trackNames] tracks actually published, e.g. ["audio","video"]
175
193
  */
176
- async goLive({ publisherSessionId, destinations, overlay, recording, trackNames } = {}) {
194
+ async goLive({ publisherSessionId, destinations, overlay, recording, trackNames, restreamChannels } = {}) {
177
195
  if (!publisherSessionId) throw new Error("publisherSessionId is required (from your existing stream session)");
178
196
  const body = {
179
197
  publisherSessionId,
@@ -182,6 +200,8 @@ export class RestreamStudio extends EventTarget {
182
200
  recording,
183
201
  };
184
202
  if (trackNames && trackNames.length) body.trackNames = trackNames;
203
+ // Per-platform selection for the "restream" fan-out bridge (channel ids or platform names).
204
+ if (restreamChannels && restreamChannels.length) body.restreamChannels = restreamChannels;
185
205
  if (this.publishableKey && this.userId) body.clientUserId = this.userId; // token mode binds server-side
186
206
  const job = await this._req("POST", "/api/v1/jobs", body);
187
207
  this.job = job;
package/src/react.js CHANGED
@@ -40,6 +40,8 @@ export function useRestream(opts) {
40
40
  connect: useCallback((p) => studio.connect(p), [studio]),
41
41
  disconnect: useCallback((p) => studio.disconnect(p), [studio]),
42
42
  listConnections: useCallback(() => studio.listConnections(), [studio]),
43
+ listOAuthPlatforms: useCallback(() => studio.listOAuthPlatforms(), [studio]),
44
+ listRestreamChannels: useCallback(() => studio.listRestreamChannels(), [studio]),
43
45
  arm: useCallback((o) => studio.arm(o), [studio]),
44
46
  goLive: useCallback((o) => studio.goLive(o), [studio]),
45
47
  stopLive: useCallback(() => studio.stopLive(), [studio]),
@@ -51,8 +53,8 @@ export function useRestream(opts) {
51
53
 
52
54
  /** Convenience: just the social-connection state + actions. */
53
55
  export function useConnections(opts) {
54
- const { connections, connect, disconnect, listConnections } = useRestream(opts);
55
- return { connections, connect, disconnect, refresh: listConnections };
56
+ const { connections, connect, disconnect, listConnections, listOAuthPlatforms, listRestreamChannels } = useRestream(opts);
57
+ return { connections, connect, disconnect, refresh: listConnections, listOAuthPlatforms, listRestreamChannels };
56
58
  }
57
59
 
58
60
  /** Convenience: live chat (incoming comments + outbound send). Pass an existing studio. */
package/types/core.d.ts CHANGED
@@ -2,6 +2,7 @@
2
2
  export { RestreamStudio, PLATFORMS } from "./index";
3
3
  export type {
4
4
  Platform,
5
+ RestreamChannel,
5
6
  RestreamOptions,
6
7
  Connection,
7
8
  Job,
package/types/index.d.ts CHANGED
@@ -1,4 +1,13 @@
1
- export type Platform = "twitch" | "kick" | "youtube" | "facebook" | "instagram";
1
+ export type Platform = "twitch" | "kick" | "youtube" | "facebook" | "instagram" | "tiktok" | "restream";
2
+
3
+ /** A channel the user connected inside their Restream account (a fan-out target). */
4
+ export interface RestreamChannel {
5
+ id: string;
6
+ platform: string;
7
+ displayName: string | null;
8
+ url: string | null;
9
+ active: boolean;
10
+ }
2
11
  export const PLATFORMS: Platform[];
3
12
 
4
13
  export interface RestreamOptions {
@@ -60,6 +69,12 @@ export interface GoLiveParams {
60
69
  recording?: boolean;
61
70
  /** Track names actually published (e.g. ["audio","video"] or ["video"]). */
62
71
  trackNames?: string[];
72
+ /**
73
+ * For the "restream" fan-out destination: which Restream channels to relay to
74
+ * (channel ids from listRestreamChannels(), or platform names like "tiktok").
75
+ * Omit to use whichever channels are currently active in the Restream account.
76
+ */
77
+ restreamChannels?: string[];
63
78
  }
64
79
 
65
80
  export interface OverlayUpdate {
@@ -84,6 +99,8 @@ export class RestreamStudio extends EventTarget {
84
99
  on(type: "comments", cb: (c: Comment[]) => void): () => void;
85
100
  on(type: "error", cb: (e: Error) => void): () => void;
86
101
  listConnections(): Promise<Connection[]>;
102
+ listOAuthPlatforms(): Promise<{ platforms: Platform[]; frontendOrigin: string; redirectOrigin: string }>;
103
+ listRestreamChannels(): Promise<RestreamChannel[]>;
87
104
  connect(platform: Platform): Promise<{ platform: Platform; closed?: boolean }>;
88
105
  disconnect(platform: Platform): Promise<Connection[]>;
89
106
  arm(opts: { destinations: Platform[] }): unknown;
@@ -111,6 +128,8 @@ export interface UseRestream {
111
128
  connect(platform: Platform): Promise<{ platform: Platform; closed?: boolean }>;
112
129
  disconnect(platform: Platform): Promise<Connection[]>;
113
130
  listConnections(): Promise<Connection[]>;
131
+ listOAuthPlatforms(): Promise<{ platforms: Platform[]; frontendOrigin: string; redirectOrigin: string }>;
132
+ listRestreamChannels(): Promise<RestreamChannel[]>;
114
133
  arm(opts: { destinations: Platform[] }): unknown;
115
134
  goLive(opts: GoLiveParams): Promise<Job>;
116
135
  stopLive(): Promise<unknown>;
@@ -125,6 +144,8 @@ export function useConnections(opts: RestreamOptions): {
125
144
  connect(platform: Platform): Promise<{ platform: Platform; closed?: boolean }>;
126
145
  disconnect(platform: Platform): Promise<Connection[]>;
127
146
  refresh(): Promise<Connection[]>;
147
+ listOAuthPlatforms(): Promise<{ platforms: Platform[]; frontendOrigin: string; redirectOrigin: string }>;
148
+ listRestreamChannels(): Promise<RestreamChannel[]>;
128
149
  };
129
150
  export function useLiveChat(studio: RestreamStudio): { comments: Comment[]; send(message: string, platforms?: Platform[]): Promise<unknown> };
130
151
  export function useViewers(studio: RestreamStudio): ViewerCounts | null;