@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 +45 -0
- package/README.md +88 -6
- package/dist/index.d.ts +137 -4
- package/dist/index.js +597 -86
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
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.
|
|
324
|
-
console.log(health.
|
|
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
|
-
|
|
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 =
|
|
650
|
-
type ConcurrencyStrategy =
|
|
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 };
|