@mirai/core 0.4.664 → 0.4.666

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.
@@ -0,0 +1,507 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useLiveSession = void 0;
7
+ var _dataSources = require("@mirai/data-sources");
8
+ var _react = require("react");
9
+ var _helpers = require("../../../../helpers");
10
+ var _helpers2 = require("../../../helpers");
11
+ var _helpers3 = require("../helpers");
12
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
13
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
14
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
15
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
16
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
17
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
18
+ const AUDIO_CONSTRAINTS = {
19
+ autoGainControl: true,
20
+ echoCancellation: true,
21
+ noiseSuppression: true
22
+ };
23
+ const CLOSE_TIMEOUT_RESULT = {};
24
+ const DATA_CHANNEL_LABEL = 'oai-events';
25
+ const ERROR_AUDIO_PLAYBACK_BLOCKED = 'audio_playback_blocked';
26
+ const ERROR_BLOCKED_OPEN_URL = 'blocked_url';
27
+ const ERROR_ICE_TIMEOUT = 'Timed out while gathering ICE candidates';
28
+ const ERROR_MISSING_AUDIO_CONTEXT = 'AudioContext not supported';
29
+ const ERROR_MISSING_LOCAL_SDP = 'Missing local SDP offer';
30
+ const ERROR_MISSING_REMOTE_SDP = 'Missing remote SDP answer';
31
+ const ERROR_SESSION_CLOSE_UNCONFIRMED = 'session_close_unconfirmed';
32
+ const FFT_SIZE = 1024;
33
+ const ICE_GATHERING_TIMEOUT = 10000;
34
+ const SESSION_CLOSE_TIMEOUT = 15000;
35
+ const SESSION_ENDPOINT = '/voice/live/session';
36
+ const TERMINAL_CONNECTION_STATES = ['closed', 'failed'];
37
+ const SSE_EVENT_CLOSED = 'closed';
38
+ const SSE_EVENT_OPEN_URL = 'open_url';
39
+ const createConnectionState = () => ({
40
+ connected: false,
41
+ ready: false,
42
+ receiving: false,
43
+ started: false
44
+ });
45
+ const parseServerEvent = value => {
46
+ if (typeof value !== 'string') return null;
47
+ try {
48
+ return JSON.parse(value);
49
+ } catch (_unused) {
50
+ return null;
51
+ }
52
+ };
53
+ const stopMediaStream = mediaStream => {
54
+ if (!mediaStream) return;
55
+ mediaStream.getTracks().forEach(track => track.stop());
56
+ };
57
+ const useLiveSession = () => {
58
+ const attemptRef = (0, _react.useRef)(0);
59
+ const audioContextRef = (0, _react.useRef)(null);
60
+ const audioElementRef = (0, _react.useRef)(null);
61
+ const closingRef = (0, _react.useRef)(null);
62
+ const connectionStateRef = (0, _react.useRef)(createConnectionState());
63
+ const dataChannelRef = (0, _react.useRef)(null);
64
+ const eventSourceRef = (0, _react.useRef)(null);
65
+ const fingerprintRef = (0, _react.useRef)(null);
66
+ const inputFrequencyDataRef = (0, _react.useRef)(null);
67
+ const inputSourceRef = (0, _react.useRef)(null);
68
+ const localStreamRef = (0, _react.useRef)(null);
69
+ const outputFrequencyDataRef = (0, _react.useRef)(null);
70
+ const outputSourceRef = (0, _react.useRef)(null);
71
+ const pageHideHandlerRef = (0, _react.useRef)(null);
72
+ const peerConnectionRef = (0, _react.useRef)(null);
73
+ const sessionIdRef = (0, _react.useRef)(null);
74
+ const audioAnalyzersRef = (0, _react.useRef)({
75
+ inputAnalyser: null,
76
+ outputAnalyser: null,
77
+ getInputByteFrequencyData: () => null,
78
+ getOutputByteFrequencyData: () => null
79
+ });
80
+ const cleanupLiveSession = (0, _react.useCallback)(() => {
81
+ attemptRef.current += 1;
82
+ if (pageHideHandlerRef.current) {
83
+ window.removeEventListener('pagehide', pageHideHandlerRef.current);
84
+ pageHideHandlerRef.current = null;
85
+ }
86
+ const eventSource = eventSourceRef.current;
87
+ if (eventSource) {
88
+ eventSource.close();
89
+ eventSourceRef.current = null;
90
+ }
91
+ const dataChannel = dataChannelRef.current;
92
+ if (dataChannel) {
93
+ dataChannel.close();
94
+ dataChannelRef.current = null;
95
+ }
96
+ const peerConnection = peerConnectionRef.current;
97
+ if (peerConnection) {
98
+ peerConnection.getSenders().forEach(_ref => {
99
+ let track = _ref.track;
100
+ if (track) track.stop();
101
+ });
102
+ peerConnection.close();
103
+ peerConnectionRef.current = null;
104
+ }
105
+ stopMediaStream(localStreamRef.current);
106
+ localStreamRef.current = null;
107
+ if (audioElementRef.current) {
108
+ audioElementRef.current.srcObject = null;
109
+ audioElementRef.current = null;
110
+ }
111
+ if (inputSourceRef.current) {
112
+ inputSourceRef.current.disconnect();
113
+ inputSourceRef.current = null;
114
+ }
115
+ if (outputSourceRef.current) {
116
+ outputSourceRef.current.disconnect();
117
+ outputSourceRef.current = null;
118
+ }
119
+ audioAnalyzersRef.current.inputAnalyser = null;
120
+ audioAnalyzersRef.current.outputAnalyser = null;
121
+ audioAnalyzersRef.current.getInputByteFrequencyData = () => null;
122
+ audioAnalyzersRef.current.getOutputByteFrequencyData = () => null;
123
+ inputFrequencyDataRef.current = null;
124
+ outputFrequencyDataRef.current = null;
125
+ const audioContext = audioContextRef.current;
126
+ if (audioContext) {
127
+ Promise.resolve(audioContext.close()).catch(() => {});
128
+ audioContextRef.current = null;
129
+ }
130
+ closingRef.current = null;
131
+ connectionStateRef.current = createConnectionState();
132
+ fingerprintRef.current = null;
133
+ sessionIdRef.current = null;
134
+ }, []);
135
+ const releaseLiveSession = (0, _react.useCallback)(() => {
136
+ if (closingRef.current) return;
137
+ cleanupLiveSession();
138
+ }, [cleanupLiveSession]);
139
+ (0, _react.useEffect)(() => releaseLiveSession, [releaseLiveSession]);
140
+ const createAudioAnalyzers = (0, _react.useCallback)(async (mediaStream, isCurrentAttempt) => {
141
+ const AudioContextConstructor = globalThis.AudioContext || globalThis.webkitAudioContext;
142
+ if (!AudioContextConstructor) throw new Error(ERROR_MISSING_AUDIO_CONTEXT);
143
+ const audioContext = new AudioContextConstructor();
144
+ if (audioContext.state === 'suspended') await audioContext.resume();
145
+ if (!isCurrentAttempt()) {
146
+ Promise.resolve(audioContext.close()).catch(() => {});
147
+ return false;
148
+ }
149
+ audioContextRef.current = audioContext;
150
+ const inputAnalyser = audioContext.createAnalyser();
151
+ const outputAnalyser = audioContext.createAnalyser();
152
+ inputAnalyser.fftSize = FFT_SIZE;
153
+ outputAnalyser.fftSize = FFT_SIZE;
154
+ audioAnalyzersRef.current.inputAnalyser = inputAnalyser;
155
+ audioAnalyzersRef.current.outputAnalyser = outputAnalyser;
156
+ inputFrequencyDataRef.current = new Uint8Array(inputAnalyser.frequencyBinCount);
157
+ outputFrequencyDataRef.current = new Uint8Array(outputAnalyser.frequencyBinCount);
158
+ audioAnalyzersRef.current.getInputByteFrequencyData = () => {
159
+ if (!audioAnalyzersRef.current.inputAnalyser || !inputFrequencyDataRef.current) return null;
160
+ audioAnalyzersRef.current.inputAnalyser.getByteFrequencyData(inputFrequencyDataRef.current);
161
+ return inputFrequencyDataRef.current;
162
+ };
163
+ audioAnalyzersRef.current.getOutputByteFrequencyData = () => {
164
+ if (!audioAnalyzersRef.current.outputAnalyser || !outputFrequencyDataRef.current) return null;
165
+ audioAnalyzersRef.current.outputAnalyser.getByteFrequencyData(outputFrequencyDataRef.current);
166
+ return outputFrequencyDataRef.current;
167
+ };
168
+ const inputSource = audioContext.createMediaStreamSource(mediaStream);
169
+ inputSourceRef.current = inputSource;
170
+ inputSource.connect(inputAnalyser);
171
+ return true;
172
+ }, []);
173
+ const waitForIceGathering = (0, _react.useCallback)(peerConnection => new Promise((resolve, reject) => {
174
+ if (peerConnection.iceGatheringState === 'complete') {
175
+ resolve();
176
+ return;
177
+ }
178
+ let timeoutId = null;
179
+ const handleStateChange = () => {
180
+ if (peerConnection.iceGatheringState !== 'complete') return;
181
+ clearTimeout(timeoutId);
182
+ peerConnection.removeEventListener('icegatheringstatechange', handleStateChange);
183
+ resolve();
184
+ };
185
+ timeoutId = setTimeout(() => {
186
+ peerConnection.removeEventListener('icegatheringstatechange', handleStateChange);
187
+ reject(new Error(ERROR_ICE_TIMEOUT));
188
+ }, ICE_GATHERING_TIMEOUT);
189
+ peerConnection.addEventListener('icegatheringstatechange', handleStateChange);
190
+ }), []);
191
+ const registerPageHide = (0, _react.useCallback)(fingerprint => {
192
+ const handlePageHide = () => {
193
+ const sessionId = sessionIdRef.current;
194
+ if (!sessionId || !fingerprint || typeof navigator.sendBeacon !== 'function') return;
195
+ const query = new URLSearchParams({
196
+ fingerprint
197
+ }).toString();
198
+ navigator.sendBeacon("".concat(process.env.SERVICE_SYNAPSE).concat(SESSION_ENDPOINT, "/").concat(sessionId, "/close?").concat(query));
199
+ };
200
+ pageHideHandlerRef.current = handlePageHide;
201
+ window.addEventListener('pagehide', handlePageHide);
202
+ }, []);
203
+ const openEventStream = (0, _react.useCallback)(_ref2 => {
204
+ let fingerprint = _ref2.fingerprint,
205
+ onClosed = _ref2.onClosed,
206
+ onOpenUrl = _ref2.onOpenUrl,
207
+ sessionId = _ref2.sessionId;
208
+ const EventSourceConstructor = globalThis.EventSource;
209
+ if (!EventSourceConstructor || !sessionId || !fingerprint) return;
210
+ const query = new URLSearchParams({
211
+ fingerprint
212
+ }).toString();
213
+ const eventSource = new EventSourceConstructor("".concat(process.env.SERVICE_SYNAPSE).concat(SESSION_ENDPOINT, "/").concat(sessionId, "/events?").concat(query));
214
+ eventSourceRef.current = eventSource;
215
+ eventSource.addEventListener(SSE_EVENT_OPEN_URL, onOpenUrl);
216
+ eventSource.addEventListener(SSE_EVENT_CLOSED, onClosed);
217
+ }, []);
218
+ const playRemoteAudio = (0, _react.useCallback)(() => {
219
+ const audioElement = audioElementRef.current;
220
+ if (!audioElement || typeof audioElement.play !== 'function') return;
221
+ const reportBlockedPlayback = () => {
222
+ _dataSources.Event.publish(_helpers.EVENT.METRICS, {
223
+ id: _helpers.METRICS_EVENTS.AURA_ERROR,
224
+ error: ERROR_AUDIO_PLAYBACK_BLOCKED
225
+ });
226
+ };
227
+ try {
228
+ const played = audioElement.play();
229
+ if (played && typeof played.catch === 'function') played.catch(reportBlockedPlayback);
230
+ } catch (_unused2) {
231
+ reportBlockedPlayback();
232
+ }
233
+ }, []);
234
+ const endSession = (0, _react.useCallback)(async () => {
235
+ if (closingRef.current) {
236
+ await closingRef.current;
237
+ return;
238
+ }
239
+ const attempt = attemptRef.current;
240
+ const isCurrentAttempt = () => attemptRef.current === attempt;
241
+ const fingerprint = fingerprintRef.current;
242
+ const sessionId = sessionIdRef.current;
243
+ if (!fingerprint || !sessionId) {
244
+ cleanupLiveSession();
245
+ return;
246
+ }
247
+ let timeoutId = null;
248
+ const closing = Promise.race([(0, _dataSources.request)({
249
+ endpoint: "".concat(SESSION_ENDPOINT, "/").concat(sessionId, "/close"),
250
+ hostname: process.env.SERVICE_SYNAPSE,
251
+ method: 'POST',
252
+ fingerprint
253
+ }), new Promise(resolve => {
254
+ timeoutId = setTimeout(() => resolve(CLOSE_TIMEOUT_RESULT), SESSION_CLOSE_TIMEOUT);
255
+ })]);
256
+ closingRef.current = closing;
257
+ try {
258
+ const result = await closing;
259
+ if (result === CLOSE_TIMEOUT_RESULT) {
260
+ _dataSources.Event.publish(_helpers.EVENT.METRICS, {
261
+ id: _helpers.METRICS_EVENTS.AURA_ERROR,
262
+ error: ERROR_SESSION_CLOSE_UNCONFIRMED
263
+ });
264
+ }
265
+ } catch (error) {
266
+ _dataSources.Event.publish(_helpers.EVENT.METRICS, {
267
+ id: _helpers.METRICS_EVENTS.AURA_ERROR,
268
+ error: ERROR_SESSION_CLOSE_UNCONFIRMED,
269
+ reason: error === null || error === void 0 ? void 0 : error.message
270
+ });
271
+ } finally {
272
+ clearTimeout(timeoutId);
273
+ if (isCurrentAttempt()) cleanupLiveSession();
274
+ }
275
+ }, [cleanupLiveSession]);
276
+ const startSession = (0, _react.useCallback)(async _ref3 => {
277
+ let chainId = _ref3.chainId,
278
+ currency = _ref3.currency,
279
+ hotelId = _ref3.hotelId,
280
+ isChain = _ref3.isChain,
281
+ locale = _ref3.locale,
282
+ setIsConnecting = _ref3.setIsConnecting,
283
+ setReady = _ref3.setReady;
284
+ cleanupLiveSession();
285
+ attemptRef.current += 1;
286
+ const attempt = attemptRef.current;
287
+ const isCurrentAttempt = () => attemptRef.current === attempt;
288
+ let createdSessionId = null;
289
+ let dataChannel = null;
290
+ let mediaStream = null;
291
+ let peerConnection = null;
292
+ const releaseAttempt = () => {
293
+ if (dataChannel) dataChannel.close();
294
+ if (peerConnection) {
295
+ peerConnection.getSenders().forEach(_ref4 => {
296
+ let track = _ref4.track;
297
+ if (track) track.stop();
298
+ });
299
+ peerConnection.close();
300
+ }
301
+ stopMediaStream(mediaStream);
302
+ if (!createdSessionId) return;
303
+ const abandonedSessionId = createdSessionId;
304
+ createdSessionId = null;
305
+ (0, _dataSources.request)({
306
+ endpoint: "".concat(SESSION_ENDPOINT, "/").concat(abandonedSessionId, "/close"),
307
+ hostname: process.env.SERVICE_SYNAPSE,
308
+ method: 'POST',
309
+ fingerprint
310
+ }).catch(() => {});
311
+ };
312
+ const abortWhenStale = () => {
313
+ if (isCurrentAttempt()) return false;
314
+ releaseAttempt();
315
+ return true;
316
+ };
317
+ const fingerprint = (0, _helpers2.getClientFingerprint)();
318
+ fingerprintRef.current = fingerprint;
319
+ registerPageHide(fingerprint);
320
+ const finalizeSession = () => {
321
+ if (!isCurrentAttempt()) return;
322
+ cleanupLiveSession();
323
+ setReady(false);
324
+ setIsConnecting(false);
325
+ };
326
+ const markReady = () => {
327
+ if (!isCurrentAttempt()) return;
328
+ const _connectionStateRef$c = connectionStateRef.current,
329
+ connected = _connectionStateRef$c.connected,
330
+ ready = _connectionStateRef$c.ready,
331
+ receiving = _connectionStateRef$c.receiving,
332
+ started = _connectionStateRef$c.started;
333
+ if (ready || !connected || !receiving || !started) return;
334
+ connectionStateRef.current.ready = true;
335
+ _dataSources.Event.publish(_helpers.EVENT.METRICS, {
336
+ id: _helpers.METRICS_EVENTS.AURA_START
337
+ });
338
+ setReady(true);
339
+ setIsConnecting(false);
340
+ };
341
+ const handleSessionClosed = payload => {
342
+ var _payload$usage;
343
+ const reason = payload.reason;
344
+ _dataSources.Event.publish(_helpers.EVENT.METRICS, {
345
+ id: _helpers.METRICS_EVENTS.AURA_USAGE,
346
+ reason,
347
+ seconds: (_payload$usage = payload.usage) === null || _payload$usage === void 0 ? void 0 : _payload$usage.seconds
348
+ });
349
+ if (closingRef.current) return;
350
+ finalizeSession();
351
+ };
352
+ const handleServerEvent = _ref5 => {
353
+ let data = _ref5.data;
354
+ if (!isCurrentAttempt()) return;
355
+ const payload = parseServerEvent(data);
356
+ if (!payload) return;
357
+ const error = payload.error,
358
+ session = payload.session,
359
+ type = payload.type;
360
+ if (type === 'session.started') {
361
+ var _session$id;
362
+ sessionIdRef.current = (_session$id = session === null || session === void 0 ? void 0 : session.id) !== null && _session$id !== void 0 ? _session$id : sessionIdRef.current;
363
+ connectionStateRef.current.started = true;
364
+ markReady();
365
+ }
366
+ if (type === 'session.closed') handleSessionClosed(payload);
367
+ if (type === 'error') _dataSources.Event.publish(_helpers.EVENT.METRICS, {
368
+ id: _helpers.METRICS_EVENTS.AURA_ERROR,
369
+ error: error === null || error === void 0 ? void 0 : error.message
370
+ });
371
+ };
372
+ const handleStreamClosed = () => {
373
+ if (!isCurrentAttempt() || closingRef.current) return;
374
+ finalizeSession();
375
+ };
376
+ const handleStreamOpenUrl = _ref6 => {
377
+ let data = _ref6.data;
378
+ if (!isCurrentAttempt()) return;
379
+ const _ref7 = parseServerEvent(data) || {},
380
+ url = _ref7.url;
381
+ const allowedUrl = (0, _helpers3.getAllowedOpenUrl)(url);
382
+ if (!allowedUrl) {
383
+ _dataSources.Event.publish(_helpers.EVENT.METRICS, {
384
+ id: _helpers.METRICS_EVENTS.AURA_ERROR,
385
+ error: ERROR_BLOCKED_OPEN_URL
386
+ });
387
+ return;
388
+ }
389
+ Promise.resolve(endSession()).catch(() => {}).then(() => window.location.assign(allowedUrl));
390
+ };
391
+ try {
392
+ var _session$id2;
393
+ mediaStream = await navigator.mediaDevices.getUserMedia({
394
+ audio: AUDIO_CONSTRAINTS
395
+ });
396
+ if (abortWhenStale()) return;
397
+ localStreamRef.current = mediaStream;
398
+ const analyzersReady = await createAudioAnalyzers(mediaStream, isCurrentAttempt);
399
+ if (!analyzersReady || abortWhenStale()) return;
400
+ peerConnection = new RTCPeerConnection();
401
+ peerConnectionRef.current = peerConnection;
402
+ audioElementRef.current = document.createElement('audio');
403
+ audioElementRef.current.autoplay = true;
404
+ peerConnection.addEventListener('connectionstatechange', () => {
405
+ if (!isCurrentAttempt()) return;
406
+ const _peerConnection = peerConnection,
407
+ connectionState = _peerConnection.connectionState;
408
+ if (connectionState === 'connected') {
409
+ connectionStateRef.current.connected = true;
410
+ markReady();
411
+ return;
412
+ }
413
+ if (TERMINAL_CONNECTION_STATES.includes(connectionState)) finalizeSession();
414
+ });
415
+ peerConnection.ontrack = _ref8 => {
416
+ let streams = _ref8.streams;
417
+ if (!isCurrentAttempt()) return;
418
+ const _ref9 = streams || [],
419
+ _ref0 = _slicedToArray(_ref9, 1),
420
+ remoteStream = _ref0[0];
421
+ if (!remoteStream) return;
422
+ if (audioElementRef.current) audioElementRef.current.srcObject = remoteStream;
423
+ playRemoteAudio();
424
+ const audioContext = audioContextRef.current;
425
+ const outputAnalyser = audioAnalyzersRef.current.outputAnalyser;
426
+ if (audioContext && outputAnalyser) {
427
+ if (outputSourceRef.current) outputSourceRef.current.disconnect();
428
+ outputSourceRef.current = audioContext.createMediaStreamSource(remoteStream);
429
+ outputSourceRef.current.connect(outputAnalyser);
430
+ }
431
+ connectionStateRef.current.receiving = true;
432
+ markReady();
433
+ };
434
+ dataChannel = peerConnection.createDataChannel(DATA_CHANNEL_LABEL);
435
+ dataChannelRef.current = dataChannel;
436
+ dataChannel.addEventListener('message', handleServerEvent);
437
+ dataChannel.addEventListener('close', () => {
438
+ if (!isCurrentAttempt() || closingRef.current) return;
439
+ finalizeSession();
440
+ });
441
+ dataChannel.addEventListener('error', () => {
442
+ if (!isCurrentAttempt()) return;
443
+ finalizeSession();
444
+ });
445
+ const _mediaStream$getAudio = mediaStream.getAudioTracks(),
446
+ _mediaStream$getAudio2 = _slicedToArray(_mediaStream$getAudio, 1),
447
+ track = _mediaStream$getAudio2[0];
448
+ if (track) peerConnection.addTrack(track, mediaStream);
449
+ const offer = await peerConnection.createOffer();
450
+ if (abortWhenStale()) return;
451
+ await peerConnection.setLocalDescription(offer);
452
+ if (abortWhenStale()) return;
453
+ await waitForIceGathering(peerConnection);
454
+ if (abortWhenStale()) return;
455
+ const _ref1 = peerConnection.localDescription || {},
456
+ sdp = _ref1.sdp;
457
+ if (!sdp) throw new Error(ERROR_MISSING_LOCAL_SDP);
458
+ const _await$request = await (0, _dataSources.request)({
459
+ endpoint: SESSION_ENDPOINT,
460
+ hostname: process.env.SERVICE_SYNAPSE,
461
+ method: 'POST',
462
+ chainId: isChain ? chainId : undefined,
463
+ currency,
464
+ fingerprint,
465
+ hotelId: isChain ? undefined : hotelId,
466
+ locale,
467
+ sdp
468
+ }),
469
+ session = _await$request.session,
470
+ transport = _await$request.transport;
471
+ createdSessionId = (_session$id2 = session === null || session === void 0 ? void 0 : session.id) !== null && _session$id2 !== void 0 ? _session$id2 : null;
472
+ if (abortWhenStale()) return;
473
+ if (!(transport !== null && transport !== void 0 && transport.sdp)) throw new Error(ERROR_MISSING_REMOTE_SDP);
474
+ sessionIdRef.current = createdSessionId;
475
+ await peerConnection.setRemoteDescription({
476
+ type: 'answer',
477
+ sdp: transport.sdp
478
+ });
479
+ if (abortWhenStale()) return;
480
+ openEventStream({
481
+ fingerprint,
482
+ onClosed: handleStreamClosed,
483
+ onOpenUrl: handleStreamOpenUrl,
484
+ sessionId: sessionIdRef.current
485
+ });
486
+ } catch (error) {
487
+ releaseAttempt();
488
+ _dataSources.Event.publish(_helpers.EVENT.METRICS, {
489
+ id: _helpers.METRICS_EVENTS.AURA_ERROR,
490
+ error: error === null || error === void 0 ? void 0 : error.message
491
+ });
492
+ if (isCurrentAttempt()) {
493
+ cleanupLiveSession();
494
+ setReady(false);
495
+ setIsConnecting(false);
496
+ }
497
+ throw error;
498
+ }
499
+ }, [cleanupLiveSession, createAudioAnalyzers, endSession, openEventStream, playRemoteAudio, registerPageHide, waitForIceGathering]);
500
+ return {
501
+ startSession,
502
+ endSession,
503
+ audioAnalyzers: audioAnalyzersRef.current
504
+ };
505
+ };
506
+ exports.useLiveSession = useLiveSession;
507
+ //# sourceMappingURL=useLiveSession.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLiveSession.js","names":["_dataSources","require","_react","_helpers","_helpers2","_helpers3","_slicedToArray","r","e","_arrayWithHoles","_iterableToArrayLimit","_unsupportedIterableToArray","_nonIterableRest","TypeError","a","_arrayLikeToArray","t","toString","call","slice","constructor","name","Array","from","test","length","n","l","Symbol","iterator","i","u","f","o","next","Object","done","push","value","return","isArray","AUDIO_CONSTRAINTS","autoGainControl","echoCancellation","noiseSuppression","CLOSE_TIMEOUT_RESULT","DATA_CHANNEL_LABEL","ERROR_AUDIO_PLAYBACK_BLOCKED","ERROR_BLOCKED_OPEN_URL","ERROR_ICE_TIMEOUT","ERROR_MISSING_AUDIO_CONTEXT","ERROR_MISSING_LOCAL_SDP","ERROR_MISSING_REMOTE_SDP","ERROR_SESSION_CLOSE_UNCONFIRMED","FFT_SIZE","ICE_GATHERING_TIMEOUT","SESSION_CLOSE_TIMEOUT","SESSION_ENDPOINT","TERMINAL_CONNECTION_STATES","SSE_EVENT_CLOSED","SSE_EVENT_OPEN_URL","createConnectionState","connected","ready","receiving","started","parseServerEvent","JSON","parse","_unused","stopMediaStream","mediaStream","getTracks","forEach","track","stop","useLiveSession","attemptRef","useRef","audioContextRef","audioElementRef","closingRef","connectionStateRef","dataChannelRef","eventSourceRef","fingerprintRef","inputFrequencyDataRef","inputSourceRef","localStreamRef","outputFrequencyDataRef","outputSourceRef","pageHideHandlerRef","peerConnectionRef","sessionIdRef","audioAnalyzersRef","inputAnalyser","outputAnalyser","getInputByteFrequencyData","getOutputByteFrequencyData","cleanupLiveSession","useCallback","current","window","removeEventListener","eventSource","close","dataChannel","peerConnection","getSenders","_ref","srcObject","disconnect","audioContext","Promise","resolve","catch","releaseLiveSession","useEffect","createAudioAnalyzers","isCurrentAttempt","AudioContextConstructor","globalThis","AudioContext","webkitAudioContext","Error","state","resume","createAnalyser","fftSize","Uint8Array","frequencyBinCount","getByteFrequencyData","inputSource","createMediaStreamSource","connect","waitForIceGathering","reject","iceGatheringState","timeoutId","handleStateChange","clearTimeout","setTimeout","addEventListener","registerPageHide","fingerprint","handlePageHide","sessionId","navigator","sendBeacon","query","URLSearchParams","concat","process","env","SERVICE_SYNAPSE","openEventStream","_ref2","onClosed","onOpenUrl","EventSourceConstructor","EventSource","playRemoteAudio","audioElement","play","reportBlockedPlayback","Event","publish","EVENT","METRICS","id","METRICS_EVENTS","AURA_ERROR","error","played","_unused2","endSession","attempt","closing","race","request","endpoint","hostname","method","result","reason","message","startSession","_ref3","chainId","currency","hotelId","isChain","locale","setIsConnecting","setReady","createdSessionId","releaseAttempt","_ref4","abandonedSessionId","abortWhenStale","getClientFingerprint","finalizeSession","markReady","_connectionStateRef$c","AURA_START","handleSessionClosed","payload","_payload$usage","AURA_USAGE","seconds","usage","handleServerEvent","_ref5","data","session","type","_session$id","handleStreamClosed","handleStreamOpenUrl","_ref6","_ref7","url","allowedUrl","getAllowedOpenUrl","then","location","assign","_session$id2","mediaDevices","getUserMedia","audio","analyzersReady","RTCPeerConnection","document","createElement","autoplay","_peerConnection","connectionState","includes","ontrack","_ref8","streams","_ref9","_ref0","remoteStream","createDataChannel","_mediaStream$getAudio","getAudioTracks","_mediaStream$getAudio2","addTrack","offer","createOffer","setLocalDescription","_ref1","localDescription","sdp","_await$request","undefined","transport","setRemoteDescription","audioAnalyzers","exports"],"sources":["../../../../../../src/components/Chat/components/Aura/hooks/useLiveSession.js"],"sourcesContent":["import { Event, request } from '@mirai/data-sources';\nimport { useCallback, useEffect, useRef } from 'react';\n\nimport { EVENT, METRICS_EVENTS } from '../../../../helpers';\nimport { getClientFingerprint } from '../../../helpers';\nimport { getAllowedOpenUrl } from '../helpers';\n\nconst AUDIO_CONSTRAINTS = { autoGainControl: true, echoCancellation: true, noiseSuppression: true };\nconst CLOSE_TIMEOUT_RESULT = {};\nconst DATA_CHANNEL_LABEL = 'oai-events';\nconst ERROR_AUDIO_PLAYBACK_BLOCKED = 'audio_playback_blocked';\nconst ERROR_BLOCKED_OPEN_URL = 'blocked_url';\nconst ERROR_ICE_TIMEOUT = 'Timed out while gathering ICE candidates';\nconst ERROR_MISSING_AUDIO_CONTEXT = 'AudioContext not supported';\nconst ERROR_MISSING_LOCAL_SDP = 'Missing local SDP offer';\nconst ERROR_MISSING_REMOTE_SDP = 'Missing remote SDP answer';\nconst ERROR_SESSION_CLOSE_UNCONFIRMED = 'session_close_unconfirmed';\nconst FFT_SIZE = 1024;\nconst ICE_GATHERING_TIMEOUT = 10000;\nconst SESSION_CLOSE_TIMEOUT = 15000;\nconst SESSION_ENDPOINT = '/voice/live/session';\nconst TERMINAL_CONNECTION_STATES = ['closed', 'failed'];\nconst SSE_EVENT_CLOSED = 'closed';\nconst SSE_EVENT_OPEN_URL = 'open_url';\n\nconst createConnectionState = () => ({ connected: false, ready: false, receiving: false, started: false });\n\nconst parseServerEvent = (value) => {\n if (typeof value !== 'string') return null;\n try {\n return JSON.parse(value);\n } catch {\n return null;\n }\n};\n\nconst stopMediaStream = (mediaStream) => {\n if (!mediaStream) return;\n mediaStream.getTracks().forEach((track) => track.stop());\n};\n\nconst useLiveSession = () => {\n const attemptRef = useRef(0);\n const audioContextRef = useRef(null);\n const audioElementRef = useRef(null);\n const closingRef = useRef(null);\n const connectionStateRef = useRef(createConnectionState());\n const dataChannelRef = useRef(null);\n const eventSourceRef = useRef(null);\n const fingerprintRef = useRef(null);\n const inputFrequencyDataRef = useRef(null);\n const inputSourceRef = useRef(null);\n const localStreamRef = useRef(null);\n const outputFrequencyDataRef = useRef(null);\n const outputSourceRef = useRef(null);\n const pageHideHandlerRef = useRef(null);\n const peerConnectionRef = useRef(null);\n const sessionIdRef = useRef(null);\n const audioAnalyzersRef = useRef({\n inputAnalyser: null,\n outputAnalyser: null,\n getInputByteFrequencyData: () => null,\n getOutputByteFrequencyData: () => null,\n });\n\n const cleanupLiveSession = useCallback(() => {\n attemptRef.current += 1;\n\n if (pageHideHandlerRef.current) {\n window.removeEventListener('pagehide', pageHideHandlerRef.current);\n pageHideHandlerRef.current = null;\n }\n\n const eventSource = eventSourceRef.current;\n if (eventSource) {\n eventSource.close();\n eventSourceRef.current = null;\n }\n\n const dataChannel = dataChannelRef.current;\n if (dataChannel) {\n dataChannel.close();\n dataChannelRef.current = null;\n }\n\n const peerConnection = peerConnectionRef.current;\n if (peerConnection) {\n peerConnection.getSenders().forEach(({ track }) => {\n if (track) track.stop();\n });\n peerConnection.close();\n peerConnectionRef.current = null;\n }\n\n stopMediaStream(localStreamRef.current);\n localStreamRef.current = null;\n\n if (audioElementRef.current) {\n audioElementRef.current.srcObject = null;\n audioElementRef.current = null;\n }\n\n if (inputSourceRef.current) {\n inputSourceRef.current.disconnect();\n inputSourceRef.current = null;\n }\n\n if (outputSourceRef.current) {\n outputSourceRef.current.disconnect();\n outputSourceRef.current = null;\n }\n\n audioAnalyzersRef.current.inputAnalyser = null;\n audioAnalyzersRef.current.outputAnalyser = null;\n audioAnalyzersRef.current.getInputByteFrequencyData = () => null;\n audioAnalyzersRef.current.getOutputByteFrequencyData = () => null;\n inputFrequencyDataRef.current = null;\n outputFrequencyDataRef.current = null;\n\n const audioContext = audioContextRef.current;\n if (audioContext) {\n Promise.resolve(audioContext.close()).catch(() => {});\n audioContextRef.current = null;\n }\n\n closingRef.current = null;\n connectionStateRef.current = createConnectionState();\n fingerprintRef.current = null;\n sessionIdRef.current = null;\n }, []);\n\n const releaseLiveSession = useCallback(() => {\n if (closingRef.current) return;\n\n cleanupLiveSession();\n }, [cleanupLiveSession]);\n\n useEffect(() => releaseLiveSession, [releaseLiveSession]);\n\n const createAudioAnalyzers = useCallback(async (mediaStream, isCurrentAttempt) => {\n const AudioContextConstructor = globalThis.AudioContext || globalThis.webkitAudioContext;\n if (!AudioContextConstructor) throw new Error(ERROR_MISSING_AUDIO_CONTEXT);\n\n const audioContext = new AudioContextConstructor();\n if (audioContext.state === 'suspended') await audioContext.resume();\n\n if (!isCurrentAttempt()) {\n Promise.resolve(audioContext.close()).catch(() => {});\n return false;\n }\n\n audioContextRef.current = audioContext;\n const inputAnalyser = audioContext.createAnalyser();\n const outputAnalyser = audioContext.createAnalyser();\n inputAnalyser.fftSize = FFT_SIZE;\n outputAnalyser.fftSize = FFT_SIZE;\n audioAnalyzersRef.current.inputAnalyser = inputAnalyser;\n audioAnalyzersRef.current.outputAnalyser = outputAnalyser;\n inputFrequencyDataRef.current = new Uint8Array(inputAnalyser.frequencyBinCount);\n outputFrequencyDataRef.current = new Uint8Array(outputAnalyser.frequencyBinCount);\n audioAnalyzersRef.current.getInputByteFrequencyData = () => {\n if (!audioAnalyzersRef.current.inputAnalyser || !inputFrequencyDataRef.current) return null;\n audioAnalyzersRef.current.inputAnalyser.getByteFrequencyData(inputFrequencyDataRef.current);\n return inputFrequencyDataRef.current;\n };\n audioAnalyzersRef.current.getOutputByteFrequencyData = () => {\n if (!audioAnalyzersRef.current.outputAnalyser || !outputFrequencyDataRef.current) return null;\n audioAnalyzersRef.current.outputAnalyser.getByteFrequencyData(outputFrequencyDataRef.current);\n return outputFrequencyDataRef.current;\n };\n\n const inputSource = audioContext.createMediaStreamSource(mediaStream);\n inputSourceRef.current = inputSource;\n inputSource.connect(inputAnalyser);\n\n return true;\n }, []);\n\n const waitForIceGathering = useCallback(\n (peerConnection) =>\n new Promise((resolve, reject) => {\n if (peerConnection.iceGatheringState === 'complete') {\n resolve();\n return;\n }\n\n let timeoutId = null;\n const handleStateChange = () => {\n if (peerConnection.iceGatheringState !== 'complete') return;\n clearTimeout(timeoutId);\n peerConnection.removeEventListener('icegatheringstatechange', handleStateChange);\n resolve();\n };\n\n timeoutId = setTimeout(() => {\n peerConnection.removeEventListener('icegatheringstatechange', handleStateChange);\n reject(new Error(ERROR_ICE_TIMEOUT));\n }, ICE_GATHERING_TIMEOUT);\n\n peerConnection.addEventListener('icegatheringstatechange', handleStateChange);\n }),\n [],\n );\n\n const registerPageHide = useCallback((fingerprint) => {\n const handlePageHide = () => {\n const sessionId = sessionIdRef.current;\n if (!sessionId || !fingerprint || typeof navigator.sendBeacon !== 'function') return;\n const query = new URLSearchParams({ fingerprint }).toString();\n navigator.sendBeacon(`${process.env.SERVICE_SYNAPSE}${SESSION_ENDPOINT}/${sessionId}/close?${query}`);\n };\n\n pageHideHandlerRef.current = handlePageHide;\n window.addEventListener('pagehide', handlePageHide);\n }, []);\n\n const openEventStream = useCallback(({ fingerprint, onClosed, onOpenUrl, sessionId }) => {\n const EventSourceConstructor = globalThis.EventSource;\n if (!EventSourceConstructor || !sessionId || !fingerprint) return;\n\n const query = new URLSearchParams({ fingerprint }).toString();\n const eventSource = new EventSourceConstructor(\n `${process.env.SERVICE_SYNAPSE}${SESSION_ENDPOINT}/${sessionId}/events?${query}`,\n );\n eventSourceRef.current = eventSource;\n eventSource.addEventListener(SSE_EVENT_OPEN_URL, onOpenUrl);\n eventSource.addEventListener(SSE_EVENT_CLOSED, onClosed);\n }, []);\n\n const playRemoteAudio = useCallback(() => {\n const audioElement = audioElementRef.current;\n if (!audioElement || typeof audioElement.play !== 'function') return;\n\n const reportBlockedPlayback = () => {\n Event.publish(EVENT.METRICS, { id: METRICS_EVENTS.AURA_ERROR, error: ERROR_AUDIO_PLAYBACK_BLOCKED });\n };\n\n try {\n const played = audioElement.play();\n if (played && typeof played.catch === 'function') played.catch(reportBlockedPlayback);\n } catch {\n reportBlockedPlayback();\n }\n }, []);\n\n const endSession = useCallback(async () => {\n if (closingRef.current) {\n await closingRef.current;\n return;\n }\n\n const attempt = attemptRef.current;\n const isCurrentAttempt = () => attemptRef.current === attempt;\n const fingerprint = fingerprintRef.current;\n const sessionId = sessionIdRef.current;\n if (!fingerprint || !sessionId) {\n cleanupLiveSession();\n return;\n }\n\n let timeoutId = null;\n const closing = Promise.race([\n request({\n endpoint: `${SESSION_ENDPOINT}/${sessionId}/close`,\n hostname: process.env.SERVICE_SYNAPSE,\n method: 'POST',\n fingerprint,\n }),\n new Promise((resolve) => {\n timeoutId = setTimeout(() => resolve(CLOSE_TIMEOUT_RESULT), SESSION_CLOSE_TIMEOUT);\n }),\n ]);\n closingRef.current = closing;\n\n try {\n const result = await closing;\n if (result === CLOSE_TIMEOUT_RESULT) {\n Event.publish(EVENT.METRICS, { id: METRICS_EVENTS.AURA_ERROR, error: ERROR_SESSION_CLOSE_UNCONFIRMED });\n }\n } catch (error) {\n Event.publish(EVENT.METRICS, {\n id: METRICS_EVENTS.AURA_ERROR,\n error: ERROR_SESSION_CLOSE_UNCONFIRMED,\n reason: error?.message,\n });\n } finally {\n clearTimeout(timeoutId);\n if (isCurrentAttempt()) cleanupLiveSession();\n }\n }, [cleanupLiveSession]);\n\n const startSession = useCallback(\n async ({ chainId, currency, hotelId, isChain, locale, setIsConnecting, setReady }) => {\n cleanupLiveSession();\n attemptRef.current += 1;\n\n const attempt = attemptRef.current;\n const isCurrentAttempt = () => attemptRef.current === attempt;\n\n let createdSessionId = null;\n let dataChannel = null;\n let mediaStream = null;\n let peerConnection = null;\n\n const releaseAttempt = () => {\n if (dataChannel) dataChannel.close();\n if (peerConnection) {\n peerConnection.getSenders().forEach(({ track }) => {\n if (track) track.stop();\n });\n peerConnection.close();\n }\n stopMediaStream(mediaStream);\n if (!createdSessionId) return;\n\n const abandonedSessionId = createdSessionId;\n createdSessionId = null;\n request({\n endpoint: `${SESSION_ENDPOINT}/${abandonedSessionId}/close`,\n hostname: process.env.SERVICE_SYNAPSE,\n method: 'POST',\n fingerprint,\n }).catch(() => {});\n };\n\n const abortWhenStale = () => {\n if (isCurrentAttempt()) return false;\n releaseAttempt();\n return true;\n };\n\n const fingerprint = getClientFingerprint();\n fingerprintRef.current = fingerprint;\n registerPageHide(fingerprint);\n\n const finalizeSession = () => {\n if (!isCurrentAttempt()) return;\n cleanupLiveSession();\n setReady(false);\n setIsConnecting(false);\n };\n\n const markReady = () => {\n if (!isCurrentAttempt()) return;\n const { connected, ready, receiving, started } = connectionStateRef.current;\n if (ready || !connected || !receiving || !started) return;\n connectionStateRef.current.ready = true;\n Event.publish(EVENT.METRICS, { id: METRICS_EVENTS.AURA_START });\n setReady(true);\n setIsConnecting(false);\n };\n\n const handleSessionClosed = (payload) => {\n const { reason } = payload;\n Event.publish(EVENT.METRICS, { id: METRICS_EVENTS.AURA_USAGE, reason, seconds: payload.usage?.seconds });\n if (closingRef.current) return;\n finalizeSession();\n };\n\n const handleServerEvent = ({ data }) => {\n if (!isCurrentAttempt()) return;\n const payload = parseServerEvent(data);\n if (!payload) return;\n const { error, session, type } = payload;\n\n if (type === 'session.started') {\n sessionIdRef.current = session?.id ?? sessionIdRef.current;\n connectionStateRef.current.started = true;\n markReady();\n }\n if (type === 'session.closed') handleSessionClosed(payload);\n if (type === 'error') Event.publish(EVENT.METRICS, { id: METRICS_EVENTS.AURA_ERROR, error: error?.message });\n };\n\n const handleStreamClosed = () => {\n if (!isCurrentAttempt() || closingRef.current) return;\n finalizeSession();\n };\n\n const handleStreamOpenUrl = ({ data }) => {\n if (!isCurrentAttempt()) return;\n const { url } = parseServerEvent(data) || {};\n const allowedUrl = getAllowedOpenUrl(url);\n\n if (!allowedUrl) {\n Event.publish(EVENT.METRICS, { id: METRICS_EVENTS.AURA_ERROR, error: ERROR_BLOCKED_OPEN_URL });\n return;\n }\n\n Promise.resolve(endSession())\n .catch(() => {})\n .then(() => window.location.assign(allowedUrl));\n };\n\n try {\n mediaStream = await navigator.mediaDevices.getUserMedia({ audio: AUDIO_CONSTRAINTS });\n if (abortWhenStale()) return;\n localStreamRef.current = mediaStream;\n\n const analyzersReady = await createAudioAnalyzers(mediaStream, isCurrentAttempt);\n if (!analyzersReady || abortWhenStale()) return;\n\n peerConnection = new RTCPeerConnection();\n peerConnectionRef.current = peerConnection;\n\n audioElementRef.current = document.createElement('audio');\n audioElementRef.current.autoplay = true;\n\n peerConnection.addEventListener('connectionstatechange', () => {\n if (!isCurrentAttempt()) return;\n const { connectionState } = peerConnection;\n if (connectionState === 'connected') {\n connectionStateRef.current.connected = true;\n markReady();\n return;\n }\n if (TERMINAL_CONNECTION_STATES.includes(connectionState)) finalizeSession();\n });\n\n peerConnection.ontrack = ({ streams }) => {\n if (!isCurrentAttempt()) return;\n const [remoteStream] = streams || [];\n if (!remoteStream) return;\n\n if (audioElementRef.current) audioElementRef.current.srcObject = remoteStream;\n playRemoteAudio();\n\n const audioContext = audioContextRef.current;\n const { outputAnalyser } = audioAnalyzersRef.current;\n if (audioContext && outputAnalyser) {\n if (outputSourceRef.current) outputSourceRef.current.disconnect();\n outputSourceRef.current = audioContext.createMediaStreamSource(remoteStream);\n outputSourceRef.current.connect(outputAnalyser);\n }\n\n connectionStateRef.current.receiving = true;\n markReady();\n };\n\n dataChannel = peerConnection.createDataChannel(DATA_CHANNEL_LABEL);\n dataChannelRef.current = dataChannel;\n dataChannel.addEventListener('message', handleServerEvent);\n dataChannel.addEventListener('close', () => {\n if (!isCurrentAttempt() || closingRef.current) return;\n finalizeSession();\n });\n dataChannel.addEventListener('error', () => {\n if (!isCurrentAttempt()) return;\n finalizeSession();\n });\n\n const [track] = mediaStream.getAudioTracks();\n if (track) peerConnection.addTrack(track, mediaStream);\n\n const offer = await peerConnection.createOffer();\n if (abortWhenStale()) return;\n\n await peerConnection.setLocalDescription(offer);\n if (abortWhenStale()) return;\n\n await waitForIceGathering(peerConnection);\n if (abortWhenStale()) return;\n\n const { sdp } = peerConnection.localDescription || {};\n if (!sdp) throw new Error(ERROR_MISSING_LOCAL_SDP);\n\n const { session, transport } = await request({\n endpoint: SESSION_ENDPOINT,\n hostname: process.env.SERVICE_SYNAPSE,\n method: 'POST',\n chainId: isChain ? chainId : undefined,\n currency,\n fingerprint,\n hotelId: isChain ? undefined : hotelId,\n locale,\n sdp,\n });\n createdSessionId = session?.id ?? null;\n if (abortWhenStale()) return;\n\n if (!transport?.sdp) throw new Error(ERROR_MISSING_REMOTE_SDP);\n sessionIdRef.current = createdSessionId;\n\n await peerConnection.setRemoteDescription({ type: 'answer', sdp: transport.sdp });\n if (abortWhenStale()) return;\n\n openEventStream({\n fingerprint,\n onClosed: handleStreamClosed,\n onOpenUrl: handleStreamOpenUrl,\n sessionId: sessionIdRef.current,\n });\n } catch (error) {\n releaseAttempt();\n Event.publish(EVENT.METRICS, { id: METRICS_EVENTS.AURA_ERROR, error: error?.message });\n if (isCurrentAttempt()) {\n cleanupLiveSession();\n setReady(false);\n setIsConnecting(false);\n }\n throw error;\n }\n },\n [\n cleanupLiveSession,\n createAudioAnalyzers,\n endSession,\n openEventStream,\n playRemoteAudio,\n registerPageHide,\n waitForIceGathering,\n ],\n );\n\n return { startSession, endSession, audioAnalyzers: audioAnalyzersRef.current };\n};\n\nexport { useLiveSession };\n"],"mappings":"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","ignoreList":[]}
@@ -8,6 +8,7 @@ var _dataSources = require("@mirai/data-sources");
8
8
  var _react = require("react");
9
9
  var _helpers = require("../../../../helpers");
10
10
  var _helpers2 = require("../../../helpers");
11
+ var _helpers3 = require("../helpers");
11
12
  function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
12
13
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
13
14
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
@@ -139,10 +140,6 @@ const useOpenAiRealtimeSession = () => {
139
140
  return null;
140
141
  }
141
142
  }, []);
142
- const isAllowedOpenUrl = (0, _react.useCallback)(url => {
143
- if (typeof url !== 'string') return false;
144
- return url.trim().startsWith('https://api.mirai');
145
- }, []);
146
143
  const enableMicrophone = (0, _react.useCallback)(() => {
147
144
  const track = localAudioTrackRef.current;
148
145
  if (!track || microphoneEnabledRef.current) return;
@@ -340,12 +337,12 @@ const useOpenAiRealtimeSession = () => {
340
337
  const callKey = call.key || call.callId || call.args || null;
341
338
  if (callKey && functionStateRef.current.handledOpenUrlCalls.has(callKey)) continue;
342
339
  const args = safeJsonParse(call.args);
343
- const url = args === null || args === void 0 ? void 0 : args.url;
344
- if (!isAllowedOpenUrl(url)) {
340
+ const allowedUrl = (0, _helpers3.getAllowedOpenUrl)(args === null || args === void 0 ? void 0 : args.url);
341
+ if (!allowedUrl) {
345
342
  if (call.callId) {
346
343
  sendFunctionCallOutput(call.callId, {
347
344
  error: 'blocked_url',
348
- allowed_prefix: 'https://api.mirai'
345
+ allowed_prefix: (0, _helpers3.getAllowedOpenUrlPrefix)()
349
346
  });
350
347
  requestFollowupResponse('open_url_blocked', call.callId);
351
348
  }
@@ -355,11 +352,11 @@ const useOpenAiRealtimeSession = () => {
355
352
  if (callKey) functionStateRef.current.handledOpenUrlCalls.add(callKey);
356
353
  if (call.key) functionStateRef.current.pendingCalls.delete(call.key);
357
354
  cleanupRealtimeSession(true);
358
- window.location.assign(url.trim());
355
+ window.location.assign(allowedUrl);
359
356
  return true;
360
357
  }
361
358
  return false;
362
- }, [cleanupRealtimeSession, getFunctionCallKey, isAllowedOpenUrl, requestFollowupResponse, safeJsonParse, sendFunctionCallOutput, upsertFunctionCall]);
359
+ }, [cleanupRealtimeSession, getFunctionCallKey, requestFollowupResponse, safeJsonParse, sendFunctionCallOutput, upsertFunctionCall]);
363
360
  const startSession = (0, _react.useCallback)(async _ref3 => {
364
361
  let assistant_name = _ref3.assistant_name,
365
362
  chainId = _ref3.chainId,