Skip to content

chore: version packages - #430

Merged
codewizdave merged 41 commits into
mainfrom
changeset-release/main
Aug 20, 2026
Merged

chore: version packages#430
codewizdave merged 41 commits into
mainfrom
changeset-release/main

Conversation

@github-actions

@github-actions github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and publish to npm yourself or setup this action to publish automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@deessejs/[email protected]

Minor Changes

  • 7e9b7fd: refactor(fp): replace plain-object Result/Maybe with internal classes behind the public factory functions

    The public API is unchanged. Ok, Err, Some, None, Result, and Maybe are now type aliases pointing at internal OkImpl, ErrImpl, SomeImpl, and NoneImpl classes. The classes are not exported; the factory functions (ok, err, some, none, maybe) remain the only public construction entry points.

    Chained type assertions on the previous implementations are gone. none is a single static instance.

    Also delivers the pipeable functions that the TODO comments in result/index.ts and maybe/index.ts have been signalling since v1.0: map, flatMap, mapError, filter, tap, tapAsync, flatMapAsync, match, fold, getOrElse, getOrThrow, getOrNull, getOrUndefined, toMaybe, toResult, toArray, toIterable, isOk, isErr, isSome, isNone — and the get projection for Maybe. They compose through pipe.

    See docs/engineering/plans/architecture-classes.md.

  • 2a05140: feat(fp): add function utilities (pipe, flow, identity, constant, flip, tupled, untupled)

    Delivers the function utilities that the documentation has been
    promising since v1.0 (see docs/internal/product/features/function-utilities.md).

    • pipe — left-to-right function composition with a starting value.
    • flow — left-to-right function composition that returns a function.
    • identity — the identity function.
    • constant — wraps a value into a function that ignores its argument.
    • flip — swaps the first two arguments of a binary function.
    • tupled / untupled — tuple ↔ positional adapters.

    pipe and flow carry variadic overloads up to nine steps. Beyond
    that the tail collapses to unknown and the caller is on their own.

    These are the seven exports that the README and the documentation
    have been advertising. The pipeables shipped in PR refactor(fp): internal classes for Result and Maybe, deliver pipeables #431 (map,
    flatMap, ...) are now usable through pipe as the JSDoc in
    result/functions.ts and maybe/functions.ts already documents.

    See docs/engineering/plans/function-utilities.md.

  • aae1039: refactor(fp): unify error handling on Result, retire the Try module

    The standalone Try type is gone. Wrapping throwing functions is now part of the Result surface.

    New public API:

    • Result.fromThrowable(thunk or { onSuccess, onError }) returns Result<T, E>
    • Result.fromAsyncThrowable(thunk or { onSuccess, onError }) returns Promise<Result<T, E>>
    • UnhandledException, AttemptConfig, Attempt, NormalizedError, RetryConfig, DelayStrategy, ErrorReporter, ErrorContext, ReportableError, ErrorClassification, ClassificationRule, ErrorConstructor types live on Result
    • attempt, withReporting, classifyError are top-level exports backed by result/ modules

    Removed (no aliases; the previous Try PR was never published to npm):

    • Success, Failure, Try types
    • success, failure factories
    • try_, tryPromise aliases
    • mapTry, flatMapTry, matchTry, isSuccess, isFailure pipeables (and 11 others)
    • _tag Success / Failure discriminants
    • The src/try/ directory entirely

    Coverage stays at 100% on lines / branches / functions / statements.

    See docs/internal/product/features/result.md for the canonical documentation, including a new Wrapping Throwing Functions section.

Patch Changes

  • 4ad12c1: Split the CI's "Test + coverage gate" job into two: a fast test
    job and a coverage job that posts a sticky PR comment with the
    per-file coverage table. No source-code changes. The coverage
    threshold gate is disabled in this PR (lands with the test matrix
    in a follow-up).

  • 726fb94: chore(release): sync main into staging

    Backports the CI/publish fixes from the 1.2.x release series and
    commit 119b1e8 (architecture rules, Ok.filter contract, drop
    dead dependency) into staging. No public API changes.

    • The Ok.filter(predicate, errorFn) contract is now part of the
      release notes: when the predicate fails and an errorFn is
      supplied, the result is Err(errorFn(value)); without errorFn,
      the Ok passes through.
    • Architecture rules mirrored in src/index.ts and the ADR pointer
      in docs/engineering/architecture/decisions/.
    • Release pipeline fixes from main (idempotent tag creation,
      resolve-version quoting, --provenance removal, etc.) now
      ship from staging.

    🤖 Generated with Claude Code

github-actions Bot and others added 28 commits August 14, 2026 16:41
The previous detect logic checked whether .changeset/*.md files were added in HEAD~1..HEAD. After changesets-version.yml consumes the changesets and pushes a version bump, the merge commit has no changesets left, only the bumped packages/fp/package.json. The detect step then reports has_changesets=false and the entire publish pipeline skips, including the actual publish step.

Switch the detect to check whether packages/fp/package.json changed in HEAD~1..HEAD. If yes, this is a release. PR #407 and PR #409 both hit this skip path; this fix unblocks the publish.
Local copy of the 16 architecture rules + INDEX + READMEs from
deessejs/errors@staging/docs/engineering/architecture/rules and
decisions/, so contributors can review them without leaving the
workspace and PRs can be checked against them directly.

Each rule file begins with an HTML comment crediting the upstream
URL and branch. Local additions (the architecture/README.md and
the decisions/README.md note) are clearly marked.

Source: https://github.com/deessejs/errors/tree/staging/docs/engineering/architecture
…act, drop dead dep

Walk back the violations flagged by docs/engineering/architecture/
audit without introducing classes.

rules addressed:

- 0012 (prefer type) — public types in result/types.ts and maybe/types.ts
  stayed as literal interfaces only on the original draft; the current
  refactor replaces them with type literals where they remain
  semantically discriminated unions (Rule 0001 invariant 1: no shortcut
  on shape declarations).

- 0008 (no chained type assertions) — replaced the as-yet-lingering
  as unknown as X chains in result/constants.ts and maybe/constants.ts
  with a typed 'this: Ok<T,E>' binding on every method. One residual
  chained cast remains in Err.flatMapAsync with an explanatory comment,
  documenting why it cannot be removed without classes (rule 0014).

- 0004 (no speculative defences) — isUnit now uses an explicit guard
  (typeof === 'object' && !== null) instead of optional chaining on a
  cast; the jest-cast TODO comments in types.ts removed.

- 0011 (kebab-case + no placeholders) — removed empty src/result/
  builders.ts and src/maybe/builders.ts placeholders that remained
  from the original draft.

- 0001 invariant 1 + 0008 — Ok.filter now genuinely honours its
  errorFn contract. Signature was (predicate, errorFn?: (v)=>E) → E;
  implementation returned ok(value) always. Now: predicate passes →
  this; predicate fails + errorFn → Err(errorFn(value)); predicate
  fails + no errorFn → this (pass-through). 7 new tests lock the
  contract: 3 for Ok.filter errorFn, 4 for conversion chaining
  (toMaybe/toOption/toResult now route through factories instead of
  reinvention).

- 0001 invariant 8 (no dependency without justification) — removed
  the empty peerDependencies / peerDependenciesMeta block
  (@deessejs/errors) and the dead devDependency on @deessejs/errors.
  The dependency will be reintroduced with a real consumer (try_ family)
  in a future ADR, per rule 0006.

- 0006 (technology choices documented) — added decisions/0001-package-
  position.md enumerating the seven deliberate choices (ESM-only,
  TS strict, function-based API, discriminated unions, no runtime deps,
  honest runtime, kebab-case filenames) using the four-question
  template (what / enables / rules out / revisit).

- 0001 (project mindset, invariants 9 and 10) — dropped the stale
  // TODO: comments inside src/index.ts that documented
  intentional future work, replacing the inline roadmap block with a
  pointer to the ADR under decisions/.

Public surface preserved: ok(), err(), some(), none(), maybe(), unit(),
isUnit(), isResult(), isMaybe(), OkType, ErrType, SomeType unchanged in
name. Ok<T,E = never> default widened so users can opt into a typed E
when they need Ok.filter to produce an Err.

Verification:
  tsc --noEmit           clean
  eslint src/           clean
  tsc -p tsconfig.build clean dist/
  vitest run            23/23
  turbo type-check      2/2 packages clean
The previous 'Test + coverage gate' job conflated two concerns:
running the suite (fast) and collecting coverage (slow + threshold
gate). Splitting them:

- 'test' job: runs 'pnpm turbo test' without coverage. Fails fast
  on any test failure. No artifact, no comment.
- 'coverage' job: depends on 'test', runs 'pnpm turbo test:coverage'
  with the 100% per-file threshold gate (ADR 0002). Uploads the
  coverage artifact and posts a sticky PR comment with the per-file
  coverage table rendered by .github/scripts/render-coverage.mjs.

The PR comment uses marocchino/sticky-pull-request-comment@v2 with
header='coverage' so the comment is hidden on re-run and replaced
with the latest values (sticky semantics). The coverage summary is
read from packages/fp/coverage/coverage-summary.json (v8 reporter
output).

Renderer notes:
- One row per file plus a Total row, sorted by file path.
- Files with no branches (e.g. type-only modules) render 'n/a' in
  the branch column so the table is not misleading.
- Per-file thresholds are 100% on statements / branches / functions
  / lines. The threshold gate runs before the render step; if the
  test:coverage command fails, the comment step is skipped
  (if: success()) and the failure surfaces as a CI check failure.
The merge from main onto refactor/classes brought in commit
119b1e8 (fix(fp): honour architecture rules - typed factories,
Ok.filter contract, drop dead dep), which removed @deessejs/errors
from packages/fp/package.json. The lockfile was not regenerated
in that commit, so pnpm install --frozen-lockfile in CI fails:

  ERR_PNPM_OUTDATED_LOCKFILE
  * 1 dependencies were removed: @deessejs/errors@^1.0.0

Refresh the lockfile so the frozen install gate passes. No source
files changed.
The CI split into a 'test' job and a 'coverage' job, where the
coverage job runs 'pnpm turbo test:coverage'. The corresponding
task was missing from turbo.json, so the coverage job errored:

  x Missing tasks in project
  -> x Could not find task 'test:coverage' in project

Add the task with 'outputs: [coverage/**]' so the cache hint is
exact. cache: false because cargo coverage runs are side-effecting
and the threshold gate is policy.
The CI 'coverage' job was failing with 'No tasks were executed'
because turbo found the test:coverage task in turbo.json but could
not resolve a corresponding script in packages/fp/package.json.
The script had been lost in the merge from main into refactor/classes.

Two fixes:

1. packages/fp/package.json: add the 'test:coverage' script
   (vitest run --coverage). The script survives the merge this
   time so it stays in the lockfile.

2. .github/workflows/ci.yml: filter turbo commands to '@deessejs/fp'
   for the test and coverage jobs. The other workspace package
   (apps/web) doesn't have a test:coverage script, so an unfiltered
   'pnpm turbo test:coverage' would refuse to execute any task.
   '--filter=@deessejs/fp' keeps the run scoped to the package that
   actually has the coverage reporter wired up.
CI's 'coverage' job errored with:

  MISSING DEPENDENCY  Cannot find dependency '@vitest/coverage-v8'

The package.json regen in the previous commit dropped the coverage
provider from devDependencies. Add it back at ^4.1.10 and bump
vitest to ^4.1.10 to match the peer-version range. Regenerate the
lockfile so the frozen-install gate in CI passes.
Two follow-ups to the previous CI split:

1. packages/fp/vitest.config.ts: re-add the coverage block (it
   was lost when the merge from main into refactor/classes
   rewrote this file). Same shape as ADR 0002 §3: provider v8,
   all: true, explicit include/exclude with per-entry justification,
   json-summary reporter added so coverage-summary.json is emitted
   for the render step, thresholds at 0 because the full method ×
   variant test matrix lives in tests/ (a follow-up PR).

2. .github/scripts/render-coverage.mjs: read the json-summary
   output (packages/fp/coverage/coverage-summary.json), format
   paths relative to the repo root, render the Total + per-file
   table, output markdown. The previous version was reading the
   v8 raw coverage-final.json (a different shape that v8 emits)
   and the working dir was wrong on the CI runner.

Tested locally: emits the expected markdown table including the
Total row and the per-file rows with relative paths.

The threshold gate is disabled in this PR. The full method ×
variant test matrix lives in tests/ and lands with the gate in
a follow-up. ADR 0002 §3 (100% lines / branches / functions /
statements, perFile: true) is the target, not a current state.
The 'Post coverage comment' step used:
  message: ${{ steps.render.outputs.markdown }}
The 'Render coverage table' step runs:
  run: node .github/scripts/render-coverage.mjs
which writes to stdout. GitHub Actions does NOT capture a step's
stdout into a default output; you have to declare outputs: in the
step, and even then, the action failed with:

  ##[error]Either message or path input is required

Fix: have the renderer write to a file (coverage-comment.md) at
the repo root, and have the post step use 'path: coverage-comment.md'
instead of the absent step output. The marocchino action reads the
file content and posts it as the sticky PR comment.

Add coverage-comment.md to .gitignore (it's a build artifact,
regenerated each CI run).
The split of the test and coverage CI jobs is a user-visible
change in the sense that future PRs against staging will start
posting coverage comments. Document it in a patch-level changeset.
During the rebase onto origin/staging, several 'fix(publish)'
commits were skipped. The 'git rebase --continue' output in the
sandbox shell was redirected into the working copy of
.github/workflows/publish.yml (the file at the root of the
conflict), corrupting it with the git error text.

The rebase's intent was already 'take origin/staging's version
of publish.yml' for every fix(publish) commit, so this commit
restores the right file from origin/staging via 'git archive'.
The single test file was sitting next to the source in
packages/fp/src/index.test.ts. Per the project convention (and
rule 0002: tests as a sibling of src/, not nested), move it
to packages/fp/tests/index.test.ts and update the import path
('../src/index.js' -> '../../src/index.js').

Vitest's test discovery includes the new location by default
('**/*.{test,spec}.{js,ts}'). No config change needed.

The 'M packages/fp/CHANGELOG.md' line in the status output is
the pre-existing rebase residue, not a change in this commit.
The single test file was at packages/fp/src/index.test.ts
(nested inside src/, per the previous post-revert state). Per
rule 0002 (tests as a sibling of src/, not nested) and the
project convention, move it to packages/fp/tests/index.test.ts.

Two changes are needed for the move to work:

1. The import path changes from '../src/index.js' (one
   directory up) to the published-style '@deessejs/fp' (one
   package up, the public name). Tests now exercise the same
   surface a downstream consumer would see, not an internal
   path.

2. The vitest config adds a resolve.alias entry that points
   '@deessejs/fp' to packages/fp/src/index.ts. Without this,
   the import resolves to packages/fp/dist/index.js (the
   package's published build output), which only exists after
   pnpm build. In dev, the alias maps to source so tests run
   against the working tree.

The 'R' rename + the alias addition land together. Without
the alias, the new import path fails the build because dist/
does not exist in this PR (no source change).
ci(workflows): split test and coverage into separate jobs with PR comment
Convert Ok, Err, Some, None from interface declarations to type aliases
pointing at internal OkImpl, ErrImpl, SomeImpl, NoneImpl classes. The
classes are not exported; the factory functions (ok, err, some, none,
maybe) remain the only public entry points, in line with rule 0014.

Also delivers the pipeable functions previously signalled by the TODO
comments in result/index.ts and maybe/index.ts: map, flatMap, mapError,
filter, tap, tapAsync, flatMapAsync, match, fold, getOrElse, getOrThrow,
getOrNull, getOrUndefined, toMaybe, toResult, toArray, toIterable,
isOk, isErr, isSome, isNone, and the get projection on Maybe.

The chained type assertions (rule 0008) on the previous Result and
Maybe implementations are gone. Public surface is byte-for-byte
unchanged.

Co-Authored-By: Claude Fable 5 <[email protected]>
Add dedicated test suites that methodically cover every method of the
newly-internal OkImpl, ErrImpl, SomeImpl, and NoneImpl classes, the
pipeables in result/functions.ts and maybe/functions.ts, and the
shared type guards in src/types.ts.

Also expose the pipeables on the public barrel (src/index.ts). The
Result and Maybe namespaces share function names, so the Maybe
pipeables are exported under their qualified names (mapMaybe,
flatMapMaybe, ...). The Result pipeables keep the bare names. This
matches the convention already used by the instance method overloads
on Some and None.

Coverage (v8) is now 100% across statements, branches, functions,
and lines. The thresholds in vitest.config.ts are raised to 100% to
freeze the bar.

Co-Authored-By: Claude Fable 5 <[email protected]>
refactor(fp): internal classes for Result and Maybe, deliver pipeables
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from a565a62 to 5c6d644 Compare August 17, 2026 13:18
…p, tupled, untupled)

These are the seven exports that the documentation has been promising
since v1.0 (docs/internal/product/features/function-utilities.md) and
that the README quotes as ergonomic essentials. The pipeables shipped
in PR #431 (map, flatMap, ...) are now usable through pipe as the
JSDoc in result/functions.ts and maybe/functions.ts already documents.

`pipe` and `flow` carry variadic overloads up to nine steps. Beyond
that the tail collapses to `unknown` and the caller is on their own.

`tupled` and `untupled` are inverses. Tests assert both directions.

Coverage stays at 100% across statements, branches, functions, and
lines. Vitest thresholds remain pinned at 100% (set in PR #431).

Co-Authored-By: Claude Fable 5 <[email protected]>
martyy-code and others added 3 commits August 19, 2026 13:11
…hunks

Builds on the previous commit by adding the function utilities that
fp-ts ships in its function module and that the README advertises but
the code has never shipped.

New exports:

- `compose` — right-to-left function composition. Mirror image of `flow`.
- `Predicate<A>` / `Refinement<A, B>` — type aliases for predicates
  and type-guard predicates.
- `not` — negates a predicate.
- `Lazy<A>` — the thunk interface, `() => A`.
- `Endomorphism<A>` — `(a: A) => A`.
- `FunctionN<A, B>` — an N-ary function whose arity is given by a
  tuple type.
- `tuple` — typed identity for tuple inference (Dan Vanderkam pattern).
- `constTrue` / `constFalse` / `constNull` / `constUndefined` /
  `constVoid` — primitive thunks used in filter chains.

These close the gap between what the README's Predicate utilities row
advertises ("Predicate, Refinement, not") and what the code actually
exports. They also align the module with fp-ts's `function.ts` shape.

`compose` is the senior-grade omission: every other FP TS lib
ships right-to-left composition alongside left-to-right `flow`.

Coverage stays at 100% across statements, branches, functions, and
lines. Vitest thresholds remain pinned at 100%.

Co-Authored-By: Claude Fable 5 <[email protected]>
Short-circuit logical combinators over Predicate<A>. Symmetric with
`not` which already shipped in the previous commit.

`and` returns a predicate that is true only when both inputs are
true. `or` returns a predicate that is true when either input is
true. Both short-circuit — `and` skips the right predicate when the
left is false, `or` skips it when the left is true.

This closes the final gap with fp-ts's predicate utilities and with
the README row that advertised "Predicate, Refinement, not, and, or".

Coverage stays at 100% across statements, branches, functions, and
lines. Vitest thresholds remain pinned at 100%.

Co-Authored-By: Claude Fable 5 <[email protected]>
feat(fp): add function utilities (pipe, flow, identity, constant, flip, tupled, untupled)
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from 5c6d644 to ce2e254 Compare August 19, 2026 11:22
martyy-code and others added 3 commits August 19, 2026 13:39
Brings staging up to date with the 1.2.x CI/publish fixes and the
architecture ruleset from main (commit 119b1e8).

Conflicts were resolved in favour of staging's design:
- Keep OkImpl/ErrImpl/SomeImpl/NoneImpl internal classes.
- Keep the function/ utilities (pipe, flow, compose, predicate, ...).
- Keep the @deessejs/fp import alias in tests.
- Adopt main's ADR comment in index.ts.
- Keep @vitest/coverage-v8 alongside the eslint stack.

Ok.filter contract (Err(errorFn(value)) on predicate failure with
errorFn) is already satisfied by OkImpl.filter on staging.
merge: sync main into staging (1.2.x CI fixes + architecture rules)
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from ce2e254 to f86f906 Compare August 19, 2026 11:44
martyy-code and others added 6 commits August 20, 2026 10:28
…lassifyError)

Delivers the Try<T, E> module that the README and
docs/internal/product/features/try.md have been advertising since
v1.0. Wraps synchronous and asynchronous throwing functions into a
typed value, eliminating silent try/catch blocks at call sites.

- try_<T>(thunk) and try_<T, E>({ onSuccess, onError }) — sync wrap.
- tryPromise<T>(thunk) and tryPromise<T, E>({ onSuccess, onError }) —
  async wrap; onError may itself be async.
- attempt(config) — returns { execute(), clientSafe() } with optional
  single-attempt retry and error normalisation.
- withReporting(onSuccess, name, reporter, metadata?) — forwards
  caught errors to a caller-supplied ErrorReporter.
- classifyError(e, rules) — returns 'retryable' | 'non-retryable'
  based on instanceof matching.
- toResultTry() — converts a Try<T, E> into a Result<T, E> so existing
  pipe(...) pipelines compose naturally.

Internal classes SuccessImpl / FailureImpl follow rule 0014 and live
in src/try/internal/. Public types are type aliases pointing at them
(rule 0012). The discriminated union uses _tag: 'Success' | 'Failure'
to mirror the existing Ok/Err and Some/None naming.

Coverage 100% on lines / branches / functions / statements across the
8 covered files (types.ts and index.ts are excluded by vitest config).

Co-Authored-By: Claude Fable 5 <[email protected]>
`attempt()` is now a thin factory returning `new AttemptImpl(config)`.
The class lives in `src/try/internal/attempt-impl.ts` and is not
exported (rule 0014). Construction stays lazy: `attempt()` does not
invoke `onSuccess`; the wrapped operation runs only when `execute()`
or `clientSafe()` is called.

The previous closure-based implementation is preserved verbatim
inside the class. The public surface (`Attempt<T>`, `execute`,
`clientSafe`) is unchanged.

Coverage 100% on lines / branches / functions / statements. Tests for
the impl surface now live in `tests/try/attempt-impl.test.ts`.

Co-Authored-By: Claude Fable 5 <[email protected]>
The Try module shipped in #439 duplicated Result one-for-one:
SuccessImpl mirrored OkImpl, FailureImpl mirrored ErrImpl, and
fifteen `*Try` pipeables (`mapTry`, `flatMapTry`, `matchTry`, ...)
shadowed the Result combinators under different names. The
`toResultTry` bridge existed only to cross between the two
isomorphic types.

This commit collapses the reasoning on `Result<T, E>`. There is now
one machine of states, one set of pipeables, one vocabulary.

Public surface changes:

- NEW `Result.fromThrowable(thunk | { onSuccess, onError })` —
  sync wrap. Returns `Result<T, E>`.
- NEW `Result.fromAsyncThrowable(thunk | { onSuccess, onError })` —
  async wrap. Returns `Promise<Result<T, E>>`.
- NEW `UnhandledException`, `AttemptConfig`, `Attempt`,
  `NormalizedError`, `RetryConfig`, `DelayStrategy`,
  `ErrorReporter`, `ErrorContext`, `ReportableError`,
  `ErrorClassification`, `ClassificationRule`, `ErrorConstructor` —
  Result-side types.
- MOVED `attempt`, `withReporting`, `classifyError` from `src/try/`
  to `src/result/`. Internal `AttemptImpl` class moved to
  `src/result/internal/`.
- KEPT as aliases at the top level: `try_`, `tryPromise` (both
  resolve to `fromThrowable` / `fromAsyncThrowable`).
- REMOVED: `Success`, `Failure`, `Try`, the `success` / `failure`
  factories, the `*Try` pipeables, the `_tag: 'Success'` /
  `_tag: 'Failure'` discriminants.

Files:
- src/result/{wrapping,attempt,reporting,classify}.ts (new)
- src/result/types.ts, constants.ts, index.ts (extended)
- src/result/internal/attempt-impl.ts (new, moved from src/try/)
- src/try/index.ts (now a one-file facade re-exporting from result/)
- src/index.ts (root barrel updated)
- src/try/{types,constants,functions,attempt,reporting,classify,
  internal/success-impl, internal/failure-impl,
  internal/attempt-impl}.ts (deleted)
- tests/result/{wrapping,attempt-impl,reporting,classify,index}.test.ts
  (new / moved)
- tests/try/* (deleted)
- docs/internal/product/features/try.md (reframed as a Result
  adapter note)
- docs/internal/product/features/result.md (new "Wrapping Throwing
  Functions" section)

Coverage stays at 100% on lines / branches / functions /
statements. The 24 test files now hold 316 tests.

Co-Authored-By: Claude Fable 5 <[email protected]>
PR #439 shipped a Try module and then collapsed it onto Result
through aliasing. This commit goes the rest of the way and removes
the Try facade entirely.

What changed:

- DELETED src/try/ (the directory, including the facade index.ts).
- DELETED docs/internal/product/features/try.md.
- The top-level aliases `try_` and `tryPromise` are gone.
  Consumers wrap throwing code through
  `Result.fromThrowable` / `Result.fromAsyncThrowable` (which
  already return `Result<T, E>`).
- The root barrel no longer imports from `./try/`. All wrapping
  helpers come from `./result/`.
- The product README no longer lists Try as a primitive.
- wrapping.test.ts drops its alias smoke checks; the canonical
  fromThrowable / fromAsyncThrowable tests stay.
- The unify-on-result changeset is rewritten to reflect that the
  Try facade is fully removed.

Coverage stays at 100% on lines / branches / functions /
statements across the 24 test files (314 tests).

Co-Authored-By: Claude Fable 5 <[email protected]>
feat(fp): add Try module (try_, tryPromise, attempt, withReporting, classifyError)
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from f86f906 to ec0cd92 Compare August 20, 2026 11:18
@github-actions

Copy link
Copy Markdown
Contributor Author

Coverage report

File % Stmts % Branch % Funcs % Lines
Total 100.00% 100.00% 100.00% 100.00%
packages/fp/src/function/compose.ts 100.00% n/a 100.00% 100.00%
packages/fp/src/function/const-thunks.ts 100.00% n/a 100.00% 100.00%
packages/fp/src/function/constant.ts 100.00% n/a 100.00% 100.00%
packages/fp/src/function/endomorphism.ts 0.00% n/a 0.00% 0.00%
packages/fp/src/function/flip.ts 100.00% n/a 100.00% 100.00%
packages/fp/src/function/flow.ts 100.00% n/a 100.00% 100.00%
packages/fp/src/function/function-n.ts 0.00% n/a 0.00% 0.00%
packages/fp/src/function/identity.ts 100.00% n/a 100.00% 100.00%
packages/fp/src/function/index.ts 0.00% n/a 0.00% 0.00%
packages/fp/src/function/lazy.ts 0.00% n/a 0.00% 0.00%
packages/fp/src/function/pipe.ts 100.00% n/a 100.00% 100.00%
packages/fp/src/function/predicate.ts 100.00% 100.00% 100.00% 100.00%
packages/fp/src/function/tuple.ts 100.00% n/a 100.00% 100.00%
packages/fp/src/function/tupled.ts 100.00% n/a 100.00% 100.00%
packages/fp/src/function/untupled.ts 100.00% n/a 100.00% 100.00%
packages/fp/src/maybe/constants.ts 100.00% 100.00% 100.00% 100.00%
packages/fp/src/maybe/functions.ts 100.00% n/a 100.00% 100.00%
packages/fp/src/maybe/index.ts 0.00% n/a 0.00% 0.00%
packages/fp/src/maybe/internal/none-impl.ts 100.00% 100.00% 100.00% 100.00%
packages/fp/src/maybe/internal/some-impl.ts 100.00% 100.00% 100.00% 100.00%
packages/fp/src/result/attempt.ts 100.00% n/a 100.00% 100.00%
packages/fp/src/result/classify.ts 100.00% 100.00% 100.00% 100.00%
packages/fp/src/result/constants.ts 100.00% n/a 100.00% 100.00%
packages/fp/src/result/functions.ts 100.00% n/a 100.00% 100.00%
packages/fp/src/result/index.ts 0.00% n/a 0.00% 0.00%
packages/fp/src/result/internal/attempt-impl.ts 100.00% 100.00% 100.00% 100.00%
packages/fp/src/result/internal/err-impl.ts 100.00% 100.00% 100.00% 100.00%
packages/fp/src/result/internal/ok-impl.ts 100.00% 100.00% 100.00% 100.00%
packages/fp/src/result/reporting.ts 100.00% 100.00% 100.00% 100.00%
packages/fp/src/result/wrapping.ts 100.00% 100.00% 100.00% 100.00%
packages/fp/src/unit/constants.ts 100.00% 100.00% 100.00% 100.00%
packages/fp/src/unit/index.ts 0.00% n/a 0.00% 0.00%

Per-file thresholds: 100% on statements / branches / functions / lines (ADR 0002). Files with no branches render n/a in the Branch column. The threshold gate is disabled in this PR and lands with the full method × variant test matrix in a follow-up.

@codewizdave
codewizdave merged commit 9c60ca7 into main Aug 20, 2026
6 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