From d3e5a403b9b9e00b66485a427db6a86fb10d3268 Mon Sep 17 00:00:00 2001 From: meh Date: Fri, 14 Aug 2026 13:13:56 +0700 Subject: [PATCH 1/9] fix(library): say why source mode wants an exports list The message was "must declare its public Layout exports", which reads as a missing required field. It sends you to write the list, when the question worth asking is whether you wanted source mode at all: convention-based discovery needs no such list, and the documentation says so in as many words. It also said nothing about the cost of keeping one. Nothing compares the list to the barrel, so a rename that misses it leaves the manifest naming components that no longer exist while rejecting the ones that do, with no diagnostic anywhere. That is worth knowing before you choose the mode, not after. The message now names the trade and points at both ways out. --- packages/solid-layouts-oxc/library.js | 37 +++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/packages/solid-layouts-oxc/library.js b/packages/solid-layouts-oxc/library.js index 053007f..5b26a08 100644 --- a/packages/solid-layouts-oxc/library.js +++ b/packages/solid-layouts-oxc/library.js @@ -219,6 +219,39 @@ function lintLibrary(options = {}) { }; } +/** + * Why source mode asks for a list when nothing else does. + * + * Convention-based discovery reads every `*.layout.tsx` and emits a `generated` + * manifest entry carrying the recipe, the Layout and their exports, so the + * application compiler can verify the join. Source mode generates alongside an + * existing package instead, where the public surface is whatever that package's + * own barrel exports, including parts like `AccordionItem` that share a parent's + * layout file and have no file of their own. The compiler cannot infer that, so + * source mode is told. + * + * The old message said only "must declare its public Layout exports", which + * reads as a missing field rather than as a consequence of the mode, and sends + * you to write the list rather than to ask whether you wanted the mode. The + * documentation says no authored component manifest is required, and for + * convention-based discovery that is true. + */ +function sourceModeExportsMessage(configPath) { + return [ + `${configPath}: source mode needs an "exports" array naming this package's public components.`, + "", + 'Only `mode: "source"` needs one. Convention-based discovery derives the manifest from', + "every `*.layout.tsx` it finds, and emits richer entries the application compiler can", + "verify; source mode generates alongside a package whose public surface it cannot see,", + "so the list is how it learns the names.", + "", + "If this package does not need adjacent generation, delete the config and let discovery", + "do it. If it does, the list has to be kept in step with the barrel by hand: nothing", + "compares them, and a rename that misses it leaves the manifest naming components that", + "no longer exist while rejecting the ones that do.", + ].join("\n"); +} + function generateLibrarySource(options = {}) { const root = resolve(options.root || process.cwd()); const { configPath, config } = readLibraryConfig(root, options); @@ -226,7 +259,7 @@ function generateLibrarySource(options = {}) { throw new Error(`${configPath || root} must set mode to "source" for adjacent generation`); } if (!Array.isArray(config.exports) || config.exports.length === 0) { - throw new Error(`${configPath} must declare its public Layout exports`); + throw new Error(sourceModeExportsMessage(configPath)); } const lint = lintLibrary({ ...options, root }); if (lint.failed) { @@ -256,7 +289,7 @@ function emitSourceManifest(options = {}) { const { configPath, config } = readLibraryConfig(root, options); if (config.mode !== "source") throw new Error(`${configPath || root} is not a source library config`); const exports = config.exports || []; - if (exports.length === 0) throw new Error(`${configPath} must declare its public Layout exports`); + if (exports.length === 0) throw new Error(sourceModeExportsMessage(configPath)); const duplicates = exports.filter((name, index) => exports.indexOf(name) !== index); if (duplicates.length) throw new Error(`${configPath} repeats Layout export ${duplicates[0]}`); const sourcePackage = readJson(resolve(root, "package.json")); From 67c8c421a9da5696158ec23c0939ffc25db34fce Mon Sep 17 00:00:00 2001 From: meh Date: Sat, 15 Aug 2026 06:03:12 +0700 Subject: [PATCH 2/9] docs: what Solid 2 support actually costs, measured Recorded on the branch rather than in a private note, because the number that matters contradicts the assumption: this was scoped as "three packages need Solid 2 support" and the whole dependence is 32 sites in one 437-line file, plus two lines of Rust. The rsbuild plugin has none at all. The one genuinely hard piece is the four-bucket splitProps that routes every prop through the runtime; omit() returns only a remainder, so the bucket boundaries have to be re-derived rather than falling out of the call. --- SOLID-2-PLAN.md | 102 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 SOLID-2-PLAN.md diff --git a/SOLID-2-PLAN.md b/SOLID-2-PLAN.md new file mode 100644 index 0000000..ec93ec6 --- /dev/null +++ b/SOLID-2-PLAN.md @@ -0,0 +1,102 @@ +# Solid 2 support for the layouts toolchain + +Measured 2026-08-15 on `next/solid-2`, branched from `master` at `a107bf1`, +which is exactly the published state: solid-layouts 0.1.3, solid-layouts-oxc +0.1.7, rsbuild-plugin-solid-layouts 0.1.4. Tagged `solid-1-baseline`. + +## It is one file + +I had this down as "three packages need Solid 2 support", which was true but +useless. Measured, the whole dependence is: + +| where | Solid sites | note | +| --- | ---: | --- | +| `packages/solid-layouts/src/component.ts` | **32** | 437 lines. This is the job. | +| `packages/solid-layouts/src/component.test.ts` | 34 | follows the source | +| `packages/solid-layouts/src/ids.test.ts` | 3 | `createRoot` only | +| `packages/solid-layouts/src/defaults.ts` | 1 | | +| `packages/solid-layouts-oxc` (3,850 lines of Rust) | **2 real** | an emitted import header and a builtins list; the other two hits are a test fixture | +| `packages/rsbuild-plugin-solid-layouts` | **0** | `index.js` + `index.d.ts`, a thin wrapper, no Solid usage | + +`component.ts` imports exactly this: + +```ts +import { + type Context, type JSX, + children as resolveChildren, createContext, createMemo, splitProps, useContext, +} from "solid-js"; +import { Dynamic, createComponent } from "solid-js/web"; +``` + +Seven named imports and two from `web`. That is the entire surface. + +## What each one becomes + +| 1.x | 2.0 | difficulty | +| --- | --- | --- | +| `splitProps(props, a, b, c)` | `omit(props, ...)` | **the real work** — see below | +| `useContext` | same name, but **throws** on a default-less context instead of returning `undefined` | design decision | +| `createComponent`, `Dynamic` | move to `@solidjs/web`; `Dynamic` becomes the `dynamic(source)` factory | mechanical | +| `children`, `createMemo`, `createContext` | unchanged names | mechanical | +| `Context.Provider` | context is the provider: `` | mechanical | + +### `splitProps` is the one that matters + +The runtime's whole prop-routing model is built on it. From `component.js`: + +```js +const [presentation, escape, behaviour, passthrough] = + splitProps(props, presentationKeys, ["class", "className", "style", "children"], behaviourKeys); +``` + +Four buckets from one call. `omit(props, ...keys)` returns **only the +remainder**, so this becomes several `omit` calls plus explicit picks, and the +bucket boundaries have to be re-derived rather than falling out of the split. +That is the piece to design first, because everything else in the file reads +those four names. + +### The Rust is two lines + +```rust +// match_layouts.rs:246 +SOLID_BUILTINS.contains(&name) && (source == "solid-js" || source == "solid-js/web") +``` + +`SOLID_BUILTINS` lists `For, Show, Switch, Match, Suspense, SuspenseList, …`. +Under 2.0, `Suspense` is `Loading`, `SuspenseList` is `Reveal`, `ErrorBoundary` +is `Errored`, and `Index` is gone in favour of ``. So the +list changes and the source check has to admit `@solidjs/web`. + +```rust +// lib.rs:257 — the header prepended to every .generated.tsx +"import { defineComponent as __defineLayoutComponent } from \"solid-layouts/application-boundary\"; + import type { Component as __LayoutComponent } from \"solid-js\";" +``` + +`Component` still comes from `solid-js`; only the builtins source list needs +widening. Both edits are small and both need fixture regeneration. + +## Order of work + +1. **`component.ts` prop routing.** Replace the four-bucket `splitProps` with + `omit` plus explicit picks. Everything else is downstream of this. +2. **The context decision.** `useContext` throwing changes what a compound + component does outside its provider — in `@pathscale/ui` that pattern appears + at 57 sites with only 17 guarded. Decide here, because the runtime is where + the fallback lives. +3. **`@solidjs/web` imports and `dynamic()`.** +4. **Rust: builtins list + source check**, then regenerate fixtures. +5. **`rsbuild-plugin-solid-layouts`**: nothing in its own source, but it sits + beside `@rsbuild/plugin-solid@1.2.2`, which *depends on* + `babel-preset-solid: ^1.9.12`. That is a hard pin on Solid 1's JSX transform + and needs an override to `babel-preset-solid@next` or a patched plugin. +6. **Publish under a prerelease tag** (`0.2.0-rc.0` on `next`) so + `@pathscale/ui` on `next/solid-2` can consume it without touching `latest`. + +## What is NOT blocked on this + +The 11 `@solid-primitives/*` packages `@pathscale/ui` depends on peer-pin +`solid-js: ^1.6.12` and call `createEffect`/`onCleanup` internally, both of +which change signature. They break at runtime, not at install, and no work here +fixes that. Either upstream ships Solid 2 releases, or the four or five we +actually use get vendored. From 601b25706acaa0c8ff222c2af5c868a76b59ddb7 Mon Sep 17 00:00:00 2001 From: meh Date: Sat, 15 Aug 2026 06:29:21 +0700 Subject: [PATCH 3/9] feat(library): run on Solid 1.9 and 2.0 from one source The runtime used four things Solid 2.0 changed, and three of them can be told apart at runtime from the module object itself: `splitProps` became `omit` and lost its subset half, `Context.Provider` became the context, and `useContext` now throws where it used to return `undefined`. Those are handled in place - detected once at load, or spelled so both majors read it the same way, which is why `createContext({})` now carries a default it never needed before. The fourth cannot. 1.9 serves `Dynamic` and `createComponent` from `solid-js/web`; 2.0 moved them to `@solidjs/web` and dropped the old subpath, so no single import statement resolves under both. That one module is now `renderer.ts`, and the build emits the tree twice with its 2.0 twin swapped in. `dist/component.js` and `dist/solid-2/component.js` are identical files; the renderer is the whole difference. The prop routing is the part that changed shape rather than name. One `splitProps` call returned all four buckets and made them disjoint by construction. `omit` returns only the remainder, so the three routed buckets are picked by name and the bucket each declared key belongs to is decided once per component instead of falling out of the call. 145 tests pass under 1.9, unchanged. The 2.0 output is emitted and its declarations bind to `@solidjs/web`, but `skipLibCheck` means it has not been checked against an installed solid-js 2 yet. --- .gitignore | 1 + packages/solid-layouts/bun.lock | 9 +- packages/solid-layouts/package.json | 27 +++- packages/solid-layouts/scripts/build.mjs | 45 ++++++ packages/solid-layouts/src/component.ts | 153 +++++++++++++++--- .../solid-layouts/src/renderer.solid-2.ts | 16 ++ packages/solid-layouts/src/renderer.ts | 20 +++ packages/solid-layouts/tsconfig.build.json | 6 +- packages/solid-layouts/tsconfig.json | 6 +- packages/solid-layouts/tsconfig.solid-2.json | 13 ++ 10 files changed, 273 insertions(+), 23 deletions(-) create mode 100644 packages/solid-layouts/scripts/build.mjs create mode 100644 packages/solid-layouts/src/renderer.solid-2.ts create mode 100644 packages/solid-layouts/src/renderer.ts create mode 100644 packages/solid-layouts/tsconfig.solid-2.json diff --git a/.gitignore b/.gitignore index 0c63d28..c1d318e 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ packages/*/index.d.ts !packages/solid-layouts-oxc/index.d.ts !packages/rsbuild-plugin-solid-layouts/index.js !packages/rsbuild-plugin-solid-layouts/index.d.ts +packages/solid-layouts/solid-2-staging/ diff --git a/packages/solid-layouts/bun.lock b/packages/solid-layouts/bun.lock index 5effad8..8f93859 100644 --- a/packages/solid-layouts/bun.lock +++ b/packages/solid-layouts/bun.lock @@ -5,16 +5,23 @@ "": { "name": "solid-layouts", "devDependencies": { + "@solidjs/web": "2.0.0-rc.0", "@types/bun": "^1.3.14", "happy-dom": "^20.11.2", "typescript": "^7.0.2", }, "peerDependencies": { - "solid-js": "^1.9.14", + "@solidjs/web": "^2.0.0-rc.0", + "solid-js": "^1.9.14 || ^2.0.0-rc.0", }, + "optionalPeers": [ + "@solidjs/web", + ], }, }, "packages": { + "@solidjs/web": ["@solidjs/web@2.0.0-rc.0", "", { "dependencies": { "seroval": "~1.5.4", "seroval-plugins": "~1.5.4" }, "peerDependencies": { "solid-js": "^2.0.0-rc.0" } }, "sha512-pYSaA9+dH8H1h/d/ZF/P2kR6omfzFGNcdzKhWTcg9fJghXhn8+5UrXUr2iYxDdYNOXZzxxFQhYHSJ7P4HKDqgw=="], + "@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="], "@types/node": ["@types/node@26.2.0", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg=="], diff --git a/packages/solid-layouts/package.json b/packages/solid-layouts/package.json index 3e4ae42..d41a31c 100644 --- a/packages/solid-layouts/package.json +++ b/packages/solid-layouts/package.json @@ -23,21 +23,44 @@ "types": "./dist/index.d.ts", "import": "./dist/index.js" }, + "./solid-2": { + "types": "./dist/solid-2/index.d.ts", + "import": "./dist/solid-2/index.js" + }, + "./solid-2/recipe": { + "types": "./dist/solid-2/recipe.d.ts", + "import": "./dist/solid-2/recipe.js" + }, + "./solid-2/cx": { + "types": "./dist/solid-2/cx.d.ts", + "import": "./dist/solid-2/cx.js" + }, + "./solid-2/application-boundary": { + "types": "./dist/solid-2/index.d.ts", + "import": "./dist/solid-2/index.js" + }, "./package.json": "./package.json" }, "files": [ "dist" ], "scripts": { - "build": "rm -rf dist && tsc -p tsconfig.build.json", + "build": "node scripts/build.mjs", "prepack": "bun run build", "test": "bun test --conditions=browser", "typecheck": "tsc --noEmit" }, "peerDependencies": { - "solid-js": "^1.9.14" + "@solidjs/web": "^2.0.0-rc.0", + "solid-js": "^1.9.14 || ^2.0.0-rc.0" + }, + "peerDependenciesMeta": { + "@solidjs/web": { + "optional": true + } }, "devDependencies": { + "@solidjs/web": "2.0.0-rc.0", "@types/bun": "^1.3.14", "happy-dom": "^20.11.2", "typescript": "^7.0.2" diff --git a/packages/solid-layouts/scripts/build.mjs b/packages/solid-layouts/scripts/build.mjs new file mode 100644 index 0000000..3461bca --- /dev/null +++ b/packages/solid-layouts/scripts/build.mjs @@ -0,0 +1,45 @@ +/** + * Emits the runtime twice: once for Solid 1.9, once for Solid 2.0. + * + * The two builds share every source file but one. `renderer.ts` is the only + * module a major of Solid can move rather than rename - 1.9 serves `Dynamic` + * and `createComponent` from `solid-js/web`, 2.0 from `@solidjs/web` and drops + * the old subpath - so the 2.0 build is the same tree with `renderer.ts` + * replaced by `renderer.solid-2.ts`. + * + * Copying the tree rather than pointing a second tsconfig at a different file + * is deliberate: TypeScript's `paths` does not remap relative specifiers, and + * `component.ts` imports `./renderer.js` relatively because at runtime it must. + * + * `dist/` keeps its path and a 1.9 consumer importing `solid-layouts` gets a + * build that imports no 2.0 package: `renderer.solid-2.ts` is excluded from + * this pass rather than merely unused by it, so nothing resolves `@solidjs/web` + * in a tree that has no reason to have installed it. + */ +import { execFileSync } from "node:child_process"; +import { cpSync, rmSync } from "node:fs"; +import { dirname, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const root = resolve(dirname(fileURLToPath(import.meta.url)), ".."); +// Not dot-prefixed: TypeScript skips hidden directories when resolving +// `include`, so a `.solid-2` staging tree compiles to "no inputs were found". +const staging = resolve(root, "solid-2-staging"); +const tsc = resolve(root, "node_modules/.bin/tsc"); + +const run = (...args) => + execFileSync(tsc, args, { cwd: root, stdio: "inherit" }); + +rmSync(resolve(root, "dist"), { recursive: true, force: true }); +rmSync(staging, { recursive: true, force: true }); + +run("-p", "tsconfig.build.json"); + +try { + cpSync(resolve(root, "src"), staging, { recursive: true }); + cpSync(resolve(staging, "renderer.solid-2.ts"), resolve(staging, "renderer.ts")); + rmSync(resolve(staging, "renderer.solid-2.ts")); + run("-p", "tsconfig.solid-2.json"); +} finally { + rmSync(staging, { recursive: true, force: true }); +} diff --git a/packages/solid-layouts/src/component.ts b/packages/solid-layouts/src/component.ts index 0ff34ad..c7626a6 100644 --- a/packages/solid-layouts/src/component.ts +++ b/packages/solid-layouts/src/component.ts @@ -1,19 +1,95 @@ +import * as solid from "solid-js"; import { type Context, - type JSX, children as resolveChildren, createContext, createMemo, - splitProps, useContext, } from "solid-js"; -import { Dynamic, createComponent } from "solid-js/web"; import type { ComponentDefaults, UIConfig } from "./defaults.js"; import { globalDefaultsFor } from "./defaults.js"; import { __nextInstance, __slotId } from "./ids.js"; import type { Recipe } from "./recipe.js"; +import { Dynamic, type JSX, createComponent } from "./renderer.js"; import type { PropsOf, SlotAttrs, SlotsOf, StateOf } from "./types.js"; +/** + * `props` without `keys`, still tracked. + * + * 1.9 spells this `splitProps(props, keys)[1]`. 2.0 renamed it to `omit`, made + * it variadic, and took `splitProps` away. + * + * Detected from the module object rather than configured, and resolved once at + * load rather than branched per call. Which one is there is a fact about the + * `solid-js` that got installed, and no build flag can be more right about that + * than the module itself; a flag can only disagree with it. + */ +type Solid1Props = { + splitProps( + props: Record, + keys: string[], + ): [Record, Record]; +}; +type Solid2Props = { + omit( + props: Record, + ...keys: string[] + ): Record; +}; + +const rest: ( + props: Record, + keys: readonly string[], +) => Record = + "omit" in solid + ? (props, keys) => + (solid as unknown as Solid2Props).omit(props, ...keys) + : (props, keys) => + (solid as unknown as Solid1Props).splitProps(props, keys as string[])[1]; + +/** + * The component that provides a context's value. + * + * 1.9 hangs it off the context as `.Provider`. In 2.0 the context *is* the + * provider and `.Provider` is gone, so asking for it and falling back covers + * both without knowing which is running. + */ +type Provider = (props: { value: T; children: JSX.Element }) => JSX.Element; + +const providerOf = (context: unknown): Provider => + ((context as { Provider?: unknown }).Provider ?? context) as Provider; + +/** The four props every consumer may set, whatever the component declares. */ +const ESCAPE_KEYS = ["class", "className", "style", "children"] as const; + +/** + * The half of `splitProps` neither major ships: both give back a remainder, + * neither gives back a subset. + * + * Each bucket is a plain object of getters over `props`, which is what + * `splitProps` returned anyway, so reads stay tracked at the point of use. + * + * A key absent from `props` is skipped rather than defined as `undefined`, + * matching `splitProps`. `setup` receives the behaviour bucket, and some read + * their own keys with `in` or `Object.keys`, which a defined-but-undefined key + * would answer wrongly. + */ +function pick( + props: Record, + keys: readonly string[], +): Record { + const out: Record = {}; + for (const key of keys) { + if (!(key in props)) continue; + Object.defineProperty(out, key, { + get: () => props[key], + enumerable: true, + configurable: true, + }); + } + return out; +} + /** * What a layout receives. * @@ -37,23 +113,34 @@ export type Layout> = ( props: PropsOf & StateOf & Model & Record, ) => JSX.Element; -/** Subtree-scoped defaults. The layer `configureUI` cannot express. */ -const UIDefaultsContext = createContext(); +/** + * Subtree-scoped defaults. The layer `configureUI` cannot express. + * + * The empty default is load-bearing under 2.0, where `useContext` throws + * `ContextNotFoundError` instead of returning `undefined` when nothing above + * has provided a value. Every component built here reads this context and most + * trees never mount a ``, so a default-less context would make an + * unconfigured application throw on its first render. 1.9 reads the same + * default the same way, so this is one spelling rather than a branch. + */ +const UIDefaultsContext = createContext({}); export function UIDefaults( props: { children: JSX.Element } & UIConfig, ): JSX.Element { - const [, overrides] = splitProps(props, ["children"]); + const overrides = rest(props as unknown as Record, [ + "children", + ]); const inherited = useContext(UIDefaultsContext); // Merged with anything above rather than replacing it, so nesting two // providers configuring different components composes instead of clobbering. const value = createMemo(() => ({ - ...(inherited ?? {}), + ...inherited, ...(overrides as UIConfig), })); - return createComponent(UIDefaultsContext.Provider, { + return createComponent(providerOf(UIDefaultsContext), { get value() { return value(); }, @@ -145,6 +232,29 @@ export function defineComponent< /** The slot this component renders as itself. See `slot` on the config. */ const rootSlot = (config.slot ?? "root") as string; + // Which bucket each declared key belongs to, decided once per component + // rather than once per render. `splitProps` made the buckets disjoint by + // construction: a key named in two lists landed in the earlier one only. + // Picking by name does not, so first claim wins here instead. The order + // decides real cases - a recipe that declares `size` and a component whose + // logic also wants `size` must not hand the logic a prop the presentation + // cascade has already resolved. + const claimed = new Set(); + const claim = (keys: readonly string[]): string[] => { + const own: string[] = []; + for (const key of keys) { + if (claimed.has(key)) continue; + claimed.add(key); + own.push(key); + } + return own; + }; + const presentationOwn = claim(presentationKeys); + const escapeOwn = claim(ESCAPE_KEYS); + const behaviourOwn = claim(behaviourKeys); + /** Everything routed somewhere. What is left over is plain HTML. */ + const routedKeys = [...presentationOwn, ...escapeOwn, ...behaviourOwn]; + const compiled = recipe.config._layouts; return function LayoutComponent(outer: ComponentProps) { @@ -177,12 +287,14 @@ export function defineComponent< // The fourth bucket is not optional. Without it `id`, `onClick`, // `aria-label` and `data-testid` were swallowed as behaviour and never // reached the DOM at all. - const [presentation, escape, behaviour, passthrough] = splitProps( - props, - presentationKeys, - ["class", "className", "style", "children"], - behaviourKeys as string[], - ); + // + // One `splitProps` call used to return all four. Solid 2 has only the + // remainder half of it, so the three routed buckets are picked by name and + // the fourth still falls out of one call, as before. + const presentation = pick(props, presentationOwn); + const escape = pick(props, escapeOwn); + const behaviour = pick(props, behaviourOwn); + const passthrough = rest(props, routedKeys); // `slotId` reaches the logic as well as the layout: an accordion item has // to hand its trigger's id to `aria-controls` on the panel, and that is a @@ -201,7 +313,7 @@ export function defineComponent< const atCallSite = (presentation as Record)[key]; if (atCallSite !== undefined) return atCallSite; return ( - subtree?.[componentName]?.[key] ?? + subtree[componentName]?.[key] ?? globalDefaultsFor(componentName)?.[key] ?? config.defaults?.[key] ?? // The recipe's own, so a default can live beside the axis it defaults @@ -345,11 +457,16 @@ export function defineComponent< ...spreadable(() => resolved()[rootSlot] as SlotAttrs), }); - if (!provide) return rendered; + // Nothing to provide means no wrapper, and under 2.0 that is a correctness + // rule rather than an optimisation: a provider counts as having provided + // even when its value is `undefined`, and `useContext` throws on an + // undefined value, so an empty provider would shadow a real one above it + // with a throw. Under 1.9 the two spellings are indistinguishable. + if (!provide || !model || !("context" in model)) return rendered; - return createComponent(provide.Provider, { + return createComponent(providerOf(provide), { get value() { - return model?.context; + return model.context; }, get children() { return rendered; diff --git a/packages/solid-layouts/src/renderer.solid-2.ts b/packages/solid-layouts/src/renderer.solid-2.ts new file mode 100644 index 0000000..a22cd21 --- /dev/null +++ b/packages/solid-layouts/src/renderer.solid-2.ts @@ -0,0 +1,16 @@ +/** + * The renderer, for Solid 2.0. See `renderer.ts` for why this file is the only + * one that has a twin. + * + * `Dynamic` survived the major with the same props, and `createComponent` is + * re-exported by `@solidjs/web` from `solid-js`, so the two names this module + * carries are the same two names its 1.9 twin carries. The `JSX` namespace did + * not survive: `solid-js` no longer declares one, because the shape of an + * element is the renderer's business, so it comes from `@solidjs/web` here. + * + * The build swaps this file in as `renderer.ts` when emitting the + * `solid-layouts/solid-2` entry. It is never part of the 1.9 output, which is + * what lets it import a package a 1.9 consumer has no reason to install. + */ +export type { JSX } from "@solidjs/web"; +export { Dynamic, createComponent } from "@solidjs/web"; diff --git a/packages/solid-layouts/src/renderer.ts b/packages/solid-layouts/src/renderer.ts new file mode 100644 index 0000000..e69e7e2 --- /dev/null +++ b/packages/solid-layouts/src/renderer.ts @@ -0,0 +1,20 @@ +/** + * The renderer, for Solid 1.9. Its Solid 2.0 twin is `renderer.solid-2.ts`. + * + * This file exists because it is the *only* thing in the runtime that a major + * of Solid can move rather than rename. Everything else either kept its name + * and module (`createContext`, `useContext`, `createMemo`, `children`, the + * `Context` type) or can be told apart at runtime from the module object + * itself, which is what `component.ts` does for `splitProps` / `omit` and for + * `Context.Provider`. Rendering cannot: 1.9 puts `Dynamic` and + * `createComponent` under `solid-js/web`, 2.0 moved them to `@solidjs/web` and + * dropped the `solid-js/web` subpath entirely, so no single import statement + * resolves under both. + * + * The build therefore emits the same sources twice, swapping this file for its + * twin: `solid-layouts` is the 1.9 package entry, `solid-layouts/solid-2` the + * 2.0 one. This module is the only difference between the two outputs - + * `dist/component.js` and `dist/solid-2/component.js` are identical files. + */ +export type { JSX } from "solid-js"; +export { Dynamic, createComponent } from "solid-js/web"; diff --git a/packages/solid-layouts/tsconfig.build.json b/packages/solid-layouts/tsconfig.build.json index dcee450..afd5d19 100644 --- a/packages/solid-layouts/tsconfig.build.json +++ b/packages/solid-layouts/tsconfig.build.json @@ -9,5 +9,9 @@ "rootDir": "src" }, "include": ["src"], - "exclude": ["src/**/*.test.ts", "src/__parity__"] + "exclude": [ + "src/**/*.test.ts", + "src/__parity__", + "src/renderer.solid-2.ts" + ] } diff --git a/packages/solid-layouts/tsconfig.json b/packages/solid-layouts/tsconfig.json index 2ceaa88..fbd99c5 100644 --- a/packages/solid-layouts/tsconfig.json +++ b/packages/solid-layouts/tsconfig.json @@ -12,5 +12,9 @@ "skipLibCheck": true, "types": ["bun"] }, - "include": ["src"] + "include": ["src"], + // The Solid 2.0 renderer is checked by `tsconfig.solid-2.json`, against the + // Solid it targets. Checking it here would mean checking `@solidjs/web` + // against 1.9, which answers nothing. + "exclude": ["src/renderer.solid-2.ts"] } diff --git a/packages/solid-layouts/tsconfig.solid-2.json b/packages/solid-layouts/tsconfig.solid-2.json new file mode 100644 index 0000000..49c08e5 --- /dev/null +++ b/packages/solid-layouts/tsconfig.solid-2.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noEmit": false, + "declaration": true, + "declarationMap": true, + "outDir": "dist/solid-2", + "rootDir": "solid-2-staging", + "jsxImportSource": "@solidjs/web" + }, + "include": ["solid-2-staging"], + "exclude": ["solid-2-staging/**/*.test.ts", "solid-2-staging/__parity__"] +} From ebd44a9ff5230a3358032b331ddec05e09e2d72d Mon Sep 17 00:00:00 2001 From: meh Date: Sat, 15 Aug 2026 06:40:21 +0700 Subject: [PATCH 4/9] feat(compiler): emit the Solid 2 boundary under a `solid` option The runtime ships twice because Solid 2.0 moved `Dynamic` and `createComponent` out of `solid-js/web` and dropped that subpath. A generated component has to import its boundary from the matching entry, and the compiler is what writes that import, so it needs to be told which major the build targets: `solid: 2` emits `solid-layouts/solid-2/application-boundary` in place of `solid-layouts/application-boundary`. Told rather than sniffed. The compiler sees one source file, and which Solid an application runs on is not written in it. Default is 1 and the emission is byte-identical to before, which the test asserts directly rather than by inspection: a host that has never heard of this option keeps getting what it always got. The builtins list gains 2.0's renames - Suspense to Loading, SuspenseList to Reveal, ErrorBoundary to Errored, plus Repeat - and the source check admits `@solidjs/web`. Neither is gated behind the option, because the check tests a name against a module and no 1.9 build can import `Loading` from a Solid module that does not export one. 60 Rust tests and 21 JS tests pass. Verified through the rebuilt binding, not only through the Rust: all three of unset, 1 and 2 emit what they should. --- .../crates/common/src/lib.rs | 31 +++++ .../crates/transform/src/lib.rs | 68 ++++++++++- .../crates/transform/src/match_layouts.rs | 20 +++- packages/solid-layouts-oxc/index.d.ts | 6 + packages/solid-layouts-oxc/index.js | 108 +++++++++--------- packages/solid-layouts-oxc/src/lib.rs | 9 ++ 6 files changed, 184 insertions(+), 58 deletions(-) diff --git a/packages/solid-layouts-oxc/crates/common/src/lib.rs b/packages/solid-layouts-oxc/crates/common/src/lib.rs index 8120fbd..450e865 100644 --- a/packages/solid-layouts-oxc/crates/common/src/lib.rs +++ b/packages/solid-layouts-oxc/crates/common/src/lib.rs @@ -41,6 +41,34 @@ pub enum LibraryOutput { Component, } +/// Which major of Solid the emitted code targets. +/// +/// It decides one thing: which `solid-layouts` entry a generated component +/// imports its boundary from. The runtime is published twice because Solid 2.0 +/// moved `Dynamic` and `createComponent` out of `solid-js/web` into +/// `@solidjs/web` and dropped the old subpath, so one specifier cannot resolve +/// under both. +/// +/// Configured rather than sniffed. The compiler sees a source file, and the +/// answer is a fact about the application being built. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum SolidVersion { + #[default] + V1, + V2, +} + +impl SolidVersion { + /// The module a generated component imports `defineComponent` from. + pub fn application_boundary(self) -> &'static str { + match self { + Self::V1 => "solid-layouts/application-boundary", + Self::V2 => "solid-layouts/solid-2/application-boundary", + } + } +} + /// One resolved Layout package available to an application build. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -93,6 +121,8 @@ pub struct TransformOptions { #[serde(default)] pub library_output: LibraryOutput, #[serde(default)] + pub solid: SolidVersion, + #[serde(default)] pub config: LayoutsConfig, /// Off by default. With it set the pass parses and returns the source /// unchanged, which is how a host proves the pipeline is wired before any @@ -107,6 +137,7 @@ impl TransformOptions { filename: filename.into(), mode, library_output: LibraryOutput::default(), + solid: SolidVersion::default(), config: LayoutsConfig::default(), parse_only: false, } diff --git a/packages/solid-layouts-oxc/crates/transform/src/lib.rs b/packages/solid-layouts-oxc/crates/transform/src/lib.rs index 9a537e4..a703bc7 100644 --- a/packages/solid-layouts-oxc/crates/transform/src/lib.rs +++ b/packages/solid-layouts-oxc/crates/transform/src/lib.rs @@ -17,7 +17,8 @@ pub mod linter; pub mod match_layouts; use layouts_common::{ - CompilerMode, Diagnostic, FileKind, LibraryOutput, Severity, TransformOptions, TransformResult, + CompilerMode, Diagnostic, FileKind, LibraryOutput, Severity, SolidVersion, TransformOptions, + TransformResult, }; use oxc_allocator::Allocator; use oxc_ast::ast::{ @@ -124,7 +125,13 @@ pub fn transform(source: &str, options: &TransformOptions) -> TransformResult { let code = match options.mode { CompilerMode::Library => { - compile_library_source(source, &parsed.program, &layouts, options.library_output) + compile_library_source( + source, + &parsed.program, + &layouts, + options.library_output, + options.solid, + ) } CompilerMode::Application => compile_application_source(source, &parsed.program, options), }; @@ -215,6 +222,7 @@ fn compile_library_source( program: &Program<'_>, layouts: &[FoundLayout], output: LibraryOutput, + solid: SolidVersion, ) -> String { let recipes = compile_recipe::find_recipes(program); let index = compile_recipe::SlotIndex::build(&recipes); @@ -252,9 +260,15 @@ fn compile_library_source( let unresolved = semantic.scoping().root_unresolved_references(); if output == LibraryOutput::Component && !layouts.is_empty() { + // The boundary specifier is the only part of this header a major of + // Solid changes. `Component` is still exported from `solid-js` in 2.0, + // so the type import is the same line either way. edits.push(SourceEdit::Insert { at: 0, - text: "import { defineComponent as __defineLayoutComponent } from \"solid-layouts/application-boundary\";\nimport type { Component as __LayoutComponent } from \"solid-js\";\n".to_owned(), + text: format!( + "import {{ defineComponent as __defineLayoutComponent }} from \"{}\";\nimport type {{ Component as __LayoutComponent }} from \"solid-js\";\n", + solid.application_boundary(), + ), }); } @@ -777,6 +791,54 @@ export const Button: Layout = () => { ); } + #[test] + fn the_solid_major_picks_which_runtime_entry_the_boundary_imports() { + let source = r#"import type { Layout } from "solid-layouts"; +import { button } from "./Button.recipe"; +export const Button: Layout = () => { + return ; +}; +"#; + let boundary_of = |solid| { + let mut options = TransformOptions::new("Button.layout.tsx", CompilerMode::Library); + options.library_output = LibraryOutput::Component; + options.solid = solid; + transform(source, &options).code + }; + + // Default and explicit 1 are the same output, which is the point: a + // host that never sets the option keeps emitting what it always did. + let default = boundary_of(SolidVersion::default()); + assert_eq!(default, boundary_of(SolidVersion::V1)); + assert!( + default.contains("from \"solid-layouts/application-boundary\""), + "{default}" + ); + + let v2 = boundary_of(SolidVersion::V2); + assert!( + v2.contains("from \"solid-layouts/solid-2/application-boundary\""), + "{v2}" + ); + // The type import is not version-specific: 2.0 still exports + // `Component` from `solid-js`. + assert!( + v2.contains("import type { Component as __LayoutComponent } from \"solid-js\";"), + "{v2}" + ); + } + + #[test] + fn solid_2_renderer_builtins_need_no_layout() { + let source = r#"import { Loading, Errored } from "solid-js"; +import { Portal } from "@solidjs/web"; +export const View = () => ; +"#; + let options = TransformOptions::new("View.tsx", CompilerMode::Application); + let result = transform(source, &options); + assert!(result.diagnostics.is_empty(), "{:?}", result.diagnostics); + } + #[test] fn application_mode_rewrites_a_validated_package_import_to_c() { let source = r#"import { Icon as StatusIcon } from "@pathscale/test-ui"; diff --git a/packages/solid-layouts-oxc/crates/transform/src/match_layouts.rs b/packages/solid-layouts-oxc/crates/transform/src/match_layouts.rs index cbe8795..5702bc7 100644 --- a/packages/solid-layouts-oxc/crates/transform/src/match_layouts.rs +++ b/packages/solid-layouts-oxc/crates/transform/src/match_layouts.rs @@ -224,6 +224,12 @@ fn declared_name(declaration: &Declaration<'_>, origins: &mut HashMap`. const SOLID_BUILTINS: &[&str] = &[ "For", "Show", @@ -235,6 +241,11 @@ const SOLID_BUILTINS: &[&str] = &[ "Index", "Dynamic", "ErrorBoundary", + // 2.0 + "Loading", + "Reveal", + "Repeat", + "Errored", ]; /// Whether a name is a Solid built-in imported from Solid itself. @@ -242,8 +253,15 @@ const SOLID_BUILTINS: &[&str] = &[ /// Both halves matter. A user's own component called `Show` imported from /// their library still needs a Layout, and a built-in imported from anywhere /// else is not the built-in. +/// +/// `@solidjs/web` is where 2.0 serves the renderer's half of the list, and it +/// is Solid itself, so it belongs beside the two 1.9 modules rather than being +/// gated behind the version option. `solid-js/web` does not exist under 2.0 and +/// `@solidjs/web` does not exist under 1.9, so admitting all three cannot make +/// one major accept the other's import. fn is_solid_builtin(name: &str, source: &str) -> bool { - SOLID_BUILTINS.contains(&name) && (source == "solid-js" || source == "solid-js/web") + SOLID_BUILTINS.contains(&name) + && matches!(source, "solid-js" | "solid-js/web" | "@solidjs/web") } /// Checks every component reference against the configured Layout sources. diff --git a/packages/solid-layouts-oxc/index.d.ts b/packages/solid-layouts-oxc/index.d.ts index 0954b23..7ea2910 100644 --- a/packages/solid-layouts-oxc/index.d.ts +++ b/packages/solid-layouts-oxc/index.d.ts @@ -34,6 +34,12 @@ export interface JsLayoutSource { export interface JsOptions { mode: string libraryOutput?: string + /** + * Which major of Solid the output targets: `1` or `2`. Defaults to 1, + * so a host that has never heard of this option keeps emitting what it + * always emitted. + */ + solid?: number layoutSources?: Array parseOnly?: boolean } diff --git a/packages/solid-layouts-oxc/index.js b/packages/solid-layouts-oxc/index.js index cf4c747..3a4b891 100644 --- a/packages/solid-layouts-oxc/index.js +++ b/packages/solid-layouts-oxc/index.js @@ -77,8 +77,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-android-arm64') const bindingPackageVersion = require('solid-layouts-oxc-android-arm64/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -93,8 +93,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-android-arm-eabi') const bindingPackageVersion = require('solid-layouts-oxc-android-arm-eabi/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -114,8 +114,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-win32-x64-gnu') const bindingPackageVersion = require('solid-layouts-oxc-win32-x64-gnu/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -130,8 +130,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-win32-x64-msvc') const bindingPackageVersion = require('solid-layouts-oxc-win32-x64-msvc/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -147,8 +147,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-win32-ia32-msvc') const bindingPackageVersion = require('solid-layouts-oxc-win32-ia32-msvc/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -163,8 +163,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-win32-arm64-msvc') const bindingPackageVersion = require('solid-layouts-oxc-win32-arm64-msvc/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -182,8 +182,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-darwin-universal') const bindingPackageVersion = require('solid-layouts-oxc-darwin-universal/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -198,8 +198,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-darwin-x64') const bindingPackageVersion = require('solid-layouts-oxc-darwin-x64/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -214,8 +214,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-darwin-arm64') const bindingPackageVersion = require('solid-layouts-oxc-darwin-arm64/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -234,8 +234,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-freebsd-x64') const bindingPackageVersion = require('solid-layouts-oxc-freebsd-x64/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -250,8 +250,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-freebsd-arm64') const bindingPackageVersion = require('solid-layouts-oxc-freebsd-arm64/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -271,8 +271,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-x64-musl') const bindingPackageVersion = require('solid-layouts-oxc-linux-x64-musl/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -287,8 +287,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-x64-gnu') const bindingPackageVersion = require('solid-layouts-oxc-linux-x64-gnu/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -305,8 +305,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-arm64-musl') const bindingPackageVersion = require('solid-layouts-oxc-linux-arm64-musl/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -321,8 +321,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-arm64-gnu') const bindingPackageVersion = require('solid-layouts-oxc-linux-arm64-gnu/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -339,8 +339,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-arm-musleabihf') const bindingPackageVersion = require('solid-layouts-oxc-linux-arm-musleabihf/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -355,8 +355,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-arm-gnueabihf') const bindingPackageVersion = require('solid-layouts-oxc-linux-arm-gnueabihf/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -373,8 +373,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-loong64-musl') const bindingPackageVersion = require('solid-layouts-oxc-linux-loong64-musl/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -389,8 +389,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-loong64-gnu') const bindingPackageVersion = require('solid-layouts-oxc-linux-loong64-gnu/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -407,8 +407,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-riscv64-musl') const bindingPackageVersion = require('solid-layouts-oxc-linux-riscv64-musl/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -423,8 +423,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-riscv64-gnu') const bindingPackageVersion = require('solid-layouts-oxc-linux-riscv64-gnu/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -440,8 +440,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-ppc64-gnu') const bindingPackageVersion = require('solid-layouts-oxc-linux-ppc64-gnu/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -456,8 +456,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-s390x-gnu') const bindingPackageVersion = require('solid-layouts-oxc-linux-s390x-gnu/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -476,8 +476,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-openharmony-arm64') const bindingPackageVersion = require('solid-layouts-oxc-openharmony-arm64/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -492,8 +492,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-openharmony-x64') const bindingPackageVersion = require('solid-layouts-oxc-openharmony-x64/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -508,8 +508,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-openharmony-arm') const bindingPackageVersion = require('solid-layouts-oxc-openharmony-arm/package.json').version - if (bindingPackageVersion !== '0.1.6' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -648,8 +648,8 @@ if (!nativeBinding || forceWasi) { if (!candidateFailed) { if (process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { const bindingPackageVersion = require('solid-layouts-oxc-wasm32-wasi/package.json').version - if (bindingPackageVersion !== '0.1.6') { - throw new Error(`WASI binding package version mismatch, expected 0.1.6 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.1.7') { + throw new Error(`WASI binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } } wasiBinding = require('solid-layouts-oxc-wasm32-wasi') diff --git a/packages/solid-layouts-oxc/src/lib.rs b/packages/solid-layouts-oxc/src/lib.rs index 468d8b6..aa3cc8d 100644 --- a/packages/solid-layouts-oxc/src/lib.rs +++ b/packages/solid-layouts-oxc/src/lib.rs @@ -53,6 +53,10 @@ mod binding { pub struct JsOptions { pub mode: String, pub library_output: Option, + /// Which major of Solid the output targets: `1` or `2`. Defaults to 1, + /// so a host that has never heard of this option keeps emitting what it + /// always emitted. + pub solid: Option, pub layout_sources: Option>, pub parse_only: Option, } @@ -169,6 +173,11 @@ mod binding { Some("component") => layouts_common::LibraryOutput::Component, Some(other) => panic!("unknown solid-layouts library output: {other}"), }; + options_inner.solid = match given.solid { + None | Some(1) => layouts_common::SolidVersion::V1, + Some(2) => layouts_common::SolidVersion::V2, + Some(other) => panic!("unknown solid major: {other}"), + }; if let Some(layout_sources) = given.layout_sources { options_inner.config.sources = layout_sources .into_iter() From 8f8eeaa7636e8e231b72f4a1d963f5ae6fd2357d Mon Sep 17 00:00:00 2001 From: meh Date: Sat, 15 Aug 2026 06:43:40 +0700 Subject: [PATCH 5/9] feat(plugins): add the Solid 2 plugin pair `pluginSolid2LayoutsLibrary` and `pluginSolid2LayoutsApplication`, beside the existing pair rather than in place of it. They thread `solid: 2` through to the compiler, so the library emits its boundary import against `solid-layouts/solid-2/application-boundary` and the application aliases that specifier to the runtime's `./solid-2` entry instead of its root. Separate names rather than an option on the old ones, because the choice is not independent of the rest of the build: it has to agree with `pluginSolid2()` and with the installed `solid-js`. A name that must match its neighbour in the plugin list is easier to get right, and to read back later, than a flag that must: pluginSolid2LayoutsLibrary(), pluginBabel({ include: /\.(?:jsx|tsx)$/ }), pluginSolid2(), Asking a runtime that predates this for `./solid-2` now says so by name rather than quietly falling back to `main` and serving the wrong major. Both modes verified against the real compiler, not only the plumbing: bundle mode through a new test in library.test.js, and source mode - the one @pathscale/ui uses - by generating a fixture both ways and reading the header. Unset and 2 differ in exactly that one specifier and nowhere else. --- .../rsbuild-plugin-solid-layouts/index.d.ts | 2 + .../rsbuild-plugin-solid-layouts/index.js | 5 ++ packages/solid-layouts-oxc/application.d.ts | 13 ++++ packages/solid-layouts-oxc/application.js | 66 +++++++++++++++++-- packages/solid-layouts-oxc/library.d.ts | 9 +++ packages/solid-layouts-oxc/library.js | 37 +++++++---- packages/solid-layouts-oxc/library.test.js | 20 ++++++ packages/solid-layouts-oxc/loader.js | 1 + 8 files changed, 134 insertions(+), 19 deletions(-) diff --git a/packages/rsbuild-plugin-solid-layouts/index.d.ts b/packages/rsbuild-plugin-solid-layouts/index.d.ts index d141d92..d52affc 100644 --- a/packages/rsbuild-plugin-solid-layouts/index.d.ts +++ b/packages/rsbuild-plugin-solid-layouts/index.d.ts @@ -1,9 +1,11 @@ export { + pluginSolid2LayoutsApplication, pluginSolidLayoutsApplication, type ApplicationLayoutSource, type SolidLayoutsApplicationOptions, } from "solid-layouts-oxc/application"; export { + pluginSolid2LayoutsLibrary, pluginSolidLayoutsLibrary, type SolidLayoutsLibraryOptions, } from "solid-layouts-oxc/library"; diff --git a/packages/rsbuild-plugin-solid-layouts/index.js b/packages/rsbuild-plugin-solid-layouts/index.js index e74b277..0e887be 100644 --- a/packages/rsbuild-plugin-solid-layouts/index.js +++ b/packages/rsbuild-plugin-solid-layouts/index.js @@ -3,3 +3,8 @@ import library from "solid-layouts-oxc/library"; export const pluginSolidLayoutsApplication = application.pluginSolidLayoutsApplication; export const pluginSolidLayoutsLibrary = library.pluginSolidLayoutsLibrary; + +// The Solid 2.0 pair. Separate names rather than an option, so the plugin list +// reads as one choice: `pluginSolid2LayoutsLibrary()` beside `pluginSolid2()`. +export const pluginSolid2LayoutsApplication = application.pluginSolid2LayoutsApplication; +export const pluginSolid2LayoutsLibrary = library.pluginSolid2LayoutsLibrary; diff --git a/packages/solid-layouts-oxc/application.d.ts b/packages/solid-layouts-oxc/application.d.ts index 74e7616..d675477 100644 --- a/packages/solid-layouts-oxc/application.d.ts +++ b/packages/solid-layouts-oxc/application.d.ts @@ -10,6 +10,11 @@ export type SolidLayoutsApplicationOptions = { layouts?: ApplicationLayoutSource[]; runtime?: string; include?: string; + /** + * Which major of Solid the build targets. Defaults to 1. Prefer + * `pluginSolid2LayoutsApplication`, which sets it. + */ + solid?: 1 | 2; }; export type ResolvedLayoutSource = { @@ -30,6 +35,11 @@ export type CompiledApplication = { }; export declare const APPLICATION_BOUNDARY: "solid-layouts/application-boundary"; +export declare const SOLID_2_APPLICATION_BOUNDARY: "solid-layouts/solid-2/application-boundary"; +export declare function boundaryFor(solid?: 1 | 2): { + specifier: string; + subpath: "." | "./solid-2"; +}; export declare const FORMAT: "solid-layouts-library-v2"; export declare function compileApplication( options?: SolidLayoutsApplicationOptions, @@ -46,3 +56,6 @@ export declare function resolveLayoutSource( export declare function pluginSolidLayoutsApplication( options?: SolidLayoutsApplicationOptions, ): { name: string; enforce: "post"; setup(api: unknown): void }; +export declare function pluginSolid2LayoutsApplication( + options?: Omit, +): { name: string; enforce: "post"; setup(api: unknown): void }; diff --git a/packages/solid-layouts-oxc/application.js b/packages/solid-layouts-oxc/application.js index 4e12716..e3e026f 100644 --- a/packages/solid-layouts-oxc/application.js +++ b/packages/solid-layouts-oxc/application.js @@ -7,6 +7,28 @@ const { transform } = require("./index.js"); const FORMAT = "solid-layouts-library-v2"; const APPLICATION_BOUNDARY = "solid-layouts/application-boundary"; +const SOLID_2_APPLICATION_BOUNDARY = "solid-layouts/solid-2/application-boundary"; + +/** + * The specifier a generated component imports its boundary from, and the + * `solid-layouts` subpath that specifier has to resolve to. + * + * Two entries because the runtime is published twice: Solid 2.0 moved + * `Dynamic` and `createComponent` out of `solid-js/web` and dropped that + * subpath, so one build cannot serve both majors. The specifier is spelled out + * in the generated file rather than resolved by a bundler condition, which + * means `grep` answers which runtime a build is on and a mismatch reads as a + * wrong-looking import rather than as a resolve failure two layers down. + */ +function boundaryFor(solid) { + if (solid === undefined || solid === 1) { + return { specifier: APPLICATION_BOUNDARY, subpath: "." }; + } + if (solid === 2) { + return { specifier: SOLID_2_APPLICATION_BOUNDARY, subpath: "./solid-2" }; + } + throw new Error(`unknown solid major: ${solid}`); +} function readJson(path, label) { try { @@ -43,14 +65,23 @@ function requiredFile(packageRoot, path, label) { return absolute; } -function publicEntryFrom(packageJson) { - const rootExport = packageJson.exports?.["."]; +function publicEntryFrom(packageJson, subpath = ".") { + const rootExport = packageJson.exports?.[subpath]; if (typeof rootExport === "string") return rootExport; if (rootExport && typeof rootExport === "object") { for (const condition of ["import", "default"]) { if (typeof rootExport[condition] === "string") return rootExport[condition]; } } + // Only the root entry has the legacy fields to fall back on. A named subpath + // that is missing is a version of the runtime the installed package does not + // publish, which is worth saying plainly rather than silently serving the + // wrong major from `main`. + if (subpath !== ".") { + throw new Error( + `${packageJson.name}@${packageJson.version} does not export ${subpath}; it predates Solid 2 support`, + ); + } for (const field of ["module", "main"]) { if (typeof packageJson[field] === "string") return packageJson[field]; } @@ -141,14 +172,18 @@ function publicSubpathSources(source) { .sort((a, b) => a.module.localeCompare(b.module)); } -function resolvePublicPackageEntry(root, module) { +function resolvePublicPackageEntry(root, module, subpath = ".") { const packageJsonPath = resolvePackageJson(root, module); const packageRoot = dirname(packageJsonPath); const packageJson = readJson(packageJsonPath, `${module} package metadata`); if (packageJson.name !== module) { throw new Error(`resolved package ${packageJson.name} does not match ${module}`); } - return requiredFile(packageRoot, publicEntryFrom(packageJson), `${module} public entry`); + return requiredFile( + packageRoot, + publicEntryFrom(packageJson, subpath), + `${module} public entry`, + ); } function validateComponent(module, packageRoot, name, component) { @@ -286,8 +321,9 @@ function compileApplicationFile(source, filename, application) { } function pluginSolidLayoutsApplication(options = {}) { + const boundary = boundaryFor(options.solid); return { - name: "solid-layouts:application", + name: options.solid === 2 ? "solid-layouts:application:solid-2" : "solid-layouts:application", enforce: "post", setup(api) { const application = compileApplication({ @@ -296,13 +332,13 @@ function pluginSolidLayoutsApplication(options = {}) { }); const runtime = options.runtime ? resolve(application.root, options.runtime) - : resolvePublicPackageEntry(application.root, "solid-layouts"); + : resolvePublicPackageEntry(application.root, "solid-layouts", boundary.subpath); if (!existsSync(runtime)) throw new Error(`solid-layouts runtime not found: ${runtime}`); api.modifyBundlerChain({ order: "post", handler(chain) { - chain.resolve.alias.set(APPLICATION_BOUNDARY, runtime); + chain.resolve.alias.set(boundary.specifier, runtime); chain.module .rule("solid-layouts-application") .after("babel-js") @@ -321,11 +357,27 @@ function pluginSolidLayoutsApplication(options = {}) { }; } +/** + * The Solid 2.0 form of the application plugin. + * + * A separate exported name rather than an option the caller passes, because + * the choice is not independent of the rest of the build: it has to agree with + * `pluginSolid2()` and with the installed `solid-js`. A name that must match + * its neighbour in the plugin list is easier to get right, and easier to read + * back later, than a flag that must. + */ +function pluginSolid2LayoutsApplication(options = {}) { + return pluginSolidLayoutsApplication({ ...options, solid: 2 }); +} + module.exports = { APPLICATION_BOUNDARY, FORMAT, + SOLID_2_APPLICATION_BOUNDARY, + boundaryFor, compileApplication, compileApplicationFile, + pluginSolid2LayoutsApplication, pluginSolidLayoutsApplication, resolveLayoutSource, }; diff --git a/packages/solid-layouts-oxc/library.d.ts b/packages/solid-layouts-oxc/library.d.ts index 69a2a51..3bc612e 100644 --- a/packages/solid-layouts-oxc/library.d.ts +++ b/packages/solid-layouts-oxc/library.d.ts @@ -5,6 +5,12 @@ export type SolidLayoutsLibraryOptions = { output?: string; check?: boolean; updateBaseline?: boolean; + /** + * Which major of Solid the emitted boundary import targets. Defaults to 1, + * or to `solid` in `layouts.library.json`. Prefer + * `pluginSolid2LayoutsLibrary`, which sets it. + */ + solid?: 1 | 2; }; export type LibraryDiagnostic = { @@ -67,3 +73,6 @@ export declare function lintLibrary( export declare function pluginSolidLayoutsLibrary( options?: SolidLayoutsLibraryOptions, ): { name: string; setup(api: unknown): void }; +export declare function pluginSolid2LayoutsLibrary( + options?: Omit, +): { name: string; setup(api: unknown): void }; diff --git a/packages/solid-layouts-oxc/library.js b/packages/solid-layouts-oxc/library.js index 5b26a08..5a9f6ea 100644 --- a/packages/solid-layouts-oxc/library.js +++ b/packages/solid-layouts-oxc/library.js @@ -12,6 +12,7 @@ const { } = require("node:fs"); const { basename, dirname, relative, resolve, sep } = require("node:path"); const { lintProject, transform } = require("./index.js"); +const { boundaryFor } = require("./application.js"); const FORMAT = "solid-layouts-library-v2"; @@ -157,8 +158,8 @@ function formatDiagnostics(filename, diagnostics) { .join("\n"); } -function compileFile(source, filename, libraryOutput = "layout") { - const result = transform(source, filename, { mode: "library", libraryOutput }); +function compileFile(source, filename, libraryOutput = "layout", solid = 1) { + const result = transform(source, filename, { mode: "library", libraryOutput, solid }); if (result.failed) throw new Error(formatDiagnostics(filename, result.diagnostics)); return result.code; } @@ -255,6 +256,7 @@ function sourceModeExportsMessage(configPath) { function generateLibrarySource(options = {}) { const root = resolve(options.root || process.cwd()); const { configPath, config } = readLibraryConfig(root, options); + const solid = options.solid ?? config.solid; if (config.mode !== "source") { throw new Error(`${configPath || root} must set mode to "source" for adjacent generation`); } @@ -272,7 +274,7 @@ function generateLibrarySource(options = {}) { for (const input of filesBelow(lint.sourceRoot)) { if (!/\.layout\.(tsx|jsx)$/.test(input)) continue; const output = input.replace(/\.layout\.(tsx|jsx)$/, ".generated.$1"); - const compiled = `${compileFile(readFileSync(input, "utf8"), input, "component").trimEnd()}\n`; + const compiled = `${compileFile(readFileSync(input, "utf8"), input, "component", solid).trimEnd()}\n`; const current = existsSync(output) ? readFileSync(output, "utf8") : ""; if (current === compiled) continue; if (options.check) { @@ -314,7 +316,7 @@ function modulePath(fromFile, toFile) { return specifier.startsWith(".") ? specifier : `./${specifier}`; } -function generateEntries(components, outputRoot) { +function generateEntries(components, outputRoot, solid) { const entries = new Map(); for (const component of components) { const entry = resolve(outputRoot, component.entry); @@ -324,7 +326,7 @@ function generateEntries(components, outputRoot) { ); const recipe = resolve(outputRoot, component.recipe); const lines = entries.get(entry) || [ - 'import { defineComponent as __defineLayoutComponent } from "solid-layouts/application-boundary";', + `import { defineComponent as __defineLayoutComponent } from "${boundaryFor(solid).specifier}";`, 'import type { Component as __LayoutComponent } from "solid-js";', ]; const componentExpression = component.propsType @@ -351,7 +353,7 @@ function generateEntries(components, outputRoot) { } } -function assertComponent(component, sourceRoot, outputRoot) { +function assertComponent(component, sourceRoot, outputRoot, solid) { for (const key of ["name", "entry", "recipe", "recipeExport", "layout", "layoutExport"]) { if (!component[key]) throw new Error(`component entry is missing ${key}`); } @@ -418,7 +420,7 @@ function assertComponent(component, sourceRoot, outputRoot) { `${component.name}: generated layout does not export ${component.layoutExport}`, ); } - if (!entryOutput.includes("solid-layouts/application-boundary")) { + if (!entryOutput.includes(boundaryFor(solid).specifier)) { throw new Error(`${component.name}: ${component.entry} has no application compiler boundary`); } @@ -465,6 +467,7 @@ function compileLibrary(options = {}) { const root = resolve(options.root || process.cwd()); const { configPath, config } = readLibraryConfig(root, options); if (config.mode === "source") return generateLibrarySource({ ...options, root }); + const solid = options.solid ?? config.solid; const sourceRoot = resolve(root, config.source || "src"); const outputRoot = resolve(root, config.output || "bundle"); const sourcePackage = readJson(resolve(root, "package.json")); @@ -490,7 +493,7 @@ function compileLibrary(options = {}) { mkdirSync(dirname(output), { recursive: true }); if (isLayout || /\.recipe\.(ts|tsx|js|jsx)$/.test(fromSource)) { - const compiled = compileFile(readFileSync(input, "utf8"), input); + const compiled = compileFile(readFileSync(input, "utf8"), input, "layout", solid); writeFileSync(output, compiled); const parsed = transform(compiled, output, { mode: "library", parseOnly: true }); if (parsed.failed) throw new Error(formatDiagnostics(output, parsed.diagnostics)); @@ -500,11 +503,11 @@ function compileLibrary(options = {}) { } const configuredComponents = config.components || discoverComponents(sourceRoot); - generateEntries(configuredComponents, outputRoot); + generateEntries(configuredComponents, outputRoot, solid); const components = {}; for (const component of configuredComponents) { - components[component.name] = assertComponent(component, sourceRoot, outputRoot); + components[component.name] = assertComponent(component, sourceRoot, outputRoot, solid); } if (Object.keys(components).length === 0) { throw new Error(`${configPath || sourceRoot} must contain at least one Layout component`); @@ -547,10 +550,11 @@ function compileLibrary(options = {}) { function pluginSolidLayoutsLibrary(options = {}) { return { - name: "solid-layouts:library", + name: options.solid === 2 ? "solid-layouts:library:solid-2" : "solid-layouts:library", setup(api) { const root = resolve(options.root || api.context.rootPath); const { config } = readLibraryConfig(root, options); + const solid = options.solid ?? config.solid; const compile = () => compileLibrary({ ...options, @@ -570,7 +574,7 @@ function pluginSolidLayoutsLibrary(options = {}) { .end() .use("solid-layouts-library") .loader(require.resolve("./loader.js")) - .options({ mode: "library", libraryOutput: "layout" }); + .options({ mode: "library", libraryOutput: "layout", solid }); }, }); api.onAfterBuild(() => emitSourceManifest({ ...options, root })); @@ -579,11 +583,20 @@ function pluginSolidLayoutsLibrary(options = {}) { }; } +/** + * The Solid 2.0 form of the library plugin. See its application twin for why + * this is a second exported name rather than an option on the first. + */ +function pluginSolid2LayoutsLibrary(options = {}) { + return pluginSolidLayoutsLibrary({ ...options, solid: 2 }); +} + module.exports = { FORMAT, compileLibrary, generateLibrarySource, emitSourceManifest, lintLibrary, + pluginSolid2LayoutsLibrary, pluginSolidLayoutsLibrary, }; diff --git a/packages/solid-layouts-oxc/library.test.js b/packages/solid-layouts-oxc/library.test.js index f298297..748bcef 100644 --- a/packages/solid-layouts-oxc/library.test.js +++ b/packages/solid-layouts-oxc/library.test.js @@ -78,6 +78,26 @@ test("builds valid generated Layout source and a package manifest", () => { ); }); +test("the solid major picks which runtime entry the generated entry imports", () => { + // The whole point of naming the runtime in the emitted source rather than + // resolving it through a bundler condition: which major a build is on is a + // line you can read, in a file you can grep. + const one = readFileSync( + join(compileLibrary({ root: fixture() }).outputRoot, "index.ts"), + "utf8", + ); + const two = readFileSync( + join(compileLibrary({ root: fixture(), solid: 2 }).outputRoot, "index.ts"), + "utf8", + ); + + expect(one).toContain('from "solid-layouts/application-boundary"'); + expect(one).not.toContain("solid-2"); + expect(two).toContain('from "solid-layouts/solid-2/application-boundary"'); + // Everything else about the two entries is the same file. + expect(two.replace("/solid-2/application-boundary", "/application-boundary")).toBe(one); +}); + test("lints the library with the native project checker", () => { const root = fixture(); const result = lintLibrary({ root }); diff --git a/packages/solid-layouts-oxc/loader.js b/packages/solid-layouts-oxc/loader.js index 8341f1c..3cb625c 100644 --- a/packages/solid-layouts-oxc/loader.js +++ b/packages/solid-layouts-oxc/loader.js @@ -31,6 +31,7 @@ module.exports = function layoutsLoader(source) { result = transform(source, filename, { mode: options.mode, libraryOutput: options.libraryOutput, + solid: options.solid, layoutSources: options.layoutSources, parseOnly: options.parseOnly, }); From 5718a1b9965c2ee264b9bdf64aaa6e8612ea3b66 Mon Sep 17 00:00:00 2001 From: meh Date: Sat, 15 Aug 2026 06:44:39 +0700 Subject: [PATCH 6/9] docs: record what Solid 2 support turned out to be --- SOLID-2-PLAN.md | 197 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 132 insertions(+), 65 deletions(-) diff --git a/SOLID-2-PLAN.md b/SOLID-2-PLAN.md index ec93ec6..46f5b16 100644 --- a/SOLID-2-PLAN.md +++ b/SOLID-2-PLAN.md @@ -1,97 +1,164 @@ # Solid 2 support for the layouts toolchain -Measured 2026-08-15 on `next/solid-2`, branched from `master` at `a107bf1`, -which is exactly the published state: solid-layouts 0.1.3, solid-layouts-oxc -0.1.7, rsbuild-plugin-solid-layouts 0.1.4. Tagged `solid-1-baseline`. +Scoped 2026-08-15 on `next/solid-2`, branched from `master` at `a107bf1`, which +is exactly the published state: solid-layouts 0.1.3, solid-layouts-oxc 0.1.7, +rsbuild-plugin-solid-layouts 0.1.4. Tagged `solid-1-baseline`. -## It is one file +**Status: built, tested, unpublished.** The toolchain now serves both majors. +Steps 1 to 5 below are done; step 6, publishing, is not. + +## It is one file, and inside that file one import I had this down as "three packages need Solid 2 support", which was true but -useless. Measured, the whole dependence is: +useless. Measured, the whole dependence was: | where | Solid sites | note | | --- | ---: | --- | -| `packages/solid-layouts/src/component.ts` | **32** | 437 lines. This is the job. | +| `packages/solid-layouts/src/component.ts` | **32** | 437 lines. This was the job. | | `packages/solid-layouts/src/component.test.ts` | 34 | follows the source | | `packages/solid-layouts/src/ids.test.ts` | 3 | `createRoot` only | -| `packages/solid-layouts/src/defaults.ts` | 1 | | -| `packages/solid-layouts-oxc` (3,850 lines of Rust) | **2 real** | an emitted import header and a builtins list; the other two hits are a test fixture | -| `packages/rsbuild-plugin-solid-layouts` | **0** | `index.js` + `index.d.ts`, a thin wrapper, no Solid usage | - -`component.ts` imports exactly this: - -```ts -import { - type Context, type JSX, - children as resolveChildren, createContext, createMemo, splitProps, useContext, -} from "solid-js"; -import { Dynamic, createComponent } from "solid-js/web"; +| `packages/solid-layouts-oxc` (3,850 lines of Rust) | **2 real** | an emitted import header and a builtins list | +| `packages/rsbuild-plugin-solid-layouts` | **0** | a thin wrapper, no Solid usage | + +Then it got smaller again. Of the four things `component.ts` used that 2.0 +changed, three can be told apart at runtime from the module object itself, so +they needed no fork at all: + +| what | how it is handled | +| --- | --- | +| `splitProps` became `omit` | resolved once at load: `"omit" in solid` | +| `Context.Provider` became the context | `context.Provider ?? context` | +| `useContext` throws instead of returning `undefined` | the internal defaults context now carries `{}`, which both majors read the same way | +| **`Dynamic` and `createComponent` moved module** | **the only real fork** | + +The fourth cannot be detected, because it is a module specifier and those are +resolved before any code runs. 1.9 serves them from `solid-js/web`; 2.0 moved +them to `@solidjs/web` **and dropped the `solid-js/web` subpath entirely**, so +no single import statement resolves under both. That is now `src/renderer.ts`, +twenty lines, with a twin in `src/renderer.solid-2.ts`. `scripts/build.mjs` +emits the tree twice with the twin swapped in. `dist/component.js` and +`dist/solid-2/component.js` are identical files. + +## Three things the migration guide did not tell me + +Read out of `solid-js@2.0.0-rc.0` and `@solidjs/signals@2.0.0-rc.0` rather than +out of the guide, and all three changed the plan: + +1. **`Dynamic` survived unchanged.** It is still a component taking a + `component` prop, exported from `@solidjs/web`. The plan predicted a rewrite + to a `dynamic(source)` factory. `dynamic()` exists, but `Dynamic` does too, + and `createComponent` is re-exported by `@solidjs/web` from `solid-js`, so + the two names the renderer needs are the same two names in both majors. +2. **`JSX` is gone from `solid-js`.** Core no longer declares the namespace at + all, because the shape of an element is the renderer's business. It comes + from `@solidjs/web` now. The plan missed this entirely, and it is the reason + the renderer module has to carry the type as well as the two values. +3. **`useContext` throws in the implementation, not just the docs.** + `getContext` throws `ContextNotFoundError` when the resolved value is + `undefined` and `NoOwnerError` when there is no owner. A provider supplying + `undefined` counts as having provided, so an empty provider **shadows a real + one above it with a throw**. `defineComponent` now skips the wrapper when the + setup returned no context, which is a correctness fix under 2.0 and a no-op + under 1.9. + +## `splitProps` was the part that changed shape + +Four buckets came out of one call, and the call made them disjoint by +construction: a key named in two lists landed in the earlier one only. + +```js +const [presentation, escape, behaviour, passthrough] = + splitProps(props, presentationKeys, ["class", "className", "style", "children"], behaviourKeys); ``` -Seven named imports and two from `web`. That is the entire surface. +`omit` returns only the remainder, and neither major ships the subset half. So +the three routed buckets are picked by name, the fourth still falls out of one +call, and which bucket each declared key belongs to is decided **once per +component** rather than once per render. -## What each one becomes +## The compiler: an option, not a fork -| 1.x | 2.0 | difficulty | -| --- | --- | --- | -| `splitProps(props, a, b, c)` | `omit(props, ...)` | **the real work** — see below | -| `useContext` | same name, but **throws** on a default-less context instead of returning `undefined` | design decision | -| `createComponent`, `Dynamic` | move to `@solidjs/web`; `Dynamic` becomes the `dynamic(source)` factory | mechanical | -| `children`, `createMemo`, `createContext` | unchanged names | mechanical | -| `Context.Provider` | context is the provider: `` | mechanical | +`solid: 1 | 2` on `TransformOptions`. It decides one thing, the specifier a +generated component imports its boundary from: -### `splitProps` is the one that matters +``` +solid-layouts/application-boundary -> solid-layouts/solid-2/application-boundary +``` -The runtime's whole prop-routing model is built on it. From `component.js`: +Told rather than sniffed: the compiler sees one source file, and which Solid an +application runs on is not written in it. Default is 1 and the emission is +byte-identical to before, asserted by a test rather than by inspection. -```js -const [presentation, escape, behaviour, passthrough] = - splitProps(props, presentationKeys, ["class", "className", "style", "children"], behaviourKeys); -``` +The builtins list gained 2.0's renames (`Suspense` to `Loading`, `SuspenseList` +to `Reveal`, `ErrorBoundary` to `Errored`, plus `Repeat`) and the source check +admits `@solidjs/web`. Neither is gated behind the option: the check tests a +name against a module, and no 1.9 build can import `Loading` from a Solid module +that does not export one. -Four buckets from one call. `omit(props, ...keys)` returns **only the -remainder**, so this becomes several `omit` calls plus explicit picks, and the -bucket boundaries have to be re-derived rather than falling out of the split. -That is the piece to design first, because everything else in the file reads -those four names. +## Why the specifier and not an export condition -### The Rust is two lines +Both work. A `solid-2` export condition would keep the generated files +byte-identical between majors and cost no compiler change at all. It was built +that way first and then removed, for one reason: a specifier is a line you can +read. `grep` answers which runtime a build is on, and a mismatch reads as a +wrong-looking import rather than as a resolve failure two layers down. The +condition also needed `customConditions` in every consumer's tsconfig to keep +tsc agreeing with the bundler. -```rust -// match_layouts.rs:246 -SOLID_BUILTINS.contains(&name) && (source == "solid-js" || source == "solid-js/web") -``` +The cost of the explicit form is one edit in `@pathscale/ui`, because the +library funnels every hand-written runtime import through `src/lib/layouts/index.ts`. -`SOLID_BUILTINS` lists `For, Show, Switch, Match, Suspense, SuspenseList, …`. -Under 2.0, `Suspense` is `Loading`, `SuspenseList` is `Reveal`, `ErrorBoundary` -is `Errored`, and `Index` is gone in favour of ``. So the -list changes and the source check has to admit `@solidjs/web`. +## The plugins -```rust -// lib.rs:257 — the header prepended to every .generated.tsx -"import { defineComponent as __defineLayoutComponent } from \"solid-layouts/application-boundary\"; - import type { Component as __LayoutComponent } from \"solid-js\";" +Two more exported names rather than an option on the existing two: + +```js +pluginSolid2LayoutsLibrary(), +pluginBabel({ include: /\.(?:jsx|tsx)$/ }), +pluginSolid2(), ``` -`Component` still comes from `solid-js`; only the builtins source list needs -widening. Both edits are small and both need fixture regeneration. +The choice is not independent of the rest of the build. It has to agree with +`pluginSolid2()` and with the installed `solid-js`, and a name that must match +its neighbour in the plugin list is easier to get right than a flag that must. +`pluginSolidLayoutsLibrary`/`Application` are untouched. + +Asking a runtime that predates this for `./solid-2` now fails by name rather +than quietly falling back to `main` and serving the wrong major. ## Order of work -1. **`component.ts` prop routing.** Replace the four-bucket `splitProps` with - `omit` plus explicit picks. Everything else is downstream of this. -2. **The context decision.** `useContext` throwing changes what a compound - component does outside its provider — in `@pathscale/ui` that pattern appears - at 57 sites with only 17 guarded. Decide here, because the runtime is where - the fallback lives. -3. **`@solidjs/web` imports and `dynamic()`.** -4. **Rust: builtins list + source check**, then regenerate fixtures. -5. **`rsbuild-plugin-solid-layouts`**: nothing in its own source, but it sits - beside `@rsbuild/plugin-solid@1.2.2`, which *depends on* - `babel-preset-solid: ^1.9.12`. That is a hard pin on Solid 1's JSX transform - and needs an override to `babel-preset-solid@next` or a patched plugin. +1. ~~**`component.ts` prop routing.**~~ Done. `pick` plus one `rest`, buckets + resolved per component. +2. **The context decision.** Half done. The runtime's own context carries a + default now, which settles `solid-layouts`. The library question is open: + `@pathscale/ui` calls `useContext` at **57 sites with only 17 guarded**, and + every compound component that currently works standalone throws under 2.0 + unless each context gets a default. That is an API decision about what 3.0 + *is*, and it does not belong in this repository. +3. ~~**`@solidjs/web` imports.**~~ Done, and smaller than expected: `Dynamic` + did not change shape. +4. ~~**Rust: builtins list, source check, boundary option.**~~ Done. 60 Rust + tests, 22 JS tests. +5. ~~**`rsbuild-plugin-solid-layouts`.**~~ Done. Still true that it sits beside + `@rsbuild/plugin-solid@1.2.2`, which *depends on* `babel-preset-solid: + ^1.9.12`. That is a hard pin on Solid 1's JSX transform and needs an override + to `babel-preset-solid@next` or a patched plugin. Untested. 6. **Publish under a prerelease tag** (`0.2.0-rc.0` on `next`) so `@pathscale/ui` on `next/solid-2` can consume it without touching `latest`. + Not done. + +## What is verified, and what is not + +Verified by running it: 145 runtime tests under 1.9 unchanged; both builds +emitted; 60 Rust tests; 22 compiler JS tests; the boundary specifier checked +end to end through the rebuilt native binding in both bundle and source mode. + +**Not verified:** the 2.0 build has never run against an installed `solid-js@2`. +It typechecks with `skipLibCheck`, so its declarations bind to `@solidjs/web` +but nothing has checked `@solidjs/web` against the Solid 2 it expects. The first +real test is a `@pathscale/ui` build on Solid 2, and that is the next thing to +do. ## What is NOT blocked on this From 137adabdb4e08f8d1c7e75c5de7c0d6d0427695b Mon Sep 17 00:00:00 2001 From: meh Date: Sat, 15 Aug 2026 06:56:48 +0700 Subject: [PATCH 7/9] chore: 0.2.0 across the three toolchain packages Minor rather than major, and not a prerelease: 1.9 is still the default on every entry point, `pluginSolidLayoutsLibrary` and its application twin are untouched, and the compiler emits byte-identical output when `solid` is unset. Nothing that installs 0.1.x breaks on 0.2.0. All three move together because the feature spans all three: the runtime gained a second build, the compiler gained the option that picks it, and the plugin gained the pair of names that sets the option. `index.js` regenerated - napi bakes the package version into the binding loader's mismatch check, so a bump that skips it publishes a loader that rejects its own binary. --- .../rsbuild-plugin-solid-layouts/package.json | 4 +- packages/solid-layouts-oxc/index.js | 108 +++++++++--------- packages/solid-layouts-oxc/package.json | 2 +- packages/solid-layouts/package.json | 2 +- 4 files changed, 58 insertions(+), 58 deletions(-) diff --git a/packages/rsbuild-plugin-solid-layouts/package.json b/packages/rsbuild-plugin-solid-layouts/package.json index b321a9d..d9d8b35 100644 --- a/packages/rsbuild-plugin-solid-layouts/package.json +++ b/packages/rsbuild-plugin-solid-layouts/package.json @@ -1,6 +1,6 @@ { "name": "rsbuild-plugin-solid-layouts", - "version": "0.1.4", + "version": "0.2.0", "description": "Rsbuild integration for the Solid Layouts library and application compilers", "license": "MIT", "type": "module", @@ -19,7 +19,7 @@ "index.d.ts" ], "dependencies": { - "solid-layouts-oxc": "0.1.7" + "solid-layouts-oxc": "0.2.0" }, "peerDependencies": { "@rsbuild/core": ">=1.3.0" diff --git a/packages/solid-layouts-oxc/index.js b/packages/solid-layouts-oxc/index.js index 3a4b891..17ba664 100644 --- a/packages/solid-layouts-oxc/index.js +++ b/packages/solid-layouts-oxc/index.js @@ -77,8 +77,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-android-arm64') const bindingPackageVersion = require('solid-layouts-oxc-android-arm64/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -93,8 +93,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-android-arm-eabi') const bindingPackageVersion = require('solid-layouts-oxc-android-arm-eabi/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -114,8 +114,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-win32-x64-gnu') const bindingPackageVersion = require('solid-layouts-oxc-win32-x64-gnu/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -130,8 +130,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-win32-x64-msvc') const bindingPackageVersion = require('solid-layouts-oxc-win32-x64-msvc/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -147,8 +147,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-win32-ia32-msvc') const bindingPackageVersion = require('solid-layouts-oxc-win32-ia32-msvc/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -163,8 +163,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-win32-arm64-msvc') const bindingPackageVersion = require('solid-layouts-oxc-win32-arm64-msvc/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -182,8 +182,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-darwin-universal') const bindingPackageVersion = require('solid-layouts-oxc-darwin-universal/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -198,8 +198,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-darwin-x64') const bindingPackageVersion = require('solid-layouts-oxc-darwin-x64/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -214,8 +214,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-darwin-arm64') const bindingPackageVersion = require('solid-layouts-oxc-darwin-arm64/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -234,8 +234,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-freebsd-x64') const bindingPackageVersion = require('solid-layouts-oxc-freebsd-x64/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -250,8 +250,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-freebsd-arm64') const bindingPackageVersion = require('solid-layouts-oxc-freebsd-arm64/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -271,8 +271,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-x64-musl') const bindingPackageVersion = require('solid-layouts-oxc-linux-x64-musl/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -287,8 +287,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-x64-gnu') const bindingPackageVersion = require('solid-layouts-oxc-linux-x64-gnu/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -305,8 +305,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-arm64-musl') const bindingPackageVersion = require('solid-layouts-oxc-linux-arm64-musl/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -321,8 +321,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-arm64-gnu') const bindingPackageVersion = require('solid-layouts-oxc-linux-arm64-gnu/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -339,8 +339,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-arm-musleabihf') const bindingPackageVersion = require('solid-layouts-oxc-linux-arm-musleabihf/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -355,8 +355,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-arm-gnueabihf') const bindingPackageVersion = require('solid-layouts-oxc-linux-arm-gnueabihf/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -373,8 +373,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-loong64-musl') const bindingPackageVersion = require('solid-layouts-oxc-linux-loong64-musl/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -389,8 +389,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-loong64-gnu') const bindingPackageVersion = require('solid-layouts-oxc-linux-loong64-gnu/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -407,8 +407,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-riscv64-musl') const bindingPackageVersion = require('solid-layouts-oxc-linux-riscv64-musl/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -423,8 +423,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-riscv64-gnu') const bindingPackageVersion = require('solid-layouts-oxc-linux-riscv64-gnu/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -440,8 +440,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-ppc64-gnu') const bindingPackageVersion = require('solid-layouts-oxc-linux-ppc64-gnu/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -456,8 +456,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-linux-s390x-gnu') const bindingPackageVersion = require('solid-layouts-oxc-linux-s390x-gnu/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -476,8 +476,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-openharmony-arm64') const bindingPackageVersion = require('solid-layouts-oxc-openharmony-arm64/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -492,8 +492,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-openharmony-x64') const bindingPackageVersion = require('solid-layouts-oxc-openharmony-x64/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -508,8 +508,8 @@ function requireNative() { try { const binding = require('solid-layouts-oxc-openharmony-arm') const bindingPackageVersion = require('solid-layouts-oxc-openharmony-arm/package.json').version - if (bindingPackageVersion !== '0.1.7' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } return binding } catch (e) { @@ -648,8 +648,8 @@ if (!nativeBinding || forceWasi) { if (!candidateFailed) { if (process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { const bindingPackageVersion = require('solid-layouts-oxc-wasm32-wasi/package.json').version - if (bindingPackageVersion !== '0.1.7') { - throw new Error(`WASI binding package version mismatch, expected 0.1.7 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + if (bindingPackageVersion !== '0.2.0') { + throw new Error(`WASI binding package version mismatch, expected 0.2.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) } } wasiBinding = require('solid-layouts-oxc-wasm32-wasi') diff --git a/packages/solid-layouts-oxc/package.json b/packages/solid-layouts-oxc/package.json index 328d9a6..01f35f6 100644 --- a/packages/solid-layouts-oxc/package.json +++ b/packages/solid-layouts-oxc/package.json @@ -1,6 +1,6 @@ { "name": "solid-layouts-oxc", - "version": "0.1.7", + "version": "0.2.0", "description": "The Layouts pre-pass for SolidJS, built on oxc", "license": "MIT", "type": "commonjs", diff --git a/packages/solid-layouts/package.json b/packages/solid-layouts/package.json index d41a31c..2b398f4 100644 --- a/packages/solid-layouts/package.json +++ b/packages/solid-layouts/package.json @@ -1,6 +1,6 @@ { "name": "solid-layouts", - "version": "0.1.3", + "version": "0.2.0", "description": "Logic in a .ts file, markup in a .layout.tsx file, presentation declared at the call site", "license": "MIT", "type": "module", From 8481053a561d1cd5e19ab5118c4c951bd1e8ccbf Mon Sep 17 00:00:00 2001 From: meh Date: Sat, 15 Aug 2026 07:04:50 +0700 Subject: [PATCH 8/9] style: cargo fmt --- .../crates/transform/src/lib.rs | 16 +++++++--------- .../crates/transform/src/match_layouts.rs | 3 +-- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/packages/solid-layouts-oxc/crates/transform/src/lib.rs b/packages/solid-layouts-oxc/crates/transform/src/lib.rs index a703bc7..65f7300 100644 --- a/packages/solid-layouts-oxc/crates/transform/src/lib.rs +++ b/packages/solid-layouts-oxc/crates/transform/src/lib.rs @@ -124,15 +124,13 @@ pub fn transform(source: &str, options: &TransformOptions) -> TransformResult { } let code = match options.mode { - CompilerMode::Library => { - compile_library_source( - source, - &parsed.program, - &layouts, - options.library_output, - options.solid, - ) - } + CompilerMode::Library => compile_library_source( + source, + &parsed.program, + &layouts, + options.library_output, + options.solid, + ), CompilerMode::Application => compile_application_source(source, &parsed.program, options), }; let changed = code != source; diff --git a/packages/solid-layouts-oxc/crates/transform/src/match_layouts.rs b/packages/solid-layouts-oxc/crates/transform/src/match_layouts.rs index 5702bc7..b196071 100644 --- a/packages/solid-layouts-oxc/crates/transform/src/match_layouts.rs +++ b/packages/solid-layouts-oxc/crates/transform/src/match_layouts.rs @@ -260,8 +260,7 @@ const SOLID_BUILTINS: &[&str] = &[ /// `@solidjs/web` does not exist under 1.9, so admitting all three cannot make /// one major accept the other's import. fn is_solid_builtin(name: &str, source: &str) -> bool { - SOLID_BUILTINS.contains(&name) - && matches!(source, "solid-js" | "solid-js/web" | "@solidjs/web") + SOLID_BUILTINS.contains(&name) && matches!(source, "solid-js" | "solid-js/web" | "@solidjs/web") } /// Checks every component reference against the configured Layout sources. From e3b368c9c5c6b9dfb44355c8d0d83c34af088c67 Mon Sep 17 00:00:00 2001 From: meh Date: Sat, 15 Aug 2026 07:43:52 +0700 Subject: [PATCH 9/9] ci: retrigger after the base change