# trian

> Trian is my experimental state management library for [React][react], heavily inspired by [Recoil][recoil].

Latest version **0.2.0** (published 2022-03-18) · MIT license · 0 weekly downloads

## Install

```sh
npm install trian
pnpm add trian
yarn add trian
bun add trian
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.2.0 |
| Published | 2022-03-18 |
| First published | 2020-08-04 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 52.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1 |
| Author | ryym |
| Maintainers | ryym |

## Links

- npm: https://www.npmjs.com/package/trian
- Repository: https://github.com/ryym/trian
- Homepage: https://github.com/ryym/trian#readme
- Issues: https://github.com/ryym/trian/issues
- npm.io page: https://npm.io/package/trian

## Recent versions

- 0.2.0 (latest) — 2022-03-18
- 0.1.0 — 2020-08-23
- 0.0.1 — 2020-08-04

## README

# Trian

Trian is my experimental state management library for [React][react], heavily inspired by [Recoil][recoil].

[react]: https://reactjs.org/
[recoil]: https://github.com/facebookexperimental/recoil

- Type Safe
- Distributed - No single state object
- Decoupled - No React Hook requirement for just running

## Motivation

- I like React Hooks, but I don't want to lock all the logic into Hooks.
    - Is it really a good practice to manage any states and effects by Hook? Even if they are UI-independent?
- Recoil seems good so I made a minimum version that suits my preference.

## Code Sample

### Play without React

```tsx
import { block, createStore, createDispatch, Thunk } from 'trian';

const Count = block({
    default: () => 0,
});

const Increment = (n: number = 1): Thunk => ({ update }) => {
  update(Count, (cnt) => cnt + n);
};

const store = createStore();

const dispatch = createDispatch(store);

console.log(store.getValue(Count)); //=> 0

dispatch(Increment);
console.log(store.getValue(Count)); //=> 1

dispatch(Increment, 20);
console.log(store.getValue(Count)); //=> 21
```

### Use with React

```typescript
import React from 'react';
import ReactDOM from 'react-dom';
import { block, createStore, TrianProvider, useValue, useDispatch, Thunk } from 'trian';

const Count = block({
  default: () => 0,
});

const Increment = (n: number = 1): Thunk => ({ update }) => {
  update(Count, (cnt) => cnt + n);
};

function Counter() {
  const count = useValue(Count);
  const dispatch = useDispatch();
  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => dispatch(Increment)}>Increment</button>
    </div>
  );
}

const store = createStore();

ReactDOM.render(
  <TrianProvider store={store}>
    <Counter />
  </TrianProvider>,
  document.getElementById('root')
);
```

```javascript
const store = createStore();

// FYI: You can customize the dispatcher.
// This maybe be useful for component testing.
const histories = [];
const dispatch = (action, ...args) => {
  histories.push({ action, args });
};
render(
  <TrianProvider store={store} dispatch={dispatch}>
    <Counter />
  </TrianProvider>
);

// FYI: You can change the state from outside of React components.
// This maybe be useful for component testing.
setTimeout(() => {
  store.setValue(Count, 100); //=> Update view
}, 1000);
```

- `useValue`, `useAsyncValue`
- `useBlock`
- `useSelector`, `useAsyncSelector`
- `useAction`
- `useDispatch`

---
_Source: https://npm.io/package/trian · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
