npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@doars/tiedliene

v1.3.1

Published

a teensy-tiny library for managing state diffs.

Readme

tiedliene

tiedliene is a teensy-tiny yet powerful state management utility designed to keep your application state consistent and manageable. With a focus on simplicity and efficiency, tiedliene enables you to track, apply, revert, and even manage undo/redo operations for state changes. It's perfect for applications that require precise control over state transitions without the overhead of more complex libraries.

  • Offers a simple set of functions, making it easy to understand and integrate into your application.
  • Comes in at less than a kilobyte and a half in size when compressed. Due to the minimal philosophy of the library and the simple concepts within the total size is tiny as well.
  • Uses a naive diffing algorithm to ensure that state changes are applied in full.
  • Allows you to not only revert state changes but also provides built-in undo and redo capabilities.

To start using tiedliene, you need to understand three core functions: determineDiff, applyDiff, and revertDiff. These calculate the differences between states, apply those changes, and revert them.

A diff contains set and delete changes. Each change has a non-empty path made from string keys or numeric array indices. Unsafe path components such as __proto__, constructor, and prototype are rejected.

The determineDiff function is the cornerstone of tiedliene. It takes two states—an original state and a modified state—and returns a list of changes (diffs) that describe how to transform the original state into the modified state.

import { determineDiff } from '@doars/tiedliene'

const oldState = {
  name: 'Luke',
  age: 22,
  interests: ['Jedi Training', 'Flying', ],
}

const newState = {
  name: 'Luke',
  age: 23,
  interests: ['Jedi Training', 'Flying', 'Meditation', ],
}

const diffs = determineDiff(oldState, newState)
console.log(diffs)

In the example above, determineDiff compares oldState and newState, outputting a list of changes that reflect the transition from the old state to the new one.

Once you've determined the diffs, use applyDiff to apply these changes to an existing state. This function updates the current state based on the provided diffs.

import { applyDiff } from '@doars/tiedliene'

let state = {
  name: 'Luke',
  age: 22,
  interests: ['Jedi Training', 'Flying', ],
}

const diffs = [{
  type: 'set',
  path: ['age'],
  old: 22,
  new: 23,
}, {
  type: 'set',
  path: ['interests', 2, ],
  new: 'Meditation',
}]

state = applyDiff(state, diffs)
console.log(state)

Here, applyDiff modifies the state according to the diffs, updating it to reflect the new values.

With the revertDiff function, you can undo changes made to the state. This is particularly useful for implementing features like "undo" or "rollback" in your application.

import { revertDiff } from '@doars/tiedliene'

const currentState = {
  name: 'Luke',
  age: 23,
  interests: ['Jedi Training', 'Flying', 'Meditation', ],
}

const diffs = [{
  type: 'set',
  path: ['age'],
  old: 22,
  new: 23,
}, {
  type: 'set',
  path: ['interests', 2, ],
  new: 'Meditation',
}]

const originalState = revertDiff(currentState, diffs)
console.log(originalState)

In this example, revertDiff undoes the changes specified in the diffs, restoring the state to its previous condition.

All the functionality above is part of the base library. The full build adds a little non-essential functionality to make development simpler, including state management through manageState. This method tracks changes and provides undo and redo while keeping the state encapsulated behind get, set, undo, and redo.

  • Use get() to retrieve the current state.
  • The set(newState) method updates the state, pushes changes to the undo stack, clears the redo stack, and returns the new snapshot.
  • The undo() method reverts the latest change, moves it to the redo stack, and returns the resulting snapshot.
  • The redo() method reapplies the latest undone change, moves it back to the undo stack, and returns the resulting snapshot.

These methods make it easy to add undo and redo to an application, keeping the history of state changes and allowing users to navigate through past states.

import { manageState } from '@doars/tiedliene'

const initialState = {
  name: 'Luke',
  age: 22,
  interests: ['Jedi Training', 'Flying', ],
}

const stateManager = manageState(initialState)

// Get the current state.
console.log(stateManager.get())

// Set a new state.
stateManager.set({
  name: 'Luke',
  age: 23,
  interests: ['Jedi Training', 'Flying', 'Meditation', ],
})

// Undo the last change.
stateManager.undo()
console.log(stateManager.get())

// Redo the last undone change.
stateManager.redo()
console.log(stateManager.get())

manageState accepts these options:

  • maximumHistory is a non-negative integer. Its default is 50; 0 disables history.
  • snapshot is either 'clone' (the defensive default) or 'reference'. Reference snapshots expose managed state directly and require callers to treat it as immutable unless they intentionally want to mutate the manager state.
  • clone is an optional clone function used for snapshots and instrumentation.

Plain objects and arrays may contain cycles and shared references, which are preserved. Date, Map, Set, and typed-array values are compared by value and stored as whole atomic changes. Functions, custom instances, weak collections, DOM nodes, symbol-keyed state, and enumerable accessors are rejected with TypeError before managed state changes.

tiedliene's diff functions work with nested plain objects and arrays, including cycles and shared references. manageState deliberately rejects functions, custom instances, weak collections, DOM nodes, symbol-keyed state, and enumerable accessors so managed transitions remain predictable.

const nestedState = {
  user: {
    name: 'Luke',
    profile: {
      age: 22,
      interests: ['Jedi Training', 'Flying', ],
    },
  },
}

Installation

Via NPM

npm install @doars/tiedliene

IIFE build via a CDN

<!-- Base bundle -->
<script src="https://cdn.jsdelivr.net/npm/@doars/tiedliene@1/dst/tiedliene.base.iife.js"></script>
<!-- Base bundle minified -->
<script src="https://cdn.jsdelivr.net/npm/@doars/tiedliene@1/dst/tiedliene.base.iife.min.js"></script>
<!-- Full bundle -->
<script src="https://cdn.jsdelivr.net/npm/@doars/tiedliene@1/dst/tiedliene.iife.js"></script>
<!-- Full bundle minified -->
<script src="https://cdn.jsdelivr.net/npm/@doars/tiedliene@1/dst/tiedliene.iife.min.js"></script>

ESM build via a CDN

// Base bundle.
import { determineDiff } from 'https://cdn.jsdelivr.net/npm/@doars/tiedliene@1/dst/tiedliene.base.js'
// Base bundle minified.
import { determineDiff } from 'https://cdn.jsdelivr.net/npm/@doars/tiedliene@1/dst/tiedliene.base.min.js'
// Full bundle.
import { determineDiff, manageState } from 'https://cdn.jsdelivr.net/npm/@doars/tiedliene@1/dst/tiedliene.js'
// Full bundle minified.
import { determineDiff, manageState } from 'https://cdn.jsdelivr.net/npm/@doars/tiedliene@1/dst/tiedliene.min.js'

For compact language-model documentation, see llms.txt.