revix
v1.2.0
Published
Manage variables with realms, scopes, and reasons.
Downloads
14
Readme
Revix
Manage variables with realms, scopes, and reasons.
import { openRealm, destroyRealm } from 'revix'
const { use } = openRealm('clock')
const [count, setCount, subsCount, destroyCount] = use('count', 0)
subsCount(({ before, after, reason }) => {
console.log(`Updated to ${after} from ${before} cause ${reason}`)
})
count() // 0
setCount(count()+1, 'updating test')
// Logging: Updated to 1 from 0 cause updating test
count() // 1
Why use Revix
?
Revix
is a JavaScript library that manages variables in units called realms. Revix
treats variables as plain objects with states, and allows you to subscribe to changes in variable values.
Revix
helps you to define the scope and dependency of variables clearly, track state changes easily, and improve the readability and maintainability of your code.
Manage realm
openRealm
(scope: any
)
Get or create a realm for this scope. If this realm has never been used before, it will create a new realm with this value. Otherwise, get an existing realm.
const { use, exists } = openRealm('realm name')
// or
const actor = new Actor()
const { use, exists } = openRealm(actor)
destroyRealm
(scope: any
)
Destroy the realm. All variables belonging to this realm are also destroyed.
Realm functions
use
(key: string
, initialValue: T
): [getter
, setter
, destroy
, subscribe
]
Get or create a variable manager for this realm. If this variable has never been created before, it will create a new variable with a initialValue
. Otherwise, get an existing variable manager.
const [name, setName, subsName, destroyName] = use('name', 'baba')
name() // baba
setName('keke', 'no reason')
name() // keke
subsName(({ before, after, reason }) => {
console.log(`The name variable did update from ${before} to ${after} because ${reason}`)
})
exists
(key: string
): boolean
Returns true
if a variable exists in the realm, or false
if not.
Variable manager functions
The variable manager is an array and each item is the same as the next,
[getter, setter, destroy, subscribe] = use(key, value)
getter
(): T
Get a value.
setter
(value: T
, reason?: string
): T
Set a value.
destroy
(reason?: string
): void
Destroy a variable.
WARNING! You can't use a same name of variable after destroyed. You should use this function when you are sure the variable will never be used again.
subscribe
(callback: ({ before: T
, after: T
, reason: string
}) => void
): Unsubscribe
You can register subscribe callbacks to watch this variable change. If the variable is changed, all subscribe callbacks will be called.
This function returns a new function that can be cancel unsubscribed. If you want, just call the returned function.
const unsubscribe = subscribe(({ before, after, reason }) => {
if (reason === 'destroy') {
unsubscribe()
}
})
With TypeScript
You can use strict variable types with TypeScript.
Just use the openRealm
function with the generic type.
Simple example
interface Member {
name: string
age: number
}
const { use } = openRealm<Member>(memberName)
const [name, setName] = use('name', initialName)
const [age, setAge] = use('age', initialAge)
Advanced usage
interface IActor {
hp: number
mp: number
}
class Actor implements IActor {
constructor() {
const { use } = openRealm<IActor>(this)
const [hp, setHp, subsHp, destroyHp] = use('hp', 100)
const [mp, setMp, subsMp, destroyMp] = use('mp', 100)
subsHp(() => {
// ...TODO
})
subsMp(() => {
// ...TODO
})
}
get hp() {
const { use } = openRealm<IActor>(this)
const [hp] = use('hp', 100)
return hp()
}
get mp() {
const { use } = openRealm<IActor>(this)
const [mp] = use('mp', 100)
return mp()
}
gotDamage(damage: number) {
const { use } = openRealm<IActor>(this)
const [hp, setHp] = use('hp', 100)
setHp(hp()-damage, 'Got a damage')
}
}
Or, you can create your own store.
// store.ts
import { openRealm } from 'revix'
interface Store {
a: number
b: string
c: boolean
}
export const STORE_SYMBOL = Symbol('store')
export const { use } = openRealm<Store>(STORE_SYMBOL)
export const [a, setA, subsA, destroyA] = use('a', 0)
// another.ts
import { destroyRealm } from 'revix'
import { subsA } from './store.ts'
subsA(({ reason }) => {
if (reason === 'unknown') {
destroyRealm(STORE_SYMBOL, 'error')
}
})
Install
|Site|Link| |---|---| |NPM|View| |Github|View| |jsdelivr|Download|
Node.js (commonjs)
npm i revix
Browser (esmodule)
<script type="module">
import { openRealm, destroyRealm } from 'https://cdn.jsdelivr.net/npm/[email protected]/dist/esm/index.min.js'
</script>
License
MIT LICENSE