/** * Effect v4 bindings for evlog wide events. * * The core idea: one evlog logger instance per unit of work (request, job, * script run), exposed as an Effect service. Context accumulates via `set` * during the work; the wide event is emitted exactly once when the unit of * work completes — including on failure and interruption, with error context * extracted from the Effect `Cause`. */ import type { Exit, Scope } from "effect"; import { Context, Effect } from "effect"; import * as Layer from "effect/Layer"; import type { AuditableLogger, FieldContext, LogLevel as EvlogLevel, RequestLoggerOptions, WideEvent as WideEventData } from "evlog"; /** * The shape of the wide-event service. All methods are thin effectful * wrappers over a single mutable evlog logger instance scoped to the * current unit of work. */ export interface WideEventService { /** * Merge fields into the wide event. Plain objects merge recursively, * arrays concatenate (evlog semantics). */ readonly set: (fields: FieldContext) => Effect.Effect; /** * Promote the event level without touching the `error` field. * Wins over levels derived from `.error()` / `.warn()`. */ readonly setLevel: (level: EvlogLevel) => Effect.Effect; /** Capture an informational message inside the wide event. */ readonly info: (message: string, fields?: FieldContext) => Effect.Effect; /** Capture a warning inside the wide event and promote the level. */ readonly warn: (message: string, fields?: FieldContext) => Effect.Effect; /** Capture an error inside the wide event and promote the level. */ readonly error: (error: Error | string, fields?: FieldContext) => Effect.Effect; /** Read the accumulated context so far. */ readonly getContext: Effect.Effect>; /** * Manually emit and seal the wide event. Normally you never call this — * the scope/`onExit` finalizer emits for you. Escape hatch for advanced * lifecycles. Returns the emitted event, or `null` if sampled out. */ readonly emit: (overrides?: FieldContext) => Effect.Effect; /** * The raw evlog logger. For synchronous interop (e.g. the Effect `Logger` * bridge) and evlog APIs not wrapped here (audit, fork). */ readonly unsafe: AuditableLogger; } declare const WideEvent_base: Context.ServiceClass; /** * Service key for the wide event of the current unit of work. * * v4 note: `Context.Service()("id")` replaces v3's * `Context.Tag("id")()`. */ export declare class WideEvent extends WideEvent_base { } /** Wrap a raw evlog logger instance as a `WideEventService`. */ export declare const fromLogger: (log: AuditableLogger) => WideEventService; /** * Record the outcome of a unit of work on the wide event, then emit it. * * - Failure: first error goes through `log.error` (sets `error` field + * promotes level); additional concurrent/sequential failures merge in * under `error.additional`. * - Interruption (with no failures): marked `outcome: "interrupted"` at * `warn` level. * - Success: emitted as-is. * * evlog seals the logger after `emit`, so late `set` calls from leaked * fibers surface as `[evlog]` console warnings rather than silent loss. */ export declare const finalize: (log: AuditableLogger, exit: Exit.Exit) => void; /** * Acquire a wide event bound to the current `Scope`: the event is emitted * when the scope closes, with the scope's exit recorded on it. */ export declare const acquire: (make: () => AuditableLogger) => Effect.Effect; /** * Run an effect as its own unit of work: a fresh wide event is created, * provided as the `WideEvent` service, and emitted when the effect * succeeds, fails, or is interrupted. * * This is the Effect-native equivalent of evlog's framework middleware, * and the recommended entry point for jobs, scripts, and handlers: * * ```ts * const job = Effect.gen(function* () { * const log = yield* WideEvent * yield* log.set({ found: users.length }) * // ... * yield* log.set({ migrated, status: "complete" }) * }) * * await Effect.runPromise(job.pipe(withWideEvent({ task: "user-migration" }))) * // one wide event emitted, success or failure * ``` * * Deliberately implemented with `onExit` rather than a `Layer`, so each * invocation gets a fresh logger — see the note on `layer` about v4's * cross-provide layer memoization. */ export declare const withWideEvent: (initialContext?: Record) => (self: Effect.Effect) => Effect.Effect>; /** * Like `withWideEvent`, but pre-populates HTTP fields (`method`, `path`, * `requestId`) via evlog's `createRequestLogger`. Use inside HTTP server * middleware: * * ```ts * import { HttpMiddleware, HttpServerRequest } from "effect/unstable/http" * * const evlogMiddleware = HttpMiddleware.make((app) => * Effect.gen(function* () { * const request = yield* HttpServerRequest.HttpServerRequest * return yield* app.pipe( * withRequestWideEvent({ method: request.method, path: request.url }) * ) * }) * ) * ``` */ export declare const withRequestWideEvent: (options?: RequestLoggerOptions) => (self: Effect.Effect) => Effect.Effect>; /** * Layer form: the wide event lives for the lifetime of the layer's scope * and is emitted when that scope closes. Useful when a whole layered * program *is* the unit of work (a script, a CLI invocation). * * v4 caveat: layers are memoized **across** `Effect.provide` calls in v4. * A module-level `const Live = layer()` provided around two different * requests would share one wide event. `Layer.fresh` is applied here so * each composition gets its own event — but for per-request use, prefer * `withWideEvent` / `withRequestWideEvent`. */ export declare const layer: (initialContext?: Record) => Layer.Layer; /** Layer form of `withRequestWideEvent`. Same memoization caveat as `layer`. */ export declare const layerRequest: (options?: RequestLoggerOptions) => Layer.Layer; /** * Convenience accessors: `set`/`info`/`warn`/`error` against the current * wide event without yielding the service first. * * ```ts * yield* annotate({ cart: { items: 3, total: 9999 } }) * ``` */ export declare const annotate: (fields: FieldContext) => Effect.Effect; export {}; //# sourceMappingURL=WideEvent.d.ts.map