Skip to content

v0.1.3 - #22

Open
NellowTCS wants to merge 11 commits into
mainfrom
0.1.3
Open

v0.1.3#22
NellowTCS wants to merge 11 commits into
mainfrom
0.1.3

Conversation

@NellowTCS

@NellowTCS NellowTCS commented Jul 8, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features
    • Added map and pipe transformations for reactive signals and derived values.
    • Added DOM helpers for finding one or multiple matching elements.
    • Improved two-way input synchronization and cleanup.
  • Bug Fixes
    • Added validation for invalid derived-value paths.
    • Improved reactive dependency-cycle handling and cleanup.
  • Refactor
    • Strengthened type safety across public reactive APIs and debugging tools.
  • Chores
    • Added linting and formatting scripts and updated package entry points.

@codesandbox

codesandbox Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review or Edit in CodeSandbox

Open the branch in Web EditorVS CodeInsiders

Open Preview

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@NellowTCS, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 27 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e84d1b9a-f559-4bcc-b57a-ab3b145472ba

📥 Commits

Reviewing files that changed from the base of the PR and between a8c5de1 and f056313.

📒 Files selected for processing (12)
  • .github/ISSUE_TEMPLATE/bug_report.yml
  • .github/ISSUE_TEMPLATE/feature_request.yml
  • .github/PULL_REQUEST_TEMPLATE.md
  • .github/workflows/ci.yml
  • .github/workflows/pages.yml
  • .nvmrc
  • Build/README.md
  • Build/jest.config.js
  • CHANGELOG.md
  • CODE_OF_CONDUCT.md
  • CONTRIBUTING.md
  • SECURITY.md
📝 Walkthrough

Walkthrough

Adds reactive map/pipe transformations, typed DOM selector helpers, two-way input binding, broader unknown typing, graph cleanup, ESLint configuration, and updated package entrypoints and scripts.

Changes

Reactive APIs and graph tracking

Layer / File(s) Summary
Reactive transformation APIs and graph tracking
Build/src/kernel/*, Build/tests/kernel.test.ts
Signals and derived values gain map/pipe transformations, derived paths are validated, and graph cycle tracking and cache invalidation use typed storage.

DOM helpers and bindings

Layer / File(s) Summary
DOM selectors and two-way input binding
Build/src/dom/*, Build/src/index.ts, Build/tests/bindings.test.ts
Adds typed find/findAll exports and synchronizes input events with signals while disposing both listeners and effects.

Type-safe runtime APIs

Layer / File(s) Summary
Type-safe runtime and public APIs
Build/src/async/*, Build/src/context/*, Build/src/debug/*, Build/src/store/*
Replaces selected any usages with unknown and explicit typing across fallback, context, debug, and reactive-store APIs.

Tooling and packaging

Layer / File(s) Summary
Lint, packaging, and binding cleanup
Build/eslint.config.ts, Build/package.json, Build/src/flow/*, Build/src/kernel/{batch,config,dependency}.ts, BUGS.md
Adds ESLint configuration, updates package metadata and scripts, removes unused bindings, strengthens immutable declarations, and revises the Subscriber documentation.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Signal
  participant Derived
  participant ReactiveGraph
  Signal->>Derived: map(fn) or pipe(fns)
  Derived->>ReactiveGraph: track source dependency
  ReactiveGraph-->>Derived: invalidate on source update
  Derived-->>Signal: expose transformed result
Loading

Possibly related PRs

  • Nisoku/Sairin#1: Related graph-system changes in Build/src/kernel/graph.ts, including subscriber de-duplication and circular-check tracking.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

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.
Title check ❓ Inconclusive The title is just a version number and does not describe the changeset in a meaningful way. Rename the PR to briefly describe the main change, such as the new API additions and type updates in v0.1.3.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 0.1.3

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.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
Build/src/dom/bindings.ts (1)

85-112: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Silent no-op when a non-writable Readable is passed to bindInputValue.

The handleInput listener silently skips writing back to the signal when sig lacks a set method (e.g., a Derived). This means the input→signal direction of the two-way binding is a quiet no-op, which could surprise callers who pass a read-only source. Consider either tightening the parameter type to Signal<string> or logging/warning when a non-writable Readable is detected at bind time.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Build/src/dom/bindings.ts` around lines 85 - 112, Update bindInputValue to
require a writable Signal<string> instead of Readable<string>, removing the
runtime set-method check in handleInput; alternatively, retain Readable support
but detect non-writable signals during binding and emit a clear warning. Ensure
callers and related types are updated consistently so read-only sources cannot
silently no-op.
Build/src/store/reactive.ts (1)

34-103: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Array proxy typeof prop === "number" checks are dead code — index assignment silently fails.

In JavaScript Proxy traps, property keys are always string or symbol; numeric indices like arr[0] arrive as the string "0". This means typeof prop === "number" is always false:

  • get handler (line 45): Harmless — the fallback at line 47 handles string "0" correctly.
  • set handler (line 56): Functional bug — arr[0] = value falls through to return false, so the assignment silently fails (or throws TypeError in strict mode).

This is pre-existing, but the lines were touched in this PR. Consider fixing alongside the type cleanup by checking for string-numeric indices instead.

🔧 Proposed fix for array proxy numeric index handling
       set(target, prop, newValue) {
         if (prop === "length") {
           const arr = [...target.get()] as unknown as T[keyof T] & unknown[];
           arr.length = newValue as number;
           target.set(arr as T[keyof T] & unknown[]);
           return true;
         }
-        if (typeof prop === "number") {
+        if (typeof prop === "string" && /^\d+$/.test(prop)) {
           const arr = [...target.get()] as unknown as T[keyof T] & unknown[];
-          (arr as unknown[])[prop] = newValue;
+          (arr as unknown[])[Number(prop)] = newValue;
           target.set(arr as T[keyof T] & unknown[]);
           return true;
         }
         return false;
       },

Similarly for the get handler:

       get(target, prop) {
         if (prop === "length") return target.get().length;
-        if (typeof prop === "number") return target.get()[prop];
+        if (typeof prop === "string" && /^\d+$/.test(prop)) {
+          return target.get()[Number(prop)];
+        }
         if (prop === "get") return () => target.get();
         return (target.get() as Record<string, unknown>)[prop as string];
       },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Build/src/store/reactive.ts` around lines 34 - 103, Fix array index detection
in the array proxy traps within reactive: Proxy property keys are strings or
symbols, so replace the typeof prop === "number" checks with handling for
numeric string indices (while excluding symbols), ensuring both get and set
correctly access and update array elements. Preserve existing length, get, and
fallback behavior.
🧹 Nitpick comments (3)
Build/src/dom/bindings.ts (1)

96-100: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Simplify the repeated Signal<string> casts in handleInput.

The duck-typing check casts sig to Signal<string> three times. Extracting a small type guard would reduce noise and make the intent clearer.

♻️ Suggested refactor
+ function isWritable<T>(r: Readable<T>): r is Signal<T> {
+   return "set" in r && typeof (r as Signal<T>).set === "function";
+ }

  const handleInput = (e: Event) => {
    const target = e.target as HTMLInputElement | HTMLTextAreaElement;
-   if ("set" in sig && typeof (sig as Signal<string>).set === "function") {
-     (sig as Signal<string>).set(target.value);
+   if (isWritable(sig)) {
+     sig.set(target.value);
    }
  };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Build/src/dom/bindings.ts` around lines 96 - 100, In handleInput, replace the
repeated Signal<string> casts used by the set-property check and invocation with
a small type guard that identifies signals exposing a callable set method, then
invoke set through the narrowed value.
BUGS.md (1)

3-4: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider fixing the misleading docs example.

The note accurately describes the issue, but the underlying problem — a misleading count.subscribe((value) => { ... }) example in the docs — remains an open checkbox. Would you like me to search for and fix the misleading example in the documentation?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@BUGS.md` around lines 3 - 4, Update the documentation example referenced by
the Subscriber note, locating the count.subscribe((value) => { ... }) usage and
removing the value parameter or replacing it with the correct callback
signature. Mark the corresponding checklist item in BUGS.md as completed if the
misleading example is fixed.
Build/src/kernel/derived.ts (1)

144-155: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider renaming the path parameter to avoid shadowing the imported path function.

The path: PathKey parameter shadows the path function imported at line 17. While the error message string literal is unaffected, any future code added inside derived() that needs to call path(...) would resolve to the parameter instead, causing a confusing runtime error.

♻️ Optional rename
 export function derived<T>(
-  path: PathKey,
+  pathKey: PathKey,
   fn: () => T,
   options?: DerivedOptions,
 ): Derived<T> {
-  if (!isPathKey(path)) {
+  if (!isPathKey(pathKey)) {
     throw new Error(
-      `derived() requires a valid PathKey as first argument. Got ${typeof path}. Use path(...) to create a path.`,
+      `derived() requires a valid PathKey as first argument. Got ${typeof pathKey}. Use path(...) to create a path.`,
     );
   }
-  return new Derived(path, fn, options);
+  return new Derived(pathKey, fn, options);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Build/src/kernel/derived.ts` around lines 144 - 155, Rename the path
parameter in derived() to a non-conflicting name such as pathKey, and update its
uses in isPathKey(), the error message, and the Derived constructor call so the
imported path function remains accessible.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Build/package.json`:
- Around line 6-8: Update the package metadata so the top-level types field
matches the CommonJS main entry: change types from dist/index.d.mts to
dist/index.d.cts, or use a neutral dist/index.d.ts if appropriate. Keep the
module field and exports-specific declarations unchanged.

---

Outside diff comments:
In `@Build/src/dom/bindings.ts`:
- Around line 85-112: Update bindInputValue to require a writable Signal<string>
instead of Readable<string>, removing the runtime set-method check in
handleInput; alternatively, retain Readable support but detect non-writable
signals during binding and emit a clear warning. Ensure callers and related
types are updated consistently so read-only sources cannot silently no-op.

In `@Build/src/store/reactive.ts`:
- Around line 34-103: Fix array index detection in the array proxy traps within
reactive: Proxy property keys are strings or symbols, so replace the typeof prop
=== "number" checks with handling for numeric string indices (while excluding
symbols), ensuring both get and set correctly access and update array elements.
Preserve existing length, get, and fallback behavior.

---

Nitpick comments:
In `@BUGS.md`:
- Around line 3-4: Update the documentation example referenced by the Subscriber
note, locating the count.subscribe((value) => { ... }) usage and removing the
value parameter or replacing it with the correct callback signature. Mark the
corresponding checklist item in BUGS.md as completed if the misleading example
is fixed.

In `@Build/src/dom/bindings.ts`:
- Around line 96-100: In handleInput, replace the repeated Signal<string> casts
used by the set-property check and invocation with a small type guard that
identifies signals exposing a callable set method, then invoke set through the
narrowed value.

In `@Build/src/kernel/derived.ts`:
- Around line 144-155: Rename the path parameter in derived() to a
non-conflicting name such as pathKey, and update its uses in isPathKey(), the
error message, and the Derived constructor call so the imported path function
remains accessible.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 124a9c74-9b61-4a29-817f-9e6d3037c885

📥 Commits

Reviewing files that changed from the base of the PR and between 5716995 and a8c5de1.

⛔ Files ignored due to path filters (1)
  • Build/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (21)
  • BUGS.md
  • Build/eslint.config.ts
  • Build/package.json
  • Build/src/async/resource.ts
  • Build/src/context/index.ts
  • Build/src/debug/index.ts
  • Build/src/dom/bindings.ts
  • Build/src/dom/selectors.ts
  • Build/src/flow/index.ts
  • Build/src/index.ts
  • Build/src/kernel/batch.ts
  • Build/src/kernel/config.ts
  • Build/src/kernel/dependency.ts
  • Build/src/kernel/derived.ts
  • Build/src/kernel/graph.ts
  • Build/src/kernel/index.ts
  • Build/src/kernel/signal.ts
  • Build/src/store/map.ts
  • Build/src/store/reactive.ts
  • Build/tests/bindings.test.ts
  • Build/tests/kernel.test.ts

Comment thread Build/package.json
Comment on lines +6 to +8
"main": "dist/index.cjs",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"types": "dist/index.d.mts",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Top-level types field doesn't match main entry point module system.

main points to dist/index.cjs (CommonJS), but types points to dist/index.d.mts (ESM declaration). The top-level types field is a fallback for consumers not using the exports map (older TypeScript or moduleResolution: "node"). It should correspond to the main entry's module system. Use dist/index.d.cts (or a neutral dist/index.d.ts) instead.

🔧 Proposed fix
-  "types": "dist/index.d.mts",
+  "types": "dist/index.d.cts",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"main": "dist/index.cjs",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"types": "dist/index.d.mts",
"main": "dist/index.cjs",
"module": "dist/index.mjs",
"types": "dist/index.d.cts",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Build/package.json` around lines 6 - 8, Update the package metadata so the
top-level types field matches the CommonJS main entry: change types from
dist/index.d.mts to dist/index.d.cts, or use a neutral dist/index.d.ts if
appropriate. Keep the module field and exports-specific declarations unchanged.

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