원클릭으로
effect
// Guides working with Effect-TS in TypeScript codebases. Use when writing Effect programs, defining services/layers, handling errors, running effects, or when code uses effect, Context, Layer, Effect.gen, or related Effect patterns.
// Guides working with Effect-TS in TypeScript codebases. Use when writing Effect programs, defining services/layers, handling errors, running effects, or when code uses effect, Context, Layer, Effect.gen, or related Effect patterns.
Use when working on files in packages/plugins/, adding new plugins, refactoring plugin components/containers, writing storybooks for plugins, or wiring capabilities like react-surface or operation-resolver.
Land an existing PR — finds it, fixes CI failures iteratively, keeps the branch up to date with main, subscribes to PR events for continuous autofixing, and adds to merge queue. Use when the user says "/land <PR number or URL>" or asks to land/ship an existing PR. Accepts optional extra instructions after the PR reference.
Test assistant conversations, agents, and blueprints using AssistantTestLayer, Effect/vitest, ECHO types, and memoized LLM fixtures. Use when writing or fixing assistant-toolkit tests, blueprint.operation tests, AiSession flows, or when CI fails on missing memoized conversations.
Author DXOS Composer plugins — primarily community plugins built in their own repo (Vite + composerPlugin, GitHub release, registered via dxos/community-plugins), with notes on how the in-repo workflow differs. Use when scaffolding a new Composer plugin, wiring capabilities (surfaces, operations, blueprints), exposing operations to AI agents, integrating external services, testing with the composer testing harness, or publishing to the community registry.
Use when authoring or refactoring Radix-style composite React components in `@dxos/react-ui` and sibling UI packages — namespaced primitives like `Foo.Root` / `Foo.Trigger` / `Foo.Content` built around `forwardRef`, `Slot`, and a `tx()` theme function.
Reference for `SubductionPolicy` (the four hooks `authorizeConnect`, `authorizeFetch`, `authorizePut`, `filterAuthorizedFetch` passed via `Subduction.hydrate(..., policy)` or `new Repo({ subductionPolicy })`). Use when designing client-side access control over Subduction-replicated data, choosing which hook to deny in, or debugging why a doc did or did not replicate.
| name | effect |
| description | Guides working with Effect-TS in TypeScript codebases. Use when writing Effect programs, defining services/layers, handling errors, running effects, or when code uses effect, Context, Layer, Effect.gen, or related Effect patterns. |
Effect is a TypeScript library for building complex synchronous and asynchronous programs with typed errors, dependency injection, and resource management. Reference: https://effect.website/llms.txt.
Effect<Success, Error, Requirements> is a lazy, immutable description of a workflow:
never when effect cannot fail.Context; use never when none needed.Effects are descriptions, not executions. They run via the Effect runtime at a single entry point.
import { Effect, Context, Layer } from 'effect';
// Effect<number, never, never> - succeeds with number, no errors, no deps
const pure = Effect.succeed(42);
// Effect<never, Error, never> - fails with Error
const failure = Effect.fail(new Error('failed'));
| Type | Tracked in type | Purpose |
|---|---|---|
| Expected | Yes (Error in Effect) | Anticipated, domain errors, recoverable (like checked exceptions) |
| Unexpected | No | Defects, bugs, unanticipated (like unchecked exceptions) |
Use Effect.fail() for expected errors. Thrown errors in sync/async code become defects. Avoid throw; prefer Effect.fail or Effect.try.
| Constructor | Use case |
|---|---|
Effect.succeed(v) | Pure success |
Effect.fail(e) | Expected failure |
Effect.sync(() => x) | Sync side effect; must not throw |
Effect.try(() => x) | Sync that may throw → defect or caught |
Effect.promise(() => Promise) | Wrap Promise (reject → defect) |
Effect.gen(function* () { ... }) | Generator style, like async/await |
const program = Effect.gen(function* () {
const a = yield* Effect.succeed(1);
const b = yield* Effect.succeed(2);
return a + b;
});
| Function | Returns | When to use |
|---|---|---|
Effect.runSync(e) | A | Sync only, no fail; throws otherwise |
Effect.runPromise(e) | Promise<A> | Async; rejects on failure |
Effect.runPromiseExit(e) | Promise<Exit<A, E>> | Get Exit for custom handling |
Provide requirements before running: Effect.runPromise(Effect.provide(program, layer)).
Context.Tag:class MyService extends Context.Tag('MyService')<
MyService,
{ readonly doSomething: () => Effect.Effect<string, never> }
>() {}
Requirements:const program = Effect.gen(function* () {
const service = yield* MyService;
return yield* service.doSomething();
});
// Effect<string, never, MyService>
Effect.provideService or Effect.provide + Layer.Layers construct services and hide implementation dependencies. Avoid leaking internal deps in service interfaces.
Layer.succeed(Tag, implementation) – static implementationLayer.effect(Tag, Effect) – effectful constructionLayer.merge(a, b) – combine layersLayer.provide / Layer.provideMerge for dependency graphsProvide at the edge: Effect.provide(program, AppLive).
Effect.gen over manual flatMap chains.Effect.catchAll, Effect.catchTag, Effect.orElse, Effect.retry.Effect.scoped, Scope, acquireRelease.Effect.all (parallel), Effect.forEach with concurrency.Data.TaggedClass or Data.TaggedEnum for typed domain errors.Import:
import { Effect, Context, Layer, Data } from 'effect';
Run program with layer:
const runnable = Effect.provide(program, AppLive);
Effect.runPromise(runnable);
Typed error:
class HttpError extends Data.TaggedClass('HttpError')<{ readonly status: number }> {}
For deeper topics, see https://effect.website/docs/: