Dark Mode

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

tasteee/datass

Repository files navigation

React stores. Local and global. DX foxused API. TypeScript first. Simple as hell. Capable as fuck.

npm add datass

Let's do it.

Global Stores

state.toUpperCase()) // 'FOO' const $bool = datass.boolean(true) $bool.set(false) $bool.state // false $bool.toggle() $bool.state // true $bool.set.reset() $bool.state // true $bool.use() // true $bool.use((state) => typeof value) // 'boolean' const $arr = datass.array([0, 1, 2]) $arr.set([10, 11, 12]) $arr.state // [10, 11, 12] $arr.set.append(13) $arr.state // [10, 11, 12, 13] $arr.set.prepend(9) $arr.state // [9, 10, 11, 12, 13] $arr.set.append(1, 2) // append or prepend multiple $arr.state // [9, 10, 11, 12, 13, 1, 2] $arr.set.reset() $arr.state // [0, 1, 2] $arr.set.lookup(3, 3) // state[3] = 3 $arr.use() // [0, 1, 2, 3] $arr.use((state) => state.reverse()[0]) // 2 $arr.use.find((value) => value > 1) // 2 $arr.use.filter((value) => value > 0) // [1, 2] $arr.use.map((arr) => arr > 0) // [false, true, true] type MyObjectT = { name: string; age?: number; numbers?: number[] } const $obj = datass.object({ name: 'tasteink' }) // NOTE: For object stores, builds the next state // by merging the object you provide into the existing // state object. To fully replace the existing state, // reach for `yourStore.set.replace({ ... })` $obj.set({ age: 123 }) $obj.set.reset() $obj.set.replace({ name: 'rokki', numbers: [0, 1, 2] }) $obj.set.lookup('name', 'tasteink') $obj.set.lookup('numbers.2', 99) $obj.use() // { name: 'tasteink', numbers: [0, 1, 99 ]} $obj.use((state) => state.name) // 'tasteink' $obj.use.lookup('name') // 'tasteink' $obj.use.lookup('numbers.2') // 99">const $num = datass.number(100)

$num.set(200)
$num.state // 200
$num.set.add(50)
$num.state // 250
$num.set.subtract(25)
$num.state // 225
$num.set.reset()
$num.state // 100
$num.use() // 100
$num.use((state) => state * 10) // 1000

const $str = datass.string('foo')

$str.set('bar')
$str.state // 'bar'
$str.set.reset()
$str.state // 'foo'
$str.use() // 'foo'
$str.use((state) => state.toUpperCase()) // 'FOO'

const $bool = datass.boolean(true)

$bool.set(false)
$bool.state // false
$bool.toggle()
$bool.state // true
$bool.set.reset()
$bool.state // true
$bool.use() // true
$bool.use((state) => typeof value) // 'boolean'

const $arr = datass.array<number>([0, 1, 2])

$arr.set([10, 11, 12])
$arr.state // [10, 11, 12]
$arr.set.append(13)
$arr.state // [10, 11, 12, 13]
$arr.set.prepend(9)
$arr.state // [9, 10, 11, 12, 13]
$arr.set.append(1, 2) // append or prepend multiple
$arr.state // [9, 10, 11, 12, 13, 1, 2]
$arr.set.reset()
$arr.state // [0, 1, 2]
$arr.set.lookup(3, 3) // state[3] = 3
$arr.use() // [0, 1, 2, 3]
$arr.use((state) => state.reverse()[0]) // 2
$arr.use.find((value) => value > 1) // 2
$arr.use.filter((value) => value > 0) // [1, 2]
$arr.use.map((arr) => arr > 0) // [false, true, true]

type MyObjectT = { name: string; age?: number; numbers?: number[] }
const $obj = datass.object<MyObjectT>({ name: 'tasteink' })

// NOTE: For object stores, builds the next state
// by merging the object you provide into the existing
// state object. To fully replace the existing state,
// reach for `yourStore.set.replace({ ... })`

$obj.set({ age: 123 })
$obj.set.reset()
$obj.set.replace({ name: 'rokki', numbers: [0, 1, 2] })
$obj.set.lookup('name', 'tasteink')
$obj.set.lookup('numbers.2', 99)
$obj.use() // { name: 'tasteink', numbers: [0, 1, 99 ]}
$obj.use((state) => state.name) // 'tasteink'
$obj.use.lookup('name') // 'tasteink'
$obj.use.lookup('numbers.2') // 99

Local Stores

{ const num = useDatass.number(250) const str = useDatass.string('hello') const bool = useDatass.boolean(false) const arr = useDatass.array([0, 99, 122]) const obj = useDatass.object({ foo: 'bar' }) // These stores have the exact same APIs // except you do not .use() them. const handleSomething = () => { num.set(120) num.add(10) num.state // 130 str.set(str.state.toUpperCase()) str.state // 'HELLO' bool.toggle() bool.state // true arr.set.append(222) arr.set.prepend(123) arr.set.lookup('1', 55) arr.state // [123, 55, 99, 122, 222] obj.set({ ...etc }) // it is all the same! } }">import { useDatass } from 'datass'

const Component = () => {
const num = useDatass.number(250)
const str = useDatass.string('hello')
const bool = useDatass.boolean(false)
const arr = useDatass.array([0, 99, 122])
const obj = useDatass.object({ foo: 'bar' })

// These stores have the exact same APIs
// except you do not .use() them.
const handleSomething = () => {
num.set(120)
num.add(10)
num.state // 130
str.set(str.state.toUpperCase())
str.state // 'HELLO'
bool.toggle()
bool.state // true
arr.set.append(222)
arr.set.prepend(123)
arr.set.lookup('1', 55)
arr.state // [123, 55, 99, 122, 222]
obj.set({ ...etc }) // it is all the same!
}
}

Immer-powered Object Store Updates

{ draft.name = draft.name.toUpperCase() draft.age += 1 draft.skills.push('datass') })">const $user = datass.object({
name: 'Brooklyn',
age: 30,
skills: ['JavaScript', 'React']
})

$user.set.by((draft) => {
draft.name = draft.name.toUpperCase()
draft.age += 1
draft.skills.push('datass')
})

Async Updates

const $users = datass.array([])

// Load users asynchronously:
async function fetchUsers() {
await $users.set.byAsync(async () => {
const response = await fetch('https://api.example.com/users')
const data = await response.json()
return data // Directly return new state
})
}

Middleware

Custom Middleware

// Create a logging middleware:
const loggingMiddleware = (store) => {
const originalSet = store.set

store.set = (...args) => {
console.log(`Setting store state`, args)
return originalSet(...args)
}

return store
}

// Apply middleware:
const ss = datass.withMiddleware(loggingMiddleware)
const $settings = ss.object({ theme: 'light', notifications: true })

undoRedo middleware

import { datass } from 'datass'

const undoRedoMiddleware = datass.middleware.undoRedo({ maxHistory: 50 })
const enhancedDatass = datass.withMiddleware(undoRedoMiddleware)
const $myStore = enhancedDatass.array([0, 5, 10])
$myStore.set.append(15)
$myStore.set.undo()
$myStore.set.redo()

TODO

  • Improve documentation on custom middleware.

About

datass is great

Resources

Readme

License

MIT license

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

Packages

Contributors