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

pict-section-dochistory

v1.0.0

Published

Version history for a document tree in Pict: a timeline of versions that says who changed what and from which side, and a rendered line diff between any two of them. Host-agnostic - it reads through two callbacks and ships no transport.

Readme

pict-section-dochistory

Version history for a document tree, as two Pict views:

  • a timeline of versions that says who changed a document, from which side, and when;
  • a line diff between any two of those versions.

It ships no transport. Both views read through host callbacks, so the section carries no assumption about where the history lives or what the backing store is called.

Install

npm install pict-section-dochistory

Use

The two views register independently, so a host places them wherever it likes (a timeline in a sidebar, a diff in a main pane) instead of accepting one fixed layout. Wire the timeline's onSelectVersion to the diff view's showDiff and they work as a pair.

const libDocHistory = require('pict-section-dochistory');

pict.addView('Doc-Timeline', Object.assign({}, libDocHistory.TimelineView.default_configuration,
	{
		Path: 'architecture/data-model.md',
		onLoadHistory: (pPath, pLimit, fCallback) => myAPI.history(pPath, pLimit, fCallback),
		onSelectVersion: (pEvent, pPrevious) =>
			pict.views['Doc-Diff'].showDiff(pPrevious ? pPrevious.Commit : '', pEvent.Commit, 'architecture/data-model.md')
	}), libDocHistory.TimelineView);

pict.addView('Doc-Diff', Object.assign({}, libDocHistory.DiffView.default_configuration,
	{ onLoadDiff: (pFrom, pTo, pPath, fCallback) => myAPI.diff(pFrom, pTo, pPath, fCallback) }),
	libDocHistory.DiffView);

pict.views['Doc-Timeline'].loadHistory();

Give the page the two containers the default configurations render into (#DocHistory-Timeline-Container and #DocHistory-Diff-Container), or override DefaultDestinationAddress on either view.

The event shape

Both views understand one event object:

{ Commit, Parent, Date, Source, AuthorName, AuthorEmail, IDUser,
  UpstreamCommitSHA, IDDocSyncBinding, Message, FilesChanged, PathChange }

Only Commit and Date are really needed; everything else degrades to a sensible blank. Unknown extra fields are carried through untouched, so a host can hang its own data off an event and read it back in a callback.

Source is an open string. These values get a friendly label and their own style hook:

| Source | Shown as | |---|---| | platform | Edited here | | github | Pulled from the repository | | merge | Merged from both sides | | agent | Written by a tool | | import | Imported |

Anything else is shown exactly as given, so a host with its own vocabulary still renders.

Timeline view

libDocHistory.TimelineView

| Option | Default | What it does | |---|---|---| | Path | '' | The document to show history for. Empty means the whole tree. | | Title | 'Version history' | Heading above the list. Empty hides the header row. | | PageSize | 40 | How many versions to ask the host for. | | ShowCommitHash | false | Show each version's short content address. | | ShowUpstreamRef | false | Show the originating upstream commit for a pulled change. | | EmptyMessage | see source | Shown when the document has no versions. | | LoadingMessage | see source | Shown while the host is loading. |

Callbacks:

  • onLoadHistory(pPath, pLimit, fCallback) required - call back with (error, { Events: [...], More: bool }).
  • onSelectVersion(pEvent, pPreviousEvent, pPath) - a version was clicked. pPreviousEvent is the next-older version in the list, so (previous -> event) is the change that version introduced. It is null for the oldest loaded version, falling back to a stub carrying the event's own Parent when there is one.
  • onError(pError) - the host surfaces a failed load its own way. Without it the view shows its own error row.

Methods: loadHistory(), setPath(pPath), events(), selectedEvent().

Diff view

libDocHistory.DiffView

| Option | Default | What it does | |---|---|---| | ContextLines | 3 | Unchanged lines kept either side of a change. 0 shows the whole document. | | ShowLineNumbers | true | Show original and new line numbers. | | EmptyMessage / IdenticalMessage / BinaryMessage / LoadingMessage | see source | The states that are not a diff. |

Callbacks:

  • onLoadDiff(pFrom, pTo, pPath, fCallback) required - call back with (error, { FromContent, ToContent, Binary, FromExists, ToExists }). FromContent is null when the document did not exist at that version; Binary: true means there is no line diff to render (an image, a PDF) and the view says so.

Methods: showDiff(pFrom, pTo, pPath), clear(), diffRows().

pFrom may be empty: the first version of a document is all additions.

Model

libDocHistory.Model is the pure, DOM-free half, exported for hosts and tests:

  • diffLines(pFrom, pTo, pOptions) - LCS line diff returning { Kind: 'same' | 'add' | 'del', Text, FromLine, ToLine } rows. Normalizes CRLF, treats a trailing newline as a terminator, and falls back to a whole-file replace past pOptions.MaxCells so a huge pair cannot hang a render.
  • collapseUnchanged(pDiff, pContext) - collapse long unchanged runs into { Kind: 'gap', Skipped } markers.
  • diffStats(pDiff), splitLines, sourceLabel, sourceKind, relativeDate, shortCommit, escapeHTML.

Notes

  • Document text is escaped before it reaches a template. A diff renders an author's prose, which may legitimately contain markup.
  • Added and removed lines carry a marker character as well as a tint, so a diff stays readable without colour vision.
  • All colors are theme tokens, so an active pict-section-theme recolors both views.

Testing

npm test

License

MIT