1/**
2 * The `References` module exposes the built-in `Context.Reference` keys that
3 * the Effect runtime consults for execution settings and diagnostic metadata.
4 * These references cover concurrency, scheduling, logging, tracing, and
5 * low-level diagnostic state.
6 *
7 * A `Context.Reference<A>` is a service key with a default value. Reading one
8 * of these references returns the value from the current fiber context, and
9 * providing a new value changes behavior for the provided effect and the fibers
10 * it starts.
11 *
12 * @since 4.0.0
13 */
14import type * as Context from "./Context.ts"
15import * as internalEffect from "./internal/effect.ts"
16import * as references from "./internal/references.ts"
17import type { Logger } from "./Logger.ts"
18import type { LogLevel, Severity } from "./LogLevel.ts"
19import type { ReadonlyRecord } from "./Record.ts"
20import { MaxOpsBeforeYield, PreventSchedulerYield } from "./Scheduler.ts"
21import { CurrentTraceLevel, DisablePropagation, MinimumTraceLevel, type SpanLink, Tracer } from "./Tracer.ts"
22
23export {
24 /**
25 * Context reference for the current trace level used for dynamic trace filtering.
26 *
27 * **When to use**
28 *
29 * Use to set the default trace level for spans created in a scope when span
30 * options do not provide `level`.
31 *
32 * @see {@link MinimumTraceLevel} for configuring the threshold that decides whether spans at a given level are sampled or exported
33 *
34 * @category references
35 * @since 4.0.0
36 */
37 CurrentTraceLevel,
38 /**
39 * Context reference for disabling trace propagation in the current context.
40 *
41 * **When to use**
42 *
43 * Use to mark tracing work as non-propagating while still allowing local span
44 * tracking.
45 *
46 * **Details**
47 *
48 * Annotated spans become non-propagating no-op spans, and parent selection
49 * skips spans marked with disabled propagation.
50 *
51 * @see {@link TracerEnabled} for disabling span registration instead of only propagation
52 *
53 * @category references
54 * @since 4.0.0
55 */
56 DisablePropagation,
57 /**
58 * Context reference for the maximum operation budget before a fiber yields to the scheduler.
59 *
60 * **When to use**
61 *
62 * Use to configure the runtime reference for the fiber operation budget that
63 * triggers a scheduler yield.
64 *
65 * **Details**
66 *
67 * The default value is `2048` operations.
68 *
69 * @see {@link PreventSchedulerYield} for bypassing scheduler yield checks instead of changing the operation budget
70 *
71 * @category references
72 * @since 4.0.0
73 */
74 MaxOpsBeforeYield,
75 /**
76 * Context reference for the minimum trace level threshold for span sampling.
77 *
78 * **When to use**
79 *
80 * Use to set the trace-level threshold that decides whether newly created
81 * spans are sampled and exported.
82 *
83 * @see {@link CurrentTraceLevel} for setting the level assigned to spans before this threshold is applied
84 *
85 * @category references
86 * @since 4.0.0
87 */
88 MinimumTraceLevel,
89 /**
90 * Context reference for whether the runtime bypasses scheduler yield checks.
91 *
92 * **When to use**
93 *
94 * Use to bypass automatic scheduler yield checks in a controlled runtime scope
95 * where throughput is preferred over scheduler fairness.
96 *
97 * **Details**
98 *
99 * When set to `true`, the fiber run loop skips `Scheduler.shouldYield`. The
100 * default value is `false`.
101 *
102 * **Gotchas**
103 *
104 * Disabling automatic yield checks can let long-running fibers monopolize the
105 * JavaScript thread.
106 *
107 * @see {@link MaxOpsBeforeYield} for tuning the operation budget while keeping scheduler yield checks enabled
108 *
109 * @category references
110 * @since 4.0.0
111 */
112 PreventSchedulerYield,
113 /**
114 * Context reference for the active tracer service used to create spans.
115 *
116 * **When to use**
117 *
118 * Use to access or override the active tracer service through the references
119 * module when working directly with Effect runtime references.
120 *
121 * @category references
122 * @since 4.0.0
123 */
124 Tracer
125}
126
127/**
128 * Context reference for managing log annotations that are automatically added to all log entries.
129 * These annotations provide contextual metadata that appears in every log message.
130 *
131 * **When to use**
132 *
133 * Use to attach shared contextual metadata to every log entry emitted in the
134 * current context.
135 *
136 * **Example** (Managing log annotations)
137 *
138 * ```ts import.meta.vitest
139 * import { Effect, References } from "effect"
140 *
141 * const logAnnotationExample = Effect.gen(function*() {
142 * // Get current annotations (empty by default)
143 * const current = yield* References.CurrentLogAnnotations
144 * const defaultCount = Object.keys(current).length
145 *
146 * // Run with custom log annotations
147 * const custom = yield* Effect.provideService(
148 * Effect.gen(function*() {
149 * const annotations = yield* References.CurrentLogAnnotations
150 * return [annotations.requestId, annotations.userId, annotations.version]
151 * }),
152 * References.CurrentLogAnnotations,
153 * {
154 * requestId: "req-123",
155 * userId: "user-456",
156 * version: "1.0.0"
157 * }
158 * )
159 *
160 * // Run with extended annotations
161 * const extended = yield* Effect.provideService(
162 * Effect.gen(function*() {
163 * const annotations = yield* References.CurrentLogAnnotations
164 * return [annotations.operation, annotations.timestamp]
165 * }),
166 * References.CurrentLogAnnotations,
167 * {
168 * requestId: "req-123",
169 * userId: "user-456",
170 * version: "1.0.0",
171 * operation: "data-sync",
172 * timestamp: 1234567890
173 * }
174 * )
175 *
176 * return [defaultCount, custom, extended]
177 * })
178 *
179 * await Effect.runPromise(logAnnotationExample) // => [0, ["req-123", "user-456", "1.0.0"], ["data-sync", 1234567890]]
180 * ```
181 *
182 * @category references
183 * @since 4.0.0
184 */
185export const CurrentLogAnnotations: Context.Reference<ReadonlyRecord<string, unknown>> =
186 references.CurrentLogAnnotations
187
188/**
189 * Context reference for the current log severity used by `Effect.log` when no explicit
190 * level is provided.
191 *
192 * **When to use**
193 *
194 * Use to set the default severity for `Effect.log` entries that do not provide
195 * an explicit level.
196 *
197 * **Details**
198 *
199 * Use `MinimumLogLevel` to control which log entries are filtered out.
200 *
201 * **Example** (Changing the level of an unqualified log)
202 *
203 * ```ts import.meta.vitest
204 * import { Effect, Logger, References } from "effect"
205 *
206 * const levels: Array<string> = []
207 * const logger = Logger.make<unknown, void>(({ logLevel }) => {
208 * levels.push(logLevel)
209 * })
210 *
211 * const program = Effect.gen(function*() {
212 * yield* Effect.log("uses the default level")
213 * yield* Effect.log("uses the provided level").pipe(
214 * Effect.provideService(References.CurrentLogLevel, "Error")
215 * )
216 * })
217 *
218 * await Effect.runPromise(program.pipe(Effect.provide(Logger.layer([logger]))))
219 * levels // => ["Info", "Error"]
220 * ```
221 *
222 * @category references
223 * @since 4.0.0
224 */
225export const CurrentLogLevel: Context.Reference<Severity> = references.CurrentLogLevel
226
227/**
228 * Context reference for managing log spans that track the duration and hierarchy of operations.
229 * Each span represents a labeled time period for performance analysis and debugging.
230 *
231 * **When to use**
232 *
233 * Use to carry the active log span stack that should be included with log
234 * entries in the current context.
235 *
236 * **Example** (Tracking log spans)
237 *
238 * ```ts import.meta.vitest
239 * import { Effect, References } from "effect"
240 *
241 * const logSpanExample = Effect.gen(function*() {
242 * // Get current spans (empty by default)
243 * const current = yield* References.CurrentLogSpans
244 * const defaultCount = current.length
245 *
246 * // Add a log span manually
247 * const databaseConnectionStartedAt = 0
248 * const database = yield* Effect.provideService(
249 * Effect.gen(function*() {
250 * const spans = yield* References.CurrentLogSpans
251 * return spans.map(([label]) => label)
252 * }),
253 * References.CurrentLogSpans,
254 * [["database-connection", databaseConnectionStartedAt]]
255 * )
256 *
257 * // Add another span
258 * const dataProcessingStartedAt = 100
259 * const processing = yield* Effect.provideService(
260 * Effect.gen(function*() {
261 * const spans = yield* References.CurrentLogSpans
262 * return spans.map(([label]) => label)
263 * }),
264 * References.CurrentLogSpans,
265 * [
266 * ["database-connection", databaseConnectionStartedAt],
267 * ["data-processing", dataProcessingStartedAt]
268 * ]
269 * )
270 *
271 * // Clear spans when operations complete
272 * const cleared = yield* Effect.provideService(
273 * Effect.gen(function*() {
274 * const spans = yield* References.CurrentLogSpans
275 * return spans.length
276 * }),
277 * References.CurrentLogSpans,
278 * []
279 * )
280 *
281 * return [defaultCount, database, processing, cleared]
282 * })
283 *
284 * await Effect.runPromise(logSpanExample) // => [0, ["database-connection"], ["database-connection", "data-processing"], 0]
285 * ```
286 *
287 * @category references
288 * @since 4.0.0
289 */
290export const CurrentLogSpans: Context.Reference<ReadonlyArray<[label: string, timestamp: number]>> =
291 references.CurrentLogSpans
292
293/**
294 * Context reference for the current captured stack-frame chain for the running
295 * fiber.
296 *
297 * **When to use**
298 *
299 * Use when writing low-level tracing or diagnostic integrations that need direct
300 * access to the stack-frame chain carried by the current fiber.
301 *
302 * **Details**
303 *
304 * Effect and Layer tracing use this reference to attach stack-frame information
305 * to failures and interruption causes. It is normally managed by tracing APIs
306 * rather than provided directly by application code.
307 *
308 * @see {@link StackFrame} for the frame node stored in this reference
309 *
310 * @category references
311 * @since 4.0.0
312 */
313export const CurrentStackFrame: Context.Reference<StackFrame | undefined> = references.CurrentStackFrame
314
315/**
316 * Context reference for setting the minimum log level threshold. Log entries below this
317 * level will be filtered out completely.
318 *
319 * **When to use**
320 *
321 * Use to filter out log entries below a severity threshold.
322 *
323 * **Example** (Filtering logs below the minimum level)
324 *
325 * ```ts import.meta.vitest
326 * import { Effect, Logger, References } from "effect"
327 *
328 * const levels: Array<string> = []
329 * const logger = Logger.make<unknown, void>(({ logLevel }) => {
330 * levels.push(logLevel)
331 * })
332 *
333 * const program = Effect.gen(function*() {
334 * yield* Effect.logInfo("filtered out")
335 * yield* Effect.logWarning("included at the threshold")
336 * yield* Effect.logError("included above the threshold")
337 * })
338 *
339 * await Effect.runPromise(program.pipe(
340 * Effect.provideService(References.MinimumLogLevel, "Warn"),
341 * Effect.provide(Logger.layer([logger]))
342 * ))
343 * levels // => ["Warn", "Error"]
344 * ```
345 *
346 * @category references
347 * @since 4.0.0
348 */
349export const MinimumLogLevel: Context.Reference<LogLevel> = references.MinimumLogLevel
350
351/**
352 * Context reference for controlling whether tracing is enabled globally. When set to false,
353 * spans will not be registered with the tracer and tracing overhead is minimized.
354 *
355 * **When to use**
356 *
357 * Use to disable or re-enable span registration in the current context.
358 *
359 * **Example** (Toggling tracing)
360 *
361 * ```ts import.meta.vitest
362 * import { Effect, References } from "effect"
363 *
364 * const tracingControl = Effect.gen(function*() {
365 * // Check if tracing is enabled (default is true)
366 * const current = yield* References.TracerEnabled
367 *
368 * // Disable tracing globally
369 * const disabled = yield* Effect.provideService(
370 * References.TracerEnabled,
371 * References.TracerEnabled,
372 * false
373 * )
374 *
375 * // Re-enable tracing
376 * const enabled = yield* Effect.provideService(
377 * References.TracerEnabled,
378 * References.TracerEnabled,
379 * true
380 * )
381 *
382 * return [current, disabled, enabled]
383 * })
384 *
385 * await Effect.runPromise(tracingControl) // => [true, false, true]
386 * ```
387 *
388 * @category references
389 * @since 4.0.0
390 */
391export const TracerEnabled: Context.Reference<boolean> = references.TracerEnabled
392
393/**
394 * Context reference for managing span annotations that are automatically added to all new spans.
395 * These annotations provide context and metadata that applies across multiple spans.
396 *
397 * **When to use**
398 *
399 * Use to attach shared metadata to every span created in the current context.
400 *
401 * **Example** (Managing span annotations)
402 *
403 * ```ts import.meta.vitest
404 * import { Effect, References } from "effect"
405 *
406 * const spanAnnotationExample = Effect.gen(function*() {
407 * // Get current annotations (empty by default)
408 * const current = yield* References.TracerSpanAnnotations
409 * const defaultCount = Object.keys(current).length
410 *
411 * // Set global span annotations
412 * const configured = yield* Effect.provideService(
413 * Effect.gen(function*() {
414 * // Get current annotations
415 * const annotations = yield* References.TracerSpanAnnotations
416 * return [annotations.service, annotations.version, annotations.environment]
417 * }),
418 * References.TracerSpanAnnotations,
419 * {
420 * service: "user-service",
421 * version: "1.2.3",
422 * environment: "production"
423 * }
424 * )
425 *
426 * // Clear annotations
427 * const cleared = yield* Effect.provideService(
428 * Effect.gen(function*() {
429 * const annotations = yield* References.TracerSpanAnnotations
430 * return Object.keys(annotations).length
431 * }),
432 * References.TracerSpanAnnotations,
433 * {}
434 * )
435 *
436 * return [defaultCount, configured, cleared]
437 * })
438 *
439 * await Effect.runPromise(spanAnnotationExample) // => [0, ["user-service", "1.2.3", "production"], 0]
440 * ```
441 *
442 * @category references
443 * @since 4.0.0
444 */
445export const TracerSpanAnnotations: Context.Reference<ReadonlyRecord<string, unknown>> =
446 references.TracerSpanAnnotations
447
448/**
449 * Context reference for managing span links that are automatically added to all new spans.
450 * Span links connect related spans that are not in a parent-child relationship.
451 *
452 * **When to use**
453 *
454 * Use to attach shared links to every span created in the current context.
455 *
456 * **Example** (Managing span links)
457 *
458 * ```ts import.meta.vitest
459 * import { Effect, References, Tracer } from "effect"
460 *
461 * const spanLinksExample = Effect.gen(function*() {
462 * // Get current links (empty by default)
463 * const current = yield* References.TracerSpanLinks
464 * const defaultCount = current.length
465 *
466 * // Create an external span for the example
467 * const externalSpan = Tracer.externalSpan({
468 * spanId: "external-span-123",
469 * traceId: "trace-456"
470 * })
471 *
472 * // Create span links
473 * const spanLink: Tracer.SpanLink = {
474 * span: externalSpan,
475 * attributes: {
476 * relationship: "follows-from",
477 * priority: "high"
478 * }
479 * }
480 *
481 * // Set global span links
482 * const configuredCount = yield* Effect.provideService(
483 * Effect.map(References.TracerSpanLinks, (links) => links.length),
484 * References.TracerSpanLinks,
485 * [spanLink]
486 * )
487 *
488 * // Clear links
489 * const clearedCount = yield* Effect.provideService(
490 * Effect.map(References.TracerSpanLinks, (links) => links.length),
491 * References.TracerSpanLinks,
492 * []
493 * )
494 *
495 * return [defaultCount, configuredCount, clearedCount]
496 * })
497 *
498 * await Effect.runPromise(spanLinksExample) // => [0, 1, 0]
499 * ```
500 *
501 * @category references
502 * @since 4.0.0
503 */
504export const TracerSpanLinks: Context.Reference<ReadonlyArray<SpanLink>> = references.TracerSpanLinks
505
506/**
507 * Context reference for controlling whether trace timing is enabled globally. When set
508 * to false, spans will not contain timing information (trace time will always
509 * be set to zero).
510 *
511 * **When to use**
512 *
513 * Use to disable or re-enable timing capture for spans in the current context.
514 *
515 * **Example** (Toggling trace timing)
516 *
517 * ```ts import.meta.vitest
518 * import { Effect, References } from "effect"
519 *
520 * const tracingControl = Effect.gen(function*() {
521 * // Check if trace timing is enabled (default is true)
522 * const current = yield* References.TracerTimingEnabled
523 *
524 * // Disable trace timing globally
525 * const disabled = yield* Effect.provideService(
526 * References.TracerTimingEnabled,
527 * References.TracerTimingEnabled,
528 * false
529 * )
530 *
531 * // Re-enable trace timing
532 * const enabled = yield* Effect.provideService(
533 * References.TracerTimingEnabled,
534 * References.TracerTimingEnabled,
535 * true
536 * )
537 *
538 * return [current, disabled, enabled]
539 * })
540 *
541 * await Effect.runPromise(tracingControl) // => [true, false, true]
542 * ```
543 *
544 * @category references
545 * @since 4.0.0
546 */
547export const TracerTimingEnabled: Context.Reference<boolean> = references.TracerTimingEnabled
548
549/**
550 * Context reference for the log severity used when a pool finalizer reports an
551 * unhandled error.
552 *
553 * **When to use**
554 *
555 * Use to choose whether and at which severity pool finalizer failures are
556 * reported.
557 *
558 * **Details**
559 *
560 * The default level is `"Error"`.
561 *
562 * **Gotchas**
563 *
564 * Providing `undefined` suppresses this report; it does not fall back to
565 * `CurrentLogLevel`.
566 *
567 * @see {@link CurrentLogLevel} for the default severity used by ordinary `Effect.log` calls
568 * @see {@link MinimumLogLevel} for filtering emitted log entries by threshold
569 *
570 * @category references
571 * @since 4.0.0
572 */
573export const UnhandledLogLevel: Context.Reference<Severity | undefined> = references.UnhandledLogLevel
574
575/**
576 * A captured stack-frame node used to describe the traced execution path.
577 *
578 * **When to use**
579 *
580 * Use when reading or supplying the stack-frame chain that Effect tracing uses
581 * to attach diagnostic call-site information to failures and interruptions.
582 *
583 * **Details**
584 *
585 * Each frame has a span or operation `name`, a lazy `stack` supplier, and an
586 * optional `parent` frame that links it to the previous captured frame.
587 *
588 * @see {@link CurrentStackFrame} for the fiber reference carrying the active stack-frame chain
589 *
590 * @category references
591 * @since 4.0.0
592 */
593export interface StackFrame {
594 readonly name: string
595 readonly stack: () => string | undefined
596 readonly parent: StackFrame | undefined
597}
598
599/**
600 * Context reference for the set of loggers currently used by Effect logging
601 * operations.
602 *
603 * **When to use**
604 *
605 * Use to inspect or provide the complete set of loggers used by Effect logging
606 * in the current context.
607 *
608 * **Details**
609 *
610 * The default set contains the built-in default logger and tracer logger.
611 * Providing this reference changes which `Logger` instances receive log entries
612 * in the current context.
613 *
614 * @category references
615 * @since 4.0.0
616 */
617export const CurrentLoggers: Context.Reference<ReadonlySet<Logger<unknown, any>>> = internalEffect.CurrentLoggers
618
619/**
620 * Context reference for controlling whether built-in console loggers write to stderr.
621 *
622 * **When to use**
623 *
624 * Use to configure the runtime reference that controls whether built-in console
625 * loggers write to stderr.
626 *
627 * **Details**
628 *
629 * The default value is `false`. When set to `true`, the built-in default logger
630 * and TTY pretty console logger call `console.error` instead of `console.log`.
631 *
632 * @category references
633 * @since 4.0.0
634 */
635export const LogToStderr: Context.Reference<boolean> = internalEffect.LogToStderr
636
637export {
638 /**
639 * Context reference for the current scheduler implementation used by the Effect runtime.
640 * Controls how Effects are scheduled and executed.
641 *
642 * **When to use**
643 *
644 * Use to provide the scheduler implementation that fibers use in the current
645 * context.
646 *
647 * **Example** (Providing a custom scheduler)
648 *
649 * ```ts import.meta.vitest
650 * import { Effect, References, Scheduler } from "effect"
651 *
652 * const customScheduling = Effect.gen(function*() {
653 * // Get current scheduler (default is MixedScheduler)
654 * const current = yield* References.Scheduler
655 * const isDefaultMixed = current instanceof Scheduler.MixedScheduler
656 *
657 * // Use a custom scheduler
658 * const isCustomMixed = yield* Effect.provideService(
659 * Effect.map(References.Scheduler, (scheduler) => scheduler instanceof Scheduler.MixedScheduler),
660 * References.Scheduler,
661 * new Scheduler.MixedScheduler()
662 * )
663 *
664 * return [isDefaultMixed, isCustomMixed]
665 * })
666 *
667 * await Effect.runPromise(customScheduling) // => [true, true]
668 * ```
669 *
670 * @category references
671 * @since 4.0.0
672 */
673 Scheduler
674} from "./Scheduler.ts"