@newgameplusinc/odyssey-audio-video-sdk-dev 1.0.258 → 1.0.260

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} +19 -52
  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 +476 -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} +56 -44
  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 +43 -9
  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 -271
  82. package/dist/SpatialAudioManager.js +0 -1512
  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,27 +59,15 @@ 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.
69
- const modelJson = await (await fetch(modelUrl)).json();
70
- if (modelJson.modelTopology?.config?.layers?.[0]?.config
71
- ?.batch_input_shape === undefined) {
72
- // Model JSON is missing inputShape - apply fix
73
- modelJson.modelTopology.config.layers[0].config.batch_input_shape = [
74
- null,
75
- 257,
76
- 1,
77
- 1,
78
- ];
79
- }
80
- this.model = await tf.loadLayersModel(tf.io.fromMemory(modelJson.modelTopology, modelJson.weightsManifest[0].weights));
66
+ // Load model - use standard loadLayersModel instead of fromMemory
67
+ // This handles weight loading automatically
68
+ console.log(`[MLNoiseSuppressor] Loading model from: ${modelUrl}`);
69
+ this.model = await tf.loadLayersModel(modelUrl);
70
+ console.log(`[MLNoiseSuppressor] Model loaded successfully`);
81
71
  // Load config
82
72
  const baseUrl = modelUrl.substring(0, modelUrl.lastIndexOf('/'));
83
73
  const configResponse = await fetch(`${baseUrl}/model_config.json`);
@@ -88,54 +78,43 @@ class MLNoiseSuppressor {
88
78
  this.normStats = await normResponse.json();
89
79
  }
90
80
  catch (e) {
91
- // No normalization stats found, use defaults
92
81
  this.normStats = { mean: 0, std: 1 };
93
82
  }
94
83
  this.isInitialized = true;
84
+ console.log(`[MLNoiseSuppressor] Initialization complete`);
95
85
  }
96
86
  catch (error) {
87
+ console.error(`[MLNoiseSuppressor] Initialization failed:`, error);
97
88
  throw error;
98
89
  }
99
90
  }
100
91
  /**
101
92
  * Process audio buffer through ML model
102
- * @param inputBuffer Audio samples to process
103
- * @returns Denoised audio samples
104
93
  */
105
94
  async processAudio(inputBuffer) {
106
95
  if (!this.isInitialized || !this.model || !this.config || !this.normStats) {
107
- // Not initialized, return original audio
108
96
  return inputBuffer;
109
97
  }
110
98
  try {
111
99
  return await tf.tidy(() => {
112
- // 1. Extract features (simplified mel-spectrogram approximation)
113
100
  const features = this.extractFeatures(inputBuffer);
114
- // 2. Normalize features
115
101
  const normalizedTensor = tf.tensor2d(features);
116
102
  const normalized = normalizedTensor
117
103
  .sub(this.normStats.mean)
118
104
  .div(Math.max(this.normStats.std, 1e-8));
119
- // 3. Create sequences for LSTM
120
105
  const sequences = this.createSequences(normalized);
121
- // 4. Run ML inference to get noise suppression mask
122
106
  const maskTensor = this.model.predict(sequences);
123
- // 5. Extract mask values
124
107
  const maskArray = maskTensor.dataSync();
125
- // 6. Apply temporal smoothing (critical for quality!)
126
108
  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;
109
+ return this.applyMaskToAudio(inputBuffer, smoothedMask);
130
110
  });
131
111
  }
132
112
  catch (error) {
133
- // Return original audio on error (graceful degradation)
134
113
  return inputBuffer;
135
114
  }
136
115
  }
137
116
  /**
138
- * Extract audio features (simplified mel-spectrogram approximation)
117
+ * Extract audio features
139
118
  */
140
119
  extractFeatures(audio) {
141
120
  if (!this.config)
@@ -148,18 +127,15 @@ class MLNoiseSuppressor {
148
127
  for (let i = 0; i < numFrames; i++) {
149
128
  const start = i * hopLength;
150
129
  const frame = audio.slice(start, Math.min(start + frameSize, audio.length));
151
- // Compute simplified mel bins
152
130
  const melBins = [];
153
131
  for (let j = 0; j < nMels; j++) {
154
132
  const binStart = Math.floor((j / nMels) * frame.length);
155
133
  const binEnd = Math.floor(((j + 1) / nMels) * frame.length);
156
- // Compute energy in this bin
157
134
  let energy = 0;
158
135
  for (let k = binStart; k < binEnd; k++) {
159
136
  energy += frame[k] * frame[k];
160
137
  }
161
138
  energy = Math.sqrt(energy / (binEnd - binStart));
162
- // Convert to log scale (dB-like)
163
139
  const logEnergy = Math.log10(energy + 1e-10) * 10;
164
140
  melBins.push(logEnergy);
165
141
  }
@@ -178,51 +154,42 @@ class MLNoiseSuppressor {
178
154
  const numFrames = shape[0];
179
155
  const numFeatures = shape[1];
180
156
  if (numFrames < seqLength) {
181
- // Pad if needed
182
157
  const padding = tf.zeros([seqLength - numFrames, numFeatures]);
183
158
  const padded = tf.concat([featureTensor, padding], 0);
184
159
  return padded.expandDims(0);
185
160
  }
186
- // Take the last seqLength frames
187
161
  const sequence = featureTensor.slice([numFrames - seqLength, 0], [seqLength, numFeatures]);
188
162
  return sequence.expandDims(0);
189
163
  }
190
164
  /**
191
- * Apply temporal smoothing to mask (prevents "musical noise")
165
+ * Apply temporal smoothing to mask
192
166
  */
193
167
  applyTemporalSmoothing(currentMask) {
194
168
  const smoothed = new Float32Array(currentMask.length);
195
169
  if (!this.prevMask || this.prevMask.length !== currentMask.length) {
196
- // First frame - no smoothing
197
170
  this.prevMask = new Float32Array(currentMask);
198
171
  return this.prevMask;
199
172
  }
200
- // Exponential moving average
201
173
  for (let i = 0; i < currentMask.length; i++) {
202
174
  smoothed[i] =
203
175
  this.SMOOTHING_ALPHA * currentMask[i] +
204
176
  (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
177
  smoothed[i] = Math.max(0.05, Math.min(1.0, smoothed[i]));
208
178
  }
209
179
  this.prevMask = smoothed;
210
180
  return smoothed;
211
181
  }
212
182
  /**
213
- * Apply noise suppression mask to audio with voice preservation
183
+ * Apply noise suppression mask to audio
214
184
  */
215
185
  applyMaskToAudio(audio, mask) {
216
186
  const output = new Float32Array(audio.length);
217
- // Apply mask with simple interpolation
218
187
  for (let i = 0; i < audio.length; i++) {
219
- // Map audio sample to mask index
220
188
  const maskIdx = Math.floor((i / audio.length) * mask.length);
221
189
  const gain = mask[Math.min(maskIdx, mask.length - 1)];
222
- // Apply gain with voice frequency boost
223
190
  output[i] = audio[i] * gain;
224
191
  }
225
- // Apply fade-in/out to prevent clicks at boundaries
192
+ // Fade edges
226
193
  const fadeLength = Math.min(128, output.length / 20);
227
194
  for (let i = 0; i < fadeLength; i++) {
228
195
  const fade = i / fadeLength;
@@ -234,7 +201,7 @@ class MLNoiseSuppressor {
234
201
  return output;
235
202
  }
236
203
  /**
237
- * Reset processing state (call when switching audio streams)
204
+ * Reset processing state
238
205
  */
239
206
  reset() {
240
207
  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);