π Middleware β
Middleware in Stunk lets you intercept and modify state updates before they happen. You can use middleware to:
β
Log state changes π
β
Validate input values β
β
Transform data before updating π
β
Trigger side effects βοΈ
Instead of modifying chunks manually, you can attach multiple middlewares to a chunk at creation.
Built-in Middleware in Stunk β
Stunk comes with some useful built-in middleware, such as logging and validation. You can use them out of the box like this:
import { chunk } from "stunk";
import { logger, nonNegativeValidator } from "stunk/middleware";
// Create a chunk with built-in middleware
const age = chunk(25, [logger, nonNegativeValidator]);
age.set(30);
// Logs: "Updating from 25 to 30"
age.set(-5);
// Throws: "Value must be non-negative!" (update prevented)
How Stunk Implements Middleware β
Internally, Stunk's middleware system works like this:
export const logger: Middleware<any> = (value, next, prev) => {
console.log(`Updating from ${prev} to ${value}`);
next(value);
};
export const nonNegativeValidator: Middleware<number> = (value, next) => {
if (value < 0) {
throw new Error("Value must be non-negative!");
}
next(value); // If validation passes, proceed with the update
};
Creating Your Own Middleware β
You can create your custom middleware using the same pattern. Hereβs an example that caps a number at a maximum value:
export const maxValue =
(max: number): Middleware<number> =>
(value, next) => {
if (value > max) {
console.warn(`Value exceeded max (${max}), setting to ${max}`);
next(max);
} else {
next(value);
}
};
// Usage:
const score = chunk(0, [maxValue(100)]);
score.set(120);
// Logs: "Value exceeded max (100), setting to 100"
Why Use Middleware? β
βοΈ Encapsulate Logic β Keep validation and transformation separate from app logic.
βοΈ Chain Multiple Behaviors β Stack middlewares for powerful state control.
βοΈ Reusability β Use the same middleware across different chunks.
Want to undo or redo state changes? Letβs explore time travel in Stunk! π