Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/farwayer/picofly
Lightweight state manager, simple, fast and built with ❤️
https://github.com/farwayer/picofly
pico proxy react react-native state state-management
Last synced: 3 months ago
JSON representation
Lightweight state manager, simple, fast and built with ❤️
- Host: GitHub
- URL: https://github.com/farwayer/picofly
- Owner: farwayer
- License: mit
- Created: 2023-03-18T12:57:00.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-09-03T13:34:04.000Z (4 months ago)
- Last Synced: 2024-10-03T15:37:08.167Z (3 months ago)
- Topics: pico, proxy, react, react-native, state, state-management
- Language: JavaScript
- Homepage:
- Size: 4.37 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Picofly
_Lightweight proxy-based state manager, simple, fast and built with ❤️_
[![NPM version](https://img.shields.io/npm/v/picofly.svg)](https://www.npmjs.com/package/picofly)
⚡ **Fast**: hand-crafted and optimized to be as fast as possible
🤏 **Tiny**: *514 bytes* in minimal config, *712 bytes* with React support
🥧 **Simple**: *~140 lines* of sparse code + *~70 lines* for React support
🍳 **Easy to use**: just modify data, magic will take care of the rest!
⚛️ **React & React Native**: *hooks* and *selectors*, uses modern React 18 API
🔋 **Charged**: *Map* support (*Set* in plans), *TypeScript* defs and more
🪟 **Transparent**: original objects are not modified## Why the hell another one?!
## How to use
### React example
#### store.js
```javascript
import {create, objMapIgnoreSpecialsRef, ref} from 'picofly'// may be not a class but a simple object
class State {
api = null
authToken = null
videos = new Map()get signedIn() {
return !!this.authToken
}
}export let createStore = () => {
let state = new State()
// see proxifiers section for options
let app = create(state, objMapIgnoreSpecialsRef)
// ref will prevent proxifing the api
app.api = ref(app, createApi())
return app
}
```#### app.js
```javascript
import {StoreProvider} from 'picofly/react'
import {createStore} from './store'
import VideoList from './video-list'let app = createStore()
let App = () => {
return (
)
}
```#### video-list.js
```javascript
// use with hookimport {memo} from 'react'
import {useStore} from 'picofly/react'
import Video from './video'export default memo(VideoList)
// will be re-rendered only when video added or removed
// because it uses video ids only but not videos data
function VideoList() {
let app = useStore()let ids = Array.from(app.videos.keys())
let videos = ids.map(id => )
let addVideo = useCallback(() => {
app.videos.set(Math.random(), {name: 'Cool video', watched: false})
})
return (
{videos}
ADD
)
}
```#### video.js
```javascript
// use with selectorsimport {useCallback} from 'react'
import {select} from 'picofly/react'// normally is in business logic
let watchVideo = async (app, id) => {
await app.api.watchVideo(id)let video = app.videos.get(id)
video.watched = true
}// selector
let video = (app, props) => ({
video: app.videos.get(props.id),
})// combine selectors and attach to component
// all props returned from selectors will be merged and passed to component
export default select(
video,
(app, props) => ({
// selectors are called in render context so you can use any hooks inside
onWatched: useCallback(() => watchVideo(app, props.id), [props.id]),
}),
)(Video)// will be re-rendered only if the video name changed
// because it only depends on it
function Video({
video = {},
onWatched,
}) {
return (
{video.name}
WATCH
)
}
```