open-index/open-npm huggingface dataset:
npm package: @pyreon/compiler
Description: Template and JSX compiler for Pyreon
Latest version: 0.12.10

# @pyreon/compiler

JSX reactive transform for Pyreon. Automatically wraps dynamic expressions in reactive getters and hoists static JSX nodes to module scope.

## Install

```bash
bun add @pyreon/compiler
```

## Quick Start

```ts
import { transformJSX } from '@pyreon/compiler'

const result = transformJSX(
  `
  const App = () => <div class={color()}>{count()}</div>
`,
  'app.tsx',
)

console.log(result.code)
// Dynamic expressions are wrapped: {() => count()}, class={() => color()}
// Static JSX nodes are hoisted to module scope
```

## What It Does

The compiler transforms JSX expression containers and props so the Pyreon runtime receives reactive getters instead of eagerly-evaluated values.

| Input                     | Output                     | Reason          |
| ------------------------- | -------------------------- | --------------- |
| `<div>{expr}</div>`       | `<div>{() => expr}</div>`  | Dynamic child   |
| `<div class={expr}>`      | `<div class={() => expr}>` | Dynamic prop    |
| `<button onClick={fn}>`   | unchanged                  | Event handler   |
| `<div>{() => expr}</div>` | unchanged                  | Already wrapped |
| `<div>{"literal"}</div>`  | unchanged                  | Static value    |

### Static Hoisting

Fully static JSX subtrees inside expression containers are hoisted to module-level constants, so they are created once at module initialization rather than per-render.

```ts
// Before
const App = () => <div>{<span>Hello</span>}</div>

// After
const _$h0 = <span>Hello</span>
const App = () => <div>{_$h0}</div>
```

## API

- **`transformJSX(code: string, filename?: string): TransformResult`** -- Transforms JSX source code. Returns an object with the transformed `code` string.

### Types

- **`TransformResult`** -- `{ code: string }` -- The output of a transform pass.

## Implementation Notes

- Uses the TypeScript parser for AST positions and magic-string for source replacements.
- Props named `key` and `ref` are never wrapped.
- Props matching `on[A-Z]*` (event handlers) are never wrapped.
- No extra runtime dependencies beyond TypeScript (already a dev dependency).

## License

MIT
npm package: @pyreon/connector-document
Description: Bridge between @pyreon/pyreon styled components and @pyreon/document rendering
Latest version: 0.12.10

# @pyreon/connector-document

Bridge between `@pyreon/ui-system` components and `@pyreon/document` for multi-format document export.

## Install

```bash
bun add @pyreon/connector-document
```

## Overview

Connects the Pyreon UI component system (elements, rocketstyle) with the document rendering engine, enabling components to be exported to PDF, DOCX, HTML email, and 14+ other formats.

## License

MIT
npm package: @pyreon/create-zero
Description: Create a new Pyreon Zero project
Author: Vit Bokisch
Latest version: 0.12.10

# @pyreon/create-zero

Interactive scaffolding tool for [Pyreon Zero](https://github.com/pyreon/zero) projects.

## Usage

```bash
bun create @pyreon/zero my-app
```

Or via the CLI:

```bash
zero create my-app
```

## Interactive Setup

The CLI prompts you to configure:

1. **Rendering mode** — SSR Streaming, SSR String, SSG, or SPA
2. **Features** — pick from store, query, forms, feature CRUD, i18n, tables, virtual lists, CSS-in-JS, UI elements, animations, hooks
3. **AI toolchain** — MCP server config, CLAUDE.md, doctor scripts

## What Gets Generated

Based on your selections:

- `package.json` — only the dependencies you chose
- `vite.config.ts` — configured for your rendering mode
- `src/entry-server.ts` — matching SSR/stream config with CORS + rate limiting
- `src/routes/` — example pages, API routes, protected dashboard
- `src/features/` — feature example with Zod schema (if selected)
- `src/stores/` — store example (if selected)
- `.mcp.json` — AI IDE integration (if AI toolchain selected)
- `CLAUDE.md` — project rules for AI agents (if AI toolchain selected)
- `env.d.ts` — virtual module type declarations

## License

[MIT](LICENSE)
npm package: @pyreon/document
Description: Universal document rendering for Pyreon — one template, every output format (HTML, PDF, DOCX, email, XLSX, Markdown, and more)
Latest version: 0.12.10

# @pyreon/document

Universal document rendering for Pyreon. One template, every output format: HTML, PDF, DOCX, email, XLSX, Markdown, plain text, CSV, and custom formats.

## Install

```bash
bun add @pyreon/document
```

## Quick Start

```tsx
import { Document, Page, Heading, Text, Table, render } from '@pyreon/document'

const doc = (
  <Document title="Report">
    <Page>
      <Heading>Sales Report</Heading>
      <Text>Q4 performance summary.</Text>
      <Table
        columns={['Region', 'Revenue']}
        rows={[
          ['US', '$1M'],
          ['EU', '$800K'],
        ]}
      />
    </Page>
  </Document>
)

await render(doc, 'pdf') // PDF Uint8Array
await render(doc, 'email') // email-safe HTML string
await render(doc, 'md') // Markdown string
```

## Browser Download

```tsx
import { download } from '@pyreon/document'

await download(doc, 'pdf', 'report.pdf')
```

## API

### Primitives

Layout: `Document`, `Page`, `PageBreak`, `Section`, `Row`, `Column`, `Spacer`, `Divider`

Content: `Heading`, `Text`, `Image`, `Link`, `Button`, `Code`, `Quote`, `List`, `ListItem`, `Table`

### `render(doc, format, options?)`

Render a document tree to the specified format. Returns a `RenderResult` (string or `Uint8Array` depending on format).

### `download(doc, format, filename, options?)`

Browser-only. Renders and triggers a file download.

### `registerRenderer(format, renderer)` / `unregisterRenderer(format)`

Register custom output formats.

### `createDocument()`

Imperative builder API for constructing documents without JSX.

## License

MIT
npm package: @pyreon/document-primitives
Description: Rocketstyle document components — render in browser, export to 18 formats
Latest version: 0.12.10

# @pyreon/document-primitives

Rocketstyle-based document components for `@pyreon/document` export.

## Install

```bash
bun add @pyreon/document-primitives
```

## Overview

Provides styled document primitives built on `@pyreon/rocketstyle` that can be rendered to PDF, DOCX, email, and other formats via `@pyreon/document`.

## License

MIT
npm package: @pyreon/flow
Description: Reactive flow diagrams for Pyreon — signal-native nodes, edges, pan/zoom, auto-layout
Latest version: 0.12.10

# @pyreon/flow

Reactive flow diagrams for Pyreon. Signal-native nodes, edges, pan/zoom, and auto-layout via elkjs. No D3 dependency.

## Install

```bash
bun add @pyreon/flow
```

## Quick Start

```tsx
import { createFlow, Flow, Background, MiniMap, Controls } from '@pyreon/flow'

const flow = createFlow({
  nodes: [
    { id: '1', position: { x: 0, y: 0 }, data: { label: 'Start' } },
    { id: '2', position: { x: 200, y: 100 }, data: { label: 'End' } },
  ],
  edges: [{ source: '1', target: '2' }],
})

<Flow instance={flow}>
  <Background />
  <MiniMap />
  <Controls />
</Flow>
```

## API

### `createFlow(config)`

Create a reactive flow instance with signal-based state.

**Reactive state:** `flow.nodes`, `flow.edges`, `flow.viewport`

**Node operations:** `addNode()`, `removeNode()`, `updateNode()`, `updateNodePosition()`

**Edge operations:** `addEdge()`, `removeEdge()`

**Selection:** `selectNode()`, `selectEdge()`, `clearSelection()`, `deleteSelected()`

**Viewport:** `zoomIn()`, `zoomOut()`, `zoomTo()`, `fitView()`, `panTo()`

**Layout:** `flow.layout(algorithm, options)` — auto-layout via elkjs (lazy-loaded). Algorithms: layered, force, stress, tree, radial, box.

**Graph queries:** `getConnectedEdges()`, `getIncomers()`, `getOutgoers()`, `isValidConnection()`

**Listeners:** `onConnect()`, `onNodesChange()`, `onNodeClick()`, `onEdgeClick()`

### Components

| Component       | Description                                                      |
| --------------- | ---------------------------------------------------------------- |
| `<Flow>`        | Main container with pan/zoom via pointer events + CSS transforms |
| `<Background>`  | Dot or line grid background                                      |
| `<MiniMap>`     | Overview minimap                                                 |
| `<Controls>`    | Zoom/fit buttons                                                 |
| `<Handle>`      | Connection handle on nodes                                       |
| `<Panel>`       | Overlay panel positioned relative to the flow                    |
| `<NodeResizer>` | Resize handle for nodes                                          |
| `<NodeToolbar>` | Toolbar attached to a node                                       |

### Edge Paths

`getBezierPath()`, `getSmoothStepPath()`, `getStraightPath()`, `getStepPath()`, `getWaypointPath()`

### `Position`

Enum: `Top`, `Right`, `Bottom`, `Left`

## License

MIT
npm package: @pyreon/head
Description: Head tag management for Pyreon — works in SSR and CSR
Latest version: 0.12.10

# @pyreon/head

Manage document head tags (title, meta, link, style, script, JSON-LD) with Pyreon's reactivity system. Supports SSR via `renderWithHead`.

## Install

```bash
bun add @pyreon/head
```

## Quick Start

```tsx
import { HeadProvider, useHead } from '@pyreon/head'

const App = () => {
  useHead({
    title: 'My App',
    meta: [
      { name: 'description', content: 'A Pyreon application' },
      { property: 'og:title', content: 'My App' },
    ],
    link: [{ rel: 'canonical', href: 'https://example.com' }],
  })

  return <div>Hello</div>
}

// Wrap your app with HeadProvider
const Root = () => (
  <HeadProvider>
    <App />
  </HeadProvider>
)
```

## SSR

Use `renderWithHead` to capture head tags during server-side rendering:

```tsx
import { renderWithHead } from '@pyreon/head'

const { html, head } = renderWithHead(<App />)
// `head` contains the serialized <title>, <meta>, <link>, etc.
```

## API

### Components

- `HeadProvider` -- context provider that collects head entries from the tree

### Hooks

- `useHead(input: UseHeadInput)` -- declare head tags from any component

### SSR

- `renderWithHead(vnode)` -- render to string and extract head tags as `RenderWithHeadResult`
- `createHeadContext()` -- create a standalone head context for manual integration

### Types

`HeadTag`, `HeadEntry`, `UseHeadInput`, `HeadContextValue`, `HeadProviderProps`, `RenderWithHeadResult`
npm package: @pyreon/hotkeys
Description: Reactive keyboard shortcut management for Pyreon — scope-aware, conflict detection
Latest version: 0.12.10

# @pyreon/hotkeys

Reactive keyboard shortcut management for Pyreon. Scope-aware, modifier keys, conflict detection, automatic lifecycle cleanup.

## Install

```bash
bun add @pyreon/hotkeys
```

## Quick Start

```tsx
import { useHotkey, useHotkeyScope } from '@pyreon/hotkeys'

// Global shortcut — auto-unregisters on unmount
useHotkey('mod+s', () => save(), { description: 'Save document' })
useHotkey('mod+k', () => openCommandPalette())

// Scoped shortcuts — only active when scope is enabled
useHotkeyScope('editor')
useHotkey('ctrl+z', () => undo(), { scope: 'editor' })
useHotkey('escape', () => closeModal(), { scope: 'modal' })
```

`mod` = Command on Mac, Ctrl elsewhere. Shortcuts are ignored in input elements by default.

## API

### `useHotkey(shortcut, handler, options?)`

Component-scoped keyboard shortcut. Automatically unregisters on unmount.

Options: `scope`, `description`, `preventDefault` (default: true), `enableInInputs` (default: false).

### `useHotkeyScope(scope)`

Activate a scope for the component's lifetime. Deactivates on unmount.

### `registerHotkey(shortcut, handler, options?)`

Imperative registration. Returns an unregister function.

### `enableScope(scope)` / `disableScope(scope)`

Manually control which scopes are active.

### `getRegisteredHotkeys()`

List all registered hotkeys — useful for help dialogs.

### `getActiveScopes()`

List currently active scopes.

### Utilities

- `parseShortcut(str)` — parse shortcut string into `KeyCombo`
- `formatCombo(combo)` — format `KeyCombo` as display string
- `matchesCombo(event, combo)` — check if a keyboard event matches a combo

## License

MIT
npm package: @pyreon/machine
Description: Reactive state machines for Pyreon — constrained signals with type-safe transitions
Latest version: 0.12.10

# @pyreon/machine

Reactive state machines for Pyreon. A machine is a constrained signal — it can only hold specific values and transition between them via specific events. Type-safe states and events inferred from the definition.

## Install

```bash
bun add @pyreon/machine
```

## Quick Start

```tsx
import { createMachine } from '@pyreon/machine'

const machine = createMachine({
  initial: 'idle',
  states: {
    idle: { on: { FETCH: 'loading' } },
    loading: { on: { SUCCESS: 'done', ERROR: 'error' } },
    done: {},
    error: { on: { RETRY: 'loading' } },
  },
})

machine() // 'idle' — reads like a signal
machine.send('FETCH') // transition to 'loading'
machine.matches('loading') // true — reactive in effects/JSX

// Reactive in JSX
{
  ;() => machine.matches('loading') && <Spinner />
}
{
  ;() => machine.matches('done') && <Results />
}
```

## Guards

Conditional transitions using guard functions:

```tsx
const form = createMachine({
  initial: 'editing',
  states: {
    editing: {
      on: { SUBMIT: { target: 'submitting', guard: () => isValid() } },
    },
    submitting: { on: { SUCCESS: 'done', ERROR: 'editing' } },
    done: {},
  },
})
```

## API

### `createMachine(config)`

Create a reactive state machine. Config: `initial` (starting state) and `states` (state/event map).

**Returns `Machine`:**

| Property                   | Description                                     |
| -------------------------- | ----------------------------------------------- |
| `machine()`                | Read current state (reactive)                   |
| `send(event, payload?)`    | Trigger a transition                            |
| `matches(...states)`       | Check if in one of the given states (reactive)  |
| `can(event)`               | Check if event would trigger a valid transition |
| `nextEvents()`             | Available events from current state             |
| `reset()`                  | Return to initial state                         |
| `onEnter(state, callback)` | Fire callback when entering a state             |
| `onTransition(callback)`   | Fire on any transition                          |

Use signals alongside machines for data. The machine manages transitions, signals manage data.

## License

MIT
npm package: @pyreon/permissions
Description: Reactive permissions for Pyreon — type-safe, signal-driven, universal
Latest version: 0.12.10

# @pyreon/permissions

Reactive permissions for Pyreon. Type-safe, signal-driven, universal — works with RBAC, ABAC, feature flags, and subscription tiers. Any model maps to string keys with boolean or predicate values.

## Install

```bash
bun add @pyreon/permissions
```

## Quick Start

```tsx
import { createPermissions } from '@pyreon/permissions'

const can = createPermissions({
  'posts.read': true,
  'posts.create': true,
  'posts.update': (post: Post) => post.authorId === currentUserId(),
  'users.manage': false,
})

can('posts.read') // true — reactive in effects/JSX
can('posts.update', myPost) // evaluates predicate
can.not('billing.export') // true if denied
can.all('posts.read', 'posts.create') // true if both granted
can.any('posts.read', 'users.manage') // true if any granted

// Update after login / role change
can.set(fromRole(user.role))
can.patch({ 'billing.export': true })

// Reactive in JSX
{
  ;() => can('posts.delete') && <DeleteButton />
}
{
  ;() => can('users.manage') && <AdminPanel />
}
```

## Wildcards

`'posts.*'` matches any `posts.X`. `'*'` matches everything (superadmin).

## Context Pattern

```tsx
import { PermissionsProvider, usePermissions } from '@pyreon/permissions'

;<PermissionsProvider instance={can}>
  <App />
</PermissionsProvider>

// In any child component:
const can = usePermissions()
```

## API

### `createPermissions(initial?)`

Create a reactive permissions instance. Permission values are `boolean` (static) or `(context?) => boolean` (predicate).

| Method               | Description                                  |
| -------------------- | -------------------------------------------- |
| `can(key, context?)` | Check a permission (reactive)                |
| `can.not(key)`       | Inverse check                                |
| `can.all(...keys)`   | True if all granted                          |
| `can.any(...keys)`   | True if any granted                          |
| `can.set(map)`       | Replace all permissions                      |
| `can.patch(map)`     | Merge permissions                            |
| `can.granted()`      | `Computed<string[]>` of all granted keys     |
| `can.entries()`      | `Computed<[key, value][]>` for introspection |

### `PermissionsProvider` / `usePermissions()`

Context pattern for dependency injection, SSR, and testing.

## License

MIT
npm package: @pyreon/reactivity
Description: Signals-based reactivity system for Pyreon
Latest version: 0.12.10

# @pyreon/reactivity

Signal-based fine-grained reactivity primitives for the Pyreon framework.

## Install

```bash
bun add @pyreon/reactivity
```

## Quick Start

```ts
import { signal, computed, effect, batch } from '@pyreon/reactivity'

const count = signal(0)
const doubled = computed(() => count() * 2)

effect(() => {
  console.log('doubled:', doubled())
})

batch(() => {
  count.set(1)
  count.set(2)
})
// logs "doubled: 4" once
```

## API

### Signals

- **`signal<T>(initial: T, options?): Signal<T>`** -- Callable getter with `.set(value)` and `.update(fn)` methods. Pass `{ name }` for debug labels (auto-injected by `@pyreon/vite-plugin` in dev mode).
- **`computed<T>(fn, options?): Computed<T>`** -- Derived signal that recomputes lazily when dependencies change.
- **`cell<T>(initial: T): Cell<T>`** -- Lightweight reactive cell.

### Effects

- **`effect(fn): Effect`** -- Runs `fn` and re-runs it whenever its tracked dependencies change.
- **`onCleanup(fn)`** -- Registers a cleanup function inside an effect. Runs before re-execution and on disposal.
- **`renderEffect(fn): Effect`** -- Like `effect`, but scheduled for render timing.
- **`watch(source, callback, options?): WatchOptions`** -- Watches a reactive source and calls back on change.
- **`setErrorHandler(handler)`** -- Sets a global error handler for effect errors.

### Batching

- **`batch(fn)`** -- Groups multiple signal writes; subscribers notified once at the end.
- **`nextTick(): Promise<void>`** -- Resolves after the current batch of updates flushes.

### Tracking

- **`runUntracked(fn)`** -- Runs `fn` without tracking any signal reads.
- **`untrack(fn)`** -- Alias for `runUntracked`.

### Scopes

- **`effectScope(): EffectScope`** -- Creates a scope that collects effects for bulk disposal.
- **`getCurrentScope(): EffectScope | undefined`** -- Returns the active effect scope.
- **`setCurrentScope(scope)`** -- Manually sets the current effect scope.

### Selectors and Resources

- **`createSelector(source)`** -- Creates an efficient selector for keyed comparisons.
- **`createResource(fetcher): Resource<T>`** -- Wraps an async data source in a reactive resource.

### Stores

- **`createStore(initial)`** -- Creates a deeply reactive store object.
- **`isStore(value): boolean`** -- Checks whether a value is a reactive store.
- **`reconcile(target, source)`** -- Efficiently patches a store to match a new value.

## License

MIT
npm package: @pyreon/router
Description: Official router for Pyreon
Latest version: 0.12.10

# @pyreon/router

Type-safe client-side router for Pyreon with hash and history modes, nested routes, guards, loaders, and scroll restoration.

## Install

```bash
bun add @pyreon/router
```

## Quick Start

```tsx
import { createRouter, RouterProvider, RouterView, RouterLink } from '@pyreon/router'

const router = createRouter({
  routes: [
    { path: '/', component: Home },
    { path: '/user/:id', component: UserPage, name: 'user' },
    {
      path: '/admin',
      component: AdminLayout,
      children: [{ path: 'users', component: AdminUsers }],
    },
    { path: '/old-path', redirect: '/new-path' },
    { path: '/dashboard', component: lazy(() => import('./Dashboard')) },
    { path: '(.*)', component: NotFound },
  ],
})

const App = () => (
  <RouterProvider router={router}>
    <RouterView />
  </RouterProvider>
)
```

## Typed Params

Route parameters are inferred from path strings:

```tsx
const route = useRoute<'/user/:id'>()
route().params.id // string
```

## Named Navigation

```tsx
const router = useRouter()
router.push({ name: 'user', params: { id: '42' } })
```

## RouterLink

```tsx
<RouterLink to="/user/42">Profile</RouterLink>
<RouterLink to={{ name: "user", params: { id: "42" } }}>Profile</RouterLink>
```

## Data Loaders

```tsx
import { useLoaderData, prefetchLoaderData } from '@pyreon/router'

const data = useLoaderData<typeof loader>()
```

## API

### Router Creation

- `createRouter(options: RouterOptions)` -- create a router instance
- `lazy(loader)` -- define a lazily loaded route component

### Hooks

- `useRouter()` -- access the router instance
- `useRoute<Path>()` -- access the current resolved route with typed params
- `useLoaderData<T>()` -- access data returned by a route loader

### Components

- `RouterProvider` -- provides router context to the tree
- `RouterView` -- renders the matched route component
- `RouterLink` -- anchor element with client-side navigation

### Utilities

- `resolveRoute(routes, path)` -- match a path against route definitions
- `parseQuery(search)` / `parseQueryMulti(search)` -- parse query strings
- `stringifyQuery(params)` -- serialize query parameters
- `buildPath(pattern, params)` -- build a path from a pattern and params
- `findRouteByName(routes, name)` -- look up a named route
- `prefetchLoaderData(router, path)` -- prefetch loader data for a path
- `serializeLoaderData(router)` / `hydrateLoaderData(router, data)` -- SSR serialization

### Types

`ExtractParams`, `RouteMeta`, `ResolvedRoute`, `RouteRecord`, `RouterOptions`, `Router`, `NavigationGuard`, `AfterEachHook`, `ScrollBehaviorFn`, `LoaderContext`, `RouteLoaderFn`
npm package: @pyreon/runtime-server
Description: SSR/SSG renderer for Pyreon — streaming HTML + static generation
Latest version: 0.12.10

# @pyreon/runtime-server

Server-side rendering for Pyreon. Renders VNode trees to HTML strings or Web-standard `ReadableStream` chunks with Suspense streaming support.

## Install

```bash
bun add @pyreon/runtime-server
```

## Quick Start

```tsx
import { renderToString } from '@pyreon/runtime-server'

function App() {
  return <h1>Hello from SSR</h1>
}

const html = await renderToString(<App />)
// "<h1>Hello from SSR</h1>"
```

## API

### `renderToString(vnode)`

Render a VNode tree to a complete HTML string. Returns `Promise<string>`. Async components are awaited. Each call gets an isolated context stack.

### `renderToStream(vnode)`

Render a VNode tree to a `ReadableStream<string>` for progressive HTML streaming. Synchronous subtrees are flushed immediately. Suspense boundaries are streamed out-of-order: the fallback is emitted first, then resolved children are sent as `<template>` elements with inline swap scripts.

```tsx
import { renderToStream } from '@pyreon/runtime-server'

const stream = renderToStream(<App />)
return new Response(stream, {
  headers: { 'Content-Type': 'text/html' },
})
```

### `runWithRequestContext(fn)`

Run an async function with a fresh, isolated context stack and store registry. Useful for calling Pyreon APIs (e.g. `useHead`, route loader prefetching) outside of `renderToString` while maintaining per-request isolation.

```ts
import { runWithRequestContext } from '@pyreon/runtime-server'

const result = await runWithRequestContext(async () => {
  // Pyreon context and stores are isolated to this call
  return await prefetchLoaderData(url)
})
```

### `configureStoreIsolation(registryProvider)`

Wire up per-request store isolation for concurrent SSR. Call once at server startup with a function that hooks your store registry into the request-scoped `AsyncLocalStorage`. Prevents store state from leaking between requests.

```ts
import { configureStoreIsolation } from '@pyreon/runtime-server'

configureStoreIsolation((provider) => {
  // Wire your store registry to use the per-request provider
})
```

## Behavior Notes

- Signal accessors are called synchronously to snapshot their current value. No effects are created on the server.
- Async component functions (`async function Component()`) are fully supported.
- Context isolation uses `AsyncLocalStorage` internally. Each `renderToString` and `renderToStream` call gets its own context stack.
- HTML output is escaped. Event handlers (`on*`) are omitted. URL attributes are sanitized against `javascript:` and `data:` URIs.
npm package: @pyreon/rx
Description: Signal-aware reactive transforms — filter, map, sort, group, pipe for Pyreon signals
Latest version: 0.12.10

# @pyreon/rx

Signal-aware reactive transforms for the Pyreon framework.

Every function is overloaded: pass a `Signal<T[]>` and get a `Computed<R>` back (reactive), or pass a plain `T[]` and get `R` (static).

## Install

```bash
bun add @pyreon/rx
```

## Usage

```ts
import { rx } from '@pyreon/rx'
import { signal } from '@pyreon/reactivity'

const users = signal<User[]>([])

const active = rx.filter(users, (u) => u.active) // Computed<User[]>
const sorted = rx.sortBy(active, 'name') // Computed<User[]>
const top10 = rx.take(sorted, 10) // Computed<User[]>

// Pipe chains
const result = rx.pipe(
  users,
  (items) => items.filter((u) => u.active),
  (items) => items.sort((a, b) => a.name.localeCompare(b.name)),
  (items) => items.slice(0, 10),
)
```

## API

**Collections:** `filter`, `map`, `sortBy`, `groupBy`, `keyBy`, `uniqBy`, `take`, `skip`, `last`, `chunk`, `flatten`, `find`, `mapValues`

**Aggregation:** `count`, `sum`, `min`, `max`, `average`

**Operators:** `distinct`, `scan`, `combine`

**Timing:** `debounce`, `throttle`

**Search:** `search`

**Pipe:** `pipe`

## License

MIT
npm package: @pyreon/server
Description: SSR handler, SSG prerender, and island architecture for Pyreon
Latest version: 0.12.10

# @pyreon/server

SSR handler, static site generation, and island architecture for Pyreon.

## Install

```bash
bun add @pyreon/server
```

## SSR

Create a request handler that renders your Pyreon app on the server:

```ts
import { createHandler } from '@pyreon/server'
import { App } from './App'
import { routes } from './routes'

const handler = createHandler({
  App,
  routes,
  template: await Bun.file('index.html').text(),
})

Bun.serve({ fetch: handler, port: 3000 })
```

## SSG (Static Site Generation)

Pre-render pages to static HTML files:

```ts
import { createHandler, prerender } from '@pyreon/server'

const handler = createHandler({ App, routes })
const result = await prerender({
  handler,
  paths: ['/', '/about', '/blog'],
  outDir: 'dist',
})
console.log(`Generated ${result.pages} pages in ${result.elapsed}ms`)
```

## Islands

Render mostly-static pages with interactive islands that hydrate independently:

```ts
// Server
import { island } from '@pyreon/server'

const Counter = island(() => import('./Counter'), {
  name: 'Counter',
  hydrate: 'visible', // load | idle | visible | media(query) | never
})
```

```ts
// Client entry
import { startClient, hydrateIslands } from '@pyreon/server/client'

// Full app hydration
startClient({ App, routes, container: '#app' })

// Or island-only hydration
hydrateIslands({
  Counter: () => import('./Counter'),
  Search: () => import('./Search'),
})
```

## API

### Server Exports (`@pyreon/server`)

- `createHandler(options: HandlerOptions)` -- create an SSR request handler
- `prerender(options: PrerenderOptions)` -- generate static HTML files
- `island(loader, options: IslandOptions)` -- define an island component
- `processTemplate(template, data)` -- inject rendered HTML into an HTML template
- `buildScripts(data)` -- generate script tags for hydration
- `DEFAULT_TEMPLATE` -- built-in HTML template

### Client Exports (`@pyreon/server/client`)

- `startClient(options: StartClientOptions)` -- hydrate a full SSR app
- `hydrateIslands(registry)` -- hydrate island components on the page

### Types

`HandlerOptions`, `PrerenderOptions`, `PrerenderResult`, `IslandOptions`, `IslandMeta`, `HydrationStrategy`, `Middleware`, `MiddlewareContext`, `TemplateData`, `StartClientOptions`
npm package: @pyreon/storage
Description: Reactive client-side storage for Pyreon — localStorage, sessionStorage, cookies, IndexedDB
Latest version: 0.12.10

# @pyreon/storage

Reactive client-side storage for Pyreon. Signal-backed persistence across localStorage, sessionStorage, cookies, IndexedDB, and custom backends. Same key returns the same signal instance — no drift between components.

## Install

```bash
bun add @pyreon/storage
```

## Quick Start

```tsx
import { useStorage, useCookie, useSessionStorage, useIndexedDB } from '@pyreon/storage'

// localStorage — persistent, cross-tab synced
const theme = useStorage('theme', 'light')
theme() // read reactively
theme.set('dark') // updates signal + localStorage
theme.remove() // remove from storage

// Cookie — SSR-readable, configurable expiry
const locale = useCookie('locale', 'en', { maxAge: 365 * 86400 })

// sessionStorage — tab-scoped
const wizardStep = useSessionStorage('wizard-step', 0)

// IndexedDB — large data, debounced writes
const draft = useIndexedDB('article-draft', { title: '', body: '' })
```

## Custom Backends

```tsx
import { createStorage } from '@pyreon/storage'

const useEncryptedStorage = createStorage({
  get: (key) => decrypt(localStorage.getItem(key)),
  set: (key, value) => localStorage.setItem(key, encrypt(value)),
  remove: (key) => localStorage.removeItem(key),
})

const secret = useEncryptedStorage('api-key', '')
```

## API

### Hooks

| Hook                                        | Backend         | Description                       |
| ------------------------------------------- | --------------- | --------------------------------- |
| `useStorage(key, default, options?)`        | localStorage    | Persistent, cross-tab synced      |
| `useSessionStorage(key, default, options?)` | sessionStorage  | Tab-scoped                        |
| `useCookie(key, default, options?)`         | document.cookie | SSR-readable, configurable expiry |
| `useIndexedDB(key, default, options?)`      | IndexedDB       | Large data, debounced writes      |
| `useMemoryStorage(key, default)`            | in-memory       | SSR/testing                       |

All hooks return `StorageSignal<T>` — extends `Signal<T>` with `.remove()`.

### `createStorage(backend)`

Factory for custom storage backends (encrypted, remote, etc.).

### `setCookieSource(header)`

Set SSR cookie source for server-side rendering.

### `removeStorage(key, options?)` / `clearStorage(type?)`

Cleanup utilities for removing stored values.

## License

MIT
npm package: @pyreon/store
Description: Global state management for Pyreon — Pinia-inspired composition stores
Latest version: 0.12.10

# @pyreon/store

Global reactive state management built on `@pyreon/reactivity` signals. Composition API returning structured `StoreApi<T>`.

## Install

```bash
bun add @pyreon/store
```

## Quick Start

```ts
import { defineStore, signal, computed } from '@pyreon/store'

const useCounter = defineStore('counter', () => {
  const count = signal(0)
  const doubled = computed(() => count() * 2)
  const increment = () => count.update((n) => n + 1)
  return { count, doubled, increment }
})

// Destructure what you need:
const { store, patch, subscribe, reset, dispose } = useCounter()
store.count() // 0
store.increment()
store.doubled() // 2
patch({ count: 10 }) // batch-update
```

Stores are singletons. The setup function runs once per store ID; subsequent calls return the cached instance.

## API

### `defineStore(id, setup)`

Define a store with a unique string ID and a setup function. Returns a hook that produces a `StoreApi<T>`:

| Property               | Description                                                      |
| ---------------------- | ---------------------------------------------------------------- |
| `store`                | The user-defined state, computed values, and actions             |
| `id`                   | Store identifier                                                 |
| `state`                | Read-only snapshot of all signal values                          |
| `patch(obj \| fn)`     | Batch-update signals (object or function form)                   |
| `subscribe(cb, opts?)` | Listen to state mutations. `{ immediate: true }` fires instantly |
| `onAction(cb)`         | Intercept action calls (sync + async). Returns unsubscribe       |
| `reset()`              | Reset all signals to initial values                              |
| `dispose()`            | Teardown: unsubscribe all, remove from registry                  |

### `addStorePlugin(plugin)`

Register a global plugin. Plugins receive the `StoreApi` when a store is created.

### `resetStore(id)`

Destroy a store by ID. The next call to `useStore()` will re-run the setup function.

### `resetAllStores()`

Destroy all stores. Useful for testing and SSR isolation.

### `setStoreRegistryProvider(fn)`

Override the store registry provider for concurrent SSR. Each request can get its own isolated registry via `AsyncLocalStorage`.

```ts
import { AsyncLocalStorage } from 'node:async_hooks'
import { setStoreRegistryProvider } from '@pyreon/store'

const als = new AsyncLocalStorage<Map<string, unknown>>()
setStoreRegistryProvider(() => als.getStore() ?? new Map())
```

## Re-exports

The following are re-exported from `@pyreon/reactivity` for convenience:

- `signal`, `computed`, `effect`, `batch`
- `Signal` (type)
npm package: @pyreon/toast
Description: Imperative toast notifications for Pyreon — no provider needed
Latest version: 0.12.10

# @pyreon/toast

Signal-driven toast notifications for the Pyreon framework.

## Install

```bash
bun add @pyreon/toast
```

## Usage

```tsx
import { toast, Toaster } from '@pyreon/toast'

// Place once at app root
;<Toaster position="top-right" />

// Show toasts from anywhere — no provider needed
toast.success('Saved!')
toast.error('Connection failed')
toast('Custom message', { duration: 8000 })

// Promise pattern
toast.promise(saveData(), {
  loading: 'Saving...',
  success: 'Done!',
  error: 'Failed',
})
```

## API

- `toast(message, options?)` — show a toast, returns id
- `toast.success/error/warning/info(message)` — typed shortcuts
- `toast.loading(message)` — persistent loading toast
- `toast.update(id, updates)` — update an existing toast
- `toast.dismiss(id?)` — dismiss one or all
- `toast.promise(promise, { loading, success, error })` — auto-updating toast
- `<Toaster position? max? gap? offset? />` — render component

## License

MIT
npm package: @pyreon/typescript
Description: TypeScript configuration presets for Pyreon projects
Latest version: 0.12.10

# @pyreon/typescript

TypeScript configuration presets for Pyreon projects. Zero-config — just extend and go.

## Install

```bash
bun add -d @pyreon/typescript
```

## Usage

### Applications

For Pyreon apps (SPAs, SSR apps, examples):

```json
{
  "extends": "@pyreon/typescript/app"
}
```

### Libraries

For publishable packages that need `.d.ts` output:

```json
{
  "extends": "@pyreon/typescript/lib"
}
```

### Base

Both `app` and `lib` extend `base`. You can extend it directly if you need full control:

```json
{
  "extends": "@pyreon/typescript",
  "compilerOptions": {
    "noEmit": true
  }
}
```

## What's Included

All presets configure:

- **JSX** — `"jsx": "preserve"` with `"jsxImportSource": "@pyreon/core"` so `<div />` just works
- **Modern target** — ES2024 with DOM and DOM.Iterable libs
- **Bundler resolution** — `"moduleResolution": "Bundler"` for Vite/esbuild/Bun compatibility
- **Strict mode** — `strict`, `exactOptionalPropertyTypes`, `noUncheckedIndexedAccess`, `noImplicitOverride`
- **Source maps** — enabled by default

### `app` adds:

- `noEmit: true` — type-checking only, bundler handles emit

### `lib` adds:

- `declaration: true` + `declarationMap: true` — generates `.d.ts` files for consumers

## License

MIT
npm package: @pyreon/url-state
Description: Reactive URL search-param state for Pyreon — signal-backed, type-coerced, SSR-safe
Latest version: 0.12.10

# @pyreon/url-state

Reactive signals synced to URL query parameters.

## Install

```bash
bun add @pyreon/url-state
```

## Usage

```ts
import { useUrlState } from '@pyreon/url-state'

// Single param — auto type coercion from default value
const page = useUrlState('page', 1) // reads ?page=X, defaults to 1
page() // 1
page.set(2) // URL becomes ?page=2
page.reset() // back to default
page.remove() // removes ?page entirely

// Schema mode — multiple params
const { page, sort, q } = useUrlState({ page: 1, sort: 'name', q: '' })

// Debounced (for search inputs)
const q = useUrlState('q', '', { debounce: 300 })
```

## Features

- Auto type coercion (number, boolean, string, string[], object)
- `replaceState` by default (no history pollution)
- Debounced URL writes
- `popstate` sync (back/forward buttons)
- SSR-safe (returns defaults when no window)
- Optional `@pyreon/router` integration
- Array encoding: `"comma"` or `"repeat"` format

## License

MIT
npm package: @pyreon/vite-plugin
Description: Vite plugin for Pyreon — .pyreon SFC support, HMR, compiler integration
Latest version: 0.12.10

# @pyreon/vite-plugin

Vite plugin for the Pyreon framework. Applies the Pyreon JSX reactive transform to `.tsx`, `.jsx`, and `.pyreon` files, and optionally adds SSR dev middleware.

## Install

```bash
bun add -D @pyreon/vite-plugin
```

## Quick Start (SPA)

```ts
// vite.config.ts
import pyreon from '@pyreon/vite-plugin'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [pyreon()],
})
```

## SSR Mode

Pass an `ssr` option to enable SSR dev middleware. The plugin will load your server entry via Vite's `ssrLoadModule` and call its exported `handler` function for every non-asset GET request.

```ts
// vite.config.ts
import pyreon from '@pyreon/vite-plugin'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [pyreon({ ssr: { entry: './src/entry-server.ts' } })],
})
```

Your server entry must export a `handler` (or default export) with the signature `(req: Request) => Promise<Response>`:

```tsx
// src/entry-server.ts
import { renderToString } from '@pyreon/runtime-server'
import App from './App'

export async function handler(req: Request): Promise<Response> {
  const html = await renderToString(<App />)
  return new Response(html, {
    headers: { 'Content-Type': 'text/html' },
  })
}
```

For production, build client and server bundles separately:

```bash
vite build                                                  # client bundle
vite build --ssr src/entry-server.ts --outDir dist/server   # server bundle
```

## API

### `pyreonPlugin(options?)`

Default export. Returns a Vite `Plugin`.

### Options

| Option      | Type     | Description                                         |
| ----------- | -------- | --------------------------------------------------- |
| `ssr.entry` | `string` | Server entry file path. Enables SSR dev middleware. |

## What It Does

- Configures `resolve.conditions: ["bun"]` so Vite resolves Pyreon workspace source files.
- Sets `esbuild.jsx` to `automatic` with `@pyreon/core` as the JSX import source.
- Transforms `.tsx`, `.jsx`, and `.pyreon` files through `@pyreon/compiler` for reactive JSX optimizations.
- In dev mode, auto-injects debug names into `signal()` calls so devtools show meaningful labels instead of "anonymous".
- In SSR mode, adds a catch-all middleware that renders pages through your server entry with full HMR support.
npm package: @pyreon/zero-cli
Description: CLI for Pyreon Zero — dev, build, preview
Author: Vit Bokisch
Latest version: 0.12.10

# @pyreon/zero-cli

Unified CLI for [Pyreon Zero](https://github.com/pyreon/zero) — development, builds, code quality, and project scaffolding.

## Install

```bash
bun add -D @pyreon/zero-cli
```

## Commands

### Development

```bash
zero dev [root]          # Start dev server (prints route table on startup)
  --port <port>          # Server port (default: 3000)
  --host [host]          # Server host (use --host for 0.0.0.0)
  --open                 # Open browser on start

zero build [root]        # Build for production
  --mode <mode>          # Rendering mode override (ssr, ssg, spa)

zero preview [root]      # Preview production build
  --port <port>          # Server port (default: 3000)
  --host [host]          # Server host
```

### Code Quality

```bash
zero doctor [root]       # Detect React patterns in codebase
  --fix                  # Auto-fix fixable issues (className → class, etc.)
  --json                 # Output as JSON
  --ci                   # CI mode — exit with code 1 on errors
```

### Project Context

```bash
zero context [root]      # Generate AI project context (.pyreon/context.json)
  --out <path>           # Custom output path
```

### Scaffolding

```bash
zero create <name>       # Scaffold a new Pyreon Zero project
```

## License

[MIT](LICENSE)
npm package: @pyriter/schwab-client
Description: Schwab Client
Author: Phong Vuong
Latest version: 0.4.6

# Charles Schwab Client for Nodejs

[![Patreon](https://img.shields.io/badge/Patreon-F96854?style=for-the-badge&logo=patreon&logoColor=white)](https://www.patreon.com/Pyriter)

## Overview

A Javascript client for the Charles Schwab Restful API written in Typescript for NodeJs.

## Features

1. Auto fetch refresh token when access token expires.
2. Credentials can be fetched and stored using these providers
    1. Local cache
    2. Local file
    3. Customizable (e.g. connect to datastore such as S3 or DynamoDB)
3. Get user account information
4. Get watchlist
5. Get option chain
6. Get quote
7. Manage orders
8. Get transactions
9. Get market hours
10. Get price history
11. Place/Replace order

## Install

```bash
$ npm install @pyriter/schwab-client
```

## Getting an Access Token

To gain access to the Schwab (TDA) APIs, you will need to get an access token from your trading account.

## How to use it

### Instantiate the SchwabClient object

At the bare minimum, you will need to provide an access token and client id and client secret in order to instantiate the schwabClient.

### Development setup for running tests

1. Create a credentials.json file at the package root level with the following information:
```json
{
  "client_id": "",
  "client_secret": "",
  "redirect_uri": "http://localhost/"
}
```
2. Run the script to generate the login url
```bash
node ./generateAuthUrl.js
```
3. Open the url provided from the output of step #2 in a browser and login to Schwab.
4. After logging in and agreeing to the terms. You will then get to a redirect to `localhost` with the code as part of the query params. Copy this url link in its entirety.
5. Within the terminal run the script to generate the auth token
```bash
node ./extractAuthCode.js [paste-your-url-from-step-4-here]
```
6. Run the tests
```bash
npm tests
```
### Publishing to npm

This command will update the package version and then publish to the public npm repo

```bash
$ npm version [patch | minor major]
$ npm publish
```

## Appendix


## License

Schwab Client is [MIT licensed](./LICENSE).
npm package: @pyrocancode/react-native-app-icon-changer
Description: Alternate app icons for React Native (iOS & Android). TurboModule / New Architecture (RN 0.76+). Fork of FerhatAdibelli0/react-native-app-icon-changer.
Author: pyrocancode
Latest version: 1.5.0

# react-native-app-icon-changer (pyrocancode fork)

TurboModule / New Architecture build of dynamic app icon switching for React Native 0.76+.

- **Этот репозиторий:** [pyrocancode/react-native-app-icon-changer](https://github.com/pyrocancode/react-native-app-icon-changer)
- **Upstream:** [FerhatAdibelli0/react-native-app-icon-changer](https://github.com/FerhatAdibelli0/react-native-app-icon-changer) (исходная реализация; в апстриме долго не было обновлений под New Architecture).
- **Изменения в форке:** Codegen spec (`NativeAppIconChanger`), Android `build.gradle` под актуальный RN (`com.facebook.react` + блок `react { }`), iOS `<NativeAppIconChangerSpec>` + `NativeAppIconChangerSpecJSI`.

JS API без изменений: `setIcon`, `getActiveIcon`, `getAllAlternativeIcons`, `resetIcon`. Имя нативного модуля — **`DynamicIconManager`**.

## Installation

Из npm (форк под New Architecture):

```sh
npm install @pyrocancode/react-native-app-icon-changer
```

Или из GitHub:

```sh
npm install github:pyrocancode/react-native-app-icon-changer
```

Оригинальный пакет без scoped-имени (`react-native-app-icon-changer` на npm) — это [upstream](https://www.npmjs.com/package/react-native-app-icon-changer); этот репозиторий публикуется как `@pyrocancode/react-native-app-icon-changer`.

Настройка альтернативных иконок в **Info.plist** (iOS) и **AndroidManifest** (activity aliases) — как в [README upstream](https://github.com/FerhatAdibelli0/react-native-app-icon-changer#readme).

## License

[MIT](LICENSE).
npm package: @pyrocancode/react-native-vpn-detector
Description: React Native module to detect VPN connection
Latest version: 0.1.6

# 🌐 react-native-vpn-detector

**React Native module to detect VPN connection**

## 📦 Installation

Install the package with npm or yarn:

```bash
npm install @pyrocancode/react-native-vpn-detector
# or
yarn add @pyrocancode/react-native-vpn-detector
```

On React Native 0.60+ автолинковка должна сработать автоматически. После установки не забудьте пересобрать приложение:

- **iOS**: `cd ios && pod install && cd ..`
- **Android**: обычная сборка/запуск (`gradlew assemble` или через `npx react-native run-android`).

## ⚠️ Note

The VPN detector does not work reliably on simulators. Please test on a real device (both Android and iOS). 

## 🚀 Usage

### 🧩 `useIsVpnActive`

The `useIsVpnActive` hook lets your component reactively track whether a VPN connection is active.

```javascript
import React from "react";
import { View, Text } from "react-native";
import { useIsVpnActive } from "@pyrocancode/react-native-vpn-detector";

const App = () => {
  const isVpnActive = useIsVpnActive();

  return (
    <View>
      <Text>VPN is {isVpnActive ? "active" : "inactive"}</Text>
    </View>
  );
};
```

### 🔍 `isVpnActive`

The `isVpnActive` function checks if a VPN connection is active (one-time check).

```javascript
import React, { useEffect, useState } from "react";
import { View, Text } from "react-native";
import { isVpnActive } from "@pyrocancode/react-native-vpn-detector";

const App = () => {
  const [value, setValue] = useState(null);

  useEffect(() => {
    isVpnActive().then(setValue).catch(() => setValue(false));
  }, []);

  return (
    <View>
      <Text>VPN is {value ? "active" : "inactive"}</Text>
    </View>
  );
};
```

### 📡 `addEventListener`

The `addEventListener` function listens for changes in the VPN connection status using a lightweight polling under the hood.

```javascript
import React, { useEffect } from "react";
import { View, Text } from "react-native";
import { addEventListener } from "@pyrocancode/react-native-vpn-detector";

const App = () => {
  useEffect(() => {
    const unsubscribe = addEventListener((isVpnActive) => {
      console.log(`VPN is now ${isVpnActive ? "active" : "inactive"}`);
    });

    return () => {
      unsubscribe();
    };
  }, []);

  return (
    <View>
      <Text>Listening for VPN status changes...</Text>
    </View>
  );
};
```

## 🤝 Contributing

Contributions are welcome! Please open an issue or submit a pull request for any bugs or enhancements.

## 📜 License

This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more information.