Skip to content

Conversation

@braden-w
Copy link
Collaborator

@braden-w braden-w commented Dec 31, 2025

Migrates from pnpm/vitest to bun for faster test execution and simpler tooling, plus refines the Result type discrimination model.

Tooling Changes:

  • Test runner: vitest → bun test
  • Package manager: pnpm → bun
  • CI workflows updated to use oven-sh/setup-bun

Result Type Refinement:
Simplifies Result discrimination to use error as the primary discriminant:

  • error === null → Ok (always)
  • error !== null → Err (always)
  • { data: null, error: null } → Ok (tiebreaker: error wins)
  • { data: "x", error: "x" } → Err (error wins when both present)

Both data and error work as discriminants in most cases (they're symmetric), but we recommend checking error by default since it handles all cases including Ok<null>.

Documentation:
Updated docs to clarify the symmetric discriminant model with error-first recommendation.

Replace pnpm with bun for package management and vitest with bun:test
for testing. All 80 tests pass with bun's built-in test runner.

Changes:
- Test imports changed from vitest to bun:test (3 files)
- package.json scripts: vitest → bun test, added typecheck script
- CI workflows updated to use oven-sh/setup-bun
- Removed vitest devDependency, added @types/bun
- Deleted pnpm-lock.yaml (bun.lock already existed)

Notes:
- Bun has expectTypeOf built-in (vitest-compatible)
- publish.yml keeps setup-node for npm registry auth (changesets uses npm)
…types

Simplifies Result type discrimination by using error as the only discriminant:
- error === null → Ok (data can be anything, including null)
- error !== null → Err

Changes:
- Added EXPECTED_ERROR_NOT_NULL failure message
- ErrSchema now checks error === null first
- ResultSchema simplified: removed isErrVariant, renamed isOkVariant to isOk
- Updated tests to reflect new validation behavior
…iminant

With error as the sole discriminant, there's no 'invalid' Result state:
- error === null → Ok (always)
- error !== null → Err (always, regardless of data)

Removed:
- INVALID_RESULT check from ResultSchema
- EXPECTED_DATA_NULL check from ErrSchema
- isNeitherNull check from core isResult() function
- Unused failure messages from failures.ts

The Result type is now maximally simple: any object with data and error
properties is valid, and error determines the variant.
Update documentation to reflect that error (not data) is the universal
discriminant for Result types. Data cannot be used reliably because it
can be null as a valid success value (Ok<null>).

Key clarifications:
- error === null → always Ok
- error !== null → always Err
- { data: null, error: null } is Ok<null> (tiebreaker rule)
- { data: x, error: x } is Err (error wins when both present)
…ecommendation

Clarify that both data and error work as discriminants (symmetric), but
recommend checking error by default since it handles all cases including
Ok<null>. Added practical example showing the edge case.

Changes based on documentation review feedback.
@braden-w braden-w merged commit 85331ec into main Dec 31, 2025
2 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