@randajan/revert
Version:
A minimalist utility for running sequential steps with automatic rollback on failure.
201 lines (142 loc) β’ 4.8 kB
Markdown
# @randajan/revert
[](https://www.npmjs.com/package/@randajan/revert) [](https://standardjs.com)
_Reversible, reliable, readable._
A tiny utility for managing forward-backward processes with automatic rollback on error.
Supports both **synchronous** and **asynchronous** workflows with optional **value passing** between steps.
## π¦ Installation
```bash
npm install @randajan/revert
```
or
```bash
yarn install @randajan/revert
```
## π§ Package Variants
| Package Path | Type | Description |
|--------------------------------------|--------------|----------------------------------------|
| `@randajan/revert/async` | ESM / CJS | Asynchronous version with logging, flow, utils |
| `@randajan/revert/async/utils` | ESM / CJS | Utility functions: `revertable`, `sleep`, `attempt` |
| `@randajan/revert/sync` | ESM / CJS | Synchronous version of the core logic |
| `@randajan/revert/sync/utils` | ESM / CJS | Sync utilities: `revertable` only (no `sleep`, `attempt`) |
## π Quick Example
```js
import { Revertable } from "@randajan/revert/async";
const task = new Revertable({ logger:(msg) => log2.push(msg) })
.pushNamed("s1", (log) => log("do1"), "r1", (log) =>{ log("undo1"); throw new Error("rollback")})
.pushNamed("s2", (log) => log("do2"))
.pushNamed("s3", (log) => log("do3"), "r3", (log) => log("undo3"))
.pushNamed("s4", (log) => { log("do4"); throw new Error("main"); }, "r4", (log) => log("undo4"));
const result = await task.run();
console.log(result);
```
### π Log Output Example
```text
β 1/4 [info] s1
β 1/4 [info] do1
β 2/4 [info] s2
β 2/4 [info] do2
β 3/4 [info] s3
β 3/4 [info] do3
β 4/4 [info] s4
β 4/4 [info] do4
β 4/4 [error] main
β 3/4 [info] r3
β 3/4 [info] undo3
β 1/4 [info] r1
β 1/4 [info] undo1
‫ 1/4 [error] rolback
```
## π Class: Revertable
A class-based interface built over the core `revertable` function.
### Constructor
```ts
new Revertable(options?: {
pass?: "omit" | "keep" | "reduce",
logger?: (text: string, kind: string, dir: boolean, step: number, count: number) => void,
logFormat?: (data: any, kind: string, dir: boolean, step: number, count: number) => string
})
```
### Modes (`pass`)
| Mode | Description |
|-----------|-------------|
| `"omit"` | No value is passed between steps (default) |
| `"keep"` | A static value is passed to each step but not modified |
| `"reduce"`| Each step receives and returns a value (like a reducer) |
### Method: push
```ts
push(
fwd: (...args) => any | Promise<any>,
rwd: (...args) => any | Promise<any>
): this
```
Adds a step to the process. Both forward and rollback handlers are required.
### Method: run
```ts
async run(initialValue?: any): Promise<{
status: "pass" | "undo" | "fail",
pass?: any,
undo?: Error,
undoStep?: number,
fail?: Error,
failStep?: number
}>
```
Runs the sequence and handles rollback automatically.
## π§° Utility Functions (in `utils`)
```js
import { revertable, sleep, attempt } from "@randajan/revert/async/utils";
```
### revertable
Core engine function.
```ts
async revertable(
value: any,
stepCount: number,
fn: (value, dir, stepIndex, totalSteps) => any,
onError?: (err, dir, stepIndex, totalSteps) => void
): Promise<{
status: "pass" | "undo" | "fail",
pass?: any,
undo?: Error,
undoStep?: number,
fail?: Error,
failStep?: number
}>
```
Handles the entire flow + rollback mechanism. Minimal, flexible and fully decoupled from logging.
### sleep
```ts
async sleep(ms: number): Promise<void>
```
Simple delay utility using Promise + `setTimeout`.
_without sync alternative_
### attempt
```ts
async attempt(
fn: (attempt: number) => any,
attempts: number = 3,
delay: number = 2000
): Promise<any>
```
Attempts the function multiple times until it succeeds, with delay between retries.
_sync attempts are without delay_
## π§ͺ Synchronous Variant
Available under:
- `@randajan/revert/sync`
- `@randajan/revert/sync/utils`
Same API, but no `sleep` and limited `attempt` (as theyβre async-only).
Use `revertable()` directly for immediate rollback logic.
## Support
If you have any questions or suggestions for improvements, feel free to open an issue in the repository.
## π License
MIT Β© [randajan](https://github.com/randajan)