npm package: @neabyte/stateless-js
Description: A universal and lightweight state management library with a clean, stateless API
Author: NeaByteLab
Latest version: 0.4.0

# Stateless JS [![](https://img.shields.io/npm/v/@neabyte/stateless-js.svg)](https://www.npmjs.org/package/@neabyte/stateless-js) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Node.js CI](https://github.com/NeaByteLab/Stateless-JS/actions/workflows/ci.yaml/badge.svg)](https://github.com/NeaByteLab/Stateless-JS/actions/workflows/ci.yaml)

A universal and lightweight state management library with a clean, stateless API.

## 📦 Installation

```bash
# Universal
npm install @neabyte/stateless-js

# Angular (Automatic Reactivity)
npm install @neabyte/stateless-js @angular/core

# React (Automatic Re-renders)
npm install @neabyte/stateless-js react

# Svelte (Automatic Reactivity)
npm install @neabyte/stateless-js svelte

# Vue (Automatic Reactivity)
npm install @neabyte/stateless-js vue
```

## 🔧 Module Support

### 📋 NPM
```typescript
// CommonJS
const { createStateless, useStateless } = require('@neabyte/stateless-js')

// ESM (ES Modules)
import { createStateless, useStateless } from '@neabyte/stateless-js'

// Angular (Automatic Reactivity)
import { StatelessService, useAngularStateless } from '@neabyte/stateless-js/angular'

// React (Automatic Re-renders)
import { useReactStateless } from '@neabyte/stateless-js/react'

// Svelte (Automatic Reactivity)
import { useSvelteStateless } from '@neabyte/stateless-js/svelte'

// Vue (Automatic Reactivity)
import { useVueStateless } from '@neabyte/stateless-js/vue'

// TypeScript types
import type { StateSetter, StateValue } from '@neabyte/stateless-js'
```

### 🌐 Browser
```typescript
// CDN
<script src="https://unpkg.com/@neabyte/stateless-js/dist/index.mjs"></script>

// jsDelivr ESM
<script type="module">
  import { createStateless, useStateless } from 'https://cdn.jsdelivr.net/npm/@neabyte/stateless-js/dist/index.mjs'
</script>
```

---

## 🚀 Usage

### 📝 Universal Usage

```typescript
import { createStateless, useStateless } from '@neabyte/stateless-js'

// Create a new state
const [setCount, count] = createStateless('counter', 0)
console.log(count.value) // 0

// Update state
setCount(current => current + 1)
console.log(count.value) // 1
```

### 🔷 Angular Usage

```typescript
import { StatelessService, useAngularStateless } from '@neabyte/stateless-js/angular'

// Using the service approach
@Injectable({ providedIn: 'root' })
export class MyService {
  constructor(private stateless: StatelessService) {}
  counterState = this.stateless.useAngularStateless('counter', 0)
  count = this.counterState[1]
  setCount = this.counterState[0]
}

// Using the standalone function approach
export class MyComponent {
  counterState = useAngularStateless('counter', 0)
  count = this.counterState[1]
  setCount = this.counterState[0]
  increment = () => this.setCount(current => current + 1)
}
```

```typescript
// In your Angular component
@Component({
  template: `
    <div>
      <p>Count: {{ count() }}</p>
      <button (click)="increment()">Increment</button>
    </div>
  `
})
export class CounterComponent {
  counterState = useAngularStateless('counter', 0)
  count = this.counterState[1]
  setCount = this.counterState[0]
  increment = () => this.setCount(current => current + 1)
}
```

### ⚛️ React Usage

```typescript
import { useReactStateless } from '@neabyte/stateless-js/react'

function Counter() {
  const [setCount, count] = useReactStateless('counter', 0)
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(c => c + 1)}>
        Increment
      </button>
    </div>
  )
}
```


### 🟠 Svelte Usage

```typescript
import { useSvelteStateless } from '@neabyte/stateless-js/svelte'

// In your Svelte component
const [setCount, count] = useSvelteStateless('counter', 0)
const increment = () => setCount(current => current + 1)
```

```svelte
<!-- In your .svelte file -->
<script>
  import { useSvelteStateless } from '@neabyte/stateless-js/svelte'
  const [setCount, count] = useSvelteStateless('counter', 0)
  const increment = () => setCount(current => current + 1)
</script>
<div>
  <p>Count: {$count}</p>
  <button on:click={increment}>Increment</button>
</div>
```

### 🟢 Vue Usage

```typescript
import { useVueStateless } from '@neabyte/stateless-js/vue'

export default {
  name: 'Counter',
  setup() {
    const [setCount, countValue] = useVueStateless('counter', 0)
    const count = computed(() => countValue.value)
    const increment = () => {
      setCount(current => current + 1)
    }
    return {
      count,
      increment
    }
  }
}
```

### 🔄 State Sharing (Universal, React & Vue)

```typescript
// Universal
const [setUser, user] = createStateless('user', { name: 'John', age: 25 })
const [setUser2, user2] = useStateless('user', { name: 'Default', age: 0 })
console.log(user.value === user2.value) // true - same state

// React - Multiple components share the same state
function UserProfile() {
  const [setUser, user] = useReactStateless('user', { name: 'John', age: 25 })
  return <div>Name: {user.name}, Age: {user.age}</div>
}

function UserEditor() {
  const [setUser, user] = useReactStateless('user', { name: 'Default', age: 0 })
  return <button onClick={() => setUser(u => ({ ...u, age: u.age + 1 }))}>
    Increase Age
  </button>
}

// Vue - Multiple components share the same state
export default {
  name: 'UserProfile',
  setup() {
    const [setUser, userValue] = useVueStateless('user', { name: 'John', age: 25 })
    const user = computed(() => userValue.value)
    return { user }
  }
}

export default {
  name: 'UserEditor',
  setup() {
    const [setUser, userValue] = useVueStateless('user', { name: 'Default', age: 0 })
    const user = computed(() => userValue.value)
    const increaseAge = () => {
      setUser(u => ({ ...u, age: u.age + 1 }))
    }
    return { user, increaseAge }
  }
}
```

### 🎯 Different Data Types

```typescript
// Numbers
const [setNum, num] = createStateless('number', 42)

// Strings
const [setStr, str] = createStateless('string', 'hello')

// Objects
const [setObj, obj] = createStateless('object', { count: 0, items: [] })

// Arrays
const [setArr, arr] = createStateless('array', [1, 2, 3])

// Special values
const [setNaN, nan] = createStateless('nan', NaN)
const [setInf, inf] = createStateless('infinity', Infinity)
const [setSymbol, sym] = createStateless('symbol', Symbol('test'))
const [setBigInt, big] = createStateless('bigint', BigInt(123))
```

### 🔧 Object Updates

```typescript
// Universal
const [setData, data] = createStateless('data', { count: 0, items: [] })

// React
const [setData, data] = useReactStateless('react-data', { count: 0, items: [] })

// Vue
const [setData, dataRef] = useVueStateless('vue-data', { count: 0, items: [] })
const data = computed(() => dataRef.value)

// Immutable updates work the same way
setData(current => ({ ...current, count: current.count + 1 }))
setData(current => ({ ...current, items: [...current.items, 'new item'] }))
```

### 🧹 Memory Management

```typescript
const [setTemp, temp] = createStateless('temporary', 'data')

// Use the state...
console.log(temp.value)

// Clean up when done
temp.dispose()

// Accessing disposed state throws error
try {
  console.log(temp.value) // Error: State has been disposed
} catch (error) {
  console.log(error.message)
}
```

---

## 📚 API Reference

### Universal Functions

#### `createStateless<T>(id: StateId, initialState: T): StatelessReturn<T>`

Creates a new state with the given ID and initial value.

- `id`: Unique identifier (string or number)
- `initialState`: Initial value for the state
- Returns: Tuple `[StateSetter<T>, StateValue<T>]`

#### `useStateless<T>(id: StateId, fallbackState: T): StatelessReturn<T>`

Uses existing state if it exists, otherwise creates a new one.

- `id`: Unique identifier (string or number)
- `fallbackState`: Value to use if state doesn't exist
- Returns: Tuple `[StateSetter<T>, StateValue<T>]`

### Angular Functions

#### `StatelessService.useAngularStateless<T>(id: StateId, initialValue: T): [StateSetter<T>, Signal<T>]`

Angular service method that provides automatic reactivity using Angular signals.

- `id`: Unique identifier (string or number)
- `initialValue`: Initial value for the state
- Returns: Tuple `[StateSetter<T>, Signal<T>]` (Angular signal for reactivity)

#### `useAngularStateless<T>(id: StateId, initialValue: T): [StateSetter<T>, Signal<T>]`

Standalone Angular function that provides automatic reactivity using Angular signals.

- `id`: Unique identifier (string or number)
- `initialValue`: Initial value for the state
- Returns: Tuple `[StateSetter<T>, Signal<T>]` (Angular signal for reactivity)

### React Functions

#### `useReactStateless<T>(id: StateId, initialValue: T): [StateSetter<T>, T]`

React hook that provides automatic re-renders when state changes.

- `id`: Unique identifier (string or number)
- `initialValue`: Initial value for the state
- Returns: Tuple `[StateSetter<T>, T]` (direct value, not StateValue object)

### Svelte Functions

#### `useSvelteStateless<T>(id: StateId, initialValue: T): [StateSetter<T>, Writable<T>]`

Svelte function that provides automatic reactivity using Svelte stores.

- `id`: Unique identifier (string or number)
- `initialValue`: Initial value for the state
- Returns: Tuple `[StateSetter<T>, Writable<T>]` (Svelte writable store for reactivity)

### Vue Functions

#### `useVueStateless<T>(id: StateId, initialValue: T): [StateSetter<T>, Ref<T>]`

Vue composable that provides automatic reactivity when state changes.

- `id`: Unique identifier (string or number)
- `initialValue`: Initial value for the state
- Returns: Tuple `[StateSetter<T>, Ref<T>]` (reactive ref for Vue reactivity)

### Types

#### `StateSetter<T>`

Function to update state: `(updater: StateUpdater<T>) => void`

#### `StateValue<T>`

Object with:
- `value`: Current state value (readonly)
- `dispose()`: Method to clean up the state

---

## 📄 License

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