@newgameplusinc/odyssey-audio-video-sdk-dev 1.0.28 → 1.0.30

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/dist/index.d.ts CHANGED
@@ -47,5 +47,54 @@ export declare class OdysseySpatialComms extends EventManager {
47
47
  }): void;
48
48
  setListenerFromLSD(listenerPos: Position, cameraPos: Position, lookAtPos: Position): void;
49
49
  private listenForEvents;
50
+ /**
51
+ * Send huddle invite to another participant
52
+ */
53
+ sendHuddleInvite(toParticipantId: string): Promise<{
54
+ success?: boolean;
55
+ inviteId?: string;
56
+ huddleId?: string;
57
+ error?: string;
58
+ }>;
59
+ /**
60
+ * Accept huddle invite
61
+ */
62
+ acceptHuddleInvite(inviteId: string): Promise<{
63
+ success?: boolean;
64
+ huddleId?: string;
65
+ participants?: string[];
66
+ error?: string;
67
+ }>;
68
+ /**
69
+ * Reject huddle invite
70
+ */
71
+ rejectHuddleInvite(inviteId: string): Promise<{
72
+ success?: boolean;
73
+ error?: string;
74
+ }>;
75
+ /**
76
+ * Join huddle (anyone can join directly without invite)
77
+ */
78
+ joinHuddle(): Promise<{
79
+ success?: boolean;
80
+ channelId?: string;
81
+ error?: string;
82
+ }>;
83
+ /**
84
+ * Leave current huddle and return to spatial audio
85
+ */
86
+ leaveHuddle(): Promise<{
87
+ success?: boolean;
88
+ channelId?: string;
89
+ error?: string;
90
+ }>;
91
+ /**
92
+ * Get participant's current channel
93
+ */
94
+ getParticipantChannel(participantId: string): Promise<string>;
95
+ /**
96
+ * Get local participant's current channel
97
+ */
98
+ getCurrentChannel(): string;
50
99
  }
51
100
  export type { Direction, MediaState, OdysseyEvent, Participant, Position, RoomJoinedData, };
package/dist/index.js CHANGED
@@ -366,6 +366,146 @@ class OdysseySpatialComms extends EventManager_1.EventManager {
366
366
  this.socket.on("disconnect", () => {
367
367
  this.emit("disconnected");
368
368
  });
369
+ // ==================== HUDDLE EVENT LISTENERS ====================
370
+ this.socket.on("huddle-invite-received", (data) => {
371
+ this.emit("huddle-invite-received", data);
372
+ });
373
+ this.socket.on("private-huddle-started", (data) => {
374
+ // Update local participant channel
375
+ if (this.localParticipant && this.localParticipant !== null) {
376
+ this.localParticipant.currentChannel = data.channelId;
377
+ }
378
+ this.emit("private-huddle-started", data);
379
+ });
380
+ this.socket.on("huddle-updated", (data) => {
381
+ // Multi-person huddle update (member joined/left)
382
+ this.emit("huddle-updated", data);
383
+ });
384
+ this.socket.on("huddle-invite-rejected", (data) => {
385
+ this.emit("huddle-invite-rejected", data);
386
+ });
387
+ this.socket.on("huddle-ended", (data) => {
388
+ // Update local participant back to spatial
389
+ if (this.localParticipant && this.localParticipant !== null) {
390
+ this.localParticipant.currentChannel = "spatial";
391
+ }
392
+ this.emit("huddle-ended", data);
393
+ });
394
+ this.socket.on("participant-channel-changed", (data) => {
395
+ const participant = this.room?.participants.get(data.participantId);
396
+ if (participant) {
397
+ participant.currentChannel = data.channelId;
398
+ }
399
+ // Update local participant if it's them
400
+ if (this.localParticipant?.participantId === data.participantId && this.localParticipant !== null) {
401
+ this.localParticipant.currentChannel = data.channelId;
402
+ }
403
+ this.emit("participant-channel-changed", data);
404
+ });
405
+ }
406
+ // ==================== HUDDLE METHODS ====================
407
+ /**
408
+ * Send huddle invite to another participant
409
+ */
410
+ async sendHuddleInvite(toParticipantId) {
411
+ if (!this.localParticipant || !this.room) {
412
+ return { success: false, error: "Not in a room" };
413
+ }
414
+ return new Promise((resolve) => {
415
+ this.socket.emit("send-huddle-invite", {
416
+ fromParticipantId: this.localParticipant.participantId,
417
+ toParticipantId,
418
+ roomId: this.room.id,
419
+ }, (response) => {
420
+ resolve(response);
421
+ });
422
+ });
423
+ }
424
+ /**
425
+ * Accept huddle invite
426
+ */
427
+ async acceptHuddleInvite(inviteId) {
428
+ if (!this.localParticipant) {
429
+ return { success: false, error: "Not in a room" };
430
+ }
431
+ return new Promise((resolve) => {
432
+ this.socket.emit("accept-huddle-invite", {
433
+ inviteId,
434
+ participantId: this.localParticipant.participantId,
435
+ }, (response) => {
436
+ resolve(response);
437
+ });
438
+ });
439
+ }
440
+ /**
441
+ * Reject huddle invite
442
+ */
443
+ async rejectHuddleInvite(inviteId) {
444
+ if (!this.localParticipant) {
445
+ return { success: false, error: "Not in a room" };
446
+ }
447
+ return new Promise((resolve) => {
448
+ this.socket.emit("reject-huddle-invite", {
449
+ inviteId,
450
+ participantId: this.localParticipant.participantId,
451
+ }, (response) => {
452
+ resolve(response);
453
+ });
454
+ });
455
+ }
456
+ /**
457
+ * Join huddle (anyone can join directly without invite)
458
+ */
459
+ async joinHuddle() {
460
+ if (!this.localParticipant || !this.room) {
461
+ return { success: false, error: "Not in a room" };
462
+ }
463
+ return new Promise((resolve) => {
464
+ this.socket.emit("join-huddle", {
465
+ participantId: this.localParticipant.participantId,
466
+ roomId: this.room.id,
467
+ }, (response) => {
468
+ if (response.success && this.localParticipant) {
469
+ this.localParticipant.currentChannel = response.channelId;
470
+ }
471
+ resolve(response);
472
+ });
473
+ });
474
+ }
475
+ /**
476
+ * Leave current huddle and return to spatial audio
477
+ */
478
+ async leaveHuddle() {
479
+ if (!this.localParticipant || !this.room) {
480
+ return { success: false, error: "Not in a room" };
481
+ }
482
+ return new Promise((resolve) => {
483
+ this.socket.emit("leave-huddle", {
484
+ participantId: this.localParticipant.participantId,
485
+ roomId: this.room.id,
486
+ }, (response) => {
487
+ if (response.success && this.localParticipant) {
488
+ this.localParticipant.currentChannel = response.channelId;
489
+ }
490
+ resolve(response);
491
+ });
492
+ });
493
+ }
494
+ /**
495
+ * Get participant's current channel
496
+ */
497
+ async getParticipantChannel(participantId) {
498
+ return new Promise((resolve) => {
499
+ this.socket.emit("get-participant-channel", { participantId }, (response) => {
500
+ resolve(response.channelId || "spatial");
501
+ });
502
+ });
503
+ }
504
+ /**
505
+ * Get local participant's current channel
506
+ */
507
+ getCurrentChannel() {
508
+ return this.localParticipant?.currentChannel || "spatial";
369
509
  }
370
510
  }
371
511
  exports.OdysseySpatialComms = OdysseySpatialComms;
package/dist/types.d.ts CHANGED
@@ -31,6 +31,7 @@ export interface Participant {
31
31
  bodyShape?: string;
32
32
  userName?: string;
33
33
  userEmail?: string;
34
+ currentChannel?: string;
34
35
  }
35
36
  export interface RoomJoinedData {
36
37
  participants: Participant[];
@@ -55,4 +56,4 @@ export interface ParticipantsSnapshotEvent {
55
56
  }>;
56
57
  timestamp: number;
57
58
  }
58
- export type OdysseyEvent = "connected" | "disconnected" | "room-joined" | "all-participants-update" | "new-participant" | "participant-left" | "producer-created" | "consumer-created" | "participant-media-state-updated" | "participant-position-updated" | "error";
59
+ export type OdysseyEvent = "connected" | "disconnected" | "room-joined" | "all-participants-update" | "new-participant" | "participant-left" | "producer-created" | "consumer-created" | "participant-media-state-updated" | "participant-position-updated" | "error" | "huddle-invite-received" | "private-huddle-started" | "huddle-updated" | "huddle-invite-rejected" | "huddle-ended" | "participant-channel-changed";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newgameplusinc/odyssey-audio-video-sdk-dev",
3
- "version": "1.0.28",
3
+ "version": "1.0.30",
4
4
  "description": "Odyssey Spatial Audio & Video SDK using MediaSoup for real-time communication",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",