Skip to content

refactor(effect)!: clean up public type surface before stable - #2320

Merged
dinwwwh merged 1 commit into
mainfrom
claude/brave-knuth-mq3cne
Oct 23, 2026
Merged

dinwwwh merged 1 commit into
mainfrom
claude/brave-knuth-mq3cne

Conversation

@dinwwwh

@dinwwwh dinwwwh commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

Cleans up the public type surface of @orpc/experimental-effect before it is promoted to stable, since each change becomes breaking afterwards.

Changes

  • HandlerGen / handlerGen follow ProcedureHandler order with TYield last: <TCurrentContext, TInput, TReturn, TErrorConstructorMap, TYield>. handlerGen gets defaults like middlewareGen, and AnyHandlerGen is added.

    const getUser = handlerGen<ServerContext, { id: string }, User>(function* ({ input }) { /* ... */ })
    const ping = handlerGen<ServerContext>(function* () { /* ... */ }) // previously required all 5 type arguments
  • MiddlewareGen moves TYield last to match middlewareGen.

  • InferEffectServices no longer distributes over union contexts, so a handler can't yield a service that some members don't provide:

    Context Before After
    WithEffectContext<A> | WithEffectContext<B> A | B never
    WithEffectContext<A> | { auth: boolean } A never
    WithEffectContext<A | B> | WithEffectContext<A> A | B A
    WithEffectContext<A> & { auth: boolean } A A
    any unknown unknown
  • InferYieldError is removed; use Effect's Effect.Error<T>.

  • runtime.ts (runPromise, RunPromiseOptions) and schema.ts (toStandardSchema) are no longer exported. Both stay internal; the docs keep Effect's native Schema.toStandardSchemaV1.

The 'effect/context' / 'effect/wrap' string keys are intentionally kept.

Breaking changes

  • HandlerGen, handlerGen and MiddlewareGen type parameter order changed (only affects explicit type arguments).
  • InferYieldError, runPromise, RunPromiseOptions and toStandardSchema are no longer exported.
  • InferEffectServices of a union context only includes services every member provides.

Tests

  • handler.test-d.ts / middleware.test-d.ts: explicit type arguments lock the new order; handlerGen defaults are checked.
  • context.test-d.ts: union, intersection and any contexts.
  • index.test.ts: asserts the internal helpers are not exported.

Verified locally on this commit: pnpm vitest run packages/effect, the effect package type check, pnpm lint and pnpm docs:validate. The full pnpm type:check runs in CI.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EJQNgdewgQDKw3FvMx6svZ

- HandlerGen/handlerGen follow ProcedureHandler order with TYield last,
  and handlerGen gets defaults like middlewareGen; add AnyHandlerGen
- MiddlewareGen moves TYield last to match middlewareGen
- InferEffectServices no longer distributes over union contexts
- Remove InferYieldError
- Stop exporting runtime.ts (runPromise, RunPromiseOptions) and
  schema.ts (toStandardSchema); the docs keep Effect's native
  Schema.toStandardSchemaV1

BREAKING CHANGE: HandlerGen, handlerGen and MiddlewareGen type parameter
order changed; InferYieldError, runPromise, RunPromiseOptions and
toStandardSchema are no longer exported; InferEffectServices of a union
context only includes services every member provides.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EJQNgdewgQDKw3FvMx6svZ
@dinwwwh
dinwwwh force-pushed the claude/brave-knuth-mq3cne branch from 87426ae to d0aec58 Compare October 23, 2026 14:13
@macroscopeapp

macroscopeapp Bot commented Oct 23, 2026

Copy link
Copy Markdown

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — This PR intentionally makes breaking public-contract changes to the Effect package, including removing root exports and reordering public generic parameters, while also changing union-context type inference. Internal handler execution remains largely unchanged, but existing consumers may require source updates, so the compatibility impact merits human review.

Notes:

  • Diff unchanged. Approvability was decided on eligibility alone.

You can add or adjust custom eligibility rules. Learn more.

@pkg-pr-new

pkg-pr-new Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
More templates

@orpc/ai-sdk

npm i https://pkg.pr.new/@orpc/ai-sdk@2320

@orpc/arktype

npm i https://pkg.pr.new/@orpc/arktype@2320

@orpc/bun

npm i https://pkg.pr.new/@orpc/bun@2320

@orpc/client

npm i https://pkg.pr.new/@orpc/client@2320

@orpc/cloudflare

npm i https://pkg.pr.new/@orpc/cloudflare@2320

@orpc/contract

npm i https://pkg.pr.new/@orpc/contract@2320

@orpc/experimental-effect

npm i https://pkg.pr.new/@orpc/experimental-effect@2320

@orpc/evlog

npm i https://pkg.pr.new/@orpc/evlog@2320

@orpc/hibernation

npm i https://pkg.pr.new/@orpc/hibernation@2320

@orpc/json-schema

npm i https://pkg.pr.new/@orpc/json-schema@2320

@orpc/experimental-lock

npm i https://pkg.pr.new/@orpc/experimental-lock@2320

@orpc/mcp

npm i https://pkg.pr.new/@orpc/mcp@2320

@orpc/msw

npm i https://pkg.pr.new/@orpc/msw@2320

@orpc/nest

npm i https://pkg.pr.new/@orpc/nest@2320

@orpc/next

npm i https://pkg.pr.new/@orpc/next@2320

@orpc/node

npm i https://pkg.pr.new/@orpc/node@2320

@orpc/openapi

npm i https://pkg.pr.new/@orpc/openapi@2320

@orpc/opentelemetry

npm i https://pkg.pr.new/@orpc/opentelemetry@2320

@orpc/pinia-colada

npm i https://pkg.pr.new/@orpc/pinia-colada@2320

@orpc/pino

npm i https://pkg.pr.new/@orpc/pino@2320

@orpc/publisher

npm i https://pkg.pr.new/@orpc/publisher@2320

@orpc/ratelimit

npm i https://pkg.pr.new/@orpc/ratelimit@2320

@orpc/server

npm i https://pkg.pr.new/@orpc/server@2320

@orpc/shared

npm i https://pkg.pr.new/@orpc/shared@2320

@orpc/swr

npm i https://pkg.pr.new/@orpc/swr@2320

@orpc/tanstack-query

npm i https://pkg.pr.new/@orpc/tanstack-query@2320

@orpc/trpc

npm i https://pkg.pr.new/@orpc/trpc@2320

@orpc/valibot

npm i https://pkg.pr.new/@orpc/valibot@2320

@orpc/zod

npm i https://pkg.pr.new/@orpc/zod@2320

commit: d0aec58

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — the pre-stable type-surface cleanup of @orpc/experimental-effect; I read the full diff and verified the package tests (pnpm vitest run packages/effect, 106 passing) plus the full root tsc, which type-checks the *.test-d.ts assertions this PR relies on.

  • Consistent generic order (TYield last) — HandlerGen, handlerGen and MiddlewareGen now mirror ProcedureHandler/Middleware; every internal call site (extensions/effect.ts, the extension HandlerGen arguments, the type tests) was updated in lockstep. Breaking only for explicit type arguments.
  • handlerGen defaults — TInput/TReturn = unknown, empty error map, and a TYield default identical to middlewareGen, so a standalone handler works with only the context. Backed by a new type test.
  • InferEffectServices is non-distributive — [T] extends [{ 'effect/context': Context<infer S> }] ? S : never restricts a union context to services every member provides (never for disjoint services). New tests cover union, intersection and any contexts, and the doc comment was updated to match.
  • Removed exports — InferYieldError, runPromise, RunPromiseOptions, toStandardSchema (and the ./runtime / ./schema re-exports). runtime.ts/schema.ts remain internal and are still exercised via direct-path unit tests; index.test.ts now asserts the helpers are absent from the public module. No remaining repo references to any removed symbol.
  • AnyHandlerGen added alongside the existing AnyMiddlewareGen.

The one internal loss of precision — handler.ts:44 now casts to Effect.Effect<TReturn, unknown> rather than InferYieldError<TYield> — is not observable: both runPromise and effect/wrap already accept Effect<..., unknown>, so no public signature changes. Docs already use Effect's native Schema.toStandardSchemaV1 and never reference the removed exports or an explicit generic order.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@codecov

codecov Bot commented Oct 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@codspeed

codspeed Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

1 warning, 1 note

⚠️ 6 benchmarks are dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

ℹ️ This run is excluded from the branch history

This commit was force-pushed, so this run no longer appears in the branch's performance history.

✅ 28 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing claude/brave-knuth-mq3cne (87426ae) with main (eb1fea8)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@dinwwwh
dinwwwh merged commit 23fc494 into main Oct 23, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants