Skip to content

Implement all and allSettled for parallel task execution#14

Merged
adelrodriguez merged 1 commit intomainfrom
02-23-implement_all_and_allsettled_with_parallel_task_execution
Feb 27, 2026
Merged

Implement all and allSettled for parallel task execution#14
adelrodriguez merged 1 commit intomainfrom
02-23-implement_all_and_allsettled_with_parallel_task_execution

Conversation

@adelrodriguez
Copy link
Copy Markdown
Owner

This pull request implements the all and allSettled functionality for parallel task execution with dependency resolution.

Key Features Added:

  • Parallel task execution: all() runs tasks concurrently and returns when all succeed or first fails
  • Settled mode: settled().all() waits for all tasks to complete regardless of failures, returning SettledResult objects
  • Dependency resolution: Tasks can reference other task results via this.$result.taskName
  • Error handling: all() supports optional catch handlers with context about failed tasks and partial results
  • Builder integration: Works with existing retry, timeout, signal, and wrap configurations
  • Resource management: Provides $disposer and $signal to tasks for cleanup and cancellation

API Examples:

// Basic parallel execution
const result = await try$.all({
  user: () => fetchUser(),
  posts: () => fetchPosts()
})

// With dependencies  
const result = await try$.all({
  user: () => fetchUser(),
  posts: async function() {
    const user = await this.$result.user
    return fetchUserPosts(user.id)
  }
})

// Settled mode (never rejects)
const results = await try$.settled().all({
  task1: () => mightFail(),
  task2: () => alsoMightFail()  
})

// With error handling
const result = await try$.all(tasks, {
  catch: (error, ctx) => ({ 
    error, 
    failedTask: ctx.failedTask,
    completed: ctx.partial 
  })
})

The implementation includes comprehensive test coverage and proper TypeScript inference for task return types and dependency relationships.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 26, 2026

Warning

Rate limit exceeded

@adelrodriguez has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 4 minutes and 44 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 448dcd6 and 63afe82.

📒 Files selected for processing (13)
  • .context/plan.md
  • AGENTS.md
  • src/__tests__/ctx-features.test.ts
  • src/__tests__/index.test.ts
  • src/__tests__/types.test.ts
  • src/index.ts
  • src/lib/__tests__/all.test.ts
  • src/lib/__tests__/run-sync.test.ts
  • src/lib/__tests__/run.test.ts
  • src/lib/all.ts
  • src/lib/builder.ts
  • src/lib/types/all.ts
  • src/lib/types/builder.ts

Walkthrough

Adds parallel task orchestration and settled-mode support: implements executeAll/executeAllSettled, threads a new settled() mode through the builder API, introduces comprehensive types for all/settled, updates public exports, and adds extensive tests covering all/settled behavior, timeouts, cancellation, and type inference.

Changes

Cohort / File(s) Summary
Planning
​.context/plan.md
Marks Phase 10 (all/allSettled -> settled) as completed.
Public surface & exports
src/index.ts
Removes allSettled export, adds settled binding and re-exports AllSettledResult, SettledFulfilled, SettledRejected, SettledResult.
Core runtime: all/settled
src/lib/all.ts
New implementation of executeAll and executeAllSettled: parallel execution, ResultProxy for inter-task dependencies, abort/signal propagation, disposers, catch/partial handling, and settled semantics. Exports related runtime types.
Builder integration
src/lib/builder.ts
Threads Settled generic through WrappedRunBuilder/RunBuilder, adds .settled() method, implements all/allSettled to call executeAll/executeAllSettled, updates method signatures (retry/timeout/signal/wrap) to preserve settled state.
Types for all/settled
src/lib/types/all.ts, src/lib/types/builder.ts
Adds comprehensive types: TaskRecord, TaskFn, TaskResult, ResultProxy, TaskContext, InferredTaskContext, AllValue, AllCatchContext, AllOptions, SettledResult family, and AllSettledResult. Adds settled?: boolean to BuilderConfig and removes old TaskMap alias.
Runtime & builder tests
src/lib/__tests__/all.test.ts, src/lib/__tests__/run.test.ts, src/lib/__tests__/run-sync.test.ts
Adds comprehensive executeAll/executeAllSettled tests and extends run/run-sync tests: parallelism, dependencies, disposers, timeouts, cancellation, catch behavior, retry/timeout combos, and settled-specific scenarios.
Integration & type tests
src/__tests__/index.test.ts, src/__tests__/types.test.ts
Reorganizes and expands integration tests (function/object forms), adds all()/settled().all() coverage, updates type inference tests for all/settled and sync-like signatures, introduces sleep helper and more gen integration tests.
Test removals
src/__tests__/ctx-features.test.ts
Deleted older ctx-features test file (removed coverage of retry-visibility scenarios).

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: implementing all and allSettled functionality for parallel task execution, which matches the core additions in the changeset.
Description check ✅ Passed The description is directly related to the changeset, providing context about parallel task execution, dependency resolution, error handling, and builder integration with relevant API examples.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 02-23-implement_all_and_allsettled_with_parallel_task_execution

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Owner Author

adelrodriguez commented Feb 26, 2026

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Feb 26, 2026

Greptile Summary

This PR successfully implements Phase 10 of the hardtry roadmap, adding parallel task execution with all() and allSettled() functionality.

Key Changes:

  • Parallel execution: Tasks run concurrently with Promise.all or Promise.allSettled semantics
  • Dependency resolution: Tasks access other results via this.$result.taskName using a clever Proxy-based mechanism
  • Resource management: Provides $disposer (AsyncDisposableStack) and $signal (AbortSignal) to all tasks
  • Error handling: all() fails fast on first error; settled().all() waits for all tasks and returns SettledResult objects
  • Builder integration: Works seamlessly with existing retry(), timeout(), signal(), and wrap() configurations
  • Type safety: Excellent TypeScript inference for task return types, dependencies, and settled results

Implementation Quality:

  • Clean architecture with AllExecution class managing execution state
  • Proper signal propagation from external signals to internal controller
  • Correct disposal cleanup using await using and AsyncDisposableStack
  • Comprehensive test coverage (800+ lines) including edge cases, error paths, and race conditions
  • Type tests verify inference and prevent invalid usage patterns

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The implementation is production-ready with excellent test coverage, proper error handling, and clean architecture. The code follows project conventions, has comprehensive type safety, and handles complex scenarios like circular dependencies, signal propagation, and resource cleanup correctly.
  • No files require special attention

Important Files Changed

Filename Overview
src/lib/all.ts New file implementing parallel task execution with dependency resolution, signal propagation, and disposer cleanup. Well-structured with comprehensive error handling.
src/lib/types/all.ts New file defining type contracts for all() and allSettled(). Type-safe task validation, result inference, and settled result types.
src/lib/builder.ts Added all() method to both RunBuilder and WrappedRunBuilder with proper settled mode handling and type-safe option enforcement.
src/lib/tests/all.test.ts Comprehensive test coverage for both executeAll and executeAllSettled, including dependency resolution, error handling, signals, disposers, and edge cases.
src/tests/index.test.ts Added integration tests for try$.all() and try$.settled().all() with builder chain combinations (retry, timeout, signal).
src/tests/types.test.ts Added type inference tests for all() and settled().all(), verifying result types, $result proxy types, and catch context types.

Sequence Diagram

sequenceDiagram
    participant User
    participant Builder
    participant AllExecution
    participant Task1
    participant Task2
    participant ResultProxy
    participant Disposer

    User->>Builder: try$.all({ task1, task2 })
    Builder->>AllExecution: new AllExecution(config, tasks, settled)
    AllExecution->>AllExecution: Setup signals & timeout
    AllExecution->>AllExecution: Create disposer stack
    
    par Parallel Task Execution
        AllExecution->>Task1: #runTask(task1)
        Task1->>Task1: Execute function
        Task1->>AllExecution: #handleResult(task1, value)
        AllExecution->>ResultProxy: Notify resolvers
    and
        AllExecution->>Task2: #runTask(task2)
        Task2->>ResultProxy: await this.$result.task1
        ResultProxy->>AllExecution: #waitForResult(task1)
        AllExecution-->>Task2: Return task1 result
        Task2->>Task2: Execute with dependency
        Task2->>AllExecution: #handleResult(task2, value)
    end
    
    AllExecution->>Disposer: disposeAsync()
    Disposer->>Disposer: Cleanup resources
    AllExecution-->>User: Return all results
Loading

Last reviewed commit: 63afe82

@adelrodriguez adelrodriguez force-pushed the 02-23-add_gen_integration_tests_and_improve_error_handling branch from 89be563 to e56039e Compare February 26, 2026 10:45
@adelrodriguez adelrodriguez force-pushed the 02-23-implement_all_and_allsettled_with_parallel_task_execution branch from 6bbd3a8 to 2873fc1 Compare February 26, 2026 10:45
@adelrodriguez adelrodriguez force-pushed the 02-23-add_gen_integration_tests_and_improve_error_handling branch from e56039e to 43a6547 Compare February 26, 2026 10:52
@adelrodriguez adelrodriguez force-pushed the 02-23-implement_all_and_allsettled_with_parallel_task_execution branch from 2873fc1 to 663957e Compare February 26, 2026 10:53
@adelrodriguez adelrodriguez force-pushed the 02-23-add_gen_integration_tests_and_improve_error_handling branch from 43a6547 to ce12ab4 Compare February 26, 2026 10:54
@adelrodriguez adelrodriguez force-pushed the 02-23-implement_all_and_allsettled_with_parallel_task_execution branch from 663957e to 4cf130f Compare February 26, 2026 10:54
@adelrodriguez adelrodriguez force-pushed the 02-23-add_gen_integration_tests_and_improve_error_handling branch from ce12ab4 to b198238 Compare February 26, 2026 11:31
@adelrodriguez adelrodriguez force-pushed the 02-23-implement_all_and_allsettled_with_parallel_task_execution branch from 4cf130f to c973b99 Compare February 26, 2026 11:31
@adelrodriguez adelrodriguez force-pushed the 02-23-add_gen_integration_tests_and_improve_error_handling branch from b198238 to ef4cffc Compare February 26, 2026 11:34
@adelrodriguez adelrodriguez force-pushed the 02-23-implement_all_and_allsettled_with_parallel_task_execution branch from c973b99 to acd7c5b Compare February 26, 2026 11:35
@adelrodriguez adelrodriguez force-pushed the 02-23-add_gen_integration_tests_and_improve_error_handling branch from ef4cffc to dc0308f Compare February 26, 2026 11:38
@adelrodriguez adelrodriguez force-pushed the 02-23-add_gen_integration_tests_and_improve_error_handling branch 3 times, most recently from 3a82f81 to 884bdb2 Compare February 26, 2026 14:30
@adelrodriguez adelrodriguez force-pushed the 02-23-implement_all_and_allsettled_with_parallel_task_execution branch from 5ac8e16 to af41db4 Compare February 26, 2026 14:30
@adelrodriguez adelrodriguez changed the base branch from 02-23-add_gen_integration_tests_and_improve_error_handling to graphite-base/14 February 26, 2026 14:35
@adelrodriguez adelrodriguez force-pushed the 02-23-implement_all_and_allsettled_with_parallel_task_execution branch 2 times, most recently from e6f2861 to ad1f17c Compare February 26, 2026 14:36
@adelrodriguez adelrodriguez changed the base branch from graphite-base/14 to main February 26, 2026 14:36
@adelrodriguez adelrodriguez force-pushed the 02-23-implement_all_and_allsettled_with_parallel_task_execution branch from ad1f17c to 075c5af Compare February 26, 2026 14:37
@adelrodriguez
Copy link
Copy Markdown
Owner Author

@greptileai review
@coderabbitai review
@codex review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 26, 2026

@adelrodriguez, I'll review the changes in this PR.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
src/lib/__tests__/run.test.ts (1)

6-9: Consider importing the existing sleep helper.

A sleep utility already exists in src/lib/utils.ts (lines 6-14). While having a local copy in tests provides isolation, importing the shared utility would reduce duplication and ensure consistent behavior.

♻️ Optional: Import shared sleep utility
 import { describe, expect, it } from "bun:test"
 import type { TryCtx } from "../types/core"
 import { CancellationError, Panic, TimeoutError, UnhandledException } from "../errors"
 import { executeRun } from "../run"
+import { sleep } from "../utils"

-const sleep = (ms: number) =>
-  new Promise<void>((resolve) => {
-    setTimeout(resolve, ms)
-  })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/__tests__/run.test.ts` around lines 6 - 9, Tests define a local sleep
function that duplicates the shared helper; remove the local sleep declaration
in run.test.ts and import the existing sleep utility instead (import { sleep }
from the shared utils module), updating the top-of-file imports so tests use the
single exported sleep function to avoid duplication and ensure consistent
behavior with the shared sleep implementation.
src/lib/builder.ts (1)

198-221: Consider extracting shared all() logic.

The all() implementation in RunBuilder is identical to WrappedRunBuilder. While the duplication is acceptable for this PR, consider extracting the shared logic to a helper function in a future refactor to reduce maintenance burden.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/builder.ts` around lines 198 - 221, Extract the duplicated all()
logic from RunBuilder and WrappedRunBuilder into a single helper (e.g.,
runAllHelper) that accepts the builder config (this.#config), the tasks
parameter, and the optional AllOptions, then inside the helper perform the
settled check and call executeAllSettled/executeAll accordingly (preserve the
existing conditional return typing and casts), and replace both classes' all()
implementations to delegate to this new helper while keeping the same generic
signatures and behavior.
src/lib/__tests__/all.test.ts (1)

4-8: Consider importing sleep from ../utils instead of duplicating.

A sleep utility already exists in src/lib/utils.ts. Importing it would reduce duplication, unless test isolation is intentionally preferred here.

♻️ Proposed refactor
 import { describe, expect, it } from "bun:test"
 import { executeAll, executeAllSettled } from "../all"
+import { sleep } from "../utils"
-
-function sleep(ms: number): Promise<void> {
-  return new Promise((resolve) => {
-    setTimeout(resolve, ms)
-  })
-}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/__tests__/all.test.ts` around lines 4 - 8, Remove the duplicate local
sleep implementation in the test and use the existing exported sleep utility
instead: delete the function sleep(...) in the test, add an import for the
exported sleep symbol from the project's utils module, and update any test
usages to call that imported sleep function so there is a single shared
implementation.
src/__tests__/index.test.ts (1)

9-13: Consider importing sleep from a shared location.

This is the second duplicate of the sleep utility. Consider either importing from ../lib/utils or creating a shared test utilities module.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/__tests__/index.test.ts` around lines 9 - 13, The test defines a
duplicate sleep utility function named sleep; instead of keeping this local
copy, remove the local function and import the shared sleep implementation (or a
shared test helper) from the existing utility module (e.g., ../lib/utils or the
shared test utilities module) where the canonical sleep is defined; update the
test file to import sleep and use that symbol so there's a single source of
truth for the sleep utility across tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/__tests__/all.test.ts`:
- Around line 267-293: The timing assertion is flaky; either raise the tolerance
or compare against a measured sequential baseline: in the "runs truly in
parallel" test (functions a, b, c, executeAll, sleep) replace the fixed
expect(elapsed).toBeLessThan(120) with a more robust check — e.g., run the same
three tasks serially to compute sequentialElapsed (await a(); await b(); await
c()) and then assert that parallel elapsed is meaningfully less than
sequentialElapsed (for example expect(elapsed).toBeLessThan(sequentialElapsed -
20)), or simply increase the threshold to a safer value like 250ms to avoid CI
timing variance.

---

Nitpick comments:
In `@src/__tests__/index.test.ts`:
- Around line 9-13: The test defines a duplicate sleep utility function named
sleep; instead of keeping this local copy, remove the local function and import
the shared sleep implementation (or a shared test helper) from the existing
utility module (e.g., ../lib/utils or the shared test utilities module) where
the canonical sleep is defined; update the test file to import sleep and use
that symbol so there's a single source of truth for the sleep utility across
tests.

In `@src/lib/__tests__/all.test.ts`:
- Around line 4-8: Remove the duplicate local sleep implementation in the test
and use the existing exported sleep utility instead: delete the function
sleep(...) in the test, add an import for the exported sleep symbol from the
project's utils module, and update any test usages to call that imported sleep
function so there is a single shared implementation.

In `@src/lib/__tests__/run.test.ts`:
- Around line 6-9: Tests define a local sleep function that duplicates the
shared helper; remove the local sleep declaration in run.test.ts and import the
existing sleep utility instead (import { sleep } from the shared utils module),
updating the top-of-file imports so tests use the single exported sleep function
to avoid duplication and ensure consistent behavior with the shared sleep
implementation.

In `@src/lib/builder.ts`:
- Around line 198-221: Extract the duplicated all() logic from RunBuilder and
WrappedRunBuilder into a single helper (e.g., runAllHelper) that accepts the
builder config (this.#config), the tasks parameter, and the optional AllOptions,
then inside the helper perform the settled check and call
executeAllSettled/executeAll accordingly (preserve the existing conditional
return typing and casts), and replace both classes' all() implementations to
delegate to this new helper while keeping the same generic signatures and
behavior.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7d82ad7 and 075c5af.

📒 Files selected for processing (11)
  • .context/plan.md
  • src/__tests__/index.test.ts
  • src/__tests__/types.test.ts
  • src/index.ts
  • src/lib/__tests__/all.test.ts
  • src/lib/__tests__/run-sync.test.ts
  • src/lib/__tests__/run.test.ts
  • src/lib/all.ts
  • src/lib/builder.ts
  • src/lib/types/all.ts
  • src/lib/types/builder.ts

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 075c5af582

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@adelrodriguez adelrodriguez force-pushed the 02-23-implement_all_and_allsettled_with_parallel_task_execution branch from 075c5af to 448dcd6 Compare February 27, 2026 10:43
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (6)
src/lib/__tests__/all.test.ts (1)

5-9: Consider importing the shared sleep utility.

Same duplication issue as in run.test.ts. The sleep helper exists in src/lib/utils.ts.

♻️ Proposed refactor
+import { sleep } from "../utils"
+
-function sleep(ms: number): Promise<void> {
-  return new Promise((resolve) => {
-    setTimeout(resolve, ms)
-  })
-}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/__tests__/all.test.ts` around lines 5 - 9, Replace the duplicated
local sleep implementation in all.test.ts with the shared utility: remove the
local function sleep(ms: number) and add an import for the shared sleep exported
from the utils module, then use that imported sleep everywhere (matching how
run.test.ts was refactored); ensure the imported symbol name is correct and
exported signature (Promise<void>) is used so existing awaits still work.
src/lib/builder.ts (1)

113-136: Consider extracting duplicated all() logic into a shared helper.

The all() method implementation is identical in both WrappedRunBuilder and RunBuilder. A private helper function could reduce duplication.

♻️ Suggested extraction pattern
function executeAllWithConfig<T extends TaskRecord, C, Settled extends boolean>(
  config: BuilderConfig,
  tasks: T & ThisType<InferredTaskContext<T>>,
  options?: AllOptions<T, C>
): Promise<Settled extends true ? AllSettledResult<T> : { [K in keyof T]: TaskResult<T[K]> } | C> {
  if (config.settled) {
    return executeAllSettled(config, tasks) as any
  }
  if (options) {
    return executeAll(config, tasks, options) as any
  }
  return executeAll(config, tasks) as any
}

Also applies to: 202-225

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/builder.ts` around lines 113 - 136, Duplicate logic in the
all<T...>() method of both RunBuilder and WrappedRunBuilder should be extracted
into a single helper: create a private/shared function (e.g.,
executeAllWithConfig) that accepts the BuilderConfig (this.#config), tasks, and
optional AllOptions and returns the same conditional Promise type; inside the
helper call executeAllSettled(config, tasks) when config.settled is true,
otherwise call executeAll(config, tasks, options) if options is provided or
executeAll(config, tasks) when not, then replace both class-level all methods to
delegate to this new helper (referencing the existing symbols all,
WrappedRunBuilder, RunBuilder, executeAll, executeAllSettled, and
BuilderConfig).
src/lib/all.ts (2)

182-189: Consider clearing resolver queue after rejection as well.

Same cleanup suggestion applies to #handleError.

♻️ Proposed refactor
     if (rejected) {
       for (const [, reject] of rejected) {
         reject(error)
       }
+      this.#resolvers.delete(taskName)
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/all.ts` around lines 182 - 189, The rejection branch in the function
that looks up const rejected = this.#resolvers.get(taskName) currently iterates
and calls each reject(error) but leaves the resolver queue intact; after
rejecting, remove the entry from this.#resolvers (e.g.,
this.#resolvers.delete(taskName)) so pending resolvers are cleared to avoid
memory leaks and duplicate handling, and apply the same cleanup in the
`#handleError` method—after rejecting any stored resolvers there, delete the
corresponding key from this.#resolvers or clear that resolver collection.

165-172: Consider clearing resolver queue after fulfillment to aid garbage collection.

After resolving all waiters in #handleResult, the resolver array remains in the map. While this doesn't affect correctness (the execution is short-lived), clearing the entry allows earlier GC of the callback closures.

♻️ Proposed refactor
     const fulfilled = this.#resolvers.get(taskName)
 
     if (fulfilled) {
       for (const [resolve] of fulfilled) {
         resolve(value)
       }
+      this.#resolvers.delete(taskName)
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/all.ts` around lines 165 - 172, In `#handleResult`, after iterating and
calling each resolve from the array retrieved via this.#resolvers.get(taskName),
remove the map entry so the resolver closures can be GC'd — e.g., after the for
loop call this.#resolvers.delete(taskName) (or set the array to an empty array)
to clear the resolver queue associated with taskName; keep the existing
resolve(value) loop unchanged.
src/lib/__tests__/run.test.ts (1)

6-9: Consider importing the shared sleep utility instead of duplicating it.

A sleep helper already exists in src/lib/utils.ts (lines 6-14). Importing it would reduce duplication and ensure consistent behavior across tests.

♻️ Proposed refactor
-const sleep = (ms: number) =>
-  new Promise<void>((resolve) => {
-    setTimeout(resolve, ms)
-  })
+import { sleep } from "../utils"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/__tests__/run.test.ts` around lines 6 - 9, Remove the duplicated
local sleep implementation in run.test.ts and import the shared sleep helper
from the project's utils (the exported sleep function in utils.ts); update the
top-of-file imports to include sleep, delete the local const sleep = ...
declaration, and ensure existing tests continue to call sleep as before so they
use the centralized utility.
src/__tests__/index.test.ts (1)

9-13: Consider importing the shared sleep utility.

Same duplication as other test files. Import from src/lib/utils.ts for consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/__tests__/index.test.ts` around lines 9 - 13, Replace the local function
sleep in this test with the shared exported sleep utility: remove the function
sleep(...) declaration and add an import for the shared sleep helper (use the
project's utils module export named sleep), then update any calls to use the
imported sleep; this keeps tests consistent and avoids duplication.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/__tests__/all.test.ts`:
- Around line 434-456: The "timeout config" test that calls executeAllSettled is
placed inside the executeAll describe block; move the entire it(...) block that
references executeAllSettled (the async test named "rejects with TimeoutError
when tasks exceed configured timeout") out of the executeAll describe and into
the executeAllSettled describe so the test suite matches the function under test
and removes the duplicate "timeout config" describe in executeAll.

---

Nitpick comments:
In `@src/__tests__/index.test.ts`:
- Around line 9-13: Replace the local function sleep in this test with the
shared exported sleep utility: remove the function sleep(...) declaration and
add an import for the shared sleep helper (use the project's utils module export
named sleep), then update any calls to use the imported sleep; this keeps tests
consistent and avoids duplication.

In `@src/lib/__tests__/all.test.ts`:
- Around line 5-9: Replace the duplicated local sleep implementation in
all.test.ts with the shared utility: remove the local function sleep(ms: number)
and add an import for the shared sleep exported from the utils module, then use
that imported sleep everywhere (matching how run.test.ts was refactored); ensure
the imported symbol name is correct and exported signature (Promise<void>) is
used so existing awaits still work.

In `@src/lib/__tests__/run.test.ts`:
- Around line 6-9: Remove the duplicated local sleep implementation in
run.test.ts and import the shared sleep helper from the project's utils (the
exported sleep function in utils.ts); update the top-of-file imports to include
sleep, delete the local const sleep = ... declaration, and ensure existing tests
continue to call sleep as before so they use the centralized utility.

In `@src/lib/all.ts`:
- Around line 182-189: The rejection branch in the function that looks up const
rejected = this.#resolvers.get(taskName) currently iterates and calls each
reject(error) but leaves the resolver queue intact; after rejecting, remove the
entry from this.#resolvers (e.g., this.#resolvers.delete(taskName)) so pending
resolvers are cleared to avoid memory leaks and duplicate handling, and apply
the same cleanup in the `#handleError` method—after rejecting any stored resolvers
there, delete the corresponding key from this.#resolvers or clear that resolver
collection.
- Around line 165-172: In `#handleResult`, after iterating and calling each
resolve from the array retrieved via this.#resolvers.get(taskName), remove the
map entry so the resolver closures can be GC'd — e.g., after the for loop call
this.#resolvers.delete(taskName) (or set the array to an empty array) to clear
the resolver queue associated with taskName; keep the existing resolve(value)
loop unchanged.

In `@src/lib/builder.ts`:
- Around line 113-136: Duplicate logic in the all<T...>() method of both
RunBuilder and WrappedRunBuilder should be extracted into a single helper:
create a private/shared function (e.g., executeAllWithConfig) that accepts the
BuilderConfig (this.#config), tasks, and optional AllOptions and returns the
same conditional Promise type; inside the helper call executeAllSettled(config,
tasks) when config.settled is true, otherwise call executeAll(config, tasks,
options) if options is provided or executeAll(config, tasks) when not, then
replace both class-level all methods to delegate to this new helper (referencing
the existing symbols all, WrappedRunBuilder, RunBuilder, executeAll,
executeAllSettled, and BuilderConfig).

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 075c5af and 448dcd6.

📒 Files selected for processing (12)
  • .context/plan.md
  • src/__tests__/ctx-features.test.ts
  • src/__tests__/index.test.ts
  • src/__tests__/types.test.ts
  • src/index.ts
  • src/lib/__tests__/all.test.ts
  • src/lib/__tests__/run-sync.test.ts
  • src/lib/__tests__/run.test.ts
  • src/lib/all.ts
  • src/lib/builder.ts
  • src/lib/types/all.ts
  • src/lib/types/builder.ts
💤 Files with no reviewable changes (1)
  • src/tests/ctx-features.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/index.ts
  • src/lib/types/builder.ts
  • .context/plan.md

Copy link
Copy Markdown

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

12 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@adelrodriguez adelrodriguez force-pushed the 02-23-implement_all_and_allsettled_with_parallel_task_execution branch from 448dcd6 to 63afe82 Compare February 27, 2026 11:06
Copy link
Copy Markdown
Owner Author

@coderabbitai review
@greptileai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 27, 2026

@adelrodriguez, I'll review the changes in this PR.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@adelrodriguez adelrodriguez merged commit 3c15dd3 into main Feb 27, 2026
8 checks passed
@adelrodriguez adelrodriguez deleted the 02-23-implement_all_and_allsettled_with_parallel_task_execution branch February 27, 2026 11:15
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.

1 participant