zapo-js 0.1.1 → 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 +8 -0
- 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 +26 -5
- 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
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { signalAddressKey } from '../../../protocol/jid.js';
|
|
1
2
|
import { resolvePositive } from '../../../util/coercion.js';
|
|
2
3
|
import { setBoundedMapEntry } from '../../../util/collections.js';
|
|
3
|
-
import { signalAddressKey } from '../../../util/signal-address.js';
|
|
4
4
|
const DEFAULT_SIGNAL_STORE_LIMITS = Object.freeze({
|
|
5
5
|
preKeys: 4096,
|
|
6
6
|
sessions: 8192,
|
|
@@ -126,15 +126,27 @@ export class WaSignalMemoryStore {
|
|
|
126
126
|
async getSession(address) {
|
|
127
127
|
return this.signalSessions.get(signalAddressKey(address)) ?? null;
|
|
128
128
|
}
|
|
129
|
+
async getSessionsBatch(addresses) {
|
|
130
|
+
return addresses.map((address) => this.signalSessions.get(signalAddressKey(address)) ?? null);
|
|
131
|
+
}
|
|
129
132
|
async setSession(address, session) {
|
|
130
133
|
setBoundedMapEntry(this.signalSessions, signalAddressKey(address), session, this.maxSessions);
|
|
131
134
|
}
|
|
135
|
+
async setSessionsBatch(entries) {
|
|
136
|
+
for (let index = 0; index < entries.length; index += 1) {
|
|
137
|
+
const entry = entries[index];
|
|
138
|
+
setBoundedMapEntry(this.signalSessions, signalAddressKey(entry.address), entry.session, this.maxSessions);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
132
141
|
async deleteSession(address) {
|
|
133
142
|
this.signalSessions.delete(signalAddressKey(address));
|
|
134
143
|
}
|
|
135
144
|
async getRemoteIdentity(address) {
|
|
136
145
|
return this.remoteIdentities.get(signalAddressKey(address)) ?? null;
|
|
137
146
|
}
|
|
147
|
+
async getRemoteIdentities(addresses) {
|
|
148
|
+
return addresses.map((address) => this.remoteIdentities.get(signalAddressKey(address)) ?? null);
|
|
149
|
+
}
|
|
138
150
|
async setRemoteIdentity(address, identityKey) {
|
|
139
151
|
setBoundedMapEntry(this.remoteIdentities, signalAddressKey(address), identityKey, this.maxRemoteIdentities);
|
|
140
152
|
}
|
|
@@ -11,6 +11,11 @@ export class WaThreadMemoryStore {
|
|
|
11
11
|
async upsert(record) {
|
|
12
12
|
setBoundedMapEntry(this.threads, record.jid, record, this.maxThreads);
|
|
13
13
|
}
|
|
14
|
+
async upsertBatch(records) {
|
|
15
|
+
for (const record of records) {
|
|
16
|
+
setBoundedMapEntry(this.threads, record.jid, record, this.maxThreads);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
14
19
|
async getByJid(jid) {
|
|
15
20
|
return this.threads.get(jid) ?? null;
|
|
16
21
|
}
|
|
@@ -2,8 +2,18 @@ import { APP_STATE_EMPTY_LT_HASH } from '../../../appstate/constants.js';
|
|
|
2
2
|
import { decodeAppStateCollections, decodeAppStateFingerprint, decodeAppStateSyncKeys, encodeAppStateFingerprint } from '../../../appstate/store/sqlite.js';
|
|
3
3
|
import { keyEpoch, pickActiveSyncKey } from '../../../appstate/utils.js';
|
|
4
4
|
import { BaseSqliteStore } from '../../providers/sqlite/BaseSqliteStore.js';
|
|
5
|
-
import { uint8Equal } from '../../../util/bytes.js';
|
|
5
|
+
import { bytesToHex, uint8Equal } from '../../../util/bytes.js';
|
|
6
6
|
import { asBytes, asNumber, asString } from '../../../util/coercion.js';
|
|
7
|
+
function repeatSqlToken(token, count, separator) {
|
|
8
|
+
if (count <= 1) {
|
|
9
|
+
return token;
|
|
10
|
+
}
|
|
11
|
+
let out = token;
|
|
12
|
+
for (let index = 1; index < count; index += 1) {
|
|
13
|
+
out += separator + token;
|
|
14
|
+
}
|
|
15
|
+
return out;
|
|
16
|
+
}
|
|
7
17
|
export class WaAppStateSqliteStore extends BaseSqliteStore {
|
|
8
18
|
constructor(options) {
|
|
9
19
|
super(options, ['appState']);
|
|
@@ -85,6 +95,25 @@ export class WaAppStateSqliteStore extends BaseSqliteStore {
|
|
|
85
95
|
}
|
|
86
96
|
return asBytes(row.key_data, 'appstate_sync_keys.key_data');
|
|
87
97
|
}
|
|
98
|
+
async getSyncKeyDataBatch(keyIds) {
|
|
99
|
+
if (keyIds.length === 0) {
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
const db = await this.getConnection();
|
|
103
|
+
const uniqueKeyIds = [
|
|
104
|
+
...new Map(keyIds.map((keyId) => [bytesToHex(keyId), keyId])).values()
|
|
105
|
+
];
|
|
106
|
+
const placeholders = repeatSqlToken('?', uniqueKeyIds.length, ', ');
|
|
107
|
+
const params = [this.options.sessionId, ...uniqueKeyIds];
|
|
108
|
+
const rows = db.all(`SELECT key_id, key_data
|
|
109
|
+
FROM appstate_sync_keys
|
|
110
|
+
WHERE session_id = ? AND key_id IN (${placeholders})`, params);
|
|
111
|
+
const byKeyHex = new Map();
|
|
112
|
+
for (const row of rows) {
|
|
113
|
+
byKeyHex.set(bytesToHex(asBytes(row.key_id, 'appstate_sync_keys.key_id')), asBytes(row.key_data, 'appstate_sync_keys.key_data'));
|
|
114
|
+
}
|
|
115
|
+
return keyIds.map((keyId) => byKeyHex.get(bytesToHex(keyId)) ?? null);
|
|
116
|
+
}
|
|
88
117
|
async getActiveSyncKey() {
|
|
89
118
|
const db = await this.getConnection();
|
|
90
119
|
const rows = db.all(`SELECT key_id, key_data, timestamp, fingerprint
|
|
@@ -109,6 +138,7 @@ export class WaAppStateSqliteStore extends BaseSqliteStore {
|
|
|
109
138
|
WHERE session_id = ? AND collection = ?`, [this.options.sessionId, collection]);
|
|
110
139
|
if (!versionRow) {
|
|
111
140
|
return {
|
|
141
|
+
initialized: false,
|
|
112
142
|
version: 0,
|
|
113
143
|
hash: APP_STATE_EMPTY_LT_HASH,
|
|
114
144
|
indexValueMap: new Map()
|
|
@@ -122,11 +152,62 @@ export class WaAppStateSqliteStore extends BaseSqliteStore {
|
|
|
122
152
|
indexValueMap.set(asString(row.index_mac_hex, 'appstate_collection_index_values.index_mac_hex'), asBytes(row.value_mac, 'appstate_collection_index_values.value_mac'));
|
|
123
153
|
}
|
|
124
154
|
return {
|
|
155
|
+
initialized: true,
|
|
125
156
|
version: asNumber(versionRow.version, 'appstate_collection_versions.version'),
|
|
126
157
|
hash: asBytes(versionRow.hash, 'appstate_collection_versions.hash'),
|
|
127
158
|
indexValueMap
|
|
128
159
|
};
|
|
129
160
|
}
|
|
161
|
+
async getCollectionStates(collections) {
|
|
162
|
+
if (collections.length === 0) {
|
|
163
|
+
return [];
|
|
164
|
+
}
|
|
165
|
+
const db = await this.getConnection();
|
|
166
|
+
const uniqueCollections = [...new Set(collections)];
|
|
167
|
+
const placeholders = repeatSqlToken('?', uniqueCollections.length, ', ');
|
|
168
|
+
const params = [this.options.sessionId, ...uniqueCollections];
|
|
169
|
+
const versionRows = db.all(`SELECT collection, version, hash
|
|
170
|
+
FROM appstate_collection_versions
|
|
171
|
+
WHERE session_id = ? AND collection IN (${placeholders})`, params);
|
|
172
|
+
const valueRows = db.all(`SELECT collection, index_mac_hex, value_mac
|
|
173
|
+
FROM appstate_collection_index_values
|
|
174
|
+
WHERE session_id = ? AND collection IN (${placeholders})`, params);
|
|
175
|
+
const versionsByCollection = new Map();
|
|
176
|
+
for (const row of versionRows) {
|
|
177
|
+
const collection = asString(row.collection, 'appstate_collection_versions.collection');
|
|
178
|
+
versionsByCollection.set(collection, {
|
|
179
|
+
version: asNumber(row.version, 'appstate_collection_versions.version'),
|
|
180
|
+
hash: asBytes(row.hash, 'appstate_collection_versions.hash')
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
const indexValueMaps = new Map();
|
|
184
|
+
for (const row of valueRows) {
|
|
185
|
+
const collection = asString(row.collection, 'appstate_collection_index_values.collection');
|
|
186
|
+
const map = indexValueMaps.get(collection);
|
|
187
|
+
const targetMap = map ?? new Map();
|
|
188
|
+
targetMap.set(asString(row.index_mac_hex, 'appstate_collection_index_values.index_mac_hex'), asBytes(row.value_mac, 'appstate_collection_index_values.value_mac'));
|
|
189
|
+
if (!map) {
|
|
190
|
+
indexValueMaps.set(collection, targetMap);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return collections.map((collection) => {
|
|
194
|
+
const version = versionsByCollection.get(collection);
|
|
195
|
+
if (!version) {
|
|
196
|
+
return {
|
|
197
|
+
initialized: false,
|
|
198
|
+
version: 0,
|
|
199
|
+
hash: APP_STATE_EMPTY_LT_HASH,
|
|
200
|
+
indexValueMap: new Map()
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
initialized: true,
|
|
205
|
+
version: version.version,
|
|
206
|
+
hash: version.hash,
|
|
207
|
+
indexValueMap: indexValueMaps.get(collection) ?? new Map()
|
|
208
|
+
};
|
|
209
|
+
});
|
|
210
|
+
}
|
|
130
211
|
async setCollectionStates(updates) {
|
|
131
212
|
if (updates.length === 0) {
|
|
132
213
|
return;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createSqliteTableNameSqlResolver, resolveSqliteTableNames, serializeSqliteTableNames } from '../../providers/sqlite/table-names.js';
|
|
1
2
|
import { toSafeNumber } from '../../../util/primitives.js';
|
|
2
3
|
import { isBunRuntime } from '../../../util/runtime.js';
|
|
3
4
|
const BETTER_SQLITE3_MODULE = 'better-sqlite3';
|
|
@@ -51,21 +52,22 @@ function statementFor(db, sql) {
|
|
|
51
52
|
}
|
|
52
53
|
return statement;
|
|
53
54
|
}
|
|
54
|
-
function wrapConnection(db, driver, onClose) {
|
|
55
|
+
function wrapConnection(db, driver, resolveSql, onClose) {
|
|
55
56
|
const statementCache = new Map();
|
|
56
57
|
const cachedStatementFor = (sql) => {
|
|
57
|
-
const
|
|
58
|
+
const resolvedSql = resolveSql(sql);
|
|
59
|
+
const cached = statementCache.get(resolvedSql);
|
|
58
60
|
if (cached) {
|
|
59
61
|
return cached;
|
|
60
62
|
}
|
|
61
|
-
const statement = statementFor(db,
|
|
62
|
-
statementCache.set(
|
|
63
|
+
const statement = statementFor(db, resolvedSql);
|
|
64
|
+
statementCache.set(resolvedSql, statement);
|
|
63
65
|
return statement;
|
|
64
66
|
};
|
|
65
67
|
return {
|
|
66
68
|
driver,
|
|
67
69
|
exec(sql) {
|
|
68
|
-
db.exec(sql);
|
|
70
|
+
db.exec(resolveSql(sql));
|
|
69
71
|
},
|
|
70
72
|
run(sql, params) {
|
|
71
73
|
const statement = cachedStatementFor(sql);
|
|
@@ -159,7 +161,7 @@ function closeDatabaseSafely(db) {
|
|
|
159
161
|
return;
|
|
160
162
|
}
|
|
161
163
|
}
|
|
162
|
-
async function openBetterSqlite(options, onClose) {
|
|
164
|
+
async function openBetterSqlite(options, resolveSql, onClose) {
|
|
163
165
|
let loaded;
|
|
164
166
|
try {
|
|
165
167
|
loaded = await import(BETTER_SQLITE3_MODULE);
|
|
@@ -176,9 +178,9 @@ async function openBetterSqlite(options, onClose) {
|
|
|
176
178
|
closeDatabaseSafely(db);
|
|
177
179
|
throw error;
|
|
178
180
|
}
|
|
179
|
-
return wrapConnection(db, 'better-sqlite3', onClose);
|
|
181
|
+
return wrapConnection(db, 'better-sqlite3', resolveSql, onClose);
|
|
180
182
|
}
|
|
181
|
-
async function openBunSqlite(options, onClose) {
|
|
183
|
+
async function openBunSqlite(options, resolveSql, onClose) {
|
|
182
184
|
let loaded;
|
|
183
185
|
try {
|
|
184
186
|
loaded = await import(BUN_SQLITE_MODULE);
|
|
@@ -201,7 +203,7 @@ async function openBunSqlite(options, onClose) {
|
|
|
201
203
|
closeDatabaseSafely(db);
|
|
202
204
|
throw error;
|
|
203
205
|
}
|
|
204
|
-
return wrapConnection(db, 'bun', onClose);
|
|
206
|
+
return wrapConnection(db, 'bun', resolveSql, onClose);
|
|
205
207
|
}
|
|
206
208
|
function resolveDriver(requested) {
|
|
207
209
|
if (requested && requested !== 'auto') {
|
|
@@ -211,15 +213,18 @@ function resolveDriver(requested) {
|
|
|
211
213
|
}
|
|
212
214
|
export async function openSqliteConnection(options) {
|
|
213
215
|
const driver = resolveDriver(options.driver);
|
|
216
|
+
const resolvedTableNames = resolveSqliteTableNames(options.tableNames);
|
|
217
|
+
const resolveSql = createSqliteTableNameSqlResolver(resolvedTableNames);
|
|
214
218
|
const normalizedOptions = {
|
|
215
219
|
...options,
|
|
216
220
|
driver,
|
|
217
|
-
pragmas: mergePragmas(options.pragmas)
|
|
221
|
+
pragmas: mergePragmas(options.pragmas),
|
|
222
|
+
tableNames: resolvedTableNames
|
|
218
223
|
};
|
|
219
224
|
const cacheKey = `${driver}|${options.path}|${Object.entries(normalizedOptions.pragmas ?? {})
|
|
220
225
|
.sort(([left], [right]) => left.localeCompare(right))
|
|
221
226
|
.map(([key, value]) => `${key}=${String(value)}`)
|
|
222
|
-
.join(';')}`;
|
|
227
|
+
.join(';')}|${serializeSqliteTableNames(resolvedTableNames)}`;
|
|
223
228
|
const cached = SQLITE_CONNECTION_CACHE.get(cacheKey);
|
|
224
229
|
if (cached) {
|
|
225
230
|
return cached;
|
|
@@ -228,8 +233,8 @@ export async function openSqliteConnection(options) {
|
|
|
228
233
|
SQLITE_CONNECTION_CACHE.delete(cacheKey);
|
|
229
234
|
};
|
|
230
235
|
const created = driver === 'bun'
|
|
231
|
-
? openBunSqlite(normalizedOptions, onClose)
|
|
232
|
-
: openBetterSqlite(normalizedOptions, onClose);
|
|
236
|
+
? openBunSqlite(normalizedOptions, resolveSql, onClose)
|
|
237
|
+
: openBetterSqlite(normalizedOptions, resolveSql, onClose);
|
|
233
238
|
const guarded = created.catch((error) => {
|
|
234
239
|
SQLITE_CONNECTION_CACHE.delete(cacheKey);
|
|
235
240
|
throw error;
|
|
@@ -16,6 +16,37 @@ export class WaContactSqliteStore extends BaseSqliteStore {
|
|
|
16
16
|
}
|
|
17
17
|
async upsert(record) {
|
|
18
18
|
const db = await this.getConnection();
|
|
19
|
+
this.upsertContactRow(db, record);
|
|
20
|
+
}
|
|
21
|
+
async upsertBatch(records) {
|
|
22
|
+
if (records.length === 0) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
await this.withTransaction((db) => {
|
|
26
|
+
for (const record of records) {
|
|
27
|
+
this.upsertContactRow(db, record);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
async getByJid(jid) {
|
|
32
|
+
const db = await this.getConnection();
|
|
33
|
+
const row = db.get(`SELECT jid, display_name, push_name, lid, phone_number, last_updated_ms
|
|
34
|
+
FROM mailbox_contacts
|
|
35
|
+
WHERE session_id = ? AND jid = ?`, [this.options.sessionId, jid]);
|
|
36
|
+
return row ? decodeContactRow(row) : null;
|
|
37
|
+
}
|
|
38
|
+
async deleteByJid(jid) {
|
|
39
|
+
const db = await this.getConnection();
|
|
40
|
+
db.run(`DELETE FROM mailbox_contacts
|
|
41
|
+
WHERE session_id = ? AND jid = ?`, [this.options.sessionId, jid]);
|
|
42
|
+
const row = db.get('SELECT changes() AS total', []);
|
|
43
|
+
return row ? Number(row.total) : 0;
|
|
44
|
+
}
|
|
45
|
+
async clear() {
|
|
46
|
+
const db = await this.getConnection();
|
|
47
|
+
db.run('DELETE FROM mailbox_contacts WHERE session_id = ?', [this.options.sessionId]);
|
|
48
|
+
}
|
|
49
|
+
upsertContactRow(db, record) {
|
|
19
50
|
db.run(`INSERT INTO mailbox_contacts (
|
|
20
51
|
session_id,
|
|
21
52
|
jid,
|
|
@@ -40,22 +71,4 @@ export class WaContactSqliteStore extends BaseSqliteStore {
|
|
|
40
71
|
record.lastUpdatedMs
|
|
41
72
|
]);
|
|
42
73
|
}
|
|
43
|
-
async getByJid(jid) {
|
|
44
|
-
const db = await this.getConnection();
|
|
45
|
-
const row = db.get(`SELECT jid, display_name, push_name, lid, phone_number, last_updated_ms
|
|
46
|
-
FROM mailbox_contacts
|
|
47
|
-
WHERE session_id = ? AND jid = ?`, [this.options.sessionId, jid]);
|
|
48
|
-
return row ? decodeContactRow(row) : null;
|
|
49
|
-
}
|
|
50
|
-
async deleteByJid(jid) {
|
|
51
|
-
const db = await this.getConnection();
|
|
52
|
-
db.run(`DELETE FROM mailbox_contacts
|
|
53
|
-
WHERE session_id = ? AND jid = ?`, [this.options.sessionId, jid]);
|
|
54
|
-
const row = db.get('SELECT changes() AS total', []);
|
|
55
|
-
return row ? Number(row.total) : 0;
|
|
56
|
-
}
|
|
57
|
-
async clear() {
|
|
58
|
-
const db = await this.getConnection();
|
|
59
|
-
db.run('DELETE FROM mailbox_contacts WHERE session_id = ?', [this.options.sessionId]);
|
|
60
|
-
}
|
|
61
74
|
}
|
|
@@ -10,13 +10,6 @@ export class WaDeviceListSqliteStore extends BaseSqliteStore {
|
|
|
10
10
|
this.ttlMs = ttlMs;
|
|
11
11
|
this.batchSize = resolvePositive(batchSize, DEFAULTS.batchSize, 'deviceList.sqlite.batchSize');
|
|
12
12
|
}
|
|
13
|
-
getTtlMs() {
|
|
14
|
-
return this.ttlMs;
|
|
15
|
-
}
|
|
16
|
-
async upsertUserDevices(snapshot) {
|
|
17
|
-
const db = await this.getConnection();
|
|
18
|
-
this.upsertUserDevicesRow(db, snapshot);
|
|
19
|
-
}
|
|
20
13
|
async upsertUserDevicesBatch(snapshots) {
|
|
21
14
|
if (snapshots.length === 0) {
|
|
22
15
|
return;
|
|
@@ -27,26 +20,6 @@ export class WaDeviceListSqliteStore extends BaseSqliteStore {
|
|
|
27
20
|
}
|
|
28
21
|
});
|
|
29
22
|
}
|
|
30
|
-
async getUserDevices(userJid, nowMs = Date.now()) {
|
|
31
|
-
const db = await this.getConnection();
|
|
32
|
-
const row = db.get(`SELECT user_jid, device_jids_json, updated_at_ms, expires_at_ms
|
|
33
|
-
FROM device_list_cache
|
|
34
|
-
WHERE session_id = ? AND user_jid = ?`, [this.options.sessionId, userJid]);
|
|
35
|
-
if (!row) {
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
const expiresAtMs = asNumber(row.expires_at_ms, 'device_list_cache.expires_at_ms');
|
|
39
|
-
if (expiresAtMs <= nowMs) {
|
|
40
|
-
db.run(`DELETE FROM device_list_cache
|
|
41
|
-
WHERE session_id = ? AND user_jid = ?`, [this.options.sessionId, userJid]);
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
return {
|
|
45
|
-
userJid: asString(row.user_jid, 'device_list_cache.user_jid'),
|
|
46
|
-
deviceJids: decodeDeviceJids(row.device_jids_json),
|
|
47
|
-
updatedAtMs: asNumber(row.updated_at_ms, 'device_list_cache.updated_at_ms')
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
23
|
async getUserDevicesBatch(userJids, nowMs = Date.now()) {
|
|
51
24
|
if (userJids.length === 0) {
|
|
52
25
|
return [];
|
|
@@ -58,7 +31,7 @@ export class WaDeviceListSqliteStore extends BaseSqliteStore {
|
|
|
58
31
|
for (let start = 0; start < uniqueUserJids.length; start += this.batchSize) {
|
|
59
32
|
const end = Math.min(start + this.batchSize, uniqueUserJids.length);
|
|
60
33
|
const batchLength = end - start;
|
|
61
|
-
const placeholders =
|
|
34
|
+
const placeholders = '?, '.repeat(batchLength).slice(0, -2);
|
|
62
35
|
const params = [this.options.sessionId];
|
|
63
36
|
for (let index = start; index < end; index += 1) {
|
|
64
37
|
params.push(uniqueUserJids[index]);
|
|
@@ -130,7 +103,7 @@ export class WaDeviceListSqliteStore extends BaseSqliteStore {
|
|
|
130
103
|
for (let start = 0; start < userJids.length; start += this.batchSize) {
|
|
131
104
|
const end = Math.min(start + this.batchSize, userJids.length);
|
|
132
105
|
const batchLength = end - start;
|
|
133
|
-
const placeholders =
|
|
106
|
+
const placeholders = '?, '.repeat(batchLength).slice(0, -2);
|
|
134
107
|
const params = [this.options.sessionId];
|
|
135
108
|
for (let index = start; index < end; index += 1) {
|
|
136
109
|
params.push(userJids[index]);
|
|
@@ -146,10 +119,9 @@ function decodeDeviceJids(raw) {
|
|
|
146
119
|
if (!Array.isArray(parsed)) {
|
|
147
120
|
throw new Error('device_list_cache.device_jids_json must be an array');
|
|
148
121
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
});
|
|
122
|
+
const deviceJids = new Array(parsed.length);
|
|
123
|
+
for (let index = 0; index < parsed.length; index += 1) {
|
|
124
|
+
deviceJids[index] = asString(parsed[index], 'device_list_cache.device_jids_json entry');
|
|
125
|
+
}
|
|
126
|
+
return deviceJids;
|
|
155
127
|
}
|
|
@@ -20,38 +20,17 @@ export class WaMessageSqliteStore extends BaseSqliteStore {
|
|
|
20
20
|
}
|
|
21
21
|
async upsert(record) {
|
|
22
22
|
const db = await this.getConnection();
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
35
|
-
ON CONFLICT(session_id, message_id) DO UPDATE SET
|
|
36
|
-
thread_jid=excluded.thread_jid,
|
|
37
|
-
sender_jid=excluded.sender_jid,
|
|
38
|
-
participant_jid=excluded.participant_jid,
|
|
39
|
-
from_me=excluded.from_me,
|
|
40
|
-
timestamp_ms=excluded.timestamp_ms,
|
|
41
|
-
enc_type=excluded.enc_type,
|
|
42
|
-
plaintext=excluded.plaintext,
|
|
43
|
-
message_bytes=excluded.message_bytes`, [
|
|
44
|
-
this.options.sessionId,
|
|
45
|
-
record.id,
|
|
46
|
-
record.threadJid,
|
|
47
|
-
record.senderJid ?? null,
|
|
48
|
-
record.participantJid ?? null,
|
|
49
|
-
record.fromMe ? 1 : 0,
|
|
50
|
-
record.timestampMs ?? null,
|
|
51
|
-
record.encType ?? null,
|
|
52
|
-
record.plaintext ?? null,
|
|
53
|
-
record.messageBytes ?? null
|
|
54
|
-
]);
|
|
23
|
+
this.upsertMessageRow(db, record);
|
|
24
|
+
}
|
|
25
|
+
async upsertBatch(records) {
|
|
26
|
+
if (records.length === 0) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
await this.withTransaction((db) => {
|
|
30
|
+
for (const record of records) {
|
|
31
|
+
this.upsertMessageRow(db, record);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
55
34
|
}
|
|
56
35
|
async getById(id) {
|
|
57
36
|
const db = await this.getConnection();
|
|
@@ -116,4 +95,38 @@ export class WaMessageSqliteStore extends BaseSqliteStore {
|
|
|
116
95
|
const db = await this.getConnection();
|
|
117
96
|
db.run('DELETE FROM mailbox_messages WHERE session_id = ?', [this.options.sessionId]);
|
|
118
97
|
}
|
|
98
|
+
upsertMessageRow(db, record) {
|
|
99
|
+
db.run(`INSERT INTO mailbox_messages (
|
|
100
|
+
session_id,
|
|
101
|
+
message_id,
|
|
102
|
+
thread_jid,
|
|
103
|
+
sender_jid,
|
|
104
|
+
participant_jid,
|
|
105
|
+
from_me,
|
|
106
|
+
timestamp_ms,
|
|
107
|
+
enc_type,
|
|
108
|
+
plaintext,
|
|
109
|
+
message_bytes
|
|
110
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
111
|
+
ON CONFLICT(session_id, message_id) DO UPDATE SET
|
|
112
|
+
thread_jid=excluded.thread_jid,
|
|
113
|
+
sender_jid=excluded.sender_jid,
|
|
114
|
+
participant_jid=excluded.participant_jid,
|
|
115
|
+
from_me=excluded.from_me,
|
|
116
|
+
timestamp_ms=excluded.timestamp_ms,
|
|
117
|
+
enc_type=excluded.enc_type,
|
|
118
|
+
plaintext=excluded.plaintext,
|
|
119
|
+
message_bytes=excluded.message_bytes`, [
|
|
120
|
+
this.options.sessionId,
|
|
121
|
+
record.id,
|
|
122
|
+
record.threadJid,
|
|
123
|
+
record.senderJid ?? null,
|
|
124
|
+
record.participantJid ?? null,
|
|
125
|
+
record.fromMe ? 1 : 0,
|
|
126
|
+
record.timestampMs ?? null,
|
|
127
|
+
record.encType ?? null,
|
|
128
|
+
record.plaintext ?? null,
|
|
129
|
+
record.messageBytes ?? null
|
|
130
|
+
]);
|
|
131
|
+
}
|
|
119
132
|
}
|
|
@@ -293,7 +293,7 @@ function isMigrationAlreadyAppliedRace(error) {
|
|
|
293
293
|
if (!(error instanceof Error)) {
|
|
294
294
|
return false;
|
|
295
295
|
}
|
|
296
|
-
return
|
|
296
|
+
return /UNIQUE constraint failed: [A-Za-z_][A-Za-z0-9_]*\.id/.test(error.message);
|
|
297
297
|
}
|
|
298
298
|
function ensureMigrationTable(db) {
|
|
299
299
|
db.exec(`
|
|
@@ -6,9 +6,6 @@ export class WaParticipantsSqliteStore extends BaseSqliteStore {
|
|
|
6
6
|
super(options, ['participants']);
|
|
7
7
|
this.ttlMs = ttlMs;
|
|
8
8
|
}
|
|
9
|
-
getTtlMs() {
|
|
10
|
-
return this.ttlMs;
|
|
11
|
-
}
|
|
12
9
|
async upsertGroupParticipants(snapshot) {
|
|
13
10
|
const db = await this.getConnection();
|
|
14
11
|
db.run(`INSERT INTO group_participants_cache (
|
|
@@ -76,10 +73,5 @@ function decodeParticipants(raw) {
|
|
|
76
73
|
if (!Array.isArray(parsed)) {
|
|
77
74
|
throw new Error('group_participants_cache.participants_json must be an array');
|
|
78
75
|
}
|
|
79
|
-
return parsed.
|
|
80
|
-
if (typeof entry !== 'string') {
|
|
81
|
-
throw new Error('group_participants_cache.participants_json entry must be string');
|
|
82
|
-
}
|
|
83
|
-
return true;
|
|
84
|
-
});
|
|
76
|
+
return parsed.map((entry) => asString(entry, 'group_participants_cache.participants_json entry'));
|
|
85
77
|
}
|
|
@@ -113,12 +113,18 @@ export class WaRetrySqliteStore extends BaseSqliteStore {
|
|
|
113
113
|
}
|
|
114
114
|
async cleanupExpired(nowMs) {
|
|
115
115
|
return this.withTransaction(async (db) => {
|
|
116
|
-
const outboundCount = this.countRows(db, 'retry_outbound_messages', nowMs);
|
|
117
|
-
const inboundCount = this.countRows(db, 'retry_inbound_counters', nowMs);
|
|
118
116
|
db.run(`DELETE FROM retry_outbound_messages
|
|
119
117
|
WHERE session_id = ? AND expires_at_ms <= ?`, [this.options.sessionId, nowMs]);
|
|
118
|
+
const outboundCountRow = db.get('SELECT changes() AS total', []);
|
|
119
|
+
const outboundCount = outboundCountRow
|
|
120
|
+
? asNumber(outboundCountRow.total, 'retry_outbound_messages.changes')
|
|
121
|
+
: 0;
|
|
120
122
|
db.run(`DELETE FROM retry_inbound_counters
|
|
121
123
|
WHERE session_id = ? AND expires_at_ms <= ?`, [this.options.sessionId, nowMs]);
|
|
124
|
+
const inboundCountRow = db.get('SELECT changes() AS total', []);
|
|
125
|
+
const inboundCount = inboundCountRow
|
|
126
|
+
? asNumber(inboundCountRow.total, 'retry_inbound_counters.changes')
|
|
127
|
+
: 0;
|
|
122
128
|
return outboundCount + inboundCount;
|
|
123
129
|
});
|
|
124
130
|
}
|
|
@@ -132,13 +138,4 @@ export class WaRetrySqliteStore extends BaseSqliteStore {
|
|
|
132
138
|
]);
|
|
133
139
|
});
|
|
134
140
|
}
|
|
135
|
-
countRows(db, table, nowMs) {
|
|
136
|
-
const row = db.get(`SELECT COUNT(*) AS total
|
|
137
|
-
FROM ${table}
|
|
138
|
-
WHERE session_id = ? AND expires_at_ms <= ?`, [this.options.sessionId, nowMs]);
|
|
139
|
-
if (!row) {
|
|
140
|
-
return 0;
|
|
141
|
-
}
|
|
142
|
-
return asNumber(row.total, `${table}.count`);
|
|
143
|
-
}
|
|
144
141
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { decodeSenderKeyDistributionRow, decodeSenderKeyRecord,
|
|
1
|
+
import { decodeSenderKeyDistributionRow, decodeSenderKeyRecord, encodeSenderKeyRecord, toSignalAddressParts } from '../../../signal/store/sqlite.js';
|
|
2
2
|
import { BaseSqliteStore } from '../../providers/sqlite/BaseSqliteStore.js';
|
|
3
3
|
import { asNumber, asString, resolvePositive } from '../../../util/coercion.js';
|
|
4
4
|
const DEFAULTS = Object.freeze({
|
|
@@ -82,18 +82,6 @@ export class SenderKeySqliteStore extends BaseSqliteStore {
|
|
|
82
82
|
device: asNumber(row.sender_device, 'sender_keys.sender_device')
|
|
83
83
|
});
|
|
84
84
|
}
|
|
85
|
-
async getDeviceSenderKeyDistribution(groupId, sender) {
|
|
86
|
-
const db = await this.getConnection();
|
|
87
|
-
const target = toSignalAddressParts(sender);
|
|
88
|
-
const row = db.get(`SELECT group_id, sender_user, sender_server, sender_device, key_id, timestamp_ms
|
|
89
|
-
FROM sender_key_distribution
|
|
90
|
-
WHERE session_id = ?
|
|
91
|
-
AND group_id = ?
|
|
92
|
-
AND sender_user = ?
|
|
93
|
-
AND sender_server = ?
|
|
94
|
-
AND sender_device = ?`, [this.options.sessionId, groupId, target.user, target.server, target.device]);
|
|
95
|
-
return row ? decodeSenderKeyDistributionRow(row) : null;
|
|
96
|
-
}
|
|
97
85
|
async getDeviceSenderKeyDistributions(groupId, senders) {
|
|
98
86
|
if (senders.length === 0) {
|
|
99
87
|
return [];
|
|
@@ -136,14 +124,29 @@ export class SenderKeySqliteStore extends BaseSqliteStore {
|
|
|
136
124
|
if (participants.length === 0) {
|
|
137
125
|
return 0;
|
|
138
126
|
}
|
|
139
|
-
return this.withTransaction(
|
|
140
|
-
let
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
127
|
+
return this.withTransaction((db) => {
|
|
128
|
+
let filters = '';
|
|
129
|
+
const params = [this.options.sessionId, groupId];
|
|
130
|
+
for (let index = 0; index < participants.length; index += 1) {
|
|
131
|
+
if (index > 0) {
|
|
132
|
+
filters += ' OR ';
|
|
133
|
+
}
|
|
134
|
+
filters += '(sender_user = ? AND sender_server = ? AND sender_device = ?)';
|
|
135
|
+
const sender = toSignalAddressParts(participants[index]);
|
|
136
|
+
params.push(sender.user, sender.server, sender.device);
|
|
145
137
|
}
|
|
146
|
-
|
|
138
|
+
const where = `session_id = ? AND group_id = ? AND (${filters})`;
|
|
139
|
+
db.run(`DELETE FROM sender_keys WHERE ${where}`, params);
|
|
140
|
+
const senderCountRow = db.get('SELECT changes() AS total', []);
|
|
141
|
+
const senderCount = senderCountRow
|
|
142
|
+
? asNumber(senderCountRow.total, 'sender_keys.changes')
|
|
143
|
+
: 0;
|
|
144
|
+
db.run(`DELETE FROM sender_key_distribution WHERE ${where}`, params);
|
|
145
|
+
const distributionCountRow = db.get('SELECT changes() AS total', []);
|
|
146
|
+
const distributionCount = distributionCountRow
|
|
147
|
+
? asNumber(distributionCountRow.total, 'sender_key_distribution.changes')
|
|
148
|
+
: 0;
|
|
149
|
+
return senderCount + distributionCount;
|
|
147
150
|
});
|
|
148
151
|
}
|
|
149
152
|
async clear() {
|
|
@@ -157,20 +160,12 @@ export class SenderKeySqliteStore extends BaseSqliteStore {
|
|
|
157
160
|
countDelete(db, table, target, groupId) {
|
|
158
161
|
const whereWithGroup = 'session_id = ? AND sender_user = ? AND sender_server = ? AND sender_device = ? AND group_id = ?';
|
|
159
162
|
const whereAllGroups = 'session_id = ? AND sender_user = ? AND sender_server = ? AND sender_device = ?';
|
|
160
|
-
const countRow = db.get(`SELECT COUNT(*) AS count
|
|
161
|
-
FROM ${table}
|
|
162
|
-
WHERE ${groupId ? whereWithGroup : whereAllGroups}`, groupId
|
|
163
|
-
? [this.options.sessionId, target.user, target.server, target.device, groupId]
|
|
164
|
-
: [this.options.sessionId, target.user, target.server, target.device]);
|
|
165
|
-
const count = decodeSqliteCount(countRow, `${table}.count`);
|
|
166
|
-
if (count === 0) {
|
|
167
|
-
return 0;
|
|
168
|
-
}
|
|
169
163
|
db.run(`DELETE FROM ${table}
|
|
170
164
|
WHERE ${groupId ? whereWithGroup : whereAllGroups}`, groupId
|
|
171
165
|
? [this.options.sessionId, target.user, target.server, target.device, groupId]
|
|
172
166
|
: [this.options.sessionId, target.user, target.server, target.device]);
|
|
173
|
-
|
|
167
|
+
const row = db.get('SELECT changes() AS total', []);
|
|
168
|
+
return row ? asNumber(row.total, `${table}.changes`) : 0;
|
|
174
169
|
}
|
|
175
170
|
upsertSenderKeyDistributionRow(db, record, sender) {
|
|
176
171
|
db.run(`INSERT INTO sender_key_distribution (
|