
Research
/Security News
9 Malicious NuGet Packages Deliver Time-Delayed Destructive Payloads
Socket researchers discovered nine malicious NuGet packages that use time-delayed payloads to crash applications and corrupt industrial control systems.
A state management library for react inspired by vue 3.0 reactivity api and immer
A state management library for react inspired by vue 3.0 reactivity api and immer
costate is a tiny package that allows you to work with immutable state in a more reactive way.
npm install --save costate
yarn add costate
import createCostate, { watch } from 'costate'
// costate is reactive
const costate = createCostate({ a: 1 })
// state is immutable
watch(costate, state => {
console.log(`state.a is: ${state.a}`)
})
// mutate costate will emit the next immutable state to watcher
costate.a += 1
Think about costate + react-hooks!
import * as React from 'react'
import { co, useCostate } from 'costate'
function Counter() {
// useCostate instead of React.useState
// state is always immutable
let state = useCostate({ count: 0 })
let handleIncre = () => {
// pass state to co, then got the costate which is reactive
// mutate costate will cause re-render and receive the next state
co(state).count += 1
}
let handleDecre = () => {
co(state).count -= 1
}
return (
<>
<button onClick={handleIncre}>+1</button>
{state.count}
<button onClick={handleDecre}>-1</button>
</>
)
}
export default function App() {
// initialize todo-app state
let state = useCostate({
todos: [],
text: {
value: ''
}
})
useSessionStorage({
key: 'todos-json',
getter: () => state,
setter: source => Object.assign(co(state), source)
})
let handleAddTodo = () => {
if (!state.text.value) {
return alert('empty content')
}
// wrap by co before mutating
co(state).todos.push({
id: Date.now(),
content: state.text.value,
completed: false
})
co(state).text.value = ''
}
let handleKeyUp = event => {
if (event.key === 'Enter') {
handleAddTodo()
}
}
let handleToggleAll = () => {
let hasActiveItem = state.todos.some(todo => !todo.completed)
// wrap by co before mutating
co(state).todos.forEach(todo => {
todo.completed = hasActiveItem
})
}
return (
<>
<div>
<TodoInput text={state.text} onKeyUp={handleKeyUp} />
<button onClick={handleAddTodo}>add</button>
<button onClick={handleToggleAll}>toggle-all</button>
</div>
<Todos todos={state.todos} />
<Footer todos={state.todos} />
</>
)
}
function Todos({ todos }) {
return (
<ul>
{todos.map(todo => {
return <Todo key={todo.id} todo={todo} />
})}
</ul>
)
}
function Todo({ todo }) {
// you can create any costate you want
// be careful, costate must be object or array
let edit = useCostate({ value: false })
let text = useCostate({ value: '' })
let handleEdit = () => {
// wrap by co before mutating
co(edit).value = !edit.value
co(text).value = todo.content
}
let handleEdited = () => {
co(edit).value = false
// magic happen!!
// we don't need TodoApp to pass updateTodo function down to Todo
// we just like todo is local state, wrap by co before mutating it
// then it will cause TodoApp drived new state and re-render
co(todo).content = text.value
}
let handleKeyUp = event => {
if (event.key === 'Enter') {
handleEdited()
}
}
let handleRemove = () => {
// we don't need TodoApp to pass removeTodo function down to Todo
// cotodo can be delete by remove function
remove(co(todo))
}
let handleToggle = () => {
co(todo).completed = !todo.completed
}
return (
<li>
<button onClick={handleRemove}>remove</button>
<button onClick={handleToggle}>{todo.completed ? 'completed' : 'active'}</button>
{edit.value && <TodoInput text={text} onBlur={handleEdited} onKeyUp={handleKeyUp} />}
{!edit.value && <span onClick={handleEdit}>{todo.content}</span>}
</li>
)
}
function TodoInput({ text, ...props }) {
let handleChange = event => {
co(text).value = event.target.value
}
return <input type="text" {...props} onChange={handleChange} value={text.value} />
}
function Footer({ todos }) {
let activeItems = todos.filter(todo => !todo.completed)
let completedItems = todos.filter(todo => todo.completed)
let handleClearCompleted = () => {
;[...completedItems].reverse().forEach(item => remove(co(item)))
}
return (
<div>
{activeItems.length} item{activeItems.length > 1 && 's'} left |{' '}
{completedItems.length > 0 && <button onClick={handleClearCompleted}>Clear completed</button>}
</div>
)
}
createCostate(state) only accept object or array as arguemnt👤 Jade Gu
Contributions, issues and feature requests are welcome!
Feel free to check issues page.
Give a ⭐️ if this project helped you!
Copyright © 2019 Jade Gu.
This project is MIT licensed.
This README was generated with ❤️ by readme-md-generator
FAQs
A state management library for react inspired by vue 3.0 reactivity api and immer
We found that costate demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
Socket researchers discovered nine malicious NuGet packages that use time-delayed payloads to crash applications and corrupt industrial control systems.

Security News
Socket CTO Ahmad Nassri discusses why supply chain attacks now target developer machines and what AI means for the future of enterprise security.

Security News
Learn the essential steps every developer should take to stay secure on npm and reduce exposure to supply chain attacks.