@qix-js/core
v0.0.10
Published
## Cool Features
Downloads
17
Readme
Qix-js: A Lightweight Atomic-CQRS based State Management Library
Cool Features
- Atomic state management coupled with CQRS principles.
- Minimal syntax, too short!
- Framework Agnostic.
- Automatic naming of commands/queries using ASTs.
- SSR-friendly listening with minimal renders.
- Synchronous state!
- Different types of queries to suit your needs.
- Command limiting & easy feature flagging.
- Super TypeScript friendly API!
Why Qix-js?
I got hooked on Canaan's scalability but wanted something simpler and faster to use. So, I created Qix-js - a compact version with shorter syntax and better TypeScript support.
Core Concepts
Qix-js is inspired by:
- Atomic state management (like Jotai)
- CQRS (Command Query Responsibility Segregation)
- PubSub (Publishers & Subscribers)
- Abstract Syntax Trees (ASTs)
A glimpse of the power of Qix-js
Queries
A query is a read-only state.
import { q } from "qix-js";
const count = q(0);
count.get(); // 0
Commands
When a query is passed to a command, it will be its setter! Typescript support? YES!!
import { q, c } from "qix-js";
const count = q(0);
const setCount = c(count);
setCount(1);
count.get(); // 1
Listening to Changes
With maximum render efficiency!
count.listen(value => {
console.log(value); // Only called when set
});
Map Queries
More memory efficient, more render efficient!
const state = q.map({ count: 0 });
const setState = c(state);
setState("count", 1); // Less overhead, more efficient!
setState({ count: 2 }); // You can still replace full object if needed.
Derived Queries
Like a second version of a query, inherits all features!
const doubled = q.derived(count, value => value * 2);
Commands as Actions
This unlocks missing powers in many state libraries, while imporving code distribution.
const command = c();
command.on(() => {
// Action logic here
});
command();
Payload is also supported!
const greet = c<string>();
greet.on(payload => {
// Action logic here, payload is string!
});
greet("Hello World!");
Limiting Commands
Great for limiting users access to freemium features :)
const maxUses = 3;
command.enabled(
({ execs }) => execs <= maxUses,
() => showUpgradeDialog()
);
Feature Flagging
Great for limiting user access, whether for premium apps or AB tests :)
command.enabled(
() => isFeatureEnabled(command.id),
() => showUpgradeDialog()
);
Automatic Naming
Thanks to ASTs, you don't need to manually name your commands. That will be automatically assigned based on your variable name.
const upgradeMembership = c();
upgradeMembership.id; // "upgradeMembership"
Groups
Groups allow you to group commands and queries under one scope, they will also automatically prefix the name of your commands/queries with the group name,
const uikit = group();
const theme = uikit.q("light");
const setTheme = uikit.c(theme);
const fontSize = uikit.q(14);
const setFontSize = uikit.c(fontSize);
theme.id; // uikit-theme
fontSize.id; // uikit-fontSize
setTheme.id; // uikit-setTheme
setFontSize.id; // uikit-setFontSize
This is super helpful for tracking and leaves your commands self-documented with zero extra effort!
Watching Commands and Groups
You can watch commands to trigger a callback of your choice.
const upgrade = c();
watch(upgrade, ({ id }, payload) => {
console.log(`'${id}' called!`); // 'upgrade' called!
});
You can do the same with groups and it will automatically watch all of the group commands for you!
const uikit = group();
const setTheme = uikit.c<"light" | "dark">();
const setFontSize = uikit.c<number>();
watch(uikit, ({ id }, payload) => {
console.log(`'${id}' called!`); // 'uikit-setTheme' called!
// 'uikit-setFontSize' called!
});
setTheme("light");
setFontSize(14);
That's it! Qix-js gives you powerful state management without any sign of complexity!