Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions .context/plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ Goal: implement `hardtry` incrementally with behavior locked by
- [ ] Phase 6 - `wrap` middleware (full-run scope)
- [ ] Phase 7 - Builder API + root namespace exports
- [ ] Phase 8 - `dispose` with `AsyncDisposableStack`
- [ ] Phase 9 - `all` and `allSettled`
- [ ] Phase 10 - `flow` + `$exit`
- [ ] Phase 11 - `gen`
- [ ] Phase 9 - `gen`
- [ ] Phase 10 - `all` and `allSettled`
- [ ] Phase 11 - `flow` + `$exit`
- [ ] Phase 12 - Hardening + release readiness

## Principles
Expand Down Expand Up @@ -186,7 +186,17 @@ Exit criteria:

- deterministic cleanup guarantees are enforced.

## Phase 9 - `all` and `allSettled`
## Phase 9 - `gen`

1. Implement generator helper for result unwrapping
2. Preserve union typing for accumulated error types
3. Add runtime and type tests

Exit criteria:

- `gen` ergonomics and typing are stable.

## Phase 10 - `all` and `allSettled`

1. Implement `all(tasks)` with named task map
2. Implement `allSettled(tasks)` with native-like settled typing
Expand All @@ -200,7 +210,7 @@ Exit criteria:

- task APIs behave consistently and inference is acceptable.

## Phase 10 - `flow` + `$exit`
## Phase 11 - `flow` + `$exit`

1. Implement `flow(tasks)` orchestration
2. Implement `$exit(value)` early-return mechanism
Expand All @@ -214,16 +224,6 @@ Exit criteria:

- flow control and cleanup semantics are deterministic.

## Phase 11 - `gen`

1. Implement generator helper for result unwrapping
2. Preserve union typing for accumulated error types
3. Add runtime and type tests

Exit criteria:

- `gen` ergonomics and typing are stable.

## Phase 12 - Hardening + release readiness

1. Add race-condition matrix tests
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
"version": "0.0.0",
"description": "A better try-catch",
"keywords": [
"bun",
"library",
"template"
"abort-signal",
"error-handling",
"retry",
"timeout",
"try-catch"
],
"homepage": "https://github.com/adelrodriguez/hardtry#readme",
"bugs": {
Expand All @@ -29,7 +31,6 @@
"dev": "bunup --watch",
"fix": "adamantite fix",
"release": "changeset publish",
"init": "bun run --bun scripts/init.ts",
"test": "bun test",
"test:coverage": "bun test --coverage",
"test:watch": "bun test --watch",
Expand Down
112 changes: 0 additions & 112 deletions scripts/init.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/__tests__/ctx-features.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* oxlint-disable typescript/no-unnecessary-type-parameters */
import { describe, it } from "bun:test"
import { retry, run, signal, timeout, wrap } from "../index"

Expand Down
6 changes: 2 additions & 4 deletions src/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,11 @@ describe("run sync", () => {
).toThrow(Panic)
})

it("throws when sync run receives a Promise-returning function via unsafe cast", () => {
it("throws Panic when sync run receives a Promise-returning function via unsafe cast", () => {
const unsafeRun = run as unknown as (tryFn: () => number) => number
const unsafeTry = (() => Promise.resolve(42)) as unknown as () => number

expect(() => unsafeRun(unsafeTry)).toThrow(
"The try function returned a Promise. Use runAsync() instead of run()."
)
expect(() => unsafeRun(unsafeTry)).toThrow(Panic)
})

it("supports multiple mapped error variants in sync object form", () => {
Expand Down
10 changes: 5 additions & 5 deletions src/lib/__tests__/retry.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { describe, expect, it } from "bun:test"
import type { BuilderConfig } from "../types/builder"
import type { TryCtx } from "../types/core"
import { RetryExhaustedError, TimeoutError } from "../errors"
import { Panic, RetryExhaustedError, TimeoutError } from "../errors"
import {
calculateRetryDelay,
checkIsRetryExhausted,
Expand Down Expand Up @@ -382,7 +382,7 @@ describe("executeRun retry", () => {
expect(mapped).toBe(false)
})

it("throws when sync runner is used with async-required retry policy", () => {
it("throws Panic when sync runner is used with async-required retry policy", () => {
expect(() =>
executeRunSync(
{
Expand All @@ -392,10 +392,10 @@ describe("executeRun retry", () => {
throw new Error("boom")
}
)
).toThrow("Use runAsync() instead of run()")
).toThrow(Panic)
})

it("throws when sync runner is used with jittered constant retry", () => {
it("throws Panic when sync runner is used with jittered constant retry", () => {
expect(() =>
executeRunSync(
{
Expand All @@ -405,7 +405,7 @@ describe("executeRun retry", () => {
throw new Error("boom")
}
)
).toThrow("Use runAsync() instead of run()")
).toThrow(Panic)
})

it("applies linear backoff delays between retries", async () => {
Expand Down
6 changes: 2 additions & 4 deletions src/lib/__tests__/runner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,10 @@ describe("executeRunSync / executeRunAsync", () => {
})
})

it("throws when sync runner returns a promise via unsafe cast", () => {
it("throws Panic when sync runner returns a promise via unsafe cast", () => {
const unsafeSyncFn = (() => Promise.resolve("ok")) as unknown as () => string

expect(() => executeRunSync({}, unsafeSyncFn)).toThrow(
"The try function returned a Promise. Use runAsync() instead of run()."
)
expect(() => executeRunSync({}, unsafeSyncFn)).toThrow(Panic)
})

it("returns CancellationError when signal is already aborted", () => {
Expand Down
7 changes: 4 additions & 3 deletions src/lib/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import type {
SyncRunInput,
SyncRunTryFn,
} from "./types/run"
import { Panic } from "./errors"
import { normalizeRetryPolicy } from "./retry"
import { executeRunAsync, executeRunSync } from "./runner"

Expand Down Expand Up @@ -94,16 +95,16 @@ export class TryBuilder<

all(_tasks: TaskMap): never {
void this.#config
throw new Error("all is not implemented yet")
throw new Panic({ message: "all is not implemented yet" })
}

allSettled(_tasks: TaskMap): never {
void this.#config
throw new Error("allSettled is not implemented yet")
throw new Panic({ message: "allSettled is not implemented yet" })
}

flow(_tasks: TaskMap): never {
void this.#config
throw new Error("flow is not implemented yet")
throw new Panic({ message: "flow is not implemented yet" })
}
}
4 changes: 3 additions & 1 deletion src/lib/dispose.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Panic } from "./errors"

export function createDisposer(): never {
throw new Error("dispose is not implemented yet")
throw new Panic({ message: "dispose is not implemented yet" })
}
4 changes: 3 additions & 1 deletion src/lib/gen.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Panic } from "./errors"

export function executeGen(): never {
throw new Error("gen is not implemented yet")
throw new Panic({ message: "gen is not implemented yet" })
}
Loading
Loading