@serve.zone/dcrouter 18.1.1 → 18.2.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.
@@ -77,6 +77,27 @@ export declare class AcceptedEmailSpool {
77
77
  private smtpTransactionListeners;
78
78
  private emailQueuePersistedListeners;
79
79
  constructor(dcRouterRef: DcRouter);
80
+ /**
81
+ * Direction is decided by the RECIPIENT, never by whether the session
82
+ * authenticated. Authentication grants permission to relay; it does not make
83
+ * a message addressed to a mailbox we host into outbound mail. A message with
84
+ * at least one locally hosted recipient is inbound — a local mailbox receives
85
+ * it — and only an envelope addressed exclusively to remote recipients is
86
+ * outbound.
87
+ *
88
+ * `IResolvedRecipientRoute.localDomain` is smartmta's own per-recipient
89
+ * verdict (non-null exactly when the domain registry hosts the domain), so
90
+ * the classification uses the same truth the routing decision used. When an
91
+ * acceptance context carries no resolution the envelope recipients are
92
+ * classified against the live registry instead — never against the session,
93
+ * which is the mistake being fixed.
94
+ */
95
+ private deriveDirectionFromResolvedRoutes;
96
+ /**
97
+ * Recipient-derived direction for programmatic submitters, which have no SMTP
98
+ * recipient resolution to consult. Falls back to the live domain registry.
99
+ */
100
+ private deriveDirectionFromRecipients;
80
101
  acceptMessage(context: IMessageAcceptanceContext, processAfterAccept?: boolean): Promise<IMessageAcceptanceDecision>;
81
102
  acceptRawMessage(optionsArg: IAcceptRawEmailOptions): Promise<IMessageAcceptanceDecision & {
82
103
  spoolItemId: string;
@@ -88,6 +109,49 @@ export declare class AcceptedEmailSpool {
88
109
  * exact-plan executor. Store recipients are fulfilled by the anchor itself.
89
110
  */
90
111
  acceptEnvelope(context: IAcceptEnvelopeContext, emailServer: UnifiedEmailServer): Promise<void>;
112
+ /**
113
+ * Session metadata for `dispatchAcceptedEnvelope`. It feeds the per-recipient
114
+ * idempotency fingerprint, so it must be JSON-round-trip stable: a replay
115
+ * reconstructed from persisted state has to produce byte-identical metadata
116
+ * or upstream refuses it as an idempotency-key reuse.
117
+ */
118
+ private buildEnvelopeDispatchMetadata;
119
+ /**
120
+ * Dispatch (or redispatch) the non-store recipients of a durably accepted
121
+ * envelope.
122
+ *
123
+ * The raw bytes handed to upstream are the exact bytes persisted for this row,
124
+ * because upstream fingerprints every recipient over the raw message: a later
125
+ * replay with different bytes would be rejected as an idempotency-key reuse
126
+ * rather than retried. Recipients that already succeeded are short-circuited
127
+ * by upstream's checkpoints, and `failed` results are deliberately not
128
+ * checkpointed upstream, so an identical replay retries exactly those.
129
+ *
130
+ * A `failed` recipient leaves the row non-terminal so the spool retries it;
131
+ * a `rejected` recipient is a permanent per-recipient refusal and is recorded
132
+ * durably instead of being retried. Either way the outcome is persisted — a
133
+ * relay recipient is never silently dropped after the SMTP 250.
134
+ */
135
+ private dispatchEnvelopeRecipients;
136
+ /**
137
+ * Persist a dispatch attempt's outcome on the durable-envelope row.
138
+ *
139
+ * The row's status tracks the stored envelope, not the relay: it goes
140
+ * `deferred` only while relay recipients still need a redispatch, and returns
141
+ * to its acceptance status once none do. Relay progress itself lives in
142
+ * `routeData.envelopeDispatch`, so a relay failure can never mark a row whose
143
+ * local copy stored successfully as failed.
144
+ */
145
+ private persistEnvelopeDispatchOutcome;
146
+ /**
147
+ * Take exclusive ownership of a durably accepted envelope row in the spool.
148
+ *
149
+ * Runs before live-queue postponement and before the normal spool handoff: a
150
+ * relay sibling that did enqueue would otherwise postpone this row forever,
151
+ * and the normal handoff would re-run route evaluation and duplicate a
152
+ * delivery the stored copy already fulfilled.
153
+ */
154
+ private handleDurableEnvelopeRow;
91
155
  private trackAcceptedInboundEmail;
92
156
  /**
93
157
  * Synthesizes the inbound SMTP transaction for the email log from the
@@ -132,6 +196,8 @@ export declare class AcceptedEmailSpool {
132
196
  private clearSpoolTimer;
133
197
  private setDcRouterCacheIdHeader;
134
198
  private isCachedEmailTerminal;
199
+ /** Whether this row was durably accepted through the envelope acceptance path. */
200
+ private isDurableEnvelopeRow;
135
201
  /** The CachedEmail row a live queue item was spooled from (via the cache-id header). */
136
202
  getCachedEmailIdFromQueueItem(item: TSmartMtaQueueItemLike): string | undefined;
137
203
  private postponeLiveSmartMtaOwnedEmail;