Skip to content

upgrade: keyed package upgrade for Solid 2.0#910

Open
davedbase wants to merge 1 commit into
solidjs-community:nextfrom
davedbase:update/v2/keyed
Open

upgrade: keyed package upgrade for Solid 2.0#910
davedbase wants to merge 1 commit into
solidjs-community:nextfrom
davedbase:update/v2/keyed

Conversation

@davedbase
Copy link
Copy Markdown
Member

@davedbase davedbase commented May 22, 2026

src/index.ts`

  • isServer and JSX type now imported from @solidjs/web
  • Removed on helper (removed in 2.0) and AccessorArray (removed in 2.0)
  • addNewItem: added INTERNAL_OPTIONS (ownedWrite: true) to both createSignal calls for item and index, satisfying Solid 2.0's owned-scope write restriction; also added as Exclude<T, Function> cast required by the new createSignal overloads
  • Rerun: rewrote without the on helper — tracks prevKey manually in a createMemo({ equals: false }); AccessorArray<S> replaced with Accessor<S>[]

package.json

  • Bumped solid-js and @solidjs/web to 2.0.0-beta.13
  • Added @solidjs/web as both dev and peer dependency
  • Test script points to vitest -c ../../configs/vitest.config.solid2.ts (shared config, no local vitest.config.ts)

test/index.test.tsx

  • Signals and stores created outside createRoot to avoid SIGNAL_WRITE_IN_OWNED_SCOPE errors
  • Store setter uses draft-function form setList(() => [...]) for Solid 2.0
  • Tests 3 & 4 replaced mutable-object + createEffect update pattern with reactive getters ({ get value() { return v().value; } }, { get i() { return i(); } }) — getters read signals synchronously without needing deferred effect applies
  • Test 4's change counter uses createMemo (synchronous) instead of createEffect (deferred apply)
  • render imported from @solidjs/web

.changeset/keyed-solid2-migration.md — changeset created marking this as a major version bump.

Summary by CodeRabbit

  • Breaking Changes
    • Major version bump to 2.0.0; now requires Solid.js 2.0 beta.13
    • Import paths for isServer and JSX have changed to @solidjs/web
    • Rerun component props have been updated

Review Change Stack

@davedbase davedbase added this to the Solid 2.0 Migration milestone May 22, 2026
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 22, 2026

🦋 Changeset detected

Latest commit: 8526767

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@solid-primitives/keyed Major
@solid-primitives/immutable Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@davedbase davedbase marked this pull request as ready for review May 22, 2026 12:54
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c1571e66-9e9a-4ff0-ba04-585cd2821389

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • ✅ Review completed - (🔄 Check again to review again)
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

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

🤖 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 `@packages/keyed/src/index.ts`:
- Around line 294-300: The memo used for Rerun is inadvertently tracking any
signals read when evaluating props.children, causing Rerun to subscribe to
child-internal dependencies; to fix, evaluate the child without tracking by
wrapping the child invocation in an untracked context (e.g., Solid's untrack) so
only props.on (and getKey) control reruns—update the anonymous memo callback
that calls getKey and executes props.children to call the child inside
untrack(() => ...) so child signal reads do not become dependencies of the Rerun
memo.
🪄 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 Plus

Run ID: a2da682b-e28f-4da0-86aa-b84f06df1f05

📥 Commits

Reviewing files that changed from the base of the PR and between 8e8ff1e and 8526767.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • .changeset/keyed-solid2-migration.md
  • packages/keyed/package.json
  • packages/keyed/src/index.ts
  • packages/keyed/test/index.test.tsx

Comment on lines +294 to +300
() => {
const currentKey = getKey();
const child = props.children;
return typeof child === "function" && child.length > 0 ? (child as any)(a, b) : child;
}),
const el =
typeof child === "function" && (child as Function).length > 0
? (child as any)(currentKey, prevKey)
: child;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid tracking child-internal dependencies in Rerun memo.

children is executed in a tracked createMemo context, so any signal reads during child evaluation can subscribe Rerun to dependencies unrelated to props.on. That changes rerun semantics versus the old on(...) behavior.

Proposed fix
   return createMemo(
     () => {
       const currentKey = getKey();
       const child = props.children;
-      const el =
-        typeof child === "function" && (child as Function).length > 0
-          ? (child as any)(currentKey, prevKey)
-          : child;
+      const el = untrack(() =>
+        typeof child === "function" && (child as Function).length > 0
+          ? (child as any)(currentKey, prevKey)
+          : child,
+      );
       prevKey = currentKey;
       return el;
     },
     { equals: false },
   ) as unknown as JSX.Element;
🤖 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 `@packages/keyed/src/index.ts` around lines 294 - 300, The memo used for Rerun
is inadvertently tracking any signals read when evaluating props.children,
causing Rerun to subscribe to child-internal dependencies; to fix, evaluate the
child without tracking by wrapping the child invocation in an untracked context
(e.g., Solid's untrack) so only props.on (and getKey) control reruns—update the
anonymous memo callback that calls getKey and executes props.children to call
the child inside untrack(() => ...) so child signal reads do not become
dependencies of the Rerun memo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant