@unboundcx/sdk 2.8.11 → 4.0.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 (2) hide show
  1. package/package.json +2 -2
  2. package/services/video.js +67 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unboundcx/sdk",
3
- "version": "2.8.11",
3
+ "version": "4.0.0",
4
4
  "description": "Official JavaScript SDK for the Unbound API - A comprehensive toolkit for integrating with Unbound's communication, AI, and data management services",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -59,7 +59,7 @@
59
59
  },
60
60
  "scripts": {
61
61
  "build": "echo 'Build complete - ESM modules ready'",
62
- "test": "echo 'Tests would run here'",
62
+ "test": "node --test 'test/*.test.js'",
63
63
  "lint": "echo 'Linting would run here'",
64
64
  "prepublishOnly": "npm run build"
65
65
  },
package/services/video.js CHANGED
@@ -503,6 +503,27 @@ export class VideoService {
503
503
  return result;
504
504
  }
505
505
 
506
+ /**
507
+ * Validate a guest JWT for a video room. Used by app1-socket's
508
+ * `authorizeVideoSocketConnection` middleware during the `/video` Socket.IO
509
+ * handshake to decide whether to admit the connection.
510
+ *
511
+ * @param {string} id - videoRoom id (must match the token's `roomId` claim)
512
+ * @param {string} [token] - raw JWT. Omit to let the server read it from
513
+ * the `videoAuthToken` cookie on the SDK's request.
514
+ * @returns {Promise<{
515
+ * valid: boolean,
516
+ * account: { id: string, namespace: string, accountCode: string },
517
+ * participant: Object,
518
+ * token: { id: string, type: 'videoRoomGuest', expiresAt: string },
519
+ * videoRoom: Object,
520
+ * podName: string,
521
+ * }>} The `podName` field (added with centralized signaling) is the
522
+ * video-server pod assigned to this room at token-mint time, re-validated
523
+ * against app1-api's live podRegistry. If the pod is no longer alive the
524
+ * server returns HTTP 409 `POD_UNAVAILABLE` — the client reacts by calling
525
+ * `/video/rooms/:id/join` for a fresh assignment.
526
+ */
506
527
  async validateGuestToken(id, token) {
507
528
  this.sdk.validateParams(
508
529
  { id, token },
@@ -524,6 +545,52 @@ export class VideoService {
524
545
  return result;
525
546
  }
526
547
 
548
+ /**
549
+ * Construct a `VideoMeetingClient` configured for this SDK instance.
550
+ *
551
+ * Dynamically imports `@unboundcx/video-sdk-client` so WebRTC peer deps
552
+ * (`mediasoup-client`, `socket.io-client`) stay out of backend bundles that
553
+ * never touch video. Returns a client with `this` SDK injected so it can
554
+ * transparently call `sdk.video.joinRoom()` for reassignment recovery and
555
+ * `sdk.video.endSession()` on leave.
556
+ *
557
+ * **Bundler note**: SvelteKit/Vite handle the dynamic import natively. If
558
+ * you use a bundler that eagerly resolves imports, pin the import path or
559
+ * ensure the package is marked external.
560
+ *
561
+ * @param {Object} [options] - Forwarded to the `VideoMeetingClient` constructor
562
+ * @returns {Promise<import('@unboundcx/video-sdk-client').VideoMeetingClient>}
563
+ */
564
+ async createMeetingClient(options = {}) {
565
+ const { VideoMeetingClient } = await import('@unboundcx/video-sdk-client');
566
+ return new VideoMeetingClient({ ...options, sdk: this.sdk });
567
+ }
568
+
569
+ /**
570
+ * End the meeting session server-side. Invalidates the token row in the
571
+ * `tokens` table and clears the `videoAuthToken` cookie so a stale cookie
572
+ * from a prior meeting can't be replayed.
573
+ *
574
+ * The endpoint is deliberately permissive: accepts expired and
575
+ * room-mismatched cookies and never returns 401/403 — rejection would
576
+ * strand stale cookies.
577
+ *
578
+ * @param {string} roomId
579
+ */
580
+ async endSession(roomId) {
581
+ this.sdk.validateParams(
582
+ { roomId },
583
+ { roomId: { type: 'string', required: true } },
584
+ );
585
+ const result = await this.sdk._fetch(
586
+ `/video/session/end`,
587
+ 'POST',
588
+ { body: { roomId } },
589
+ true,
590
+ );
591
+ return result;
592
+ }
593
+
527
594
  async logStats(roomId, stats) {
528
595
  this.sdk.validateParams(
529
596
  { roomId, stats },