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

gitfred

v7.2.5

Published

In-memory git-like library for managing textual content

Downloads

10

Readme

Gitfred

Gitfred

In-memory git-like library for managing textual content.

I've made the library as part of my work on poet.codes where I need to store multiple files and their different versions. Storing all the content every time simply doesn't scale so I needed a smarter approach. Something like Git but running in the browser. It needed to be lightweight and to provide similar diff/patch experience. That's what Gitfred is.


Installation

npm install gitfred / yarn add gitfred

or directly using https://unpkg.com/gitfred

Usage

const git = gitfred();

git.save("foo.js", { content: "hello winter" });

We have no commits yet, but we have our file in the working directory. If we run git.export() we'll see the following:

{
  "commits": {},
  "stage": [],
  "working": [
    [
      "foo.js",
      { "content": "hello winter" }
    ]
  ],
  "head": null
}

Let's stage our file.

git.add('foo.js');

No we have our file staged. The working directory and our staging area contain the same information.

{
  "commits": {},
  "stage": [
    [
      "foo.js",
      { "content": "hello winter" }
    ]
  ],
  "working": [
    [
      "foo.js",
      { "content": "hello winter" }
    ]
  ],
  "head": null
}

Let's make our first commit:

git.commit('first commit');

We just created a new commit with a hash equal to _1. There is nothing in our staging area and head now points to our first commit.

{
  "commits": {
    "_1": {
      "message": "first commit",
      "parent": null,
      "files": "[[\"foo.js\",{\"content\":\"hello winter\"}]]"
    }
  },
  "stage": [],
  "working": [
    [
      "foo.js",
      { "content": "hello winter" }
    ]
  ],
  "head": "_1"
}

We'll continue by editing our file and making another commit.

git.save("foo.js", { content: "winter is coming" });
git.add('foo.js');
git.commit('second commit');

There are two commits now and head points to the second one (with a hash of _2).

{
  "commits": {
    "_1": {
      "message": "first commit",
      "parent": null,
      "files": "[[\"foo.js\",{\"content\":\"hello winter\"}]]"
    },
    "_2": {
      "message": "second commit",
      "parent": "_1",
      "files": "@@ -20,20 +20,25 @@\n t\":\"\n-hello \n winter\n+ is comming\n \"}]]\n"
    }
  },
  "stage": [],
  "working": [
    [
      "foo.js",
      { "content": "winter is comming" }
    ]
  ],
  "head": "_2"
}

Also notice that the second commit does not contain the whole file but a patch on top of the first commit.

We may now go back to our first commit:

git.checkout('_1');

The head again points to _1 and our working directory contains also the files from that first commit.

{
  "commits": {
    "_1": {
      "message": "first commit",
      "parent": null,
      "files": "[[\"foo.js\",{\"content\":\"hello winter\"}]]"
    },
    "_2": {
      "message": "second commit",
      "parent": "_1",
      "files": "@@ -20,20 +20,25 @@\n t\":\"\n-hello \n winter\n+ is comming\n \"}]]\n"
    }
  },
  "stage": [],
  "working": [
    [
      "foo.js",
      { "content": "hello winter" }
    ]
  ],
  "head": "_1"
}

API

save(filepath:<string>, file:<object>):<object>

Saves a file in the working directory.

| | type | description | | ------------- |:-------------:| -----| | filepath | <string> | A file path (ex. script.js). | | file | <object> | A file object (ex. { "content": "let foo = 'bar';" }). | | returns | <object> | A file object. |

save(files:<object>):<object>

Saves multiple files in the working directory.

| | type | description | | ------------- |:-------------:| -----| | files | <object> | A map where the keys are filepaths and the values are file objects. (ex. { "script.js": { content: "let foo = 'bar';" } }) | | returns | <object> | Gitfred instance. |

discard():<object>

Cleans up the working directory.

| | type | description | | ------------- |:-------------:| -----| | returns | <object> | Gitfred instance. |

saveAll(file:<object>):<object>

Sometimes we need to update all the files at once with a single property. This method allows that.

| | type | description | | ------------- |:-------------:| -----| | file | <object> | A file object (ex. { "content": "" }) | | returns | <object> | Gitfred instance. |

If we for example use { "content": "" } all the files in the working directory will have empty content property.

del(filepath:<string>):<object>

Deletes a file from the working directory.

| | type | description | | ------------- |:-------------:| -----| | filepath | <string> | A file path (ex. script.js). | | returns | <object> | Gitfred instance. |

get(filepath:<string>):<object>

Gets a file (from the working directory) behind a specific file path.

| | type | description | | ------------- |:-------------:| -----| | filepath | <string> | A file path (ex. script.js). | | returns | <object> | A file object or undefined if the file is not found. |

getAll():<array>

Gets all the files in the working directory.

| | type | description | | ------------- |:-------------:| -----| | returns | <array> | An array with all the files. |

rename(oldFilepath:<string>, newFilepath:<string>):<object>

It renames a file or in other words updates a filepath but keeps the file object assign to it.

| | type | description | | ------------- |:-------------:| -----| | oldFilepath | <string> | A file path (ex. scriptA.js). | | newFilepath | <string> | A file path (ex. scriptB.js). | | returns | <object> | Gitfred instance. |

getFilepath(file:<object>):<string>

Gets a file path which responds to a specific file object.

| | type | description | | ------------- |:-------------:| -----| | file | <object> | A file object. | | returns | <object> | A file path (ex. script.js) or undefined if the file object is not found. |

exists(filepath:<string>):<boolean>

Checks if the file exists in the current working directory.

| | type | description | | ------------- |:-------------:| -----| | filepath | <string> | A file path. | | returns | <boolean> | true or false. |

add(filepath:<string>):<object>

Adds a file to the staging area.

| | type | description | | ------------- |:-------------:| -----| | filepath | <string> | A file path (ex. script.js). | | returns | <object> | Gitfred instance. |

add():<object>

Like the above one but it adds all the files from the working directory to the staging area.

| | type | description | | ------------- |:-------------:| -----| | returns | <object> | Gitfred instance. |

commit(message:<string>, meta:<object>):<string>

Registers a commit, cleans the staging area and sets the head to point to the new commit.

| | type | description | | ------------- |:-------------:| -----| | message | <string> | The message of the commit | | meta | <object> | Optional. A meta data that could be attached to the commit. (ex. { flag: true }) | | returns | <string> | The hash of the commit which is nothing fancy but _<number> |

amend(hash:<string>, changes:<object>):<object>

Amends an already existing commit.

| | type | description | | ------------- |:-------------:| -----| | hash | <string> | Hash of the commit that needs to be amended. | | changes | <string> | An object key-value pairs. Check below. | | returns | <object> | It returns the commit object. |

The changes object has the following structure:

{
  message: <string>,
  meta: <object>,
  files: {
    <filepath:string>: <file:object>,
    <filepath:string>: <file:object>
  }
}

For example:

{
  message: 'A better message',
  meta: { flag: false, foo: 'bar' },
  files: {
    'a.js': { content: 'Foo' },
    'b.js': { content: 'Bar' }
  }
};

If the method is called with no arguments Gitfred takes whatever is in the current working directory and applies it to the commit where the head points to.

show(hash:<string>):<object>

Gets a commit behind a specific hash. If used with no arguments returns the commit where the head points to.

| | type | description | | ------------- |:-------------:| -----| | hash | <string> | Hash of a commit. | | returns | <object> | It returns a commit object. |

diff():<object>

Shows the diff between the current working directory and the commit which the head points to.

| | type | description | | ------------- |:-------------:| -----| | returns | <object> | It returns null if there's no diff or an object { text:<string>, html:<string> }. |

adios(hash):<object>

You probably wonder why I picked such a method name right? This method deletes a specific commit. There is no such a thing in Git. We have revert and rebase but that's not really deleting. Gitfred has ridicules simple structure and it is quite easy to implement such functionality.

| | type | description | | ------------- |:-------------:| -----| | hash | <string> | Hash of a commit. | | returns | <object> | It returns the commit which is deleted. |

checkout(hash:<string>, force:<boolean>):<object>

Sets the head to point to a specific commit.

| | type | description | | ------------- |:-------------:| -----| | hash | <string> | Hash of a commit. | | force | <boolean> | false by default. Gitfred throws an error if the staging area is empty or there is unstaged files. By setting this flag to true you are skipping those checks. | | returns | <object> | Gitfred instance. |

head():<string>

| | type | description | | ------------- |:-------------:| -----| | returns | <string> |Returns a hash of a commit or null. |

log():<object>

Get all the commits.

| | type | description | | ------------- |:-------------:| -----| | returns | <object> | It returns all the commits in a single object where the commit hash is a key and the commit object a value. |

logAsTree():<object>

Get all the commits.

| | type | description | | ------------- |:-------------:| -----| | returns | <object> | It returns all the commits in a tree of objects. |

rollOut():<object>

Get all the commits but with actual file content. .log and .logAsTree deliver the files as patches.

| | type | description | | ------------- |:-------------:| -----| | returns | <object> | It returns all the commits. |

export():<object>

It dumps all the data of Gitfred.

| | type | description | | ------------- |:-------------:| -----| | returns | <object> | All the data of Gitfred. |

import(data:<object>):<object>

The opposite of export method.

| | type | description | | ------------- |:-------------:| -----| | data | <object> | Gitfred data. | | returns | <object> | The working directory object. |

listen(callback:<function>):<nothing>

Send a listener function which will be called when the working tree is changed (ON_CHANGE event), when the staging area is changed (ON_ADD event), when a new commit is made (ON_COMMIT event) and when the head is updated (ON_CHECKOUT event).

| | type | description | | ------------- |:-------------:| -----| | callback | <function> | Fired with either one of the following: ON_CHANGE, ON_ADD, ON_COMMIT, or ON_CHECKOUT. | | returns | <nothing> | |

commitDiffToHTML(hash:<string>):<string>

It returns a HTML string containing the diff in a specific commit

| | type | description | | ------------- |:-------------:| -----| | hash | <string> | Hash of a commit. | | returns | <string> | HTML string. |

calcStrDiff(a:<string>, b:string):<object>

Compares string a with string b. Returns either null or a diff object which contains text and html properties.

| | type | description | | ------------- |:-------------:| -----| | a | <string> | Old Text | | b | <string> | New text | | returns | <string> | null or object { text:<string>, html:<string> }. |

Static variables:

  • git.ON_CHANGE - send to the listener passed to listen method. Fired when something in the working directory is changed.
  • git.ON_ADD - send to the listener passed to listen method
  • git.ON_COMMIT - send to the listener passed to listen method
  • git.ON_CHECKOUT - send to the listener passed to listen method

Scripts

  • yarn release - building the library
  • yarn test - running the tests once
  • yarn dev - running the tests in a watch mode