@ipcom/asterisk-ari 0.0.102 → 0.0.103

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/esm/index.js CHANGED
@@ -910,38 +910,41 @@ function isChannelEvent(event, channelId) {
910
910
  // src/ari-client/resources/channels.ts
911
911
  var ChannelInstance = class extends EventEmitter2 {
912
912
  // ID do canal
913
- constructor(client, baseClient, channelId = `channel-${Date.now()}`) {
913
+ constructor(client, baseClient, channelId = `channel-${Date.now()}`, app) {
914
914
  super();
915
915
  this.client = client;
916
916
  this.baseClient = baseClient;
917
917
  this.channelId = channelId;
918
+ this.app = app;
918
919
  this.id = channelId || `channel-${Date.now()}`;
919
920
  const wsClients = this.client.getWebSocketClients();
920
- const wsClient = Array.from(wsClients.values()).find(
921
- (client2) => client2.isConnected()
922
- );
921
+ const wsClient = wsClients.get(this.app);
923
922
  if (!wsClient) {
924
923
  throw new Error(
925
924
  `Nenhum WebSocket conectado dispon\xEDvel para o canal: ${this.id}`
926
925
  );
927
926
  }
928
- try {
929
- wsClient.addScopedMessageListener(this.id, (event) => {
927
+ wsClient.addScopedMessageListener(
928
+ this.id,
929
+ this.app,
930
+ (event) => {
930
931
  if (isChannelEvent(event, this.id)) {
931
932
  const channelEventType = event.type;
932
933
  this.emit(channelEventType, event);
933
934
  }
934
- });
935
- } catch (error) {
936
- console.error(
937
- `Erro ao adicionar listener escopado para canal '${this.id}':`,
938
- error
939
- );
940
- throw error;
941
- }
935
+ }
936
+ );
942
937
  this.on("removeListener", (eventName) => {
943
938
  if (this.eventNames().length === 0 || this.listenerCount(eventName) === 0) {
944
- wsClient.removeScopedMessageListeners(this.id);
939
+ wsClient.removeScopedMessageListeners(this.id, this.app);
940
+ console.log(
941
+ `Listeners escopados removidos para canal '${this.id}' no app '${this.app}'.`
942
+ );
943
+ }
944
+ });
945
+ this.on("removeListener", (eventName) => {
946
+ if (this.eventNames().length === 0 || this.listenerCount(eventName) === 0) {
947
+ wsClient.removeScopedMessageListeners(this.id, this.app);
945
948
  console.log(`Listeners escopados removidos para canal '${this.id}'.`);
946
949
  }
947
950
  });
@@ -977,14 +980,14 @@ var ChannelInstance = class extends EventEmitter2 {
977
980
  console.log(`Recebido evento '${event}' para canal '${this.id}'`);
978
981
  this.emit(event, webSocketEvent);
979
982
  callback(webSocketEvent);
980
- wsClient.removeScopedMessageListeners(this.id);
983
+ wsClient.removeScopedMessageListeners(this.id, this.app);
981
984
  console.log(
982
985
  `Listeners escopados para canal '${this.id}' foram removidos.`
983
986
  );
984
987
  }
985
988
  };
986
989
  try {
987
- wsClient.addScopedMessageListener(this.id, globalListener);
990
+ wsClient.addScopedMessageListener(this.id, this.app, globalListener);
988
991
  } catch (error) {
989
992
  console.error(
990
993
  `Erro ao adicionar listener escopado em 'once' para canal '${this.id}':`,
@@ -1188,8 +1191,13 @@ var Channels = class extends EventEmitter2 {
1188
1191
  this.baseClient = baseClient;
1189
1192
  this.client = client;
1190
1193
  }
1191
- Channel(channelId) {
1192
- return new ChannelInstance(this.client, this.baseClient, channelId);
1194
+ Channel({ id, app }) {
1195
+ if (!app) {
1196
+ throw new Error(
1197
+ "O nome do aplicativo (app) \xE9 obrigat\xF3rio para criar um Channel."
1198
+ );
1199
+ }
1200
+ return new ChannelInstance(this.client, this.baseClient, id, app);
1193
1201
  }
1194
1202
  /**
1195
1203
  * Origina um canal físico diretamente, sem uma instância de `ChannelInstance`.
@@ -1419,11 +1427,12 @@ var Endpoints = class {
1419
1427
  import { EventEmitter as EventEmitter3 } from "events";
1420
1428
  var PlaybackInstance = class extends EventEmitter3 {
1421
1429
  // Garantimos que o ID esteja disponível
1422
- constructor(client, baseClient, playbackId = `playback-${Date.now()}`) {
1430
+ constructor(client, baseClient, playbackId = `playback-${Date.now()}`, app) {
1423
1431
  super();
1424
1432
  this.client = client;
1425
1433
  this.baseClient = baseClient;
1426
1434
  this.playbackId = playbackId;
1435
+ this.app = app;
1427
1436
  this.id = playbackId || `playback-${Date.now()}`;
1428
1437
  const wsClients = this.client.getWebSocketClients();
1429
1438
  const wsClient = Array.from(wsClients.values()).find(
@@ -1435,12 +1444,16 @@ var PlaybackInstance = class extends EventEmitter3 {
1435
1444
  );
1436
1445
  }
1437
1446
  try {
1438
- wsClient.addScopedMessageListener(this.id, (event) => {
1439
- if (isPlaybackEvent(event, this.id)) {
1440
- const playbackEventType = event.type;
1441
- this.emit(playbackEventType, event);
1447
+ wsClient.addScopedMessageListener(
1448
+ this.id,
1449
+ this.app,
1450
+ (event) => {
1451
+ if (isPlaybackEvent(event, this.id)) {
1452
+ const playbackEventType = event.type;
1453
+ this.emit(playbackEventType, event);
1454
+ }
1442
1455
  }
1443
- });
1456
+ );
1444
1457
  } catch (error) {
1445
1458
  console.error(
1446
1459
  `Erro ao adicionar listener escopado para playback '${this.id}':`,
@@ -1450,7 +1463,7 @@ var PlaybackInstance = class extends EventEmitter3 {
1450
1463
  }
1451
1464
  this.on("removeListener", (eventName) => {
1452
1465
  if (this.eventNames().length === 0 || this.listenerCount(eventName) === 0) {
1453
- wsClient.removeScopedMessageListeners(this.id);
1466
+ wsClient.removeScopedMessageListeners(this.id, this.app);
1454
1467
  console.log(
1455
1468
  `Listeners escopados removidos para playback '${this.id}'.`
1456
1469
  );
@@ -1491,14 +1504,14 @@ var PlaybackInstance = class extends EventEmitter3 {
1491
1504
  console.log(`Recebido evento '${event}' para playback '${this.id}'`);
1492
1505
  this.emit(event, webSocketEvent);
1493
1506
  callback(webSocketEvent);
1494
- wsClient.removeScopedMessageListeners(this.id);
1507
+ wsClient.removeScopedMessageListeners(this.id, this.app);
1495
1508
  console.log(
1496
1509
  `Listeners escopados para playback '${this.id}' foram removidos.`
1497
1510
  );
1498
1511
  }
1499
1512
  };
1500
1513
  try {
1501
- wsClient.addScopedMessageListener(this.id, globalListener);
1514
+ wsClient.addScopedMessageListener(this.id, this.app, globalListener);
1502
1515
  } catch (error) {
1503
1516
  console.error(
1504
1517
  `Erro ao adicionar listener escopado em 'once' para playback '${this.id}':`,
@@ -1576,9 +1589,14 @@ var Playbacks = class extends EventEmitter3 {
1576
1589
  /**
1577
1590
  * Inicializa uma nova instância de `PlaybackInstance`.
1578
1591
  */
1579
- Playback(playbackId) {
1580
- const id = playbackId || `playback-${Date.now()}`;
1581
- return new PlaybackInstance(this.client, this.baseClient, id);
1592
+ Playback({ id, app }) {
1593
+ if (!app) {
1594
+ throw new Error(
1595
+ "O nome do aplicativo (app) \xE9 obrigat\xF3rio para criar um Channel."
1596
+ );
1597
+ }
1598
+ const playbackId = id || `playback-${Date.now()}`;
1599
+ return new PlaybackInstance(this.client, this.baseClient, playbackId, app);
1582
1600
  }
1583
1601
  /**
1584
1602
  * Obtém os clientes WebSocket disponíveis.
@@ -1841,28 +1859,36 @@ var WebSocketClient = class extends EventEmitter4 {
1841
1859
  /**
1842
1860
  * Adiciona um listener escopado ao evento "message".
1843
1861
  * @param instanceId - Identificador único da instância que está registrando o listener.
1862
+ * @param app
1844
1863
  * @param callback - Função de callback para o evento.
1845
1864
  */
1846
- addScopedMessageListener(instanceId, callback) {
1847
- if (this.scopedListeners.has(instanceId)) {
1865
+ addScopedMessageListener(instanceId, app, callback) {
1866
+ const key = `${app}:${instanceId}`;
1867
+ if (this.scopedListeners.has(key)) {
1848
1868
  console.warn(
1849
- `Listener escopado para a inst\xE2ncia '${instanceId}' j\xE1 existe. Ignorando duplica\xE7\xE3o.`
1869
+ `Listener escopado para a inst\xE2ncia '${key}' j\xE1 existe. Ignorando.`
1850
1870
  );
1851
1871
  return;
1852
1872
  }
1853
1873
  const scopedListener = (data) => {
1854
- if (data.type.startsWith("Channel") && "channel" in data && data.channel?.id === instanceId || data.type.startsWith("Playback") && "playbackId" in data && data.playbackId === instanceId) {
1855
- console.log(data);
1856
- console.log(
1857
- `Listener escopado para a inst\xE2ncia '${instanceId}' ativado.`
1874
+ try {
1875
+ if (data.application === app && (data.type.startsWith("Channel") && "channel" in data && data.channel?.id === instanceId || data.type.startsWith("Playback") && "playbackId" in data && data.playbackId === instanceId)) {
1876
+ console.log(
1877
+ `Listener escopado ativado para inst\xE2ncia '${instanceId}' no app '${app}'.`
1878
+ );
1879
+ callback(data);
1880
+ }
1881
+ } catch (error) {
1882
+ console.error(
1883
+ `Erro no listener escopado para inst\xE2ncia '${instanceId}' no app '${app}':`,
1884
+ error
1858
1885
  );
1859
- callback(data);
1860
1886
  }
1861
1887
  };
1862
- this.scopedListeners.set(instanceId, scopedListener);
1888
+ this.scopedListeners.set(key, scopedListener);
1863
1889
  this.on("message", scopedListener);
1864
1890
  console.log(
1865
- `Listener escopado adicionado para a inst\xE2ncia '${instanceId}'. Total de listeners: ${this.listenerCount(
1891
+ `Listener escopado adicionado para a inst\xE2ncia '${instanceId}' no app '${app}'. Total de listeners: ${this.listenerCount(
1866
1892
  "message"
1867
1893
  )}`
1868
1894
  );
@@ -1870,23 +1896,25 @@ var WebSocketClient = class extends EventEmitter4 {
1870
1896
  /**
1871
1897
  * Remove todos os listeners associados a uma instância específica.
1872
1898
  * @param instanceId - Identificador da instância cujos listeners serão removidos.
1899
+ * @param app
1873
1900
  */
1874
- removeScopedMessageListeners(instanceId) {
1875
- if (!this.scopedListeners.has(instanceId)) {
1876
- console.warn(
1877
- `Nenhum listener encontrado para a inst\xE2ncia '${instanceId}'.`
1878
- );
1901
+ removeScopedMessageListeners(instanceId, app) {
1902
+ const key = `${app}:${instanceId}`;
1903
+ if (!this.scopedListeners.has(key)) {
1904
+ console.warn(`Nenhum listener encontrado para a inst\xE2ncia '${key}'.`);
1879
1905
  return;
1880
1906
  }
1881
- const scopedListener = this.scopedListeners.get(instanceId);
1907
+ const scopedListener = this.scopedListeners.get(key);
1882
1908
  if (scopedListener) {
1883
1909
  this.off("message", scopedListener);
1884
- this.scopedListeners.delete(instanceId);
1910
+ this.scopedListeners.delete(key);
1885
1911
  console.log(
1886
- `Listeners removidos para a inst\xE2ncia '${instanceId}'. Total de listeners restantes: ${this.listenerCount(
1912
+ `Listeners removidos para a inst\xE2ncia '${key}'. Total de listeners restantes: ${this.listenerCount(
1887
1913
  "message"
1888
1914
  )}`
1889
1915
  );
1916
+ } else {
1917
+ console.warn(`Listener j\xE1 foi removido para a inst\xE2ncia '${key}'.`);
1890
1918
  }
1891
1919
  }
1892
1920
  /**
@@ -1896,13 +1924,14 @@ var WebSocketClient = class extends EventEmitter4 {
1896
1924
  handleMessage(rawData) {
1897
1925
  try {
1898
1926
  const decodedData = JSON.parse(rawData.toString());
1899
- if (decodedData?.type) {
1900
- this.emit(decodedData.type, decodedData);
1901
- if (this.listenerCount("message") > 0) {
1902
- this.emit("message", decodedData);
1903
- }
1927
+ if (decodedData?.type && decodedData?.application) {
1928
+ this.emit(decodedData.application, decodedData);
1929
+ this.emit("message", decodedData);
1904
1930
  } else {
1905
- console.warn("Mensagem recebida sem tipo:", decodedData);
1931
+ console.warn(
1932
+ "Mensagem recebida sem tipo ou aplica\xE7\xE3o v\xE1lida:",
1933
+ decodedData
1934
+ );
1906
1935
  }
1907
1936
  } catch (err) {
1908
1937
  console.error("Erro ao decodificar mensagem do WebSocket:", err);
@@ -2012,14 +2041,18 @@ var AriClient = class {
2012
2041
  * Registra listeners globais para eventos de WebSocket.
2013
2042
  */
2014
2043
  on(eventType, callback, app) {
2044
+ if (!app) {
2045
+ throw new Error(
2046
+ "O nome do app \xE9 obrigat\xF3rio para registrar um listener de evento."
2047
+ );
2048
+ }
2015
2049
  console.log(
2016
- app ? `Registrando listener para evento '${eventType}' no app '${app}'` : `Registrando listener global para evento: '${eventType}'`
2050
+ `Registrando listener para evento '${eventType}' no app '${app}'.`
2017
2051
  );
2018
- console.log("********************************************** ", app);
2019
- const callbackKey = app ? `${eventType}-${app}` : eventType;
2052
+ const callbackKey = `${eventType}-${app}`;
2020
2053
  if (this.eventListeners.has(callbackKey)) {
2021
2054
  console.log(
2022
- `Listener para evento '${eventType}' j\xE1 est\xE1 registrado${app ? ` no app '${app}'` : " globalmente"}. Ignorando duplicata.`
2055
+ `Listener para evento '${eventType}' j\xE1 est\xE1 registrado no app '${app}'. Ignorando duplicata.`
2023
2056
  );
2024
2057
  return;
2025
2058
  }
@@ -2028,7 +2061,7 @@ var AriClient = class {
2028
2061
  const channelId = event.channel.id;
2029
2062
  if (channelId) {
2030
2063
  if (!this.channelInstances.has(channelId)) {
2031
- const channelInstance = this.createChannelInstance(channelId);
2064
+ const channelInstance = this.createChannelInstance(channelId, app);
2032
2065
  this.channelInstances.set(channelId, channelInstance);
2033
2066
  }
2034
2067
  event.instanceChannel = this.channelInstances.get(channelId);
@@ -2037,19 +2070,15 @@ var AriClient = class {
2037
2070
  }
2038
2071
  callback(event);
2039
2072
  };
2040
- if (app) {
2041
- const wsClient = this.wsClients.get(app);
2042
- if (wsClient) {
2043
- wsClient.on(eventType, wrappedCallback);
2044
- this.eventListeners.set(callbackKey, wrappedCallback);
2045
- } else {
2046
- console.warn(`WebSocket para o app '${app}' n\xE3o est\xE1 conectado.`);
2047
- }
2048
- } else {
2049
- for (const [_app, wsClient] of this.wsClients.entries()) {
2050
- wsClient.on(eventType, wrappedCallback);
2051
- }
2073
+ const wsClient = this.wsClients.get(app);
2074
+ if (wsClient) {
2075
+ wsClient.on(eventType, wrappedCallback);
2052
2076
  this.eventListeners.set(callbackKey, wrappedCallback);
2077
+ console.log(
2078
+ `Listener para evento '${eventType}' registrado com sucesso no app '${app}'.`
2079
+ );
2080
+ } else {
2081
+ console.warn(`WebSocket para o app '${app}' n\xE3o est\xE1 conectado.`);
2053
2082
  }
2054
2083
  }
2055
2084
  removeListener(eventType, app) {
@@ -2092,17 +2121,20 @@ var AriClient = class {
2092
2121
  return data?.channel?.id !== void 0;
2093
2122
  }
2094
2123
  // Método para criar uma instância de ChannelInstance
2095
- createChannelInstance(channelId) {
2096
- return this.channels.Channel(channelId);
2124
+ createChannelInstance(channelId, app) {
2125
+ return this.channels.Channel({
2126
+ id: channelId,
2127
+ app
2128
+ });
2097
2129
  }
2098
- handleWebSocketEvent(event) {
2130
+ handleWebSocketEvent(event, app) {
2099
2131
  console.log("Evento recebido no WebSocket:", event.type, event);
2100
2132
  const { type, ...data } = event;
2101
2133
  if (this.hasChannel(data)) {
2102
2134
  const channelId = data.channel.id;
2103
2135
  if (channelId) {
2104
2136
  if (!this.channelInstances.has(channelId)) {
2105
- const channelInstance2 = this.createChannelInstance(channelId);
2137
+ const channelInstance2 = this.createChannelInstance(channelId, app);
2106
2138
  this.channelInstances.set(channelId, channelInstance2);
2107
2139
  }
2108
2140
  const channelInstance = this.channelInstances.get(channelId);
@@ -2140,8 +2172,9 @@ var AriClient = class {
2140
2172
  if (!Array.isArray(apps) || apps.length === 0) {
2141
2173
  throw new Error("\xC9 necess\xE1rio fornecer pelo menos um aplicativo.");
2142
2174
  }
2175
+ const uniqueApps = [...new Set(apps)];
2143
2176
  return Promise.all(
2144
- apps.map(async (app) => {
2177
+ uniqueApps.map(async (app) => {
2145
2178
  if (this.wsClients.has(app)) {
2146
2179
  console.log(`Conex\xE3o WebSocket para '${app}' j\xE1 existe. Ignorando.`);
2147
2180
  return;
@@ -2331,19 +2364,31 @@ var AriClient = class {
2331
2364
  * Inicializa uma nova instância de `ChannelInstance` para manipular canais localmente.
2332
2365
  *
2333
2366
  * @param channelId - O ID do canal, se disponível. Caso contrário, a instância será para um canal ainda não criado.
2367
+ * @param app
2334
2368
  * @returns Uma instância de `ChannelInstance` vinculada ao cliente atual.
2335
2369
  */
2336
- Channel(channelId) {
2337
- return this.channels.Channel(channelId);
2370
+ Channel(channelId, app) {
2371
+ if (!app) {
2372
+ throw new Error(
2373
+ "O nome do aplicativo (app) \xE9 obrigat\xF3rio para criar um Channel."
2374
+ );
2375
+ }
2376
+ return this.channels.Channel({ id: channelId, app });
2338
2377
  }
2339
2378
  /**
2340
2379
  * Inicializa uma nova instância de `PlaybackInstance` para manipular playbacks.
2341
2380
  *
2342
2381
  * @param playbackId - O ID do playback, se disponível. Caso contrário, a instância será para um playback ainda não inicializado.
2382
+ * @param app
2343
2383
  * @returns Uma instância de `PlaybackInstance` vinculada ao cliente atual.
2344
2384
  */
2345
- Playback(playbackId) {
2346
- return this.playbacks.Playback(playbackId);
2385
+ Playback(playbackId, app) {
2386
+ if (!app) {
2387
+ throw new Error(
2388
+ "O nome do aplicativo (app) \xE9 obrigat\xF3rio para criar um Channel."
2389
+ );
2390
+ }
2391
+ return this.playbacks.Playback({ id: playbackId, app });
2347
2392
  }
2348
2393
  };
2349
2394
  export {