@whanext/core 0.19.15 → 0.19.18

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,50 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.19.18
4
+
5
+ ### Stability
6
+ - Added bounded command queues for `strategy: 'queue'`: `maxQueue` defaults to 10 waiting executions and `queueTimeoutMs` defaults to 60 seconds. Set either option to `0` to disable that limit.
7
+ - Added `COMMAND_QUEUE_FULL` and `COMMAND_QUEUE_TIMEOUT` with typed `commandQueueFull` and `commandQueueTimeout` application events.
8
+ - Added explicit Zapo transport/query timeouts through `providerTimeouts.connectTimeoutMs` and `providerTimeouts.nodeQueryTimeoutMs`, defaulting to 15 seconds and 30 seconds.
9
+ - Stability event listeners are isolated from provider recovery work so consumer handler failures cannot turn a successful metadata recovery into a provider failure.
10
+
11
+ ### Health
12
+ - Expanded `app.health()` without removing the existing fields. It now exposes `stability`, connection/reconnect state, messaging counters, crypto degradation counters, group metadata recovery counters, command queue metrics, and effective provider timeouts.
13
+ - Added `healthy`, `degraded`, `reconnecting`, and `offline` operational stability states. Transient crypto/group warnings move the provider to `degraded` for a bounded window and automatically return it to `healthy`.
14
+ - Added typed `healthChanged`, `connectionRecovered`, `groupMetadataRecovered`, and `cryptoDegraded` events.
15
+
16
+ ### Performance
17
+ - Added `@zapo-js/native@0.1.0` as an optional dependency. Zapo automatically uses its X25519/XEdDSA accelerator when available and falls back to JavaScript when unavailable.
18
+ - Health reports the detected crypto backend as `napi`, `wasm`, `js`, or `unknown`; the published optional package is detected as WASM on supported Node runtimes while locally built N-API addons are reported only when they can actually be loaded.
19
+
20
+ ### Compatibility
21
+ - Existing command concurrency declarations remain valid; the queue limits only affect commands that already use `strategy: 'queue'`.
22
+ - Custom providers are not required to implement `health()`; WhaNext supplies neutral health fallbacks when a provider does not expose runtime metrics.
23
+
24
+ ## 0.19.17
25
+
26
+ ### Reliability
27
+ - Group sends now self-heal when Zapo reports an acknowledged participant-hash mismatch: WhaNext invalidates only the affected group's metadata cache, fetches fresh server metadata, invalidates the public group snapshot, and rate-limits recovery to once per group per minute.
28
+ - Volatile Zapo `groupMetadata` and `deviceList` memory caches now expire after 3 minutes instead of the 5-minute default, reducing stale LID/device fan-out windows without disabling caching or forcing an IQ/usync on every send.
29
+ - Transient WhatsApp disconnects now retry indefinitely by default with the existing exponential backoff; applications that set `reconnect.maxAttempts` keep their explicit limit. Fatal/logout reasons still stop reconnection immediately.
30
+
31
+ ### Performance
32
+ - The shared Zapo SQLite store now uses `WAL`, `synchronous=NORMAL`, and a 5-second `busy_timeout`, improving concurrent reads/writes for persisted Signal, sender-key, mailbox, and app-state data.
33
+ - The WhaNext mutation-snapshot SQLite database now uses the same WAL/NORMAL settings, reducing fsync contention on active bots.
34
+
35
+ ### Safety
36
+ - Sender keys and Signal sessions are never globally reset during mismatch recovery. Zapo's normal retry-receipt/decryption recovery remains authoritative; WhaNext only refreshes stale group metadata.
37
+
38
+ ## 0.19.16
39
+
40
+ ### Fixed
41
+ - Remote media URLs are now streamed into Zapo instead of being fully materialized as `Uint8Array` in memory before upload. This removes the extra whole-file buffering step that could stall or intermittently fail larger MP3/audio sends.
42
+ - Remote media fetches now have a bounded 120-second transfer timeout and surface provider errors when the source cannot be opened or returns an empty body.
43
+ - Local paths and caller-provided byte arrays keep their existing behavior.
44
+
45
+ ### Performance
46
+ - URL-backed audio/video/image uploads now follow Zapo's recommended streaming media path, keeping memory usage flat while Zapo stages, hashes, encrypts, and uploads the attachment.
47
+
3
48
  ## 0.19.15
4
49
 
5
50
  ### Added
package/README.md CHANGED
@@ -311,20 +311,27 @@ const app = await create({
311
311
 
312
312
  ## Health checks
313
313
 
314
- `app.health()` entrega um snapshot sem consultar o WhatsApp novamente:
314
+ `app.health()` entrega um snapshot local e barato, sem consultar o WhatsApp novamente. Os campos antigos permanecem disponíveis e a camada de estabilidade acrescenta conexão, mensagens, crypto, grupos, filas e timeouts:
315
315
 
316
316
  ```ts
317
317
  const health = app.health();
318
318
 
319
319
  console.log(health.status);
320
+ console.log(health.stability);
320
321
  console.log(health.ready);
321
322
  console.log(health.state);
322
323
  console.log(health.uptimeMs);
323
- console.log(health.muteEnabled);
324
- console.log(health.logLevel);
324
+ console.log(health.connection);
325
+ console.log(health.messaging);
326
+ console.log(health.crypto);
327
+ console.log(health.groups);
328
+ console.log(health.commands);
329
+ console.log(health.timeouts);
325
330
  ```
326
331
 
327
- Estados possíveis: `idle`, `starting`, `ready` e `stopped`.
332
+ `status` continua representando o ciclo da aplicação: `idle`, `starting`, `ready` ou `stopped`. `stability` representa a saúde operacional do provider: `healthy`, `degraded`, `reconnecting` ou `offline`.
333
+
334
+ O provider Zapo contabiliza reconexões, mensagens enviadas/recebidas, falhas de envio, falhas de descriptografia, `sender key id mismatch`, falhas de addons, divergências de `phash` e recuperações de metadata. O router contabiliza execuções ativas, fila atual, expirações e rejeições por fila cheia.
328
335
 
329
336
  ```ts
330
337
  server.get('/health', async () => app.health());
@@ -333,11 +340,67 @@ server.get('/health', async () => app.health());
333
340
  Para uma verificação simples:
334
341
 
335
342
  ```ts
336
- if (app.isReady) {
337
- console.log('Aplicação pronta.');
343
+ if (app.isReady && app.health().stability === 'healthy') {
344
+ console.log('Aplicação pronta e saudável.');
338
345
  }
339
346
  ```
340
347
 
348
+ ## Estabilidade do provider
349
+
350
+ O provider oficial usa timeouts explícitos para conexão e queries de protocolo. Os padrões são 15 segundos para conexão e 30 segundos para queries; ambos podem ser ajustados na criação da aplicação:
351
+
352
+ ```ts
353
+ const app = await create({
354
+ providerTimeouts: {
355
+ connectTimeoutMs: 15_000,
356
+ nodeQueryTimeoutMs: 30_000,
357
+ },
358
+ });
359
+ ```
360
+
361
+ Valores menores que 1 segundo são normalizados para 1 segundo. Os valores efetivos ficam disponíveis em `app.health().timeouts`.
362
+
363
+ A aceleração crypto do Zapo também é integrada de forma opcional. `@zapo-js/native` acelera X25519 e XEdDSA e o provider continua funcionando com o backend JavaScript caso o acelerador não esteja disponível. O pacote publicado usa WASM; um build N-API local também é detectado quando realmente carregável.
364
+
365
+ ```ts
366
+ const health = app.health();
367
+
368
+ console.log(health.crypto.backend);
369
+ console.log(health.crypto.acceleration);
370
+ ```
371
+
372
+ Backends reportados: `napi`, `wasm`, `js` ou `unknown`. Para forçar o fallback JavaScript, inicie o processo com `ZAPO_NATIVE_BACKEND=js`.
373
+
374
+ A aplicação expõe eventos tipados para observabilidade sem parsing de logs:
375
+
376
+ ```ts
377
+ app.on('healthChanged', ({ previous, current }) => {
378
+ console.log(previous, current);
379
+ });
380
+
381
+ app.on('connectionRecovered', ({ recoveredAt, reconnects }) => {
382
+ console.log(recoveredAt, reconnects);
383
+ });
384
+
385
+ app.on('groupMetadataRecovered', ({ groupId }) => {
386
+ console.log(groupId);
387
+ });
388
+
389
+ app.on('cryptoDegraded', ({ kind, chatId }) => {
390
+ console.log(kind, chatId);
391
+ });
392
+
393
+ app.on('commandQueueTimeout', ({ command, queuedForMs }) => {
394
+ console.log(command, queuedForMs);
395
+ });
396
+
397
+ app.on('commandQueueFull', ({ command, queued }) => {
398
+ console.log(command, queued);
399
+ });
400
+ ```
401
+
402
+ Falhas criptográficas transitórias deixam o provider em `degraded` por uma janela curta; a volta para `healthy` também dispara `healthChanged`. A recuperação de metadata por `phash` continua específica ao grupo afetado e não apaga Sender Keys nem sessões Signal.
403
+
341
404
  ## Usuários
342
405
 
343
406
  Toda mensagem possui `message.sender: User`. Menções ficam em `message.mentionedUsers`, e o remetente de um reply em `message.quoted?.sender`.
@@ -537,6 +600,8 @@ const downloaded = await app.media.download(message);
537
600
  await writeFile(`./downloads/${downloaded.fileName ?? message.id}`, downloaded.data);
538
601
  ```
539
602
 
603
+ Ao enviar `{ url }`, o provider abre a origem remota como stream e entrega o fluxo ao pipeline de mídia do Zapo; o arquivo não é carregado inteiro na memória antes do upload. Para arquivos locais, `{ path }` continua sendo a opção mais direta.
604
+
540
605
  `download()` aceita a `Message` recebida, uma `QuotedMessage` ou uma `MessageKey` e devolve o buffer junto dos metadados normalizados. A mídia deve ser baixada enquanto a mensagem ainda está no cache da instância; o provider tenta renovar a URL de mídia automaticamente quando necessário.
541
606
 
542
607
  Para visualização única citada, o provider oficial preserva os metadados do envelope sem expor tipos do Zapo:
@@ -695,6 +760,8 @@ app.commands.command(
695
760
  scope: 'chat',
696
761
  max: 1,
697
762
  strategy: 'queue',
763
+ maxQueue: 10,
764
+ queueTimeoutMs: 60_000,
698
765
  },
699
766
 
700
767
  async execute(ctx) {
@@ -713,6 +780,21 @@ app.commands.command(
713
780
  );
714
781
  ```
715
782
 
783
+ Para `strategy: 'queue'`, o WhaNext limita por padrão a fila a 10 execuções aguardando e cada entrada pode esperar até 60 segundos. `maxQueue: 0` remove o limite de quantidade e `queueTimeoutMs: 0` remove o timeout. Quando os limites são atingidos, o router usa `COMMAND_QUEUE_FULL` ou `COMMAND_QUEUE_TIMEOUT` e emite os eventos tipados correspondentes.
784
+
785
+ ```ts
786
+ app.commands.onError(async (ctx, error) => {
787
+ if (error.code === 'COMMAND_QUEUE_FULL') {
788
+ await ctx.reply('Muitos comandos estão aguardando. Tente novamente em instantes.');
789
+ return;
790
+ }
791
+
792
+ if (error.code === 'COMMAND_QUEUE_TIMEOUT') {
793
+ await ctx.reply('A fila demorou demais. Envie o comando novamente.');
794
+ }
795
+ });
796
+ ```
797
+
716
798
  ### Comandos exclusivos do dono
717
799
 
718
800
  O dono é a própria conta conectada naquela aplicação. Não é necessário salvar número, JID ou LID manualmente. O provider usa a marca de mensagem enviada pela própria conta e, quando necessário, compara as identidades normalizadas da sessão.
package/dist/index.d.ts CHANGED
@@ -289,6 +289,8 @@ interface CallEvent {
289
289
  }
290
290
 
291
291
  type ConnectionState = 'idle' | 'connecting' | 'connected' | 'reconnecting' | 'closed';
292
+ type StabilityHealthStatus = 'healthy' | 'degraded' | 'reconnecting' | 'offline';
293
+ type CryptoAccelerationBackend = 'napi' | 'wasm' | 'js' | 'unknown';
292
294
  type PresenceState = 'typing' | 'recording' | 'paused';
293
295
  type ParticipantAction = 'remove' | 'promote' | 'demote';
294
296
  interface ParticipantUpdateResult {
@@ -301,6 +303,69 @@ interface ConnectionUpdate {
301
303
  attempt?: number;
302
304
  error?: Error;
303
305
  }
306
+ interface ProviderConnectionHealth {
307
+ state: ConnectionState;
308
+ uptimeMs: number;
309
+ reconnects: number;
310
+ reconnectAttempt: number;
311
+ lastConnectedAt?: Date;
312
+ lastDisconnectedAt?: Date;
313
+ }
314
+ interface ProviderMessagingHealth {
315
+ sent: number;
316
+ received: number;
317
+ failed: number;
318
+ lastIncomingAt?: Date;
319
+ lastOutgoingAt?: Date;
320
+ }
321
+ interface ProviderCryptoHealth {
322
+ backend: CryptoAccelerationBackend;
323
+ acceleration: boolean;
324
+ decryptFailures: number;
325
+ addonDecryptFailures: number;
326
+ senderKeyMismatches: number;
327
+ }
328
+ interface ProviderGroupHealth {
329
+ phashMismatches: number;
330
+ metadataRecoveries: number;
331
+ metadataRecoveryFailures: number;
332
+ }
333
+ interface ProviderTimeoutHealth {
334
+ connectTimeoutMs: number;
335
+ nodeQueryTimeoutMs: number;
336
+ }
337
+ interface ProviderHealth {
338
+ stability: StabilityHealthStatus;
339
+ connection: ProviderConnectionHealth;
340
+ messaging: ProviderMessagingHealth;
341
+ crypto: ProviderCryptoHealth;
342
+ groups: ProviderGroupHealth;
343
+ timeouts: ProviderTimeoutHealth;
344
+ }
345
+ interface GroupMetadataRecoveredEvent {
346
+ groupId: string;
347
+ recoveredAt: Date;
348
+ }
349
+ type CryptoDegradationKind = 'decrypt_failure' | 'addon_decrypt_failure' | 'sender_key_mismatch';
350
+ interface CryptoDegradedEvent {
351
+ kind: CryptoDegradationKind;
352
+ occurredAt: Date;
353
+ messageId?: string;
354
+ chatId?: string;
355
+ participantId?: string;
356
+ }
357
+ type ProviderStabilityEvent = {
358
+ type: 'groupMetadataRecovered';
359
+ payload: GroupMetadataRecoveredEvent;
360
+ } | {
361
+ type: 'cryptoDegraded';
362
+ payload: CryptoDegradedEvent;
363
+ } | {
364
+ type: 'healthRefresh';
365
+ payload: {
366
+ occurredAt: Date;
367
+ };
368
+ };
304
369
  interface ProviderEvents {
305
370
  message: Message;
306
371
  messageDeleted: MessageDeleted;
@@ -311,6 +376,7 @@ interface ProviderEvents {
311
376
  };
312
377
  groupParticipantsChanged: GroupParticipantsChanged;
313
378
  call: CallEvent;
379
+ stability: ProviderStabilityEvent;
314
380
  }
315
381
  type Unsubscribe = () => void;
316
382
  interface WhatsAppProvider {
@@ -319,6 +385,7 @@ interface WhatsAppProvider {
319
385
  getCurrentUserIds(): string[];
320
386
  requestPairingCode(phone: string): Promise<string>;
321
387
  on<Event extends keyof ProviderEvents>(event: Event, listener: (payload: ProviderEvents[Event]) => void | Promise<void>): Unsubscribe;
388
+ health?(): ProviderHealth;
322
389
  sendMessage(chatId: string, content: MessageContent, replyTo?: MessageKey): Promise<SentMessage>;
323
390
  repostMessage(source: MessageKey, chatId: string, options?: RepostMessageOptions): Promise<SentMessage>;
324
391
  reactToMessage(key: MessageKey, emoji?: string): Promise<SentMessage>;
@@ -616,7 +683,7 @@ declare class DeferredReply {
616
683
  delete(): Promise<void>;
617
684
  }
618
685
 
619
- type WhaNextErrorCode = 'AUTH_INVALID_PHONE' | 'AUTH_EXPIRED' | 'AUTH_PASSKEY_REQUIRED' | 'CONNECTION_CLOSED' | 'CONNECTION_FAILED' | 'GROUP_NOT_FOUND' | 'MEMBER_NOT_FOUND' | 'BOT_NOT_ADMIN' | 'MESSAGE_NOT_FOUND' | 'MEDIA_NOT_AVAILABLE' | 'MESSAGE_REACHOUT_LOCKED' | 'MUTE_DISABLED' | 'STORAGE_ERROR' | 'ARGUMENT_MISSING' | 'ARGUMENT_INVALID' | 'COMMAND_NOT_ALLOWED' | 'COMMAND_COOLDOWN' | 'COMMAND_BUSY' | 'COMMAND_LOAD_FAILED' | 'PROVIDER_ERROR' | 'UNKNOWN_ERROR';
686
+ type WhaNextErrorCode = 'AUTH_INVALID_PHONE' | 'AUTH_EXPIRED' | 'AUTH_PASSKEY_REQUIRED' | 'CONNECTION_CLOSED' | 'CONNECTION_FAILED' | 'GROUP_NOT_FOUND' | 'MEMBER_NOT_FOUND' | 'BOT_NOT_ADMIN' | 'MESSAGE_NOT_FOUND' | 'MEDIA_NOT_AVAILABLE' | 'MESSAGE_REACHOUT_LOCKED' | 'MUTE_DISABLED' | 'STORAGE_ERROR' | 'ARGUMENT_MISSING' | 'ARGUMENT_INVALID' | 'COMMAND_NOT_ALLOWED' | 'COMMAND_COOLDOWN' | 'COMMAND_BUSY' | 'COMMAND_QUEUE_FULL' | 'COMMAND_QUEUE_TIMEOUT' | 'COMMAND_LOAD_FAILED' | 'PROVIDER_ERROR' | 'UNKNOWN_ERROR';
620
687
  interface WhaNextErrorOptions {
621
688
  cause?: unknown;
622
689
  context?: Readonly<Record<string, unknown>>;
@@ -646,8 +713,8 @@ declare const guards: {
646
713
  custom(guard: CommandGuard): CommandGuard;
647
714
  };
648
715
 
649
- type CommandScope = "global" | "user" | "chat" | "user-chat" | "user-group";
650
- type ConcurrencyStrategy = "parallel" | "reject" | "queue" | "replace";
716
+ type CommandScope = 'global' | 'user' | 'chat' | 'user-chat' | 'user-group';
717
+ type ConcurrencyStrategy = 'parallel' | 'reject' | 'queue' | 'replace';
651
718
  interface CommandCooldown {
652
719
  durationMs: number;
653
720
  scope?: CommandScope;
@@ -656,6 +723,8 @@ interface CommandConcurrency {
656
723
  max?: number;
657
724
  scope?: CommandScope;
658
725
  strategy?: ConcurrencyStrategy;
726
+ maxQueue?: number;
727
+ queueTimeoutMs?: number;
659
728
  }
660
729
  interface CommandLocalization {
661
730
  name?: string;
@@ -710,6 +779,37 @@ declare function defineCommandGroup<const Group extends CommandGroupDefinition>(
710
779
  declare function defineCommands<const Commands extends readonly CommandDefinition[]>(...commands: Commands): Commands;
711
780
  declare function isCommandGroup(definition: CommandDefinition): definition is CommandGroupDefinition;
712
781
 
782
+ interface CommandConcurrencyContext {
783
+ command: string;
784
+ messageId: string;
785
+ chatId: string;
786
+ userId: string;
787
+ }
788
+ interface CommandQueueTimeoutEvent extends CommandConcurrencyContext {
789
+ key: string;
790
+ queuedForMs: number;
791
+ queueTimeoutMs: number;
792
+ queued: number;
793
+ }
794
+ interface CommandQueueFullEvent extends CommandConcurrencyContext {
795
+ key: string;
796
+ maxQueue: number;
797
+ queued: number;
798
+ }
799
+ interface CommandConcurrencyHealth {
800
+ running: number;
801
+ queued: number;
802
+ queueTimeouts: number;
803
+ queueRejected: number;
804
+ }
805
+ type CommandConcurrencyEvent = {
806
+ type: 'commandQueueTimeout';
807
+ payload: CommandQueueTimeoutEvent;
808
+ } | {
809
+ type: 'commandQueueFull';
810
+ payload: CommandQueueFullEvent;
811
+ };
812
+
713
813
  interface CommandRegistrar {
714
814
  command(definition: CommandDefinition): unknown;
715
815
  }
@@ -743,6 +843,10 @@ interface CommandHelpOptions extends CommandCatalogOptions {
743
843
  title?: string;
744
844
  }
745
845
  type CommandErrorHandler = (context: CommandContext, error: WhaNextError) => void | Promise<void>;
846
+ interface CommandRouterEvents {
847
+ commandQueueTimeout: CommandQueueTimeoutEvent;
848
+ commandQueueFull: CommandQueueFullEvent;
849
+ }
746
850
  declare class CommandRouter {
747
851
  #private;
748
852
  constructor(services: CommandRuntimeServices, options?: RouterOptions);
@@ -751,6 +855,8 @@ declare class CommandRouter {
751
855
  get prefixes(): readonly string[];
752
856
  setPrefixes(prefixes: string | readonly string[]): this;
753
857
  get size(): number;
858
+ health(): CommandConcurrencyHealth;
859
+ on<Event extends keyof CommandRouterEvents>(event: Event, listener: (payload: CommandRouterEvents[Event]) => void | Promise<void>): () => void;
754
860
  command(definition: CommandDefinition): this;
755
861
  load(dirPath: string | URL, options?: LoadCommandsOptions): Promise<LoadCommandsResult>;
756
862
  use(middleware: CommandMiddleware): this;
@@ -808,6 +914,15 @@ declare class AccountService {
808
914
  isOwner(message: Pick<Message, 'keys' | 'senderIds'>): boolean;
809
915
  }
810
916
 
917
+ interface HealthChangedEvent {
918
+ previous: StabilityHealthStatus;
919
+ current: StabilityHealthStatus;
920
+ health: AppHealth;
921
+ }
922
+ interface ConnectionRecoveredEvent {
923
+ recoveredAt: Date;
924
+ reconnects: number;
925
+ }
811
926
  interface AppEvents {
812
927
  message: Message;
813
928
  messageDeleted: MessageDeleted;
@@ -817,6 +932,12 @@ interface AppEvents {
817
932
  mute: MuteEnforcement;
818
933
  call: CallEvent;
819
934
  groupParticipantsChanged: GroupParticipantsChanged;
935
+ healthChanged: HealthChangedEvent;
936
+ connectionRecovered: ConnectionRecoveredEvent;
937
+ groupMetadataRecovered: GroupMetadataRecoveredEvent;
938
+ cryptoDegraded: CryptoDegradedEvent;
939
+ commandQueueTimeout: CommandQueueTimeoutEvent;
940
+ commandQueueFull: CommandQueueFullEvent;
820
941
  }
821
942
  interface LoginOptions {
822
943
  onCode?: (code: string) => void | Promise<void>;
@@ -825,12 +946,19 @@ interface LoginOptions {
825
946
  type AppHealthStatus = 'idle' | 'starting' | 'ready' | 'stopped';
826
947
  interface AppHealth {
827
948
  status: AppHealthStatus;
949
+ stability: StabilityHealthStatus;
828
950
  state: ConnectionUpdate['state'];
829
951
  ready: boolean;
830
952
  uptimeMs: number;
831
953
  timestamp: Date;
832
954
  muteEnabled: boolean;
833
955
  logLevel: LogLevel;
956
+ connection: ProviderConnectionHealth;
957
+ messaging: ProviderMessagingHealth;
958
+ crypto: ProviderCryptoHealth;
959
+ groups: ProviderGroupHealth;
960
+ commands: CommandConcurrencyHealth;
961
+ timeouts: ProviderTimeoutHealth;
834
962
  }
835
963
  interface WhaNextAppOptions {
836
964
  phone?: string;
@@ -869,6 +997,10 @@ declare enum Browser {
869
997
  Ubuntu = "ubuntu"
870
998
  }
871
999
 
1000
+ interface ProviderTimeoutOptions {
1001
+ connectTimeoutMs?: number;
1002
+ nodeQueryTimeoutMs?: number;
1003
+ }
872
1004
  interface ReconnectOptions {
873
1005
  enabled?: boolean;
874
1006
  maxAttempts?: number;
@@ -885,6 +1017,7 @@ interface CreateOptions {
885
1017
  mute?: MuteOptions;
886
1018
  router?: Omit<RouterOptions, 'prefix'>;
887
1019
  reconnect?: ReconnectOptions;
1020
+ providerTimeouts?: ProviderTimeoutOptions;
888
1021
  messageCacheSize?: number;
889
1022
  processOfflineMessages?: boolean;
890
1023
  provider?: WhatsAppProvider;
@@ -972,4 +1105,4 @@ declare class SqliteMuteStore implements MuteStore {
972
1105
  close(): void;
973
1106
  }
974
1107
 
975
- export { AccountService, type AddMuteOptions, type AddMuteResult, type AppEvents, type AppHealth, type AppHealthStatus, ArgsParser, type AudioContent, type BooleanOption, Browser, type ButtonsContent, type CacheOptions, type CacheStore, type CallEvent, type CallStatus, type ChangeResult, type CommandAccountContext, type CommandCatalogOptions, type CommandCatalogView, type CommandChatContext, type CommandConcurrency, type CommandContext, type CommandCooldown, type CommandDefinition, type CommandErrorHandler, type CommandGroupContext, type CommandGroupDefinition, type CommandGuard, type CommandHelpOptions, type CommandHooks, type CommandLocalization, type CommandMetadata, type CommandMiddleware, type CommandOptionDefinition, type CommandOptionSchema, type CommandOptionValue, type CommandOptionValues, type CommandRegistrar, CommandRouter, type CommandRuntimeServices, type CommandScope, type ConcurrencyStrategy, type ConnectionState, type ConnectionUpdate, type CopyCodeButton, type CreateMultiOptions, type CreateOptions, DeferredReply, type DownloadedMedia, type DurationOption, type EnumOption, type ExecutableCommandDefinition, type GroupAccess, type GroupAddressingMode, type GroupParticipant, type GroupParticipantAction, type GroupParticipantsChanged, type GroupRole, type GroupSnapshot, type GuardResult, type ImageContent, type InteractiveResponse, type InteractiveResponseKind, type InviteResult, type LinkButton, type ListContent, type ListRow, type ListSection, type LoadCommandsOptions, type LoadCommandsResult, type LoadedCommand, type LogContext, type LogEntry, type LogFormat, type LogLevel, type LogWriter, Logger, type LoggerConfig, type LoggerOptions, type LoginOptions, type MediaKind, type MediaSource, type MemberActionState, MemoryCache, type MemoryCacheStats, type MentionTarget, type Message, type MessageButton, type MessageContent, type MessageContentKind, type MessageDeleted, type MessageEdited, type MessageKey, type MessageMedia, type MessagePayloadKind, type MessageProtocolKind, type MultiAccountOptions, type MultiAppEvent, type MultiAppHealth, MultiCommandRouter, type MultiLoadCommandsResult, type MultiLoginOptions, type MuteChangeResult, type MuteEnforcement, type MuteOptions, type MuteRecord, MuteService, type MuteStore, type NumberOption, ParsedCommandOptions, type ParticipantUpdateResult, type PollContent, type PresenceState, type QuickReplyButton, type QuotedMessage, type ReconnectOptions, type RegisteredCommand, type RemoveMuteResult, type ReplyOptions, type RepostMessageOptions, type RouterOptions, type SentMessage, SqliteMuteStore, type StickerContent, type StoredMute, type StringOption, type TextContent, User, type UserData, type UserOption, type VideoContent, WhaNextApp, WhaNextError, type WhaNextErrorCode, WhaNextMultiApp, type WhatsAppProvider, create, createMulti, defineCommand, defineCommandGroup, defineCommands, defineSubcommand, guards, isCommandGroup, loadCommands, option, toWhaNextError };
1108
+ export { AccountService, type AddMuteOptions, type AddMuteResult, type AppEvents, type AppHealth, type AppHealthStatus, ArgsParser, type AudioContent, type BooleanOption, Browser, type ButtonsContent, type CacheOptions, type CacheStore, type CallEvent, type CallStatus, type ChangeResult, type CommandAccountContext, type CommandCatalogOptions, type CommandCatalogView, type CommandChatContext, type CommandConcurrency, type CommandConcurrencyContext, type CommandConcurrencyEvent, type CommandConcurrencyHealth, type CommandContext, type CommandCooldown, type CommandDefinition, type CommandErrorHandler, type CommandGroupContext, type CommandGroupDefinition, type CommandGuard, type CommandHelpOptions, type CommandHooks, type CommandLocalization, type CommandMetadata, type CommandMiddleware, type CommandOptionDefinition, type CommandOptionSchema, type CommandOptionValue, type CommandOptionValues, type CommandQueueFullEvent, type CommandQueueTimeoutEvent, type CommandRegistrar, CommandRouter, type CommandRouterEvents, type CommandRuntimeServices, type CommandScope, type ConcurrencyStrategy, type ConnectionRecoveredEvent, type ConnectionState, type ConnectionUpdate, type CopyCodeButton, type CreateMultiOptions, type CreateOptions, type CryptoAccelerationBackend, type CryptoDegradationKind, type CryptoDegradedEvent, DeferredReply, type DownloadedMedia, type DurationOption, type EnumOption, type ExecutableCommandDefinition, type GroupAccess, type GroupAddressingMode, type GroupMetadataRecoveredEvent, type GroupParticipant, type GroupParticipantAction, type GroupParticipantsChanged, type GroupRole, type GroupSnapshot, type GuardResult, type HealthChangedEvent, type ImageContent, type InteractiveResponse, type InteractiveResponseKind, type InviteResult, type LinkButton, type ListContent, type ListRow, type ListSection, type LoadCommandsOptions, type LoadCommandsResult, type LoadedCommand, type LogContext, type LogEntry, type LogFormat, type LogLevel, type LogWriter, Logger, type LoggerConfig, type LoggerOptions, type LoginOptions, type MediaKind, type MediaSource, type MemberActionState, MemoryCache, type MemoryCacheStats, type MentionTarget, type Message, type MessageButton, type MessageContent, type MessageContentKind, type MessageDeleted, type MessageEdited, type MessageKey, type MessageMedia, type MessagePayloadKind, type MessageProtocolKind, type MultiAccountOptions, type MultiAppEvent, type MultiAppHealth, MultiCommandRouter, type MultiLoadCommandsResult, type MultiLoginOptions, type MuteChangeResult, type MuteEnforcement, type MuteOptions, type MuteRecord, MuteService, type MuteStore, type NumberOption, ParsedCommandOptions, type ParticipantUpdateResult, type PollContent, type PresenceState, type ProviderConnectionHealth, type ProviderCryptoHealth, type ProviderGroupHealth, type ProviderHealth, type ProviderMessagingHealth, type ProviderStabilityEvent, type ProviderTimeoutHealth, type ProviderTimeoutOptions, type QuickReplyButton, type QuotedMessage, type ReconnectOptions, type RegisteredCommand, type RemoveMuteResult, type ReplyOptions, type RepostMessageOptions, type RouterOptions, type SentMessage, SqliteMuteStore, type StabilityHealthStatus, type StickerContent, type StoredMute, type StringOption, type TextContent, User, type UserData, type UserOption, type VideoContent, WhaNextApp, WhaNextError, type WhaNextErrorCode, WhaNextMultiApp, type WhatsAppProvider, create, createMulti, defineCommand, defineCommandGroup, defineCommands, defineSubcommand, guards, isCommandGroup, loadCommands, option, toWhaNextError };