npm package: @mappoh/nova
Description: Nova — a lightweight web engine built on Web Components
Author: mappoh
Latest version: 0.19.0

# Nova

A lightweight web engine built on Web Components. Zero dependencies.

```
npm install @mappoh/nova
```

## Modules

### Core

| Module | Import | Description |
|--------|--------|-------------|
| Component | `@mappoh/nova/component` | Web Components base class with generic typed state (`Component<S>`), ES2022 class field support, reactive props, lifecycle hooks, and template engine |
| Router | `@mappoh/nova/router` | SPA router with path params, guards, layouts, loaders, and view transitions |
| Store | `@mappoh/nova/store` | Reactive signals, computed values, effects, and batched updates |
| Theme | `@mappoh/nova/theme` | CSS custom property management with dark/light mode switching |

### Component Utilities

All utilities auto-cleanup when the component disconnects.

```ts
import {
  classMap, styleMap,     // template helpers
  createRef,              // DOM refs
  useComputed,            // memoization
  useInterval,            // non-pausing interval
  useScroll,              // Shadow DOM scroll fix
  afterRender,            // post-paint callback
  createPortal, usePortal,// render outside shadow root
  slotStyles,             // deep slot styling
} from '@mappoh/nova/component';
```

| Utility | Description |
|---------|-------------|
| `classMap({ active: true })` | Build class strings from boolean maps |
| `styleMap({ fontSize: 16 })` | Build style strings with auto `px` and kebab-case |
| `createRef()` | DOM element ref that survives re-renders |
| `useComputed(this, fn, deps)` | Memoize expensive render calculations |
| `useInterval(this, fn, ms)` | Interval that keeps running when tab is hidden |
| `useScroll(this, selector)` | Fix wheel events for Shadow DOM scroll containers |
| `afterRender(this, fn)` | Callback after browser paint (via rAF) |
| `this.on(event, selector, handler)` | Declarative event delegation with auto-cleanup |
| `createPortal(content)` | Render outside shadow root (tooltips, dropdowns) |
| `slotStyles(this, css)` | Deep slot styling beyond `::slotted()` |
| `useClickOutside(this, fn)` | Detect clicks outside component (Shadow DOM–aware) |
| `useResize(this, fn)` | ResizeObserver with auto-cleanup |
| `usePatch(this, selector, fn)` | Surgical text node update without re-render |

### Component Static Flags

```ts
class MyComponent extends Component {
  static tag = 'my-component';
  static scrollFix = true;     // auto-fix wheel events in Shadow DOM
  static debugRender = true;   // log render triggers to console
}
```

### Template Bindings

The `html` tagged template supports declarative bindings:

```ts
render() {
  return html`
    <input
      type="text"
      value=${this.name}
      .value=${this.name}
      class=${classMap({ active: this.isActive })}
      @input=${(e: Event) => this.name = (e.target as HTMLInputElement).value}
      @keydown=${this._onKey}
      ref=${this.inputRef}
    />
    <button @click=${() => this.save()}>Save</button>
  `;
}
```

| Syntax | Description |
|--------|-------------|
| `attr=${value}` | Set HTML attribute (strings, numbers, booleans) |
| `.prop=${value}` | Set DOM property directly (bypasses attribute) |
| `@event=${handler}` | Declarative event listener — re-bound efficiently on each render |
| `ref=${createRef()}` | Capture DOM element reference |
| `class=${classMap({})}` | Conditional class strings |
| `style=${styleMap({})}` | Conditional style strings |

Event handlers (`@click`, `@input`, etc.) are automatically managed by the template engine — they are added on first render and updated in place on re-renders without creating duplicate listeners. For delegation across many similar elements, use `this.on(event, selector, handler)` instead.

### Data & State

| Module | Import | Description |
|--------|--------|-------------|
| Query | `@mappoh/nova/query` | SWR-style data fetching with stale-while-revalidate and tag-based invalidation |
| Idempotent | `@mappoh/nova/query/idempotent` | Ensures identical operations execute once within a TTL window |
| Query Pagination | `@mappoh/nova/query/pagination` | Offset-based pagination with fetch integration and deduplication |
| State Machine | `@mappoh/nova/machine` | Finite state machine with enter/exit actions |
| WebSocket | `@mappoh/nova/websocket` | Reconnecting WebSocket with heartbeat and backoff |
| Event Bus | `@mappoh/nova/event-bus` | Typed publish/subscribe |
| Cache | `@mappoh/nova/cache` | LRU cache with optional TTL |
| Context | `@mappoh/nova/context` | Dependency injection via DOM events |
| HTTP | `@mappoh/nova/http` | Fetch wrapper with interceptors, retries, timeout |
| Persistent State | `@mappoh/nova/persistent-state` | IndexedDB-backed persistent store |
| IndexedDB Store | `@mappoh/nova/state/idb` | IndexedDB persistence adapter with field filtering and validation |
| Offline Query | `@mappoh/nova/query/offline` | Offline-aware SWR query with auto-retry on reconnection |
| Convex | `@mappoh/nova/convex` | Reactive Convex query subscriptions with synchronous cache delivery |

### UI Components

| Component | Import | Description |
|-----------|--------|-------------|
| Modal | `@mappoh/nova/modal` | Accessible dialog with focus trap and scroll lock |
| Toast | `@mappoh/nova/toast` | Notification toasts with auto-dismiss |
| Tooltip | `@mappoh/nova/tooltip` | Positioned tooltips with flip/shift |
| Popover | `@mappoh/nova/popover` | Positioned popovers with click/hover/focus triggers |
| Dropdown | `@mappoh/nova/dropdown` | Accessible dropdown menu |
| Accordion | `@mappoh/nova/accordion` | Collapsible panels with ARIA |
| Tabs | `@mappoh/nova/tabs` | Tab panel switcher with keyboard nav |
| Stepper | `@mappoh/nova/stepper` | Multi-step wizard with validation |
| Carousel | `@mappoh/nova/carousel` | CSS scroll-snap carousel with drag |
| Pagination | `@mappoh/nova/pagination` | Page navigation with ellipsis |
| Switch | `@mappoh/nova/switch` | Toggle switch |
| Radio Group | `@mappoh/nova/radio-group` | Radio group with roving tabindex |
| Slider | `@mappoh/nova/slider` | Custom slider with pointer drag |
| Rating | `@mappoh/nova/rating` | Star rating |
| Alert | `@mappoh/nova/alert` | Alert/banner with variants |
| Badge | `@mappoh/nova/badge` | Inline badge |
| Avatar | `@mappoh/nova/avatar` | Image with initials fallback |
| Progress | `@mappoh/nova/progress` | Linear and circular progress bars |
| Skeleton | `@mappoh/nova/skeleton` | Shimmer loading placeholder |
| Spinner | `@mappoh/nova/spinner` | Loading spinner |
| Breadcrumb | `@mappoh/nova/breadcrumb` | Navigation breadcrumbs |
| Command Palette | `@mappoh/nova/command-palette` | Cmd+K searchable command overlay with custom positioning |
| Editor | `@mappoh/nova/editor` | Markdown editor with split/write/preview modes |
| Navbar | `@mappoh/nova/navbar` | Responsive navbar with hamburger menu, mobile drawer, `drawerClass`, and rich content cloning |
| Notification Center | `@mappoh/nova/notification-center` | Notification drawer with badge count |
| Bottom Sheet | `@mappoh/nova/bottom-sheet` | Mobile-first slide-up overlay with snap points and drag-to-dismiss |
| Toolbar | `@mappoh/nova/toolbar` | Premium action bar with overflow, roving tabindex, responsive sizing |
| Button | `@mappoh/nova/button` | Styled button with variants, loading state, and spring press animation |
| Input | `@mappoh/nova/input` | Text input with label, helper text, error state, and icons |
| Textarea | `@mappoh/nova/textarea` | Multi-line input with auto-resize and character counter |
| Select | `@mappoh/nova/select` | Custom dropdown select with search, keyboard nav, and option groups |
| Checkbox | `@mappoh/nova/checkbox` | Animated checkbox with indeterminate state and label |
| Link | `@mappoh/nova/link` | Styled anchor with underline variants and external indicator |
| Card | `@mappoh/nova/card` | Content card with header/body/footer, tilt interaction, and elevation |
| Divider | `@mappoh/nova/divider` | Horizontal/vertical divider with label support |
| Text | `@mappoh/nova/text` | Typography primitive with semantic scale and truncation |
| Tag | `@mappoh/nova/tag` | Inline tag/chip with color variants and dismiss |
| Kbd | `@mappoh/nova/kbd` | Keyboard shortcut display with platform-aware symbols |
| Stat | `@mappoh/nova/stat` | Statistic display with label, value, and trend indicator |
| Empty State | `@mappoh/nova/empty-state` | Empty content placeholder with icon, text, and action |
| Dialog | `@mappoh/nova/dialog` | Native dialog modal with confirm/alert variants and `DialogHandle` for external cleanup |
| Segmented Control | `@mappoh/nova/segmented-control` | Animated tablist with sliding indicator |
| Drawer | `@mappoh/nova/drawer` | Slide-in side panel with left/right placement |
| Banner | `@mappoh/nova/banner` | Full-width notification bar with variants and dismiss |
| Callout | `@mappoh/nova/callout` | Highlighted content block with collapsible mode |
| List | `@mappoh/nova/list` | Interactive list with selection and keyboard nav |
| Meter | `@mappoh/nova/meter` | Value meter with threshold colors and animated fill |
| Chart | `@mappoh/nova/chart` | Bar, line, pie/donut charts with SVG rendering and CSS animations |
| Combobox | `@mappoh/nova/combobox` | Searchable combobox with single/multi-select and keyboard nav |
| Data Table | `@mappoh/nova/data-table` | Sortable, paginated data table with selection |
| Date Picker | `@mappoh/nova/date-picker` | Calendar date picker with locale support |
| Color Picker | `@mappoh/nova/color-picker` | Canvas color picker with hex/RGB/HSL input |
| File Upload | `@mappoh/nova/file-upload` | Drag-and-drop file upload with validation |
| Tree View | `@mappoh/nova/tree-view` | Hierarchical tree with expand/collapse and checkboxes |

### Layout

| Component | Import | Description |
|-----------|--------|-------------|
| Stack | `@mappoh/nova/layout` | Vertical/horizontal flex layout with gap control |
| Grid | `@mappoh/nova/layout` | Responsive CSS Grid with auto-fit or explicit columns |
| Cluster | `@mappoh/nova/layout` | Inline flex for wrapping groups (tags, buttons, chips) |

### Forms

| Module | Import | Description |
|--------|--------|-------------|
| Form Engine | `@mappoh/nova/forms` | Schema-driven forms with validation, touched/dirty tracking, and micro-interactions (`shake`, `checkmark`, `pulse`, `formFx`) |
| WASM Validators | `@mappoh/nova/forms/wasm-validators` | Email, URL, credit card, IBAN validation (WASM + TS fallback) |

### Animation & Canvas

| Module | Import | Description |
|--------|--------|-------------|
| Spring | `@mappoh/nova/animation/spring` | Physics-based spring animation |
| Stagger | `@mappoh/nova/animation/stagger` | Staggered animations across element arrays |
| FLIP | `@mappoh/nova/animation/flip` | First-Last-Invert-Play layout transitions |
| Scroll Animate | `@mappoh/nova/animation/scroll-animate` | CSS `animation-timeline` with fallback |
| Parallax | `@mappoh/nova/animation/parallax` | Scroll-driven parallax layers |
| Text Reveal | `@mappoh/nova/text-reveal` | Staggered word/line entrance |
| Particles | `@mappoh/nova/canvas/particles` | 2D particle system |
| Dot Grid | `@mappoh/nova/canvas/dot-grid` | Interactive dot grid |
| Noise | `@mappoh/nova/canvas/noise` | Simplex/Perlin noise rendering |
| Virtual List | `@mappoh/nova/virtual-list` | DOM-recycling virtual scroller |

### i18n

| Module | Import | Description |
|--------|--------|-------------|
| i18n | `@mappoh/nova/i18n` | Reactive i18n with ICU pluralization, `formatNumber`, `formatDate`, `formatRelative` |

### Utilities

| Module | Import | Description |
|--------|--------|-------------|
| Utils | `@mappoh/nova/utils` | `debounce`, `throttle`, `deepEqual`, `clamp`, `lerp`, `remap`, `uniqueId`, `isBrowser`, `isMac`, `isTouch`, `backoffDelay`, `wait` |
| A11y | `@mappoh/nova/a11y` | `trapFocus`, `rovingTabIndex`, `announce`, `skipLink` |
| Clipboard | `@mappoh/nova/clipboard` | Copy/read text and HTML |
| Search | `@mappoh/nova/search` | Full-text search with WASM fuzzy matching, themeable via CSS custom properties, headless `createSearchEngine()` for custom UIs |
| Gesture | `@mappoh/nova/gesture` | Swipe, pinch, pan, long-press, tap with Pointer Events |
| Drag | `@mappoh/nova/drag` | Sortable lists with keyboard support |
| Responsive | `@mappoh/nova/responsive` | Breakpoint hooks, container queries, responsive CSS utilities |
| Shortcuts | `@mappoh/nova/shortcuts` | Keyboard shortcut registry |
| Lazy Load | `@mappoh/nova/lazy` | IntersectionObserver lazy loading |
| Infinite Scroll | `@mappoh/nova/infinite-scroll` | Infinite scroll loading |
| Scale | `@mappoh/nova/theme` | Mathematical type scale via CSS custom properties |
| Service Worker | `@mappoh/nova/sw` | SW generation with caching strategies |
| SW Cache | `@mappoh/nova/sw/cache` | Runtime cache management from main thread |
| Devtools | `@mappoh/nova/devtools` | Component inspector and render debugging |

### WASM Bridge

| Module | Import | Description |
|--------|--------|-------------|
| Worker Pool | `@mappoh/nova/wasm` | Web Worker pool for offloading WASM ops off the main thread |
| Shared Buffer | `@mappoh/nova/wasm` | Zero-copy SharedArrayBuffer data sharing between JS and WASM workers |
| Streaming Compile | `@mappoh/nova/wasm` | `compileStreaming` with module caching and `precompileWasm` |

### WASM Accelerators

Optional Rust-compiled modules. Each has a pure TypeScript fallback.

| Module | Import | Description |
|--------|--------|-------------|
| Markdown | `@mappoh/nova/markdown/wasm` | CommonMark + GFM parser |
| Noise | `@mappoh/nova/canvas/noise-wasm` | Batch noise with FBM |
| Validation | `@mappoh/nova/forms/wasm-validators` | Email, credit card, IBAN, password strength |
| Image | `@mappoh/nova/image/wasm` | Grayscale, blur, sharpen, crop, rotate, resize |
| Physics | `@mappoh/nova/canvas/physics-wasm` | 2D particle dynamics |
| Crypto | `@mappoh/nova/security/wasm-crypto` | Argon2id, bcrypt, PBKDF2-SHA256 |
| Diff | `@mappoh/nova/component/diff-wasm` | LIS-based keyed list reconciliation |

### SSR

| Module | Import | Description |
|--------|--------|-------------|
| SSR | `@mappoh/nova/ssr` | Declarative Shadow DOM rendering, `renderToString`, `renderComponent`, `renderPage`, `renderWithMarkers`, hydration |
| Hydration | `@mappoh/nova/component` | `hydrateTemplate()` — adoptive hydration that wakes up SSR DOM with live bindings |

### Testing

| Module | Import | Description |
|--------|--------|-------------|
| Test | `@mappoh/nova/test` | `mount`, `simulate`, `flush`, `shadowSnapshot`, `shadowHTML`, `withMount`, prop/state helpers |

## Quick Start

```ts
import { Component, html, classMap, createRef } from '@mappoh/nova/component';
import { createNovaStore } from '@mappoh/nova/store';

const { signal } = createNovaStore();
const count = signal(0);

class Counter extends Component {
  static tag = 'my-counter';
  static styles = `
    button { padding: 8px 16px; border-radius: 6px; background: #333; color: #fff; }
    .active { background: #0066ff; }
  `;

  private ref = createRef<HTMLButtonElement>();

  render() {
    const value = count();
    return html`
      <button
        ref=${this.ref}
        class=${classMap({ active: value > 0 })}
        @click=${() => count.update(n => n + 1)}
      >
        Count: ${value}
      </button>
    `;
  }
}

Counter.define();
```

See [CHANGELOG.md](./CHANGELOG.md) for release notes.