Skip to content

Add Result utility and fixed race condition in useDelayedToggleState - #27

Merged
Curstantine merged 3 commits into
masterfrom
results
Jul 17, 2026
Merged

Add Result utility and fixed race condition in useDelayedToggleState#27
Curstantine merged 3 commits into
masterfrom
results

Conversation

@Curstantine

Copy link
Copy Markdown
Owner

No description provided.

Curstantine and others added 2 commits July 17, 2026 22:19
Export the Result class as a named export, add `map`, `mapErr`,
`andThen`,
`orElse`, `unwrapOr`, and `unwrapOrElse` methods, and change
`isOk`/`isErr`
to getter properties. Add default error mapper to `run`/`runAsync`,
update
`runAsync` to call `fn` directly without `.call(null)`, and fix an issue
where `null`/`undefined` values were coalescing to the `empty` symbol.

Also fix a race condition in `useDelayedToggleState` by clearing
timeouts
before setting new ones, add a `coverage` entry to `.gitignore`, install
`@vitest/coverage-v8`, and add tests for the new Result methods.
Copilot AI review requested due to automatic review settings July 17, 2026 17:49
@Curstantine Curstantine changed the title Add Result utility Add Result utility and fixed race condition in useDelayedToggleState Jul 17, 2026
@Curstantine
Curstantine merged commit 1ce1d44 into master Jul 17, 2026
1 check passed
@Curstantine
Curstantine deleted the results branch July 17, 2026 17:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a new Result utility in @jabascript/core for functional error handling, and also fixes a race condition in @jabascript/react’s useDelayedToggleState by tracking/cancelling pending timeouts.

Changes:

  • Add Result implementation + tests and export it from @jabascript/core.
  • Fix rapid-toggle race condition in useDelayedToggleState and extend hook tests to cover the scenario.
  • Add Vitest v8 coverage dependency and ignore generated coverage/ output.

Reviewed changes

Copilot reviewed 8 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pnpm-lock.yaml Locks new dev dependency graph changes (Vitest coverage/UI-related additions).
packages/react/tests/client.test.js Adds a new rapid-toggling race-condition regression test for useDelayedToggleState.
packages/react/src/client.js Fixes useDelayedToggleState by storing/clearing timeout handles and cleaning up on unmount.
packages/core/tests/result.test.js Adds comprehensive tests for the new Result API surface (ok/err, map, andThen, etc.).
packages/core/src/result.js Introduces Result implementation and documentation.
packages/core/package.json Exports ./result entrypoint (types + import) for consumers.
package.json Adds @vitest/coverage-v8 dev dependency at the workspace root.
.gitignore Ignores coverage/ output.
.changeset/thirty-llamas-invent.md Declares a patch release for @jabascript/react for the hook race-condition fix.
.changeset/eager-planets-admire.md Declares a patch release for @jabascript/core for the new Result utility.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +55 to +58
constructor(value, error) {
this.error = error ?? empty;
this.value = value ?? empty;
}
Comment on lines +11 to +14
* ## Falsy Values
* Because the constructor uses the nullish coalescing operator (`?? empty`) to fallback,
* passing `null` or `undefined` will cause them to coalesce to the `empty` symbol.
* Other falsy values (such as `0`, `false`, `""`) are preserved.
Comment on lines +123 to +142
it("should handle actual rapid toggling without race conditions", async () => {
const { result, act } = await renderHook(() => useDelayedToggleState(true, 100));

// Start closing (toggled becomes false immediately)
await act(() => result.current[2](false));
expect(result.current[0]).toBe(false);
expect(result.current[1]).toBe(true);

// Reopen immediately (after 10ms, before 100ms delay finishes)
await new Promise((resolve) => setTimeout(resolve, 10));
await act(() => result.current[2](true));
expect(result.current[1]).toBe(true);

// Wait for states to settle (past the 100ms delay)
await new Promise((resolve) => setTimeout(resolve, 150));

// Since we reopened, both should remain true
expect(result.current[0]).toBe(true);
expect(result.current[1]).toBe(true);
});
Comment on lines +1 to +5
---
"@jabascript/react": patch
---

- Fix race condition bug in useDelayedToggleState hook by tracking and clearing pending timeouts.
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