zapo-js 0.1.0 → 0.1.2
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/README.md +12 -7
- package/dist/appstate/WaAppStateCrypto.js +18 -25
- package/dist/appstate/WaAppStateSyncClient.js +181 -114
- package/dist/appstate/WaAppStateSyncResponseParser.js +16 -5
- package/dist/appstate/constants.js +4 -3
- package/dist/appstate/utils.js +10 -30
- package/dist/auth/WaAuthClient.js +48 -55
- package/dist/auth/flow/WaAuthCredentialsFlow.js +21 -14
- package/dist/auth/index.js +1 -3
- package/dist/auth/pairing/WaPairingFlow.js +21 -23
- package/dist/auth/pairing/WaQrFlow.js +37 -24
- package/dist/client/WaClient.js +103 -276
- package/dist/client/WaClientFactory.js +227 -110
- package/dist/client/connection/WaConnectionManager.js +292 -0
- package/dist/client/connection/WaKeyShareCoordinator.js +63 -0
- package/dist/client/connection/WaReceiptQueue.js +51 -0
- package/dist/client/coordinators/WaAppStateMutationCoordinator.js +471 -0
- package/dist/client/coordinators/WaGroupCoordinator.js +27 -17
- package/dist/client/coordinators/WaIncomingNodeCoordinator.js +20 -27
- package/dist/client/coordinators/WaMessageDispatchCoordinator.js +231 -686
- package/dist/client/coordinators/WaRetryCoordinator.js +70 -37
- package/dist/client/dirty.js +35 -29
- package/dist/client/events/chat.js +4 -3
- package/dist/client/events/group.js +59 -36
- package/dist/client/history-sync.js +53 -63
- package/dist/client/incoming.js +23 -20
- package/dist/client/mailbox.js +8 -8
- package/dist/client/messages.js +4 -4
- package/dist/client/messaging/fanout.js +189 -0
- package/dist/client/messaging/key-protocol.js +130 -0
- package/dist/client/messaging/participants.js +191 -0
- package/dist/crypto/core/hkdf.js +3 -8
- package/dist/crypto/core/index.js +1 -4
- package/dist/crypto/core/keys.js +2 -3
- package/dist/crypto/core/primitives.js +12 -15
- package/dist/crypto/core/random.js +7 -26
- package/dist/crypto/curves/Ed25519.js +7 -8
- package/dist/crypto/curves/X25519.js +13 -16
- package/dist/crypto/index.js +0 -5
- package/dist/esm/appstate/WaAppStateCrypto.js +6 -13
- package/dist/esm/appstate/WaAppStateSyncClient.js +174 -107
- package/dist/esm/appstate/WaAppStateSyncResponseParser.js +17 -6
- package/dist/esm/appstate/constants.js +3 -2
- package/dist/esm/appstate/utils.js +8 -27
- package/dist/esm/auth/WaAuthClient.js +48 -55
- package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +21 -14
- package/dist/esm/auth/index.js +0 -1
- package/dist/esm/auth/pairing/WaPairingFlow.js +14 -16
- package/dist/esm/auth/pairing/WaQrFlow.js +37 -24
- package/dist/esm/client/WaClient.js +103 -276
- package/dist/esm/client/WaClientFactory.js +227 -110
- package/dist/esm/client/connection/WaConnectionManager.js +288 -0
- package/dist/esm/client/connection/WaKeyShareCoordinator.js +59 -0
- package/dist/esm/client/connection/WaReceiptQueue.js +47 -0
- package/dist/esm/client/coordinators/WaAppStateMutationCoordinator.js +467 -0
- package/dist/esm/client/coordinators/WaGroupCoordinator.js +20 -10
- package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +20 -27
- package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +232 -687
- package/dist/esm/client/coordinators/WaRetryCoordinator.js +71 -38
- package/dist/esm/client/dirty.js +30 -24
- package/dist/esm/client/events/chat.js +4 -3
- package/dist/esm/client/events/group.js +50 -28
- package/dist/esm/client/history-sync.js +50 -60
- package/dist/esm/client/incoming.js +23 -20
- package/dist/esm/client/mailbox.js +8 -8
- package/dist/esm/client/messages.js +1 -1
- package/dist/esm/client/messaging/fanout.js +186 -0
- package/dist/esm/client/messaging/key-protocol.js +127 -0
- package/dist/esm/client/messaging/participants.js +188 -0
- package/dist/esm/crypto/core/hkdf.js +3 -8
- package/dist/esm/crypto/core/index.js +0 -1
- package/dist/esm/crypto/core/keys.js +2 -3
- package/dist/esm/crypto/core/primitives.js +12 -15
- package/dist/esm/crypto/core/random.js +6 -25
- package/dist/esm/crypto/curves/Ed25519.js +4 -5
- package/dist/esm/crypto/curves/X25519.js +10 -13
- package/dist/esm/crypto/index.js +0 -2
- package/dist/esm/infra/log/ConsoleLogger.js +18 -17
- package/dist/esm/infra/log/PinoLogger.js +15 -9
- package/dist/esm/infra/log/types.js +11 -1
- package/dist/esm/infra/perf/BoundedTaskQueue.js +13 -17
- package/dist/esm/media/WaMediaCrypto.js +2 -4
- package/dist/esm/media/WaMediaTransferClient.js +226 -58
- package/dist/esm/media/conn.js +10 -6
- package/dist/esm/media/constants.js +4 -1
- package/dist/esm/message/WaMessageClient.js +4 -13
- package/dist/esm/message/ack.js +6 -6
- package/dist/esm/message/addon-crypto.js +59 -0
- package/dist/esm/message/incoming.js +106 -111
- package/dist/esm/message/index.js +2 -0
- package/dist/esm/message/reporting-token.js +438 -0
- package/dist/esm/message/use-case-secret.js +49 -0
- package/dist/esm/protocol/appstate.js +58 -0
- package/dist/esm/protocol/constants.js +2 -1
- package/dist/esm/protocol/index.js +2 -10
- package/dist/esm/protocol/jid.js +63 -51
- package/dist/esm/protocol/media.js +3 -3
- package/dist/esm/protocol/nodes.js +2 -0
- package/dist/esm/protocol/usync.js +11 -0
- package/dist/esm/retry/index.js +1 -0
- package/dist/esm/retry/outbound.js +4 -5
- package/dist/esm/retry/parse.js +58 -76
- package/dist/esm/retry/replay.js +48 -49
- package/dist/esm/retry/tracker.js +56 -0
- package/dist/esm/signal/api/SignalDeviceSyncApi.js +249 -82
- package/dist/esm/signal/api/SignalDigestSyncApi.js +6 -1
- package/dist/esm/signal/api/SignalIdentitySyncApi.js +49 -34
- package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +70 -62
- package/dist/esm/signal/api/SignalSessionSyncApi.js +23 -30
- package/dist/esm/signal/crypto/WaAdvSignature.js +3 -5
- package/dist/esm/signal/group/SenderKeyChain.js +28 -23
- package/dist/esm/signal/group/SenderKeyCodec.js +2 -4
- package/dist/esm/signal/group/SenderKeyManager.js +26 -16
- package/dist/esm/signal/index.js +1 -0
- package/dist/esm/signal/session/SignalProtocol.js +49 -14
- package/dist/esm/signal/session/SignalRatchet.js +24 -15
- package/dist/esm/signal/session/SignalSession.js +14 -9
- package/dist/esm/signal/session/resolver.js +186 -0
- package/dist/esm/signal/store/sqlite.js +16 -37
- package/dist/esm/store/createStore.js +16 -18
- package/dist/esm/store/noop.store.js +3 -6
- package/dist/esm/store/providers/memory/appstate.store.js +30 -6
- package/dist/esm/store/providers/memory/contact.store.js +5 -0
- package/dist/esm/store/providers/memory/device-list.store.js +3 -30
- package/dist/esm/store/providers/memory/message.store.js +11 -5
- package/dist/esm/store/providers/memory/participants.store.js +1 -8
- package/dist/esm/store/providers/memory/sender-key.store.js +5 -7
- package/dist/esm/store/providers/memory/signal.store.js +13 -1
- package/dist/esm/store/providers/memory/thread.store.js +5 -0
- package/dist/esm/store/providers/sqlite/appstate.store.js +82 -1
- package/dist/esm/store/providers/sqlite/connection.js +18 -13
- package/dist/esm/store/providers/sqlite/contact.store.js +31 -18
- package/dist/esm/store/providers/sqlite/device-list.store.js +7 -35
- package/dist/esm/store/providers/sqlite/message.store.js +45 -32
- package/dist/esm/store/providers/sqlite/migrations.js +1 -1
- package/dist/esm/store/providers/sqlite/participants.store.js +1 -9
- package/dist/esm/store/providers/sqlite/retry.store.js +8 -11
- package/dist/esm/store/providers/sqlite/sender-key.store.js +25 -30
- package/dist/esm/store/providers/sqlite/signal.store.js +104 -22
- package/dist/esm/store/providers/sqlite/table-names.js +107 -0
- package/dist/esm/store/providers/sqlite/thread.store.js +35 -22
- package/dist/esm/transport/WaComms.js +25 -23
- package/dist/esm/transport/WaWebSocket.js +115 -12
- package/dist/esm/transport/binary/decoder.js +4 -4
- package/dist/esm/transport/binary/encoder.js +12 -4
- package/dist/esm/transport/index.js +1 -0
- package/dist/esm/transport/keepalive/WaKeepAlive.js +2 -8
- package/dist/esm/transport/node/WaNodeOrchestrator.js +2 -4
- package/dist/esm/transport/node/WaNodeTransport.js +0 -3
- package/dist/esm/transport/node/builders/{accountSync.js → account-sync.js} +16 -36
- package/dist/esm/transport/node/builders/index.js +2 -1
- package/dist/esm/transport/node/builders/message.js +9 -0
- package/dist/esm/transport/node/builders/pairing.js +4 -5
- package/dist/esm/transport/node/builders/usync.js +41 -0
- package/dist/esm/transport/node/helpers.js +107 -5
- package/dist/esm/transport/node/usync.js +35 -0
- package/dist/esm/transport/noise/WaFrameCodec.js +48 -33
- package/dist/esm/transport/noise/WaNoiseCert.js +3 -6
- package/dist/esm/transport/noise/WaNoiseSession.js +17 -10
- package/dist/esm/transport/proxy.js +27 -0
- package/dist/esm/transport/stream/parse.js +13 -48
- package/dist/esm/util/bytes.js +50 -32
- package/dist/esm/util/coercion.js +6 -14
- package/dist/esm/util/primitives.js +39 -14
- package/dist/infra/log/ConsoleLogger.js +18 -17
- package/dist/infra/log/PinoLogger.js +15 -9
- package/dist/infra/log/types.js +12 -0
- package/dist/infra/perf/BoundedTaskQueue.js +13 -17
- package/dist/media/WaMediaCrypto.js +1 -3
- package/dist/media/WaMediaTransferClient.js +259 -58
- package/dist/media/conn.js +10 -6
- package/dist/media/constants.js +4 -1
- package/dist/message/WaMessageClient.js +5 -14
- package/dist/message/ack.js +6 -6
- package/dist/message/addon-crypto.js +65 -0
- package/dist/message/incoming.js +104 -109
- package/dist/message/index.js +2 -0
- package/dist/message/reporting-token.js +443 -0
- package/dist/message/use-case-secret.js +55 -0
- package/dist/protocol/appstate.js +59 -1
- package/dist/protocol/constants.js +7 -1
- package/dist/protocol/index.js +20 -42
- package/dist/protocol/jid.js +64 -51
- package/dist/protocol/media.js +3 -3
- package/dist/protocol/nodes.js +2 -0
- package/dist/protocol/usync.js +14 -0
- package/dist/retry/index.js +3 -1
- package/dist/retry/outbound.js +6 -7
- package/dist/retry/parse.js +57 -75
- package/dist/retry/replay.js +46 -47
- package/dist/retry/tracker.js +59 -0
- package/dist/signal/api/SignalDeviceSyncApi.js +247 -80
- package/dist/signal/api/SignalDigestSyncApi.js +6 -1
- package/dist/signal/api/SignalIdentitySyncApi.js +49 -34
- package/dist/signal/api/SignalMissingPreKeysSyncApi.js +67 -59
- package/dist/signal/api/SignalSessionSyncApi.js +23 -30
- package/dist/signal/crypto/WaAdvSignature.js +2 -4
- package/dist/signal/group/SenderKeyChain.js +27 -22
- package/dist/signal/group/SenderKeyCodec.js +1 -3
- package/dist/signal/group/SenderKeyManager.js +26 -16
- package/dist/signal/index.js +3 -1
- package/dist/signal/session/SignalProtocol.js +49 -14
- package/dist/signal/session/SignalRatchet.js +24 -15
- package/dist/signal/session/SignalSession.js +14 -9
- package/dist/signal/session/resolver.js +189 -0
- package/dist/signal/store/sqlite.js +16 -37
- package/dist/store/createStore.js +16 -18
- package/dist/store/noop.store.js +3 -6
- package/dist/store/providers/memory/appstate.store.js +28 -4
- package/dist/store/providers/memory/contact.store.js +5 -0
- package/dist/store/providers/memory/device-list.store.js +3 -30
- package/dist/store/providers/memory/message.store.js +11 -5
- package/dist/store/providers/memory/participants.store.js +1 -8
- package/dist/store/providers/memory/sender-key.store.js +8 -10
- package/dist/store/providers/memory/signal.store.js +21 -9
- package/dist/store/providers/memory/thread.store.js +5 -0
- package/dist/store/providers/sqlite/appstate.store.js +81 -0
- package/dist/store/providers/sqlite/connection.js +18 -13
- package/dist/store/providers/sqlite/contact.store.js +31 -18
- package/dist/store/providers/sqlite/device-list.store.js +7 -35
- package/dist/store/providers/sqlite/message.store.js +45 -32
- package/dist/store/providers/sqlite/migrations.js +1 -1
- package/dist/store/providers/sqlite/participants.store.js +1 -9
- package/dist/store/providers/sqlite/retry.store.js +8 -11
- package/dist/store/providers/sqlite/sender-key.store.js +24 -29
- package/dist/store/providers/sqlite/signal.store.js +105 -23
- package/dist/store/providers/sqlite/table-names.js +113 -0
- package/dist/store/providers/sqlite/thread.store.js +35 -22
- package/dist/transport/WaComms.js +27 -25
- package/dist/transport/WaWebSocket.js +148 -12
- package/dist/transport/binary/decoder.js +4 -4
- package/dist/transport/binary/encoder.js +12 -4
- package/dist/transport/index.js +7 -1
- package/dist/transport/keepalive/WaKeepAlive.js +1 -7
- package/dist/transport/node/WaNodeOrchestrator.js +2 -4
- package/dist/transport/node/WaNodeTransport.js +0 -3
- package/dist/transport/node/builders/{accountSync.js → account-sync.js} +15 -35
- package/dist/transport/node/builders/index.js +12 -9
- package/dist/transport/node/builders/message.js +9 -0
- package/dist/transport/node/builders/pairing.js +4 -5
- package/dist/transport/node/builders/usync.js +45 -0
- package/dist/transport/node/helpers.js +112 -4
- package/dist/transport/node/usync.js +38 -0
- package/dist/transport/noise/WaFrameCodec.js +47 -32
- package/dist/transport/noise/WaNoiseCert.js +5 -8
- package/dist/transport/noise/WaNoiseSession.js +17 -10
- package/dist/transport/proxy.js +34 -0
- package/dist/transport/stream/parse.js +17 -53
- package/dist/types/appstate/WaAppStateCrypto.d.ts +0 -1
- package/dist/types/appstate/WaAppStateSyncClient.d.ts +5 -2
- package/dist/types/appstate/constants.d.ts +1 -0
- package/dist/types/appstate/store/sqlite.d.ts +4 -18
- package/dist/types/appstate/utils.d.ts +0 -1
- package/dist/types/auth/WaAuthClient.d.ts +10 -12
- package/dist/types/auth/index.d.ts +0 -2
- package/dist/types/auth/pairing/WaQrFlow.d.ts +1 -1
- package/dist/types/auth/types.d.ts +6 -9
- package/dist/types/client/WaClient.d.ts +27 -25
- package/dist/types/client/WaClientFactory.d.ts +22 -23
- package/dist/types/client/connection/WaConnectionManager.d.ts +64 -0
- package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +14 -0
- package/dist/types/client/connection/WaReceiptQueue.d.ts +13 -0
- package/dist/types/client/coordinators/WaAppStateMutationCoordinator.d.ts +46 -0
- package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +0 -1
- package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +18 -41
- package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +2 -0
- package/dist/types/client/dirty.d.ts +1 -0
- package/dist/types/client/events/group.d.ts +2 -1
- package/dist/types/client/index.d.ts +1 -1
- package/dist/types/client/messaging/fanout.d.ts +14 -0
- package/dist/types/client/messaging/key-protocol.d.ts +18 -0
- package/dist/types/client/messaging/participants.d.ts +13 -0
- package/dist/types/client/types.d.ts +24 -1
- package/dist/types/crypto/core/hkdf.d.ts +0 -6
- package/dist/types/crypto/core/index.d.ts +0 -1
- package/dist/types/crypto/core/random.d.ts +1 -7
- package/dist/types/crypto/index.d.ts +0 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/infra/log/ConsoleLogger.d.ts +2 -1
- package/dist/types/infra/log/PinoLogger.d.ts +1 -1
- package/dist/types/infra/log/types.d.ts +1 -0
- package/dist/types/infra/perf/BoundedTaskQueue.d.ts +1 -1
- package/dist/types/media/WaMediaTransferClient.d.ts +13 -3
- package/dist/types/media/types.d.ts +5 -0
- package/dist/types/message/addon-crypto.d.ts +25 -0
- package/dist/types/message/index.d.ts +2 -0
- package/dist/types/message/reporting-token.d.ts +19 -0
- package/dist/types/message/use-case-secret.d.ts +20 -0
- package/dist/types/protocol/appstate.d.ts +58 -0
- package/dist/types/protocol/constants.d.ts +2 -1
- package/dist/types/protocol/index.d.ts +2 -10
- package/dist/types/protocol/jid.d.ts +3 -3
- package/dist/types/protocol/nodes.d.ts +2 -0
- package/dist/types/protocol/usync.d.ts +11 -0
- package/dist/types/retry/index.d.ts +1 -0
- package/dist/types/retry/replay.d.ts +0 -4
- package/dist/types/retry/tracker.d.ts +19 -0
- package/dist/types/retry/types.d.ts +4 -3
- package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +13 -1
- package/dist/types/signal/group/SenderKeyCodec.d.ts +4 -6
- package/dist/types/signal/index.d.ts +1 -0
- package/dist/types/signal/session/SignalProtocol.d.ts +9 -0
- package/dist/types/signal/session/resolver.d.ts +17 -0
- package/dist/types/store/contracts/appstate.store.d.ts +3 -0
- package/dist/types/store/contracts/contact.store.d.ts +1 -0
- package/dist/types/store/contracts/device-list.store.d.ts +0 -3
- package/dist/types/store/contracts/message.store.d.ts +1 -0
- package/dist/types/store/contracts/participants.store.d.ts +0 -1
- package/dist/types/store/contracts/sender-key.store.d.ts +0 -1
- package/dist/types/store/contracts/signal.store.d.ts +6 -0
- package/dist/types/store/contracts/thread.store.d.ts +1 -0
- package/dist/types/store/index.d.ts +1 -1
- package/dist/types/store/providers/memory/appstate.store.d.ts +2 -0
- package/dist/types/store/providers/memory/contact.store.d.ts +1 -0
- package/dist/types/store/providers/memory/device-list.store.d.ts +0 -3
- package/dist/types/store/providers/memory/message.store.d.ts +1 -0
- package/dist/types/store/providers/memory/participants.store.d.ts +0 -1
- package/dist/types/store/providers/memory/sender-key.store.d.ts +0 -1
- package/dist/types/store/providers/memory/signal.store.d.ts +6 -0
- package/dist/types/store/providers/memory/thread.store.d.ts +1 -0
- package/dist/types/store/providers/sqlite/appstate.store.d.ts +2 -0
- package/dist/types/store/providers/sqlite/contact.store.d.ts +2 -0
- package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -3
- package/dist/types/store/providers/sqlite/message.store.d.ts +2 -0
- package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -1
- package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -1
- package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -1
- package/dist/types/store/providers/sqlite/signal.store.d.ts +7 -0
- package/dist/types/store/providers/sqlite/table-names.d.ts +5 -0
- package/dist/types/store/providers/sqlite/thread.store.d.ts +2 -0
- package/dist/types/store/types.d.ts +3 -0
- package/dist/types/transport/WaWebSocket.d.ts +3 -0
- package/dist/types/transport/index.d.ts +2 -1
- package/dist/types/transport/keepalive/WaKeepAlive.d.ts +0 -1
- package/dist/types/transport/node/WaNodeTransport.d.ts +0 -9
- package/dist/types/transport/node/builders/group.d.ts +4 -6
- package/dist/types/transport/node/builders/index.d.ts +2 -1
- package/dist/types/transport/node/builders/message.d.ts +14 -25
- package/dist/types/transport/node/builders/retry.d.ts +2 -4
- package/dist/types/transport/node/builders/usync.d.ts +21 -0
- package/dist/types/transport/node/helpers.d.ts +8 -0
- package/dist/types/transport/node/usync.d.ts +2 -0
- package/dist/types/transport/noise/WaFrameCodec.d.ts +3 -0
- package/dist/types/transport/noise/WaNoiseSession.d.ts +1 -0
- package/dist/types/transport/proxy.d.ts +6 -0
- package/dist/types/transport/stream/parse.d.ts +0 -1
- package/dist/types/transport/types.d.ts +18 -1
- package/dist/types/util/bytes.d.ts +5 -0
- package/dist/types/util/primitives.d.ts +3 -0
- package/dist/util/bytes.js +55 -33
- package/dist/util/coercion.js +6 -14
- package/dist/util/primitives.js +42 -14
- package/package.json +27 -9
- package/proto/index.d.ts +1090 -1048
- package/proto/index.js +1 -1
- package/scripts/check-node-version.cjs +0 -1
- package/dist/crypto/core/encoding.js +0 -29
- package/dist/esm/crypto/core/encoding.js +0 -25
- package/dist/esm/util/base64.js +0 -18
- package/dist/esm/util/signal-address.js +0 -5
- package/dist/types/crypto/core/encoding.d.ts +0 -11
- package/dist/types/util/base64.d.ts +0 -4
- package/dist/types/util/signal-address.d.ts +0 -2
- package/dist/util/base64.js +0 -24
- package/dist/util/signal-address.js +0 -8
- /package/dist/types/transport/node/builders/{accountSync.d.ts → account-sync.d.ts} +0 -0
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WaAppStateMutationCoordinator = void 0;
|
|
4
|
+
const constants_1 = require("../../protocol/constants");
|
|
5
|
+
const jid_1 = require("../../protocol/jid");
|
|
6
|
+
const coercion_1 = require("../../util/coercion");
|
|
7
|
+
const primitives_1 = require("../../util/primitives");
|
|
8
|
+
const WA_APP_STATE_MUTATION_FLUSH_SUCCESS_STATES = new Set([
|
|
9
|
+
constants_1.WA_APP_STATE_COLLECTION_STATES.SUCCESS,
|
|
10
|
+
constants_1.WA_APP_STATE_COLLECTION_STATES.SUCCESS_HAS_MORE
|
|
11
|
+
]);
|
|
12
|
+
const WA_APP_STATE_ARCHIVE_RANGE_DEFAULT_LIMIT = 256;
|
|
13
|
+
class WaAppStateMutationCoordinator {
|
|
14
|
+
constructor(options) {
|
|
15
|
+
this.logger = options.logger;
|
|
16
|
+
this.messageStore = options.messageStore;
|
|
17
|
+
this.syncAppState = options.syncAppState;
|
|
18
|
+
this.archiveRangeLimit = (0, coercion_1.resolvePositive)(options.archiveRangeLimit, WA_APP_STATE_ARCHIVE_RANGE_DEFAULT_LIMIT, 'WaAppStateMutationCoordinatorOptions.archiveRangeLimit');
|
|
19
|
+
this.pendingMutations = new Map();
|
|
20
|
+
this.flushPromise = null;
|
|
21
|
+
}
|
|
22
|
+
async setChatMute(chatJid, muted, muteEndTimestampMs) {
|
|
23
|
+
const chatIndexJid = this.normalizeChatMutationJid(chatJid);
|
|
24
|
+
const timestamp = Date.now();
|
|
25
|
+
const normalizedMuteEnd = muteEndTimestampMs;
|
|
26
|
+
if (normalizedMuteEnd !== undefined &&
|
|
27
|
+
(!Number.isFinite(normalizedMuteEnd) ||
|
|
28
|
+
!Number.isSafeInteger(normalizedMuteEnd) ||
|
|
29
|
+
normalizedMuteEnd < 0)) {
|
|
30
|
+
throw new Error(`invalid muteEndTimestampMs: ${muteEndTimestampMs}`);
|
|
31
|
+
}
|
|
32
|
+
if (muted && normalizedMuteEnd === undefined) {
|
|
33
|
+
throw new Error('setChatMute requires muteEndTimestampMs when muted is true');
|
|
34
|
+
}
|
|
35
|
+
const mutation = this.createSetMutation({
|
|
36
|
+
spec: constants_1.WA_APP_STATE_CHAT_MUTATION_SPECS.MUTE,
|
|
37
|
+
chatIndexJid,
|
|
38
|
+
value: {
|
|
39
|
+
muteAction: {
|
|
40
|
+
muted,
|
|
41
|
+
...(normalizedMuteEnd === undefined
|
|
42
|
+
? {}
|
|
43
|
+
: { muteEndTimestamp: normalizedMuteEnd })
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
timestamp
|
|
47
|
+
});
|
|
48
|
+
await this.enqueueAndFlush([mutation]);
|
|
49
|
+
}
|
|
50
|
+
async setMessageStar(message, starred) {
|
|
51
|
+
const messageIndex = this.buildMessageMutationIndex(message);
|
|
52
|
+
const timestamp = Date.now();
|
|
53
|
+
const mutation = this.createSetMutation({
|
|
54
|
+
spec: constants_1.WA_APP_STATE_CHAT_MUTATION_SPECS.STAR,
|
|
55
|
+
chatIndexJid: messageIndex.chatIndexJid,
|
|
56
|
+
value: {
|
|
57
|
+
starAction: {
|
|
58
|
+
starred
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
timestamp,
|
|
62
|
+
indexPartsTail: messageIndex.indexPartsTail
|
|
63
|
+
});
|
|
64
|
+
await this.enqueueAndFlush([mutation]);
|
|
65
|
+
}
|
|
66
|
+
async setChatRead(chatJid, read) {
|
|
67
|
+
const chatIndexJid = this.normalizeChatMutationJid(chatJid);
|
|
68
|
+
const timestamp = Date.now();
|
|
69
|
+
const messageRange = await this.buildChatMessageRange(chatIndexJid);
|
|
70
|
+
const mutation = this.createSetMutation({
|
|
71
|
+
spec: constants_1.WA_APP_STATE_CHAT_MUTATION_SPECS.MARK_CHAT_AS_READ,
|
|
72
|
+
chatIndexJid,
|
|
73
|
+
value: {
|
|
74
|
+
markChatAsReadAction: {
|
|
75
|
+
read,
|
|
76
|
+
messageRange
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
timestamp
|
|
80
|
+
});
|
|
81
|
+
await this.enqueueAndFlush([mutation]);
|
|
82
|
+
}
|
|
83
|
+
async setChatPin(chatJid, pinned) {
|
|
84
|
+
const chatIndexJid = this.normalizeChatMutationJid(chatJid);
|
|
85
|
+
const timestamp = Date.now();
|
|
86
|
+
const pending = [
|
|
87
|
+
this.createSetMutation({
|
|
88
|
+
spec: constants_1.WA_APP_STATE_CHAT_MUTATION_SPECS.PIN,
|
|
89
|
+
chatIndexJid,
|
|
90
|
+
value: {
|
|
91
|
+
pinAction: {
|
|
92
|
+
pinned
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
timestamp
|
|
96
|
+
})
|
|
97
|
+
];
|
|
98
|
+
if (pinned) {
|
|
99
|
+
pending.push(await this.createArchiveMutation(chatIndexJid, false, timestamp));
|
|
100
|
+
}
|
|
101
|
+
await this.enqueueAndFlush(pending);
|
|
102
|
+
}
|
|
103
|
+
async setChatArchive(chatJid, archived) {
|
|
104
|
+
const chatIndexJid = this.normalizeChatMutationJid(chatJid);
|
|
105
|
+
const timestamp = Date.now();
|
|
106
|
+
const pending = [
|
|
107
|
+
await this.createArchiveMutation(chatIndexJid, archived, timestamp)
|
|
108
|
+
];
|
|
109
|
+
if (archived) {
|
|
110
|
+
pending.push(this.createSetMutation({
|
|
111
|
+
spec: constants_1.WA_APP_STATE_CHAT_MUTATION_SPECS.PIN,
|
|
112
|
+
chatIndexJid,
|
|
113
|
+
value: {
|
|
114
|
+
pinAction: {
|
|
115
|
+
pinned: false
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
timestamp
|
|
119
|
+
}));
|
|
120
|
+
}
|
|
121
|
+
await this.enqueueAndFlush(pending);
|
|
122
|
+
}
|
|
123
|
+
async clearChat(chatJid, options = {}) {
|
|
124
|
+
const chatIndexJid = this.normalizeChatMutationJid(chatJid);
|
|
125
|
+
const timestamp = Date.now();
|
|
126
|
+
const deleteStarred = options.deleteStarred === true;
|
|
127
|
+
const deleteMedia = options.deleteMedia === true;
|
|
128
|
+
const messageRange = await this.buildChatMessageRange(chatIndexJid);
|
|
129
|
+
const mutation = this.createSetMutation({
|
|
130
|
+
spec: constants_1.WA_APP_STATE_CHAT_MUTATION_SPECS.CLEAR_CHAT,
|
|
131
|
+
chatIndexJid,
|
|
132
|
+
value: {
|
|
133
|
+
clearChatAction: {
|
|
134
|
+
messageRange
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
timestamp,
|
|
138
|
+
indexPartsTail: [deleteStarred ? '1' : '0', deleteMedia ? '1' : '0']
|
|
139
|
+
});
|
|
140
|
+
await this.enqueueAndFlush([mutation]);
|
|
141
|
+
}
|
|
142
|
+
async deleteChat(chatJid, options = {}) {
|
|
143
|
+
const chatIndexJid = this.normalizeChatMutationJid(chatJid);
|
|
144
|
+
const timestamp = Date.now();
|
|
145
|
+
const deleteMedia = options.deleteMedia === true;
|
|
146
|
+
const messageRange = await this.buildChatMessageRange(chatIndexJid);
|
|
147
|
+
const mutation = this.createSetMutation({
|
|
148
|
+
spec: constants_1.WA_APP_STATE_CHAT_MUTATION_SPECS.DELETE_CHAT,
|
|
149
|
+
chatIndexJid,
|
|
150
|
+
value: {
|
|
151
|
+
deleteChatAction: {
|
|
152
|
+
messageRange
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
timestamp,
|
|
156
|
+
indexPartsTail: [deleteMedia ? '1' : '0']
|
|
157
|
+
});
|
|
158
|
+
await this.enqueueAndFlush([mutation]);
|
|
159
|
+
}
|
|
160
|
+
async deleteMessageForMe(message, options = {}) {
|
|
161
|
+
const messageIndex = this.buildMessageMutationIndex(message);
|
|
162
|
+
const timestamp = Date.now();
|
|
163
|
+
const deleteMedia = options.deleteMedia === true;
|
|
164
|
+
const messageTimestampMs = options.messageTimestampMs;
|
|
165
|
+
let messageTimestamp;
|
|
166
|
+
if (messageTimestampMs !== undefined) {
|
|
167
|
+
if (!Number.isFinite(messageTimestampMs) ||
|
|
168
|
+
!Number.isSafeInteger(messageTimestampMs) ||
|
|
169
|
+
messageTimestampMs < 0) {
|
|
170
|
+
throw new Error(`invalid messageTimestampMs: ${messageTimestampMs}`);
|
|
171
|
+
}
|
|
172
|
+
messageTimestamp = Math.floor(messageTimestampMs / 1000);
|
|
173
|
+
}
|
|
174
|
+
const mutation = this.createSetMutation({
|
|
175
|
+
spec: constants_1.WA_APP_STATE_CHAT_MUTATION_SPECS.DELETE_MESSAGE_FOR_ME,
|
|
176
|
+
chatIndexJid: messageIndex.chatIndexJid,
|
|
177
|
+
value: {
|
|
178
|
+
deleteMessageForMeAction: {
|
|
179
|
+
deleteMedia,
|
|
180
|
+
...(messageTimestamp === undefined ? {} : { messageTimestamp })
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
timestamp,
|
|
184
|
+
indexPartsTail: messageIndex.indexPartsTail
|
|
185
|
+
});
|
|
186
|
+
await this.enqueueAndFlush([mutation]);
|
|
187
|
+
}
|
|
188
|
+
async setChatLock(chatJid, locked) {
|
|
189
|
+
const chatIndexJid = this.normalizeChatMutationJid(chatJid);
|
|
190
|
+
const timestamp = Date.now();
|
|
191
|
+
const pending = [];
|
|
192
|
+
if (locked) {
|
|
193
|
+
pending.push(await this.createArchiveMutation(chatIndexJid, false, timestamp));
|
|
194
|
+
pending.push(this.createSetMutation({
|
|
195
|
+
spec: constants_1.WA_APP_STATE_CHAT_MUTATION_SPECS.PIN,
|
|
196
|
+
chatIndexJid,
|
|
197
|
+
value: {
|
|
198
|
+
pinAction: {
|
|
199
|
+
pinned: false
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
timestamp
|
|
203
|
+
}));
|
|
204
|
+
}
|
|
205
|
+
pending.push(this.createSetMutation({
|
|
206
|
+
spec: constants_1.WA_APP_STATE_CHAT_MUTATION_SPECS.LOCK_CHAT,
|
|
207
|
+
chatIndexJid,
|
|
208
|
+
value: {
|
|
209
|
+
lockChatAction: {
|
|
210
|
+
locked
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
timestamp
|
|
214
|
+
}));
|
|
215
|
+
await this.enqueueAndFlush(pending);
|
|
216
|
+
}
|
|
217
|
+
async flushMutations() {
|
|
218
|
+
if (this.flushPromise) {
|
|
219
|
+
return this.flushPromise;
|
|
220
|
+
}
|
|
221
|
+
const inFlight = this.flushPendingMutationsLoop();
|
|
222
|
+
this.flushPromise = inFlight;
|
|
223
|
+
try {
|
|
224
|
+
return await inFlight;
|
|
225
|
+
}
|
|
226
|
+
finally {
|
|
227
|
+
if (this.flushPromise === inFlight) {
|
|
228
|
+
this.flushPromise = null;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
async enqueueAndFlush(mutations) {
|
|
233
|
+
for (const mutation of mutations) {
|
|
234
|
+
this.enqueueMutation(mutation);
|
|
235
|
+
}
|
|
236
|
+
await this.flushMutations();
|
|
237
|
+
}
|
|
238
|
+
enqueueMutation(mutation) {
|
|
239
|
+
const key = `${mutation.collection}\u0001${mutation.index}`;
|
|
240
|
+
if (this.pendingMutations.has(key)) {
|
|
241
|
+
this.pendingMutations.delete(key);
|
|
242
|
+
}
|
|
243
|
+
this.pendingMutations.set(key, mutation);
|
|
244
|
+
}
|
|
245
|
+
takePendingMutationsBatch() {
|
|
246
|
+
if (this.pendingMutations.size === 0) {
|
|
247
|
+
return [];
|
|
248
|
+
}
|
|
249
|
+
const batch = [...this.pendingMutations.values()];
|
|
250
|
+
this.pendingMutations.clear();
|
|
251
|
+
return batch;
|
|
252
|
+
}
|
|
253
|
+
async flushPendingMutationsLoop() {
|
|
254
|
+
while (true) {
|
|
255
|
+
const batch = this.takePendingMutationsBatch();
|
|
256
|
+
if (batch.length === 0) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
this.logger.debug('app-state mutation flush start', {
|
|
260
|
+
pending: batch.length,
|
|
261
|
+
actions: this.describeMutationActions(batch)
|
|
262
|
+
});
|
|
263
|
+
const collections = [];
|
|
264
|
+
let syncResult;
|
|
265
|
+
try {
|
|
266
|
+
const seenCollections = new Set();
|
|
267
|
+
for (const mutation of batch) {
|
|
268
|
+
if (seenCollections.has(mutation.collection)) {
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
seenCollections.add(mutation.collection);
|
|
272
|
+
collections.push(mutation.collection);
|
|
273
|
+
}
|
|
274
|
+
syncResult = await this.syncAppState({
|
|
275
|
+
collections,
|
|
276
|
+
pendingMutations: batch
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
this.requeueMutations(batch);
|
|
281
|
+
this.logger.warn('app-state mutation flush failed', {
|
|
282
|
+
pending: batch.length,
|
|
283
|
+
actions: this.describeMutationActions(batch),
|
|
284
|
+
message: (0, primitives_1.toError)(error).message
|
|
285
|
+
});
|
|
286
|
+
throw (0, primitives_1.toError)(error);
|
|
287
|
+
}
|
|
288
|
+
const stateByCollection = new Map();
|
|
289
|
+
for (const entry of syncResult.collections) {
|
|
290
|
+
stateByCollection.set(entry.collection, entry.state);
|
|
291
|
+
}
|
|
292
|
+
const failedCollections = collections.filter((collection) => {
|
|
293
|
+
const state = stateByCollection.get(collection);
|
|
294
|
+
return !state || !WA_APP_STATE_MUTATION_FLUSH_SUCCESS_STATES.has(state);
|
|
295
|
+
});
|
|
296
|
+
if (failedCollections.length === 0) {
|
|
297
|
+
this.logger.debug('app-state mutation flush completed', {
|
|
298
|
+
pending: batch.length
|
|
299
|
+
});
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
this.requeueMutations(batch.filter((mutation) => failedCollections.includes(mutation.collection)));
|
|
303
|
+
const error = new Error(`app-state mutation flush incomplete (${failedCollections.join(',')})`);
|
|
304
|
+
this.logger.warn('app-state mutation flush incomplete', {
|
|
305
|
+
pending: batch.length,
|
|
306
|
+
actions: this.describeMutationActions(batch),
|
|
307
|
+
failedCollections: failedCollections.join(','),
|
|
308
|
+
message: error.message
|
|
309
|
+
});
|
|
310
|
+
throw error;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
requeueMutations(mutations) {
|
|
314
|
+
if (mutations.length === 0) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
const existing = [...this.pendingMutations.values()];
|
|
318
|
+
this.pendingMutations.clear();
|
|
319
|
+
for (const mutation of mutations) {
|
|
320
|
+
this.enqueueMutation(mutation);
|
|
321
|
+
}
|
|
322
|
+
for (const mutation of existing) {
|
|
323
|
+
this.enqueueMutation(mutation);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
createSetMutation(input) {
|
|
327
|
+
return {
|
|
328
|
+
collection: input.spec.collection,
|
|
329
|
+
operation: 'set',
|
|
330
|
+
index: this.buildMutationIndex(input.spec.action, input.chatIndexJid, input.indexPartsTail ?? []),
|
|
331
|
+
value: {
|
|
332
|
+
...input.value,
|
|
333
|
+
timestamp: input.timestamp
|
|
334
|
+
},
|
|
335
|
+
version: input.spec.version,
|
|
336
|
+
timestamp: input.timestamp
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
async createArchiveMutation(chatIndexJid, archived, timestamp) {
|
|
340
|
+
const messageRange = await this.buildChatMessageRange(chatIndexJid);
|
|
341
|
+
return this.createSetMutation({
|
|
342
|
+
spec: constants_1.WA_APP_STATE_CHAT_MUTATION_SPECS.ARCHIVE,
|
|
343
|
+
chatIndexJid,
|
|
344
|
+
value: {
|
|
345
|
+
archiveChatAction: {
|
|
346
|
+
archived,
|
|
347
|
+
messageRange
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
timestamp
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
async buildChatMessageRange(chatIndexJid) {
|
|
354
|
+
const records = await this.messageStore.listByThread(chatIndexJid, this.archiveRangeLimit);
|
|
355
|
+
const messages = [];
|
|
356
|
+
let lastMessageTimestamp;
|
|
357
|
+
let skippedMissingGroupParticipant = 0;
|
|
358
|
+
for (const record of records) {
|
|
359
|
+
const timestampSeconds = this.toOptionalTimestampSeconds(record.timestampMs);
|
|
360
|
+
const message = this.toChatMessageRangeMessage(record, chatIndexJid, timestampSeconds);
|
|
361
|
+
if (!message) {
|
|
362
|
+
skippedMissingGroupParticipant += 1;
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
if (timestampSeconds !== undefined &&
|
|
366
|
+
(lastMessageTimestamp === undefined || timestampSeconds > lastMessageTimestamp)) {
|
|
367
|
+
lastMessageTimestamp = timestampSeconds;
|
|
368
|
+
}
|
|
369
|
+
messages.push(message);
|
|
370
|
+
}
|
|
371
|
+
if (skippedMissingGroupParticipant > 0) {
|
|
372
|
+
this.logger.debug('app-state message range skipped invalid group messages', {
|
|
373
|
+
chatJid: chatIndexJid,
|
|
374
|
+
skippedMissingGroupParticipant
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
return {
|
|
378
|
+
...(lastMessageTimestamp === undefined ? {} : { lastMessageTimestamp }),
|
|
379
|
+
messages
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
toChatMessageRangeMessage(record, chatIndexJid, timestampSeconds) {
|
|
383
|
+
const key = {
|
|
384
|
+
remoteJid: chatIndexJid,
|
|
385
|
+
fromMe: record.fromMe,
|
|
386
|
+
id: record.id
|
|
387
|
+
};
|
|
388
|
+
if ((0, jid_1.isGroupJid)(chatIndexJid) && !record.fromMe) {
|
|
389
|
+
const participant = record.participantJid ?? record.senderJid;
|
|
390
|
+
if (!participant) {
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
key.participant = this.normalizeMessageRangeParticipant(participant);
|
|
394
|
+
}
|
|
395
|
+
return {
|
|
396
|
+
key,
|
|
397
|
+
...(timestampSeconds === undefined ? {} : { timestamp: timestampSeconds })
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
normalizeMessageRangeParticipant(participantJid) {
|
|
401
|
+
const normalized = (0, jid_1.normalizeRecipientJid)(participantJid);
|
|
402
|
+
if ((0, jid_1.isGroupOrBroadcastJid)(normalized)) {
|
|
403
|
+
throw new Error(`invalid group/broadcast participant in message range: ${participantJid}`);
|
|
404
|
+
}
|
|
405
|
+
return (0, jid_1.normalizeDeviceJid)(normalized);
|
|
406
|
+
}
|
|
407
|
+
toOptionalTimestampSeconds(timestampMs) {
|
|
408
|
+
if (timestampMs === undefined) {
|
|
409
|
+
return undefined;
|
|
410
|
+
}
|
|
411
|
+
if (!Number.isFinite(timestampMs) ||
|
|
412
|
+
!Number.isSafeInteger(timestampMs) ||
|
|
413
|
+
timestampMs < 0) {
|
|
414
|
+
return undefined;
|
|
415
|
+
}
|
|
416
|
+
return Math.floor(timestampMs / 1000);
|
|
417
|
+
}
|
|
418
|
+
normalizeChatMutationJid(chatJid) {
|
|
419
|
+
const normalized = (0, jid_1.normalizeRecipientJid)(chatJid);
|
|
420
|
+
if ((0, jid_1.isGroupOrBroadcastJid)(normalized)) {
|
|
421
|
+
return normalized;
|
|
422
|
+
}
|
|
423
|
+
return (0, jid_1.toUserJid)(normalized);
|
|
424
|
+
}
|
|
425
|
+
buildMessageMutationIndex(message) {
|
|
426
|
+
const chatIndexJid = this.normalizeChatMutationJid(message.chatJid);
|
|
427
|
+
const messageId = message.id.trim();
|
|
428
|
+
if (messageId.length === 0) {
|
|
429
|
+
throw new Error('message id cannot be empty');
|
|
430
|
+
}
|
|
431
|
+
const fromMe = message.fromMe === true;
|
|
432
|
+
const participant = this.resolveMessageMutationParticipant(chatIndexJid, fromMe, message.participantJid);
|
|
433
|
+
return {
|
|
434
|
+
chatIndexJid,
|
|
435
|
+
indexPartsTail: [messageId, fromMe ? '1' : '0', participant]
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
resolveMessageMutationParticipant(chatIndexJid, fromMe, participantJid) {
|
|
439
|
+
if (fromMe || !(0, jid_1.isGroupOrBroadcastJid)(chatIndexJid)) {
|
|
440
|
+
return '0';
|
|
441
|
+
}
|
|
442
|
+
if (!participantJid) {
|
|
443
|
+
throw new Error('participantJid is required for incoming message mutations in group/broadcast chats');
|
|
444
|
+
}
|
|
445
|
+
const normalized = (0, jid_1.normalizeRecipientJid)(participantJid);
|
|
446
|
+
if ((0, jid_1.isGroupOrBroadcastJid)(normalized)) {
|
|
447
|
+
throw new Error(`invalid participantJid for message mutation: ${participantJid}`);
|
|
448
|
+
}
|
|
449
|
+
return (0, jid_1.normalizeDeviceJid)(normalized);
|
|
450
|
+
}
|
|
451
|
+
buildMutationIndex(action, chatIndexJid, indexPartsTail) {
|
|
452
|
+
return JSON.stringify([action, chatIndexJid, ...indexPartsTail]);
|
|
453
|
+
}
|
|
454
|
+
describeMutationActions(mutations) {
|
|
455
|
+
return mutations
|
|
456
|
+
.map((mutation) => {
|
|
457
|
+
try {
|
|
458
|
+
const parsed = JSON.parse(mutation.index);
|
|
459
|
+
if (Array.isArray(parsed) && typeof parsed[0] === 'string') {
|
|
460
|
+
return `${mutation.collection}:${parsed[0]}`;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
catch (error) {
|
|
464
|
+
void error;
|
|
465
|
+
}
|
|
466
|
+
return `${mutation.collection}:unknown`;
|
|
467
|
+
})
|
|
468
|
+
.join(',');
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
exports.WaAppStateMutationCoordinator = WaAppStateMutationCoordinator;
|
|
@@ -1,24 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createGroupCoordinator = createGroupCoordinator;
|
|
4
|
+
const group_1 = require("../events/group");
|
|
4
5
|
const defaults_1 = require("../../protocol/defaults");
|
|
5
|
-
const
|
|
6
|
+
const group_2 = require("../../protocol/group");
|
|
6
7
|
const nodes_1 = require("../../protocol/nodes");
|
|
7
|
-
const
|
|
8
|
+
const group_3 = require("../../transport/node/builders/group");
|
|
8
9
|
const helpers_1 = require("../../transport/node/helpers");
|
|
9
10
|
const query_1 = require("../../transport/node/query");
|
|
10
11
|
function parseGroupParticipants(node) {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const parsed = (0, group_1.parseParticipants)(node);
|
|
13
|
+
const participants = [];
|
|
14
|
+
for (const participant of parsed) {
|
|
15
|
+
if (!participant.jid) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
const type = participant.role ?? group_2.WA_GROUP_PARTICIPANT_TYPES.REGULAR;
|
|
19
|
+
participants.push({
|
|
20
|
+
jid: participant.jid,
|
|
16
21
|
type,
|
|
17
|
-
isAdmin: type ===
|
|
18
|
-
type ===
|
|
19
|
-
isSuperAdmin: type ===
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
+
isAdmin: type === group_2.WA_GROUP_PARTICIPANT_TYPES.ADMIN ||
|
|
23
|
+
type === group_2.WA_GROUP_PARTICIPANT_TYPES.SUPERADMIN,
|
|
24
|
+
isSuperAdmin: type === group_2.WA_GROUP_PARTICIPANT_TYPES.SUPERADMIN
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return participants;
|
|
22
28
|
}
|
|
23
29
|
function parseGroupMetadata(node) {
|
|
24
30
|
const groupNode = node.tag === nodes_1.WA_NODE_TAGS.GROUP ? node : (0, helpers_1.findNodeChild)(node, nodes_1.WA_NODE_TAGS.GROUP);
|
|
@@ -63,7 +69,7 @@ function createGroupCoordinator(options) {
|
|
|
63
69
|
const { queryWithContext } = options;
|
|
64
70
|
const changeParticipants = async (action, groupJid, participants) => {
|
|
65
71
|
const context = `group.${action}Participants`;
|
|
66
|
-
const node = (0,
|
|
72
|
+
const node = (0, group_3.buildGroupParticipantChangeIq)({
|
|
67
73
|
groupJid,
|
|
68
74
|
action,
|
|
69
75
|
participants
|
|
@@ -97,8 +103,12 @@ function createGroupCoordinator(options) {
|
|
|
97
103
|
]);
|
|
98
104
|
const result = await queryWithContext('group.list', node);
|
|
99
105
|
(0, query_1.assertIqResult)(result, 'group.list');
|
|
100
|
-
const groupNodes = (0, helpers_1.
|
|
101
|
-
|
|
106
|
+
const groupNodes = (0, helpers_1.getNodeChildrenByTagFromChildren)(result, nodes_1.WA_NODE_TAGS.GROUP);
|
|
107
|
+
const metadata = [];
|
|
108
|
+
for (const groupNode of groupNodes) {
|
|
109
|
+
metadata.push(parseGroupMetadata(groupNode));
|
|
110
|
+
}
|
|
111
|
+
return metadata;
|
|
102
112
|
},
|
|
103
113
|
queryGroupInviteInfo: async (code) => {
|
|
104
114
|
const node = (0, query_1.buildIqNode)('get', defaults_1.WA_DEFAULTS.GROUP_SERVER, nodes_1.WA_XMLNS.GROUPS, [
|
|
@@ -109,7 +119,7 @@ function createGroupCoordinator(options) {
|
|
|
109
119
|
return result;
|
|
110
120
|
},
|
|
111
121
|
createGroup: async (subject, participants, opts) => {
|
|
112
|
-
const node = (0,
|
|
122
|
+
const node = (0, group_3.buildCreateGroupIq)({
|
|
113
123
|
subject,
|
|
114
124
|
participants,
|
|
115
125
|
description: opts?.description
|
|
@@ -166,7 +176,7 @@ function createGroupCoordinator(options) {
|
|
|
166
176
|
promoteParticipants: async (groupJid, participants) => changeParticipants('promote', groupJid, participants),
|
|
167
177
|
demoteParticipants: async (groupJid, participants) => changeParticipants('demote', groupJid, participants),
|
|
168
178
|
leaveGroup: async (groupJids) => {
|
|
169
|
-
const node = (0,
|
|
179
|
+
const node = (0, group_3.buildLeaveGroupIq)(groupJids);
|
|
170
180
|
const result = await queryWithContext('group.leave', node);
|
|
171
181
|
(0, query_1.assertIqResult)(result, 'group.leave');
|
|
172
182
|
return result;
|
|
@@ -80,14 +80,20 @@ class WaIncomingNodeCoordinator {
|
|
|
80
80
|
return true;
|
|
81
81
|
}
|
|
82
82
|
async dispatchIncomingNode(node) {
|
|
83
|
+
const handlersByTag = this.nodeHandlerRegistry.get(node.tag);
|
|
84
|
+
const nodeSubtype = node.attrs.type;
|
|
83
85
|
if (node.tag === constants_1.WA_MESSAGE_TAGS.RECEIPT) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
if (handlersByTag && handlersByTag.length > 0) {
|
|
87
|
+
for (const entry of handlersByTag) {
|
|
88
|
+
if (entry.subtype !== undefined && entry.subtype !== nodeSubtype) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (await entry.handler(node)) {
|
|
92
|
+
if (!this.isRetryReceiptType(nodeSubtype)) {
|
|
93
|
+
this.runtime.tryResolvePendingNode(node);
|
|
94
|
+
}
|
|
95
|
+
return true;
|
|
89
96
|
}
|
|
90
|
-
return true;
|
|
91
97
|
}
|
|
92
98
|
}
|
|
93
99
|
return this.runtime.tryResolvePendingNode(node);
|
|
@@ -99,12 +105,14 @@ class WaIncomingNodeCoordinator {
|
|
|
99
105
|
if (genericHandled) {
|
|
100
106
|
return true;
|
|
101
107
|
}
|
|
102
|
-
|
|
103
|
-
if (handlers.length === 0) {
|
|
108
|
+
if (!handlersByTag || handlersByTag.length === 0) {
|
|
104
109
|
return false;
|
|
105
110
|
}
|
|
106
|
-
for (const
|
|
107
|
-
if (
|
|
111
|
+
for (const entry of handlersByTag) {
|
|
112
|
+
if (entry.subtype !== undefined && entry.subtype !== nodeSubtype) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (await entry.handler(node)) {
|
|
108
116
|
return true;
|
|
109
117
|
}
|
|
110
118
|
}
|
|
@@ -113,21 +121,6 @@ class WaIncomingNodeCoordinator {
|
|
|
113
121
|
isRetryReceiptType(type) {
|
|
114
122
|
return type === 'retry' || type === 'enc_rekey_retry';
|
|
115
123
|
}
|
|
116
|
-
getHandlersForNode(node) {
|
|
117
|
-
const handlersByTag = this.nodeHandlerRegistry.get(node.tag);
|
|
118
|
-
if (!handlersByTag || handlersByTag.length === 0) {
|
|
119
|
-
return [];
|
|
120
|
-
}
|
|
121
|
-
const nodeSubtype = node.attrs.type;
|
|
122
|
-
const handlers = [];
|
|
123
|
-
for (const entry of handlersByTag) {
|
|
124
|
-
if (entry.subtype !== undefined && entry.subtype !== nodeSubtype) {
|
|
125
|
-
continue;
|
|
126
|
-
}
|
|
127
|
-
handlers.push(entry.handler);
|
|
128
|
-
}
|
|
129
|
-
return handlers;
|
|
130
|
-
}
|
|
131
124
|
registerDefaultIncomingHandlers() {
|
|
132
125
|
const runtime = this.runtime;
|
|
133
126
|
this.registerIncomingHandler({
|
|
@@ -275,8 +268,8 @@ class WaIncomingNodeCoordinator {
|
|
|
275
268
|
const ibType = node.attrs.type;
|
|
276
269
|
if (ibType && INFO_BULLETIN_NOTIFICATION_TYPES.has(ibType)) {
|
|
277
270
|
this.runtime.emitIncomingNotification((0, incoming_1.createInfoBulletinNotificationEvent)(node, ibType, {
|
|
278
|
-
count: (0,
|
|
279
|
-
t: (0,
|
|
271
|
+
count: (0, primitives_1.parseOptionalInt)(node.attrs.count),
|
|
272
|
+
t: (0, primitives_1.parseOptionalInt)(node.attrs.t)
|
|
280
273
|
}));
|
|
281
274
|
handled = true;
|
|
282
275
|
}
|