# Files changed · Pull request \#3 · versecafe/quoin

[View on GitCafe](https://git.cafe/versecafe/quoin/pull/3/diffs)

Repository: [versecafe/quoin](https://git.cafe/versecafe/quoin)

Visibility: public

[Release quoin-ui 0.4.0 with Solid 2 RC support](https://git.cafe/versecafe/quoin/pull/3.md)

Version: 1

Head commit: 62599becdc82824f5d54667ea493285cb71dd825

Base commit: 7545d17e8aecad98f126e982a34b9b5973519311

Comparison base: 7545d17e8aecad98f126e982a34b9b5973519311

Showing up to 20 entries from this revision. If the pull request changes, reopen the first page before continuing.

## README.md

Status: modified; +10; −10

````diff
@@ -1,13 +1,13 @@
 # quoin
 
-[![Socket Badge](https://badge.socket.dev/npm/package/quoin-ui/0.3.0)](https://badge.socket.dev/npm/package/quoin-ui/0.3.0)
+[![Socket Badge](https://badge.socket.dev/npm/package/quoin-ui/0.4.0)](https://badge.socket.dev/npm/package/quoin-ui/0.4.0)
 
 An unstyled, accessible UI component library for [SolidJS](https://www.solidjs.com) — a faithful port of [Base UI](https://base-ui.com), built on Solid 2.0's fine-grained reactivity.
 
 You bring the styles and the markup; quoin brings the behavior, accessibility, and positioning. Every component is a set of composable parts you assemble yourself, so you keep full control over the DOM.
 
 > [!WARNING]
+> quoin is pre-release software (`0.4.x`). The API is still settling and breaking changes should be expected. It targets the `solid-js@2.0.0-rc` line and currently carries one development-build context patch (see `patches/`).
-> quoin is pre-release software (`0.3.x`). The API is still settling and breaking changes should be expected. It targets the `solid-js@2.0.0-beta` line and currently carries one development-build context patch (see `patches/`).
 
 ## Installation
 
@@ -20,12 +20,12 @@
 quoin targets **Solid 2.0** and expects the following peers:
 
 ```bash
-bun install solid-js@2.0.0-beta.28 @solidjs/web@2.0.0-beta.28 @solidjs/signals@2.0.0-beta.28
+bun install solid-js@2.0.0-rc.1 @solidjs/web@2.0.0-rc.1 @solidjs/signals@2.0.0-rc.1
 ```
 
+### Required patch (Solid RC)
-### Required patches (Solid beta)
 
-quoin relies on one small fix to the Solid 2.0 beta: the `createContext`
+quoin relies on one small fix to the Solid 2.0 RC: the `createContext`
 provider must read its value outside the provider root's tracking scope.
 Until that lands upstream, **bun** consumers should apply the included patch
 to avoid strict-read diagnostics and accidental provider-root subscriptions.
@@ -42,7 +42,7 @@
 // package.json
 {
   "patchedDependencies": {
-    "solid-js@2.0.0-beta.28": "patches/solid-js@2.0.0-beta.28.patch"
+    "solid-js@2.0.0-rc.1": "patches/solid-js@2.0.0-rc.1.patch"
   }
 }
 ```
@@ -165,10 +165,10 @@
 ## Required Solid patch
 
 > [!IMPORTANT]
+> quoin carries one fix against `solid-js@2.0.0-rc.1`. Package-manager patch settings do not transfer from a published dependency, so consumers that run Solid's development build should apply the included patch themselves.
-> quoin carries one fix against `solid-js@2.0.0-beta.28`. Package-manager patch settings do not transfer from a published dependency, so consumers that run Solid's development build should apply the included patch themselves.
 
 The patch wraps the context value write in `untrack`, preventing the provider
-root from subscribing to signals read through `props.value`. Beta.28 already
+root from subscribing to signals read through `props.value`. The RC already
 contains the former Portal and async rejection fixes.
 
 ### Applying them
@@ -180,7 +180,7 @@
 ```jsonc
 {
   "patchedDependencies": {
+    "solid-js@2.0.0-rc.1": "patches/solid-js@2.0.0-rc.1.patch"
-    "solid-js@2.0.0-beta.28": "patches/solid-js@2.0.0-beta.28.patch"
   }
 }
 ```
@@ -191,4 +191,4 @@
 `untrack(() => setContext(provider, props.value))`.
 
 > [!NOTE]
-> This patch is pinned to `2.0.0-beta.28`. Re-confirm and re-derive or remove it on every Solid bump. Full rationale lives in [`solid/patches.md`](./solid/patches.md).
+> This patch is pinned to `2.0.0-rc.1`. Re-confirm and re-derive or remove it on every Solid bump. Full rationale lives in [`solid/patches.md`](./solid/patches.md).
````

## bun.lock

Status: modified; +37; −34

```diff
@@ -13,16 +13,19 @@
         "@babel/preset-typescript": "7.29.7",
         "@biomejs/biome": "2.4.16",
         "@happy-dom/global-registrator": "20.9.0",
+        "@solidjs/signals": "2.0.0-rc.1",
+        "@solidjs/web": "2.0.0-rc.1",
         "@types/babel__core": "7.20.5",
         "@typescript/native-preview": "7.0.0-dev.20260527.2",
+        "babel-preset-solid": "2.0.0-rc.1",
-        "babel-preset-solid": "2.0.0-beta.28",
         "bun-types": "latest",
+        "solid-js": "2.0.0-rc.1",
         "typescript": "6.0.3",
       },
       "peerDependencies": {
-        "@solidjs/signals": "2.0.0-beta.28",
-        "@solidjs/web": "2.0.0-beta.28",
-        "solid-js": "2.0.0-beta.28",
+        "@solidjs/signals": "2.0.0-rc.1",
+        "@solidjs/web": "2.0.0-rc.1",
+        "solid-js": "2.0.0-rc.1",
       },
     },
     "demo": {
@@ -36,21 +39,21 @@
       "devDependencies": {
         "@babel/core": "7.29.7",
         "@babel/preset-react": "^7.29.7",
+        "@solidjs/vite-plugin": "3.0.0-next.32",
         "@types/react": "^19.2.15",
         "@types/react-dom": "^19.2.3",
-        "babel-preset-solid": "2.0.0-beta.28",
+        "babel-preset-solid": "2.0.0-rc.1",
         "vite": "^8.0.14",
-        "vite-plugin-solid": "3.0.0-next.20",
       },
       "peerDependencies": {
-        "@solidjs/signals": "2.0.0-beta.28",
-        "@solidjs/web": "2.0.0-beta.28",
-        "solid-js": "2.0.0-beta.28",
+        "@solidjs/signals": "2.0.0-rc.1",
+        "@solidjs/web": "2.0.0-rc.1",
+        "solid-js": "2.0.0-rc.1",
       },
     },
   },
   "patchedDependencies": {
-    "solid-js@2.0.0-beta.28": "patches/solid-js@2.0.0-beta.28.patch",
+    "solid-js@2.0.0-rc.1": "patches/solid-js@2.0.0-rc.1.patch",
   },
   "packages": {
     "@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="],
@@ -145,27 +148,27 @@
 
     "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.16", "", { "os": "win32", "cpu": "x64" }, "sha512-Kp85jgoBHa05gix6UIRjfCDiUV3w/8VIdZ247VyyO2gEjaw12WEVhdIjlxp/AMzXxqxQwbxNTDVZ3Mwd2RG5rw=="],
 
-    "@dom-expressions/babel-plugin-jsx": ["@dom-expressions/babel-plugin-jsx@0.50.0-next.33", "", { "dependencies": { "@babel/helper-module-imports": "7.18.6", "@babel/plugin-syntax-jsx": "^7.18.6", "@babel/types": "^7.20.7", "html-entities": "2.3.3", "parse5": "^7.1.2", "validate-html-nesting": "^1.2.1" }, "peerDependencies": { "@babel/core": "^7.20.12" } }, "sha512-LihNVZsuGAruNaldHoa2JAGVY6s/a8Bb+p2vLPb8l6UX5r5DXkaMoMmfF5qdnupxKMqMcrEwNuVl9CRfeeVbwg=="],
+    "@dom-expressions/babel-plugin-jsx": ["@dom-expressions/babel-plugin-jsx@0.50.0-next.43", "", { "dependencies": { "@babel/helper-module-imports": "7.18.6", "@babel/plugin-syntax-jsx": "^7.18.6", "@babel/types": "^7.20.7", "html-entities": "2.3.3", "parse5": "^7.1.2", "validate-html-nesting": "^1.2.1" }, "peerDependencies": { "@babel/core": "^7.20.12" } }, "sha512-JMMS/WHcptu2xMQQhUd7P0c0g2RSvvILg5Fj2y48AiWbPylQX8oXvekDTTXOlrebg1qapqMcEnw0OwYxwr7wOw=="],
 
-    "@dom-expressions/compiler": ["@dom-expressions/compiler@0.50.0-next.33", "", { "optionalDependencies": { "@dom-expressions/compiler-darwin-arm64": "0.50.0-next.33", "@dom-expressions/compiler-darwin-x64": "0.50.0-next.33", "@dom-expressions/compiler-linux-arm64-gnu": "0.50.0-next.33", "@dom-expressions/compiler-linux-x64-gnu": "0.50.0-next.33", "@dom-expressions/compiler-wasm32-wasi": "0.50.0-next.33", "@dom-expressions/compiler-win32-x64-msvc": "0.50.0-next.33" } }, "sha512-xqos+uZd9ztAUAE+U9fv4xSR5oq/MHSc2balhXnsz5/P88MbfKHKOAyhtjBu4fKlxcxcXAi3rMbeMSvXP8P2hQ=="],
+    "@dom-expressions/compiler": ["@dom-expressions/compiler@0.50.0-next.43", "", { "optionalDependencies": { "@dom-expressions/compiler-darwin-arm64": "0.50.0-next.43", "@dom-expressions/compiler-darwin-x64": "0.50.0-next.43", "@dom-expressions/compiler-linux-arm64-gnu": "0.50.0-next.43", "@dom-expressions/compiler-linux-x64-gnu": "0.50.0-next.43", "@dom-expressions/compiler-wasm32-wasi": "0.50.0-next.43", "@dom-expressions/compiler-win32-x64-msvc": "0.50.0-next.43" } }, "sha512-ekEuAFLb868iGu6bw8KA2wgD3gYJpYYTjSbOtuXGlCZnWFA6Wx8Qf720ZYNlb40QjGe3/2kUHTtn47JfaCwPcA=="],
 
-    "@dom-expressions/compiler-darwin-arm64": ["@dom-expressions/compiler-darwin-arm64@0.50.0-next.33", "", { "os": "darwin", "cpu": "arm64" }, "sha512-v59K7yqxboVDHNRkK0YgWO33N6bwLLegxNBJoL/l4jIBeuu5R0IEcMK90zApv5OdAJpD2ZpoMpHrvJvMre75qw=="],
+    "@dom-expressions/compiler-darwin-arm64": ["@dom-expressions/compiler-darwin-arm64@0.50.0-next.43", "", { "os": "darwin", "cpu": "arm64" }, "sha512-aVkvvRtEyHPbtZMZe4DHhFzPzQ4qHO9uGXyPDiddBXfjZgkCqejpcJ18t0emJIpIPpproHFdr+9VyLOKs9ENNw=="],
 
+    "@dom-expressions/compiler-darwin-x64": ["@dom-expressions/compiler-darwin-x64@0.50.0-next.43", "", { "os": "darwin", "cpu": "x64" }, "sha512-zJXhjsSydgZbu0pCfD5/FH5UYH7t6Vy8dKD9AVTokE3LFQgLIVrssX2WwN60jh5+OW9okbJBGZXiZ4/2sqb9OA=="],
-    "@dom-expressions/compiler-darwin-x64": ["@dom-expressions/compiler-darwin-x64@0.50.0-next.33", "", { "os": "darwin", "cpu": "x64" }, "sha512-M9eGbReFxP0taBTJrYUjdOCXTMayyCmrXVBDszFf4bdrLRFVZVrW+H+bucUXr+wYPIygVGLguPHYCCHYrUtcnA=="],
 
+    "@dom-expressions/compiler-linux-arm64-gnu": ["@dom-expressions/compiler-linux-arm64-gnu@0.50.0-next.43", "", { "os": "linux", "cpu": "arm64" }, "sha512-ZEjWL59aAj39C7TANYvtzW5rmeH/kfzZIWoZ3Wf/MSiXm8Ermadx76hX0yMMqLdxy0ec69lRYF4gXC7X2k6LMw=="],
-    "@dom-expressions/compiler-linux-arm64-gnu": ["@dom-expressions/compiler-linux-arm64-gnu@0.50.0-next.33", "", { "os": "linux", "cpu": "arm64" }, "sha512-C7UwgnOK7t0GF/iQMdPDUnApIze08oadrZbz0SYPxx5u4wfYcL1BZbMgMmcLQMLs4EhZWbo5rYLJYP3s8irPoQ=="],
 
-    "@dom-expressions/compiler-linux-x64-gnu": ["@dom-expressions/compiler-linux-x64-gnu@0.50.0-next.33", "", { "os": "linux", "cpu": "x64" }, "sha512-MzgWfZJ06+Upqn0SvhMA7ABn8GmWKfWHigkWLlP5ScwXGjWQrOh1BUc2lRBiKqkgOwWNkeuSfIiaFHmCVdRyfw=="],
+    "@dom-expressions/compiler-linux-x64-gnu": ["@dom-expressions/compiler-linux-x64-gnu@0.50.0-next.43", "", { "os": "linux", "cpu": "x64" }, "sha512-ur/VTzMqAkJq45GHSGlk4uq0I/92Zow5mPcovh+Lg2bnyNrPXMNM9kXrIqio2jUgSyRT4y2QbeI9Us30IeZI6g=="],
 
+    "@dom-expressions/compiler-wasm32-wasi": ["@dom-expressions/compiler-wasm32-wasi@0.50.0-next.43", "", { "dependencies": { "@emnapi/core": "1.11.2", "@emnapi/runtime": "1.11.2", "@napi-rs/wasm-runtime": "^1.1.6" } }, "sha512-X+0Rz1fm7Z1S3ONFwg+NJ8edf2MWUrxOrP50hM2x4PkIe2ST0WzqHbkH4yIXjqttF0R1NErh+ac3q4WGF4wWBg=="],
-    "@dom-expressions/compiler-wasm32-wasi": ["@dom-expressions/compiler-wasm32-wasi@0.50.0-next.33", "", { "dependencies": { "@emnapi/core": "1.11.2", "@emnapi/runtime": "1.11.2", "@napi-rs/wasm-runtime": "^1.1.6" } }, "sha512-vr9cdL2TWgN+KQam6lnjsB0AhCgyGzHd7hZbKmwjjiCyco/zjEY5m7sjE2iSV4GqCeNLgaa9GUG90AOlIDsu0Q=="],
 
+    "@dom-expressions/compiler-win32-x64-msvc": ["@dom-expressions/compiler-win32-x64-msvc@0.50.0-next.43", "", { "os": "win32", "cpu": "x64" }, "sha512-hQlqtiYVst4rNKAWtC9cwfuP95L8Dw+PR5Zwp6AA92vsMgQlJ7+QaJoQAxuKkEUtl212VnW06SJKzx00pSkv8g=="],
-    "@dom-expressions/compiler-win32-x64-msvc": ["@dom-expressions/compiler-win32-x64-msvc@0.50.0-next.33", "", { "os": "win32", "cpu": "x64" }, "sha512-u8O8jUdlYm65XXALYbRzy+3ADaBbG0IIIms0JFxtflsgwYEPuP8jz8EeaqSjZ35oNq/wn9ISUwz3PyeIurPB3A=="],
 
-    "@emnapi/core": ["@emnapi/core@1.10.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw=="],
+    "@emnapi/core": ["@emnapi/core@1.11.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA=="],
 
-    "@emnapi/runtime": ["@emnapi/runtime@1.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA=="],
+    "@emnapi/runtime": ["@emnapi/runtime@1.11.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA=="],
 
-    "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="],
+    "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA=="],
 
     "@floating-ui/core": ["@floating-ui/core@1.7.5", "", { "dependencies": { "@floating-ui/utils": "^0.2.11" } }, "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ=="],
 
@@ -187,7 +190,7 @@
 
     "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
 
-    "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="],
+    "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.2.1", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.3", "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.3" } }, "sha512-KjZdi8Q1wh89gsVmghvbrMgWl6ZWmRmHV6wjB7/g4Zf0dyO+hH3neZUtuDNPO00qq5YE5RITVWvrIZKRaAmzGQ=="],
 
     "@oxc-project/types": ["@oxc-project/types@0.132.0", "", {}, "sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ=="],
 
@@ -223,11 +226,13 @@
 
     "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.1", "", {}, "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw=="],
 
+    "@solidjs/signals": ["@solidjs/signals@2.0.0-rc.1", "", {}, "sha512-KQpgUbn9xuzFaXupwej9MvUnQV+H6wcCgvrERf+dygco3T9JWP9S02g/UoYwwmJ6Vh+LE1b82ZlSHYR2Bd1O8A=="],
+
+    "@solidjs/vite-plugin": ["@solidjs/vite-plugin@3.0.0-next.32", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "@babel/core": "^7.23.3", "@dom-expressions/compiler": "^0.50.0-next.43", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^2.0.0-rc.0", "merge-anything": "^5.1.7", "vitefu": "^1.0.4" }, "peerDependencies": { "@solidjs/start-devtools": "^1.0.0-next.2", "@solidjs/web": "^2.0.0-rc.0", "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", "solid-js": "^2.0.0-rc.0", "vite": "^8.0.0 || ^9.0.0" }, "optionalPeers": ["@solidjs/start-devtools", "@testing-library/jest-dom"] }, "sha512-ql+AdWuMwMnZLLYuBgejJxRtX7ak0Hu4ejtCiPMBplJjpvczzYV/ruvWIg4HA1YW24GkJ9wUy5TNjEk3O1c1pA=="],
-    "@solidjs/signals": ["@solidjs/signals@2.0.0-beta.28", "", {}, "sha512-apxoq3Rhp+NbqPOxipMU32QXgzkfXg4gTHxL1dLSm49NuTid+KrSSHLzGJNaxoaGgoWjLj2RPPnfa38twQAW/A=="],
 
-    "@solidjs/web": ["@solidjs/web@2.0.0-beta.28", "", { "dependencies": { "seroval": "~1.5.4", "seroval-plugins": "~1.5.4" }, "peerDependencies": { "solid-js": "^2.0.0-beta.28" } }, "sha512-PsJkpcXQB/lO7lariIBcYo4AAPoueih2QpFJmiIWyLYee7RyobK1V76r7pwURmt9tz32t+Y0pcj0yYmgMirXeg=="],
+    "@solidjs/web": ["@solidjs/web@2.0.0-rc.1", "", { "dependencies": { "seroval": "~1.5.4", "seroval-plugins": "~1.5.4" }, "peerDependencies": { "solid-js": "^2.0.0-rc.1" } }, "sha512-wLuxGtQUxaFfqxqhIUJGGSZB/upd3GzokQRFJKvO7biJGNZLAws+eanMqi0kK2Amg+MZZ7aVyPPKydf8mzdhkg=="],
 
+    "@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="],
-    "@tybys/wasm-util": ["@tybys/wasm-util@0.10.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg=="],
 
     "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],
 
@@ -263,7 +268,7 @@
 
     "@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260527.2", "", { "os": "win32", "cpu": "x64" }, "sha512-1tBlErMvQgcMqqYwsx4tytupcjCJcOUXD3vBn1Wb/kAvus1FzWQAFE0fcKBvLfcqLQfTiiEwKKEtbLjGmakqqg=="],
 
+    "babel-preset-solid": ["babel-preset-solid@2.0.0-rc.1", "", { "dependencies": { "@dom-expressions/babel-plugin-jsx": "0.50.0-next.43" }, "peerDependencies": { "@babel/core": "^7.0.0", "solid-js": "^2.0.0-rc.1" }, "optionalPeers": ["solid-js"] }, "sha512-HMefWI9rhIGYmefNCmcX21p7di4UUeuayQceUG1Xi6l0/AEhqi6iqPKMr+vvqP31EkoJU9/EcjIBnqS5vSEEhw=="],
-    "babel-preset-solid": ["babel-preset-solid@2.0.0-beta.28", "", { "dependencies": { "@dom-expressions/babel-plugin-jsx": "0.50.0-next.33" }, "peerDependencies": { "@babel/core": "^7.0.0", "solid-js": "^2.0.0-beta.28" }, "optionalPeers": ["solid-js"] }, "sha512-RcIYajyjIwRngIcvBxdg4YqKpVHVz53ffnwDMQRC+0z7RSc5QbWCRQvczVvTKLEgSuHtBq9FfQ3rtElJhEVqfw=="],
 
     "baseline-browser-mapping": ["baseline-browser-mapping@2.10.32", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-wbPvpyjJPC0zdfdKXxqEL3Ea+bOMD/87X4lftiJkkaBiuG6ALQy1SLmEd7BSmVCuwCQsBrCamgBoLyfFDD1EPg=="],
 
@@ -365,7 +370,7 @@
 
     "seroval-plugins": ["seroval-plugins@1.5.4", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-S0xQPhUTefAhNvNWFg0c1J8qJArHt5KdtJ/cFAofo06KD1MVSeFWyl4iiu+ApDIuw0WhjpOfCdgConOfAnLgkw=="],
 
-    "solid-js": ["solid-js@2.0.0-beta.28", "", { "dependencies": { "@solidjs/signals": "^2.0.0-beta.28", "csstype": "^3.1.0", "seroval": "~1.5.4", "seroval-plugins": "~1.5.4" } }, "sha512-NBSTrSFYbMq5kHUzacLLWHHbfJ3PT8zAtEcP+HGNJ/cGf6OyxJgWImOSnD/iV+MnvsGaNr4xU3ec3W6iMCFa9Q=="],
+    "solid-js": ["solid-js@2.0.0-rc.1", "", { "dependencies": { "@solidjs/signals": "^2.0.0-rc.1", "csstype": "^3.1.0", "seroval": "~1.5.4", "seroval-plugins": "~1.5.4" } }, "sha512-UD+UfqfiuuOTaDw01YeT+LwsYJC2ilTlMfs6h8EC8FFLmZD0ZjeZIoJXdZEo9uMzIof2tu0Rfh3dnzI7FAmuJQ=="],
 
     "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
 
@@ -385,8 +390,6 @@
 
     "vite": ["vite@8.0.14", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.15", "rolldown": "1.0.2", "tinyglobby": "^0.2.16" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.18", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-s4BJJ+5y1pYL6Otw51FHhVJQhPnuRinKig64g/1+EUNaJsd3gCKdD31IPFvswUgW9/60QT9oFHbZHbQK5imcxw=="],
 
-    "vite-plugin-solid": ["vite-plugin-solid@3.0.0-next.20", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "@babel/core": "^7.23.3", "@dom-expressions/compiler": "0.50.0-next.33", "@types/babel__core": "^7.20.4", "babel-preset-solid": ">=2.0.0-beta.28 <2.0.0-experimental.0", "merge-anything": "^5.1.7", "vitefu": "^1.0.4" }, "peerDependencies": { "@solidjs/web": ">=2.0.0-beta.28 <2.0.0-experimental.0", "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", "solid-js": ">=2.0.0-beta.28 <2.0.0-experimental.0", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-ndiYZFBcBDyUpbgkb3tRMhtM1WeV+J+Fjg/xDzDJAiKzUToC+eMXYbPSa6Dl+KdZEUjl50XktnKBmpEaV7twBg=="],
-
     "vitefu": ["vitefu@1.1.3", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["vite"] }, "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg=="],
 
     "whatwg-mimetype": ["whatwg-mimetype@3.0.0", "", {}, "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q=="],
@@ -397,16 +400,16 @@
 
     "@dom-expressions/babel-plugin-jsx/@babel/helper-module-imports": ["@babel/helper-module-imports@7.18.6", "", { "dependencies": { "@babel/types": "^7.18.6" } }, "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA=="],
 
-    "@dom-expressions/compiler-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA=="],
+    "@rolldown/binding-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.10.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw=="],
 
-    "@dom-expressions/compiler-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA=="],
+    "@rolldown/binding-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA=="],
 
-    "@dom-expressions/compiler-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.2.1", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.3", "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.3" } }, "sha512-KjZdi8Q1wh89gsVmghvbrMgWl6ZWmRmHV6wjB7/g4Zf0dyO+hH3neZUtuDNPO00qq5YE5RITVWvrIZKRaAmzGQ=="],
+    "@rolldown/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="],
 
     "parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
 
-    "@dom-expressions/compiler-wasm32-wasi/@emnapi/core/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA=="],
+    "@rolldown/binding-wasm32-wasi/@emnapi/core/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="],
 
-    "@dom-expressions/compiler-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="],
+    "@rolldown/binding-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg=="],
   }
 }
```

## demo/README.md

Status: modified; +2; −2

````diff
@@ -36,7 +36,7 @@
 ```
 demo/
 ├── package.json      # this demo's own deps + scripts (React, Base UI, Vite)
-├── vite.config.ts    # Vite config: React via @babel/preset-react, Solid via vite-plugin-solid
+├── vite.config.ts    # Vite config: React via @babel/preset-react, Solid via @solidjs/vite-plugin
 ├── index.html
 └── src/
     ├── App.tsx        # the side-by-side gallery
@@ -54,7 +54,7 @@
 - Files under `src/react/**` compile with `@babel/preset-react` (automatic
   runtime) — these are the Base UI demos.
 - Everything else (the Quoin library + `src/solid/**`) compiles with
-  `vite-plugin-solid`, using the **same** `babel-preset-solid` options as the
+  `@solidjs/vite-plugin`, using the **same** `babel-preset-solid` options as the
   library's own build (`moduleName: "@solidjs/web"`, `generate: "dom"`).
 
 Each runtime is `dedupe`d to a single copy so reactivity and React context stay
````

## demo/package.json

Status: modified; +5; −5

```diff
@@ -19,13 +19,13 @@
 		"@babel/preset-react": "^7.29.7",
 		"@types/react": "^19.2.15",
 		"@types/react-dom": "^19.2.3",
-		"babel-preset-solid": "2.0.0-beta.28",
+		"babel-preset-solid": "2.0.0-rc.1",
 		"vite": "^8.0.14",
+		"@solidjs/vite-plugin": "3.0.0-next.32"
-		"vite-plugin-solid": "3.0.0-next.20"
 	},
 	"peerDependencies": {
-		"solid-js": "2.0.0-beta.28",
+		"solid-js": "2.0.0-rc.1",
+		"@solidjs/web": "2.0.0-rc.1",
+		"@solidjs/signals": "2.0.0-rc.1"
-		"@solidjs/web": "2.0.0-beta.28",
-		"@solidjs/signals": "2.0.0-beta.28"
 	}
 }
```

## demo/vite.config.ts

Status: modified; +2; −2

```diff
@@ -2,8 +2,8 @@
 import { transformAsync } from "@babel/core";
 // @ts-expect-error — no types ship with @babel/preset-react
 import presetReact from "@babel/preset-react";
+import solid from "@solidjs/vite-plugin";
 import { defineConfig, type Plugin } from "vite";
-import solid from "vite-plugin-solid";
 
 const demoRoot = fileURLToPath(new URL("./", import.meta.url));
 const repoRoot = fileURLToPath(new URL("../", import.meta.url));
@@ -19,7 +19,7 @@
  * JSX; Vite's own esbuild pass strips the remaining TypeScript afterwards.
  *
  * Everything else (the Quoin library + `demo/src/solid/**`) is handled by
- * `vite-plugin-solid` below, configured with the SAME `babel-preset-solid`
+ * `@solidjs/vite-plugin` below, configured with the SAME `babel-preset-solid`
  * options the library's Bun build uses (`scripts/solid-plugin.ts`):
  * `{ moduleName: "@solidjs/web", generate: "dom", hydratable: false }`.
  */
```

## package.json

Status: modified; +9; −6

```diff
@@ -1,6 +1,6 @@
 {
 	"name": "quoin-ui",
-	"version": "0.3.0",
+	"version": "0.4.0",
 	"type": "module",
 	"private": false,
 	"license": "MIT",
@@ -303,9 +303,9 @@
 		"prepublishOnly": "bun run build"
 	},
 	"peerDependencies": {
-		"solid-js": "2.0.0-beta.28",
-		"@solidjs/web": "2.0.0-beta.28",
-		"@solidjs/signals": "2.0.0-beta.28"
+		"solid-js": "2.0.0-rc.1",
+		"@solidjs/web": "2.0.0-rc.1",
+		"@solidjs/signals": "2.0.0-rc.1"
 	},
 	"dependencies": {
 		"@floating-ui/dom": "^1.7.6",
@@ -318,11 +318,14 @@
 		"@happy-dom/global-registrator": "20.9.0",
 		"@types/babel__core": "7.20.5",
 		"@typescript/native-preview": "7.0.0-dev.20260527.2",
-		"babel-preset-solid": "2.0.0-beta.28",
+		"@solidjs/signals": "2.0.0-rc.1",
+		"@solidjs/web": "2.0.0-rc.1",
+		"babel-preset-solid": "2.0.0-rc.1",
 		"bun-types": "latest",
+		"solid-js": "2.0.0-rc.1",
 		"typescript": "6.0.3"
 	},
 	"patchedDependencies": {
+		"solid-js@2.0.0-rc.1": "patches/solid-js@2.0.0-rc.1.patch"
-		"solid-js@2.0.0-beta.28": "patches/solid-js@2.0.0-beta.28.patch"
 	}
 }
```

## patches/solid-js@2.0.0-beta.28.patch

Status: deleted; +0; −26

```diff
@@ -1,26 +1,0 @@
-diff --git a/dist/dev.cjs b/dist/dev.cjs
-index 772b280e293985fa51c13f770bbac46708108376..0d0be69e9233339c8963ba984e8a21d0988312a3 100644
---- a/dist/dev.cjs
-+++ b/dist/dev.cjs
-@@ -7,7 +7,7 @@ function createContext(defaultValue, options) {
-   const id = Symbol(options && options.name || "");
-   function provider(props) {
-     return signals.createRoot(() => {
--      signals.setContext(provider, props.value);
-+      signals.untrack(() => signals.setContext(provider, props.value));
-       return children(() => props.children);
-     });
-   }
-diff --git a/dist/dev.js b/dist/dev.js
-index a11aaa71261c253fdf0bc4acb60ca968003dc249..f49cf7f9529b9cc54a15e23818f7827032317082 100644
---- a/dist/dev.js
-+++ b/dist/dev.js
-@@ -6,7 +6,7 @@ function createContext(defaultValue, options) {
-   const id = Symbol(options && options.name || "");
-   function provider(props) {
-     return createRoot(() => {
--      setContext(provider, props.value);
-+      untrack(() => setContext(provider, props.value));
-       return children(() => props.children);
-     });
-   }
```

## patches/solid-js@2.0.0-rc.1.patch

Status: added; +26; −0

```diff
@@ -1,0 +1,26 @@
+diff --git a/dist/dev.cjs b/dist/dev.cjs
+index 8ba7f481d7192eb19cf7b70a9b284b7b878da06e..eef3e8fb54cca6e11aa1731d540f3bc43949f5dc 100644
+--- a/dist/dev.cjs
++++ b/dist/dev.cjs
+@@ -7,7 +7,7 @@ function createContext(defaultValue, options) {
+   const id = Symbol(options && options.name || "");
+   function provider(props) {
+     return signals.createRoot(() => {
+-      signals.setContext(provider, props.value);
++      signals.untrack(() => signals.setContext(provider, props.value));
+       return children(() => props.children);
+     });
+   }
+diff --git a/dist/dev.js b/dist/dev.js
+index 848207804595e7997d68ef21f77d8b3991a1a2b4..4d0d543f2b24cb4f154b45069c373322442f7ab4 100644
+--- a/dist/dev.js
++++ b/dist/dev.js
+@@ -6,7 +6,7 @@ function createContext(defaultValue, options) {
+   const id = Symbol(options && options.name || "");
+   function provider(props) {
+     return createRoot(() => {
+-      setContext(provider, props.value);
++      untrack(() => setContext(provider, props.value));
+       return children(() => props.children);
+     });
+   }
```

## scripts/build.ts

Status: modified; +1; −1

```diff
@@ -10,7 +10,7 @@
  *     Solid-aware toolchain. Relative specifiers are rewritten to `.js`.
  *   - **JSX-preserved** → `dist/**\/*.jsx` — TypeScript stripped, JSX left
  *     intact (no `babel-preset-solid`). This is the `"solid"` export
- *     condition. A Solid-aware consumer (`vite-plugin-solid` / `solid-start`)
+ *     condition. A Solid-aware consumer (`@solidjs/vite-plugin` / `solid-start`)
  *     injects `"solid"` into its resolve conditions, pulls these `.jsx` files,
  *     and recompiles them with *its own* Solid version and *its own* target
  *     (`dom` for the client pass, `ssr` for the server pass, hydratable when
```

## scripts/preload.ts

Status: modified; +1; −1

```diff
@@ -27,7 +27,7 @@
 // Three compile modes, selected by env:
 //
 //   - SSR (`BUI_SSR=1`): server generate + real `@solidjs/web` server runtime
-//     (`renderToStringAsync`). No happy-dom (the server has no DOM) and no
+//     (`renderToString`). No happy-dom (the server has no DOM) and no
 //     server→browser redirect. Used by `test/ssr/**`.
 //   - HYDRATION (`BUI_HYDRATION=1`): DOM generate but `hydratable: true`, so
 //     the compiled output emits the hydration keys `hydrate()` walks. Keeps
```

## scripts/solid-plugin.ts

Status: modified; +1; −1

```diff
@@ -18,7 +18,7 @@
 	 * Bun's `node` export condition) back to their browser builds. Required
 	 * for `generate: "dom"` runs — the server builds throw on client-only
 	 * APIs like `render()`. Set to `false` for `generate: "ssr"` runs, where
-	 * the real server builds (`renderToStringAsync`, `ssr`, …) are exactly
+	 * the real server builds (`renderToString`, `ssr`, …) are exactly
 	 * what we want to exercise. Defaults to `true`.
 	 */
 	redirectServerToBrowser?: boolean;
```

## scripts/ssr-node-check.mjs

Status: modified; +3; −3

```diff
@@ -14,7 +14,7 @@
  *
  * It does two things per exported subpath:
  *   1. import the `solid`-condition entry (catches module-load crashers), and
- *   2. for a representative few, `renderToStringAsync` (catches render-time
+ *   2. for a representative few, `renderToString` (catches render-time
  *      DOM-global access).
  *
  * Run: `bun run build && node scripts/ssr-node-check.mjs`
@@ -32,7 +32,7 @@
 // every import below is dynamic (`await import(...)`).
 registerHooks({ load });
 
-const { renderToStringAsync } = await import("@solidjs/web");
+const { renderToString } = await import("@solidjs/web");
 
 const ROOT = fileURLToPath(new URL("..", import.meta.url));
 const pkg = JSON.parse(await readFile(`${ROOT}/package.json`, "utf8"));
@@ -58,7 +58,7 @@
 async function renderCheck(label, entry, factory) {
 	try {
 		const mod = await import(`${ROOT}/${entry}`);
+		const html = await renderToString(() => factory(mod));
-		const html = await renderToStringAsync(() => factory(mod));
 		if (typeof html !== "string" || html.length === 0) {
 			failures.push(`render ${label}: empty output`);
 		}
```

## scripts/ssr-render-apps.ts

Status: modified; +2; −2

```diff
@@ -8,12 +8,12 @@
  * exact server markup it then hydrates against — same source file, so the
  * trees match by construction.
  */
-import { renderToStringAsync } from "@solidjs/web";
+import { renderToString } from "@solidjs/web";
 import { apps } from "../test/hydration/apps.tsx";
 
 const html: Record<string, string> = {};
 for (const [key, App] of Object.entries(apps)) {
-	html[key] = await renderToStringAsync(() => App());
+	html[key] = renderToString(() => App());
 }
 
 // Sole stdout payload — the parent parses `{ html }` verbatim. (The client
```

## solid/bugs.md

Status: modified; +8; −9

```diff
@@ -1,12 +1,12 @@
-# Solid 2.0 beta — upstream bug history
+# Solid 2.0 — upstream bug history
 
 Surfaced during the spike run consolidated in `work-left/primitive-template.md`. Each entry has a minimal repro,
 the workaround or local patch we shipped, and where in the codebase the
 workaround lives so removal is easy when upstream fixes land.
 
+Solid version pinned: `solid-js@2.0.0-rc.1` /
+`@solidjs/signals@2.0.0-rc.1`. The entries below were originally confirmed
+against beta.14; statuses retain the release where each fix landed.
-Solid version pinned: `solid-js@2.0.0-beta.28` /
-`@solidjs/signals@2.0.0-beta.28`. The entries below were originally confirmed
-against beta.14; statuses note what changed in beta.28.
 
 Bugs #1 and #2 are fixed upstream in beta.28. Quoin now carries only the
 `createContext` untrack patch documented in `patches.md`.
@@ -271,11 +271,10 @@
 
 When filing or tracking upstream fixes:
 
+- [x] **#1 action()-rejection-hang** — fixed upstream in beta.28; the patch
-- [ ] **#1 action()-rejection-hang** — drop the patch (see
-      `solid-patches.md`) once upstream ships. No userland code change
-      required (`create-async-source.ts` already wraps `action()` plainly).
-- [ ] **#2 resolve()-rejection-hang** — drop the patch (see
-      `solid-patches.md`). No userland code change required.
+      was removed.
+- [x] **#2 resolve()-rejection-hang** — fixed upstream in beta.28; the patch
+      was removed.
 - [ ] **#3 bundle phase asymmetry** — restore the natural-shape
       `effect: (v) => settled(v)` in `create-validator.ts`. Remove the no-op
       `effect: () => undefined`.
```

## solid/patches.md

Status: modified; +5; −5

```diff
@@ -1,8 +1,8 @@
-# Solid 2.0 beta 28 — local patch
+# Solid 2.0 RC 1 — local patch
 
+Quoin carries one `bun patch` against `solid-js@2.0.0-rc.1`:
-Quoin carries one `bun patch` against `solid-js@2.0.0-beta.28`:
 
-- `patches/solid-js@2.0.0-beta.28.patch`
+- `patches/solid-js@2.0.0-rc.1.patch`
 
 It is registered through `patchedDependencies` in `package.json`.
 
@@ -46,9 +46,9 @@
 Their patch files and `patchedDependencies` entries were removed during the
 beta.28 upgrade.
 
+## Re-checking on the next RC
-## Re-checking on the next beta
 
-1. Remove the `solid-js` patch entry and install the new beta.
+1. Remove the `solid-js` patch entry and install the new RC.
 2. Inspect every `createContext` provider build for an untracked value write.
 3. If the fix is upstream, delete the patch. Otherwise regenerate it against
    the exact new package version.
```

## src/internals/use-image-loading-status.ts

Status: modified; +6; −0

```diff
@@ -1,3 +1,4 @@
+import { isServer } from "@solidjs/web";
 import {
 	type Accessor,
 	createEffect,
@@ -117,6 +118,11 @@
 		ownedWrite: true,
 	});
 
+	// The RC's synchronous server renderer evaluates memos during render. Image
+	// probing is browser-only; keep the initial idle status so the fallback is
+	// rendered on the server and the client owns the first real probe.
+	if (isServer) return status;
+
 	// Async probe — source of truth. A non-empty `src` resolves on load /
 	// rejects on error; an empty `src` is a domain "error" state, surfaced as a
 	// rejected Promise so the bundle's `error` half routes it to `"error"`.
```

## src/slider/control/slider-control.tsx

Status: modified; +1; −1

```diff
@@ -353,7 +353,7 @@
 
 	function stopListening(): void {
 		// Reached on the server via the setup `onCleanup` when a render scope is
-		// disposed (e.g. during `renderToStringAsync`). No listeners were ever
+		// disposed (e.g. during `renderToString`). No listeners were ever
 		// bound server-side, and `ownerDocument(null)` would fall through to the
 		// absent `document` global — so there is nothing to detach.
 		if (isServer) return;
```

## test/ssr/compounds.test.tsx

Status: modified; +3; −3

```diff
@@ -1,7 +1,7 @@
 /**
  * SSR smoke coverage for every exported compound. See `smoke.test.tsx` for
  * the harness contract. Each case renders a minimal-but-valid tree through
- * `renderToStringAsync` and asserts it produced a non-empty string without
+ * `renderToString` and asserts it produced a non-empty string without
  * throwing. The value is the *no-throw* — it proves nothing in the component
  * body or a JSX getter reaches for a DOM global during render.
  *
@@ -9,7 +9,7 @@
  * where a root owns state.
  */
 import { describe, expect, it } from "bun:test";
-import { renderToStringAsync } from "@solidjs/web";
+import { renderToString } from "@solidjs/web";
 
 import { Accordion } from "../../src/accordion/index.ts";
 import { Avatar } from "../../src/avatar/index.ts";
@@ -39,7 +39,7 @@
 const d = process.env.BUI_SSR === "1" ? describe : describe.skip;
 
 async function renders(el: () => unknown): Promise<string> {
+	const html = await renderToString(el);
-	const html = await renderToStringAsync(el);
 	expect(typeof html).toBe("string");
 	return html;
 }
```

## test/ssr/floating.probe.test.tsx

Status: modified; +6; −6

```diff
@@ -9,7 +9,7 @@
  * until the user opens it, so the server only needs to emit the trigger.
  */
 import { describe, expect, it } from "bun:test";
-import { renderToStringAsync } from "@solidjs/web";
+import { renderToString } from "@solidjs/web";
 
 import { Dialog } from "../../src/dialog/index.ts";
 import { Menu } from "../../src/menu/index.ts";
@@ -22,7 +22,7 @@
 
 d("SSR floating probe (closed = first-paint state)", () => {
 	it("dialog trigger", async () => {
-		const html = await renderToStringAsync(() => (
+		const html = await renderToString(() => (
 			<Dialog.Root open={false}>
 				<Dialog.Trigger>Open</Dialog.Trigger>
 			</Dialog.Root>
@@ -31,7 +31,7 @@
 	});
 
 	it("popover trigger", async () => {
+		const html = await renderToString(() => (
-		const html = await renderToStringAsync(() => (
 			<Popover.Root open={false}>
 				<Popover.Trigger>Open</Popover.Trigger>
 			</Popover.Root>
@@ -40,7 +40,7 @@
 	});
 
 	it("tooltip trigger", async () => {
-		const html = await renderToStringAsync(() => (
+		const html = await renderToString(() => (
 			<Tooltip.Provider>
 				<Tooltip.Root open={false}>
 					<Tooltip.Trigger>Hover</Tooltip.Trigger>
@@ -51,7 +51,7 @@
 	});
 
 	it("select trigger", async () => {
-		const html = await renderToStringAsync(() => (
+		const html = await renderToString(() => (
 			<Select.Root open={false} value="a">
 				<Select.Trigger>
 					<Select.Value />
@@ -62,7 +62,7 @@
 	});
 
 	it("menu trigger", async () => {
+		const html = await renderToString(() => (
-		const html = await renderToStringAsync(() => (
 			<Menu.Root open={false}>
 				<Menu.Trigger>Menu</Menu.Trigger>
 			</Menu.Root>
```

## test/ssr/smoke.test.tsx

Status: modified; +6; −6

```diff
@@ -4,14 +4,14 @@
  * Runs ONLY under `bun run test:ssr` (BUI_SSR=1), which swaps the preload
  * into Solid's server-generate mode: `src` is compiled with
  * `generate: "ssr"` / `hydratable: true`, and `@solidjs/web` resolves to its
- * real server runtime (`renderToStringAsync`) instead of being redirected to
+ * real server runtime (`renderToString`) instead of being redirected to
  * the browser build. There is NO DOM here — happy-dom is not registered.
  *
  * The point is twofold:
  *   1. Prove each compound renders to a string without throwing — i.e. no
  *      component body / JSX getter touches `document`, `window`,
  *      `ResizeObserver`, `getComputedStyle`, etc. outside an effect (effects
- *      don't run during `renderToStringAsync`).
+ *      don't run during `renderToString`).
  *   2. Assert the emitted markup carries the expected role/structure so a
  *      later hydration pass has something stable to attach to.
  *
@@ -19,13 +19,13 @@
  * this is the render-without-DOM gate.
  */
 import { describe, expect, it } from "bun:test";
+import { renderToString } from "@solidjs/web";
-import { renderToStringAsync } from "@solidjs/web";
 import { Progress } from "../../src/progress/index.ts";
 import { Separator } from "../../src/separator/index.ts";
 
 // These only make sense under `bun run test:ssr` (BUI_SSR=1), which swaps the
 // preload into server-generate mode. Under the default DOM preload there is a
-// `document` and `@solidjs/web` is the browser build (no `renderToStringAsync`),
+// `document` and `@solidjs/web` is the browser build (no `renderToString`),
 // so we self-skip — matching how `test/browser/**` gates on BUN_WEBVIEW_TESTS.
 const d = process.env.BUI_SSR === "1" ? describe : describe.skip;
 
@@ -36,7 +36,7 @@
 	});
 
 	it("Separator renders to a string", async () => {
-		const html = await renderToStringAsync(() => (
+		const html = await renderToString(() => (
 			<Separator orientation="horizontal" />
 		));
 		expect(typeof html).toBe("string");
@@ -44,7 +44,7 @@
 	});
 
 	it("Progress (full compound) renders to a string", async () => {
+		const html = await renderToString(() => (
-		const html = await renderToStringAsync(() => (
 			<Progress.Root value={40}>
 				<Progress.Label>Loading</Progress.Label>
 				<Progress.Track>
```
