0.0.10 • Published 9 months ago

@qix-js/core v0.0.10

Weekly downloads
-
License
-
Repository
-
Last release
9 months ago

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!

0.0.10

9 months ago

0.0.9

9 months ago

0.0.8

9 months ago

0.0.5

9 months ago

0.0.4

9 months ago

0.0.7

9 months ago

0.0.6

9 months ago

0.0.3

9 months ago

0.0.2

9 months ago

0.0.1

9 months ago