npm package: @lum-js/core
Description: Tiny JS framework.
Author: asboy2035
Latest version: 0.0.1

<img src="/images/Lum-Icon.png" width="256" alt="LümJS Icon">

# LümJS Core - ALPHA
A lightweight, reactive state management framework for vanilla TypeScript with strict typing and few dependencies.
Designed to get you from 0 to MVP as quickly as possible.
Want to make a fully production-ready future-proof application?
Use [Vue](https://vuejs.org) instead.

## Features
- **Reactive State Management** - Automatic UI updates when state changes
- **Strict TypeScript** - Full type safety with custom types
- **Near-Zero Dependencies** - Lightweight and small bundles
- **Template Interpolation** - `{{ variable }}` syntax in HTML
- **Directives** - `lum-value`, `lum-model`, `lum-if`, `lum-show`, `lum-class`, `lum-attr`
- **Computed States** - Derive values from other states
- **Watchers** - React to multiple state changes
- **Utilities** - Debounce, throttle, deep clone, and more

## Installation
```bash
npm i @lumjs/core
```

## Quick Start
Check out the [counter example](https://github.com/lumjs/counter).

## Directives
### `lum-value`
Binds state value to element text content (one-way).

```html
<p lum-value="count"></p>
```

### `lum-model`
Creates two-way binding with form inputs.

```html
<input lum-model="userName">
```

### `lum-if`
Conditionally renders element based on state truthiness.

```html
<div lum-if="isVisible">This shows when isVisible is true</div>
```

### `lum-show`
Toggles element display based on state.

```html
<div lum-show="isVisible">This hides with display:none</div>
```

### `lum-class`
Toggles CSS class based on state.

```html
<div lum-class="active">Gets 'active' class when state is true</div>
```

### `lum-attr`
Binds state to any HTML attribute.

```html
<img lum-attr="src" lum-value="imageUrl" alt="image">
```

## API Reference
### State Management
#### `state<T>(initialValue: T): State<T>`

Creates a reactive state.

```typescript
// Will be simplified in a future version
const counter = state(0, 'counter');
const user = state({ name: 'John', age: 30 }, 'user');
```

#### `computed<T>(computeFn: () => T, dependencies: State[]): State<T>`
Creates a computed state that automatically updates.

```typescript
const doubled = computed(() => counter.val * 2, [counter]);
```

### State Interface
```typescript
interface State<T> {
  val: T;  // Get or set value
  get(): T;  // Get current value
  set(newValue: T): void;  // Set new value
  subscribe(callback: (newValue: T, oldValue: T) => void): () => void;
}
```

### Registry Functions
```typescript
function registerState(name: string, state: State): void {}
function getStateByName(name: string): State | undefined {}
function unregisterState(name: string): void {}
function clearRegistry(): void {}
```

### Initialization
```typescript
// Usually not needed - framework auto-initializes!
function init(root?: HTMLElement): void {}  // Manually initialize if needed
function autoInit(): void {}  // Called automatically on import
function createApp(selector: string, setupFn: () => void): { mount: () => void } {}
```

The framework automatically:
1. Does NOT register names. Currently, you have to do it manually.
2. Initializes when the DOM is ready
3. Binds all directives and template interpolations

**You typically don't need to call anything** - just import `state` and create your states!

### Utilities

```typescript
function watch(states: State[], callback: () => void): () => void {}
function debounce<T>(fn: T, delay: number): T {}
function throttle<T>(fn: T, limit: number): T {}
function deepClone<T>(value: T): T {}
function deepEqual(a: any, b: any): boolean {}
function derive<T, U>(state: State<T>, transform: (value: T) => U): State<U> {}
function logState(name: string, state: State): void {}
```

## Configuration
```typescript
import { configure } from 'lumjs';

configure({
  debug: true,
  directivePrefix: 'lum-',
  interpolationStart: '{{',
  interpolationEnd: '}}'
});
```

## Advanced Examples (ALPHA)
### Computed State
```typescript
const firstName = state('John');
const lastName = state('Doe');

const fullName = computed(
  () => `${firstName.val} ${lastName.val}`,
  [firstName, lastName]
);
```

### Watchers
```typescript
const unwatch = watch([firstName, lastName], () => {
  console.log('Name changed!');
});

// Later: unwatch();
```

### Validation
```typescript
validateState(
  age,
  (value) => value >= 0 && value <= 120,
  'Age must be between 0 and 120'
);
```