Patronum: Effector Operators and Utilities
Patronum is a comprehensive utility library designed to extend the core capabilities of the Effector state management framework, providing a rich collection of operators and methods for common reactive programming patterns. It helps Effector developers implement functionality like debouncing, throttling, delays, status tracking for effects, event combination, and store value manipulation with significantly less boilerplate. The current stable version is 2.3.0, and the project exhibits an active development and release cadence, frequently adding new operators and improving existing ones, often with multiple minor and patch releases within a few months. Its key differentiator lies in its deep integration and specialization for the Effector ecosystem, offering purpose-built, type-safe solutions that seamlessly work with Effector's primitive units like Stores, Events, and Effects, fostering modularity and maintainability in complex applications. While it simplifies many common tasks, users must pay attention to its `effector` peer dependency version for compatibility.
Common errors
-
TypeError: (0, patronum_1.status) is not a function
cause This typically occurs in CommonJS environments trying to `require()` an ESM-only package, or due to incorrect transpilation settings where named ESM exports are not correctly resolved.fixEnsure your project is configured for ES Modules (e.g., `"type": "module"` in `package.json` for Node.js) and use `import { status } from 'patronum';`. If in a mixed environment, check your bundler/transpiler configuration. -
Error: `patronum` is not compatible with `effector` version X. Expected `^23`.
cause Your installed `effector` version does not meet the peer dependency requirements of `patronum` (specifically, Patronum v2+ requires Effector v23+).fixUpdate your `effector` package to version `^23` or higher: `npm install effector@^23` or `yarn add effector@^23`. -
TS2345: Argument of type '{ effect: Effect<any, any, any>; }' is not assignable to parameter of type 'object'.cause This TypeScript error often points to an outdated `patronum` version where types were incorrect (e.g., `status` return type fix in v2.1.1) or a mismatch between `patronum` and `effector` types.fixUpgrade `patronum` to the latest version (e.g., `npm update patronum`). Ensure both `patronum` and `effector` packages are compatible and up-to-date. -
Error: Module not found: Error: Can't resolve 'patronum' in 'path/to/your/file'
cause The `patronum` package is not correctly installed or resolvable in your project's `node_modules`.fixRun `npm install patronum` or `yarn add patronum` to ensure the package is installed. Verify your `node_modules` directory and import paths.
Warnings
- breaking Version 2.0.0 of Patronum introduced a breaking change, requiring Effector version 23 or higher. Older versions of Effector are no longer supported.
- gotcha Patronum's documentation is versioned. Viewing documentation for the latest version while using an older library version can lead to confusion and incorrect API usage. Always refer to the documentation corresponding to your installed Patronum version.
- breaking Older breaking changes occurred during major version bumps from 0.x to 1.x (0.14 to 0.100, 0.100 to 0.110, and 0.110 to 1.0). Users upgrading from very old `0.x` versions should consult the migration guide.
- gotcha An issue in v2.1.2 fixed incorrect types for `@@trigger` in the `interval` operator since Effector 23. This might affect advanced usages relying on `@@trigger` protocol.
- gotcha Version 2.1.1 included fixes for the return types of `status` and `snapshot` operators, ensuring they correctly return `StoreWritable`. This could cause type errors if your codebase relied on previous, incorrect type inferences.
Install
-
npm install patronum -
yarn add patronum -
pnpm add patronum
Imports
- status
const { status } = require('patronum');import { status } from 'patronum'; - debounce
import debounce from 'patronum';
import { debounce } from 'patronum'; - combineEvents
import { combineEvents } from 'patronum'; - spread
import * as patronum from 'patronum'; patronum.spread(...);
import { spread } from 'patronum';
Quickstart
import { createEvent, createEffect, createStore } from 'effector';
import { status, debounce, pending, spread } from 'patronum';
// Example 1: Track effect status
const userLoadFx = createEffect<string, { name: string }, Error>();
const $userLoadStatus = status({ effect: userLoadFx });
userLoadFx.use(async (userId) => {
console.log(`Loading user ${userId}...`);
await new Promise(resolve => setTimeout(resolve, 500));
return { name: `User ${userId}` };
});
$userLoadStatus.watch(s => console.log('User load status:', s));
userLoadFx('1'); // Initiates user loading
// Example 2: Debounce an event for search input
const searchInputChanged = createEvent<string>();
const $searchTerm = createStore('');
// Debounce the search input event by 300ms
const debouncedSearch = debounce({
source: searchInputChanged,
timeout: 300
});
debouncedSearch.watch(term => console.log('Debounced search term:', term));
searchInputChanged('a');
setTimeout(() => searchInputChanged('ab'), 100);
setTimeout(() => searchInputChanged('abc'), 200); // Only 'abc' will be logged after 300ms from its last call