@newgameplusinc/odyssey-audio-video-sdk-dev 1.0.257 → 1.0.259

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 (83) hide show
  1. package/README.md +45 -1
  2. package/dist/audio/AudioNodeFactory.d.ts +130 -0
  3. package/dist/audio/AudioNodeFactory.js +158 -0
  4. package/dist/audio/AudioPipeline.d.ts +89 -0
  5. package/dist/audio/AudioPipeline.js +138 -0
  6. package/dist/{MLNoiseSuppressor.d.ts → audio/MLNoiseSuppressor.d.ts} +7 -7
  7. package/dist/{MLNoiseSuppressor.js → audio/MLNoiseSuppressor.js} +13 -41
  8. package/dist/audio/index.d.ts +6 -0
  9. package/dist/audio/index.js +22 -0
  10. package/dist/channels/huddle/HuddleChannel.d.ts +87 -0
  11. package/dist/channels/huddle/HuddleChannel.js +152 -0
  12. package/dist/channels/huddle/HuddleTypes.d.ts +85 -0
  13. package/dist/channels/huddle/HuddleTypes.js +25 -0
  14. package/dist/channels/huddle/index.d.ts +5 -0
  15. package/dist/channels/huddle/index.js +21 -0
  16. package/dist/channels/index.d.ts +5 -0
  17. package/dist/channels/index.js +21 -0
  18. package/dist/channels/spatial/SpatialAudioChannel.d.ts +144 -0
  19. package/dist/channels/spatial/SpatialAudioChannel.js +455 -0
  20. package/dist/channels/spatial/SpatialAudioTypes.d.ts +85 -0
  21. package/dist/channels/spatial/SpatialAudioTypes.js +42 -0
  22. package/dist/channels/spatial/index.d.ts +5 -0
  23. package/dist/channels/spatial/index.js +21 -0
  24. package/dist/{EventManager.d.ts → core/EventManager.d.ts} +4 -2
  25. package/dist/{EventManager.js → core/EventManager.js} +5 -3
  26. package/dist/{MediasoupManager.d.ts → core/MediasoupManager.d.ts} +10 -4
  27. package/dist/{MediasoupManager.js → core/MediasoupManager.js} +31 -42
  28. package/dist/core/index.d.ts +5 -0
  29. package/dist/core/index.js +21 -0
  30. package/dist/index.d.ts +2 -2
  31. package/dist/index.js +30 -4
  32. package/dist/sdk/index.d.ts +36 -0
  33. package/dist/sdk/index.js +121 -0
  34. package/dist/types/events.d.ts +154 -0
  35. package/dist/{types.js → types/events.js} +3 -0
  36. package/dist/types/index.d.ts +7 -0
  37. package/dist/types/index.js +23 -0
  38. package/dist/types/participant.d.ts +65 -0
  39. package/dist/types/participant.js +5 -0
  40. package/dist/types/position.d.ts +47 -0
  41. package/dist/types/position.js +9 -0
  42. package/dist/types/room.d.ts +82 -0
  43. package/dist/types/room.js +5 -0
  44. package/dist/utils/audio/clarity-score.d.ts +33 -0
  45. package/dist/utils/audio/clarity-score.js +81 -0
  46. package/dist/utils/audio/index.d.ts +5 -0
  47. package/dist/utils/audio/index.js +21 -0
  48. package/dist/utils/audio/voice-filter.d.ts +30 -0
  49. package/dist/utils/audio/voice-filter.js +70 -0
  50. package/dist/utils/index.d.ts +7 -0
  51. package/dist/utils/index.js +23 -0
  52. package/dist/utils/position/coordinates.d.ts +37 -0
  53. package/dist/utils/position/coordinates.js +61 -0
  54. package/dist/utils/position/index.d.ts +6 -0
  55. package/dist/utils/position/index.js +22 -0
  56. package/dist/utils/position/normalize.d.ts +37 -0
  57. package/dist/utils/position/normalize.js +78 -0
  58. package/dist/utils/position/snap.d.ts +51 -0
  59. package/dist/utils/position/snap.js +81 -0
  60. package/dist/utils/smoothing/gain-smoothing.d.ts +45 -0
  61. package/dist/utils/smoothing/gain-smoothing.js +77 -0
  62. package/dist/utils/smoothing/index.d.ts +5 -0
  63. package/dist/utils/smoothing/index.js +21 -0
  64. package/dist/utils/smoothing/pan-smoothing.d.ts +43 -0
  65. package/dist/utils/smoothing/pan-smoothing.js +85 -0
  66. package/dist/utils/spatial/angle-calc.d.ts +24 -0
  67. package/dist/utils/spatial/angle-calc.js +69 -0
  68. package/dist/utils/spatial/distance-calc.d.ts +33 -0
  69. package/dist/utils/spatial/distance-calc.js +48 -0
  70. package/dist/utils/spatial/gain-calc.d.ts +37 -0
  71. package/dist/utils/spatial/gain-calc.js +52 -0
  72. package/dist/utils/spatial/head-position.d.ts +32 -0
  73. package/dist/utils/spatial/head-position.js +76 -0
  74. package/dist/utils/spatial/index.d.ts +9 -0
  75. package/dist/utils/spatial/index.js +25 -0
  76. package/dist/utils/spatial/listener-calc.d.ts +28 -0
  77. package/dist/utils/spatial/listener-calc.js +74 -0
  78. package/dist/utils/spatial/pan-calc.d.ts +48 -0
  79. package/dist/utils/spatial/pan-calc.js +80 -0
  80. package/package.json +1 -1
  81. package/dist/SpatialAudioManager.d.ts +0 -272
  82. package/dist/SpatialAudioManager.js +0 -1537
  83. package/dist/types.d.ts +0 -73
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  /**
3
3
  * ML Noise Suppressor - TensorFlow.js-based Real-Time Audio Enhancement
4
- * Integrates trained ML model for noise suppression with fallback to traditional DSP
4
+ *
5
+ * Integrates trained ML model for noise suppression
6
+ * Falls back to traditional DSP if ML is unavailable
5
7
  */
6
8
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
9
  if (k2 === undefined) k2 = k;
@@ -45,9 +47,9 @@ class MLNoiseSuppressor {
45
47
  this.config = null;
46
48
  this.normStats = null;
47
49
  this.isInitialized = false;
48
- // Temporal smoothing state (prevents "musical noise" artifacts)
50
+ // Temporal smoothing state
49
51
  this.prevMask = null;
50
- this.SMOOTHING_ALPHA = 0.85; // 85% current, 15% previous
52
+ this.SMOOTHING_ALPHA = 0.85;
51
53
  // Voice frequency preservation
52
54
  this.VOICE_FUNDAMENTAL_MIN = 80;
53
55
  this.VOICE_FUNDAMENTAL_MAX = 500;
@@ -57,19 +59,14 @@ class MLNoiseSuppressor {
57
59
  * @param modelUrl Path to model.json file
58
60
  */
59
61
  async initialize(modelUrl) {
60
- //console.log('🤖 [ML] Initializing ML Noise Suppressor...');
61
62
  try {
62
- // Set TensorFlow.js backend (WebGL for GPU acceleration)
63
+ // Set TensorFlow.js backend
63
64
  await tf.setBackend('webgl');
64
65
  await tf.ready();
65
- // HACK: Explicitly provide inputShape to fix model loading errors.
66
- // The model's JSON file is missing the input layer configuration, which causes
67
- // TensorFlow.js to throw a ValueError. This workaround intercepts the loading
68
- // process and injects the correct input shape before the model is fully parsed.
66
+ // Load model with input shape fix
69
67
  const modelJson = await (await fetch(modelUrl)).json();
70
68
  if (modelJson.modelTopology?.config?.layers?.[0]?.config
71
69
  ?.batch_input_shape === undefined) {
72
- // Model JSON is missing inputShape - apply fix
73
70
  modelJson.modelTopology.config.layers[0].config.batch_input_shape = [
74
71
  null,
75
72
  257,
@@ -88,7 +85,6 @@ class MLNoiseSuppressor {
88
85
  this.normStats = await normResponse.json();
89
86
  }
90
87
  catch (e) {
91
- // No normalization stats found, use defaults
92
88
  this.normStats = { mean: 0, std: 1 };
93
89
  }
94
90
  this.isInitialized = true;
@@ -99,43 +95,31 @@ class MLNoiseSuppressor {
99
95
  }
100
96
  /**
101
97
  * Process audio buffer through ML model
102
- * @param inputBuffer Audio samples to process
103
- * @returns Denoised audio samples
104
98
  */
105
99
  async processAudio(inputBuffer) {
106
100
  if (!this.isInitialized || !this.model || !this.config || !this.normStats) {
107
- // Not initialized, return original audio
108
101
  return inputBuffer;
109
102
  }
110
103
  try {
111
104
  return await tf.tidy(() => {
112
- // 1. Extract features (simplified mel-spectrogram approximation)
113
105
  const features = this.extractFeatures(inputBuffer);
114
- // 2. Normalize features
115
106
  const normalizedTensor = tf.tensor2d(features);
116
107
  const normalized = normalizedTensor
117
108
  .sub(this.normStats.mean)
118
109
  .div(Math.max(this.normStats.std, 1e-8));
119
- // 3. Create sequences for LSTM
120
110
  const sequences = this.createSequences(normalized);
121
- // 4. Run ML inference to get noise suppression mask
122
111
  const maskTensor = this.model.predict(sequences);
123
- // 5. Extract mask values
124
112
  const maskArray = maskTensor.dataSync();
125
- // 6. Apply temporal smoothing (critical for quality!)
126
113
  const smoothedMask = this.applyTemporalSmoothing(Array.from(maskArray));
127
- // 7. Apply mask to audio with voice preservation
128
- const enhanced = this.applyMaskToAudio(inputBuffer, smoothedMask);
129
- return enhanced;
114
+ return this.applyMaskToAudio(inputBuffer, smoothedMask);
130
115
  });
131
116
  }
132
117
  catch (error) {
133
- // Return original audio on error (graceful degradation)
134
118
  return inputBuffer;
135
119
  }
136
120
  }
137
121
  /**
138
- * Extract audio features (simplified mel-spectrogram approximation)
122
+ * Extract audio features
139
123
  */
140
124
  extractFeatures(audio) {
141
125
  if (!this.config)
@@ -148,18 +132,15 @@ class MLNoiseSuppressor {
148
132
  for (let i = 0; i < numFrames; i++) {
149
133
  const start = i * hopLength;
150
134
  const frame = audio.slice(start, Math.min(start + frameSize, audio.length));
151
- // Compute simplified mel bins
152
135
  const melBins = [];
153
136
  for (let j = 0; j < nMels; j++) {
154
137
  const binStart = Math.floor((j / nMels) * frame.length);
155
138
  const binEnd = Math.floor(((j + 1) / nMels) * frame.length);
156
- // Compute energy in this bin
157
139
  let energy = 0;
158
140
  for (let k = binStart; k < binEnd; k++) {
159
141
  energy += frame[k] * frame[k];
160
142
  }
161
143
  energy = Math.sqrt(energy / (binEnd - binStart));
162
- // Convert to log scale (dB-like)
163
144
  const logEnergy = Math.log10(energy + 1e-10) * 10;
164
145
  melBins.push(logEnergy);
165
146
  }
@@ -178,51 +159,42 @@ class MLNoiseSuppressor {
178
159
  const numFrames = shape[0];
179
160
  const numFeatures = shape[1];
180
161
  if (numFrames < seqLength) {
181
- // Pad if needed
182
162
  const padding = tf.zeros([seqLength - numFrames, numFeatures]);
183
163
  const padded = tf.concat([featureTensor, padding], 0);
184
164
  return padded.expandDims(0);
185
165
  }
186
- // Take the last seqLength frames
187
166
  const sequence = featureTensor.slice([numFrames - seqLength, 0], [seqLength, numFeatures]);
188
167
  return sequence.expandDims(0);
189
168
  }
190
169
  /**
191
- * Apply temporal smoothing to mask (prevents "musical noise")
170
+ * Apply temporal smoothing to mask
192
171
  */
193
172
  applyTemporalSmoothing(currentMask) {
194
173
  const smoothed = new Float32Array(currentMask.length);
195
174
  if (!this.prevMask || this.prevMask.length !== currentMask.length) {
196
- // First frame - no smoothing
197
175
  this.prevMask = new Float32Array(currentMask);
198
176
  return this.prevMask;
199
177
  }
200
- // Exponential moving average
201
178
  for (let i = 0; i < currentMask.length; i++) {
202
179
  smoothed[i] =
203
180
  this.SMOOTHING_ALPHA * currentMask[i] +
204
181
  (1 - this.SMOOTHING_ALPHA) * this.prevMask[i];
205
- // Clamp to valid range [0.05, 1.0]
206
- // Never completely mute (min 5% to preserve voice quality)
207
182
  smoothed[i] = Math.max(0.05, Math.min(1.0, smoothed[i]));
208
183
  }
209
184
  this.prevMask = smoothed;
210
185
  return smoothed;
211
186
  }
212
187
  /**
213
- * Apply noise suppression mask to audio with voice preservation
188
+ * Apply noise suppression mask to audio
214
189
  */
215
190
  applyMaskToAudio(audio, mask) {
216
191
  const output = new Float32Array(audio.length);
217
- // Apply mask with simple interpolation
218
192
  for (let i = 0; i < audio.length; i++) {
219
- // Map audio sample to mask index
220
193
  const maskIdx = Math.floor((i / audio.length) * mask.length);
221
194
  const gain = mask[Math.min(maskIdx, mask.length - 1)];
222
- // Apply gain with voice frequency boost
223
195
  output[i] = audio[i] * gain;
224
196
  }
225
- // Apply fade-in/out to prevent clicks at boundaries
197
+ // Fade edges
226
198
  const fadeLength = Math.min(128, output.length / 20);
227
199
  for (let i = 0; i < fadeLength; i++) {
228
200
  const fade = i / fadeLength;
@@ -234,7 +206,7 @@ class MLNoiseSuppressor {
234
206
  return output;
235
207
  }
236
208
  /**
237
- * Reset processing state (call when switching audio streams)
209
+ * Reset processing state
238
210
  */
239
211
  reset() {
240
212
  this.prevMask = null;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Audio module exports
3
+ */
4
+ export * from './AudioPipeline';
5
+ export * from './AudioNodeFactory';
6
+ export * from './MLNoiseSuppressor';
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ /**
3
+ * Audio module exports
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
17
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ __exportStar(require("./AudioPipeline"), exports);
21
+ __exportStar(require("./AudioNodeFactory"), exports);
22
+ __exportStar(require("./MLNoiseSuppressor"), exports);
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Huddle Channel
3
+ *
4
+ * Manages private huddle conversations between participants
5
+ */
6
+ import { Socket } from 'socket.io-client';
7
+ import { HuddleAcceptResponse, HuddleRejectResponse, HuddleResponse } from './HuddleTypes';
8
+ /**
9
+ * Huddle channel configuration
10
+ */
11
+ export interface HuddleChannelConfig {
12
+ socket: Socket;
13
+ localParticipantId: string;
14
+ roomId: string;
15
+ }
16
+ /**
17
+ * Huddle Channel class
18
+ * Handles all huddle-related socket communication
19
+ */
20
+ export declare class HuddleChannel {
21
+ private socket;
22
+ private localParticipantId;
23
+ private roomId;
24
+ private currentChannel;
25
+ constructor(config: HuddleChannelConfig);
26
+ /**
27
+ * Get current channel ID
28
+ */
29
+ getCurrentChannel(): string;
30
+ /**
31
+ * Set current channel (called when channel changes)
32
+ */
33
+ setCurrentChannel(channelId: string): void;
34
+ /**
35
+ * Check if currently in a huddle
36
+ */
37
+ isInHuddle(): boolean;
38
+ /**
39
+ * Send huddle invite to another participant
40
+ */
41
+ sendInvite(toParticipantId: string): Promise<{
42
+ success?: boolean;
43
+ inviteId?: string;
44
+ huddleId?: string;
45
+ error?: string;
46
+ }>;
47
+ /**
48
+ * Accept a huddle invite
49
+ */
50
+ acceptInvite(inviteId: string): Promise<HuddleAcceptResponse>;
51
+ /**
52
+ * Reject a huddle invite
53
+ */
54
+ rejectInvite(inviteId: string): Promise<HuddleRejectResponse>;
55
+ /**
56
+ * Join the global huddle channel
57
+ */
58
+ join(): Promise<{
59
+ success?: boolean;
60
+ channelId?: string;
61
+ error?: string;
62
+ }>;
63
+ /**
64
+ * Leave current huddle and return to spatial audio
65
+ */
66
+ leave(): Promise<{
67
+ success?: boolean;
68
+ channelId?: string;
69
+ error?: string;
70
+ }>;
71
+ /**
72
+ * Get a participant's current channel
73
+ */
74
+ getParticipantChannel(participantId: string): Promise<string>;
75
+ /**
76
+ * Request another participant to mute (owner only)
77
+ */
78
+ muteParticipant(participantId: string, requesterId: string): Promise<HuddleResponse>;
79
+ /**
80
+ * Update local participant ID (after reconnection)
81
+ */
82
+ updateLocalParticipantId(participantId: string): void;
83
+ /**
84
+ * Update room ID (after room change)
85
+ */
86
+ updateRoomId(roomId: string): void;
87
+ }
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ /**
3
+ * Huddle Channel
4
+ *
5
+ * Manages private huddle conversations between participants
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.HuddleChannel = void 0;
9
+ const HuddleTypes_1 = require("./HuddleTypes");
10
+ /**
11
+ * Huddle Channel class
12
+ * Handles all huddle-related socket communication
13
+ */
14
+ class HuddleChannel {
15
+ constructor(config) {
16
+ this.currentChannel = HuddleTypes_1.SPATIAL_CHANNEL_ID;
17
+ this.socket = config.socket;
18
+ this.localParticipantId = config.localParticipantId;
19
+ this.roomId = config.roomId;
20
+ }
21
+ /**
22
+ * Get current channel ID
23
+ */
24
+ getCurrentChannel() {
25
+ return this.currentChannel;
26
+ }
27
+ /**
28
+ * Set current channel (called when channel changes)
29
+ */
30
+ setCurrentChannel(channelId) {
31
+ this.currentChannel = channelId;
32
+ }
33
+ /**
34
+ * Check if currently in a huddle
35
+ */
36
+ isInHuddle() {
37
+ return this.currentChannel !== HuddleTypes_1.SPATIAL_CHANNEL_ID;
38
+ }
39
+ /**
40
+ * Send huddle invite to another participant
41
+ */
42
+ async sendInvite(toParticipantId) {
43
+ return new Promise((resolve) => {
44
+ this.socket.emit('send-huddle-invite', {
45
+ fromParticipantId: this.localParticipantId,
46
+ toParticipantId,
47
+ roomId: this.roomId,
48
+ }, (response) => {
49
+ resolve(response);
50
+ });
51
+ });
52
+ }
53
+ /**
54
+ * Accept a huddle invite
55
+ */
56
+ async acceptInvite(inviteId) {
57
+ return new Promise((resolve) => {
58
+ this.socket.emit('accept-huddle-invite', {
59
+ inviteId,
60
+ participantId: this.localParticipantId,
61
+ }, (response) => {
62
+ if (response.success) {
63
+ // Server may send huddleId OR channelId - handle both
64
+ this.currentChannel = response.channelId || response.huddleId || 'odyssey-huddle';
65
+ }
66
+ resolve(response);
67
+ });
68
+ });
69
+ }
70
+ /**
71
+ * Reject a huddle invite
72
+ */
73
+ async rejectInvite(inviteId) {
74
+ return new Promise((resolve) => {
75
+ this.socket.emit('reject-huddle-invite', {
76
+ inviteId,
77
+ participantId: this.localParticipantId,
78
+ }, (response) => {
79
+ resolve(response);
80
+ });
81
+ });
82
+ }
83
+ /**
84
+ * Join the global huddle channel
85
+ */
86
+ async join() {
87
+ return new Promise((resolve) => {
88
+ this.socket.emit('join-huddle', {
89
+ participantId: this.localParticipantId,
90
+ roomId: this.roomId,
91
+ }, (response) => {
92
+ if (response.success && response.channelId) {
93
+ this.currentChannel = response.channelId;
94
+ }
95
+ resolve(response);
96
+ });
97
+ });
98
+ }
99
+ /**
100
+ * Leave current huddle and return to spatial audio
101
+ */
102
+ async leave() {
103
+ return new Promise((resolve) => {
104
+ this.socket.emit('leave-huddle', {
105
+ participantId: this.localParticipantId,
106
+ roomId: this.roomId,
107
+ }, (response) => {
108
+ if (response.success) {
109
+ this.currentChannel = response.channelId || HuddleTypes_1.SPATIAL_CHANNEL_ID;
110
+ }
111
+ resolve(response);
112
+ });
113
+ });
114
+ }
115
+ /**
116
+ * Get a participant's current channel
117
+ */
118
+ async getParticipantChannel(participantId) {
119
+ return new Promise((resolve) => {
120
+ this.socket.emit('get-participant-channel', { participantId }, (response) => {
121
+ resolve(response.channelId || HuddleTypes_1.SPATIAL_CHANNEL_ID);
122
+ });
123
+ });
124
+ }
125
+ /**
126
+ * Request another participant to mute (owner only)
127
+ */
128
+ async muteParticipant(participantId, requesterId) {
129
+ return new Promise((resolve) => {
130
+ this.socket.emit('mute-participant', {
131
+ targetParticipantId: participantId,
132
+ roomId: this.roomId,
133
+ requesterId,
134
+ }, (response) => {
135
+ resolve(response);
136
+ });
137
+ });
138
+ }
139
+ /**
140
+ * Update local participant ID (after reconnection)
141
+ */
142
+ updateLocalParticipantId(participantId) {
143
+ this.localParticipantId = participantId;
144
+ }
145
+ /**
146
+ * Update room ID (after room change)
147
+ */
148
+ updateRoomId(roomId) {
149
+ this.roomId = roomId;
150
+ }
151
+ }
152
+ exports.HuddleChannel = HuddleChannel;
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Huddle Types
3
+ *
4
+ * Type definitions for huddle (private conversation) functionality
5
+ */
6
+ /**
7
+ * Spatial channel ID constant
8
+ */
9
+ export declare const SPATIAL_CHANNEL_ID = "spatial";
10
+ /**
11
+ * Huddle channel ID prefix
12
+ */
13
+ export declare const HUDDLE_CHANNEL_PREFIX = "odyssey-huddle";
14
+ /**
15
+ * Check if a channel ID is a huddle channel
16
+ */
17
+ export declare function isHuddleChannel(channelId?: string): boolean;
18
+ /**
19
+ * Huddle invite data
20
+ */
21
+ export interface HuddleInvite {
22
+ inviteId: string;
23
+ fromParticipantId: string;
24
+ toParticipantId: string;
25
+ roomId: string;
26
+ huddleId?: string;
27
+ timestamp: number;
28
+ fromUserName?: string;
29
+ }
30
+ /**
31
+ * Huddle response data
32
+ */
33
+ export interface HuddleResponse {
34
+ success: boolean;
35
+ error?: string;
36
+ }
37
+ /**
38
+ * Huddle accept response
39
+ */
40
+ export interface HuddleAcceptResponse extends HuddleResponse {
41
+ huddleId?: string;
42
+ channelId?: string;
43
+ participants?: string[];
44
+ }
45
+ /**
46
+ * Huddle reject response
47
+ */
48
+ export interface HuddleRejectResponse extends HuddleResponse {
49
+ inviteId?: string;
50
+ }
51
+ /**
52
+ * Huddle started event data
53
+ */
54
+ export interface HuddleStartedEvent {
55
+ huddleId: string;
56
+ channelId: string;
57
+ participants: string[];
58
+ initiatorId: string;
59
+ }
60
+ /**
61
+ * Huddle updated event data
62
+ */
63
+ export interface HuddleUpdatedEvent {
64
+ huddleId: string;
65
+ channelId: string;
66
+ participants: string[];
67
+ action: 'joined' | 'left';
68
+ participantId: string;
69
+ }
70
+ /**
71
+ * Huddle ended event data
72
+ */
73
+ export interface HuddleEndedEvent {
74
+ huddleId: string;
75
+ channelId: string;
76
+ reason: 'all_left' | 'timeout' | 'forced';
77
+ }
78
+ /**
79
+ * Participant channel changed event data
80
+ */
81
+ export interface ParticipantChannelChangedEvent {
82
+ participantId: string;
83
+ channelId: string;
84
+ previousChannel?: string;
85
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ /**
3
+ * Huddle Types
4
+ *
5
+ * Type definitions for huddle (private conversation) functionality
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.HUDDLE_CHANNEL_PREFIX = exports.SPATIAL_CHANNEL_ID = void 0;
9
+ exports.isHuddleChannel = isHuddleChannel;
10
+ /**
11
+ * Spatial channel ID constant
12
+ */
13
+ exports.SPATIAL_CHANNEL_ID = 'spatial';
14
+ /**
15
+ * Huddle channel ID prefix
16
+ */
17
+ exports.HUDDLE_CHANNEL_PREFIX = 'odyssey-huddle';
18
+ /**
19
+ * Check if a channel ID is a huddle channel
20
+ */
21
+ function isHuddleChannel(channelId) {
22
+ if (!channelId)
23
+ return false;
24
+ return channelId !== exports.SPATIAL_CHANNEL_ID && channelId.includes('huddle');
25
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Huddle module - Re-exports huddle channel functionality
3
+ */
4
+ export * from './HuddleTypes';
5
+ export * from './HuddleChannel';
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ /**
3
+ * Huddle module - Re-exports huddle channel functionality
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
17
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ __exportStar(require("./HuddleTypes"), exports);
21
+ __exportStar(require("./HuddleChannel"), exports);
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Channels module - Re-exports all channel functionality
3
+ */
4
+ export * from './huddle';
5
+ export * from './spatial';
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ /**
3
+ * Channels module - Re-exports all channel functionality
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
17
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ __exportStar(require("./huddle"), exports);
21
+ __exportStar(require("./spatial"), exports);