zapo-js 1.6.2 → 1.7.1

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.
Files changed (218) hide show
  1. package/README.md +26 -12
  2. package/dist/abprops-spec.d.ts +10 -0
  3. package/dist/abprops-spec.js +25 -0
  4. package/dist/appstate/crypto/WaAppStateCrypto.js +4 -6
  5. package/dist/auth/WaAuthClient.d.ts +14 -1
  6. package/dist/auth/WaAuthClient.js +22 -1
  7. package/dist/auth/credentials-flow.d.ts +3 -1
  8. package/dist/auth/credentials-flow.js +3 -0
  9. package/dist/auth/pairing/WaPairingFlow.d.ts +5 -0
  10. package/dist/auth/pairing/WaPairingFlow.js +66 -14
  11. package/dist/auth/types.d.ts +13 -0
  12. package/dist/client/WaClient.d.ts +11 -0
  13. package/dist/client/WaClient.js +60 -0
  14. package/dist/client/WaClientFactory.d.ts +2 -2
  15. package/dist/client/WaClientFactory.js +53 -13
  16. package/dist/client/coordinators/WaAbPropsCoordinator.d.ts +2 -2
  17. package/dist/client/coordinators/WaAbPropsCoordinator.js +16 -4
  18. package/dist/client/coordinators/WaIncomingNodeCoordinator.d.ts +2 -1
  19. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +4 -0
  20. package/dist/client/coordinators/WaMessageCoordinator.d.ts +96 -0
  21. package/dist/client/coordinators/WaMessageCoordinator.js +163 -8
  22. package/dist/client/coordinators/WaMessageDispatchCoordinator.d.ts +64 -0
  23. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +252 -57
  24. package/dist/client/coordinators/WaPrivacyCoordinator.d.ts +97 -19
  25. package/dist/client/coordinators/WaPrivacyCoordinator.js +152 -101
  26. package/dist/client/coordinators/WaRetryCoordinator.d.ts +22 -0
  27. package/dist/client/coordinators/WaRetryCoordinator.js +74 -11
  28. package/dist/client/events/dirty.d.ts +3 -0
  29. package/dist/client/events/dirty.js +12 -7
  30. package/dist/client/events/offline.d.ts +9 -0
  31. package/dist/client/events/offline.js +95 -0
  32. package/dist/client/events/privacy.d.ts +45 -0
  33. package/dist/client/events/privacy.js +130 -0
  34. package/dist/client/messaging/group-metadata.d.ts +12 -0
  35. package/dist/client/messaging/group-metadata.js +24 -8
  36. package/dist/client/messaging/link-preview.d.ts +7 -0
  37. package/dist/client/messaging/link-preview.js +27 -0
  38. package/dist/client/messaging/messages.js +16 -12
  39. package/dist/client/newsletter/content.d.ts +4 -1
  40. package/dist/client/newsletter/content.js +43 -18
  41. package/dist/client/newsletter/discovery.js +4 -2
  42. package/dist/client/newsletter/messaging.d.ts +2 -0
  43. package/dist/client/newsletter/messaging.js +2 -1
  44. package/dist/client/newsletter/mex.d.ts +2 -2
  45. package/dist/client/persistence/WriteBehindPersistence.js +2 -1
  46. package/dist/client/persistence/ephemeral-setting.d.ts +42 -0
  47. package/dist/client/persistence/ephemeral-setting.js +120 -0
  48. package/dist/client/persistence/group-history.d.ts +29 -0
  49. package/dist/client/persistence/group-history.js +149 -0
  50. package/dist/client/persistence/history-blob.d.ts +25 -0
  51. package/dist/client/persistence/history-blob.js +38 -0
  52. package/dist/client/persistence/history-sync.d.ts +20 -0
  53. package/dist/client/persistence/history-sync.js +165 -71
  54. package/dist/client/plugins/types.d.ts +10 -2
  55. package/dist/client/types.d.ts +150 -16
  56. package/dist/crypto/core/index.d.ts +1 -1
  57. package/dist/crypto/core/index.js +2 -1
  58. package/dist/crypto/core/primitives.d.ts +19 -0
  59. package/dist/crypto/core/primitives.js +48 -0
  60. package/dist/crypto/core/xeddsa.js +35 -4
  61. package/dist/crypto/curves/X25519.js +29 -2
  62. package/dist/crypto/nativeBackend.d.ts +20 -0
  63. package/dist/crypto/nativeBackend.js +95 -0
  64. package/dist/esm/abprops-spec.js +15 -0
  65. package/dist/esm/appstate/crypto/WaAppStateCrypto.js +4 -6
  66. package/dist/esm/auth/WaAuthClient.js +22 -1
  67. package/dist/esm/auth/credentials-flow.js +3 -0
  68. package/dist/esm/auth/pairing/WaPairingFlow.js +67 -15
  69. package/dist/esm/client/WaClient.js +60 -0
  70. package/dist/esm/client/WaClientFactory.js +54 -14
  71. package/dist/esm/client/coordinators/WaAbPropsCoordinator.js +17 -5
  72. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +4 -0
  73. package/dist/esm/client/coordinators/WaMessageCoordinator.js +166 -11
  74. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +254 -60
  75. package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +145 -94
  76. package/dist/esm/client/coordinators/WaRetryCoordinator.js +74 -11
  77. package/dist/esm/client/events/dirty.js +12 -7
  78. package/dist/esm/client/events/offline.js +92 -0
  79. package/dist/esm/client/events/privacy.js +123 -0
  80. package/dist/esm/client/messaging/group-metadata.js +25 -9
  81. package/dist/esm/client/messaging/link-preview.js +29 -2
  82. package/dist/esm/client/messaging/messages.js +16 -12
  83. package/dist/esm/client/newsletter/content.js +44 -19
  84. package/dist/esm/client/newsletter/discovery.js +4 -2
  85. package/dist/esm/client/newsletter/messaging.js +2 -1
  86. package/dist/esm/client/persistence/WriteBehindPersistence.js +2 -1
  87. package/dist/esm/client/persistence/ephemeral-setting.js +116 -0
  88. package/dist/esm/client/persistence/group-history.js +145 -0
  89. package/dist/esm/client/persistence/history-blob.js +34 -0
  90. package/dist/esm/client/persistence/history-sync.js +157 -65
  91. package/dist/esm/crypto/core/index.js +1 -1
  92. package/dist/esm/crypto/core/primitives.js +47 -0
  93. package/dist/esm/crypto/core/xeddsa.js +36 -5
  94. package/dist/esm/crypto/curves/X25519.js +29 -2
  95. package/dist/esm/crypto/nativeBackend.js +93 -0
  96. package/dist/esm/index.js +3 -1
  97. package/dist/esm/media/crypto/WaMediaCrypto.js +38 -19
  98. package/dist/esm/message/context-info.js +39 -0
  99. package/dist/esm/message/crypto/reporting-token.js +38 -216
  100. package/dist/esm/message/encode/content.js +73 -12
  101. package/dist/esm/message/encode/media-payload.js +3 -1
  102. package/dist/esm/message/kinds/group-history.js +36 -0
  103. package/dist/esm/message/primitives/incoming.js +32 -13
  104. package/dist/esm/protocol/abprops.js +18 -162
  105. package/dist/esm/protocol/constants.js +4 -3
  106. package/dist/esm/protocol/defaults.js +7 -0
  107. package/dist/esm/protocol/device-identity.js +10 -5
  108. package/dist/esm/protocol/jid.js +83 -36
  109. package/dist/esm/protocol/media.js +1 -0
  110. package/dist/esm/protocol/message.js +8 -0
  111. package/dist/esm/protocol/notification.js +1 -0
  112. package/dist/esm/protocol/privacy.js +70 -4
  113. package/dist/esm/signal/group/SenderKeyChain.js +1 -2
  114. package/dist/esm/signal/group/SenderKeyManager.js +1 -7
  115. package/dist/esm/signal/session/SignalProtocol.js +22 -21
  116. package/dist/esm/signal/session/SignalRatchet.js +20 -17
  117. package/dist/esm/signal/session/encoding.js +25 -3
  118. package/dist/esm/signal/session/resolver.js +11 -5
  119. package/dist/esm/store/contracts/chat-metadata.store.js +1 -0
  120. package/dist/esm/store/createStore.js +19 -2
  121. package/dist/esm/store/index.js +1 -0
  122. package/dist/esm/store/memory/chat-metadata.store.js +66 -0
  123. package/dist/esm/store/noop.store.js +8 -0
  124. package/dist/esm/transport/binary/constants.js +19 -0
  125. package/dist/esm/transport/binary/decoder.js +17 -19
  126. package/dist/esm/transport/binary/encoder.js +61 -18
  127. package/dist/esm/transport/node/builders/global.js +20 -0
  128. package/dist/esm/transport/node/builders/message.js +32 -15
  129. package/dist/esm/transport/node/builders/privacy.js +63 -4
  130. package/dist/esm/transport/noise/WaClientPayload.js +43 -22
  131. package/dist/esm/transport/noise/WaFrameCodec.js +14 -4
  132. package/dist/esm/util/coercion.js +12 -4
  133. package/dist/esm/util/index.js +1 -1
  134. package/dist/esm/util/protoscan.js +181 -0
  135. package/dist/esm/util/runtime.js +34 -0
  136. package/dist/index.d.ts +11 -6
  137. package/dist/index.js +15 -2
  138. package/dist/media/crypto/WaMediaCrypto.js +36 -17
  139. package/dist/media/types.d.ts +1 -1
  140. package/dist/message/context-info.d.ts +10 -0
  141. package/dist/message/context-info.js +40 -0
  142. package/dist/message/crypto/reporting-token.d.ts +3 -1
  143. package/dist/message/crypto/reporting-token.js +38 -216
  144. package/dist/message/encode/content.d.ts +24 -4
  145. package/dist/message/encode/content.js +74 -12
  146. package/dist/message/encode/media-payload.d.ts +5 -2
  147. package/dist/message/encode/media-payload.js +3 -1
  148. package/dist/message/kinds/group-history.d.ts +30 -0
  149. package/dist/message/kinds/group-history.js +40 -0
  150. package/dist/message/primitives/incoming.d.ts +5 -0
  151. package/dist/message/primitives/incoming.js +32 -13
  152. package/dist/message/types.d.ts +10 -0
  153. package/dist/protocol/abprops.d.ts +27 -140
  154. package/dist/protocol/abprops.js +18 -163
  155. package/dist/protocol/constants.d.ts +4 -3
  156. package/dist/protocol/constants.js +10 -3
  157. package/dist/protocol/defaults.d.ts +7 -0
  158. package/dist/protocol/defaults.js +7 -0
  159. package/dist/protocol/device-identity.d.ts +14 -4
  160. package/dist/protocol/device-identity.js +9 -4
  161. package/dist/protocol/jid.d.ts +4 -1
  162. package/dist/protocol/jid.js +83 -36
  163. package/dist/protocol/media.d.ts +1 -0
  164. package/dist/protocol/media.js +1 -0
  165. package/dist/protocol/message.d.ts +6 -0
  166. package/dist/protocol/message.js +9 -0
  167. package/dist/protocol/notification.d.ts +1 -0
  168. package/dist/protocol/notification.js +1 -0
  169. package/dist/protocol/privacy.d.ts +52 -0
  170. package/dist/protocol/privacy.js +71 -5
  171. package/dist/signal/group/SenderKeyChain.d.ts +1 -1
  172. package/dist/signal/group/SenderKeyChain.js +1 -2
  173. package/dist/signal/group/SenderKeyManager.js +1 -7
  174. package/dist/signal/session/SignalProtocol.d.ts +13 -0
  175. package/dist/signal/session/SignalProtocol.js +22 -21
  176. package/dist/signal/session/SignalRatchet.d.ts +4 -4
  177. package/dist/signal/session/SignalRatchet.js +19 -16
  178. package/dist/signal/session/SignalSession.d.ts +8 -1
  179. package/dist/signal/session/encoding.d.ts +5 -0
  180. package/dist/signal/session/encoding.js +25 -3
  181. package/dist/signal/session/resolver.js +11 -5
  182. package/dist/store/contracts/chat-metadata.store.d.ts +34 -0
  183. package/dist/store/contracts/chat-metadata.store.js +2 -0
  184. package/dist/store/contracts/group-metadata.store.d.ts +7 -0
  185. package/dist/store/contracts/thread.store.d.ts +6 -0
  186. package/dist/store/createStore.d.ts +10 -2
  187. package/dist/store/createStore.js +18 -1
  188. package/dist/store/index.d.ts +3 -1
  189. package/dist/store/index.js +3 -1
  190. package/dist/store/memory/chat-metadata.store.d.ts +26 -0
  191. package/dist/store/memory/chat-metadata.store.js +70 -0
  192. package/dist/store/noop.store.d.ts +2 -0
  193. package/dist/store/noop.store.js +9 -1
  194. package/dist/store/types.d.ts +190 -39
  195. package/dist/transport/binary/constants.d.ts +8 -0
  196. package/dist/transport/binary/constants.js +20 -1
  197. package/dist/transport/binary/decoder.js +17 -19
  198. package/dist/transport/binary/encoder.js +60 -17
  199. package/dist/transport/node/builders/global.d.ts +8 -0
  200. package/dist/transport/node/builders/global.js +21 -0
  201. package/dist/transport/node/builders/message.js +32 -15
  202. package/dist/transport/node/builders/privacy.d.ts +26 -2
  203. package/dist/transport/node/builders/privacy.js +63 -3
  204. package/dist/transport/noise/WaClientPayload.js +43 -22
  205. package/dist/transport/noise/WaFrameCodec.d.ts +1 -0
  206. package/dist/transport/noise/WaFrameCodec.js +14 -4
  207. package/dist/transport/noise/types.d.ts +17 -0
  208. package/dist/util/coercion.d.ts +6 -0
  209. package/dist/util/coercion.js +13 -4
  210. package/dist/util/index.d.ts +1 -1
  211. package/dist/util/index.js +2 -1
  212. package/dist/util/protoscan.d.ts +33 -0
  213. package/dist/util/protoscan.js +186 -0
  214. package/dist/util/runtime.d.ts +12 -0
  215. package/dist/util/runtime.js +35 -0
  216. package/package.json +3 -1
  217. package/spec/abprops/index.d.ts +4402 -0
  218. package/spec/abprops/index.js +4372 -0
@@ -1,13 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.scanHistorySyncBlob = scanHistorySyncBlob;
4
+ exports.scanConversationJidPair = scanConversationJidPair;
3
5
  exports.runHistorySyncNotification = runHistorySyncNotification;
4
6
  exports.processHistorySyncNotification = processHistorySyncNotification;
5
7
  const node_util_1 = require("node:util");
6
8
  const node_zlib_1 = require("node:zlib");
9
+ const history_blob_1 = require("../persistence/history-blob");
7
10
  const _proto_1 = require("../../proto");
8
11
  const jid_1 = require("../../protocol/jid");
12
+ const message_1 = require("../../protocol/message");
9
13
  const bytes_1 = require("../../util/bytes");
10
14
  const primitives_1 = require("../../util/primitives");
15
+ const protoscan_1 = require("../../util/protoscan");
11
16
  const unzipAsync = (0, node_util_1.promisify)(node_zlib_1.unzip);
12
17
  const HANDLED_SYNC_TYPES = new Set([
13
18
  _proto_1.proto.Message.HistorySyncType.INITIAL_BOOTSTRAP,
@@ -18,6 +23,90 @@ const HANDLED_SYNC_TYPES = new Set([
18
23
  _proto_1.proto.Message.HistorySyncType.NON_BLOCKING_DATA
19
24
  ]);
20
25
  const HISTORY_SYNC_MAX_PENDING_WRITES = 1024;
26
+ const HISTORY_SYNC_FIELDS = Object.freeze({
27
+ CONVERSATIONS: 2,
28
+ CHUNK_ORDER: 5,
29
+ PROGRESS: 6,
30
+ PUSHNAMES: 7,
31
+ PHONE_NUMBER_TO_LID_MAPPINGS: 15,
32
+ NCT_SALT: 19,
33
+ INLINE_CONTACTS: 20
34
+ });
35
+ const CONVERSATION_JID_FIELDS = Object.freeze({
36
+ PN_JID: 39,
37
+ LID_JID: 42,
38
+ ACCOUNT_LID: 49
39
+ });
40
+ function scanHistorySyncBlob(bytes) {
41
+ const conversationRanges = [];
42
+ const pushnames = [];
43
+ const inlineContacts = [];
44
+ const phoneNumberToLidMappings = [];
45
+ let nctSalt = null;
46
+ let chunkOrder = null;
47
+ let progress = null;
48
+ (0, protoscan_1.scanProtoFields)(bytes, 0, bytes.length, (field) => {
49
+ if (field.wireType === protoscan_1.PROTO_WIRE_TYPES.LEN) {
50
+ if (field.fieldNumber === HISTORY_SYNC_FIELDS.CONVERSATIONS) {
51
+ conversationRanges[conversationRanges.length] = {
52
+ start: field.valueStart,
53
+ end: field.valueEnd
54
+ };
55
+ }
56
+ else if (field.fieldNumber === HISTORY_SYNC_FIELDS.PUSHNAMES) {
57
+ pushnames[pushnames.length] = _proto_1.proto.Pushname.decode(bytes.subarray(field.valueStart, field.valueEnd));
58
+ }
59
+ else if (field.fieldNumber === HISTORY_SYNC_FIELDS.PHONE_NUMBER_TO_LID_MAPPINGS) {
60
+ phoneNumberToLidMappings[phoneNumberToLidMappings.length] =
61
+ _proto_1.proto.PhoneNumberToLIDMapping.decode(bytes.subarray(field.valueStart, field.valueEnd));
62
+ }
63
+ else if (field.fieldNumber === HISTORY_SYNC_FIELDS.INLINE_CONTACTS) {
64
+ inlineContacts[inlineContacts.length] = _proto_1.proto.InlineContact.decode(bytes.subarray(field.valueStart, field.valueEnd));
65
+ }
66
+ else if (field.fieldNumber === HISTORY_SYNC_FIELDS.NCT_SALT) {
67
+ nctSalt = bytes.slice(field.valueStart, field.valueEnd);
68
+ }
69
+ return;
70
+ }
71
+ if (field.wireType === protoscan_1.PROTO_WIRE_TYPES.VARINT) {
72
+ if (field.fieldNumber === HISTORY_SYNC_FIELDS.CHUNK_ORDER) {
73
+ chunkOrder = field.varintValue;
74
+ }
75
+ else if (field.fieldNumber === HISTORY_SYNC_FIELDS.PROGRESS) {
76
+ progress = field.varintValue;
77
+ }
78
+ }
79
+ });
80
+ return {
81
+ conversationRanges,
82
+ pushnames,
83
+ inlineContacts,
84
+ phoneNumberToLidMappings,
85
+ nctSalt,
86
+ chunkOrder,
87
+ progress
88
+ };
89
+ }
90
+ function scanConversationJidPair(bytes, range) {
91
+ let pnJid = null;
92
+ let lidJid = null;
93
+ let accountLid = null;
94
+ (0, protoscan_1.scanProtoFields)(bytes, range.start, range.end, (field) => {
95
+ if (field.wireType !== protoscan_1.PROTO_WIRE_TYPES.LEN) {
96
+ return;
97
+ }
98
+ if (field.fieldNumber === CONVERSATION_JID_FIELDS.PN_JID) {
99
+ pnJid = bytes_1.TEXT_DECODER.decode(bytes.subarray(field.valueStart, field.valueEnd));
100
+ }
101
+ else if (field.fieldNumber === CONVERSATION_JID_FIELDS.LID_JID) {
102
+ lidJid = bytes_1.TEXT_DECODER.decode(bytes.subarray(field.valueStart, field.valueEnd));
103
+ }
104
+ else if (field.fieldNumber === CONVERSATION_JID_FIELDS.ACCOUNT_LID) {
105
+ accountLid = bytes_1.TEXT_DECODER.decode(bytes.subarray(field.valueStart, field.valueEnd));
106
+ }
107
+ });
108
+ return { pnJid, lidJid: lidJid ?? accountLid };
109
+ }
21
110
  async function runHistorySyncNotification(deps, notification) {
22
111
  try {
23
112
  await processHistorySyncNotification(deps, notification);
@@ -47,14 +136,17 @@ async function processHistorySyncNotification(deps, notification) {
47
136
  }
48
137
  const blob = await downloadHistorySyncBlob(deps, notification);
49
138
  const decompressed = (0, bytes_1.toBytesView)(await unzipAsync(blob));
50
- const historySync = _proto_1.proto.HistorySync.decode(decompressed);
139
+ // Conversations are decoded one record at a time in the loop below so the
140
+ // full message graph never coexists in memory; the scan only records their
141
+ // byte ranges and decodes the small metadata fields.
142
+ const scan = scanHistorySyncBlob(decompressed);
51
143
  deps.logger.info('decoded history sync chunk', {
52
144
  syncType,
53
- chunkOrder: historySync.chunkOrder,
54
- progress: historySync.progress,
55
- conversations: historySync.conversations.length,
56
- pushnames: historySync.pushnames.length,
57
- inlineContacts: historySync.inlineContacts?.length ?? 0
145
+ chunkOrder: scan.chunkOrder,
146
+ progress: scan.progress,
147
+ conversations: scan.conversationRanges.length,
148
+ pushnames: scan.pushnames.length,
149
+ inlineContacts: scan.inlineContacts.length
58
150
  });
59
151
  const nowMs = Date.now();
60
152
  const pendingWrites = [];
@@ -63,24 +155,23 @@ async function processHistorySyncNotification(deps, notification) {
63
155
  // pushnames and mappings land on a single canonical (LID-form) contact
64
156
  // row instead of two mirror rows (one keyed by PN, one keyed by LID).
65
157
  const pnToLid = new Map();
66
- for (const map of historySync.phoneNumberToLidMappings ?? []) {
158
+ for (const map of scan.phoneNumberToLidMappings) {
67
159
  if (map.pnJid && map.lidJid) {
68
160
  pnToLid.set(map.pnJid, map.lidJid);
69
161
  }
70
162
  }
71
- for (const c of historySync.inlineContacts ?? []) {
163
+ for (const c of scan.inlineContacts) {
72
164
  if (c.pnJid && c.lidJid) {
73
165
  pnToLid.set(c.pnJid, c.lidJid);
74
166
  }
75
167
  }
76
- for (const conversation of historySync.conversations) {
77
- const pnJid = conversation.pnJid;
78
- const lidJid = conversation.lidJid ?? conversation.accountLid;
79
- if (pnJid && lidJid) {
80
- pnToLid.set(pnJid, lidJid);
168
+ for (const range of scan.conversationRanges) {
169
+ const pair = scanConversationJidPair(decompressed, range);
170
+ if (pair.pnJid && pair.lidJid) {
171
+ pnToLid.set(pair.pnJid, pair.lidJid);
81
172
  }
82
173
  }
83
- for (const pn of historySync.pushnames) {
174
+ for (const pn of scan.pushnames) {
84
175
  if (!pn.id) {
85
176
  continue;
86
177
  }
@@ -98,10 +189,10 @@ async function processHistorySyncNotification(deps, notification) {
98
189
  lastUpdatedMs: nowMs
99
190
  });
100
191
  if (pendingWrites.length >= HISTORY_SYNC_MAX_PENDING_WRITES) {
101
- await flushPendingWrites(pendingWrites);
192
+ await (0, history_blob_1.flushPendingWrites)(pendingWrites);
102
193
  }
103
194
  }
104
- for (const c of historySync.inlineContacts ?? []) {
195
+ for (const c of scan.inlineContacts) {
105
196
  const jid = c.lidJid ?? c.pnJid;
106
197
  if (!jid) {
107
198
  continue;
@@ -117,16 +208,55 @@ async function processHistorySyncNotification(deps, notification) {
117
208
  lastUpdatedMs: nowMs
118
209
  });
119
210
  if (pendingWrites.length >= HISTORY_SYNC_MAX_PENDING_WRITES) {
120
- await flushPendingWrites(pendingWrites);
211
+ await (0, history_blob_1.flushPendingWrites)(pendingWrites);
121
212
  }
122
213
  }
123
214
  let messagesCount = 0;
124
- for (const conversation of historySync.conversations) {
215
+ const tokenConversations = [];
216
+ for (const range of scan.conversationRanges) {
217
+ let conversation;
218
+ try {
219
+ conversation = _proto_1.proto.Conversation.decode(decompressed.subarray(range.start, range.end));
220
+ }
221
+ catch (error) {
222
+ await Promise.allSettled(pendingWrites);
223
+ throw (0, primitives_1.toError)(error);
224
+ }
125
225
  const threadJid = conversation.id;
126
226
  if (!threadJid) {
127
227
  deps.logger.debug('skipping history sync conversation without thread jid');
128
228
  continue;
129
229
  }
230
+ if (deps.onPrivacyTokens &&
231
+ (conversation.tcToken ||
232
+ conversation.tcTokenTimestamp ||
233
+ conversation.tcTokenSenderTimestamp)) {
234
+ tokenConversations[tokenConversations.length] = {
235
+ jid: threadJid,
236
+ tcToken: conversation.tcToken ? new Uint8Array(conversation.tcToken) : undefined,
237
+ tcTokenTimestamp: (0, primitives_1.longToNumber)(conversation.tcTokenTimestamp) || undefined,
238
+ tcTokenSenderTimestamp: (0, primitives_1.longToNumber)(conversation.tcTokenSenderTimestamp) || undefined
239
+ };
240
+ }
241
+ const ephemeralExpiration = conversation.ephemeralExpiration ?? undefined;
242
+ const ephemeralSettingTimestamp = (0, message_1.normalizeEphemeralSettingSeconds)((0, primitives_1.longToNumber)(conversation.ephemeralSettingTimestamp)) || undefined;
243
+ if (deps.chatMetadataStore && ephemeralExpiration !== undefined) {
244
+ pendingWrites[pendingWrites.length] = deps.chatMetadataStore
245
+ .upsertChatMetadata({
246
+ chatJid: threadJid,
247
+ ephemeralExpiration,
248
+ ...(ephemeralSettingTimestamp !== undefined
249
+ ? { ephemeralSettingTimestamp }
250
+ : {}),
251
+ updatedAtMs: nowMs
252
+ })
253
+ .catch((error) => {
254
+ deps.logger.debug('failed to cache history sync chat metadata', {
255
+ jid: threadJid,
256
+ message: (0, primitives_1.toError)(error).message
257
+ });
258
+ });
259
+ }
130
260
  pendingWrites[pendingWrites.length] = deps.writeBehind.persistThreadAsync({
131
261
  jid: threadJid,
132
262
  name: conversation.name ?? undefined,
@@ -135,10 +265,11 @@ async function processHistorySyncNotification(deps, notification) {
135
265
  pinned: conversation.pinned ?? undefined,
136
266
  muteEndMs: (0, primitives_1.longToNumber)(conversation.muteEndTime) || undefined,
137
267
  markedAsUnread: conversation.markedAsUnread ?? undefined,
138
- ephemeralExpiration: conversation.ephemeralExpiration ?? undefined
268
+ ephemeralExpiration,
269
+ ephemeralSettingTimestamp
139
270
  });
140
271
  if (pendingWrites.length >= HISTORY_SYNC_MAX_PENDING_WRITES) {
141
- await flushPendingWrites(pendingWrites);
272
+ await (0, history_blob_1.flushPendingWrites)(pendingWrites);
142
273
  }
143
274
  if ((0, jid_1.isUserJid)(threadJid) || (conversation.lidJid ?? conversation.accountLid)) {
144
275
  const contactDisplay = conversation.displayName || conversation.username || undefined;
@@ -153,7 +284,7 @@ async function processHistorySyncNotification(deps, notification) {
153
284
  lastUpdatedMs: nowMs
154
285
  });
155
286
  if (pendingWrites.length >= HISTORY_SYNC_MAX_PENDING_WRITES) {
156
- await flushPendingWrites(pendingWrites);
287
+ await (0, history_blob_1.flushPendingWrites)(pendingWrites);
157
288
  }
158
289
  }
159
290
  }
@@ -176,7 +307,7 @@ async function processHistorySyncNotification(deps, notification) {
176
307
  messageBytes: _proto_1.proto.Message.encode(webMsg.message).finish()
177
308
  });
178
309
  if (pendingWrites.length >= HISTORY_SYNC_MAX_PENDING_WRITES) {
179
- await flushPendingWrites(pendingWrites);
310
+ await (0, history_blob_1.flushPendingWrites)(pendingWrites);
180
311
  }
181
312
  messagesCount += 1;
182
313
  }
@@ -191,70 +322,33 @@ async function processHistorySyncNotification(deps, notification) {
191
322
  lastUpdatedMs: nowMs
192
323
  });
193
324
  if (pendingWrites.length >= HISTORY_SYNC_MAX_PENDING_WRITES) {
194
- await flushPendingWrites(pendingWrites);
325
+ await (0, history_blob_1.flushPendingWrites)(pendingWrites);
195
326
  }
196
327
  }
197
- if (deps.onPrivacyTokens) {
198
- const tokenConversations = [];
199
- for (const conversation of historySync.conversations) {
200
- if (!conversation.id)
201
- continue;
202
- if (conversation.tcToken ||
203
- conversation.tcTokenTimestamp ||
204
- conversation.tcTokenSenderTimestamp) {
205
- tokenConversations[tokenConversations.length] = {
206
- jid: conversation.id,
207
- tcToken: conversation.tcToken,
208
- tcTokenTimestamp: (0, primitives_1.longToNumber)(conversation.tcTokenTimestamp) || undefined,
209
- tcTokenSenderTimestamp: (0, primitives_1.longToNumber)(conversation.tcTokenSenderTimestamp) || undefined
210
- };
211
- }
212
- }
213
- if (tokenConversations.length > 0) {
214
- pendingWrites[pendingWrites.length] = deps.onPrivacyTokens(tokenConversations);
215
- }
328
+ if (deps.onPrivacyTokens && tokenConversations.length > 0) {
329
+ pendingWrites[pendingWrites.length] = deps.onPrivacyTokens(tokenConversations);
216
330
  }
217
- if (deps.onNctSalt && historySync.nctSalt) {
218
- pendingWrites[pendingWrites.length] = deps.onNctSalt(historySync.nctSalt);
331
+ if (deps.onNctSalt && scan.nctSalt) {
332
+ pendingWrites[pendingWrites.length] = deps.onNctSalt(scan.nctSalt);
219
333
  }
220
334
  const event = {
221
335
  syncType,
222
336
  messagesCount,
223
- conversationsCount: historySync.conversations.length,
224
- pushnamesCount: historySync.pushnames.length,
225
- inlineContactsCount: historySync.inlineContacts?.length ?? 0,
226
- chunkOrder: historySync.chunkOrder ?? undefined,
227
- progress: historySync.progress ?? undefined
337
+ conversationsCount: scan.conversationRanges.length,
338
+ pushnamesCount: scan.pushnames.length,
339
+ inlineContactsCount: scan.inlineContacts.length,
340
+ chunkOrder: scan.chunkOrder ?? undefined,
341
+ progress: scan.progress ?? undefined
228
342
  };
229
- await flushPendingWrites(pendingWrites);
343
+ await (0, history_blob_1.flushPendingWrites)(pendingWrites);
230
344
  deps.emitEvent('history_sync_chunk', event);
231
345
  if (deps.onProcessed) {
232
346
  await deps.onProcessed(syncType);
233
347
  }
234
348
  }
235
- async function flushPendingWrites(pendingWrites) {
236
- if (pendingWrites.length === 0) {
237
- return;
238
- }
239
- const settled = Promise.all(pendingWrites);
240
- pendingWrites.length = 0;
241
- await settled;
242
- }
243
349
  async function downloadHistorySyncBlob(deps, notification) {
244
350
  if (notification.initialHistBootstrapInlinePayload) {
245
351
  return (0, bytes_1.decodeProtoBytes)(notification.initialHistBootstrapInlinePayload, 'initialHistBootstrapInlinePayload');
246
352
  }
247
- if (!notification.directPath) {
248
- throw new Error('history sync notification missing directPath');
249
- }
250
- const mediaKey = (0, bytes_1.decodeProtoBytes)(notification.mediaKey, 'history sync mediaKey');
251
- const fileSha256 = (0, bytes_1.decodeProtoBytes)(notification.fileSha256, 'history sync fileSha256');
252
- const fileEncSha256 = (0, bytes_1.decodeProtoBytes)(notification.fileEncSha256, 'history sync fileEncSha256');
253
- return deps.mediaTransfer.downloadAndDecrypt({
254
- directPath: notification.directPath,
255
- mediaType: 'history',
256
- mediaKey,
257
- fileSha256,
258
- fileEncSha256
259
- });
353
+ return (0, history_blob_1.downloadHistoryBlob)(deps.mediaTransfer, notification, 'history', 'history sync');
260
354
  }
@@ -63,10 +63,18 @@ type ExposedOf<P> = P extends {
63
63
  * `{ readonly voip: WaVoipCoordinator }`.
64
64
  */
65
65
  export type WaClientExposedFromPlugins<P extends readonly unknown[]> = UnionToIntersection<ExposedOf<P[number]>>;
66
- /** Event map a plugin contributes, carried as a phantom marker on its definition. */
66
+ /**
67
+ * Event map a plugin contributes, carried as a phantom marker on its definition.
68
+ *
69
+ * The marker is optional (it never exists at runtime), so under
70
+ * `exactOptionalPropertyTypes` the inferred `E` keeps the `| undefined` the
71
+ * declaration emits. `Exclude` drops it before the union reaches
72
+ * {@link UnionToIntersection}, which would otherwise collapse
73
+ * `Events | undefined` to `never` and type every client listener as `never`.
74
+ */
67
75
  type EventsOf<P> = P extends {
68
76
  readonly __pluginEvents?: infer E;
69
- } ? unknown extends E ? {} : E : {};
77
+ } ? unknown extends E ? {} : Exclude<E, undefined> : {};
70
78
  /**
71
79
  * Client events contributed by a tuple of plugin definitions, derived from the
72
80
  * plugin values (no global augmentation). Threaded into the client's
@@ -2,8 +2,10 @@ import type { AppStateCollectionName } from '../appstate/types';
2
2
  import type { DataForKey, WaAppstateActionKey, WaAppstateIndexArgs } from '../appstate-spec';
3
3
  import type { WaShortcakeAssertionSigner } from '../auth/pairing/WaShortcakeFlow';
4
4
  import type { WaAuthClientOptions, WaAuthCredentials, WaAuthDangerousOptions, WaAuthSocketOptions } from '../auth/types';
5
+ import type { WaPrivacyAccountSyncResult } from './coordinators/WaPrivacyCoordinator';
5
6
  import type { WaCallGroupParticipant, WaCallType } from './events/call';
6
7
  import type { IncomingPresenceType, PresenceLastSeen } from './events/presence';
8
+ import type { WaBlocklistResult } from './events/privacy';
7
9
  import type { CompanionHostPersistence } from './persistence/companion-host';
8
10
  import type { WaClientPluginDefinition } from './plugins/types';
9
11
  import type { WaMediaProcessor } from '../media/processor';
@@ -148,7 +150,9 @@ export interface WaClientOptions extends WaAuthClientOptions, WaAuthSocketOption
148
150
  * on-demand backfill triggered by `message.requestHistorySync`) are
149
151
  * downloaded and emitted as `history_sync_chunk` events. Set
150
152
  * `enabled: false` to drop them; `requireFullSync: true` asks the
151
- * primary device for a full history download instead of just recent.
153
+ * primary device for a full history download instead of just recent;
154
+ * `groupBundles: true` opts into the group-history bundle a member may
155
+ * share after somebody joins a group.
152
156
  */
153
157
  readonly history?: WaHistorySyncOptions;
154
158
  /**
@@ -315,6 +319,14 @@ export interface WaHistorySyncOptions {
315
319
  */
316
320
  readonly enabled?: boolean;
317
321
  readonly requireFullSync?: boolean;
322
+ /**
323
+ * Whether to download and process the group-history bundle a member may
324
+ * share after somebody joins a group, emitting `group_history_bundle`.
325
+ * **Off by default** - a bundle is media a third party pushes at this
326
+ * account unprompted, so fetching it is opt-in. Bundles addressed to
327
+ * other members are dropped either way.
328
+ */
329
+ readonly groupBundles?: boolean;
318
330
  }
319
331
  export interface WaSignalMessagePublishInput {
320
332
  readonly to: string;
@@ -375,9 +387,23 @@ export interface WaSendMessageOptions extends WaMessagePublishOptions {
375
387
  */
376
388
  readonly expirationSeconds?: number;
377
389
  /**
378
- * Skip the automatic `ephemeralSettingTimestamp`/`expiration` injection
379
- * applied to messages sent into groups with disappearing-mode on (the cached
380
- * group ephemeral is otherwise fetched and applied for you). Off by default.
390
+ * Unix seconds when disappearing-mode was enabled, sent as
391
+ * `contextInfo.ephemeralSettingTimestamp`. 1:1 only – groups never carry it.
392
+ * Overrides the value the auto-inject resolves from the thread store; omit
393
+ * it unless you have a reason, since a missing timestamp makes the peer warn
394
+ * that the message will not disappear.
395
+ */
396
+ readonly ephemeralSettingTimestamp?: number;
397
+ /**
398
+ * Overrides `contextInfo.disappearingMode.trigger`. The 1:1 auto-inject
399
+ * already sets `CHAT_SETTING`.
400
+ */
401
+ readonly disappearingModeTrigger?: Proto.DisappearingMode.Trigger;
402
+ /**
403
+ * Skip the automatic disappearing-message injection on **group** sends, which
404
+ * would otherwise stamp `contextInfo.expiration` and `disappearingMode` from
405
+ * the group metadata cache. Has no effect on 1:1 – see
406
+ * {@link disableDirectEphemeralAutoInject}. Off by default.
381
407
  *
382
408
  * Relationship with {@link expirationSeconds}: a non-undefined
383
409
  * `expirationSeconds` already short-circuits the auto-inject, so this flag is
@@ -385,6 +411,17 @@ export interface WaSendMessageOptions extends WaMessagePublishOptions {
385
411
  * auto-inject AND not set any expiration yourself.
386
412
  */
387
413
  readonly disableGroupEphemeralAutoInject?: boolean;
414
+ /**
415
+ * Skip the automatic disappearing-message injection on **1:1** sends, which
416
+ * would otherwise stamp `contextInfo.expiration`,
417
+ * `ephemeralSettingTimestamp` and `disappearingMode` from the chat metadata
418
+ * cache. Also skips the cache lookup itself. Has no effect on groups – see
419
+ * {@link disableGroupEphemeralAutoInject}. Off by default.
420
+ *
421
+ * Same relationship with {@link expirationSeconds} as the group flag: a
422
+ * non-undefined `expirationSeconds` already short-circuits the auto-inject.
423
+ */
424
+ readonly disableDirectEphemeralAutoInject?: boolean;
388
425
  /** Raw child nodes appended to the `<message>` stanza. Escape hatch for protocol features the typed API doesn't cover. */
389
426
  readonly customNodes?: readonly BinaryNode[];
390
427
  /** Wrap the outgoing message as view-once. Only valid for image/video/audio content. */
@@ -788,19 +825,26 @@ export interface WaIncomingUnhandledStanzaEvent extends WaIncomingBaseEvent {
788
825
  readonly reason: string;
789
826
  }
790
827
  /**
791
- * Why an incoming message arrived as a content-less placeholder. `view_once`:
792
- * a view-once already consumed elsewhere. `hosted`: a hosted/bot message that
793
- * could not be fanned out. `other`: an `unavailable` marker the lib does not
794
- * categorize yet.
828
+ * Why an incoming message arrived as a content-less placeholder. `view_once`: a
829
+ * view-once already consumed elsewhere. `hosted`: a hosted account whose message
830
+ * could not be fanned out. `bot`: a bot message whose fanout never ran. `other`:
831
+ * a plain fanout placeholder – the only kind the primary device resends.
795
832
  */
796
- export type WaUnavailableMessageKind = 'view_once' | 'hosted' | 'other';
833
+ export type WaUnavailableMessageKind = 'view_once' | 'hosted' | 'bot' | 'other';
797
834
  export interface WaIncomingUnavailableMessageEvent extends Omit<WaIncomingBaseEvent, 'chatJid' | 'stanzaId'> {
798
835
  /** Which flavour of content the server signalled as unavailable. */
799
836
  readonly kind: WaUnavailableMessageKind;
837
+ /**
838
+ * `true` when a resend was queued for the primary device; the payload then
839
+ * arrives as a `message` event with the same key. Best-effort, like wa-web:
840
+ * the request is not persisted, so a failed peer message is not retried.
841
+ * `false` for the unrecoverable flavours, messages past the server age
842
+ * window, and mobile-primary sessions.
843
+ */
844
+ readonly resendRequested: boolean;
800
845
  /**
801
846
  * The message key (chat, stanza id, author, addressing metadata) – same
802
- * shape the `message` event carries, so it can be stored or correlated. There
803
- * is no decrypted `message`: the payload is unavailable and cannot be fetched.
847
+ * shape the `message` event carries, so it can be stored or correlated.
804
848
  */
805
849
  readonly key: WaIncomingMessageKey;
806
850
  /** Stanza `t` attr (seconds since epoch). */
@@ -1032,6 +1076,32 @@ export interface WaHistorySyncChunkEvent {
1032
1076
  /** Server-reported progress, 0–100. */
1033
1077
  readonly progress?: number;
1034
1078
  }
1079
+ /**
1080
+ * A group-history bundle shared with this account after it joined a group,
1081
+ * already downloaded, filtered and persisted. Emitted once per bundle, only
1082
+ * when `history.groupBundles` is enabled.
1083
+ */
1084
+ export interface WaGroupHistoryBundleEvent {
1085
+ readonly groupJid: string;
1086
+ /** Member who shared the history. */
1087
+ readonly senderJid?: string;
1088
+ /** Stanza id of the message that carried the bundle. */
1089
+ readonly bundleMessageId?: string;
1090
+ /** Messages persisted from this bundle, after filtering. */
1091
+ readonly messagesCount: number;
1092
+ /** Pinned messages older than the shared window, exempt from the age cutoff. */
1093
+ readonly outOfWindowPinsCount: number;
1094
+ /** Entries skipped as stubs, foreign-chat, ephemeral-expired or too old. */
1095
+ readonly droppedCount: number;
1096
+ /** Oldest persisted message timestamp, in ms. */
1097
+ readonly oldestTimestampMs?: number;
1098
+ /**
1099
+ * Members the sender addressed the bundle to (PN or LID form). Copied out
1100
+ * of the decoded payload, so mutating it cannot corrupt the message proto
1101
+ * the `message` event handed to the same listener.
1102
+ */
1103
+ readonly historyReceivers: readonly string[];
1104
+ }
1035
1105
  export type WaAppStateMutationSource = 'snapshot' | 'patch' | 'local';
1036
1106
  type MutationEventBase = {
1037
1107
  readonly source: WaAppStateMutationSource;
@@ -1168,11 +1238,11 @@ export interface WaClientEventMap {
1168
1238
  */
1169
1239
  readonly message_protocol: (event: WaIncomingProtocolMessageEvent) => void;
1170
1240
  /**
1171
- * A message the server delivered as a content-less placeholder: the payload
1172
- * is unavailable and cannot be recovered (a view-once already consumed, or a
1173
- * hosted/bot message that could not be fanned out). The lib acks it and emits
1174
- * this instead of a `message` event for the same stanza. Branch on
1175
- * `event.kind`.
1241
+ * A message the server delivered as a content-less placeholder. The lib acks
1242
+ * it and emits this instead of a `message` event for the same stanza. A plain
1243
+ * fanout placeholder is asked back from the primary device and arrives later
1244
+ * as a `message` event (see `event.resendRequested`); a consumed view-once or
1245
+ * a hosted/bot message that could not be fanned out is never resent.
1176
1246
  */
1177
1247
  readonly message_unavailable: (event: WaIncomingUnavailableMessageEvent) => void;
1178
1248
  /**
@@ -1205,6 +1275,28 @@ export interface WaClientEventMap {
1205
1275
  readonly business: (event: WaBusinessEvent) => void;
1206
1276
  /** Profile/group/community picture change notification – the new picture must still be fetched explicitly. */
1207
1277
  readonly picture: (event: WaPictureEvent) => void;
1278
+ /**
1279
+ * The account's privacy, refetched after the primary or another companion
1280
+ * changed it: the full category set plus any disallowed list the server
1281
+ * reported. The two halves are read by separate queries, so a change
1282
+ * landing mid-refresh can leave them describing slightly different server
1283
+ * states - the payload is exactly what
1284
+ * {@link WaPrivacyCoordinator.refreshFromAccountSync} returns.
1285
+ *
1286
+ * Two paths trigger it: the live `account_sync` notification (debounced,
1287
+ * so a burst of changes on the phone collapses into one refresh) and the
1288
+ * `account_sync` dirty bit that catches a session up after being offline.
1289
+ * Neither is trusted for its payload - the values always come from a
1290
+ * fresh read. Categories the library does not model are dropped.
1291
+ */
1292
+ readonly privacy: (event: WaPrivacyAccountSyncResult) => void;
1293
+ /**
1294
+ * The account blocklist after a block/unblock made on another device -
1295
+ * same refetch path as `privacy`, from its own account-sync protocol. The
1296
+ * payload is the full list ({@link WaPrivacyCoordinator.getBlocklist}'s
1297
+ * shape), never a delta.
1298
+ */
1299
+ readonly blocklist: (event: WaBlocklistResult) => void;
1208
1300
  /**
1209
1301
  * A parsed app-state mutation arriving from a sync – chat mute/star/read/
1210
1302
  * pin/archive/contact/label/etc. changed on another device. Inbound only;
@@ -1228,12 +1320,24 @@ export interface WaClientEventMap {
1228
1320
  * Skipped only when `history.enabled` is explicitly `false`.
1229
1321
  */
1230
1322
  readonly history_sync_chunk: (event: WaHistorySyncChunkEvent) => void;
1323
+ /**
1324
+ * A group-history bundle another member shared with this account after it
1325
+ * joined a group, already downloaded and persisted. Requires
1326
+ * `history.groupBundles: true` - the download is opt-in because a third
1327
+ * party triggers it.
1328
+ */
1329
+ readonly group_history_bundle: (event: WaGroupHistoryBundleEvent) => void;
1231
1330
  /**
1232
1331
  * Offline-message queue progress after a reconnect (`'resuming'` ticks
1233
1332
  * with `remainingStanzas`, then `'complete'`). Useful to defer UI updates
1234
1333
  * until the catch-up finishes.
1235
1334
  */
1236
1335
  readonly offline_resume: (event: WaOfflineResumeEvent) => void;
1336
+ /**
1337
+ * Preview manifest of the offline queue, sent just before the flush. Not
1338
+ * guaranteed to arrive - use `offline_resume` for progress, never this.
1339
+ */
1340
+ readonly offline_thread_metadata: (event: WaOfflineThreadMetadataEvent) => void;
1237
1341
  /**
1238
1342
  * Fatal stream-level error from the server (e.g. logged out from another
1239
1343
  * device, stream conflict). The connection will close right after.
@@ -1314,6 +1418,36 @@ export interface WaOfflineResumeEvent {
1314
1418
  /** `true` when triggered by an explicit catch-up request rather than auto-resume on reconnect. */
1315
1419
  readonly forced: boolean;
1316
1420
  }
1421
+ export interface WaOfflineThreadPreview {
1422
+ /** User (`@lid`/`@s.whatsapp.net`) or group (`@g.us`) jid. */
1423
+ readonly jid: string;
1424
+ /** Unix seconds of the most recent queued stanza for this thread. */
1425
+ readonly timestampSeconds: number;
1426
+ }
1427
+ export interface WaOfflineThreadReadWatermark {
1428
+ readonly jid: string;
1429
+ /** Unix seconds up to which the peer has already read this thread. */
1430
+ readonly readTimestampSeconds: number;
1431
+ }
1432
+ /**
1433
+ * Which threads have queued traffic, announced right before the offline flush.
1434
+ * Informational only - every listed thread still delivers its stanzas
1435
+ * normally. All fields but `threads` depend on server gating and are commonly
1436
+ * absent.
1437
+ */
1438
+ export interface WaOfflineThreadMetadataEvent {
1439
+ readonly threads: readonly WaOfflineThreadPreview[];
1440
+ readonly readWatermarks?: readonly WaOfflineThreadReadWatermark[];
1441
+ /** Status-update backlog still queued behind this flush. */
1442
+ readonly pendingStatusMessages?: {
1443
+ readonly count: number;
1444
+ readonly jids: readonly string[];
1445
+ };
1446
+ /** Notification backlog still queued behind this flush. */
1447
+ readonly pendingNotifications?: {
1448
+ readonly count: number;
1449
+ };
1450
+ }
1317
1451
  export interface WaPrivacyTokenUpdateEvent {
1318
1452
  /** Peer whose trusted-contact-token (TC token) changed. */
1319
1453
  readonly jid: string;
@@ -7,5 +7,5 @@ export { hkdf, hkdfSplit } from '../core/hkdf';
7
7
  export { toSerializedPubKey, toRawPubKey, prependVersion, readVersionedContent } from '../core/keys';
8
8
  export { writeNonceCounter } from '../core/nonce';
9
9
  export { randomBytesAsync, randomFillAsync, randomIntAsync } from '../core/random';
10
- export { sha1, sha256, sha512, md5Bytes, aesGcmEncrypt, aesGcmDecrypt, aesCbcEncrypt, aesCbcDecrypt, aesCtrEncrypt, aesCtrDecrypt, hmacSha256Sign, hmacSha512Sign, pbkdf2Sha256 } from '../core/primitives';
10
+ export { sha1, sha256, sha512, md5Bytes, aesGcmEncrypt, aesGcmDecrypt, aesCbcEncrypt, aesCbcEncryptWithTrailer, aesCbcDecrypt, aesCtrEncrypt, aesCtrDecrypt, hmacSha256Sign, hmacSha512Sign, pbkdf2Sha256 } from '../core/primitives';
11
11
  export { xeddsaSign, xeddsaVerify } from '../core/xeddsa';
@@ -3,7 +3,7 @@
3
3
  * Cryptographic utilities
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.xeddsaVerify = exports.xeddsaSign = exports.pbkdf2Sha256 = exports.hmacSha512Sign = exports.hmacSha256Sign = exports.aesCtrDecrypt = exports.aesCtrEncrypt = exports.aesCbcDecrypt = exports.aesCbcEncrypt = exports.aesGcmDecrypt = exports.aesGcmEncrypt = exports.md5Bytes = exports.sha512 = exports.sha256 = exports.sha1 = exports.randomIntAsync = exports.randomFillAsync = exports.randomBytesAsync = exports.writeNonceCounter = exports.readVersionedContent = exports.prependVersion = exports.toRawPubKey = exports.toSerializedPubKey = exports.hkdfSplit = exports.hkdf = exports.X25519 = exports.Ed25519 = void 0;
6
+ exports.xeddsaVerify = exports.xeddsaSign = exports.pbkdf2Sha256 = exports.hmacSha512Sign = exports.hmacSha256Sign = exports.aesCtrDecrypt = exports.aesCtrEncrypt = exports.aesCbcDecrypt = exports.aesCbcEncryptWithTrailer = exports.aesCbcEncrypt = exports.aesGcmDecrypt = exports.aesGcmEncrypt = exports.md5Bytes = exports.sha512 = exports.sha256 = exports.sha1 = exports.randomIntAsync = exports.randomFillAsync = exports.randomBytesAsync = exports.writeNonceCounter = exports.readVersionedContent = exports.prependVersion = exports.toRawPubKey = exports.toSerializedPubKey = exports.hkdfSplit = exports.hkdf = exports.X25519 = exports.Ed25519 = void 0;
7
7
  var Ed25519_1 = require("../curves/Ed25519");
8
8
  Object.defineProperty(exports, "Ed25519", { enumerable: true, get: function () { return Ed25519_1.Ed25519; } });
9
9
  var X25519_1 = require("../curves/X25519");
@@ -30,6 +30,7 @@ Object.defineProperty(exports, "md5Bytes", { enumerable: true, get: function ()
30
30
  Object.defineProperty(exports, "aesGcmEncrypt", { enumerable: true, get: function () { return primitives_1.aesGcmEncrypt; } });
31
31
  Object.defineProperty(exports, "aesGcmDecrypt", { enumerable: true, get: function () { return primitives_1.aesGcmDecrypt; } });
32
32
  Object.defineProperty(exports, "aesCbcEncrypt", { enumerable: true, get: function () { return primitives_1.aesCbcEncrypt; } });
33
+ Object.defineProperty(exports, "aesCbcEncryptWithTrailer", { enumerable: true, get: function () { return primitives_1.aesCbcEncryptWithTrailer; } });
33
34
  Object.defineProperty(exports, "aesCbcDecrypt", { enumerable: true, get: function () { return primitives_1.aesCbcDecrypt; } });
34
35
  Object.defineProperty(exports, "aesCtrEncrypt", { enumerable: true, get: function () { return primitives_1.aesCtrEncrypt; } });
35
36
  Object.defineProperty(exports, "aesCtrDecrypt", { enumerable: true, get: function () { return primitives_1.aesCtrDecrypt; } });