vg-x07df 1.4.0 → 1.5.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/dist/index.cjs +496 -431
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +288 -59
- package/dist/index.d.ts +288 -59
- package/dist/index.mjs +496 -432
- package/dist/index.mjs.map +1 -1
- package/dist/livekit/index.cjs.map +1 -1
- package/dist/livekit/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4,9 +4,8 @@ var React = require('react');
|
|
|
4
4
|
var socket_ioClient = require('socket.io-client');
|
|
5
5
|
var zustand = require('zustand');
|
|
6
6
|
var immer = require('zustand/middleware/immer');
|
|
7
|
-
var mitt = require('mitt');
|
|
8
7
|
var zod = require('zod');
|
|
9
|
-
var
|
|
8
|
+
var mitt = require('mitt');
|
|
10
9
|
var livekitClient = require('livekit-client');
|
|
11
10
|
|
|
12
11
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -163,96 +162,6 @@ var useRtcStore = zustand.create()(
|
|
|
163
162
|
);
|
|
164
163
|
var rtcStore = useRtcStore;
|
|
165
164
|
|
|
166
|
-
// src/state/errors.ts
|
|
167
|
-
function pushError(code, message, context, logger5) {
|
|
168
|
-
const error = {
|
|
169
|
-
code,
|
|
170
|
-
message,
|
|
171
|
-
timestamp: Date.now(),
|
|
172
|
-
context
|
|
173
|
-
};
|
|
174
|
-
logger5?.("error", message, { code, context });
|
|
175
|
-
rtcStore.getState().addError(error);
|
|
176
|
-
}
|
|
177
|
-
function clearErrors(predicate) {
|
|
178
|
-
rtcStore.getState().patch((state) => {
|
|
179
|
-
if (predicate) {
|
|
180
|
-
state.errors = state.errors.filter((error) => !predicate(error));
|
|
181
|
-
} else {
|
|
182
|
-
state.errors = [];
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
function pushSocketValidationError(eventType, issues, payload, logger5) {
|
|
187
|
-
pushError(
|
|
188
|
-
"SOCKET_PAYLOAD",
|
|
189
|
-
`Invalid ${eventType} event payload`,
|
|
190
|
-
{ eventType, issues, payload },
|
|
191
|
-
logger5
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
function pushIdentityGuardError(reason, expected, received, logger5) {
|
|
195
|
-
pushError(
|
|
196
|
-
"JOIN_FLOW",
|
|
197
|
-
// Use new error code
|
|
198
|
-
`Identity guard failed: ${reason}`,
|
|
199
|
-
{ expected, received },
|
|
200
|
-
logger5
|
|
201
|
-
);
|
|
202
|
-
}
|
|
203
|
-
function pushLiveKitConnectError(message, error, logger5) {
|
|
204
|
-
pushError(
|
|
205
|
-
"LIVEKIT_CONNECT",
|
|
206
|
-
`LiveKit connection failed: ${message}`,
|
|
207
|
-
{ originalError: error },
|
|
208
|
-
logger5
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
function pushStaleEventError(eventType, reason, context, logger5) {
|
|
212
|
-
pushError(
|
|
213
|
-
"JOIN_FLOW",
|
|
214
|
-
// Use new error code
|
|
215
|
-
`Ignored stale ${eventType} event: ${reason}`,
|
|
216
|
-
context,
|
|
217
|
-
logger5
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
function pushApiError(operation, error, logger5) {
|
|
221
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
222
|
-
pushError(
|
|
223
|
-
"API_ERROR",
|
|
224
|
-
`API ${operation} failed: ${errorMessage}`,
|
|
225
|
-
{ operation, originalError: error },
|
|
226
|
-
logger5
|
|
227
|
-
);
|
|
228
|
-
}
|
|
229
|
-
function pushNetworkError(operation, error, logger5) {
|
|
230
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
231
|
-
pushError(
|
|
232
|
-
"NETWORK",
|
|
233
|
-
`Network error during ${operation}: ${errorMessage}`,
|
|
234
|
-
{ operation, originalError: error },
|
|
235
|
-
logger5
|
|
236
|
-
);
|
|
237
|
-
}
|
|
238
|
-
function pushMediaPermissionError(device, error, logger5) {
|
|
239
|
-
pushError(
|
|
240
|
-
"MEDIA_PERMISSION",
|
|
241
|
-
`${device} permission denied`,
|
|
242
|
-
{ device, originalError: error },
|
|
243
|
-
logger5
|
|
244
|
-
);
|
|
245
|
-
}
|
|
246
|
-
function pushDeviceError(operation, device, error, logger5) {
|
|
247
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
248
|
-
pushError(
|
|
249
|
-
"DEVICE_SWITCH",
|
|
250
|
-
`Failed to ${operation} ${device}: ${errorMessage}`,
|
|
251
|
-
{ operation, device, originalError: error },
|
|
252
|
-
logger5
|
|
253
|
-
);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
165
|
// src/core/socketio/handlers/base.handler.ts
|
|
257
166
|
var BaseSocketHandler = class {
|
|
258
167
|
constructor(options = {}) {
|
|
@@ -266,37 +175,8 @@ var BaseSocketHandler = class {
|
|
|
266
175
|
}
|
|
267
176
|
async handleRaw(rawData) {
|
|
268
177
|
this.logger.info(`${this.eventName} received`, rawData);
|
|
269
|
-
const result = this.schema.safeParse(rawData);
|
|
270
|
-
if (!result.success) {
|
|
271
|
-
this.logger.error(
|
|
272
|
-
`${this.eventName} validation failed`,
|
|
273
|
-
result.error.issues
|
|
274
|
-
);
|
|
275
|
-
pushSocketValidationError(
|
|
276
|
-
this.eventName,
|
|
277
|
-
result.error.issues,
|
|
278
|
-
rawData,
|
|
279
|
-
(level, message, meta) => {
|
|
280
|
-
switch (level) {
|
|
281
|
-
case "debug":
|
|
282
|
-
this.logger.debug(message, meta);
|
|
283
|
-
break;
|
|
284
|
-
case "info":
|
|
285
|
-
this.logger.info(message, meta);
|
|
286
|
-
break;
|
|
287
|
-
case "warn":
|
|
288
|
-
this.logger.warn(message, meta);
|
|
289
|
-
break;
|
|
290
|
-
case "error":
|
|
291
|
-
this.logger.error(message, meta);
|
|
292
|
-
break;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
);
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
298
178
|
try {
|
|
299
|
-
await this.handle(
|
|
179
|
+
await this.handle(JSON.parse(JSON.stringify(rawData)));
|
|
300
180
|
this.logger.debug(`${this.eventName} handled successfully`);
|
|
301
181
|
} catch (error) {
|
|
302
182
|
this.logger.error(`${this.eventName} handler error`, error);
|
|
@@ -310,52 +190,6 @@ var BaseSocketHandler = class {
|
|
|
310
190
|
return this.options.livekit;
|
|
311
191
|
}
|
|
312
192
|
};
|
|
313
|
-
var EventBus = class {
|
|
314
|
-
constructor() {
|
|
315
|
-
this.emitter = mitt__default.default();
|
|
316
|
-
}
|
|
317
|
-
on(eventType, handler) {
|
|
318
|
-
const wrappedHandler = (event) => {
|
|
319
|
-
handler(event);
|
|
320
|
-
};
|
|
321
|
-
this.emitter.on(eventType.toString(), wrappedHandler);
|
|
322
|
-
return {
|
|
323
|
-
unsubscribe: () => {
|
|
324
|
-
this.emitter.off(eventType.toString(), wrappedHandler);
|
|
325
|
-
}
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
emit(eventType, payload) {
|
|
329
|
-
const event = {
|
|
330
|
-
type: eventType.toString(),
|
|
331
|
-
payload,
|
|
332
|
-
timestamp: Date.now()
|
|
333
|
-
};
|
|
334
|
-
this.emitter.emit(eventType.toString(), event);
|
|
335
|
-
}
|
|
336
|
-
off(eventType) {
|
|
337
|
-
this.emitter.off(eventType.toString());
|
|
338
|
-
}
|
|
339
|
-
removeAllListeners() {
|
|
340
|
-
this.emitter.all.clear();
|
|
341
|
-
}
|
|
342
|
-
};
|
|
343
|
-
var eventBus = new EventBus();
|
|
344
|
-
|
|
345
|
-
// src/core/events/types.ts
|
|
346
|
-
var SdkEventType = /* @__PURE__ */ ((SdkEventType2) => {
|
|
347
|
-
SdkEventType2["CALL_INITIATED"] = "call:initiated";
|
|
348
|
-
SdkEventType2["CALL_INCOMING"] = "call:incoming";
|
|
349
|
-
SdkEventType2["CALL_DECLINED"] = "call:declined";
|
|
350
|
-
SdkEventType2["CALL_ENDED"] = "call:ended";
|
|
351
|
-
SdkEventType2["CALL_CANCELED"] = "call:canceled";
|
|
352
|
-
SdkEventType2["CALL_TIMEOUT"] = "call:timeout";
|
|
353
|
-
SdkEventType2["JOIN_INFO_RECEIVED"] = "join-info:received";
|
|
354
|
-
SdkEventType2["CALL_STARTED"] = "call:started";
|
|
355
|
-
SdkEventType2["PARTICIPANT_UPDATED"] = "participant:updated";
|
|
356
|
-
SdkEventType2["PARTICIPANT_INVITED"] = "participant:invited";
|
|
357
|
-
return SdkEventType2;
|
|
358
|
-
})(SdkEventType || {});
|
|
359
193
|
var callCancelledSchema = zod.z.object({
|
|
360
194
|
callId: zod.z.string(),
|
|
361
195
|
status: zod.z.literal("cancelled"),
|
|
@@ -372,7 +206,7 @@ var callCreatedSchema = zod.z.object({
|
|
|
372
206
|
username: zod.z.string().nullable(),
|
|
373
207
|
email: zod.z.string().nullable(),
|
|
374
208
|
profilePhoto: zod.z.string().nullable(),
|
|
375
|
-
userId: zod.z.string()
|
|
209
|
+
userId: zod.z.union([zod.z.string(), zod.z.number()])
|
|
376
210
|
}).strict(),
|
|
377
211
|
participants: zod.z.array(zod.z.object({
|
|
378
212
|
firstName: zod.z.string().nullable(),
|
|
@@ -380,7 +214,7 @@ var callCreatedSchema = zod.z.object({
|
|
|
380
214
|
username: zod.z.string().nullable(),
|
|
381
215
|
email: zod.z.string().nullable(),
|
|
382
216
|
profilePhoto: zod.z.string().nullable(),
|
|
383
|
-
userId: zod.z.string()
|
|
217
|
+
userId: zod.z.union([zod.z.string(), zod.z.number()])
|
|
384
218
|
}).strict())
|
|
385
219
|
}).strict();
|
|
386
220
|
var callEndedSchema = zod.z.object({
|
|
@@ -391,6 +225,7 @@ var callEndedSchema = zod.z.object({
|
|
|
391
225
|
}).strict();
|
|
392
226
|
var callInviteSchema = zod.z.object({
|
|
393
227
|
callId: zod.z.string(),
|
|
228
|
+
inviteId: zod.z.string(),
|
|
394
229
|
status: zod.z.enum(["pending", "ready", "active", "ended"]),
|
|
395
230
|
caller: zod.z.object({
|
|
396
231
|
firstName: zod.z.string().nullable(),
|
|
@@ -398,7 +233,7 @@ var callInviteSchema = zod.z.object({
|
|
|
398
233
|
username: zod.z.string().nullable(),
|
|
399
234
|
email: zod.z.string().nullable(),
|
|
400
235
|
profilePhoto: zod.z.string().nullable(),
|
|
401
|
-
userId: zod.z.string()
|
|
236
|
+
userId: zod.z.union([zod.z.string(), zod.z.number()])
|
|
402
237
|
}).strict(),
|
|
403
238
|
mode: zod.z.enum(["VIDEO", "AUDIO"])
|
|
404
239
|
}).strict();
|
|
@@ -411,7 +246,7 @@ var callInviteAcceptedSchema = zod.z.object({
|
|
|
411
246
|
username: zod.z.string().nullable(),
|
|
412
247
|
email: zod.z.string().nullable(),
|
|
413
248
|
profilePhoto: zod.z.string().nullable(),
|
|
414
|
-
userId: zod.z.string()
|
|
249
|
+
userId: zod.z.union([zod.z.string(), zod.z.number()])
|
|
415
250
|
}).strict(),
|
|
416
251
|
acceptedAt: zod.z.string()
|
|
417
252
|
}).strict();
|
|
@@ -431,7 +266,7 @@ var callInviteDeclinedSchema = zod.z.object({
|
|
|
431
266
|
username: zod.z.string().nullable(),
|
|
432
267
|
email: zod.z.string().nullable(),
|
|
433
268
|
profilePhoto: zod.z.string().nullable(),
|
|
434
|
-
userId: zod.z.string()
|
|
269
|
+
userId: zod.z.union([zod.z.string(), zod.z.number()])
|
|
435
270
|
}).strict(),
|
|
436
271
|
reason: zod.z.string().optional(),
|
|
437
272
|
declinedAt: zod.z.string()
|
|
@@ -445,7 +280,7 @@ var callInviteMissedSchema = zod.z.object({
|
|
|
445
280
|
username: zod.z.string().nullable(),
|
|
446
281
|
email: zod.z.string().nullable(),
|
|
447
282
|
profilePhoto: zod.z.string().nullable(),
|
|
448
|
-
userId: zod.z.string()
|
|
283
|
+
userId: zod.z.union([zod.z.string(), zod.z.number()])
|
|
449
284
|
}).strict(),
|
|
450
285
|
missedAt: zod.z.string()
|
|
451
286
|
}).strict();
|
|
@@ -457,7 +292,7 @@ var callInviteSentSchema = zod.z.object({
|
|
|
457
292
|
username: zod.z.string().nullable(),
|
|
458
293
|
email: zod.z.string().nullable(),
|
|
459
294
|
profilePhoto: zod.z.string().nullable(),
|
|
460
|
-
userId: zod.z.string()
|
|
295
|
+
userId: zod.z.union([zod.z.string(), zod.z.number()])
|
|
461
296
|
}).strict(),
|
|
462
297
|
status: zod.z.literal("sent")
|
|
463
298
|
}).strict();
|
|
@@ -488,6 +323,22 @@ var callParticipantAddedSchema = zod.z.object({
|
|
|
488
323
|
joinState: zod.z.enum(["not_joined", "joined"])
|
|
489
324
|
}).strict()
|
|
490
325
|
}).strict();
|
|
326
|
+
var callReadySchema = zod.z.object({
|
|
327
|
+
callId: zod.z.string(),
|
|
328
|
+
status: zod.z.literal("ready"),
|
|
329
|
+
participant: zod.z.object({
|
|
330
|
+
firstName: zod.z.string().nullable(),
|
|
331
|
+
lastName: zod.z.string().nullable(),
|
|
332
|
+
username: zod.z.string().nullable(),
|
|
333
|
+
email: zod.z.string().nullable(),
|
|
334
|
+
profilePhoto: zod.z.string().nullable(),
|
|
335
|
+
userId: zod.z.union([zod.z.string(), zod.z.number()])
|
|
336
|
+
}).strict(),
|
|
337
|
+
joinInfo: zod.z.object({
|
|
338
|
+
token: zod.z.string(),
|
|
339
|
+
lkUrl: zod.z.string()
|
|
340
|
+
}).strict()
|
|
341
|
+
}).strict();
|
|
491
342
|
var callRoomStartedSchema = zod.z.object({
|
|
492
343
|
callId: zod.z.string(),
|
|
493
344
|
roomName: zod.z.string(),
|
|
@@ -495,103 +346,294 @@ var callRoomStartedSchema = zod.z.object({
|
|
|
495
346
|
status: zod.z.literal("active")
|
|
496
347
|
}).strict();
|
|
497
348
|
|
|
498
|
-
// src/
|
|
499
|
-
|
|
349
|
+
// src/state/errors.ts
|
|
350
|
+
function pushError(code, message, context, logger4) {
|
|
351
|
+
const error = {
|
|
352
|
+
code,
|
|
353
|
+
message,
|
|
354
|
+
timestamp: Date.now(),
|
|
355
|
+
context
|
|
356
|
+
};
|
|
357
|
+
logger4?.("error", message, { code, context });
|
|
358
|
+
rtcStore.getState().addError(error);
|
|
359
|
+
}
|
|
360
|
+
function clearErrors(predicate) {
|
|
361
|
+
rtcStore.getState().patch((state) => {
|
|
362
|
+
if (predicate) {
|
|
363
|
+
state.errors = state.errors.filter((error) => !predicate(error));
|
|
364
|
+
} else {
|
|
365
|
+
state.errors = [];
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
function pushSocketValidationError(eventType, issues, payload, logger4) {
|
|
370
|
+
pushError(
|
|
371
|
+
"SOCKET_PAYLOAD",
|
|
372
|
+
`Invalid ${eventType} event payload`,
|
|
373
|
+
{ eventType, issues, payload },
|
|
374
|
+
logger4
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
function pushIdentityGuardError(reason, expected, received, logger4) {
|
|
378
|
+
pushError(
|
|
379
|
+
"JOIN_FLOW",
|
|
380
|
+
// Use new error code
|
|
381
|
+
`Identity guard failed: ${reason}`,
|
|
382
|
+
{ expected, received },
|
|
383
|
+
logger4
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
function pushLiveKitConnectError(message, error, logger4) {
|
|
387
|
+
pushError(
|
|
388
|
+
"LIVEKIT_CONNECT",
|
|
389
|
+
`LiveKit connection failed: ${message}`,
|
|
390
|
+
{ originalError: error },
|
|
391
|
+
logger4
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
function pushStaleEventError(eventType, reason, context, logger4) {
|
|
395
|
+
pushError(
|
|
396
|
+
"JOIN_FLOW",
|
|
397
|
+
// Use new error code
|
|
398
|
+
`Ignored stale ${eventType} event: ${reason}`,
|
|
399
|
+
context,
|
|
400
|
+
logger4
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
function pushApiError(operation, error, logger4) {
|
|
404
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
405
|
+
pushError(
|
|
406
|
+
"API_ERROR",
|
|
407
|
+
`API ${operation} failed: ${errorMessage}`,
|
|
408
|
+
{ operation, originalError: error },
|
|
409
|
+
logger4
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
function pushNetworkError(operation, error, logger4) {
|
|
413
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
414
|
+
pushError(
|
|
415
|
+
"NETWORK",
|
|
416
|
+
`Network error during ${operation}: ${errorMessage}`,
|
|
417
|
+
{ operation, originalError: error },
|
|
418
|
+
logger4
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
function pushMediaPermissionError(device, error, logger4) {
|
|
422
|
+
pushError(
|
|
423
|
+
"MEDIA_PERMISSION",
|
|
424
|
+
`${device} permission denied`,
|
|
425
|
+
{ device, originalError: error },
|
|
426
|
+
logger4
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
function pushDeviceError(operation, device, error, logger4) {
|
|
430
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
431
|
+
pushError(
|
|
432
|
+
"DEVICE_SWITCH",
|
|
433
|
+
`Failed to ${operation} ${device}: ${errorMessage}`,
|
|
434
|
+
{ operation, device, originalError: error },
|
|
435
|
+
logger4
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
var EventBus = class {
|
|
439
|
+
constructor() {
|
|
440
|
+
this.emitter = mitt__default.default();
|
|
441
|
+
}
|
|
442
|
+
on(eventType, handler) {
|
|
443
|
+
const wrappedHandler = (event) => {
|
|
444
|
+
handler(event);
|
|
445
|
+
};
|
|
446
|
+
this.emitter.on(eventType.toString(), wrappedHandler);
|
|
447
|
+
return {
|
|
448
|
+
unsubscribe: () => {
|
|
449
|
+
this.emitter.off(eventType.toString(), wrappedHandler);
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
emit(eventType, payload) {
|
|
454
|
+
const event = {
|
|
455
|
+
type: eventType.toString(),
|
|
456
|
+
payload,
|
|
457
|
+
timestamp: Date.now()
|
|
458
|
+
};
|
|
459
|
+
this.emitter.emit(eventType.toString(), event);
|
|
460
|
+
}
|
|
461
|
+
off(eventType) {
|
|
462
|
+
this.emitter.off(eventType.toString());
|
|
463
|
+
}
|
|
464
|
+
removeAllListeners() {
|
|
465
|
+
this.emitter.all.clear();
|
|
466
|
+
}
|
|
467
|
+
};
|
|
468
|
+
var eventBus = new EventBus();
|
|
469
|
+
|
|
470
|
+
// src/core/events/types.ts
|
|
471
|
+
var SdkEventType = /* @__PURE__ */ ((SdkEventType2) => {
|
|
472
|
+
SdkEventType2["CALL_INITIATED"] = "call:initiated";
|
|
473
|
+
SdkEventType2["CALL_INCOMING"] = "call:incoming";
|
|
474
|
+
SdkEventType2["CALL_DECLINED"] = "call:declined";
|
|
475
|
+
SdkEventType2["CALL_ENDED"] = "call:ended";
|
|
476
|
+
SdkEventType2["CALL_CANCELED"] = "call:canceled";
|
|
477
|
+
SdkEventType2["CALL_TIMEOUT"] = "call:timeout";
|
|
478
|
+
SdkEventType2["JOIN_INFO_RECEIVED"] = "join-info:received";
|
|
479
|
+
SdkEventType2["CALL_STARTED"] = "call:started";
|
|
480
|
+
SdkEventType2["PARTICIPANT_UPDATED"] = "participant:updated";
|
|
481
|
+
SdkEventType2["PARTICIPANT_INVITED"] = "participant:invited";
|
|
482
|
+
return SdkEventType2;
|
|
483
|
+
})(SdkEventType || {});
|
|
484
|
+
|
|
485
|
+
// src/core/socketio/handlers/call-cancelled.handler.ts
|
|
486
|
+
var SessionCancelledHandler = class extends BaseSocketHandler {
|
|
500
487
|
constructor() {
|
|
501
488
|
super(...arguments);
|
|
502
|
-
this.eventName = "call:
|
|
503
|
-
this.schema =
|
|
489
|
+
this.eventName = "call:cancelled";
|
|
490
|
+
this.schema = callCancelledSchema;
|
|
504
491
|
}
|
|
505
492
|
handle(data) {
|
|
506
|
-
|
|
493
|
+
const currentState = rtcStore.getState();
|
|
494
|
+
this.logger.info("Call session cancelled", {
|
|
507
495
|
callId: data.callId,
|
|
508
|
-
|
|
509
|
-
mode: data.mode
|
|
496
|
+
status: data.status
|
|
510
497
|
});
|
|
498
|
+
if (currentState.session?.id !== data.callId) {
|
|
499
|
+
pushStaleEventError("call:cancelled", "callId mismatch", {
|
|
500
|
+
eventCallId: data.callId,
|
|
501
|
+
sessionCallId: currentState.session?.id
|
|
502
|
+
});
|
|
503
|
+
this.logger.warn("Ignoring cancel event for different call", {
|
|
504
|
+
callId: data.callId
|
|
505
|
+
});
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
511
508
|
this.updateStore((state) => {
|
|
512
|
-
state.
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
509
|
+
state.initiated = false;
|
|
510
|
+
state.session = null;
|
|
511
|
+
state.outgoingInvites = {};
|
|
512
|
+
state.room.participants = {};
|
|
513
|
+
});
|
|
514
|
+
eventBus.emit("call:canceled" /* CALL_CANCELED */, {
|
|
515
|
+
callId: data.callId,
|
|
516
|
+
reason: "cancelled by host",
|
|
517
|
+
timestamp: Date.now()
|
|
518
|
+
});
|
|
519
|
+
this.logger.debug("Session cleared due to cancellation");
|
|
520
|
+
}
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
// src/core/socketio/handlers/call-created.handler.ts
|
|
524
|
+
var SessionCreatedHandler = class extends BaseSocketHandler {
|
|
525
|
+
constructor() {
|
|
526
|
+
super(...arguments);
|
|
527
|
+
this.eventName = "call:created";
|
|
528
|
+
this.schema = callCreatedSchema;
|
|
529
|
+
}
|
|
530
|
+
handle(data) {
|
|
531
|
+
this.logger.info("Call session created", {
|
|
532
|
+
callId: data.callId,
|
|
533
|
+
roomName: data.roomName,
|
|
534
|
+
host: data.host.userId,
|
|
535
|
+
participantCount: data.participants.length
|
|
536
|
+
});
|
|
537
|
+
this.updateStore((state) => {
|
|
538
|
+
state.initiated = true;
|
|
524
539
|
state.session = {
|
|
525
540
|
id: data.callId,
|
|
526
541
|
status: "pending",
|
|
527
|
-
mode:
|
|
528
|
-
role: "
|
|
542
|
+
mode: "VIDEO",
|
|
543
|
+
role: "HOST"
|
|
529
544
|
};
|
|
545
|
+
state.outgoingInvites = {};
|
|
530
546
|
});
|
|
531
|
-
eventBus.emit("call:
|
|
547
|
+
eventBus.emit("call:initiated" /* CALL_INITIATED */, {
|
|
532
548
|
callId: data.callId,
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
lastName: data.caller.lastName,
|
|
537
|
-
avatarUrl: data.caller.profilePhoto
|
|
538
|
-
},
|
|
539
|
-
type: data.mode,
|
|
549
|
+
participants: data.participants.map((p) => p.userId),
|
|
550
|
+
type: "VIDEO",
|
|
551
|
+
// Default, TODO: get from API request context
|
|
540
552
|
timestamp: Date.now()
|
|
541
553
|
});
|
|
542
|
-
this.logger.debug("
|
|
554
|
+
this.logger.debug("Session created for outbound call");
|
|
543
555
|
}
|
|
544
556
|
};
|
|
545
557
|
|
|
546
|
-
// src/core/socketio/handlers/
|
|
547
|
-
var
|
|
558
|
+
// src/core/socketio/handlers/call-ended.handler.ts
|
|
559
|
+
var SessionEndedHandler = class extends BaseSocketHandler {
|
|
548
560
|
constructor() {
|
|
549
561
|
super(...arguments);
|
|
550
|
-
this.eventName = "call:
|
|
551
|
-
this.schema =
|
|
562
|
+
this.eventName = "call:ended";
|
|
563
|
+
this.schema = callEndedSchema;
|
|
552
564
|
}
|
|
553
565
|
handle(data) {
|
|
554
566
|
const currentState = rtcStore.getState();
|
|
555
|
-
this.logger.info("
|
|
567
|
+
this.logger.info("Call session ended", {
|
|
556
568
|
callId: data.callId,
|
|
557
|
-
|
|
569
|
+
endedBy: data.endedByUserId,
|
|
570
|
+
reason: data.reason
|
|
558
571
|
});
|
|
559
572
|
if (currentState.session?.id !== data.callId) {
|
|
560
|
-
pushStaleEventError("call:
|
|
573
|
+
pushStaleEventError("call:ended", "callId mismatch", {
|
|
561
574
|
eventCallId: data.callId,
|
|
562
575
|
sessionCallId: currentState.session?.id
|
|
563
576
|
});
|
|
564
|
-
this.logger.warn("Ignoring
|
|
577
|
+
this.logger.warn("Ignoring end event for different call", {
|
|
578
|
+
callId: data.callId
|
|
579
|
+
});
|
|
565
580
|
return;
|
|
566
581
|
}
|
|
567
582
|
this.updateStore((state) => {
|
|
568
|
-
|
|
569
|
-
state.
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
participant: {
|
|
573
|
-
userId: data.invitee.userId,
|
|
574
|
-
firstName: data.invitee.firstName,
|
|
575
|
-
lastName: data.invitee.lastName,
|
|
576
|
-
username: data.invitee.username,
|
|
577
|
-
email: data.invitee.email,
|
|
578
|
-
profilePhoto: data.invitee.profilePhoto
|
|
579
|
-
}
|
|
580
|
-
};
|
|
583
|
+
state.initiated = false;
|
|
584
|
+
state.session = null;
|
|
585
|
+
state.outgoingInvites = {};
|
|
586
|
+
state.room.participants = {};
|
|
581
587
|
});
|
|
582
|
-
|
|
588
|
+
if (this.livekit) {
|
|
589
|
+
this.livekit.disconnect().catch((error) => {
|
|
590
|
+
this.logger.error("Error disconnecting from LiveKit", { error });
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
eventBus.emit("call:ended" /* CALL_ENDED */, {
|
|
583
594
|
callId: data.callId,
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
firstName: data.invitee.firstName,
|
|
587
|
-
lastName: data.invitee.lastName,
|
|
588
|
-
avatarUrl: data.invitee.profilePhoto
|
|
589
|
-
},
|
|
595
|
+
endedBy: data.endedByUserId,
|
|
596
|
+
reason: "user",
|
|
590
597
|
timestamp: Date.now()
|
|
591
598
|
});
|
|
592
|
-
this.logger.debug("
|
|
593
|
-
|
|
599
|
+
this.logger.debug("Session cleared and LiveKit disconnected");
|
|
600
|
+
}
|
|
601
|
+
};
|
|
602
|
+
|
|
603
|
+
// src/core/socketio/handlers/call-missed.handler.ts
|
|
604
|
+
var SessionMissedHandler = class extends BaseSocketHandler {
|
|
605
|
+
constructor() {
|
|
606
|
+
super(...arguments);
|
|
607
|
+
this.eventName = "call:missed";
|
|
608
|
+
this.schema = callMissedSchema;
|
|
609
|
+
}
|
|
610
|
+
handle(data) {
|
|
611
|
+
const currentState = rtcStore.getState();
|
|
612
|
+
this.logger.info("Call missed by all participants", {
|
|
613
|
+
callId: data.callId
|
|
594
614
|
});
|
|
615
|
+
if (currentState.session?.id !== data.callId) {
|
|
616
|
+
pushStaleEventError("call:missed", "callId mismatch", {
|
|
617
|
+
eventCallId: data.callId,
|
|
618
|
+
sessionCallId: currentState.session?.id
|
|
619
|
+
});
|
|
620
|
+
this.logger.warn("Ignoring missed call for different session", {
|
|
621
|
+
callId: data.callId
|
|
622
|
+
});
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
this.updateStore((state) => {
|
|
626
|
+
state.initiated = false;
|
|
627
|
+
state.session = null;
|
|
628
|
+
state.outgoingInvites = {};
|
|
629
|
+
state.room.participants = {};
|
|
630
|
+
});
|
|
631
|
+
eventBus.emit("call:timeout" /* CALL_TIMEOUT */, {
|
|
632
|
+
callId: data.callId,
|
|
633
|
+
reason: "All participants missed/declined",
|
|
634
|
+
timestamp: Date.now()
|
|
635
|
+
});
|
|
636
|
+
this.logger.debug("Session cleared - call was missed by all");
|
|
595
637
|
}
|
|
596
638
|
};
|
|
597
639
|
|
|
@@ -613,13 +655,16 @@ var InviteAcceptedHandler = class extends BaseSocketHandler {
|
|
|
613
655
|
eventCallId: data.callId,
|
|
614
656
|
sessionCallId: currentState.session?.id
|
|
615
657
|
});
|
|
616
|
-
this.logger.warn("Ignoring accept event for different call", {
|
|
658
|
+
this.logger.warn("Ignoring accept event for different call", {
|
|
659
|
+
callId: data.callId
|
|
660
|
+
});
|
|
617
661
|
return;
|
|
618
662
|
}
|
|
619
663
|
this.updateStore((state) => {
|
|
620
664
|
if (state.session && data.status) {
|
|
621
665
|
state.session.status = data.status;
|
|
622
666
|
}
|
|
667
|
+
console.log("state.session.status", state.session.status, data.status);
|
|
623
668
|
const userId = data.participant.userId;
|
|
624
669
|
if (state.outgoingInvites[userId]) {
|
|
625
670
|
state.outgoingInvites[userId].status = "accepted";
|
|
@@ -644,6 +689,39 @@ var InviteAcceptedHandler = class extends BaseSocketHandler {
|
|
|
644
689
|
}
|
|
645
690
|
};
|
|
646
691
|
|
|
692
|
+
// src/core/socketio/handlers/invite-cancelled.handler.ts
|
|
693
|
+
var InviteCancelledHandler = class extends BaseSocketHandler {
|
|
694
|
+
constructor() {
|
|
695
|
+
super(...arguments);
|
|
696
|
+
this.eventName = "call:inviteCancelled";
|
|
697
|
+
this.schema = callInviteCancelledSchema;
|
|
698
|
+
}
|
|
699
|
+
handle(data) {
|
|
700
|
+
const currentState = rtcStore.getState();
|
|
701
|
+
this.logger.info("Invitation cancelled by host", {
|
|
702
|
+
callId: data.callId,
|
|
703
|
+
cancelledBy: data.cancelledByUserId,
|
|
704
|
+
reason: data.reason
|
|
705
|
+
});
|
|
706
|
+
if (currentState.incomingInvite?.callId !== data.callId) {
|
|
707
|
+
this.logger.debug("Ignoring cancelled invite for different call", {
|
|
708
|
+
callId: data.callId
|
|
709
|
+
});
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
this.updateStore((state) => {
|
|
713
|
+
state.incomingInvite = null;
|
|
714
|
+
state.session = null;
|
|
715
|
+
});
|
|
716
|
+
eventBus.emit("call:canceled" /* CALL_CANCELED */, {
|
|
717
|
+
callId: data.callId,
|
|
718
|
+
reason: data.reason,
|
|
719
|
+
timestamp: Date.now()
|
|
720
|
+
});
|
|
721
|
+
this.logger.debug("Incoming invite cleared due to cancellation");
|
|
722
|
+
}
|
|
723
|
+
};
|
|
724
|
+
|
|
647
725
|
// src/core/socketio/handlers/invite-declined.handler.ts
|
|
648
726
|
var InviteDeclinedHandler = class extends BaseSocketHandler {
|
|
649
727
|
constructor() {
|
|
@@ -663,7 +741,9 @@ var InviteDeclinedHandler = class extends BaseSocketHandler {
|
|
|
663
741
|
eventCallId: data.callId,
|
|
664
742
|
sessionCallId: currentState.session?.id
|
|
665
743
|
});
|
|
666
|
-
this.logger.warn("Ignoring decline event for different call", {
|
|
744
|
+
this.logger.warn("Ignoring decline event for different call", {
|
|
745
|
+
callId: data.callId
|
|
746
|
+
});
|
|
667
747
|
return;
|
|
668
748
|
}
|
|
669
749
|
this.updateStore((state) => {
|
|
@@ -715,7 +795,9 @@ var InviteMissedHandler = class extends BaseSocketHandler {
|
|
|
715
795
|
eventCallId: data.callId,
|
|
716
796
|
sessionCallId: currentState.session?.id
|
|
717
797
|
});
|
|
718
|
-
this.logger.warn("Ignoring missed invite for different call", {
|
|
798
|
+
this.logger.warn("Ignoring missed invite for different call", {
|
|
799
|
+
callId: data.callId
|
|
800
|
+
});
|
|
719
801
|
return;
|
|
720
802
|
}
|
|
721
803
|
this.updateStore((state) => {
|
|
@@ -743,185 +825,111 @@ var InviteMissedHandler = class extends BaseSocketHandler {
|
|
|
743
825
|
}
|
|
744
826
|
};
|
|
745
827
|
|
|
746
|
-
// src/core/socketio/handlers/invite-
|
|
747
|
-
var
|
|
828
|
+
// src/core/socketio/handlers/invite-sent.handler.ts
|
|
829
|
+
var InviteSentHandler = class extends BaseSocketHandler {
|
|
748
830
|
constructor() {
|
|
749
831
|
super(...arguments);
|
|
750
|
-
this.eventName = "call:
|
|
751
|
-
this.schema =
|
|
832
|
+
this.eventName = "call:inviteSent";
|
|
833
|
+
this.schema = callInviteSentSchema;
|
|
752
834
|
}
|
|
753
835
|
handle(data) {
|
|
754
836
|
const currentState = rtcStore.getState();
|
|
755
|
-
this.logger.info("Invitation
|
|
837
|
+
this.logger.info("Invitation sent to participant", {
|
|
756
838
|
callId: data.callId,
|
|
757
|
-
|
|
758
|
-
reason: data.reason
|
|
839
|
+
invitee: data.invitee.userId
|
|
759
840
|
});
|
|
760
|
-
if (currentState.
|
|
761
|
-
|
|
841
|
+
if (currentState.session?.id !== data.callId) {
|
|
842
|
+
pushStaleEventError("call:inviteSent", "callId mismatch", {
|
|
843
|
+
eventCallId: data.callId,
|
|
844
|
+
sessionCallId: currentState.session?.id
|
|
845
|
+
});
|
|
846
|
+
this.logger.warn("Ignoring invite sent for different call", {
|
|
762
847
|
callId: data.callId
|
|
763
848
|
});
|
|
764
849
|
return;
|
|
765
850
|
}
|
|
766
851
|
this.updateStore((state) => {
|
|
767
|
-
|
|
768
|
-
state.
|
|
852
|
+
const userId = data.invitee.userId;
|
|
853
|
+
state.outgoingInvites[userId] = {
|
|
854
|
+
userId,
|
|
855
|
+
status: "sent",
|
|
856
|
+
participant: {
|
|
857
|
+
userId: data.invitee.userId,
|
|
858
|
+
firstName: data.invitee.firstName,
|
|
859
|
+
lastName: data.invitee.lastName,
|
|
860
|
+
username: data.invitee.username,
|
|
861
|
+
email: data.invitee.email,
|
|
862
|
+
profilePhoto: data.invitee.profilePhoto
|
|
863
|
+
}
|
|
864
|
+
};
|
|
769
865
|
});
|
|
770
|
-
eventBus.emit("
|
|
866
|
+
eventBus.emit("participant:invited" /* PARTICIPANT_INVITED */, {
|
|
771
867
|
callId: data.callId,
|
|
772
|
-
|
|
868
|
+
participant: {
|
|
869
|
+
id: data.invitee.userId,
|
|
870
|
+
firstName: data.invitee.firstName,
|
|
871
|
+
lastName: data.invitee.lastName,
|
|
872
|
+
avatarUrl: data.invitee.profilePhoto
|
|
873
|
+
},
|
|
773
874
|
timestamp: Date.now()
|
|
774
875
|
});
|
|
775
|
-
this.logger.debug("
|
|
876
|
+
this.logger.debug("Outgoing invite tracked", {
|
|
877
|
+
userId: data.invitee.userId
|
|
878
|
+
});
|
|
776
879
|
}
|
|
777
880
|
};
|
|
778
881
|
|
|
779
|
-
// src/core/socketio/handlers/
|
|
780
|
-
var
|
|
882
|
+
// src/core/socketio/handlers/invite.handler.ts
|
|
883
|
+
var InviteHandler = class extends BaseSocketHandler {
|
|
781
884
|
constructor() {
|
|
782
885
|
super(...arguments);
|
|
783
|
-
this.eventName = "call:
|
|
784
|
-
this.schema =
|
|
886
|
+
this.eventName = "call:invite";
|
|
887
|
+
this.schema = callInviteSchema;
|
|
785
888
|
}
|
|
786
889
|
handle(data) {
|
|
787
|
-
this.logger.info("
|
|
890
|
+
this.logger.info("Incoming call invitation", {
|
|
788
891
|
callId: data.callId,
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
participantCount: data.participants.length
|
|
892
|
+
caller: data.caller.userId,
|
|
893
|
+
mode: data.mode
|
|
792
894
|
});
|
|
793
895
|
this.updateStore((state) => {
|
|
794
|
-
|
|
896
|
+
const now = /* @__PURE__ */ new Date();
|
|
897
|
+
const expiresAt = new Date(now.getTime() + 3e4);
|
|
898
|
+
state.incomingInvite = {
|
|
899
|
+
callId: data.callId,
|
|
900
|
+
inviteId: data.inviteId,
|
|
901
|
+
caller: {
|
|
902
|
+
userId: data.caller.userId,
|
|
903
|
+
role: "HOST",
|
|
904
|
+
firstName: data.caller.firstName ?? "",
|
|
905
|
+
lastName: data.caller.lastName ?? "",
|
|
906
|
+
username: data.caller.username ?? "",
|
|
907
|
+
email: data.caller.email ?? "",
|
|
908
|
+
profilePhoto: data.caller.profilePhoto ?? ""
|
|
909
|
+
},
|
|
910
|
+
mode: data.mode,
|
|
911
|
+
expiresAt: expiresAt.toISOString(),
|
|
912
|
+
expiresInMs: 3e4
|
|
913
|
+
};
|
|
795
914
|
state.session = {
|
|
796
915
|
id: data.callId,
|
|
797
916
|
status: "pending",
|
|
798
|
-
mode:
|
|
799
|
-
role: "
|
|
917
|
+
mode: data.mode,
|
|
918
|
+
role: "PARTICIPANT"
|
|
800
919
|
};
|
|
801
|
-
state.outgoingInvites = {};
|
|
802
|
-
});
|
|
803
|
-
eventBus.emit("call:initiated" /* CALL_INITIATED */, {
|
|
804
|
-
callId: data.callId,
|
|
805
|
-
participants: data.participants.map((p) => p.userId),
|
|
806
|
-
type: "VIDEO",
|
|
807
|
-
// Default, TODO: get from API request context
|
|
808
|
-
timestamp: Date.now()
|
|
809
|
-
});
|
|
810
|
-
this.logger.debug("Session created for outbound call");
|
|
811
|
-
}
|
|
812
|
-
};
|
|
813
|
-
|
|
814
|
-
// src/core/socketio/handlers/call-ended.handler.ts
|
|
815
|
-
var SessionEndedHandler = class extends BaseSocketHandler {
|
|
816
|
-
constructor() {
|
|
817
|
-
super(...arguments);
|
|
818
|
-
this.eventName = "call:ended";
|
|
819
|
-
this.schema = callEndedSchema;
|
|
820
|
-
}
|
|
821
|
-
handle(data) {
|
|
822
|
-
const currentState = rtcStore.getState();
|
|
823
|
-
this.logger.info("Call session ended", {
|
|
824
|
-
callId: data.callId,
|
|
825
|
-
endedBy: data.endedByUserId,
|
|
826
|
-
reason: data.reason
|
|
827
|
-
});
|
|
828
|
-
if (currentState.session?.id !== data.callId) {
|
|
829
|
-
pushStaleEventError("call:ended", "callId mismatch", {
|
|
830
|
-
eventCallId: data.callId,
|
|
831
|
-
sessionCallId: currentState.session?.id
|
|
832
|
-
});
|
|
833
|
-
this.logger.warn("Ignoring end event for different call", { callId: data.callId });
|
|
834
|
-
return;
|
|
835
|
-
}
|
|
836
|
-
this.updateStore((state) => {
|
|
837
|
-
state.initiated = false;
|
|
838
|
-
state.session = null;
|
|
839
|
-
state.outgoingInvites = {};
|
|
840
|
-
state.room.participants = {};
|
|
841
|
-
});
|
|
842
|
-
if (this.livekit) {
|
|
843
|
-
this.livekit.disconnect().catch((error) => {
|
|
844
|
-
this.logger.error("Error disconnecting from LiveKit", { error });
|
|
845
|
-
});
|
|
846
|
-
}
|
|
847
|
-
eventBus.emit("call:ended" /* CALL_ENDED */, {
|
|
848
|
-
callId: data.callId,
|
|
849
|
-
endedBy: data.endedByUserId,
|
|
850
|
-
reason: "user",
|
|
851
|
-
timestamp: Date.now()
|
|
852
|
-
});
|
|
853
|
-
this.logger.debug("Session cleared and LiveKit disconnected");
|
|
854
|
-
}
|
|
855
|
-
};
|
|
856
|
-
|
|
857
|
-
// src/core/socketio/handlers/call-cancelled.handler.ts
|
|
858
|
-
var SessionCancelledHandler = class extends BaseSocketHandler {
|
|
859
|
-
constructor() {
|
|
860
|
-
super(...arguments);
|
|
861
|
-
this.eventName = "call:cancelled";
|
|
862
|
-
this.schema = callCancelledSchema;
|
|
863
|
-
}
|
|
864
|
-
handle(data) {
|
|
865
|
-
const currentState = rtcStore.getState();
|
|
866
|
-
this.logger.info("Call session cancelled", {
|
|
867
|
-
callId: data.callId,
|
|
868
|
-
status: data.status
|
|
869
|
-
});
|
|
870
|
-
if (currentState.session?.id !== data.callId) {
|
|
871
|
-
pushStaleEventError("call:cancelled", "callId mismatch", {
|
|
872
|
-
eventCallId: data.callId,
|
|
873
|
-
sessionCallId: currentState.session?.id
|
|
874
|
-
});
|
|
875
|
-
this.logger.warn("Ignoring cancel event for different call", { callId: data.callId });
|
|
876
|
-
return;
|
|
877
|
-
}
|
|
878
|
-
this.updateStore((state) => {
|
|
879
|
-
state.initiated = false;
|
|
880
|
-
state.session = null;
|
|
881
|
-
state.outgoingInvites = {};
|
|
882
|
-
state.room.participants = {};
|
|
883
|
-
});
|
|
884
|
-
eventBus.emit("call:canceled" /* CALL_CANCELED */, {
|
|
885
|
-
callId: data.callId,
|
|
886
|
-
reason: "cancelled by host",
|
|
887
|
-
timestamp: Date.now()
|
|
888
|
-
});
|
|
889
|
-
this.logger.debug("Session cleared due to cancellation");
|
|
890
|
-
}
|
|
891
|
-
};
|
|
892
|
-
|
|
893
|
-
// src/core/socketio/handlers/call-missed.handler.ts
|
|
894
|
-
var SessionMissedHandler = class extends BaseSocketHandler {
|
|
895
|
-
constructor() {
|
|
896
|
-
super(...arguments);
|
|
897
|
-
this.eventName = "call:missed";
|
|
898
|
-
this.schema = callMissedSchema;
|
|
899
|
-
}
|
|
900
|
-
handle(data) {
|
|
901
|
-
const currentState = rtcStore.getState();
|
|
902
|
-
this.logger.info("Call missed by all participants", {
|
|
903
|
-
callId: data.callId
|
|
904
|
-
});
|
|
905
|
-
if (currentState.session?.id !== data.callId) {
|
|
906
|
-
pushStaleEventError("call:missed", "callId mismatch", {
|
|
907
|
-
eventCallId: data.callId,
|
|
908
|
-
sessionCallId: currentState.session?.id
|
|
909
|
-
});
|
|
910
|
-
this.logger.warn("Ignoring missed call for different session", { callId: data.callId });
|
|
911
|
-
return;
|
|
912
|
-
}
|
|
913
|
-
this.updateStore((state) => {
|
|
914
|
-
state.initiated = false;
|
|
915
|
-
state.session = null;
|
|
916
|
-
state.outgoingInvites = {};
|
|
917
|
-
state.room.participants = {};
|
|
918
920
|
});
|
|
919
|
-
eventBus.emit("call:
|
|
921
|
+
eventBus.emit("call:incoming" /* CALL_INCOMING */, {
|
|
920
922
|
callId: data.callId,
|
|
921
|
-
|
|
923
|
+
caller: {
|
|
924
|
+
id: data.caller.userId,
|
|
925
|
+
firstName: data.caller.firstName,
|
|
926
|
+
lastName: data.caller.lastName,
|
|
927
|
+
avatarUrl: data.caller.profilePhoto
|
|
928
|
+
},
|
|
929
|
+
type: data.mode,
|
|
922
930
|
timestamp: Date.now()
|
|
923
931
|
});
|
|
924
|
-
this.logger.debug("
|
|
932
|
+
this.logger.debug("Incoming invite state updated");
|
|
925
933
|
}
|
|
926
934
|
};
|
|
927
935
|
|
|
@@ -944,7 +952,9 @@ var JoinInfoHandler = class extends BaseSocketHandler {
|
|
|
944
952
|
eventCallId: data.callId,
|
|
945
953
|
sessionCallId: currentState.session?.id
|
|
946
954
|
});
|
|
947
|
-
this.logger.warn("Ignoring join info for unknown call", {
|
|
955
|
+
this.logger.warn("Ignoring join info for unknown call", {
|
|
956
|
+
callId: data.callId
|
|
957
|
+
});
|
|
948
958
|
return;
|
|
949
959
|
}
|
|
950
960
|
this.updateStore((state) => {
|
|
@@ -988,7 +998,9 @@ var ParticipantAddedHandler = class extends BaseSocketHandler {
|
|
|
988
998
|
eventCallId: data.callId,
|
|
989
999
|
sessionCallId: currentState.session?.id
|
|
990
1000
|
});
|
|
991
|
-
this.logger.warn("Ignoring participant added for different call", {
|
|
1001
|
+
this.logger.warn("Ignoring participant added for different call", {
|
|
1002
|
+
callId: data.callId
|
|
1003
|
+
});
|
|
992
1004
|
return;
|
|
993
1005
|
}
|
|
994
1006
|
this.updateStore((state) => {
|
|
@@ -1674,7 +1686,8 @@ var CallsService = class {
|
|
|
1674
1686
|
static postSignalCallsByCallIdAccept(data) {
|
|
1675
1687
|
const {
|
|
1676
1688
|
callId,
|
|
1677
|
-
appId
|
|
1689
|
+
appId,
|
|
1690
|
+
requestBody
|
|
1678
1691
|
} = data;
|
|
1679
1692
|
return request(OpenAPI, {
|
|
1680
1693
|
method: "POST",
|
|
@@ -1685,6 +1698,8 @@ var CallsService = class {
|
|
|
1685
1698
|
query: {
|
|
1686
1699
|
appId
|
|
1687
1700
|
},
|
|
1701
|
+
body: requestBody,
|
|
1702
|
+
mediaType: "application/json",
|
|
1688
1703
|
errors: {
|
|
1689
1704
|
400: `Invalid request`,
|
|
1690
1705
|
401: `Authentication required`,
|
|
@@ -1905,12 +1920,12 @@ var OpenApiConfigService = class _OpenApiConfigService {
|
|
|
1905
1920
|
if (headers instanceof Headers) {
|
|
1906
1921
|
authHeader = headers.get("Authorization") || null;
|
|
1907
1922
|
} else if (headers && typeof headers === "object") {
|
|
1908
|
-
authHeader = headers
|
|
1923
|
+
authHeader = headers.Authorization || null;
|
|
1909
1924
|
}
|
|
1910
1925
|
if (authHeader) {
|
|
1911
1926
|
logger2.debug("API Request with Authorization header", {
|
|
1912
1927
|
hasAuth: true,
|
|
1913
|
-
authPrefix: authHeader.substring(0, 20)
|
|
1928
|
+
authPrefix: `${authHeader.substring(0, 20)}...`
|
|
1914
1929
|
});
|
|
1915
1930
|
} else {
|
|
1916
1931
|
logger2.warn("API Request WITHOUT Authorization header", {
|
|
@@ -1937,7 +1952,7 @@ var OpenApiConfigService = class _OpenApiConfigService {
|
|
|
1937
1952
|
logger2.warn("Token provider returned empty token");
|
|
1938
1953
|
} else {
|
|
1939
1954
|
logger2.debug("Token resolved successfully", {
|
|
1940
|
-
tokenPrefix: token.substring(0, 10)
|
|
1955
|
+
tokenPrefix: `${token.substring(0, 10)}...`
|
|
1941
1956
|
});
|
|
1942
1957
|
}
|
|
1943
1958
|
return token;
|
|
@@ -1966,75 +1981,123 @@ var OpenApiConfigService = class _OpenApiConfigService {
|
|
|
1966
1981
|
var apiConfig = OpenApiConfigService.getInstance();
|
|
1967
1982
|
|
|
1968
1983
|
// src/services/calls.service.ts
|
|
1969
|
-
var logger3 = createLogger("calls-service");
|
|
1970
1984
|
function createCallsService(config) {
|
|
1971
1985
|
const { appId } = config;
|
|
1972
|
-
const ensureApiConfigured = () => {
|
|
1973
|
-
if (!apiConfig.isConfigured()) {
|
|
1974
|
-
logger3.error("API not configured before making call service request");
|
|
1975
|
-
throw new Error(
|
|
1976
|
-
"API configuration missing. Ensure the SDK is properly initialized."
|
|
1977
|
-
);
|
|
1978
|
-
}
|
|
1979
|
-
};
|
|
1980
1986
|
async function initiate(params) {
|
|
1981
|
-
ensureApiConfigured();
|
|
1982
1987
|
const requestBody = {
|
|
1983
|
-
|
|
1984
|
-
participants: params.invitees.map((userId) => ({ userId }))
|
|
1988
|
+
participants: params.invitees.map((userId) => ({ userId: String(userId) }))
|
|
1985
1989
|
};
|
|
1986
1990
|
if (params.callId) {
|
|
1987
1991
|
requestBody.callId = params.callId;
|
|
1992
|
+
} else {
|
|
1993
|
+
requestBody.mode = params.mode || "AUDIO";
|
|
1988
1994
|
}
|
|
1989
|
-
|
|
1995
|
+
const response = await CallsService.postSignalCallsInvite({
|
|
1990
1996
|
appId,
|
|
1991
1997
|
requestBody
|
|
1992
1998
|
});
|
|
1999
|
+
rtcStore.getState().patch((state) => {
|
|
2000
|
+
for (const participant of response.participants) {
|
|
2001
|
+
if (participant.userId) {
|
|
2002
|
+
state.outgoingInvites[participant.userId] = {
|
|
2003
|
+
userId: participant.userId,
|
|
2004
|
+
status: "sent",
|
|
2005
|
+
participant: {
|
|
2006
|
+
userId: participant.userId,
|
|
2007
|
+
role: participant.role,
|
|
2008
|
+
firstName: participant.firstName ?? "",
|
|
2009
|
+
lastName: participant.lastName ?? "",
|
|
2010
|
+
username: participant.username ?? "",
|
|
2011
|
+
email: participant.email ?? "",
|
|
2012
|
+
profilePhoto: participant.profilePhoto ?? ""
|
|
2013
|
+
}
|
|
2014
|
+
};
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
if (!params.callId) {
|
|
2018
|
+
state.initiated = true;
|
|
2019
|
+
state.session = {
|
|
2020
|
+
id: response.callId,
|
|
2021
|
+
status: response.status.toLowerCase(),
|
|
2022
|
+
mode: "AUDIO",
|
|
2023
|
+
role: "HOST"
|
|
2024
|
+
};
|
|
2025
|
+
}
|
|
2026
|
+
if (response.joinInfo && state.session) {
|
|
2027
|
+
state.session.livekitInfo = {
|
|
2028
|
+
token: response.joinInfo.token,
|
|
2029
|
+
roomName: state.session.id,
|
|
2030
|
+
url: response.joinInfo.lkUrl
|
|
2031
|
+
};
|
|
2032
|
+
}
|
|
2033
|
+
});
|
|
2034
|
+
return response;
|
|
1993
2035
|
}
|
|
1994
|
-
async function accept(
|
|
1995
|
-
|
|
1996
|
-
|
|
2036
|
+
async function accept() {
|
|
2037
|
+
const currentState = rtcStore.getState();
|
|
2038
|
+
if (!currentState.incomingInvite) {
|
|
2039
|
+
throw new Error("No incoming invite to accept");
|
|
2040
|
+
}
|
|
2041
|
+
const { callId, inviteId } = currentState.incomingInvite;
|
|
2042
|
+
rtcStore.getState().patch((state) => {
|
|
1997
2043
|
state.incomingInvite = null;
|
|
1998
2044
|
});
|
|
1999
|
-
|
|
2045
|
+
const response = await CallsService.postSignalCallsByCallIdAccept({
|
|
2000
2046
|
callId,
|
|
2001
|
-
appId
|
|
2047
|
+
appId,
|
|
2048
|
+
requestBody: {
|
|
2049
|
+
inviteId
|
|
2050
|
+
}
|
|
2051
|
+
});
|
|
2052
|
+
rtcStore.getState().patch((state) => {
|
|
2053
|
+
if (response.joinInfo && state.session) {
|
|
2054
|
+
state.session.status = "ready";
|
|
2055
|
+
state.session.livekitInfo = {
|
|
2056
|
+
token: response.joinInfo.token,
|
|
2057
|
+
roomName: state.session.id,
|
|
2058
|
+
url: response.joinInfo.lkUrl
|
|
2059
|
+
};
|
|
2060
|
+
}
|
|
2002
2061
|
});
|
|
2062
|
+
return response;
|
|
2003
2063
|
}
|
|
2004
|
-
async function decline(
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2064
|
+
async function decline(reason) {
|
|
2065
|
+
const currentState = rtcStore.getState();
|
|
2066
|
+
if (!currentState.incomingInvite) {
|
|
2067
|
+
throw new Error("No incoming invite to decline");
|
|
2068
|
+
}
|
|
2069
|
+
const { callId, inviteId } = currentState.incomingInvite;
|
|
2070
|
+
const requestBody = {
|
|
2071
|
+
inviteId
|
|
2009
2072
|
};
|
|
2010
2073
|
if (reason) {
|
|
2011
|
-
|
|
2074
|
+
requestBody.reason = reason;
|
|
2012
2075
|
}
|
|
2013
|
-
return CallsService.postSignalCallsByCallIdDecline(
|
|
2076
|
+
return CallsService.postSignalCallsByCallIdDecline({
|
|
2077
|
+
callId,
|
|
2078
|
+
appId,
|
|
2079
|
+
requestBody
|
|
2080
|
+
});
|
|
2014
2081
|
}
|
|
2015
2082
|
async function cancel(callId) {
|
|
2016
|
-
ensureApiConfigured();
|
|
2017
2083
|
return CallsService.postSignalCallsByCallIdCancel({
|
|
2018
2084
|
callId,
|
|
2019
2085
|
appId
|
|
2020
2086
|
});
|
|
2021
2087
|
}
|
|
2022
2088
|
async function leave(callId) {
|
|
2023
|
-
ensureApiConfigured();
|
|
2024
2089
|
return CallsService.postSignalCallsByCallIdLeave({
|
|
2025
2090
|
callId,
|
|
2026
2091
|
appId
|
|
2027
2092
|
});
|
|
2028
2093
|
}
|
|
2029
2094
|
async function end(callId) {
|
|
2030
|
-
ensureApiConfigured();
|
|
2031
2095
|
return CallsService.postSignalCallsByCallIdEnd({
|
|
2032
2096
|
callId,
|
|
2033
2097
|
appId
|
|
2034
2098
|
});
|
|
2035
2099
|
}
|
|
2036
2100
|
async function transfer(callId, targetParticipantId, reason) {
|
|
2037
|
-
ensureApiConfigured();
|
|
2038
2101
|
const requestBody = {
|
|
2039
2102
|
targetParticipantId
|
|
2040
2103
|
};
|
|
@@ -2048,7 +2111,6 @@ function createCallsService(config) {
|
|
|
2048
2111
|
});
|
|
2049
2112
|
}
|
|
2050
2113
|
async function kick(callId, participantId, reason) {
|
|
2051
|
-
ensureApiConfigured();
|
|
2052
2114
|
const requestBody = {
|
|
2053
2115
|
participantId
|
|
2054
2116
|
};
|
|
@@ -2062,7 +2124,6 @@ function createCallsService(config) {
|
|
|
2062
2124
|
});
|
|
2063
2125
|
}
|
|
2064
2126
|
async function mute(callId, participantId) {
|
|
2065
|
-
ensureApiConfigured();
|
|
2066
2127
|
return CallsService.postSignalCallsByCallIdMute({
|
|
2067
2128
|
callId,
|
|
2068
2129
|
appId,
|
|
@@ -2182,16 +2243,16 @@ function useCallState() {
|
|
|
2182
2243
|
};
|
|
2183
2244
|
}
|
|
2184
2245
|
|
|
2185
|
-
// src/hooks/useSessionId.ts
|
|
2186
|
-
function useSessionId() {
|
|
2187
|
-
return useRtcStore((state) => state.session?.id ?? null);
|
|
2188
|
-
}
|
|
2189
|
-
|
|
2190
2246
|
// src/hooks/useIncomingInvite.ts
|
|
2191
2247
|
function useIncomingInvite() {
|
|
2192
2248
|
return useRtcStore((state) => state.incomingInvite);
|
|
2193
2249
|
}
|
|
2194
2250
|
|
|
2251
|
+
// src/hooks/useSessionId.ts
|
|
2252
|
+
function useSessionId() {
|
|
2253
|
+
return useRtcStore((state) => state.session?.id ?? null);
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2195
2256
|
// src/hooks/useCallActions.ts
|
|
2196
2257
|
function useCallActions() {
|
|
2197
2258
|
const sdk = useSdk();
|
|
@@ -2217,13 +2278,13 @@ function useCallActions() {
|
|
|
2217
2278
|
if (!incomingInvite) {
|
|
2218
2279
|
throw new Error("No incoming invite to accept");
|
|
2219
2280
|
}
|
|
2220
|
-
return sdk.calls.accept(
|
|
2281
|
+
return sdk.calls.accept();
|
|
2221
2282
|
},
|
|
2222
2283
|
decline: (reason) => {
|
|
2223
2284
|
if (!incomingInvite) {
|
|
2224
2285
|
throw new Error("No incoming invite to decline");
|
|
2225
2286
|
}
|
|
2226
|
-
return sdk.calls.decline(
|
|
2287
|
+
return sdk.calls.decline(reason);
|
|
2227
2288
|
},
|
|
2228
2289
|
cancel: () => {
|
|
2229
2290
|
if (!sessionId) {
|
|
@@ -2307,10 +2368,11 @@ function useCallInitiated() {
|
|
|
2307
2368
|
function useSessionDuration() {
|
|
2308
2369
|
return 0;
|
|
2309
2370
|
}
|
|
2371
|
+
|
|
2372
|
+
// src/hooks/useParticipantMetadata.ts
|
|
2310
2373
|
function useParticipantMetadata(participant) {
|
|
2311
|
-
const info = componentsReact.useParticipantInfo({ participant });
|
|
2312
2374
|
try {
|
|
2313
|
-
const metadata = JSON.parse(
|
|
2375
|
+
const metadata = participant.metadata ? JSON.parse(participant.metadata) : {};
|
|
2314
2376
|
return {
|
|
2315
2377
|
userId: metadata.userId,
|
|
2316
2378
|
role: metadata.role,
|
|
@@ -2347,7 +2409,7 @@ function useRoomReady() {
|
|
|
2347
2409
|
const { status } = useCallState();
|
|
2348
2410
|
return livekitInfo !== null && (status === "ready" || status === "active");
|
|
2349
2411
|
}
|
|
2350
|
-
var
|
|
2412
|
+
var logger3 = createLogger("useAutoConnectRoom");
|
|
2351
2413
|
function useAutoConnectRoom(options) {
|
|
2352
2414
|
const [room] = React.useState(() => new livekitClient.Room(options));
|
|
2353
2415
|
const isReady = useRoomReady();
|
|
@@ -2355,7 +2417,9 @@ function useAutoConnectRoom(options) {
|
|
|
2355
2417
|
React.useEffect(() => {
|
|
2356
2418
|
if (isReady && livekitInfo) {
|
|
2357
2419
|
room.connect(livekitInfo.url, livekitInfo.token).catch((error) => {
|
|
2358
|
-
|
|
2420
|
+
logger3.error("Failed to connect to LiveKit room", error);
|
|
2421
|
+
}).then(() => {
|
|
2422
|
+
room.localParticipant.setMicrophoneEnabled(true);
|
|
2359
2423
|
});
|
|
2360
2424
|
} else if (room.state === livekitClient.ConnectionState.Connected) {
|
|
2361
2425
|
room.disconnect();
|
|
@@ -2382,6 +2446,7 @@ exports.callInviteSentSchema = callInviteSentSchema;
|
|
|
2382
2446
|
exports.callJoinInfoSchema = callJoinInfoSchema;
|
|
2383
2447
|
exports.callMissedSchema = callMissedSchema;
|
|
2384
2448
|
exports.callParticipantAddedSchema = callParticipantAddedSchema;
|
|
2449
|
+
exports.callReadySchema = callReadySchema;
|
|
2385
2450
|
exports.callRoomStartedSchema = callRoomStartedSchema;
|
|
2386
2451
|
exports.clearErrors = clearErrors;
|
|
2387
2452
|
exports.eventBus = eventBus;
|