@whanext/core 0.19.3 → 0.19.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.19.4
4
+ ### Corrigido
5
+ - Corrigida a normalização de `timestampMs` dos eventos nativos de chamada; removida uma referência inválida ao helper privado `#number`.
6
+ - Chamadas no provider Zapo agora usam o evento nativo `call`, sem depender do plugin completo de VoIP.
7
+ - `rejectCall()` envia diretamente a sinalização mínima `<call><reject/></call>` pelo `client.lowlevel.sendNode()`, preservando `callId` e `callCreatorJid`.
8
+ - Removidas as dependências `@zapo-js/voip`, `@roamhq/wrtc` e `libmlow-wasm` do WhaNext Core; detectar/rejeitar chamadas não exige WebRTC nem binário nativo.
9
+ - O `callCreatorJid` técnico é mantido em cache limitado para que a rejeição use o endereço de protocolo correto mesmo quando o evento público expõe o `callerPnJid`.
10
+
11
+ ### Compatibilidade
12
+ - A API pública permanece igual: `app.on('call')`, `CallEvent` e `rejectCall(callId, from)` não mudam para consumidores.
13
+ - O suporte completo a aceitar/realizar chamadas VoIP não faz parte da API pública do WhaNext.
14
+
3
15
  ## 0.19.3
4
16
  ### Corrigido
5
17
  - Carregamento lazy do plugin VoIP do Zapo para evitar importar o runtime WebRTC em consumidores e testes que não inicializam o provider.
@@ -58,7 +58,7 @@ O provider usa `@zapo-js/media-utils`. Para processamento completo de imagem, v
58
58
 
59
59
  ## Chamadas
60
60
 
61
- O suporte a `app.on('call')` e `rejectCall()` usa o plugin oficial `@zapo-js/voip`. As dependências de runtime do plugin fazem parte do pacote do WhaNext v0.18.
61
+ A partir da v0.19.4, `app.on('call')` usa o evento `call` nativo do Zapo e `rejectCall()` envia somente a sinalização de rejeição pelo `client.lowlevel`. O WhaNext não carrega o stack completo de VoIP/WebRTC para detectar ou rejeitar chamadas.
62
62
 
63
63
  ## Checklist de atualização
64
64
 
package/README.md CHANGED
@@ -994,6 +994,8 @@ app.on('call', async (call) => {
994
994
 
995
995
  `call.status` reflete o ciclo da chamada (`offer`, `ringing`, `preaccept`, `timeout`, `reject`, `accept`). `call.isVideo` e `call.isGroup` indicam o tipo. Somente chamadas em `offer` podem ser rejeitadas.
996
996
 
997
+ No provider Zapo, detecção e rejeição usam apenas a sinalização nativa de chamadas e `client.lowlevel.sendNode()`. O WhaNext não carrega o stack completo de VoIP/WebRTC para esse fluxo.
998
+
997
999
  ## Erros
998
1000
 
999
1001
  ```ts
package/dist/index.js CHANGED
@@ -2710,6 +2710,7 @@ var ZapoProvider = class {
2710
2710
  #messageKeyStore = /* @__PURE__ */ new WeakMap();
2711
2711
  #deliveredMessageStore = /* @__PURE__ */ new Set();
2712
2712
  #handledProtocolStore = /* @__PURE__ */ new Set();
2713
+ #callCreatorStore = /* @__PURE__ */ new Map();
2713
2714
  #messageCacheSize;
2714
2715
  #client;
2715
2716
  #intentionalClose = false;
@@ -2965,9 +2966,26 @@ var ZapoProvider = class {
2965
2966
  const presence = this.#requireClient().presence;
2966
2967
  await presence.sendChatstate(chatId, { state: value });
2967
2968
  }
2968
- async rejectCall(callId, _from) {
2969
+ async rejectCall(callId, from) {
2969
2970
  const client = this.#requireClient();
2970
- await client.voip.rejectCall(callId);
2971
+ const creator = this.#callCreatorStore.get(callId) ?? from;
2972
+ if (!creator) {
2973
+ throw new WhaNextError("ARGUMENT_INVALID", "Call creator is required to reject a call.");
2974
+ }
2975
+ const lowlevel = client.lowlevel;
2976
+ await lowlevel.sendNode({
2977
+ tag: "call",
2978
+ attrs: { to: creator },
2979
+ content: [
2980
+ {
2981
+ tag: "reject",
2982
+ attrs: {
2983
+ "call-id": callId,
2984
+ "call-creator": creator
2985
+ }
2986
+ }
2987
+ ]
2988
+ });
2971
2989
  }
2972
2990
  async #ensureClient() {
2973
2991
  if (this.#client) return this.#client;
@@ -2996,8 +3014,6 @@ var ZapoProvider = class {
2996
3014
  messageSecret: "sqlite"
2997
3015
  }
2998
3016
  });
2999
- const { voipPlugin } = await import("@zapo-js/voip");
3000
- const voip = voipPlugin({ logLevel: "warn" });
3001
3017
  const client = new WaClient({
3002
3018
  store,
3003
3019
  sessionId: this.#options.sessionId ?? "default",
@@ -3009,8 +3025,7 @@ var ZapoProvider = class {
3009
3025
  autoDecrypt: true,
3010
3026
  persistAllSecrets: true
3011
3027
  },
3012
- media: { processor: createMediaProcessor() },
3013
- plugins: [voip]
3028
+ media: { processor: createMediaProcessor() }
3014
3029
  }, new WhaNextZapoLogger(this.#logger));
3015
3030
  this.#client = client;
3016
3031
  this.#bind(client);
@@ -3050,22 +3065,8 @@ var ZapoProvider = class {
3050
3065
  client.on("group", (event) => {
3051
3066
  this.#handleGroupEvent(event);
3052
3067
  });
3053
- const voipClient = client;
3054
- voipClient.on("voip_call_incoming", (event) => {
3055
- const call = this.#normalizeVoipCall(event, "offer");
3056
- if (call) void this.#events.emit("call", call);
3057
- });
3058
- voipClient.on("voip_call_state", (event) => {
3059
- const state = event.stateData?.state;
3060
- if (state === "incoming_ringing" || state === "ended") return;
3061
- const call = this.#normalizeVoipCall(event);
3062
- if (call) void this.#events.emit("call", call);
3063
- });
3064
- voipClient.on("voip_call_ended", (event) => {
3065
- const call = this.#normalizeVoipCall(
3066
- event,
3067
- this.#callEndStatus(event.stateData?.endReason)
3068
- );
3068
+ client.on("call", (event) => {
3069
+ const call = this.#normalizeCall(event);
3069
3070
  if (call) void this.#events.emit("call", call);
3070
3071
  });
3071
3072
  client.on("connection", (event) => {
@@ -3571,49 +3572,49 @@ var ZapoProvider = class {
3571
3572
  timestamp: /* @__PURE__ */ new Date()
3572
3573
  };
3573
3574
  }
3574
- #normalizeVoipCall(event, forcedStatus) {
3575
+ #normalizeCall(event) {
3575
3576
  const id = event.callId;
3576
- const from = event.callerPn ?? event.peerJid ?? event.callCreator;
3577
- const chatId = event.groupJid ?? event.peerJid ?? from;
3577
+ const creator = event.callCreatorJid ?? void 0;
3578
+ const from = event.callerPnJid ?? creator;
3579
+ const chatId = event.groupJid ?? from;
3578
3580
  if (!id || !from || !chatId) return void 0;
3581
+ if (creator) {
3582
+ this.#callCreatorStore.delete(id);
3583
+ this.#callCreatorStore.set(id, creator);
3584
+ while (this.#callCreatorStore.size > 256) {
3585
+ const oldest = this.#callCreatorStore.keys().next().value;
3586
+ if (!oldest) break;
3587
+ this.#callCreatorStore.delete(oldest);
3588
+ }
3589
+ }
3590
+ const timestampMs = toNumber2(event.timestampMs);
3579
3591
  return {
3580
3592
  id,
3581
3593
  chatId,
3582
3594
  from,
3583
- status: forcedStatus ?? this.#callStatus(event.stateData?.state),
3584
- isVideo: event.mediaType === "video",
3595
+ status: this.#callStatus(event.type),
3596
+ isVideo: event.isVideo === true,
3585
3597
  isGroup: Boolean(event.groupJid),
3586
- date: event.createdAt ?? /* @__PURE__ */ new Date()
3598
+ date: timestampMs && timestampMs > 0 ? new Date(timestampMs) : /* @__PURE__ */ new Date()
3587
3599
  };
3588
3600
  }
3589
3601
  #callStatus(status) {
3590
3602
  switch (status?.toLowerCase()) {
3591
3603
  case "offer":
3592
- case "initiating":
3593
3604
  return "offer";
3594
3605
  case "ringing":
3595
- case "incoming_ringing":
3596
3606
  return "ringing";
3597
3607
  case "preaccept":
3598
- case "connecting":
3599
3608
  return "preaccept";
3600
3609
  case "accept":
3601
- case "accepted":
3602
- case "active":
3603
3610
  return "accept";
3604
3611
  case "reject":
3605
- case "rejected":
3606
3612
  case "terminate":
3607
- case "terminated":
3608
- case "ended":
3609
3613
  return "reject";
3610
3614
  default:
3611
3615
  return "timeout";
3612
3616
  }
3613
3617
  }
3614
- #callEndStatus(reason) {
3615
- return reason?.toLowerCase() === "timeout" ? "timeout" : "reject";
3616
- }
3617
3618
  #groupAction(action) {
3618
3619
  const value = action?.toLowerCase() ?? "";
3619
3620
  if (value.includes("promote")) return "promote";
@@ -3773,6 +3774,12 @@ var WhaNextZapoLogger = class _WhaNextZapoLogger {
3773
3774
  return context ? { ...this.#context, ...context } : this.#context;
3774
3775
  }
3775
3776
  };
3777
+ function toNumber2(value) {
3778
+ if (typeof value === "number") return value;
3779
+ if (value?.toNumber) return value.toNumber();
3780
+ if (typeof value?.low === "number") return value.low;
3781
+ return void 0;
3782
+ }
3776
3783
  function toSeconds(value) {
3777
3784
  const raw = typeof value === "number" ? value : value?.toNumber ? value.toNumber() : value?.low;
3778
3785
  if (raw === void 0) return void 0;