@pyreon/mcp 0.11.4 → 0.11.6

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.
@@ -17,8 +17,8 @@ export const API_REFERENCE: Record<string, ApiEntry> = {
17
17
  // @pyreon/reactivity
18
18
  // ═══════════════════════════════════════════════════════════════════════════
19
19
 
20
- "reactivity/signal": {
21
- signature: "signal<T>(initialValue: T, options?: { name?: string }): Signal<T>",
20
+ 'reactivity/signal': {
21
+ signature: 'signal<T>(initialValue: T, options?: { name?: string }): Signal<T>',
22
22
  example: `const count = signal(0)
23
23
 
24
24
  // Read (subscribes to updates):
@@ -33,15 +33,15 @@ count.update(n => n + 1) // 6
33
33
  // Read without subscribing:
34
34
  count.peek() // 6`,
35
35
  notes:
36
- "Signals are callable functions, NOT .value getters. Components run once — signal reads in JSX auto-subscribe. Optional { name } for debugging — auto-injected by @pyreon/vite-plugin in dev mode.",
36
+ 'Signals are callable functions, NOT .value getters. Components run once — signal reads in JSX auto-subscribe. Optional { name } for debugging — auto-injected by @pyreon/vite-plugin in dev mode.',
37
37
  mistakes: `- \`count.value\` → Use \`count()\` to read
38
38
  - \`{count}\` in JSX → Use \`{count()}\` to read (or let the compiler wrap it)
39
39
  - \`const [val, setVal] = signal(0)\` → Not destructurable. Use \`const val = signal(0)\``,
40
40
  },
41
41
 
42
- "reactivity/computed": {
42
+ 'reactivity/computed': {
43
43
  signature:
44
- "computed<T>(fn: () => T, options?: { equals?: (a: T, b: T) => boolean }): Computed<T>",
44
+ 'computed<T>(fn: () => T, options?: { equals?: (a: T, b: T) => boolean }): Computed<T>',
45
45
  example: `const count = signal(0)
46
46
  const doubled = computed(() => count() * 2)
47
47
 
@@ -49,13 +49,13 @@ doubled() // 0
49
49
  count.set(5)
50
50
  doubled() // 10`,
51
51
  notes:
52
- "Dependencies auto-tracked. No dependency array needed. Memoized — only recomputes when dependencies change.",
52
+ 'Dependencies auto-tracked. No dependency array needed. Memoized — only recomputes when dependencies change.',
53
53
  mistakes: `- \`computed(() => count)\` → Must call signal: \`computed(() => count())\`
54
54
  - Don't use for side effects — use effect() instead`,
55
55
  },
56
56
 
57
- "reactivity/effect": {
58
- signature: "effect(fn: () => (() => void) | void): () => void",
57
+ 'reactivity/effect': {
58
+ signature: 'effect(fn: () => (() => void) | void): () => void',
59
59
  example: `const count = signal(0)
60
60
 
61
61
  // Auto-tracks count() dependency:
@@ -77,26 +77,26 @@ effect(() => {
77
77
  return () => window.removeEventListener("resize", handler)
78
78
  })`,
79
79
  notes:
80
- "Returns a dispose function. Dependencies auto-tracked on each run. Use onCleanup() inside to register cleanup that runs before re-execution. For DOM-specific effects, use renderEffect().",
80
+ 'Returns a dispose function. Dependencies auto-tracked on each run. Use onCleanup() inside to register cleanup that runs before re-execution. For DOM-specific effects, use renderEffect().',
81
81
  mistakes: `- Don't pass a dependency array — Pyreon auto-tracks
82
82
  - \`effect(() => { count })\` → Must call: \`effect(() => { count() })\``,
83
83
  },
84
84
 
85
- "reactivity/onCleanup": {
86
- signature: "onCleanup(fn: () => void): void",
85
+ 'reactivity/onCleanup': {
86
+ signature: 'onCleanup(fn: () => void): void',
87
87
  example: `effect(() => {
88
88
  const handler = () => console.log(count())
89
89
  window.addEventListener("resize", handler)
90
90
  onCleanup(() => window.removeEventListener("resize", handler))
91
91
  })`,
92
92
  notes:
93
- "Registers a cleanup function inside an effect. Runs between re-executions (before the effect re-runs) and when the effect is disposed.",
93
+ 'Registers a cleanup function inside an effect. Runs between re-executions (before the effect re-runs) and when the effect is disposed.',
94
94
  mistakes: `- Using onCleanup outside an effect — it only works inside effect() or renderEffect()
95
95
  - Confusing with onUnmount — onCleanup is for effects, onUnmount is for components`,
96
96
  },
97
97
 
98
- "reactivity/batch": {
99
- signature: "batch(fn: () => void): void",
98
+ 'reactivity/batch': {
99
+ signature: 'batch(fn: () => void): void',
100
100
  example: `const a = signal(1)
101
101
  const b = signal(2)
102
102
 
@@ -105,11 +105,11 @@ batch(() => {
105
105
  a.set(10)
106
106
  b.set(20)
107
107
  })`,
108
- notes: "Defers all signal notifications until the batch completes. Nested batches are merged.",
108
+ notes: 'Defers all signal notifications until the batch completes. Nested batches are merged.',
109
109
  },
110
110
 
111
- "reactivity/createStore": {
112
- signature: "createStore<T extends object>(initialValue: T): T",
111
+ 'reactivity/createStore': {
112
+ signature: 'createStore<T extends object>(initialValue: T): T',
113
113
  example: `const store = createStore({
114
114
  user: { name: "Alice", age: 30 },
115
115
  items: [1, 2, 3]
@@ -119,12 +119,12 @@ batch(() => {
119
119
  store.user.name = "Bob" // only name subscribers fire
120
120
  store.items.push(4) // only items subscribers fire`,
121
121
  notes:
122
- "Deep proxy — nested objects are automatically reactive. Use reconcile() for bulk updates.",
122
+ 'Deep proxy — nested objects are automatically reactive. Use reconcile() for bulk updates.',
123
123
  },
124
124
 
125
- "reactivity/createResource": {
125
+ 'reactivity/createResource': {
126
126
  signature:
127
- "createResource<T>(fetcher: () => Promise<T>, options?: ResourceOptions): Resource<T>",
127
+ 'createResource<T>(fetcher: () => Promise<T>, options?: ResourceOptions): Resource<T>',
128
128
  example: `const users = createResource(() => fetch("/api/users").then(r => r.json()))
129
129
 
130
130
  // In JSX:
@@ -134,11 +134,11 @@ store.items.push(4) // only items subscribers fire`,
134
134
  </For>
135
135
  </Show>`,
136
136
  notes:
137
- "Integrates with Suspense. Access .loading(), .error(), and call resource() for the value.",
137
+ 'Integrates with Suspense. Access .loading(), .error(), and call resource() for the value.',
138
138
  },
139
139
 
140
- "reactivity/untrack": {
141
- signature: "untrack<T>(fn: () => T): T",
140
+ 'reactivity/untrack': {
141
+ signature: 'untrack<T>(fn: () => T): T',
142
142
  example: `import { untrack } from "@pyreon/reactivity"
143
143
 
144
144
  // Read signals without subscribing:
@@ -147,26 +147,26 @@ effect(() => {
147
147
  console.log("Count changed:", count(), "user is", name)
148
148
  })`,
149
149
  notes:
150
- "Alias for runUntracked. Reads signals inside fn without adding them as dependencies of the current effect/computed.",
150
+ 'Alias for runUntracked. Reads signals inside fn without adding them as dependencies of the current effect/computed.',
151
151
  },
152
152
 
153
153
  // ═══════════════════════════════════════════════════════════════════════════
154
154
  // @pyreon/core
155
155
  // ═══════════════════════════════════════════════════════════════════════════
156
156
 
157
- "core/h": {
157
+ 'core/h': {
158
158
  signature:
159
- "h<P>(type: ComponentFn<P> | string | symbol, props: P | null, ...children: VNodeChild[]): VNode",
159
+ 'h<P>(type: ComponentFn<P> | string | symbol, props: P | null, ...children: VNodeChild[]): VNode',
160
160
  example: `// Usually use JSX instead:
161
161
  const vnode = h("div", { class: "container" },
162
162
  h("h1", null, "Hello"),
163
163
  h(Counter, { initial: 0 })
164
164
  )`,
165
- notes: "Low-level API. Prefer JSX which compiles to h() calls (or _tpl() for templates).",
165
+ notes: 'Low-level API. Prefer JSX which compiles to h() calls (or _tpl() for templates).',
166
166
  },
167
167
 
168
- "core/Fragment": {
169
- signature: "Fragment: symbol",
168
+ 'core/Fragment': {
169
+ signature: 'Fragment: symbol',
170
170
  example: `// JSX:
171
171
  <>
172
172
  <h1>Title</h1>
@@ -177,8 +177,8 @@ const vnode = h("div", { class: "container" },
177
177
  h(Fragment, null, h("h1", null, "Title"), h("p", null, "Content"))`,
178
178
  },
179
179
 
180
- "core/onMount": {
181
- signature: "onMount(fn: () => CleanupFn | void): void",
180
+ 'core/onMount': {
181
+ signature: 'onMount(fn: () => CleanupFn | void): void',
182
182
  example: `const Timer = () => {
183
183
  const count = signal(0)
184
184
 
@@ -189,19 +189,19 @@ h(Fragment, null, h("h1", null, "Title"), h("p", null, "Content"))`,
189
189
 
190
190
  return <div>{count()}</div>
191
191
  }`,
192
- notes: "Optionally return a cleanup function that runs on unmount.",
192
+ notes: 'Optionally return a cleanup function that runs on unmount.',
193
193
  mistakes: `- Forgetting cleanup: \`onMount(() => { const id = setInterval(...) })\` → Return cleanup: \`onMount(() => { const id = setInterval(...); return () => clearInterval(id) })\``,
194
194
  },
195
195
 
196
- "core/onUnmount": {
197
- signature: "onUnmount(fn: () => void): void",
196
+ 'core/onUnmount': {
197
+ signature: 'onUnmount(fn: () => void): void',
198
198
  example: `onUnmount(() => {
199
199
  console.log("Component removed from DOM")
200
200
  })`,
201
201
  },
202
202
 
203
- "core/createContext": {
204
- signature: "createContext<T>(defaultValue: T): Context<T>",
203
+ 'core/createContext': {
204
+ signature: 'createContext<T>(defaultValue: T): Context<T>',
205
205
  example: `const ThemeContext = createContext<"light" | "dark">("light")
206
206
 
207
207
  // Provide:
@@ -217,13 +217,13 @@ const Child = () => {
217
217
  }`,
218
218
  },
219
219
 
220
- "core/useContext": {
221
- signature: "useContext<T>(ctx: Context<T>): T",
220
+ 'core/useContext': {
221
+ signature: 'useContext<T>(ctx: Context<T>): T',
222
222
  example: `const theme = useContext(ThemeContext) // returns provided value or default`,
223
223
  },
224
224
 
225
- "core/provide": {
226
- signature: "provide<T>(ctx: Context<T>, value: T): void",
225
+ 'core/provide': {
226
+ signature: 'provide<T>(ctx: Context<T>, value: T): void',
227
227
  example: `const ThemeCtx = createContext<"light" | "dark">("light")
228
228
 
229
229
  function App() {
@@ -231,21 +231,21 @@ function App() {
231
231
  return <Child />
232
232
  }`,
233
233
  notes:
234
- "Pushes a context value and auto-cleans up on unmount. Preferred over manual pushContext/popContext. Must be called during component setup.",
234
+ 'Pushes a context value and auto-cleans up on unmount. Preferred over manual pushContext/popContext. Must be called during component setup.',
235
235
  },
236
236
 
237
- "core/ExtractProps": {
238
- signature: "type ExtractProps<T> = T extends ComponentFn<infer P> ? P : T",
237
+ 'core/ExtractProps': {
238
+ signature: 'type ExtractProps<T> = T extends ComponentFn<infer P> ? P : T',
239
239
  example: `const Greet: ComponentFn<{ name: string }> = ({ name }) => <h1>{name}</h1>
240
240
 
241
241
  type Props = ExtractProps<typeof Greet>
242
242
  // { name: string }`,
243
243
  notes:
244
- "Extracts the props type from a ComponentFn. Passes through unchanged if T is not a ComponentFn.",
244
+ 'Extracts the props type from a ComponentFn. Passes through unchanged if T is not a ComponentFn.',
245
245
  },
246
246
 
247
- "core/HigherOrderComponent": {
248
- signature: "type HigherOrderComponent<HOP, P> = ComponentFn<HOP & P>",
247
+ 'core/HigherOrderComponent': {
248
+ signature: 'type HigherOrderComponent<HOP, P> = ComponentFn<HOP & P>',
249
249
  example: `function withLogger<P>(Wrapped: ComponentFn<P>): HigherOrderComponent<{ logLevel?: string }, P> {
250
250
  return (props) => {
251
251
  console.log(\`[\${props.logLevel ?? "info"}] Rendering\`)
@@ -256,8 +256,8 @@ type Props = ExtractProps<typeof Greet>
256
256
  "Typed HOC pattern — HOP is the props the HOC adds, P is the wrapped component's own props.",
257
257
  },
258
258
 
259
- "core/For": {
260
- signature: "<For each={items} by={keyFn}>{renderFn}</For>",
259
+ 'core/For': {
260
+ signature: '<For each={items} by={keyFn}>{renderFn}</For>',
261
261
  example: `const items = signal([
262
262
  { id: 1, name: "Apple" },
263
263
  { id: 2, name: "Banana" },
@@ -272,17 +272,17 @@ type Props = ExtractProps<typeof Greet>
272
272
  - \`{items().map(...)}\` → Use <For> for reactive list rendering`,
273
273
  },
274
274
 
275
- "core/Show": {
276
- signature: "<Show when={condition} fallback={alternative}>{children}</Show>",
275
+ 'core/Show': {
276
+ signature: '<Show when={condition} fallback={alternative}>{children}</Show>',
277
277
  example: `<Show when={isLoggedIn()} fallback={<LoginForm />}>
278
278
  <Dashboard />
279
279
  </Show>`,
280
280
  notes:
281
- "More efficient than ternary for signal-driven conditions. Only mounts/unmounts when condition changes.",
281
+ 'More efficient than ternary for signal-driven conditions. Only mounts/unmounts when condition changes.',
282
282
  },
283
283
 
284
- "core/Suspense": {
285
- signature: "<Suspense fallback={loadingUI}>{children}</Suspense>",
284
+ 'core/Suspense': {
285
+ signature: '<Suspense fallback={loadingUI}>{children}</Suspense>',
286
286
  example: `const LazyPage = lazy(() => import("./HeavyPage"))
287
287
 
288
288
  <Suspense fallback={<div>Loading...</div>}>
@@ -290,9 +290,9 @@ type Props = ExtractProps<typeof Greet>
290
290
  </Suspense>`,
291
291
  },
292
292
 
293
- "core/lazy": {
293
+ 'core/lazy': {
294
294
  signature:
295
- "lazy(loader: () => Promise<{ default: ComponentFn }>, options?: LazyOptions): LazyComponent",
295
+ 'lazy(loader: () => Promise<{ default: ComponentFn }>, options?: LazyOptions): LazyComponent',
296
296
  example: `const Settings = lazy(() => import("./pages/Settings"))
297
297
 
298
298
  // Use in JSX (wrap with Suspense):
@@ -301,16 +301,16 @@ type Props = ExtractProps<typeof Greet>
301
301
  </Suspense>`,
302
302
  },
303
303
 
304
- "core/Dynamic": {
305
- signature: "<Dynamic component={comp} {...props} />",
304
+ 'core/Dynamic': {
305
+ signature: '<Dynamic component={comp} {...props} />',
306
306
  example: `const components = { home: HomePage, about: AboutPage }
307
307
  const current = signal("home")
308
308
 
309
309
  <Dynamic component={components[current()]} />`,
310
310
  },
311
311
 
312
- "core/ErrorBoundary": {
313
- signature: "<ErrorBoundary onCatch={handler} fallback={errorUI}>{children}</ErrorBoundary>",
312
+ 'core/ErrorBoundary': {
313
+ signature: '<ErrorBoundary onCatch={handler} fallback={errorUI}>{children}</ErrorBoundary>',
314
314
  example: `<ErrorBoundary
315
315
  onCatch={(err) => console.error(err)}
316
316
  fallback={(err) => <div>Error: {err.message}</div>}
@@ -319,8 +319,8 @@ const current = signal("home")
319
319
  </ErrorBoundary>`,
320
320
  },
321
321
 
322
- "core/cx": {
323
- signature: "cx(...values: ClassValue[]): string",
322
+ 'core/cx': {
323
+ signature: 'cx(...values: ClassValue[]): string',
324
324
  example: `import { cx } from "@pyreon/core"
325
325
 
326
326
  cx("foo", "bar") // "foo bar"
@@ -332,13 +332,13 @@ cx(["a", ["b", { c: true }]]) // nested arrays
332
332
  <div class={["base", cond && "active"]} />
333
333
  <div class={{ base: true, active: isActive() }} />`,
334
334
  notes:
335
- "Combines class values into a single string. Accepts strings, booleans, objects, arrays (nested). Falsy values are ignored. ClassValue type is also exported from @pyreon/core.",
335
+ 'Combines class values into a single string. Accepts strings, booleans, objects, arrays (nested). Falsy values are ignored. ClassValue type is also exported from @pyreon/core.',
336
336
  mistakes: `- \`class={cx(...)}\` works but is redundant — class prop already accepts ClassValue
337
337
  - \`class={condition ? "a" : undefined}\` → Use \`class={[condition && "a"]}\` or \`class={{ a: condition }}\``,
338
338
  },
339
339
 
340
- "core/splitProps": {
341
- signature: "splitProps<T, K extends keyof T>(props: T, keys: K[]): [Pick<T, K>, Omit<T, K>]",
340
+ 'core/splitProps': {
341
+ signature: 'splitProps<T, K extends keyof T>(props: T, keys: K[]): [Pick<T, K>, Omit<T, K>]',
342
342
  example: `import { splitProps } from "@pyreon/core"
343
343
 
344
344
  const Button = (props: { class?: string; onClick: () => void; children: VNodeChild }) => {
@@ -346,13 +346,13 @@ const Button = (props: { class?: string; onClick: () => void; children: VNodeChi
346
346
  return <button {...rest} class={cx("btn", local.class)} />
347
347
  }`,
348
348
  notes:
349
- "Splits a props object into two: picked keys and the rest. Preserves signal reactivity on both halves.",
349
+ 'Splits a props object into two: picked keys and the rest. Preserves signal reactivity on both halves.',
350
350
  mistakes: `- Destructuring props directly breaks reactivity — use splitProps instead
351
351
  - \`const { class: cls, ...rest } = props\` → \`const [local, rest] = splitProps(props, ["class"])\``,
352
352
  },
353
353
 
354
- "core/mergeProps": {
355
- signature: "mergeProps<T extends object[]>(...sources: T): MergedProps<T>",
354
+ 'core/mergeProps': {
355
+ signature: 'mergeProps<T extends object[]>(...sources: T): MergedProps<T>',
356
356
  example: `import { mergeProps } from "@pyreon/core"
357
357
 
358
358
  const Button = (props: { size?: string; variant?: string }) => {
@@ -360,11 +360,11 @@ const Button = (props: { size?: string; variant?: string }) => {
360
360
  return <button class={\`btn-\${merged.size} btn-\${merged.variant}\`} />
361
361
  }`,
362
362
  notes:
363
- "Merges multiple props objects. Last source wins for each key. Preserves reactivity — reads are lazy.",
363
+ 'Merges multiple props objects. Last source wins for each key. Preserves reactivity — reads are lazy.',
364
364
  },
365
365
 
366
- "core/createUniqueId": {
367
- signature: "createUniqueId(): string",
366
+ 'core/createUniqueId': {
367
+ signature: 'createUniqueId(): string',
368
368
  example: `import { createUniqueId } from "@pyreon/core"
369
369
 
370
370
  const LabeledInput = (props: { label: string }) => {
@@ -384,8 +384,8 @@ const LabeledInput = (props: { label: string }) => {
384
384
  // @pyreon/router
385
385
  // ═══════════════════════════════════════════════════════════════════════════
386
386
 
387
- "router/createRouter": {
388
- signature: "createRouter(options: RouterOptions | RouteRecord[]): Router",
387
+ 'router/createRouter': {
388
+ signature: 'createRouter(options: RouterOptions | RouteRecord[]): Router',
389
389
  example: `const router = createRouter([
390
390
  { path: "/", component: Home },
391
391
  { path: "/user/:id", component: User, loader: ({ params }) => fetchUser(params.id) },
@@ -395,8 +395,8 @@ const LabeledInput = (props: { label: string }) => {
395
395
  ])`,
396
396
  },
397
397
 
398
- "router/RouterProvider": {
399
- signature: "<RouterProvider router={router}>{children}</RouterProvider>",
398
+ 'router/RouterProvider': {
399
+ signature: '<RouterProvider router={router}>{children}</RouterProvider>',
400
400
  example: `const App = () => (
401
401
  <RouterProvider router={router}>
402
402
  <nav><RouterLink to="/">Home</RouterLink></nav>
@@ -405,8 +405,8 @@ const LabeledInput = (props: { label: string }) => {
405
405
  )`,
406
406
  },
407
407
 
408
- "router/RouterView": {
409
- signature: "<RouterView />",
408
+ 'router/RouterView': {
409
+ signature: '<RouterView />',
410
410
  example: `// Renders the matched route's component
411
411
  <RouterView />
412
412
 
@@ -419,14 +419,14 @@ const Admin = () => (
419
419
  )`,
420
420
  },
421
421
 
422
- "router/RouterLink": {
423
- signature: "<RouterLink to={path} activeClass={cls} exactActiveClass={cls} />",
422
+ 'router/RouterLink': {
423
+ signature: '<RouterLink to={path} activeClass={cls} exactActiveClass={cls} />',
424
424
  example: `<RouterLink to="/" activeClass="nav-active">Home</RouterLink>
425
425
  <RouterLink to={{ name: "user", params: { id: "42" } }}>Profile</RouterLink>`,
426
426
  },
427
427
 
428
- "router/useRouter": {
429
- signature: "useRouter(): Router",
428
+ 'router/useRouter': {
429
+ signature: 'useRouter(): Router',
430
430
  example: `const router = useRouter()
431
431
 
432
432
  router.push("/settings")
@@ -437,8 +437,8 @@ router.forward()
437
437
  router.go(-2)`,
438
438
  },
439
439
 
440
- "router/useRoute": {
441
- signature: "useRoute<TPath extends string>(): () => ResolvedRoute<ExtractParams<TPath>>",
440
+ 'router/useRoute': {
441
+ signature: 'useRoute<TPath extends string>(): () => ResolvedRoute<ExtractParams<TPath>>',
442
442
  example: `// Type-safe params:
443
443
  const route = useRoute<"/user/:id">()
444
444
  const userId = route().params.id // string
@@ -448,9 +448,9 @@ route().query
448
448
  route().meta`,
449
449
  },
450
450
 
451
- "router/useSearchParams": {
451
+ 'router/useSearchParams': {
452
452
  signature:
453
- "useSearchParams<T>(defaults?: T): [get: () => T, set: (updates: Partial<T>) => Promise<void>]",
453
+ 'useSearchParams<T>(defaults?: T): [get: () => T, set: (updates: Partial<T>) => Promise<void>]',
454
454
  example: `const [search, setSearch] = useSearchParams({ page: "1", sort: "name" })
455
455
 
456
456
  // Read:
@@ -460,8 +460,8 @@ search().page // "1"
460
460
  setSearch({ page: "2" })`,
461
461
  },
462
462
 
463
- "router/useLoaderData": {
464
- signature: "useLoaderData<T>(): T",
463
+ 'router/useLoaderData': {
464
+ signature: 'useLoaderData<T>(): T',
465
465
  example: `// Route: { path: "/user/:id", component: User, loader: ({ params }) => fetchUser(params.id) }
466
466
 
467
467
  const User = () => {
@@ -474,8 +474,8 @@ const User = () => {
474
474
  // @pyreon/head
475
475
  // ═══════════════════════════════════════════════════════════════════════════
476
476
 
477
- "head/useHead": {
478
- signature: "useHead(input: UseHeadInput | (() => UseHeadInput)): void",
477
+ 'head/useHead': {
478
+ signature: 'useHead(input: UseHeadInput | (() => UseHeadInput)): void',
479
479
  example: `// Static:
480
480
  useHead({ title: "My Page", meta: [{ name: "description", content: "..." }] })
481
481
 
@@ -486,8 +486,8 @@ useHead(() => ({
486
486
  }))`,
487
487
  },
488
488
 
489
- "head/HeadProvider": {
490
- signature: "<HeadProvider>{children}</HeadProvider>",
489
+ 'head/HeadProvider': {
490
+ signature: '<HeadProvider>{children}</HeadProvider>',
491
491
  example: `// Client-side setup:
492
492
  mount(
493
493
  <HeadProvider>
@@ -501,8 +501,8 @@ mount(
501
501
  // @pyreon/server
502
502
  // ═══════════════════════════════════════════════════════════════════════════
503
503
 
504
- "server/createHandler": {
505
- signature: "createHandler(options: HandlerOptions): (req: Request) => Promise<Response>",
504
+ 'server/createHandler': {
505
+ signature: 'createHandler(options: HandlerOptions): (req: Request) => Promise<Response>',
506
506
  example: `import { createHandler } from "@pyreon/server"
507
507
 
508
508
  export default createHandler({
@@ -513,9 +513,9 @@ export default createHandler({
513
513
  })`,
514
514
  },
515
515
 
516
- "server/island": {
516
+ 'server/island': {
517
517
  signature:
518
- "island(loader: () => Promise<ComponentFn>, options: { name: string; hydrate?: HydrationStrategy }): ComponentFn",
518
+ 'island(loader: () => Promise<ComponentFn>, options: { name: string; hydrate?: HydrationStrategy }): ComponentFn',
519
519
  example: `const SearchBar = island(
520
520
  () => import("./SearchBar"),
521
521
  { name: "SearchBar", hydrate: "visible" }
@@ -524,8 +524,8 @@ export default createHandler({
524
524
  // Hydration strategies: "load" | "idle" | "visible" | "media" | "never"`,
525
525
  },
526
526
 
527
- "server/prerender": {
528
- signature: "prerender(options: PrerenderOptions): Promise<PrerenderResult>",
527
+ 'server/prerender': {
528
+ signature: 'prerender(options: PrerenderOptions): Promise<PrerenderResult>',
529
529
  example: `await prerender({
530
530
  handler,
531
531
  paths: ["/", "/about", "/blog/1", "/blog/2"],
@@ -537,8 +537,8 @@ export default createHandler({
537
537
  // @pyreon/runtime-dom
538
538
  // ═══════════════════════════════════════════════════════════════════════════
539
539
 
540
- "runtime-dom/mount": {
541
- signature: "mount(root: VNodeChild, container: Element): () => void",
540
+ 'runtime-dom/mount': {
541
+ signature: 'mount(root: VNodeChild, container: Element): () => void',
542
542
  example: `import { mount } from "@pyreon/runtime-dom"
543
543
 
544
544
  const dispose = mount(<App />, document.getElementById("app")!)
@@ -549,16 +549,16 @@ dispose()`,
549
549
  - Container must not be null/undefined`,
550
550
  },
551
551
 
552
- "runtime-dom/hydrateRoot": {
553
- signature: "hydrateRoot(root: VNodeChild, container: Element): () => void",
552
+ 'runtime-dom/hydrateRoot': {
553
+ signature: 'hydrateRoot(root: VNodeChild, container: Element): () => void',
554
554
  example: `import { hydrateRoot } from "@pyreon/runtime-dom"
555
555
 
556
556
  // Hydrate server-rendered HTML:
557
557
  hydrateRoot(<App />, document.getElementById("app")!)`,
558
558
  },
559
559
 
560
- "runtime-dom/Transition": {
561
- signature: "<Transition name={name} mode={mode}>{children}</Transition>",
560
+ 'runtime-dom/Transition': {
561
+ signature: '<Transition name={name} mode={mode}>{children}</Transition>',
562
562
  example: `<Transition name="fade" mode="out-in">
563
563
  <Show when={visible()}>
564
564
  <div>Content</div>
@@ -575,8 +575,8 @@ hydrateRoot(<App />, document.getElementById("app")!)`,
575
575
  // @pyreon/store
576
576
  // ═══════════════════════════════════════════════════════════════════════════
577
577
 
578
- "store/defineStore": {
579
- signature: "defineStore<T>(id: string, setup: () => T): () => StoreApi<T>",
578
+ 'store/defineStore': {
579
+ signature: 'defineStore<T>(id: string, setup: () => T): () => StoreApi<T>',
580
580
  example: `const useCounter = defineStore('counter', () => {
581
581
  const count = signal(0)
582
582
  const increment = () => count.update(n => n + 1)
@@ -587,16 +587,16 @@ const { store } = useCounter()
587
587
  store.count() // 0
588
588
  store.increment() // reactive update`,
589
589
  notes:
590
- "Composition-style stores. Singleton by ID. Returns StoreApi with .store, .patch(), .subscribe(), .onAction(), .reset(), .dispose().",
590
+ 'Composition-style stores. Singleton by ID. Returns StoreApi with .store, .patch(), .subscribe(), .onAction(), .reset(), .dispose().',
591
591
  },
592
592
 
593
593
  // ═══════════════════════════════════════════════════════════════════════════
594
594
  // @pyreon/form
595
595
  // ═══════════════════════════════════════════════════════════════════════════
596
596
 
597
- "form/useForm": {
597
+ 'form/useForm': {
598
598
  signature:
599
- "useForm<T>(options: { initialValues: T, onSubmit: (values: T) => void | Promise<void>, schema?, validateOn?, debounceMs? }): FormInstance<T>",
599
+ 'useForm<T>(options: { initialValues: T, onSubmit: (values: T) => void | Promise<void>, schema?, validateOn?, debounceMs? }): FormInstance<T>',
600
600
  example: `const form = useForm({
601
601
  initialValues: { name: '', email: '' },
602
602
  onSubmit: async (values) => await api.save(values),
@@ -606,11 +606,11 @@ store.increment() // reactive update`,
606
606
  form.handleSubmit() // triggers validation + onSubmit
607
607
  form.reset() // reset to initial values`,
608
608
  notes:
609
- "Signal-based form state. Use useField() for individual field binding, useFieldArray() for dynamic arrays.",
609
+ 'Signal-based form state. Use useField() for individual field binding, useFieldArray() for dynamic arrays.',
610
610
  },
611
611
 
612
- "form/useField": {
613
- signature: "useField<T>(form: FormInstance<T>, name: keyof T): FieldInstance",
612
+ 'form/useField': {
613
+ signature: 'useField<T>(form: FormInstance<T>, name: keyof T): FieldInstance',
614
614
  example: `const name = useField(form, 'name')
615
615
 
616
616
  <input {...name.register()} />
@@ -621,23 +621,23 @@ form.reset() // reset to initial values`,
621
621
  // @pyreon/query
622
622
  // ═══════════════════════════════════════════════════════════════════════════
623
623
 
624
- "query/useQuery": {
624
+ 'query/useQuery': {
625
625
  signature:
626
- "useQuery<T>(options: { queryKey: unknown[], queryFn: () => Promise<T>, ... }): { data: Signal<T>, error: Signal<Error>, isFetching: Signal<boolean>, ... }",
626
+ 'useQuery<T>(options: { queryKey: unknown[], queryFn: () => Promise<T>, ... }): { data: Signal<T>, error: Signal<Error>, isFetching: Signal<boolean>, ... }',
627
627
  example: `const { data, error, isFetching } = useQuery({
628
628
  queryKey: ['users'],
629
629
  queryFn: () => fetch('/api/users').then(r => r.json()),
630
630
  })`,
631
631
  notes:
632
- "TanStack Query adapter. Fine-grained signals per field. Reactive options via function getter. Also: useMutation, useInfiniteQuery, useSuspenseQuery, useSubscription (WebSocket).",
632
+ 'TanStack Query adapter. Fine-grained signals per field. Reactive options via function getter. Also: useMutation, useInfiniteQuery, useSuspenseQuery, useSubscription (WebSocket).',
633
633
  },
634
634
 
635
635
  // ═══════════════════════════════════════════════════════════════════════════
636
636
  // @pyreon/permissions
637
637
  // ═══════════════════════════════════════════════════════════════════════════
638
638
 
639
- "permissions/createPermissions": {
640
- signature: "createPermissions<T extends PermissionMap>(initial?: T): PermissionsInstance",
639
+ 'permissions/createPermissions': {
640
+ signature: 'createPermissions<T extends PermissionMap>(initial?: T): PermissionsInstance',
641
641
  example: `const can = createPermissions({
642
642
  'posts.read': true,
643
643
  'posts.delete': (post) => post.authorId === userId,
@@ -657,8 +657,8 @@ can.any('admin.users', 'posts.read')`,
657
657
  // @pyreon/machine
658
658
  // ═══════════════════════════════════════════════════════════════════════════
659
659
 
660
- "machine/createMachine": {
661
- signature: "createMachine<S, E>(config: MachineConfig<S, E>): Machine<S, E>",
660
+ 'machine/createMachine': {
661
+ signature: 'createMachine<S, E>(config: MachineConfig<S, E>): Machine<S, E>',
662
662
  example: `const traffic = createMachine({
663
663
  initial: 'red',
664
664
  states: {
@@ -673,31 +673,31 @@ traffic.send('NEXT') // 'green'
673
673
  traffic.matches('green') // true
674
674
  traffic.can('NEXT') // true`,
675
675
  notes:
676
- "Constrained signal with type-safe transitions. Guards: { target, guard: (payload?) => boolean }. No context — use signals alongside.",
676
+ 'Constrained signal with type-safe transitions. Guards: { target, guard: (payload?) => boolean }. No context — use signals alongside.',
677
677
  },
678
678
 
679
679
  // ═══════════════════════════════════════════════════════════════════════════
680
680
  // @pyreon/storage
681
681
  // ═══════════════════════════════════════════════════════════════════════════
682
682
 
683
- "storage/useStorage": {
683
+ 'storage/useStorage': {
684
684
  signature:
685
- "useStorage<T>(key: string, defaultValue: T, options?: StorageOptions<T>): StorageSignal<T>",
685
+ 'useStorage<T>(key: string, defaultValue: T, options?: StorageOptions<T>): StorageSignal<T>',
686
686
  example: `const theme = useStorage('theme', 'light')
687
687
  theme() // 'light'
688
688
  theme.set('dark') // persists + cross-tab sync
689
689
  theme.remove() // delete from storage`,
690
690
  notes:
691
- "localStorage by default. Also: useSessionStorage, useCookie, useIndexedDB, useMemoryStorage, createStorage(backend). All return StorageSignal<T> extending Signal<T> with .remove().",
691
+ 'localStorage by default. Also: useSessionStorage, useCookie, useIndexedDB, useMemoryStorage, createStorage(backend). All return StorageSignal<T> extending Signal<T> with .remove().',
692
692
  },
693
693
 
694
694
  // ═══════════════════════════════════════════════════════════════════════════
695
695
  // @pyreon/i18n
696
696
  // ═══════════════════════════════════════════════════════════════════════════
697
697
 
698
- "i18n/createI18n": {
698
+ 'i18n/createI18n': {
699
699
  signature:
700
- "createI18n(options: { locale: string, messages: Record<string, Record<string, string>>, loader?, fallbackLocale?, pluralRules? }): I18nInstance",
700
+ 'createI18n(options: { locale: string, messages: Record<string, Record<string, string>>, loader?, fallbackLocale?, pluralRules? }): I18nInstance',
701
701
  example: `const i18n = createI18n({
702
702
  locale: 'en',
703
703
  messages: { en: { greeting: 'Hello, {{name}}!' } },
@@ -708,15 +708,15 @@ const { t, locale } = useI18n()
708
708
  t('greeting', { name: 'World' }) // "Hello, World!"
709
709
  locale.set('fr') // switch reactively`,
710
710
  notes:
711
- "Interpolation with {{name}}, pluralization with _one/_other suffixes. Namespace lazy loading. <Trans> component for rich JSX interpolation.",
711
+ 'Interpolation with {{name}}, pluralization with _one/_other suffixes. Namespace lazy loading. <Trans> component for rich JSX interpolation.',
712
712
  },
713
713
 
714
714
  // ═══════════════════════════════════════════════════════════════════════════
715
715
  // @pyreon/document
716
716
  // ═══════════════════════════════════════════════════════════════════════════
717
717
 
718
- "document/createDocument": {
719
- signature: "createDocument(props?: DocumentProps): DocumentBuilder",
718
+ 'document/createDocument': {
719
+ signature: 'createDocument(props?: DocumentProps): DocumentBuilder',
720
720
  example: `const doc = createDocument({ title: 'Report' })
721
721
  .heading('Sales Report')
722
722
  .table({ columns: ['Region', 'Revenue'], rows: [['US', '$1M']] })
@@ -727,15 +727,15 @@ await doc.toDocx() // Word document
727
727
  await doc.toSlack() // Slack Block Kit JSON
728
728
  await doc.toNotion() // Notion blocks`,
729
729
  notes:
730
- "14+ output formats. JSX primitives: Document, Page, Heading, Text, Table, Image, List, Code, etc. Heavy renderers lazy-loaded.",
730
+ '14+ output formats. JSX primitives: Document, Page, Heading, Text, Table, Image, List, Code, etc. Heavy renderers lazy-loaded.',
731
731
  },
732
732
 
733
733
  // ═══════════════════════════════════════════════════════════════════════════
734
734
  // @pyreon/flow
735
735
  // ═══════════════════════════════════════════════════════════════════════════
736
736
 
737
- "flow/createFlow": {
738
- signature: "createFlow(config: { nodes: FlowNode[], edges: FlowEdge[], ... }): FlowInstance",
737
+ 'flow/createFlow': {
738
+ signature: 'createFlow(config: { nodes: FlowNode[], edges: FlowEdge[], ... }): FlowInstance',
739
739
  example: `const flow = createFlow({
740
740
  nodes: [
741
741
  { id: '1', position: { x: 0, y: 0 }, data: { label: 'Start' } },
@@ -749,16 +749,16 @@ await flow.layout('layered') // auto-layout via elkjs
749
749
 
750
750
  <Flow instance={flow}><Background /><Controls /><MiniMap /></Flow>`,
751
751
  notes:
752
- "Signal-native nodes/edges. Auto-layout via elkjs (lazy-loaded). Pan/zoom via pointer events + CSS transforms. No D3.",
752
+ 'Signal-native nodes/edges. Auto-layout via elkjs (lazy-loaded). Pan/zoom via pointer events + CSS transforms. No D3.',
753
753
  },
754
754
 
755
755
  // ═══════════════════════════════════════════════════════════════════════════
756
756
  // @pyreon/code
757
757
  // ═══════════════════════════════════════════════════════════════════════════
758
758
 
759
- "code/createEditor": {
759
+ 'code/createEditor': {
760
760
  signature:
761
- "createEditor(config: { value?: string, language?: string, theme?: string, minimap?: boolean, ... }): EditorInstance",
761
+ 'createEditor(config: { value?: string, language?: string, theme?: string, minimap?: boolean, ... }): EditorInstance',
762
762
  example: `const editor = createEditor({
763
763
  value: '// hello',
764
764
  language: 'typescript',
@@ -780,9 +780,9 @@ editor.insert('new code')
780
780
  // @pyreon/hotkeys
781
781
  // ═══════════════════════════════════════════════════════════════════════════
782
782
 
783
- "hotkeys/useHotkey": {
783
+ 'hotkeys/useHotkey': {
784
784
  signature:
785
- "useHotkey(shortcut: string, handler: (e: KeyboardEvent) => void, options?: HotkeyOptions): void",
785
+ 'useHotkey(shortcut: string, handler: (e: KeyboardEvent) => void, options?: HotkeyOptions): void',
786
786
  example: `useHotkey('mod+s', (e) => {
787
787
  e.preventDefault()
788
788
  save()
@@ -798,8 +798,8 @@ useHotkeyScope('editor') // activate scope for component lifetime`,
798
798
  // @pyreon/table
799
799
  // ═══════════════════════════════════════════════════════════════════════════
800
800
 
801
- "table/useTable": {
802
- signature: "useTable<T>(options: TableOptions<T>): Table<T>",
801
+ 'table/useTable': {
802
+ signature: 'useTable<T>(options: TableOptions<T>): Table<T>',
803
803
  example: `const table = useTable({
804
804
  data: () => users(),
805
805
  columns: [
@@ -810,31 +810,31 @@ useHotkeyScope('editor') // activate scope for component lifetime`,
810
810
 
811
811
  // flexRender for column templates:
812
812
  flexRender(cell.column.columnDef.cell, cell.getContext())`,
813
- notes: "TanStack Table adapter with reactive options and auto state sync.",
813
+ notes: 'TanStack Table adapter with reactive options and auto state sync.',
814
814
  },
815
815
 
816
816
  // ═══════════════════════════════════════════════════════════════════════════
817
817
  // @pyreon/virtual
818
818
  // ═══════════════════════════════════════════════════════════════════════════
819
819
 
820
- "virtual/useVirtualizer": {
820
+ 'virtual/useVirtualizer': {
821
821
  signature:
822
- "useVirtualizer(options: VirtualizerOptions): { virtualItems: Signal, totalSize: Signal, scrollToIndex: (i) => void, ... }",
822
+ 'useVirtualizer(options: VirtualizerOptions): { virtualItems: Signal, totalSize: Signal, scrollToIndex: (i) => void, ... }',
823
823
  example: `const { virtualItems, totalSize } = useVirtualizer({
824
824
  count: 10000,
825
825
  getScrollElement: () => scrollRef.current,
826
826
  estimateSize: () => 35,
827
827
  })`,
828
- notes: "TanStack Virtual adapter. Also: useWindowVirtualizer for window-scoped virtualization.",
828
+ notes: 'TanStack Virtual adapter. Also: useWindowVirtualizer for window-scoped virtualization.',
829
829
  },
830
830
 
831
831
  // ═══════════════════════════════════════════════════════════════════════════
832
832
  // @pyreon/feature
833
833
  // ═══════════════════════════════════════════════════════════════════════════
834
834
 
835
- "feature/defineFeature": {
835
+ 'feature/defineFeature': {
836
836
  signature:
837
- "defineFeature<T>(config: { name: string, schema: FeatureSchema<T>, api: FeatureApi<T> }): Feature<T>",
837
+ 'defineFeature<T>(config: { name: string, schema: FeatureSchema<T>, api: FeatureApi<T> }): Feature<T>',
838
838
  example: `const Posts = defineFeature({
839
839
  name: 'posts',
840
840
  schema: { title: 'string', body: 'string', author: reference('users') },
@@ -848,7 +848,7 @@ Posts.useCreate() // mutation
848
848
  Posts.useForm(id) // edit form with validation
849
849
  Posts.useTable() // TanStack Table config`,
850
850
  notes:
851
- "Schema-driven CRUD. Composes @pyreon/query, @pyreon/form, @pyreon/validation, @pyreon/store, @pyreon/table.",
851
+ 'Schema-driven CRUD. Composes @pyreon/query, @pyreon/form, @pyreon/validation, @pyreon/store, @pyreon/table.',
852
852
  },
853
853
 
854
854
  // ═══════════════════════════════════════════════════════════════════════════
@@ -859,8 +859,8 @@ Posts.useTable() // TanStack Table config`,
859
859
  // @pyreon/lint
860
860
  // ═══════════════════════════════════════════════════════════════════════════
861
861
 
862
- "lint/lint": {
863
- signature: "lint(options?: LintOptions): LintResult",
862
+ 'lint/lint': {
863
+ signature: 'lint(options?: LintOptions): LintResult',
864
864
  example: `import { lint } from "@pyreon/lint"
865
865
 
866
866
  const result = lint({ paths: ["src/"], preset: "recommended" })
@@ -869,23 +869,23 @@ console.log(result.totalErrors, result.totalWarnings)
869
869
  // With config file auto-loading + rule overrides
870
870
  lint({ paths: ["."], ruleOverrides: { "pyreon/no-classname": "off" } })`,
871
871
  notes:
872
- "Programmatic API. 55 rules across 12 categories. Auto-loads .pyreonlintrc.json. Presets: recommended, strict, app, lib. Uses oxc-parser with AST caching.",
872
+ 'Programmatic API. 55 rules across 12 categories. Auto-loads .pyreonlintrc.json. Presets: recommended, strict, app, lib. Uses oxc-parser with AST caching.',
873
873
  },
874
874
 
875
- "lint/lintFile": {
875
+ 'lint/lintFile': {
876
876
  signature:
877
- "lintFile(filePath: string, sourceText: string, rules: Rule[], config: LintConfig, cache?: AstCache): LintFileResult",
877
+ 'lintFile(filePath: string, sourceText: string, rules: Rule[], config: LintConfig, cache?: AstCache): LintFileResult',
878
878
  example: `import { lintFile, allRules, getPreset, AstCache } from "@pyreon/lint"
879
879
 
880
880
  const cache = new AstCache()
881
881
  const config = getPreset("recommended")
882
882
  const result = lintFile("app.tsx", source, allRules, config, cache)`,
883
- notes: "Low-level single-file API. Optional AstCache for repeat runs (FNV-1a hash keyed).",
883
+ notes: 'Low-level single-file API. Optional AstCache for repeat runs (FNV-1a hash keyed).',
884
884
  },
885
885
 
886
- "lint/cli": {
886
+ 'lint/cli': {
887
887
  signature:
888
- "pyreon-lint [--preset name] [--fix] [--format text|json|compact] [--quiet] [--watch] [--list] [--config path] [--ignore path] [--rule id=severity] [path...]",
888
+ 'pyreon-lint [--preset name] [--fix] [--format text|json|compact] [--quiet] [--watch] [--list] [--config path] [--ignore path] [--rule id=severity] [path...]',
889
889
  example: `pyreon-lint --preset strict --quiet # CI mode
890
890
  pyreon-lint --fix # auto-fix
891
891
  pyreon-lint --watch src/ # watch mode
@@ -899,7 +899,7 @@ pyreon-lint --format json # machine-readable`,
899
899
  // @pyreon/ui-core
900
900
  // ═══════════════════════════════════════════════════════════════════════════
901
901
 
902
- "ui-core/PyreonUI": {
902
+ 'ui-core/PyreonUI': {
903
903
  signature:
904
904
  "PyreonUI(props: { theme?: Theme; mode?: 'light' | 'dark' | 'system'; inversed?: boolean; children: VNodeChild }): VNodeChild",
905
905
  example: `import { PyreonUI } from "@pyreon/ui-core"
@@ -919,7 +919,7 @@ const theme = enrichTheme({ colors: { primary: "#3b82f6" } })
919
919
  - Forgetting enrichTheme() → raw theme objects miss default breakpoints/spacing`,
920
920
  },
921
921
 
922
- "ui-core/useMode": {
922
+ 'ui-core/useMode': {
923
923
  signature: "useMode(): Signal<'light' | 'dark'>",
924
924
  example: `import { useMode } from "@pyreon/ui-core"
925
925
 
@@ -934,8 +934,8 @@ const mode = useMode()
934
934
  // @pyreon/unistyle
935
935
  // ═══════════════════════════════════════════════════════════════════════════
936
936
 
937
- "unistyle/enrichTheme": {
938
- signature: "enrichTheme(theme: PartialTheme): Theme",
937
+ 'unistyle/enrichTheme': {
938
+ signature: 'enrichTheme(theme: PartialTheme): Theme',
939
939
  example: `import { enrichTheme } from "@pyreon/unistyle"
940
940
 
941
941
  const theme = enrichTheme({
@@ -945,7 +945,7 @@ const theme = enrichTheme({
945
945
 
946
946
  // Merges user overrides with default breakpoints, spacing, and units`,
947
947
  notes:
948
- "Merges a partial theme with the full default theme (breakpoints, spacing, unit utilities). Always use when passing a theme to PyreonUI.",
948
+ 'Merges a partial theme with the full default theme (breakpoints, spacing, unit utilities). Always use when passing a theme to PyreonUI.',
949
949
  },
950
950
 
951
951
  // ═══════════════════════════════════════════════════════════════════════════
@@ -956,9 +956,9 @@ const theme = enrichTheme({
956
956
  // @pyreon/rx
957
957
  // ═══════════════════════════════════════════════════════════════════════════
958
958
 
959
- "rx/filter": {
959
+ 'rx/filter': {
960
960
  signature:
961
- "filter<T>(source: Signal<T[]> | T[], predicate: (item: T) => boolean): Computed<T[]> | T[]",
961
+ 'filter<T>(source: Signal<T[]> | T[], predicate: (item: T) => boolean): Computed<T[]> | T[]',
962
962
  example: `import { filter } from '@pyreon/rx'
963
963
 
964
964
  // Signal input → Computed output (auto-tracks):
@@ -969,11 +969,11 @@ evens() // [2, 4]
969
969
  // Plain input → plain output:
970
970
  const result = filter([1, 2, 3, 4, 5], n => n > 3) // [4, 5]`,
971
971
  notes:
972
- "Every @pyreon/rx function is overloaded: Signal<T[]> input produces Computed<T[]>, plain T[] input produces plain T[]. 24 functions total: filter, map, sortBy, groupBy, keyBy, uniqBy, take, skip, last, chunk, flatten, find, mapValues, count, sum, min, max, average, distinct, scan, combine, debounce, throttle, search.",
972
+ 'Every @pyreon/rx function is overloaded: Signal<T[]> input produces Computed<T[]>, plain T[] input produces plain T[]. 24 functions total: filter, map, sortBy, groupBy, keyBy, uniqBy, take, skip, last, chunk, flatten, find, mapValues, count, sum, min, max, average, distinct, scan, combine, debounce, throttle, search.',
973
973
  },
974
974
 
975
- "rx/pipe": {
976
- signature: "pipe<T>(source: Signal<T[]> | T[], ...operators: Operator[]): Computed<T[]> | T[]",
975
+ 'rx/pipe': {
976
+ signature: 'pipe<T>(source: Signal<T[]> | T[], ...operators: Operator[]): Computed<T[]> | T[]',
977
977
  example: `import { pipe, filter, sortBy, map } from '@pyreon/rx'
978
978
 
979
979
  const users = signal([
@@ -991,16 +991,16 @@ const result = pipe(
991
991
  )
992
992
  // Computed<string[]> → ["Bob", "Charlie"]`,
993
993
  notes:
994
- "Pipe composes operators left-to-right. Signal source produces reactive Computed that re-derives when source changes.",
994
+ 'Pipe composes operators left-to-right. Signal source produces reactive Computed that re-derives when source changes.',
995
995
  },
996
996
 
997
997
  // ═══════════════════════════════════════════════════════════════════════════
998
998
  // @pyreon/toast
999
999
  // ═══════════════════════════════════════════════════════════════════════════
1000
1000
 
1001
- "toast/toast": {
1001
+ 'toast/toast': {
1002
1002
  signature:
1003
- "toast(message: string, options?: ToastOptions): string\ntoast.success/error/warning/info/loading(message): string\ntoast.update(id, options): void\ntoast.dismiss(id?): void\ntoast.promise(promise, { loading, success, error }): string",
1003
+ 'toast(message: string, options?: ToastOptions): string\ntoast.success/error/warning/info/loading(message): string\ntoast.update(id, options): void\ntoast.dismiss(id?): void\ntoast.promise(promise, { loading, success, error }): string',
1004
1004
  example: `import { toast, Toaster } from '@pyreon/toast'
1005
1005
 
1006
1006
  // Basic:
@@ -1034,9 +1034,9 @@ toast.dismiss() // all
1034
1034
  // @pyreon/url-state
1035
1035
  // ═══════════════════════════════════════════════════════════════════════════
1036
1036
 
1037
- "url-state/useUrlState": {
1037
+ 'url-state/useUrlState': {
1038
1038
  signature:
1039
- "useUrlState<T>(key: string, defaultValue: T): UrlStateSignal<T>\nuseUrlState<T extends Record<string, unknown>>(schema: T): UrlStateSchema<T>",
1039
+ 'useUrlState<T>(key: string, defaultValue: T): UrlStateSignal<T>\nuseUrlState<T extends Record<string, unknown>>(schema: T): UrlStateSchema<T>',
1040
1040
  example: `import { useUrlState } from '@pyreon/url-state'
1041
1041
 
1042
1042
  // Single param — synced to ?page=:
@@ -1050,16 +1050,16 @@ filters.page() // 1
1050
1050
  filters.sort() // "name"
1051
1051
  filters.set({ page: 2, sort: 'date' })`,
1052
1052
  notes:
1053
- "Auto type coercion (numbers, booleans, arrays). Uses replaceState (no history spam). Configurable debounce. SSR-safe — reads request URL on server.",
1053
+ 'Auto type coercion (numbers, booleans, arrays). Uses replaceState (no history spam). Configurable debounce. SSR-safe — reads request URL on server.',
1054
1054
  },
1055
1055
 
1056
1056
  // ═══════════════════════════════════════════════════════════════════════════
1057
1057
  // @pyreon/query — useSSE
1058
1058
  // ═══════════════════════════════════════════════════════════════════════════
1059
1059
 
1060
- "query/useSSE": {
1060
+ 'query/useSSE': {
1061
1061
  signature:
1062
- "useSSE<T>(options: { queryKey: unknown[], url: string, transform?: (event: MessageEvent) => T, ... }): { data: Signal<T>, error: Signal<Error>, status: Signal<string> }",
1062
+ 'useSSE<T>(options: { queryKey: unknown[], url: string, transform?: (event: MessageEvent) => T, ... }): { data: Signal<T>, error: Signal<Error>, status: Signal<string> }',
1063
1063
  example: `import { useSSE } from '@pyreon/query'
1064
1064
 
1065
1065
  const { data, error, status } = useSSE({
@@ -1072,15 +1072,15 @@ const { data, error, status } = useSSE({
1072
1072
  // Auto-reconnects on disconnect
1073
1073
  // Integrates with QueryClient for cache invalidation`,
1074
1074
  notes:
1075
- "Server-Sent Events hook. Same pattern as useSubscription but read-only (no send). Integrates with QueryClient cache.",
1075
+ 'Server-Sent Events hook. Same pattern as useSubscription but read-only (no send). Integrates with QueryClient cache.',
1076
1076
  },
1077
1077
 
1078
1078
  // ═══════════════════════════════════════════════════════════════════════════
1079
1079
  // @pyreon/router — useIsActive
1080
1080
  // ═══════════════════════════════════════════════════════════════════════════
1081
1081
 
1082
- "router/useIsActive": {
1083
- signature: "useIsActive(path: string, exact?: boolean): () => boolean",
1082
+ 'router/useIsActive': {
1083
+ signature: 'useIsActive(path: string, exact?: boolean): () => boolean',
1084
1084
  example: `import { useIsActive } from '@pyreon/router'
1085
1085
 
1086
1086
  const isHome = useIsActive('/')
@@ -1090,11 +1090,11 @@ const isExactAdmin = useIsActive('/admin', true) // exact only
1090
1090
  // Reactive — updates when route changes:
1091
1091
  <a class={{ active: isAdmin() }} href="/admin">Admin</a>`,
1092
1092
  notes:
1093
- "Returns a reactive boolean. Segment-aware prefix matching: /admin matches /admin/users but not /admin-panel. Pass exact=true for exact-only matching.",
1093
+ 'Returns a reactive boolean. Segment-aware prefix matching: /admin matches /admin/users but not /admin-panel. Pass exact=true for exact-only matching.',
1094
1094
  },
1095
1095
 
1096
- "storybook/renderToCanvas": {
1097
- signature: "renderToCanvas(context: StoryContext, canvasElement: HTMLElement): void",
1096
+ 'storybook/renderToCanvas': {
1097
+ signature: 'renderToCanvas(context: StoryContext, canvasElement: HTMLElement): void',
1098
1098
  example: `// .storybook/main.ts:
1099
1099
  export default { framework: '@pyreon/storybook' }
1100
1100
 
@@ -1109,6 +1109,6 @@ export const Primary: StoryObj<typeof meta> = {
1109
1109
  args: { variant: 'primary', label: 'Click me' },
1110
1110
  }`,
1111
1111
  notes:
1112
- "Storybook renderer for Pyreon components. Re-exports h, Fragment, signal, computed, effect, mount for story convenience.",
1112
+ 'Storybook renderer for Pyreon components. Re-exports h, Fragment, signal, computed, effect, mount for story convenience.',
1113
1113
  },
1114
1114
  }