Skip to content
Corven Email SDK
Esc
↑↓navigate↵open⌘Jpreview
On this page

Submission observations

Observe minimal starting and settled sender-call facts without capturing private payloads.

Use observedEmailSenderLayer from @corven/email-sdk/observations around an EmailSender, then build the common Email service:

import { Effect, Layer } from "effect";
import { Email, emailLayer } from "@corven/email-sdk";
import type { EmailMessageInput } from "@corven/email-sdk";
import {
  EmailSubmissionObservations,
  observedEmailSenderLayer,
} from "@corven/email-sdk/observations";
import type {
  EmailSubmissionObserver,
  EmailSubmissionStartingObserver,
} from "@corven/email-sdk/observations";
import { recordingSenderLayer } from "@corven/email-sdk/testing";

export const submitAndInspectSyntheticEmail = Effect.fnUntraced(
  function* submitAndInspectSyntheticEmail(message: EmailMessageInput) {
    const email = yield* Email;
    const observations = yield* EmailSubmissionObservations;
    const receipt = yield* email.send(message);
    const snapshot = yield* observations.snapshot;

    return { receipt, snapshot };
  },
);

export const observedSyntheticEmailLayer = (
  observer: EmailSubmissionObserver,
  startingObserver?: EmailSubmissionStartingObserver,
) =>
  emailLayer().pipe(
    Layer.provideMerge(
      observedEmailSenderLayer(recordingSenderLayer, { capacity: 10 }, observer, startingObserver),
    ),
  );

Layer.provideMerge keeps the observation query service available alongside sending. Acquire both from the same composed Layer.

Read the view

EmailSubmissionObservations.snapshot returns retained observations and truncated. Settled cases are Receipt, Rejected and Unknown. A receipt observation includes only its kind and provider; it does not retain recipients, message content, keys or original private causes.

The optional starting callback describes a sender invocation. It is a separate event from settled history, not evidence that the provider accepted a message.

Choose the correct unit

A sender call is not necessarily a whole logical workflow, an audience or a lifetime delivery count. Local validation can fail before this observation boundary. For complete prepared-operation outcomes, use operation observations; for Loops/Iterable use native instrumentation.

Callbacks are awaited Effects. A callback failure can stop the caller’s workflow, but cannot roll back a provider acknowledgment or authorize retry/fallback. Treat missing data and truncated history as incomplete evidence.