restream-sdk 0.5.0 → 0.7.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "restream-sdk",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "Plug-and-play headless React hooks to add multi-platform restreaming (connect socials, go live, live chat + viewers, collaborative split-screen) with zero client backend.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/core.js CHANGED
@@ -400,14 +400,27 @@ export class RestreamStudio extends EventTarget {
400
400
  * Restream channels. Any field omitted falls back to the
401
401
  * default pre-set for this creator on the platform.
402
402
  */
403
- async goLive({ publisherSessionId, destinations, overlay, recording, trackNames, restreamChannels, streamMeta, destinationMeta, streamingProvider, layout, screenSessionId } = {}) {
403
+ async goLive({ publisherSessionId, destinations, overlay, recording, trackNames, restreamChannels, streamMeta, destinationMeta, streamingProvider, layout, screenSessionId, participantOnly } = {}) {
404
404
  if (!publisherSessionId) throw new Error("publisherSessionId is required (from your existing stream session)");
405
+ // Idempotency guard: refuse a second goLive while a job is already live. Re-publishing a fresh
406
+ // session and calling goLive() again on reconnect / screen toggle / collaborator change is the #1
407
+ // cause of duplicate + stale jobs — those are LIVE changes, so use setStreamState() /
408
+ // startScreenShare() / acceptCollab(), NOT a new goLive. Keep ONE publisher session for the whole
409
+ // stream; call stopLive() first to intentionally start over. Only live states block, so after the
410
+ // job stops (status becomes stopping/stopped/failed/ended) a genuine restart works normally.
411
+ if (this.job?.id && ["queued", "starting", "connecting", "running"].includes(this.job.status)) {
412
+ throw new Error(`goLive blocked: a stream is already live (job ${this.job.id}, status ${this.job.status}). Use setStreamState()/startScreenShare()/acceptCollab() for live changes, and call stopLive() before starting a new stream — do not re-publish or re-goLive on reconnect/screen/collab changes.`);
413
+ }
405
414
  const body = {
406
415
  publisherSessionId,
407
416
  destinations: destinations || this._armed?.destinations || [],
408
417
  overlay,
409
418
  recording,
410
419
  };
420
+ // Compositing-only participant (e.g. a collab challenger with no socials): go live with NO
421
+ // destinations. The job reaches 'running' — discoverable as an activeSoloJob so a per-creator
422
+ // collab can composite its camera — but fans out nowhere. Only forwarded when true.
423
+ if (participantOnly) body.participantOnly = true;
411
424
  if (trackNames && trackNames.length) body.trackNames = trackNames;
412
425
  // Per-platform selection for the "restream" fan-out bridge (channel ids or platform names).
413
426
  if (restreamChannels && restreamChannels.length) body.restreamChannels = restreamChannels;
@@ -523,10 +536,11 @@ export class RestreamStudio extends EventTarget {
523
536
 
524
537
  /**
525
538
  * Start screen sharing: capture the screen and publish it as its OWN Cloudflare Realtime
526
- * session (a separate LAYER from the camera). Returns { sessionId, trackName } pass the
527
- * sessionId to goLive({ screenSessionId }) (or updateScreenLayer() while live) so the backend
528
- * composites screen + camera server-side via the template. Restream-only; not shown in the
529
- * client's own player. Must be called from a user gesture (getDisplayMedia requires it).
539
+ * session (a separate LAYER from the camera). Returns { sessionId, trackName }. Also calls
540
+ * setStreamState({ screenShare: true, screenSessionId, screenTrackName }) for you, so the backend
541
+ * composites screen + camera server-side (solo screen_camera, collab collab_screen) at
542
+ * go-live if called first, or LIVE mid-stream via the layout transition. Restream-only; not shown
543
+ * in the client's own player. Must be called from a user gesture (getDisplayMedia requires it).
530
544
  *
531
545
  * @param {object} [opts] { trackName='screen', audio=false }
532
546
  * @returns {Promise<{sessionId:string, trackName:string}>}
package/types/index.d.ts CHANGED
@@ -107,6 +107,12 @@ export interface GoLiveParams {
107
107
  /** Cloudflare session of a screen-share publish (from startScreenShare) to composite as a
108
108
  * separate layer. Defaults to the SDK's active screen share if omitted. */
109
109
  screenSessionId?: string;
110
+ /**
111
+ * Compositing-only participant: go live with NO destinations. The job reaches `running` (so it's
112
+ * discoverable as an active solo job for a per-creator collab to composite its camera) but fans
113
+ * out nowhere. For a collab participant with no socials of their own (e.g. a challenger).
114
+ */
115
+ participantOnly?: boolean;
110
116
  }
111
117
 
112
118
  export interface StreamMeta {