feat(bldr, cli, conventional-commits, core, env, fs, git, group, idx, json, num, oak, oxlint-rules, paka, resource, syn, test, tex, tree)!, feat(color, doc-inject, html, http, log, mod, name, npm-registry, release, sch, semver, url, ware), fix(flo, github, kitz): upgrade to Effect v4 beta (4.0.0-beta.31)#130
feat(bldr, cli, conventional-commits, core, env, fs, git, group, idx, json, num, oak, oxlint-rules, paka, resource, syn, test, tex, tree)!, feat(color, doc-inject, html, http, log, mod, name, npm-registry, release, sch, semver, url, ware), fix(flo, github, kitz): upgrade to Effect v4 beta (4.0.0-beta.31)#130jasonkuhrt merged 12 commits intomainfrom
Conversation
BREAKING CHANGE: All Effect imports updated to v4 API surface.
Key changes:
- Either → Result (Left/Right → Failure/Success)
- Effect.either → Effect.result
- Effect.catchAll → Effect.catch
- Schema.Union(...spread) → Schema.Union([array])
- Schema.Record({key,value}) → Schema.Record(key, value)
- Schema.parseJson → Schema.fromJsonString
- S.transformOrFail → S.decodeTo + SchemaGetter.transformOrFail
- ParseResult → SchemaIssue
- @effect/vitest: it.scoped removed, use it.effect/it.live
- Logger.withMinimumLogLevel removed
- Cause.YieldableError runtime removed
- Effect.orElseFail removed, use Effect.mapError
- Updated custom oxlint rules for v4 API compatibility
Release Forecast39 packages · 35 primary · 4 cascades · head How release calculation worksPrimary — packages with commits directly touching their source in this PR.
Bump rules: Projected Release Header
Doctor
Manual Preview Runbook
Step 2 writes the exact ephemeral publish plan to Could Still Go Wrong LocallyThis comment cannot verify your local machine. Before applying the manual preview release, these checks still need to pass:
Primary (35)
Cascades (4)
Tree |
- Fix Result.Failure/Success type parameter order in assert package (v3 Either<E,A> was error-first, v4 Result<A,E> is value-first) - Remove unnecessary type assertions now that v4 narrows better - Fix no-base-to-string errors with proper error stringification - Fix Schema.Class constructability in git tests (new → make) - Remove service type widening from explicit Schema annotations - Remove as-any casts poisoning DecodingServices/EncodingServices - Fix optionalKey + withDecodingDefaultKey double-wrapping in publishing
Migration Evidence — Major Change Chains1.
|
Additional Migration ReferencesCommunity-sourced migration tables with complete rename mappings:
|
Canonical Migration ReferencesAdding the two canonical migration documents from
Bun Resolution Bug FoundDuring investigation, discovered that bun resolves Effect v3 (3.19.19) at runtime despite the lockfile and
This means all runtime tests in this worktree executed against v3 code while TypeScript checked against v4 types. The |
Schema.make() was removed in Effect v4. The only call site in the codebase was the generic memberSchema.make() in union.ts makeMake.
Effect v4 renamed .make() to .makeUnsafe(). This adds `static make = this.makeUnsafe` to all 135 class definitions and reverts all `new X(...)` call sites back to `X.make(...)`. Includes verification script: tools/verify-no-new-schema-classes.sh
- Merge main to pick up packages/oxlint-rules (PR #132) - Fix v4 API changes in plugin.mjs: Either→Result, Record({key,value})→Record(key,value), Union(a,b)→Union([a,b]), parseJson→fromJsonString - Disable typescript/unbound-method lint rule (false positive on static make = this.makeUnsafe pattern)
The rule checked for `S.Schema<Exact, string>` but v4 uses `S.Codec<Exact, string>`.
- Remove S.is(Class as any) casts where S.is(Class) works directly (18 classes)
- Remove S.decodeSync/encodeSync/decodeUnknownOption casts that aren't needed
- Replace new (ReleaseCommit as any)({}) with ReleaseCommit.make({})
- Fix defaultPublishing() cast by using encoded default ({}) directly
- Remove dead commented-out code (ManifestSchemaMutable)
- Fix lint disable comment for renamed rule (kitz/schema/no-json-parse)
- Keep justified casts: DecodingServices constraints, dynamic schema
construction (pat/compiler), recursive schemas (json), AST traversal
- compiler.ts: use instance .check() method instead of S.check() to leverage concrete Type for filter contravariance; collect array checks into typed arrays; handle null with S.Null; use ServiceFreeSchema for S.is() calls - json.ts: use S.Codec<Value, Value> instead of S.Schema<Value> to carry DecodingServices: never through recursive schemas - npm-registry.ts: use error.response getter instead of manual reason narrowing with as-any - release models: TaggedClass already satisfies S.is constraints; use Sink.drain for mock stdin/getInputFd; Effect.die bottom type needs no cast - fs: readonly segments, Uint8Array from Buffer, Stream.fromEffect for watch, precise normalize<$input> assertion for exhaustive match - sch/tagged.ts: encoding[0]?.to works directly after guard narrows - tex/box.ts: double-assertion for recursive suspend DecodingServices
Summary
Key API migrations
Either(Left/Right)Result(Failure/Success)Effect.eitherEffect.resultEffect.catchAllEffect.catchEffect.orElseFailEffect.mapErrorSchema.Union(...spread)Schema.Union([array])Schema.Record({key, value})Schema.Record(key, value)Schema.parseJsonSchema.fromJsonStringS.transformOrFailS.decodeTo+SchemaGetter.transformOrFailParseResultSchemaIssueSchema.Schema<T, E>(2-arg)Schema.Codec<T, E>Layer.succeed(Tag)(val)Layer.succeed(Tag, val)it.scoped/it.scopedLiveit.effect/it.liveLogger.withMinimumLogLevelCause.YieldableError(runtime)globalThis.ErrorActivityas Effectactivity.asEffect()Lint rule updates
kitz/no-promise-then-chain: Added exclusion forEffect.catch/Effect.finally(v4 renames that collide with Promise method names)kitz/schema-parsing-contract: Accepts bothS.Schema<T, E>andS.Codec<T, E>for theFromStringpatternTest plan
--deny-warningsThis change is