npm package: @mxweb/react-provider
Description: A lightweight, type-safe React state management library inspired by Redux Toolkit's createSlice. Quickly create reusable Context Providers without repetitive boilerplate code.
Author: MXWeb Team
Latest version: 1.0.0

# @mxweb/react-provider

A lightweight, type-safe React state management library inspired by Redux Toolkit's `createSlice`, designed to quickly create reusable Context Providers without repetitive boilerplate code.

## 💡 Inspiration

This library takes inspiration from [@reduxjs/toolkit](https://redux-toolkit.js.org/)'s `createSlice` API, which provides a simple and intuitive way to define state and reducers. However, instead of using Redux, we wanted a solution that:

- ✨ **Works with React Context** - No additional Redux setup required
- 🚀 **Factory-based Provider creation** - Quickly create Providers for any part of your app
- 🔄 **Zero boilerplate** - No need to repeatedly write Provider, Context, and hooks
- 📦 **Lightweight** - Minimal dependencies, just React
- 🎯 **Type-safe** - Full TypeScript support with inferred types

The goal is to have a **Provider factory** that can be used anywhere in a project without repeating the Provider initialization process every time you need local state management.

## 📦 Installation

```bash
npm install @mxweb/react-provider
```

```bash
yarn add @mxweb/react-provider
```

```bash
pnpm add @mxweb/react-provider
```

## 🚀 Quick Start

### Basic Example

```tsx
import { createProvider, PayloadAction } from '@mxweb/react-provider';

// 1. Create your provider with createProvider (similar to Redux Toolkit's createSlice)
const { Provider, useProvider } = createProvider({
  name: 'Counter',
  initialState: {
    count: 0,
  },
  reducers: {
    increment: (state) => {
      state.count += 1;
    },
    decrement: (state) => {
      state.count -= 1;
    },
    incrementByAmount: (state, action: PayloadAction<number>) => {
      state.count += action.payload;
    },
  },
});

// 2. Wrap your component tree with the Provider
function App() {
  return (
    <Provider>
      <Counter />
    </Provider>
  );
}

// 3. Use the hook to access state and actions
function Counter() {
  const { count, increment, decrement, incrementByAmount } = useProvider();

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={increment}>+1</button>
      <button onClick={decrement}>-1</button>
      <button onClick={() => incrementByAmount(5)}>+5</button>
    </div>
  );
}
```

## 📚 Features

### 1. **Simple Provider Creation**

No need to manually create Context, Provider, and hooks. Everything is generated automatically:

```tsx
const { Provider, Consumer, useProvider } = createProvider({
  name: 'MyProvider',
  initialState: { /* ... */ },
  reducers: { /* ... */ },
});
```

### 2. **Redux Toolkit-like API**

Familiar API if you've used Redux Toolkit's `createSlice`:

```tsx
createProvider({
  name: 'Todo',
  initialState: {
    todos: [],
    filter: 'all',
  },
  reducers: {
    addTodo: (state, action: PayloadAction<string>) => {
      state.todos.push({ id: Date.now(), text: action.payload, completed: false });
    },
    toggleTodo: (state, action: PayloadAction<number>) => {
      const todo = state.todos.find(t => t.id === action.payload);
      if (todo) todo.completed = !todo.completed;
    },
    setFilter: (state, action: PayloadAction<'all' | 'active' | 'completed'>) => {
      state.filter = action.payload;
    },
  },
});
```

### 3. **Type-Safe**

Full TypeScript support with automatic type inference:

```tsx
const { useProvider } = createProvider({
  name: 'User',
  initialState: {
    name: '',
    age: 0,
  },
  reducers: {
    setName: (state, action: PayloadAction<string>) => {
      state.name = action.payload;
    },
  },
});

function Component() {
  const { name, age, setName } = useProvider();
  // ✅ name: string
  // ✅ age: number
  // ✅ setName: (payload: string) => void
}
```

### 4. **Initial State Override**

Pass initial state values as props to the Provider:

```tsx
<Provider count={10} max={100}>
  <Counter />
</Provider>
```

### 5. **Middleware Support**

Add middleware to intercept and modify actions:

```tsx
const logger = (api) => (next) => (action) => {
  console.log('Dispatching:', action);
  const result = next(action);
  console.log('Next state:', api.getState());
  return result;
};

createProvider({
  name: 'Counter',
  initialState: { count: 0 },
  reducers: { /* ... */ },
  middleware: [logger],
});
```

### 6. **Consumer Component**

Alternative render props pattern for accessing context:

```tsx
<Consumer>
  {({ count, increment }) => (
    <div>
      <p>{count}</p>
      <button onClick={increment}>+</button>
    </div>
  )}
</Consumer>
```

## ⚠️ Utility Functions

By default, this library uses basic implementations of `cloneDeep` and `isEqual` that work for simple use cases but have limitations (no circular reference handling, limited special object support, etc.).

**For production apps with complex data structures**, it's recommended to replace these with robust implementations like lodash before creating your providers:

```tsx
import { UTIL_FUNCTIONS } from '@mxweb/react-provider/create-slice';
import cloneDeep from 'lodash.clonedeep';
import isEqual from 'lodash.isequal';

// Replace utility functions with lodash
UTIL_FUNCTIONS.cloneDeep = cloneDeep;
UTIL_FUNCTIONS.isEqual = isEqual;

// Now create your providers
const CounterProvider = createProvider({ /* ... */ });
```

See the JSDoc comments in the source code for more details about the limitations of the default implementations.

## 🎯 Use Cases

This library is perfect for:

- 🎨 **Component-level state** - Modal dialogs, forms, wizards
- 🌳 **Feature-level state** - Shopping cart, user preferences, filters
- 📱 **Multiple instances** - Reusable components with independent state
- 🔧 **Quick prototyping** - Fast state management setup without Redux overhead

## 📖 API Reference

### `createProvider(options)`

Creates a Provider with state management capabilities.

**Parameters:**

- `options.name` (string) - Name of the provider (used for debugging)
- `options.initialState` (object | function) - Initial state or function that returns initial state
- `options.reducers` (object) - Map of reducer functions
- `options.middleware?` (array) - Optional middleware functions

**Returns:**

- `Provider` - React component to wrap your app/component tree
- `Consumer` - React component for render props pattern
- `useProvider` - Hook to access state and actions

### `PayloadAction<Payload, Type, Meta, Err>`

Type for actions with payload, metadata, and error information.

### `UTIL_FUNCTIONS`

Object containing utility functions (`cloneDeep`, `isEqual`) that can be replaced with more robust implementations.

## 🤝 Comparison with Redux Toolkit

| Feature | @mxweb/react-provider | Redux Toolkit |
|---------|----------------------|---------------|
| Learning curve | ⭐⭐ Low | ⭐⭐⭐⭐ Medium-High |
| Setup complexity | ⭐ Minimal | ⭐⭐⭐ Moderate |
| Bundle size | 📦 Very small | 📦 Larger |
| DevTools | ❌ No | ✅ Redux DevTools |
| Middleware ecosystem | ⚠️ Basic | ✅ Rich ecosystem |
| Time travel debugging | ❌ No | ✅ Yes |
| Use case | Local/Feature state | Global app state |

## 📝 Examples

Check out the [examples](./examples) directory for more use cases:

- Counter example
- Todo list
- Form management
- Nested providers

## 📄 License

MIT

## 🙏 Credits

Inspired by [@reduxjs/toolkit](https://redux-toolkit.js.org/) and the amazing work of the Redux team.

---

Made with ❤️ for developers who want simple, type-safe state management without the Redux ceremony.