@push.rocks/smartmta 6.5.2 → 8.0.0

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 (84) hide show
  1. package/changelog.md +40 -0
  2. package/dist_rust/mailer-bin_linux_amd64 +0 -0
  3. package/dist_rust/mailer-bin_linux_arm64 +0 -0
  4. package/dist_ts/00_commitinfo_data.js +1 -1
  5. package/dist_ts/functions.errors.d.ts +3 -0
  6. package/dist_ts/functions.errors.js +8 -0
  7. package/dist_ts/index.d.ts +3 -0
  8. package/dist_ts/index.js +4 -1
  9. package/dist_ts/mail/core/classes.bouncemanager.d.ts +16 -12
  10. package/dist_ts/mail/core/classes.bouncemanager.js +146 -129
  11. package/dist_ts/mail/core/classes.email.js +15 -13
  12. package/dist_ts/mail/core/classes.emailvalidator.d.ts +3 -3
  13. package/dist_ts/mail/core/classes.emailvalidator.js +7 -5
  14. package/dist_ts/mail/core/classes.templatemanager.d.ts +10 -6
  15. package/dist_ts/mail/core/classes.templatemanager.js +35 -51
  16. package/dist_ts/mail/delivery/classes.delivery.queue.d.ts +92 -22
  17. package/dist_ts/mail/delivery/classes.delivery.queue.js +738 -151
  18. package/dist_ts/mail/delivery/classes.delivery.system.d.ts +13 -7
  19. package/dist_ts/mail/delivery/classes.delivery.system.js +458 -145
  20. package/dist_ts/mail/delivery/classes.unified.rate.limiter.js +9 -8
  21. package/dist_ts/mail/delivery/functions.safe-observers.d.ts +10 -0
  22. package/dist_ts/mail/delivery/functions.safe-observers.js +37 -0
  23. package/dist_ts/mail/delivery/interfaces.d.ts +21 -0
  24. package/dist_ts/mail/delivery/interfaces.js +1 -1
  25. package/dist_ts/mail/interfaces.storage.d.ts +37 -6
  26. package/dist_ts/mail/interfaces.storage.js +33 -3
  27. package/dist_ts/mail/routing/classes.dkim.manager.d.ts +10 -6
  28. package/dist_ts/mail/routing/classes.dkim.manager.js +47 -31
  29. package/dist_ts/mail/routing/classes.dns.manager.d.ts +7 -5
  30. package/dist_ts/mail/routing/classes.dns.manager.js +22 -11
  31. package/dist_ts/mail/routing/classes.email.action.executor.d.ts +2 -1
  32. package/dist_ts/mail/routing/classes.email.action.executor.js +45 -16
  33. package/dist_ts/mail/routing/classes.email.router.d.ts +5 -2
  34. package/dist_ts/mail/routing/classes.email.router.js +17 -12
  35. package/dist_ts/mail/routing/classes.unified.email.server.d.ts +12 -6
  36. package/dist_ts/mail/routing/classes.unified.email.server.js +69 -78
  37. package/dist_ts/mail/routing/interfaces.d.ts +0 -2
  38. package/dist_ts/mail/security/classes.dkimcreator.d.ts +22 -45
  39. package/dist_ts/mail/security/classes.dkimcreator.js +93 -296
  40. package/dist_ts/mail/security/classes.spfverifier.js +5 -3
  41. package/dist_ts/paths.d.ts +0 -12
  42. package/dist_ts/paths.js +3 -36
  43. package/dist_ts/plugins.d.ts +2 -5
  44. package/dist_ts/plugins.js +3 -6
  45. package/dist_ts/security/classes.contentscanner.js +14 -12
  46. package/dist_ts/security/classes.ipreputationchecker.d.ts +9 -6
  47. package/dist_ts/security/classes.ipreputationchecker.js +42 -93
  48. package/dist_ts/security/classes.rustsecuritybridge.d.ts +52 -4
  49. package/dist_ts/security/classes.rustsecuritybridge.js +201 -4
  50. package/dist_ts/security/classes.securitylogger.js +7 -5
  51. package/dist_ts/security/index.d.ts +1 -1
  52. package/dist_ts/security/index.js +2 -2
  53. package/package.json +8 -9
  54. package/readme.hints.md +4 -3
  55. package/readme.md +50 -18
  56. package/readme.plan.md +6 -0
  57. package/ts/00_commitinfo_data.ts +1 -1
  58. package/ts/functions.errors.ts +8 -0
  59. package/ts/index.ts +3 -0
  60. package/ts/mail/core/classes.bouncemanager.ts +188 -155
  61. package/ts/mail/core/classes.email.ts +20 -14
  62. package/ts/mail/core/classes.emailvalidator.ts +9 -7
  63. package/ts/mail/core/classes.templatemanager.ts +42 -57
  64. package/ts/mail/delivery/classes.delivery.queue.ts +996 -185
  65. package/ts/mail/delivery/classes.delivery.system.ts +583 -170
  66. package/ts/mail/delivery/classes.unified.rate.limiter.ts +9 -8
  67. package/ts/mail/delivery/functions.safe-observers.ts +45 -0
  68. package/ts/mail/delivery/interfaces.ts +27 -1
  69. package/ts/mail/interfaces.storage.ts +64 -10
  70. package/ts/mail/routing/classes.dkim.manager.ts +65 -40
  71. package/ts/mail/routing/classes.dns.manager.ts +39 -16
  72. package/ts/mail/routing/classes.email.action.executor.ts +64 -17
  73. package/ts/mail/routing/classes.email.router.ts +20 -13
  74. package/ts/mail/routing/classes.unified.email.server.ts +107 -86
  75. package/ts/mail/routing/interfaces.ts +0 -2
  76. package/ts/mail/security/classes.dkimcreator.ts +150 -355
  77. package/ts/mail/security/classes.spfverifier.ts +4 -2
  78. package/ts/paths.ts +2 -41
  79. package/ts/plugins.ts +1 -6
  80. package/ts/security/classes.contentscanner.ts +14 -12
  81. package/ts/security/classes.ipreputationchecker.ts +46 -99
  82. package/ts/security/classes.rustsecuritybridge.ts +272 -6
  83. package/ts/security/classes.securitylogger.ts +6 -4
  84. package/ts/security/index.ts +5 -1
@@ -1,9 +1,29 @@
1
- import * as plugins from '../../plugins.js';
2
1
  import { EventEmitter } from 'node:events';
3
- import * as fs from 'node:fs';
4
- import * as path from 'node:path';
2
+ import { createHash } from 'node:crypto';
3
+ import { deserialize, serialize } from 'node:v8';
5
4
  import { logger } from '../../logger.js';
6
5
  import {} from './interfaces.js';
6
+ import { normalizeSmtpTranscript, SMTP_TRANSCRIPT_MAX_ENTRIES, SMTP_TRANSCRIPT_MAX_ENTRY_CODE_POINTS, SMTP_TRANSCRIPT_MAX_UTF8_BYTES, } from '../../security/classes.rustsecuritybridge.js';
7
+ import { Email } from '../core/classes.email.js';
8
+ import { emitSafely } from './functions.safe-observers.js';
9
+ import { getErrorMessage } from '../../functions.errors.js';
10
+ /**
11
+ * Queue statistics interface
12
+ */
13
+ function normalizeStoragePrefix(prefixArg = '/email/queue/') {
14
+ if (!prefixArg.startsWith('/') ||
15
+ !prefixArg.endsWith('/') ||
16
+ prefixArg.includes('\\') ||
17
+ prefixArg.includes('\0')) {
18
+ throw new Error('Queue storagePrefix must be an absolute managed-storage prefix');
19
+ }
20
+ const segments = prefixArg.slice(1, -1).split('/');
21
+ if (segments.some((segment) => !segment || segment === '.' || segment === '..')) {
22
+ throw new Error('Queue storagePrefix contains an invalid path segment');
23
+ }
24
+ return prefixArg;
25
+ }
26
+ const managedQueueOwners = new WeakMap();
7
27
  /**
8
28
  * A unified queue for all email modes
9
29
  */
@@ -15,16 +35,24 @@ export class UnifiedDeliveryQueue extends EventEmitter {
15
35
  stats;
16
36
  processing = false;
17
37
  totalProcessed = 0;
38
+ ownsManagedPrefix = false;
39
+ lifecycleState = 'new';
18
40
  /**
19
41
  * Create a new unified delivery queue
20
42
  * @param options Queue options
21
43
  */
22
44
  constructor(options) {
23
45
  super();
24
- // Set default options
46
+ if (options.storageMode === 'managed' && !options.storageManager) {
47
+ throw new Error('Managed queue storage requires an IBlobStorageManager');
48
+ }
49
+ if (options.storageMode === 'memory' && options.storageManager) {
50
+ throw new Error('Memory-only queue storage cannot receive an IBlobStorageManager');
51
+ }
25
52
  this.options = {
26
- storageType: options.storageType || 'memory',
27
- persistentPath: options.persistentPath || path.join(process.cwd(), 'email-queue'),
53
+ storageMode: options.storageMode,
54
+ storageManager: options.storageManager,
55
+ storagePrefix: normalizeStoragePrefix(options.storagePrefix),
28
56
  checkInterval: options.checkInterval || 30000, // 30 seconds
29
57
  maxQueueSize: options.maxQueueSize || 10000,
30
58
  maxPerDestination: options.maxPerDestination || 100,
@@ -52,27 +80,90 @@ export class UnifiedDeliveryQueue extends EventEmitter {
52
80
  processingActive: false
53
81
  };
54
82
  }
83
+ assertMutable() {
84
+ if (this.lifecycleState === 'shutting-down' || this.lifecycleState === 'closed') {
85
+ throw new Error(`Delivery queue is ${this.lifecycleState}; mutations are no longer allowed`);
86
+ }
87
+ }
88
+ createInitialRecipientStates(email) {
89
+ const byRecipient = new Map();
90
+ const now = new Date();
91
+ for (const recipient of email.getAllRecipients()) {
92
+ const normalizedRecipient = recipient.trim().toLowerCase();
93
+ if (!normalizedRecipient || byRecipient.has(normalizedRecipient))
94
+ continue;
95
+ byRecipient.set(normalizedRecipient, {
96
+ recipient,
97
+ normalizedRecipient,
98
+ state: 'unresolved',
99
+ updatedAt: now,
100
+ });
101
+ }
102
+ return [...byRecipient.values()];
103
+ }
104
+ createBounceOperationId(itemId, normalizedRecipient) {
105
+ return createHash('sha256')
106
+ .update(itemId)
107
+ .update('\0')
108
+ .update(normalizedRecipient)
109
+ .update('\0smtpFailure')
110
+ .digest('hex');
111
+ }
55
112
  /**
56
113
  * Initialize the queue
57
114
  */
58
- async initialize() {
115
+ claimManagedPrefix() {
116
+ const storageManager = this.options.storageManager;
117
+ if (!storageManager || this.ownsManagedPrefix)
118
+ return;
119
+ let owners = managedQueueOwners.get(storageManager);
120
+ if (!owners) {
121
+ owners = new Map();
122
+ managedQueueOwners.set(storageManager, owners);
123
+ }
124
+ const existingOwner = owners.get(this.options.storagePrefix);
125
+ if (existingOwner && existingOwner !== this) {
126
+ throw new Error(`Managed queue prefix ${this.options.storagePrefix} already has an active delivery owner`);
127
+ }
128
+ owners.set(this.options.storagePrefix, this);
129
+ this.ownsManagedPrefix = true;
130
+ }
131
+ releaseManagedPrefix() {
132
+ const storageManager = this.options.storageManager;
133
+ if (!storageManager || !this.ownsManagedPrefix)
134
+ return;
135
+ const owners = managedQueueOwners.get(storageManager);
136
+ if (owners?.get(this.options.storagePrefix) === this) {
137
+ owners.delete(this.options.storagePrefix);
138
+ if (owners.size === 0)
139
+ managedQueueOwners.delete(storageManager);
140
+ }
141
+ this.ownsManagedPrefix = false;
142
+ }
143
+ async initialize(optionsArg = {}) {
59
144
  logger.log('info', 'Initializing UnifiedDeliveryQueue');
145
+ if (this.lifecycleState !== 'new') {
146
+ throw new Error(`Delivery queue cannot initialize from ${this.lifecycleState} state`);
147
+ }
148
+ this.claimManagedPrefix();
60
149
  try {
61
- // Create persistent storage directory if using disk storage
62
- if (this.options.storageType === 'disk') {
63
- if (!fs.existsSync(this.options.persistentPath)) {
64
- fs.mkdirSync(this.options.persistentPath, { recursive: true });
65
- }
66
- // Load existing items from disk
67
- await this.loadFromDisk();
150
+ if (this.options.storageManager) {
151
+ await this.loadFromStorage();
152
+ }
153
+ this.lifecycleState = 'initialized';
154
+ // Embedders may hydrate durable state before delivery dependencies are ready.
155
+ if (optionsArg.startProcessing !== false) {
156
+ this.startProcessing();
68
157
  }
69
- // Start the queue processing timer
70
- this.startProcessing();
71
158
  // Emit initialized event
72
- this.emit('initialized');
159
+ await emitSafely(this, 'initialized');
73
160
  logger.log('info', 'UnifiedDeliveryQueue initialized successfully');
74
161
  }
75
162
  catch (error) {
163
+ this.queue.clear();
164
+ this.updateStats();
165
+ this.lifecycleState = 'new';
166
+ this.releaseManagedPrefix();
76
167
  logger.log('error', `Failed to initialize queue: ${error.message}`);
77
168
  throw error;
78
169
  }
@@ -96,7 +187,7 @@ export class UnifiedDeliveryQueue extends EventEmitter {
96
187
  }, 30 * 60 * 1000);
97
188
  this.processing = true;
98
189
  this.stats.processingActive = true;
99
- this.emit('processingStarted');
190
+ void emitSafely(this, 'processingStarted');
100
191
  logger.log('info', 'Queue processing started');
101
192
  }
102
193
  /**
@@ -113,7 +204,7 @@ export class UnifiedDeliveryQueue extends EventEmitter {
113
204
  }
114
205
  this.processing = false;
115
206
  this.stats.processingActive = false;
116
- this.emit('processingStopped');
207
+ void emitSafely(this, 'processingStopped');
117
208
  logger.log('info', 'Queue processing stopped');
118
209
  }
119
210
  /**
@@ -135,14 +226,14 @@ export class UnifiedDeliveryQueue extends EventEmitter {
135
226
  // Sort by oldest first
136
227
  readyItems.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
137
228
  // Emit event for ready items
138
- this.emit('itemsReady', readyItems);
229
+ await emitSafely(this, 'itemsReady', readyItems);
139
230
  logger.log('info', `Found ${readyItems.length} items ready for processing`);
140
231
  // Update statistics
141
232
  this.updateStats();
142
233
  }
143
234
  catch (error) {
144
- logger.log('error', `Error processing queue: ${error.message}`);
145
- this.emit('error', error);
235
+ logger.log('error', `Error processing queue: ${getErrorMessage(error)}`);
236
+ await emitSafely(this, 'error', error);
146
237
  }
147
238
  }
148
239
  /**
@@ -152,6 +243,10 @@ export class UnifiedDeliveryQueue extends EventEmitter {
152
243
  * @param route Email route
153
244
  */
154
245
  async enqueue(processingResult, mode, route) {
246
+ this.assertMutable();
247
+ if (!(processingResult instanceof Email)) {
248
+ throw new Error('Queue processingResult must be an Email instance');
249
+ }
155
250
  // Check if queue is full
156
251
  if (this.queue.size >= this.options.maxQueueSize) {
157
252
  throw new Error('Queue is full');
@@ -168,18 +263,20 @@ export class UnifiedDeliveryQueue extends EventEmitter {
168
263
  attempts: 0,
169
264
  nextAttempt: new Date(),
170
265
  createdAt: new Date(),
171
- updatedAt: new Date()
266
+ updatedAt: new Date(),
267
+ deliveredRecipients: [],
268
+ terminalRecipients: [],
269
+ recipientStates: this.createInitialRecipientStates(processingResult),
270
+ bounceOperations: [],
271
+ smtpTransactions: [],
172
272
  };
173
- // Add to queue
273
+ // Commit durable state before exposing the item in memory or emitting acceptance.
274
+ await this.persistItem(item);
174
275
  this.queue.set(id, item);
175
- // Persist to disk if using disk storage
176
- if (this.options.storageType === 'disk') {
177
- await this.persistItem(item);
178
- }
179
276
  // Update statistics
180
277
  this.updateStats();
181
278
  // Emit event
182
- this.emit('itemEnqueued', item);
279
+ await emitSafely(this, 'itemEnqueued', item);
183
280
  logger.log('info', `Item enqueued with ID ${id}, mode: ${mode}`);
184
281
  return id;
185
282
  }
@@ -191,29 +288,41 @@ export class UnifiedDeliveryQueue extends EventEmitter {
191
288
  return this.queue.get(id);
192
289
  }
193
290
  listItems() {
194
- return Array.from(this.queue.values()).map((item) => ({ ...item }));
291
+ return Array.from(this.queue.values()).map((item) => ({
292
+ ...item,
293
+ deliveredRecipients: [...(item.deliveredRecipients || [])],
294
+ terminalRecipients: [...(item.terminalRecipients || [])],
295
+ recipientStates: (item.recipientStates || []).map((state) => ({ ...state })),
296
+ bounceOperations: (item.bounceOperations || []).map((operation) => ({ ...operation })),
297
+ smtpTransactions: (item.smtpTransactions || []).map((transaction) => ({
298
+ ...transaction,
299
+ recipients: [...transaction.recipients],
300
+ recipientResults: transaction.recipientResults?.map((result) => ({ ...result })),
301
+ transcript: transaction.transcript.map((entry) => ({ ...entry })),
302
+ })),
303
+ }));
195
304
  }
196
305
  /**
197
306
  * Mark an item as being processed
198
307
  * @param id Item ID
199
308
  */
200
309
  async markProcessing(id) {
310
+ this.assertMutable();
201
311
  const item = this.queue.get(id);
202
- if (!item) {
312
+ if (!item
313
+ || !(item.status === 'pending'
314
+ || (item.status === 'deferred' && item.nextAttempt <= new Date()))) {
203
315
  return false;
204
316
  }
205
- // Update status
206
- item.status = 'processing';
207
- item.attempts++;
208
- item.updatedAt = new Date();
209
- // Persist changes if using disk storage
210
- if (this.options.storageType === 'disk') {
211
- await this.persistItem(item);
212
- }
317
+ await this.applyPersistedMutation(item, (updatedItem) => {
318
+ updatedItem.status = 'processing';
319
+ updatedItem.attempts++;
320
+ updatedItem.updatedAt = new Date();
321
+ });
213
322
  // Update statistics
214
323
  this.updateStats();
215
324
  // Emit event
216
- this.emit('itemProcessing', item);
325
+ await emitSafely(this, 'itemProcessing', item);
217
326
  logger.log('info', `Item ${id} marked as processing, attempt ${item.attempts}`);
218
327
  return true;
219
328
  }
@@ -222,23 +331,21 @@ export class UnifiedDeliveryQueue extends EventEmitter {
222
331
  * @param id Item ID
223
332
  */
224
333
  async markDelivered(id) {
334
+ this.assertMutable();
225
335
  const item = this.queue.get(id);
226
- if (!item) {
336
+ if (!item || item.status === 'delivered' || item.status === 'failed') {
227
337
  return false;
228
338
  }
229
- // Update status
230
- item.status = 'delivered';
231
- item.updatedAt = new Date();
232
- item.deliveredAt = new Date();
233
- // Persist changes if using disk storage
234
- if (this.options.storageType === 'disk') {
235
- await this.persistItem(item);
236
- }
339
+ await this.applyPersistedMutation(item, (updatedItem) => {
340
+ updatedItem.status = 'delivered';
341
+ updatedItem.updatedAt = new Date();
342
+ updatedItem.deliveredAt = new Date();
343
+ });
237
344
  // Update statistics
238
345
  this.totalProcessed++;
239
346
  this.updateStats();
240
347
  // Emit event
241
- this.emit('itemDelivered', item);
348
+ await emitSafely(this, 'itemDelivered', item);
242
349
  logger.log('info', `Item ${id} marked as delivered after ${item.attempts} attempts`);
243
350
  return true;
244
351
  }
@@ -247,45 +354,227 @@ export class UnifiedDeliveryQueue extends EventEmitter {
247
354
  * @param id Item ID
248
355
  * @param error Error message
249
356
  */
250
- async markFailed(id, error) {
357
+ async markFailed(id, error, optionsArg = {}) {
358
+ return (await this.markFailedWithTransition(id, error, optionsArg)).updated;
359
+ }
360
+ /** Rich internal disposition used by the delivery system without breaking markFailed(). */
361
+ async markFailedWithTransition(id, error, optionsArg = {}) {
362
+ this.assertMutable();
251
363
  const item = this.queue.get(id);
252
364
  if (!item) {
253
- return false;
365
+ return { updated: false, terminal: false };
366
+ }
367
+ if (item.status === 'delivered' || item.status === 'failed') {
368
+ return {
369
+ updated: false,
370
+ status: item.status === 'failed' ? 'failed' : undefined,
371
+ terminal: true,
372
+ };
254
373
  }
255
374
  // Determine if we should retry
256
- if (item.attempts < this.options.maxRetries) {
375
+ const retryable = optionsArg.retryable !== false;
376
+ if (retryable && item.attempts < this.options.maxRetries) {
257
377
  // Calculate next retry time with exponential backoff
258
378
  const delay = Math.min(this.options.baseRetryDelay * Math.pow(2, item.attempts - 1), this.options.maxRetryDelay);
259
- // Update status
260
- item.status = 'deferred';
261
- item.lastError = error;
262
- item.nextAttempt = new Date(Date.now() + delay);
263
- item.updatedAt = new Date();
264
- // Persist changes if using disk storage
265
- if (this.options.storageType === 'disk') {
266
- await this.persistItem(item);
267
- }
379
+ await this.applyPersistedMutation(item, (updatedItem) => {
380
+ updatedItem.status = 'deferred';
381
+ updatedItem.lastError = error;
382
+ updatedItem.nextAttempt = new Date(Date.now() + delay);
383
+ updatedItem.updatedAt = new Date();
384
+ });
268
385
  // Emit event
269
- this.emit('itemDeferred', item);
386
+ await emitSafely(this, 'itemDeferred', item);
270
387
  logger.log('info', `Item ${id} deferred for ${delay}ms, attempt ${item.attempts}, error: ${error}`);
388
+ this.updateStats();
389
+ return { updated: true, status: 'deferred', terminal: false };
271
390
  }
272
391
  else {
273
392
  // Mark as permanently failed
274
- item.status = 'failed';
275
- item.lastError = error;
276
- item.updatedAt = new Date();
277
- // Persist changes if using disk storage
278
- if (this.options.storageType === 'disk') {
279
- await this.persistItem(item);
280
- }
393
+ await this.applyPersistedMutation(item, (updatedItem) => {
394
+ updatedItem.status = 'failed';
395
+ updatedItem.lastError = error;
396
+ updatedItem.updatedAt = new Date();
397
+ });
281
398
  // Update statistics
282
399
  this.totalProcessed++;
283
400
  // Emit event
284
- this.emit('itemFailed', item);
401
+ await emitSafely(this, 'itemFailed', item);
285
402
  logger.log('warn', `Item ${id} permanently failed after ${item.attempts} attempts, error: ${error}`);
286
403
  }
287
- // Update statistics
288
404
  this.updateStats();
405
+ return {
406
+ updated: true,
407
+ status: 'failed',
408
+ terminal: true,
409
+ terminalReason: retryable ? 'retry_exhausted' : 'permanent',
410
+ };
411
+ }
412
+ /** Persist a completed SMTP attempt before any queue status event is emitted. */
413
+ async appendSmtpTransaction(id, transaction) {
414
+ this.assertMutable();
415
+ const item = this.queue.get(id);
416
+ if (!item)
417
+ return false;
418
+ const normalizedTransaction = {
419
+ ...transaction,
420
+ queueItemId: id,
421
+ recipients: [...transaction.recipients],
422
+ recipientResults: transaction.recipientResults?.map((result) => ({ ...result })),
423
+ transcript: normalizeSmtpTranscript(transaction.transcript),
424
+ };
425
+ await this.applyPersistedMutation(item, (updatedItem) => {
426
+ updatedItem.smtpTransactions = [
427
+ ...(updatedItem.smtpTransactions || []),
428
+ normalizedTransaction,
429
+ ].slice(-20);
430
+ updatedItem.updatedAt = new Date();
431
+ });
432
+ await emitSafely(this, 'smtpTransaction', item, normalizedTransaction);
433
+ return true;
434
+ }
435
+ /** Record recipients accepted after the SMTP final-response 250 checkpoint. */
436
+ async markRecipientsDelivered(id, recipients) {
437
+ this.assertMutable();
438
+ const item = this.queue.get(id);
439
+ if (!item)
440
+ return false;
441
+ const normalizedRecipients = new Set(recipients.map((recipient) => recipient.trim().toLowerCase()).filter(Boolean));
442
+ if (normalizedRecipients.size === 0)
443
+ return false;
444
+ await this.applyPersistedMutation(item, (updatedItem) => {
445
+ const states = updatedItem.recipientStates || this.createInitialRecipientStates(updatedItem.processingResult);
446
+ const delivered = new Set(updatedItem.deliveredRecipients || []);
447
+ const now = new Date();
448
+ for (const state of states) {
449
+ if (normalizedRecipients.has(state.normalizedRecipient)
450
+ && state.state === 'unresolved') {
451
+ state.state = 'delivered';
452
+ state.updatedAt = now;
453
+ delete state.smtpCode;
454
+ delete state.smtpResponse;
455
+ delivered.add(state.normalizedRecipient);
456
+ }
457
+ }
458
+ updatedItem.recipientStates = states;
459
+ updatedItem.deliveredRecipients = [...delivered];
460
+ updatedItem.updatedAt = now;
461
+ });
462
+ return true;
463
+ }
464
+ /**
465
+ * Atomically checkpoint permanent recipient failures together with their
466
+ * durable bounce work. This is the sole 5xx recipient transition.
467
+ */
468
+ async markRecipientsTerminal(id, failures) {
469
+ this.assertMutable();
470
+ const item = this.queue.get(id);
471
+ if (!item || failures.length === 0)
472
+ return [];
473
+ const normalizedFailures = failures.map((failure) => (typeof failure === 'string'
474
+ ? {
475
+ recipient: failure,
476
+ smtpCode: 550,
477
+ smtpResponse: 'SMTP recipient permanently rejected',
478
+ }
479
+ : failure));
480
+ const newlyTerminal = [];
481
+ await this.applyPersistedMutation(item, (updatedItem) => {
482
+ const states = updatedItem.recipientStates || this.createInitialRecipientStates(updatedItem.processingResult);
483
+ const terminal = new Set(updatedItem.terminalRecipients || []);
484
+ const operations = updatedItem.bounceOperations || [];
485
+ const operationIds = new Set(operations.map((operation) => operation.operationId));
486
+ const now = new Date();
487
+ for (const failure of normalizedFailures) {
488
+ const normalizedRecipient = failure.recipient.trim().toLowerCase();
489
+ const state = states.find((candidate) => candidate.normalizedRecipient === normalizedRecipient);
490
+ if (!state || state.state !== 'unresolved')
491
+ continue;
492
+ state.state = 'permanentFailure';
493
+ state.smtpCode = failure.smtpCode;
494
+ state.smtpResponse = failure.smtpResponse;
495
+ state.updatedAt = now;
496
+ terminal.add(normalizedRecipient);
497
+ newlyTerminal.push(state.recipient);
498
+ const operationId = this.createBounceOperationId(updatedItem.id, normalizedRecipient);
499
+ if (!operationIds.has(operationId)) {
500
+ operations.push({
501
+ operationId,
502
+ kind: 'smtpFailure',
503
+ recipient: state.recipient,
504
+ normalizedRecipient,
505
+ smtpCode: failure.smtpCode,
506
+ smtpResponse: failure.smtpResponse,
507
+ state: 'pending',
508
+ attempts: 0,
509
+ nextAttempt: now,
510
+ });
511
+ operationIds.add(operationId);
512
+ }
513
+ }
514
+ updatedItem.recipientStates = states;
515
+ updatedItem.terminalRecipients = [...terminal];
516
+ updatedItem.bounceOperations = operations;
517
+ updatedItem.updatedAt = now;
518
+ });
519
+ return newlyTerminal;
520
+ }
521
+ getRecipientDisposition(id) {
522
+ const item = this.queue.get(id);
523
+ if (!item)
524
+ return { unresolved: [], delivered: [], permanentFailures: [] };
525
+ const states = item.recipientStates || this.createInitialRecipientStates(item.processingResult);
526
+ return {
527
+ unresolved: states.filter((state) => state.state === 'unresolved').map((state) => state.recipient),
528
+ delivered: states.filter((state) => state.state === 'delivered').map((state) => state.recipient),
529
+ permanentFailures: states
530
+ .filter((state) => state.state === 'permanentFailure')
531
+ .map((state) => state.recipient),
532
+ };
533
+ }
534
+ /** Includes terminal queue items because bounce work outlives delivery status. */
535
+ listPendingBounceOperations(now = new Date()) {
536
+ const result = [];
537
+ for (const item of this.queue.values()) {
538
+ for (const operation of item.bounceOperations || []) {
539
+ if (operation.state === 'pending' && operation.nextAttempt <= now) {
540
+ result.push({ itemId: item.id, operation: { ...operation } });
541
+ }
542
+ }
543
+ }
544
+ return result;
545
+ }
546
+ async markBounceOperationCompleted(itemId, operationId) {
547
+ this.assertMutable();
548
+ const item = this.queue.get(itemId);
549
+ const operation = item?.bounceOperations?.find((candidate) => candidate.operationId === operationId);
550
+ if (!item || !operation || operation.state === 'completed')
551
+ return false;
552
+ await this.applyPersistedMutation(item, (updatedItem) => {
553
+ const updatedOperation = updatedItem.bounceOperations?.find((candidate) => candidate.operationId === operationId);
554
+ if (!updatedOperation)
555
+ return;
556
+ updatedOperation.state = 'completed';
557
+ updatedOperation.completedAt = new Date();
558
+ delete updatedOperation.lastError;
559
+ updatedItem.updatedAt = new Date();
560
+ });
561
+ return true;
562
+ }
563
+ async markBounceOperationFailed(itemId, operationId, error) {
564
+ this.assertMutable();
565
+ const item = this.queue.get(itemId);
566
+ const operation = item?.bounceOperations?.find((candidate) => candidate.operationId === operationId);
567
+ if (!item || !operation || operation.state === 'completed')
568
+ return false;
569
+ await this.applyPersistedMutation(item, (updatedItem) => {
570
+ const updatedOperation = updatedItem.bounceOperations?.find((candidate) => candidate.operationId === operationId);
571
+ if (!updatedOperation)
572
+ return;
573
+ updatedOperation.attempts++;
574
+ updatedOperation.lastError = error;
575
+ updatedOperation.nextAttempt = new Date(Date.now() + Math.min(60_000 * (2 ** Math.max(0, updatedOperation.attempts - 1)), 3_600_000));
576
+ updatedItem.updatedAt = new Date();
577
+ });
289
578
  return true;
290
579
  }
291
580
  /**
@@ -293,92 +582,375 @@ export class UnifiedDeliveryQueue extends EventEmitter {
293
582
  * @param id Item ID
294
583
  */
295
584
  async removeItem(id) {
585
+ this.assertMutable();
296
586
  const item = this.queue.get(id);
297
587
  if (!item) {
298
588
  return false;
299
589
  }
300
- // Remove from queue
590
+ // Delete durable state before making the removal visible in memory.
591
+ await this.removeItemFromStorage(id);
301
592
  this.queue.delete(id);
302
- // Remove from disk if using disk storage
303
- if (this.options.storageType === 'disk') {
304
- await this.removeItemFromDisk(id);
305
- }
306
593
  // Update statistics
307
594
  this.updateStats();
308
595
  // Emit event
309
- this.emit('itemRemoved', item);
596
+ await emitSafely(this, 'itemRemoved', item);
310
597
  logger.log('info', `Item ${id} removed from queue`);
311
598
  return true;
312
599
  }
313
- /**
314
- * Persist an item to disk
315
- * @param item Item to persist
316
- */
600
+ storageKey(id) {
601
+ return `${this.options.storagePrefix}${id}.json`;
602
+ }
317
603
  async persistItem(item) {
604
+ if (!this.options.storageManager)
605
+ return;
606
+ await this.options.storageManager.set(this.storageKey(item.id), serialize(this.serializeItem(item)));
607
+ }
608
+ serializeItem(item) {
609
+ return {
610
+ schemaVersion: 2,
611
+ id: item.id,
612
+ processingMode: item.processingMode,
613
+ processingResult: {
614
+ options: item.processingResult.toEmailOptions(),
615
+ messageId: item.processingResult.getMessageId(),
616
+ envelopeFrom: item.processingResult.getEnvelopeFrom(),
617
+ },
618
+ ...(item.route ? { route: item.route } : {}),
619
+ status: item.status,
620
+ attempts: item.attempts,
621
+ nextAttempt: item.nextAttempt.getTime(),
622
+ ...(item.lastError !== undefined ? { lastError: item.lastError } : {}),
623
+ createdAt: item.createdAt.getTime(),
624
+ updatedAt: item.updatedAt.getTime(),
625
+ ...(item.deliveredAt ? { deliveredAt: item.deliveredAt.getTime() } : {}),
626
+ deliveredRecipients: item.deliveredRecipients || [],
627
+ terminalRecipients: item.terminalRecipients || [],
628
+ recipientStates: (item.recipientStates || this.createInitialRecipientStates(item.processingResult)).map((state) => ({
629
+ ...state,
630
+ updatedAt: state.updatedAt.getTime(),
631
+ })),
632
+ bounceOperations: (item.bounceOperations || []).map((operation) => {
633
+ const { nextAttempt, completedAt, ...storedOperation } = operation;
634
+ return {
635
+ ...storedOperation,
636
+ nextAttempt: nextAttempt.getTime(),
637
+ ...(completedAt ? { completedAt: completedAt.getTime() } : {}),
638
+ };
639
+ }),
640
+ smtpTransactions: (item.smtpTransactions || []).slice(-20).map((transaction) => ({
641
+ ...transaction,
642
+ queueItemId: item.id,
643
+ recipients: [...transaction.recipients],
644
+ recipientResults: transaction.recipientResults?.map((result) => ({ ...result })),
645
+ transcript: normalizeSmtpTranscript(transaction.transcript),
646
+ })),
647
+ };
648
+ }
649
+ async applyPersistedMutation(item, mutation) {
650
+ this.assertMutable();
651
+ const updatedItem = {
652
+ ...item,
653
+ deliveredRecipients: [...(item.deliveredRecipients || [])],
654
+ terminalRecipients: [...(item.terminalRecipients || [])],
655
+ recipientStates: (item.recipientStates || []).map((state) => ({ ...state })),
656
+ bounceOperations: (item.bounceOperations || []).map((operation) => ({ ...operation })),
657
+ smtpTransactions: [...(item.smtpTransactions || [])],
658
+ };
659
+ mutation(updatedItem);
660
+ await this.persistItem(updatedItem);
661
+ Object.assign(item, updatedItem);
662
+ }
663
+ async removeItemFromStorage(id) {
664
+ await this.options.storageManager?.delete(this.storageKey(id));
665
+ }
666
+ deserializeItem(key, data) {
667
+ let parsed;
318
668
  try {
319
- const filePath = path.join(this.options.persistentPath, `${item.id}.json`);
320
- await fs.promises.writeFile(filePath, JSON.stringify(item, null, 2), 'utf8');
669
+ parsed = deserialize(data);
321
670
  }
322
671
  catch (error) {
323
- logger.log('error', `Failed to persist item ${item.id}: ${error.message}`);
324
- this.emit('error', error);
672
+ throw new Error(`Invalid managed queue item at ${key}: ${getErrorMessage(error)}`);
325
673
  }
326
- }
327
- /**
328
- * Remove an item from disk
329
- * @param id Item ID
330
- */
331
- async removeItemFromDisk(id) {
332
- try {
333
- const filePath = path.join(this.options.persistentPath, `${id}.json`);
334
- if (fs.existsSync(filePath)) {
335
- await fs.promises.unlink(filePath);
674
+ if (!parsed || typeof parsed !== 'object' || typeof parsed.id !== 'string' || !parsed.id) {
675
+ throw new Error(`Invalid managed queue item at ${key}: missing id`);
676
+ }
677
+ if (parsed.schemaVersion !== 1 && parsed.schemaVersion !== 2) {
678
+ throw new Error(`Invalid managed queue item at ${key}: unsupported schema version`);
679
+ }
680
+ if (this.storageKey(parsed.id) !== key) {
681
+ throw new Error(`Invalid managed queue item at ${key}: id does not match object key`);
682
+ }
683
+ if (!['pending', 'processing', 'delivered', 'failed', 'deferred'].includes(parsed.status)) {
684
+ throw new Error(`Invalid managed queue item at ${key}: unsupported status`);
685
+ }
686
+ if (!['forward', 'mta', 'process'].includes(parsed.processingMode)) {
687
+ throw new Error(`Invalid managed queue item at ${key}: unsupported processing mode`);
688
+ }
689
+ if (!Number.isInteger(parsed.attempts) || parsed.attempts < 0) {
690
+ throw new Error(`Invalid managed queue item at ${key}: invalid attempt count`);
691
+ }
692
+ if (parsed.deliveredRecipients !== undefined
693
+ && (!Array.isArray(parsed.deliveredRecipients)
694
+ || parsed.deliveredRecipients.some((value) => typeof value !== 'string'))) {
695
+ throw new Error(`Invalid managed queue item at ${key}: invalid delivered recipients`);
696
+ }
697
+ if (parsed.terminalRecipients !== undefined
698
+ && (!Array.isArray(parsed.terminalRecipients)
699
+ || parsed.terminalRecipients.some((value) => typeof value !== 'string'))) {
700
+ throw new Error(`Invalid managed queue item at ${key}: invalid terminal recipients`);
701
+ }
702
+ if (parsed.schemaVersion === 2) {
703
+ if (!Array.isArray(parsed.recipientStates)
704
+ || parsed.recipientStates.some((value) => {
705
+ if (!value || typeof value !== 'object')
706
+ return true;
707
+ const state = value;
708
+ return !(typeof state.recipient === 'string'
709
+ && typeof state.normalizedRecipient === 'string'
710
+ && state.normalizedRecipient === state.recipient.trim().toLowerCase()
711
+ && ['unresolved', 'delivered', 'permanentFailure'].includes(state.state)
712
+ && Number.isFinite(state.updatedAt)
713
+ && (state.smtpCode === undefined || Number.isInteger(state.smtpCode))
714
+ && (state.smtpResponse === undefined || typeof state.smtpResponse === 'string'));
715
+ })) {
716
+ throw new Error(`Invalid managed queue item at ${key}: invalid recipient states`);
717
+ }
718
+ if (!Array.isArray(parsed.bounceOperations)
719
+ || parsed.bounceOperations.some((value) => {
720
+ if (!value || typeof value !== 'object')
721
+ return true;
722
+ const operation = value;
723
+ return !(typeof operation.operationId === 'string'
724
+ && operation.operationId.length > 0
725
+ && operation.kind === 'smtpFailure'
726
+ && typeof operation.recipient === 'string'
727
+ && typeof operation.normalizedRecipient === 'string'
728
+ && operation.normalizedRecipient === operation.recipient.trim().toLowerCase()
729
+ && Number.isInteger(operation.smtpCode)
730
+ && operation.smtpCode >= 500
731
+ && typeof operation.smtpResponse === 'string'
732
+ && ['pending', 'completed'].includes(operation.state)
733
+ && Number.isInteger(operation.attempts)
734
+ && operation.attempts >= 0
735
+ && Number.isFinite(operation.nextAttempt)
736
+ && (operation.lastError === undefined || typeof operation.lastError === 'string')
737
+ && (operation.completedAt === undefined || Number.isFinite(operation.completedAt)));
738
+ })) {
739
+ throw new Error(`Invalid managed queue item at ${key}: invalid bounce operations`);
336
740
  }
337
741
  }
338
- catch (error) {
339
- logger.log('error', `Failed to remove item ${id} from disk: ${error.message}`);
340
- this.emit('error', error);
742
+ const deliveryPhases = new Set([
743
+ 'connect',
744
+ 'greeting',
745
+ 'ehlo',
746
+ 'starttls',
747
+ 'tls_handshake',
748
+ 'post_tls_ehlo',
749
+ 'auth',
750
+ 'mail_from',
751
+ 'rcpt_to',
752
+ 'data_command',
753
+ 'message_body',
754
+ 'final_response',
755
+ 'rset',
756
+ 'quit',
757
+ 'unknown',
758
+ ]);
759
+ const isValidTimestamp = (value) => (typeof value === 'string' && Number.isFinite(Date.parse(value)));
760
+ const isValidTranscriptEntry = (value) => {
761
+ if (!value || typeof value !== 'object')
762
+ return false;
763
+ const entry = value;
764
+ return (typeof entry.timestampMs === 'number'
765
+ && Number.isFinite(entry.timestampMs)
766
+ && deliveryPhases.has(entry.phase)
767
+ && ['client', 'server', 'system'].includes(entry.direction)
768
+ && typeof entry.text === 'string'
769
+ && [...entry.text].length <= SMTP_TRANSCRIPT_MAX_ENTRY_CODE_POINTS
770
+ && (entry.responseCode === undefined
771
+ || (Number.isInteger(entry.responseCode) && entry.responseCode >= 100)));
772
+ };
773
+ const isValidTransaction = (value) => {
774
+ if (!value || typeof value !== 'object')
775
+ return false;
776
+ const transaction = value;
777
+ return (typeof transaction.id === 'string'
778
+ && transaction.id.length > 0
779
+ && transaction.queueItemId === parsed.id
780
+ && Number.isInteger(transaction.queueAttempt)
781
+ && transaction.queueAttempt >= 0
782
+ && typeof transaction.targetHost === 'string'
783
+ && transaction.targetHost.length > 0
784
+ && Number.isInteger(transaction.targetPort)
785
+ && transaction.targetPort >= 1
786
+ && transaction.targetPort <= 65_535
787
+ && (transaction.recipientDomain === undefined
788
+ || typeof transaction.recipientDomain === 'string')
789
+ && Array.isArray(transaction.recipients)
790
+ && transaction.recipients.every((recipient) => typeof recipient === 'string')
791
+ && isValidTimestamp(transaction.startedAt)
792
+ && isValidTimestamp(transaction.completedAt)
793
+ && typeof transaction.durationMs === 'number'
794
+ && Number.isFinite(transaction.durationMs)
795
+ && transaction.durationMs >= 0
796
+ && ['succeeded', 'failed'].includes(transaction.outcome)
797
+ && typeof transaction.retryable === 'boolean'
798
+ && (transaction.errorType === undefined || typeof transaction.errorType === 'string')
799
+ && (transaction.smtpCode === undefined || Number.isInteger(transaction.smtpCode))
800
+ && (transaction.recipientResults === undefined
801
+ || (Array.isArray(transaction.recipientResults)
802
+ && transaction.recipientResults.every((value) => {
803
+ if (!value || typeof value !== 'object')
804
+ return false;
805
+ const result = value;
806
+ return (typeof result.recipient === 'string'
807
+ && typeof result.accepted === 'boolean'
808
+ && Number.isInteger(result.responseCode));
809
+ })))
810
+ && (transaction.failurePhase === undefined || deliveryPhases.has(transaction.failurePhase))
811
+ && (transaction.error === undefined || typeof transaction.error === 'string')
812
+ && Array.isArray(transaction.transcript)
813
+ && transaction.transcript.length <= SMTP_TRANSCRIPT_MAX_ENTRIES
814
+ && transaction.transcript.every(isValidTranscriptEntry)
815
+ && transaction.transcript.reduce((sum, entry) => sum + Buffer.byteLength(entry.text, 'utf8'), 0) <= SMTP_TRANSCRIPT_MAX_UTF8_BYTES);
816
+ };
817
+ if (parsed.smtpTransactions !== undefined
818
+ && (!Array.isArray(parsed.smtpTransactions)
819
+ || parsed.smtpTransactions.length > 20
820
+ || parsed.smtpTransactions.some((value) => !isValidTransaction(value)))) {
821
+ throw new Error(`Invalid managed queue item at ${key}: invalid SMTP transactions`);
341
822
  }
342
- }
343
- /**
344
- * Load queue items from disk
345
- */
346
- async loadFromDisk() {
347
- try {
348
- // Check if directory exists
349
- if (!fs.existsSync(this.options.persistentPath)) {
350
- return;
823
+ const parseDate = (value, field) => {
824
+ if (!Number.isFinite(value) || value < 0) {
825
+ throw new Error(`Invalid managed queue item at ${key}: invalid ${field}`);
351
826
  }
352
- // Get all JSON files
353
- const files = fs.readdirSync(this.options.persistentPath).filter(file => file.endsWith('.json'));
354
- // Load each file
355
- for (const file of files) {
356
- try {
357
- const filePath = path.join(this.options.persistentPath, file);
358
- const data = await fs.promises.readFile(filePath, 'utf8');
359
- const item = JSON.parse(data);
360
- // Convert date strings to Date objects
361
- item.createdAt = new Date(item.createdAt);
362
- item.updatedAt = new Date(item.updatedAt);
363
- item.nextAttempt = new Date(item.nextAttempt);
364
- if (item.deliveredAt) {
365
- item.deliveredAt = new Date(item.deliveredAt);
366
- }
367
- // Add to queue
368
- this.queue.set(item.id, item);
369
- }
370
- catch (error) {
371
- logger.log('error', `Failed to load item from ${file}: ${error.message}`);
827
+ return new Date(value);
828
+ };
829
+ if (!parsed.processingResult ||
830
+ typeof parsed.processingResult !== 'object' ||
831
+ !parsed.processingResult.options ||
832
+ typeof parsed.processingResult.options !== 'object' ||
833
+ typeof parsed.processingResult.messageId !== 'string' ||
834
+ !parsed.processingResult.messageId ||
835
+ typeof parsed.processingResult.envelopeFrom !== 'string') {
836
+ throw new Error(`Invalid managed queue item at ${key}: invalid email payload`);
837
+ }
838
+ const storedOptions = parsed.processingResult.options;
839
+ if (storedOptions.attachments !== undefined) {
840
+ if (!Array.isArray(storedOptions.attachments)) {
841
+ throw new Error(`Invalid managed queue item at ${key}: invalid attachments`);
842
+ }
843
+ for (const attachment of storedOptions.attachments) {
844
+ if (!attachment || typeof attachment !== 'object' || !Buffer.isBuffer(attachment.content)) {
845
+ throw new Error(`Invalid managed queue item at ${key}: invalid attachment content`);
372
846
  }
373
847
  }
374
- // Update statistics
375
- this.updateStats();
376
- logger.log('info', `Loaded ${this.queue.size} items from disk`);
848
+ }
849
+ let processingResult;
850
+ try {
851
+ processingResult = new Email(storedOptions)
852
+ .setMessageId(parsed.processingResult.messageId)
853
+ .setEnvelopeFrom(parsed.processingResult.envelopeFrom);
377
854
  }
378
855
  catch (error) {
379
- logger.log('error', `Failed to load items from disk: ${error.message}`);
380
- throw error;
856
+ throw new Error(`Invalid managed queue item at ${key}: ${getErrorMessage(error)}`);
381
857
  }
858
+ let recipientStates;
859
+ let bounceOperations;
860
+ if (parsed.schemaVersion === 2) {
861
+ recipientStates = parsed.recipientStates.map((state) => ({
862
+ ...state,
863
+ updatedAt: parseDate(state.updatedAt, 'recipient state updatedAt'),
864
+ }));
865
+ bounceOperations = parsed.bounceOperations.map((operation) => ({
866
+ ...operation,
867
+ nextAttempt: parseDate(operation.nextAttempt, 'bounce operation nextAttempt'),
868
+ ...(operation.completedAt !== undefined
869
+ ? { completedAt: parseDate(operation.completedAt, 'bounce operation completedAt') }
870
+ : {}),
871
+ }));
872
+ }
873
+ else {
874
+ // V1 hydration deliberately starts with an empty outbox. Bounce work is
875
+ // never synthesized retroactively without a durable recipient transition.
876
+ recipientStates = this.createInitialRecipientStates(processingResult);
877
+ const delivered = new Set((parsed.deliveredRecipients || []).map((recipient) => recipient.toLowerCase()));
878
+ const terminal = new Set((parsed.terminalRecipients || []).map((recipient) => recipient.toLowerCase()));
879
+ for (const state of recipientStates) {
880
+ if (delivered.has(state.normalizedRecipient))
881
+ state.state = 'delivered';
882
+ else if (terminal.has(state.normalizedRecipient))
883
+ state.state = 'permanentFailure';
884
+ }
885
+ bounceOperations = [];
886
+ }
887
+ return {
888
+ id: parsed.id,
889
+ processingMode: parsed.processingMode,
890
+ processingResult,
891
+ ...(parsed.route ? { route: parsed.route } : {}),
892
+ status: parsed.status,
893
+ attempts: parsed.attempts,
894
+ ...(typeof parsed.lastError === 'string' ? { lastError: parsed.lastError } : {}),
895
+ createdAt: parseDate(parsed.createdAt, 'createdAt'),
896
+ updatedAt: parseDate(parsed.updatedAt, 'updatedAt'),
897
+ nextAttempt: parseDate(parsed.nextAttempt, 'nextAttempt'),
898
+ ...(parsed.deliveredAt
899
+ ? { deliveredAt: parseDate(parsed.deliveredAt, 'deliveredAt') }
900
+ : {}),
901
+ deliveredRecipients: Array.isArray(parsed.deliveredRecipients)
902
+ ? [...parsed.deliveredRecipients]
903
+ : [],
904
+ terminalRecipients: Array.isArray(parsed.terminalRecipients)
905
+ ? [...parsed.terminalRecipients]
906
+ : [],
907
+ recipientStates,
908
+ bounceOperations,
909
+ smtpTransactions: Array.isArray(parsed.smtpTransactions)
910
+ ? parsed.smtpTransactions.slice(-20).map((transaction) => ({
911
+ ...transaction,
912
+ recipients: [...transaction.recipients],
913
+ recipientResults: transaction.recipientResults?.map((result) => ({ ...result })),
914
+ transcript: normalizeSmtpTranscript(transaction.transcript),
915
+ }))
916
+ : [],
917
+ };
918
+ }
919
+ async loadFromStorage() {
920
+ const storageManager = this.options.storageManager;
921
+ if (!storageManager)
922
+ return;
923
+ const keys = (await storageManager.list(this.options.storagePrefix)).sort();
924
+ const recoveredItems = [];
925
+ for (const key of keys) {
926
+ if (!key.startsWith(this.options.storagePrefix)) {
927
+ throw new Error(`Blob storage returned a queue key outside ${this.options.storagePrefix}: ${key}`);
928
+ }
929
+ if (!key.endsWith('.json'))
930
+ continue;
931
+ const data = await storageManager.get(key);
932
+ if (!data) {
933
+ throw new Error(`Managed queue item disappeared while loading: ${key}`);
934
+ }
935
+ const item = this.deserializeItem(key, data);
936
+ if (this.queue.has(item.id)) {
937
+ throw new Error(`Duplicate managed queue item id: ${item.id}`);
938
+ }
939
+ if (this.queue.size >= this.options.maxQueueSize) {
940
+ throw new Error(`Managed queue contains more than ${this.options.maxQueueSize} items`);
941
+ }
942
+ if (item.status === 'processing') {
943
+ item.status = 'deferred';
944
+ item.nextAttempt = new Date();
945
+ item.updatedAt = new Date();
946
+ item.lastError = 'Recovered after process restart during delivery';
947
+ recoveredItems.push(item);
948
+ }
949
+ this.queue.set(item.id, item);
950
+ }
951
+ await Promise.all(recoveredItems.map((item) => this.persistItem(item)));
952
+ this.updateStats();
953
+ logger.log('info', `Loaded ${this.queue.size} items from managed blob storage; recovered ${recoveredItems.length} interrupted item(s)`);
382
954
  }
383
955
  /**
384
956
  * Update queue statistics
@@ -428,7 +1000,7 @@ export class UnifiedDeliveryQueue extends EventEmitter {
428
1000
  // Set processing active
429
1001
  this.stats.processingActive = this.processing;
430
1002
  // Emit statistics event
431
- this.emit('statsUpdated', this.stats);
1003
+ void emitSafely(this, 'statsUpdated', this.stats);
432
1004
  }
433
1005
  /**
434
1006
  * Get queue statistics
@@ -440,6 +1012,7 @@ export class UnifiedDeliveryQueue extends EventEmitter {
440
1012
  * Pause queue processing
441
1013
  */
442
1014
  pause() {
1015
+ this.assertMutable();
443
1016
  if (this.processing) {
444
1017
  this.stopProcessing();
445
1018
  logger.log('info', 'Queue processing paused');
@@ -449,6 +1022,7 @@ export class UnifiedDeliveryQueue extends EventEmitter {
449
1022
  * Resume queue processing
450
1023
  */
451
1024
  resume() {
1025
+ this.assertMutable();
452
1026
  if (!this.processing) {
453
1027
  this.startProcessing();
454
1028
  logger.log('info', 'Queue processing resumed');
@@ -459,11 +1033,15 @@ export class UnifiedDeliveryQueue extends EventEmitter {
459
1033
  * @param maxAge Maximum age in milliseconds (default: 7 days)
460
1034
  */
461
1035
  async cleanupOldItems(maxAge = 7 * 24 * 60 * 60 * 1000) {
1036
+ this.assertMutable();
462
1037
  const cutoff = new Date(Date.now() - maxAge);
463
1038
  // Collect IDs first to avoid modifying the Map during iteration
464
1039
  const idsToRemove = [];
465
1040
  for (const item of this.queue.values()) {
466
- if (['delivered', 'failed'].includes(item.status) && item.updatedAt < cutoff) {
1041
+ const hasPendingBounceWork = (item.bounceOperations || []).some((operation) => operation.state !== 'completed');
1042
+ if (['delivered', 'failed'].includes(item.status)
1043
+ && item.updatedAt < cutoff
1044
+ && !hasPendingBounceWork) {
467
1045
  idsToRemove.push(item.id);
468
1046
  }
469
1047
  }
@@ -480,25 +1058,34 @@ export class UnifiedDeliveryQueue extends EventEmitter {
480
1058
  * Shutdown the queue
481
1059
  */
482
1060
  async shutdown() {
1061
+ if (this.lifecycleState === 'closed')
1062
+ return;
483
1063
  logger.log('info', 'Shutting down UnifiedDeliveryQueue');
484
- // Stop processing (clears both check and cleanup timers)
485
- this.stopProcessing();
486
- // If using disk storage, make sure all items are persisted
487
- if (this.options.storageType === 'disk') {
488
- const pendingWrites = [];
489
- for (const item of this.queue.values()) {
490
- pendingWrites.push(this.persistItem(item));
1064
+ this.lifecycleState = 'shutting-down';
1065
+ let persistenceError;
1066
+ try {
1067
+ // Stop processing (clears both check and cleanup timers).
1068
+ this.stopProcessing();
1069
+ if (this.options.storageManager) {
1070
+ await Promise.all([...this.queue.values()].map((item) => this.persistItem(item)));
491
1071
  }
492
- // Wait for all writes to complete
493
- await Promise.all(pendingWrites);
494
1072
  }
495
- // Clear the queue (memory only)
496
- this.queue.clear();
497
- // Update statistics
498
- this.updateStats();
499
- // Emit shutdown event
500
- this.emit('shutdown');
1073
+ catch (error) {
1074
+ // Preserve the original persistence failure; observer diagnostics are
1075
+ // isolated and can never replace it.
1076
+ persistenceError = error;
1077
+ logger.log('error', `Failed to persist delivery queue during shutdown: ${error.message}`);
1078
+ }
1079
+ finally {
1080
+ this.queue.clear();
1081
+ this.updateStats();
1082
+ await emitSafely(this, 'shutdown');
1083
+ this.lifecycleState = 'closed';
1084
+ this.releaseManagedPrefix();
1085
+ }
1086
+ if (persistenceError)
1087
+ throw persistenceError;
501
1088
  logger.log('info', 'UnifiedDeliveryQueue shut down successfully');
502
1089
  }
503
1090
  }
504
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5kZWxpdmVyeS5xdWV1ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL21haWwvZGVsaXZlcnkvY2xhc3Nlcy5kZWxpdmVyeS5xdWV1ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDM0MsT0FBTyxLQUFLLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDOUIsT0FBTyxLQUFLLElBQUksTUFBTSxXQUFXLENBQUM7QUFDbEMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFBNEIsTUFBTSxpQkFBaUIsQ0FBQztBQW9FM0Q7O0dBRUc7QUFDSCxNQUFNLE9BQU8sb0JBQXFCLFNBQVEsWUFBWTtJQUM1QyxPQUFPLENBQTBCO0lBQ2pDLEtBQUssR0FBNEIsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUMzQyxVQUFVLENBQWtCO0lBQzVCLFlBQVksQ0FBa0I7SUFDOUIsS0FBSyxDQUFjO0lBQ25CLFVBQVUsR0FBWSxLQUFLLENBQUM7SUFDNUIsY0FBYyxHQUFXLENBQUMsQ0FBQztJQUVuQzs7O09BR0c7SUFDSCxZQUFZLE9BQXNCO1FBQ2hDLEtBQUssRUFBRSxDQUFDO1FBRVIsc0JBQXNCO1FBQ3RCLElBQUksQ0FBQyxPQUFPLEdBQUc7WUFDYixXQUFXLEVBQUUsT0FBTyxDQUFDLFdBQVcsSUFBSSxRQUFRO1lBQzVDLGNBQWMsRUFBRSxPQUFPLENBQUMsY0FBYyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLGFBQWEsQ0FBQztZQUNqRixhQUFhLEVBQUUsT0FBTyxDQUFDLGFBQWEsSUFBSSxLQUFLLEVBQUUsYUFBYTtZQUM1RCxZQUFZLEVBQUUsT0FBTyxDQUFDLFlBQVksSUFBSSxLQUFLO1lBQzNDLGlC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
1091
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5kZWxpdmVyeS5xdWV1ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL21haWwvZGVsaXZlcnkvY2xhc3Nlcy5kZWxpdmVyeS5xdWV1ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDekMsT0FBTyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFakQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFBNEIsTUFBTSxpQkFBaUIsQ0FBQztBQUUzRCxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLDJCQUEyQixFQUMzQixxQ0FBcUMsRUFDckMsOEJBQThCLEdBQy9CLE1BQU0sOENBQThDLENBQUM7QUFFdEQsT0FBTyxFQUFFLEtBQUssRUFBc0IsTUFBTSwwQkFBMEIsQ0FBQztBQUNyRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBd0k1RDs7R0FFRztBQUNILFNBQVMsc0JBQXNCLENBQUMsU0FBUyxHQUFHLGVBQWU7SUFDekQsSUFDRSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDO1FBQzFCLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7UUFDeEIsU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7UUFDeEIsU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFDeEIsQ0FBQztRQUNELE1BQU0sSUFBSSxLQUFLLENBQUMsZ0VBQWdFLENBQUMsQ0FBQztJQUNwRixDQUFDO0lBQ0QsTUFBTSxRQUFRLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUs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