Effect Service Generator
Generate Effect-TS services following project conventions.
Service Template
ts
import * as Context from "effect/Context";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
// Interface defines the contract
export interface MyServiceInterface {
readonly doSomething: (
input: InputType,
) => Effect.Effect<OutputType, MyError>;
}
// Tag for dependency injection
export class MyService extends Context.Tag("@wowlab/services/MyService")<
MyService,
MyServiceInterface
>() {}
// Live implementation
export const MyServiceLive: Layer.Layer<MyService, never, Dependencies> =
Layer.effect(
MyService,
Effect.gen(function* () {
const dep = yield* SomeDependency;
return {
doSomething: (input) =>
Effect.gen(function* () {
// implementation
return result;
}),
} satisfies MyServiceInterface;
}),
);
Alternative: Effect.Service Pattern
For simpler services with built-in Default layer:
ts
export class MyService extends Effect.Service<MyService>()("MyService", {
dependencies: [Dep1.Default, Dep2.Default],
effect: Effect.gen(function* () {
const dep1 = yield* Dep1;
const dep2 = yield* Dep2;
return {
doSomething: (input) => Effect.gen(function* () { ... }),
};
}),
}) {}
File Location
- •New service:
packages/wowlab-services/src/internal/{domain}/ - •Re-export from:
packages/wowlab-services/src/{Domain}.ts
Naming Conventions
- •Interface:
{Name}Interfaceor{Name}Service - •Tag:
@wowlab/services/{Name} - •Layer:
{Name}Liveor{Name}.Default - •Errors:
{Name}ErrorusingData.TaggedError
Instructions
- •Ask what the service should do
- •Identify dependencies needed
- •Generate interface with typed methods
- •Generate Layer implementation
- •Add re-export to barrel file