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 🙏

© 2024 – Pkg Stats / Ryan Hefner

knockout-undoredo

v3.0.8

Published

Generic undo/redo history-management for knockout observables

Downloads

46

Readme

npm version Build Status Dependency Status devDependency Status Known Vulnerabilities Greenkeeper badge

Knockout Undo-Redo

Generic undo/redo history-management for knockout observables.

Install

$ npm install knockout-undoredo

Usage

Heads up: knockout-undoredo is only available via npm, thus it expects to be run in an node.js environment with require() and everything. If you want to use it in the browser you'll have to browserify the final code.

import ko from 'knockout';
import UndoManager from 'knockout-undoredo';

class ViewModel {
    constructor() {
        this.name = ko.observable('Obama');
        this.message = ko.pureComputed(() => `Thanks ${this.name()}`);
    }
}

const vm = new ViewModel();

// Connect your viewmodel with the undomanager
const undomanager = new UndoManager();
undomanager.startListening(vm);

ko.applyBindings(vm);

// ... and later

console.log(vm.message()); // Thanks Obama
vm.name('Trump');
console.log(vm.message()); // Thanks Trump
undomanager.undo();
console.log(vm.message()); // Thanks Obama
undomanager.redo();
console.log(vm.message()); // Thanks Trump

Create changesets as an undo/redo step

knockout-undoredo has the ability to collect multiple changes over a defined time as a changeset. These collections will be merged to just one undo/redo step in the history timeline.

// ...

const undomanager = new UndoManager({throttle: 300});
undomanager.startListening(vm);

console.log(vm.message()); // Thanks Obama
vm.name('Trump');
vm.name('Clinton');
console.log(vm.message()); // Thanks Clinton
undomanager.undo();
console.log(vm.message()); // Thanks Obama

Constructor Options

| Prop | Type | Default | Description | | ---------- | -------------------- | ------- |------------ | | throttle | integer | 300 | Timeout in which changes will be collected into a changeset | | steps | integer | 30 | Stack size for undoable/redoable changes |

Taking manual snapshots

Snapshots are a collection of operations as one undo step. You can configure which operations should be bundled through the throttle contructor option. Besides that you can always manually trigger a snapshot through undomanager.takeSnapshot():

// ...

const undomanager = new UndoManager({throttle: 300});
undomanager.startListening(vm);

console.log(vm.message()); // Thanks Obama
vm.name('Trump');

// Take an early snapshot
undomanager.takeSnapshot()

vm.name('Clinton');
console.log(vm.message()); // Thanks Clinton
undomanager.undo();
console.log(vm.message()); // Thanks Trump

Skipping observables

By default all enumerable properties of an object will be subscribed to. If you want to skip a knockout obersvable you can modify the object's enumerable property:

Object.defineProperty(obj, 'key', {
  enumerable: false,
});

If you are one of the lucky guys who can make use of ES2016+ features in your code (i.e. through babel) you can simply import the nonenumerable decorator from the core-decorators module, or anything alike.

import {nonenumerable} from 'core-decorators';

class Example {
    @nonenumerable
    unobserved = ko.observable();
}

That way you can still explicitly reference the variable in your code, but it won't be collected by for-loops and Object.keys, Object.values or Object.entries respectively. Remember that it'll still be visible to Object.getOwnPropertyNames!

TODOs

  • [x] Implement proper garbage collection for old listeners (2016-11-24)
  • [x] Make knockout-undoredo's properties observable themselves. (steps, throttle, past, future, subscriptions, recording) (2016-11-24)
  • [x] implement hasUndo() and hasRedo(), as an observable of course (2016-12-06)

Build & Release

gulp do-release --patch
git push --tags
npm publish