@octanejs/mcp-server 0.2.24 → 0.2.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@octanejs/mcp-server",
3
- "version": "0.2.24",
3
+ "version": "0.2.26",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=22.22.2"
@@ -30,6 +30,15 @@ details but do not replace these gates.
30
30
  the retained state.
31
31
  - Use native event semantics. `onInput` is the per-edit event for text controls;
32
32
  do not add synthetic `onChange` compatibility or event wrapper allocation.
33
+ - Style with sibling-scoped `<style>` blocks and assigned theme blocks
34
+ (`const theme = <style>…</style>`, `class={theme.card}`,
35
+ `<style apply={theme} />`) instead of a CSS-in-JS runtime. A block styles
36
+ the items beside it and everything below them, never the element that
37
+ contains it: put it beside the element in a fragment
38
+ (`<><style>…</style><div>…</div></>`), inside `@{ … }` and directive bodies
39
+ too. Keep block CSS static and pass runtime values through custom
40
+ properties. A block inside a control-flow branch ships its CSS whichever
41
+ branch renders, so keep branch-only rules small.
33
42
  - For SSR, avoid client/server data divergence and duplicate fetches. Exercise
34
43
  hydration with production-compiled output and preserve abort/error behavior.
35
44
  - Treat bundle size and dependency cost as performance. Check for an official
@@ -45,6 +45,7 @@ locals, early returns) stays above it.
45
45
  | text `<input onChange={...}>` meaning every edit | `<input onInput={...}>` (native event) |
46
46
  | controlled `value={state}` | keep it — React's controlled semantics apply; pair with `onInput` |
47
47
  | `className={clsx(...)}` | `class={[...]}` composes clsx-style natively |
48
+ | CSS Modules `styles.card` / CSS-in-JS | `const theme = <style>…</style>` (a class map: `$class` plus one key per class) and `class={theme.card}`; a `<style>` block among an element's or fragment's children styles the items beside it and below (never its container), and `<style apply={theme} />` applies a theme to those same items |
48
49
  | `useDebugValue(x)` | keep or delete — present as an accepted no-op |
49
50
  | `React.lazy(() => import(...))` | `lazy()` works as-is (and also accepts a bare component from the loader) |
50
51
  | `defaultProps` | parameter defaults / destructuring defaults |
@@ -85,6 +85,28 @@ React's `{ default }` module shape works, and Octane additionally accepts a
85
85
  component directly from the loader. Suspense and ViewTransition are ordinary
86
86
  components, so wrapping them in `lazy()` is valid; nested lazy wrappers are not.
87
87
 
88
+ ## Scoped styles are sibling-scoped
89
+
90
+ A `<style>` block with raw CSS is TSRX template syntax, not a global stylesheet
91
+ as in React. It is a child of an element or a fragment and is scoped to its
92
+ siblings, not to the `@{ … }` body around it: it styles the items beside it and
93
+ everything below them — never the element that contains it —
94
+ selectors are rewritten with the hash of that children list and the hash is
95
+ stamped on those siblings and their descendants. To style an element, make the
96
+ block and the element fragment siblings (`<><style>…</style><div>…</div></>`);
97
+ a `@{ … }` or directive body holds one output node, so wrap the block and the
98
+ output in a fragment there too. Nested scopes stack their hashes outer to
99
+ inner; several blocks among the same children share one hash; `:global(…)` opts
100
+ out. `const theme = <style>…</style>` yields a class map (`$class` plus one key
101
+ per class) and `<style apply={theme} />` applies it to the items beside it,
102
+ with `apply={[a, b]}` composing. A theme must be declared before its applier.
103
+ The CSS of a control-flow branch is always emitted; only the stamping follows
104
+ the branch. A raw-CSS block is allowed only inside a `@{ … }` or
105
+ `@if`/`@for`/`@switch`/`@try` body; plain TSX keeps React's rule, where
106
+ `<style>{css}</style>` is an ordinary element passed through untouched. Only
107
+ `<style href precedence>` keeps React's Float semantics. Do not port this to
108
+ CSS Modules or a CSS-in-JS runtime.
109
+
88
110
  ## class / className composes clsx-style
89
111
 
90
112
  Strings, numbers, arrays, objects, and nesting compose into a class string;
@@ -24,8 +24,10 @@ const { html, css } = await prerender(App, props, {
24
24
  - `html`: rendered markup with hydration markers, plus an inline suspense seed
25
25
  script when anything resolved. Hoisted `<title>/<meta>/<link>` fold in
26
26
  (spliced into `<head>` if present, else prepended).
27
- - `css`: deduped `<style data-octane>` tags from scoped styles; place inside
28
- `<head>`.
27
+ - `css`: deduped `<style data-octane>` tags from scoped styles, one per hash;
28
+ a component contributes one per style scope (nested `@{ … }` and
29
+ control-flow bodies have their own) plus one per assigned theme block. Place
30
+ them inside `<head>`.
29
31
  - Use `renderToString` (from `octane/server`) for a single synchronous pass that
30
32
  leaves `@pending` fallbacks in place; use `prerender` to await the data.
31
33
  - Options are optional: `nonce` stamps CSP nonces on the emitted inline tags (all
@@ -54,7 +56,9 @@ hydrateRoot(document.getElementById('app')!, App, props);
54
56
  ```
55
57
 
56
58
  Pass the same component and props on both sides. `useId` and scoped styles are
57
- hydration-stable; the client adopts server DOM instead of rebuilding it.
59
+ hydration-stable, including the stacked scope hashes and applied theme classes
60
+ (`<style apply={theme} />`, `theme.$class`); the client adopts server DOM
61
+ instead of rebuilding it.
58
62
 
59
63
  ## Two integration paths
60
64
 
package/src/bridge.js CHANGED
@@ -68,6 +68,8 @@ export const KNOWN_BINDINGS = {
68
68
  'react-hook-form': '@octanejs/hook-form',
69
69
  'better-auth/react': '@octanejs/better-auth',
70
70
  '@base-ui-components/react': '@octanejs/base-ui',
71
+ '@base-ui/react': '@octanejs/base-ui',
72
+ '@base-ui/utils': '@octanejs/base-ui-utils',
71
73
  '@dnd-kit/react': '@octanejs/dnd-kit',
72
74
  'embla-carousel-react': '@octanejs/embla-carousel',
73
75
  'react-dropzone': '@octanejs/dropzone',
package/src/index.js CHANGED
@@ -79,6 +79,7 @@ export const BENCHMARK_SUITES = [
79
79
  'radix-collection-order',
80
80
  'router-dispatch',
81
81
  'visx-categorical-scale',
82
+ 'style-unitless',
82
83
  'rspack-css-graph',
83
84
  'floating-tree-navigation',
84
85
  'ink-cursor-update',
@@ -107,6 +108,8 @@ export const BENCHMARK_SUITES = [
107
108
  'universal-leaf-update',
108
109
  'universal-object-teardown',
109
110
  'universal-template-events',
111
+ 'universal-native-hover',
112
+ 'universal-owner-drafts',
110
113
  'universal-external-store',
111
114
  'lynx-render',
112
115
  'lynx-table',