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

textpatcher

v1.3.0

Published

text patching, compatible with the chainpad api

Downloads

7

Readme

TextPatcher

String diffing is the basis of the chainpad API, yet it must be implemented differently depending on the application which is built around chainpad.

TextPatcher.js exposes the components of the code we use in conjunction with chainpad at various degrees of abstraction.

API

TextPatcher.diff(oldval, newval)

The foundation of this library is the diff method.

Given two strings, it will compute a set of instructions which chainpad can use to transform the first string into the second.

The returned value is called an Operation within chainpad.

var op = TextPatcher.diff('pew', 'pow');

/*

{
    type: "Operation",
    offset: 1,
    toInsert: "o",
    toRemove: 1
}

*/

TextPatcher.patch(ctx, op)

The patch method accepts an instance of a chainpad facade (or anything with a compatible API), and an operation.

It then handles inserting and removing characters from the realtime document.

patch has no return value, and operate entirely through side effects.

var oldval = myRealtime.getUserDoc();
var newval = "pew pew pew";

var op = TextPatcher.diff(oldval, newval);

TextPatcher.patch(myRealtime, op);

TextPatcher.format(text, op)

Operations are useful for chainpad, but they are not always easy for a human to read.

format makes it easier to understand what is happening by showing exactly what content will be removed, and what will be inserted.

var text1 = "I can run faster than you";
var text2 = "I can jump farther than you";
var op = TextPatcher.diff(text1, text2);

var formatted = TextPatcher.format(text1, op);
/*

{
    insert: "jump farth",
    remove: "run fast"
}

*/

TextPatcher.log(text, op)

The log method is simply a convenience function.

Given the original text and an operation for transforming that text, it formats the operation and prints it to the console.

TextPatcher.applyChange(ctx, oldval, newval, logging)

apply wraps up most of the components of this library.

It accepts a chainpad compatible realtime facade, the previous value, the desired new value, and optionally a flag indicating whether it should log debugging info to the console.

TextPatcher.apply(myRealtime, "pew", "pow", false);

TextPatcher.transformCursor(cursor, op)

Chainpad is generally used for synchronizing the contents of two users' interfaces. In this context, replacing the contents of a textarea (for instance) displaces the text selection of the user receiving the changes.

In general, browser APIs represent the text selection of an element as an offset (in characters) from the first character of the textual interface.

transformCursor takes this offset as its first argument, and an operation as its second argument, and returns the value of the cursor, corrected for the operation's changes (if necessary).

var textarea = document.getElementsByTagName('textarea')[0];

textarea.selectionStart = TextPatcher.transformCursor(textarea.selectionStart, op);

TextPatcher.create(config)

Finally, the create method wraps everything up into an extremely easy to use function.

Simply create a patcher by supplying a realtime facade, and optionally a flag indicating whether it should print debugging information to the console.

It will return a function which takes one argument (the string which you would like the realtime session to have as its new state).

That function will efficiently diff the current and updated strings and compute an operation, and then apply it to the realtime, logging the changes if necessary.

var patcher = TextPatcher.create({
    realtime: myChainpadInstance,
    logging: true
});

// transform the document to have the content 'pewpewpew'
patcher('pewpewpew');

// now remove the last 'pew' and make it ' bang bang'
patcher('pewpew bang bang')

Now you can easily attach listeners to whichever user interface text value you'd like to sync, and when it changes simply pass the new content into the patching function. TextPatcher will make it so.