| 1 | /** |
| 2 | * Operations for handles returned by forking effects. A `Fiber<A, E>` is a |
| 3 | * lightweight execution of an `Effect` that may still be running or may already |
| 4 | * have completed. This module lets callers await or join fiber results, |
| 5 | * interrupt one or many fibers, check unknown values, access the current fiber, |
| 6 | * and attach manually managed fibers to a `Scope` for cleanup. |
| 7 | * |
| 8 | * @since 2.0.0 |
| 9 | */ |
| 10 | import type * as Arr from "./Array.ts" |
| 11 | import type * as Context from "./Context.ts" |
| 12 | import type { Effect } from "./Effect.ts" |
| 13 | import type { Exit } from "./Exit.ts" |
| 14 | import * as effect from "./internal/effect.ts" |
| 15 | import type { LogLevel } from "./LogLevel.ts" |
| 16 | import type { FiberRuntimeMetricsService } from "./Metric.ts" |
| 17 | import type { Pipeable } from "./Pipeable.ts" |
| 18 | import { hasProperty } from "./Predicate.ts" |
| 19 | import type { StackFrame } from "./References.ts" |
| 20 | import type { Scheduler, SchedulerDispatcher } from "./Scheduler.ts" |
| 21 | import type { Scope } from "./Scope.ts" |
| 22 | import type { AnySpan, Tracer } from "./Tracer.ts" |
| 23 | import type { Covariant } from "./Types.ts" |
| 24 | |
| 25 | const TypeId = "~effect/Fiber" |
| 26 | |
| 27 | /** |
| 28 | * A runtime fiber is a lightweight thread that executes Effects. Fibers are |
| 29 | * the unit of concurrency in Effect. They provide a way to run multiple |
| 30 | * Effects concurrently while maintaining structured concurrency and |
| 31 | * cancellation safety. |
| 32 | * |
| 33 | * **When to use** |
| 34 | * |
| 35 | * Use to observe, join, interrupt, or coordinate work that has already been |
| 36 | * forked. |
| 37 | * |
| 38 | * **Details** |
| 39 | * |
| 40 | * A fiber exposes both safe Effect-based operations, such as {@link await_ await}, |
| 41 | * {@link join}, and {@link interrupt}, and low-level runtime fields used by |
| 42 | * the scheduler and runtime internals. |
| 43 | * |
| 44 | * **Gotchas** |
| 45 | * |
| 46 | * Prefer the exported functions in this module over calling `interruptUnsafe` |
| 47 | * or `pollUnsafe` directly. The unsafe methods are immediate runtime hooks and |
| 48 | * do not provide the same Effect-based sequencing guarantees. |
| 49 | * |
| 50 | * **Example** (Awaiting a forked fiber) |
| 51 | * |
| 52 | * ```ts import.meta.vitest |
| 53 | * import { Effect, Exit, Fiber } from "effect" |
| 54 | * |
| 55 | * const program = Effect.gen(function*() { |
| 56 | * // Fork an effect to run in a new fiber |
| 57 | * const fiber = yield* Effect.forkChild(Effect.succeed(42)) |
| 58 | * |
| 59 | * // Wait for the fiber to complete and get its result |
| 60 | * const result = yield* Fiber.await(fiber) |
| 61 | * return result |
| 62 | * }) |
| 63 | * |
| 64 | * const actual = await Effect.runPromise(program) |
| 65 | * actual // => Exit.succeed(42) |
| 66 | * ``` |
| 67 | * |
| 68 | * @category models |
| 69 | * @since 2.0.0 |
| 70 | */ |
| 71 | export interface Fiber<out A, out E = never> extends Pipeable { |
| 72 | readonly [TypeId]: Fiber.Variance<A, E> |
| 73 | |
| 74 | readonly id: number |
| 75 | readonly currentOpCount: number |
| 76 | readonly getRef: <A>(ref: Context.Reference<A>) => A |
| 77 | readonly context: Context.Context<never> |
| 78 | setContext(context: Context.Context<never>): void |
| 79 | readonly cache: Fiber.Cache |
| 80 | readonly currentDispatcher: SchedulerDispatcher |
| 81 | readonly addObserver: (cb: (exit: Exit<A, E>) => void) => () => void |
| 82 | readonly interruptUnsafe: ( |
| 83 | fiberId?: number | undefined, |
| 84 | annotations?: Context.Context<never> | undefined |
| 85 | ) => void |
| 86 | readonly pollUnsafe: () => Exit<A, E> | undefined |
| 87 | } |
| 88 | |
| 89 | /** |
| 90 | * The Fiber namespace contains utility types and functions for working with fibers. |
| 91 | * It provides type-level utilities for fiber operations and variance encoding. |
| 92 | * |
| 93 | * **When to use** |
| 94 | * |
| 95 | * Use to reference type-level helpers associated with `Fiber`. |
| 96 | * |
| 97 | * **Details** |
| 98 | * |
| 99 | * The namespace currently exposes type-level support used by the `Fiber` |
| 100 | * interface. Runtime operations are exported as module-level functions. |
| 101 | * |
| 102 | * **Example** (Working with fiber types) |
| 103 | * |
| 104 | * ```ts import.meta.vitest |
| 105 | * import { Effect, Fiber } from "effect" |
| 106 | * |
| 107 | * const program = Effect.gen(function*() { |
| 108 | * // Create a fiber |
| 109 | * const fiber = yield* Effect.forkChild(Effect.succeed(42)) |
| 110 | * |
| 111 | * // Use namespace types for variance |
| 112 | * const typedFiber: Fiber.Fiber<number, never> = fiber |
| 113 | * |
| 114 | * // Join the fiber |
| 115 | * return yield* Fiber.join(fiber) |
| 116 | * }) |
| 117 | * |
| 118 | * const actual = await Effect.runPromise(program) |
| 119 | * actual // => 42 |
| 120 | * ``` |
| 121 | * |
| 122 | * @since 2.0.0 |
| 123 | */ |
| 124 | export declare namespace Fiber { |
| 125 | /** |
| 126 | * Variance encoding for the Fiber type, specifying covariance in both the |
| 127 | * success type `A` and the error type `E`. |
| 128 | * |
| 129 | * **When to use** |
| 130 | * |
| 131 | * Use to carry the success and error type parameters for `Fiber` in Effect's |
| 132 | * type machinery. |
| 133 | * |
| 134 | * **Example** (Upcasting fibers safely) |
| 135 | * |
| 136 | * ```ts import.meta.vitest |
| 137 | * import { Effect, Fiber } from "effect" |
| 138 | * |
| 139 | * // Variance allows safe subtyping |
| 140 | * const fiber: Fiber.Fiber<number, never> = Effect.runFork(Effect.succeed(1)) |
| 141 | * const upcast: Fiber.Fiber<unknown, unknown> = fiber |
| 142 | * const actual = await Effect.runPromise(Fiber.join(upcast)) |
| 143 | * actual // => 1 |
| 144 | * ``` |
| 145 | * |
| 146 | * @category models |
| 147 | * @since 2.0.0 |
| 148 | */ |
| 149 | export interface Variance<out A, out E = never> { |
| 150 | readonly _A: Covariant<A> |
| 151 | readonly _E: Covariant<E> |
| 152 | } |
| 153 | |
| 154 | /** |
| 155 | * Context-derived values cached for the fiber's current `Context`. |
| 156 | * |
| 157 | * **When to use** |
| 158 | * |
| 159 | * Use to read runtime services resolved from the fiber's context, such as |
| 160 | * the scheduler, current span, or log levels. |
| 161 | * |
| 162 | * **Details** |
| 163 | * |
| 164 | * The cache object is computed once per context cache root and shared by |
| 165 | * every fiber running with that root, so it must be treated as immutable. |
| 166 | * |
| 167 | * @category models |
| 168 | * @since 4.0.0 |
| 169 | */ |
| 170 | export interface Cache { |
| 171 | readonly scheduler: Scheduler |
| 172 | readonly tracer: Tracer | undefined |
| 173 | readonly tracerContext: Tracer["context"] | undefined |
| 174 | readonly tracerEnabled: boolean |
| 175 | readonly span: AnySpan | undefined |
| 176 | readonly logLevel: LogLevel |
| 177 | readonly minimumLogLevel: LogLevel |
| 178 | readonly stackFrame: StackFrame | undefined |
| 179 | readonly runtimeMetrics: FiberRuntimeMetricsService | undefined |
| 180 | readonly maxOpsBeforeYield: number |
| 181 | readonly preventYield: boolean |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | const await_: <A, E>(self: Fiber<A, E>) => Effect<Exit<A, E>> = effect.fiberAwait |
| 186 | export { |
| 187 | /** |
| 188 | * Waits for a fiber to complete and returns its exit value. |
| 189 | * |
| 190 | * **When to use** |
| 191 | * |
| 192 | * Use when you need to inspect whether the fiber succeeded, |
| 193 | * failed, died, or was interrupted without propagating the failure. |
| 194 | * |
| 195 | * **Details** |
| 196 | * |
| 197 | * The returned Effect always succeeds with an `Exit` describing the fiber's |
| 198 | * outcome. |
| 199 | * |
| 200 | * **Gotchas** |
| 201 | * |
| 202 | * This does not flatten the fiber result into the current Effect. Use |
| 203 | * {@link join} when you want fiber failures to fail the current Effect. |
| 204 | * |
| 205 | * **Example** (Awaiting a fiber exit) |
| 206 | * |
| 207 | * ```ts import.meta.vitest |
| 208 | * import { Effect, Exit, Fiber } from "effect" |
| 209 | * |
| 210 | * const program = Effect.gen(function*() { |
| 211 | * const fiber = yield* Effect.forkChild(Effect.succeed(42)) |
| 212 | * return yield* Fiber.await(fiber) |
| 213 | * }) |
| 214 | * |
| 215 | * const actual = await Effect.runPromise(program) |
| 216 | * actual // => Exit.succeed(42) |
| 217 | * ``` |
| 218 | * |
| 219 | * @category combinators |
| 220 | * @since 2.0.0 |
| 221 | */ |
| 222 | await_ as await |
| 223 | } |
| 224 | /** |
| 225 | * Waits for all fibers in the provided iterable to complete and returns |
| 226 | * an array of their exit values. |
| 227 | * |
| 228 | * **When to use** |
| 229 | * |
| 230 | * Use when you need every fiber outcome as data, including failures and |
| 231 | * interruptions. |
| 232 | * |
| 233 | * **Details** |
| 234 | * |
| 235 | * The returned array is ordered like the input iterable. |
| 236 | * |
| 237 | * **Gotchas** |
| 238 | * |
| 239 | * Failures are captured as `Exit.Failure` values. Use {@link joinAll} when you |
| 240 | * want the first failed fiber to fail the returned Effect. |
| 241 | * |
| 242 | * **Example** (Awaiting multiple fiber exits) |
| 243 | * |
| 244 | * ```ts import.meta.vitest |
| 245 | * import { Effect, Exit, Fiber } from "effect" |
| 246 | * |
| 247 | * const program = Effect.gen(function*() { |
| 248 | * const fiber1 = yield* Effect.forkChild(Effect.succeed(1)) |
| 249 | * const fiber2 = yield* Effect.forkChild(Effect.succeed(2)) |
| 250 | * return yield* Fiber.awaitAll([fiber1, fiber2]) |
| 251 | * }) |
| 252 | * |
| 253 | * const actual = await Effect.runPromise(program) |
| 254 | * actual // => [Exit.succeed(1), Exit.succeed(2)] |
| 255 | * ``` |
| 256 | * |
| 257 | * @category combinators |
| 258 | * @since 2.0.0 |
| 259 | */ |
| 260 | export const awaitAll: <A extends Fiber<any, any>>( |
| 261 | self: Iterable<A> |
| 262 | ) => Effect< |
| 263 | Array< |
| 264 | Exit< |
| 265 | A extends Fiber<infer _A, infer _E> ? _A : never, |
| 266 | A extends Fiber<infer _A, infer _E> ? _E : never |
| 267 | > |
| 268 | > |
| 269 | > = effect.fiberAwaitAll |
| 270 | |
| 271 | /** |
| 272 | * Joins a fiber, blocking until it completes. If the fiber succeeds, |
| 273 | * returns its value. If it fails, the error is propagated. |
| 274 | * |
| 275 | * **When to use** |
| 276 | * |
| 277 | * Use when you need a forked fiber's failure to fail the current Effect because |
| 278 | * that fiber is part of the current workflow. |
| 279 | * |
| 280 | * **Gotchas** |
| 281 | * |
| 282 | * Joining a failed fiber propagates the fiber's Cause. Use {@link await_ await} when |
| 283 | * you need to inspect the `Exit` instead of failing. |
| 284 | * |
| 285 | * **Example** (Joining a fiber) |
| 286 | * |
| 287 | * ```ts import.meta.vitest |
| 288 | * import { Effect, Fiber } from "effect" |
| 289 | * |
| 290 | * const program = Effect.gen(function*() { |
| 291 | * const fiber = yield* Effect.forkChild(Effect.succeed(42)) |
| 292 | * return yield* Fiber.join(fiber) |
| 293 | * }) |
| 294 | * |
| 295 | * const actual = await Effect.runPromise(program) |
| 296 | * actual // => 42 |
| 297 | * ``` |
| 298 | * |
| 299 | * @see {@link await_ await} for inspecting the fiber outcome as an Exit |
| 300 | * |
| 301 | * @category combinators |
| 302 | * @since 2.0.0 |
| 303 | */ |
| 304 | export const join: <A, E>(self: Fiber<A, E>) => Effect<A, E> = effect.fiberJoin |
| 305 | |
| 306 | /** |
| 307 | * Waits for all fibers to succeed and returns their values in input order. |
| 308 | * |
| 309 | * **When to use** |
| 310 | * |
| 311 | * Use when you need every fiber to succeed and want the successful values |
| 312 | * rather than the `Exit` values. |
| 313 | * |
| 314 | * **Details** |
| 315 | * |
| 316 | * If any fiber fails, the returned `Effect` fails with that fiber's cause and |
| 317 | * stops waiting for additional results. This does not interrupt the remaining |
| 318 | * fibers. |
| 319 | * |
| 320 | * **Gotchas** |
| 321 | * |
| 322 | * A failure stops waiting, but it does not interrupt any other fibers. Use |
| 323 | * {@link interruptAll} separately when remaining fibers should be stopped. |
| 324 | * |
| 325 | * @see {@link awaitAll} for collecting every fiber outcome as an Exit |
| 326 | * |
| 327 | * @category combinators |
| 328 | * @since 2.0.0 |
| 329 | */ |
| 330 | export const joinAll: <A extends Iterable<Fiber<any, any>>>( |
| 331 | self: A |
| 332 | ) => Effect< |
| 333 | Arr.ReadonlyArray.With< |
| 334 | A, |
| 335 | A extends Iterable<Fiber<infer _A, infer _E>> ? _A : never |
| 336 | >, |
| 337 | A extends Iterable<Fiber<infer _A, infer _E>> ? _E : never |
| 338 | > = effect.fiberJoinAll |
| 339 | |
| 340 | /** |
| 341 | * Interrupts a fiber, causing it to stop executing and clean up any |
| 342 | * acquired resources. |
| 343 | * |
| 344 | * **When to use** |
| 345 | * |
| 346 | * Use when you need to cancel a forked fiber and wait for its cleanup to |
| 347 | * complete. |
| 348 | * |
| 349 | * **Details** |
| 350 | * |
| 351 | * The returned Effect completes only after the interrupted fiber has completed. |
| 352 | * |
| 353 | * **Gotchas** |
| 354 | * |
| 355 | * Interruption is cooperative. A fiber can continue running while it is inside |
| 356 | * uninterruptible work or finalizers. |
| 357 | * |
| 358 | * **Example** (Interrupting a fiber) |
| 359 | * |
| 360 | * ```ts import.meta.vitest |
| 361 | * import { Effect, Fiber } from "effect" |
| 362 | * |
| 363 | * const program = Effect.gen(function*() { |
| 364 | * const fiber = yield* Effect.forkChild( |
| 365 | * Effect.delay("1 second")(Effect.succeed(42)) |
| 366 | * ) |
| 367 | * yield* Fiber.interrupt(fiber) |
| 368 | * }) |
| 369 | * |
| 370 | * await Effect.runPromise(program) |
| 371 | * ``` |
| 372 | * |
| 373 | * @see {@link interruptAs} for specifying the interrupting fiber ID |
| 374 | * @see {@link await_ await} for observing the interrupted fiber's Exit |
| 375 | * |
| 376 | * @category interruption |
| 377 | * @since 2.0.0 |
| 378 | */ |
| 379 | export const interrupt: <A, E>(self: Fiber<A, E>) => Effect<void> = effect.fiberInterrupt |
| 380 | |
| 381 | /** |
| 382 | * Interrupts a fiber with a specific fiber ID as the interruptor. This allows |
| 383 | * tracking which fiber initiated the interruption. |
| 384 | * |
| 385 | * **When to use** |
| 386 | * |
| 387 | * Use when runtime diagnostics or tracing should attribute the interruption to |
| 388 | * a specific fiber ID. |
| 389 | * |
| 390 | * **Details** |
| 391 | * |
| 392 | * The returned Effect completes only after the interrupted fiber has completed. |
| 393 | * |
| 394 | * **Gotchas** |
| 395 | * |
| 396 | * The supplied ID affects the recorded interruptor. It does not make |
| 397 | * interruption synchronous or force uninterruptible regions to stop early. |
| 398 | * |
| 399 | * **Example** (Interrupting a fiber as another fiber) |
| 400 | * |
| 401 | * ```ts import.meta.vitest |
| 402 | * import { Effect, Fiber } from "effect" |
| 403 | * |
| 404 | * const program = Effect.gen(function*() { |
| 405 | * const targetFiber = yield* Effect.forkChild( |
| 406 | * Effect.delay("5 seconds")(Effect.succeed("task completed")) |
| 407 | * ) |
| 408 | * |
| 409 | * // Interrupt the fiber, specifying fiber ID 123 as the interruptor |
| 410 | * yield* Fiber.interruptAs(targetFiber, 123) |
| 411 | * }) |
| 412 | * |
| 413 | * await Effect.runPromise(program) |
| 414 | * ``` |
| 415 | * |
| 416 | * @see {@link interrupt} for using the current fiber as the interruptor |
| 417 | * |
| 418 | * @category interruption |
| 419 | * @since 2.0.0 |
| 420 | */ |
| 421 | export const interruptAs: { |
| 422 | ( |
| 423 | fiberId: number | undefined, |
| 424 | annotations?: Context.Context<never> | undefined |
| 425 | ): <A, E>(self: Fiber<A, E>) => Effect<void> |
| 426 | <A, E>( |
| 427 | self: Fiber<A, E>, |
| 428 | fiberId: number | undefined, |
| 429 | annotations?: Context.Context<never> | undefined |
| 430 | ): Effect<void> |
| 431 | } = effect.fiberInterruptAs |
| 432 | |
| 433 | /** |
| 434 | * Interrupts all fibers in the provided iterable, causing them to stop executing |
| 435 | * and clean up any acquired resources. |
| 436 | * |
| 437 | * **When to use** |
| 438 | * |
| 439 | * Use when you need to cancel several forked fibers and wait for their cleanup |
| 440 | * to complete. |
| 441 | * |
| 442 | * **Details** |
| 443 | * |
| 444 | * The current fiber is recorded as the interruptor. The returned Effect |
| 445 | * completes only after all interrupted fibers have completed. |
| 446 | * |
| 447 | * **Gotchas** |
| 448 | * |
| 449 | * Interruption is cooperative for each fiber. The returned Effect can wait for |
| 450 | * uninterruptible work and finalizers in any interrupted fiber. |
| 451 | * |
| 452 | * **Example** (Interrupting multiple fibers) |
| 453 | * |
| 454 | * ```ts import.meta.vitest |
| 455 | * import { Effect, Fiber } from "effect" |
| 456 | * |
| 457 | * const program = Effect.gen(function*() { |
| 458 | * const fiber1 = yield* Effect.forkChild(Effect.never) |
| 459 | * const fiber2 = yield* Effect.forkChild(Effect.never) |
| 460 | * const fiber3 = yield* Effect.forkChild(Effect.never) |
| 461 | * yield* Fiber.interruptAll([fiber1, fiber2, fiber3]) |
| 462 | * }) |
| 463 | * |
| 464 | * await Effect.runPromise(program) |
| 465 | * ``` |
| 466 | * |
| 467 | * @see {@link interruptAllAs} for specifying the interrupting fiber ID |
| 468 | * |
| 469 | * @category interruption |
| 470 | * @since 2.0.0 |
| 471 | */ |
| 472 | export const interruptAll: <A extends Iterable<Fiber<any, any>>>( |
| 473 | fibers: A |
| 474 | ) => Effect<void> = effect.fiberInterruptAll |
| 475 | |
| 476 | /** |
| 477 | * Interrupts all fibers in the provided iterable using the specified fiber ID as the |
| 478 | * interrupting fiber. This allows you to control which fiber is considered the source |
| 479 | * of the interruption, which can be useful for debugging and tracing. |
| 480 | * |
| 481 | * **When to use** |
| 482 | * |
| 483 | * Use to interrupt several fibers while recording a specific fiber ID as the |
| 484 | * interruptor. |
| 485 | * |
| 486 | * **Details** |
| 487 | * |
| 488 | * The returned Effect completes only after all interrupted fibers have |
| 489 | * completed. |
| 490 | * |
| 491 | * **Gotchas** |
| 492 | * |
| 493 | * The supplied ID affects the recorded interruptor. It does not make |
| 494 | * interruption synchronous or force uninterruptible regions to stop early. |
| 495 | * |
| 496 | * **Example** (Interrupting multiple fibers as another fiber) |
| 497 | * |
| 498 | * ```ts import.meta.vitest |
| 499 | * import { Effect, Fiber } from "effect" |
| 500 | * |
| 501 | * const program = Effect.gen(function*() { |
| 502 | * // Create a controlling fiber |
| 503 | * const controllerFiber = yield* Effect.forkChild(Effect.succeed("controller")) |
| 504 | * |
| 505 | * const worker1 = yield* Effect.forkChild(Effect.never) |
| 506 | * const worker2 = yield* Effect.forkChild(Effect.never) |
| 507 | * |
| 508 | * yield* Fiber.interruptAllAs([worker1, worker2], controllerFiber.id) |
| 509 | * }) |
| 510 | * |
| 511 | * await Effect.runPromise(program) |
| 512 | * ``` |
| 513 | * |
| 514 | * @see {@link interruptAll} for using the current fiber as the interruptor |
| 515 | * |
| 516 | * @category interruption |
| 517 | * @since 2.0.0 |
| 518 | */ |
| 519 | export const interruptAllAs: { |
| 520 | (fiberId: number): <A extends Iterable<Fiber<any, any>>>(fibers: A) => Effect<void> |
| 521 | <A extends Iterable<Fiber<any, any>>>(fibers: A, fiberId: number): Effect<void> |
| 522 | } = effect.fiberInterruptAllAs |
| 523 | |
| 524 | /** |
| 525 | * Checks whether a value is a Fiber. This is a type guard that can be used to |
| 526 | * determine if an unknown value is a Fiber instance. |
| 527 | * |
| 528 | * **When to use** |
| 529 | * |
| 530 | * Use when checking values at boundaries where an unknown value may be a |
| 531 | * runtime fiber. |
| 532 | * |
| 533 | * **Details** |
| 534 | * |
| 535 | * The check looks for the internal Fiber type ID marker and does not inspect |
| 536 | * the fiber's current state. |
| 537 | * |
| 538 | * **Example** (Checking for fibers) |
| 539 | * |
| 540 | * ```ts import.meta.vitest |
| 541 | * import { Effect, Fiber } from "effect" |
| 542 | * |
| 543 | * const program = Effect.gen(function*() { |
| 544 | * // Create a fiber |
| 545 | * const fiber = yield* Effect.forkChild(Effect.succeed(42)) |
| 546 | * |
| 547 | * // Test if values are fibers |
| 548 | * return [Fiber.isFiber(fiber), Fiber.isFiber("hello"), Fiber.isFiber(42), Fiber.isFiber(null)] |
| 549 | * }) |
| 550 | * |
| 551 | * const actual = await Effect.runPromise(program) |
| 552 | * actual // => [true, false, false, false] |
| 553 | * ``` |
| 554 | * |
| 555 | * @category guards |
| 556 | * @since 2.0.0 |
| 557 | */ |
| 558 | export const isFiber = ( |
| 559 | u: unknown |
| 560 | ): u is Fiber<unknown, unknown> => hasProperty(u, effect.FiberTypeId) |
| 561 | |
| 562 | /** |
| 563 | * Returns the current fiber if called from within a fiber context, |
| 564 | * otherwise returns `undefined`. |
| 565 | * |
| 566 | * **When to use** |
| 567 | * |
| 568 | * Use when you need low-level runtime integrations that need access to the currently |
| 569 | * executing fiber. |
| 570 | * |
| 571 | * **Gotchas** |
| 572 | * |
| 573 | * This is a synchronous accessor, not an Effect. It returns `undefined` outside |
| 574 | * an active fiber runtime context. |
| 575 | * |
| 576 | * **Example** (Getting the current fiber) |
| 577 | * |
| 578 | * ```ts import.meta.vitest |
| 579 | * import { Effect, Fiber } from "effect" |
| 580 | * |
| 581 | * const program = Effect.gen(function*() { |
| 582 | * const current = Fiber.getCurrent() |
| 583 | * return current !== undefined |
| 584 | * }) |
| 585 | * |
| 586 | * const actual = await Effect.runPromise(program) |
| 587 | * actual // => true |
| 588 | * ``` |
| 589 | * |
| 590 | * @category getters |
| 591 | * @since 4.0.0 |
| 592 | */ |
| 593 | export const getCurrent: () => Fiber<any, any> | undefined = effect.getCurrentFiber |
| 594 | |
| 595 | /** |
| 596 | * Adds a fiber to a `Scope` and returns the same fiber. |
| 597 | * |
| 598 | * **When to use** |
| 599 | * |
| 600 | * Use when a manually managed fiber should be interrupted when a Scope closes. |
| 601 | * |
| 602 | * **Details** |
| 603 | * |
| 604 | * When the scope is closed, the fiber is interrupted. If the scope is already |
| 605 | * closed, the fiber is interrupted immediately. |
| 606 | * |
| 607 | * **Gotchas** |
| 608 | * |
| 609 | * This does not wait for the fiber to complete. It only registers the |
| 610 | * interruption finalizer and returns the same fiber. |
| 611 | * |
| 612 | * @see {@link interrupt} for interrupting and waiting for completion |
| 613 | * |
| 614 | * @category resource management |
| 615 | * @since 4.0.0 |
| 616 | */ |
| 617 | export const runIn: { |
| 618 | (scope: Scope): <A, E>(self: Fiber<A, E>) => Fiber<A, E> |
| 619 | <A, E>(self: Fiber<A, E>, scope: Scope): Fiber<A, E> |
| 620 | } = effect.fiberRunIn |