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

@projectpac/core-data

v0.6.0

Published

Part of PAC: @projectpac/core-data.

Downloads

810

Readme

@projectpac/core-data

Not implemented. This is a spine row that mounts, claims no service key, and does nothing. It exists so the node's composition shows the seam that belongs here while the code behind it is unwritten.

What it is meant to be

A collection of the principal's data sources -- web data, credentials, payment instruments, skills. Sources are created and kept current by source adapters, and each source is owned by the adapter that writes it. Data policies are how authorization over sources is expressed and enforced: which plugins and peers may learn what about a source, which uses are allowed on what terms, and what must be asked of the principal instead.

When a plugin needs a source applied somewhere -- staked into a box, presented to an endpoint -- this plugin performs the operation on the caller's behalf, so contents never cross into the caller's code. That one verb is apply: the caller names what to use and where it goes, and never holds what it named.

  • Provides: the source registry; source writes by owning source adapters; the policy check every access passes through; execution of the operations that apply sources on a caller's behalf; the authorization queue, whose decisions come back as events in the caller's own context the way completed runs do.
  • Not responsible for: interpreting the data. That is the caller's work.

Why the previous version went

There was one, and it was removed rather than kept. It held a policy document nothing wrote, a capability check that allowed everything, and an authorization queue no interface answered -- so every refusal it could express was one that never fired. Enforcement that cannot be exercised is not enforcement, and code shaped like a check that always passes is worse than no check, because the rest of the node is written as though the check were real.

What replaced it, for now:

  • An operation adapter claims its own service key rather than registering into a seam here. A plugin injects the adapter it needs -- ctx.jcBox, ctx.dobj -- and each one derives its caller the same way this would have, so a plugin still stakes a file it cannot itself read.
  • Files live in the plugin that owns them. Every plugin has a folder under the data directory, and readUnderCaller in the sdk is the one bounded way an adapter reads another plugin's file. There is no shared store to hold a registry of, and no private directory outside the data directory.

What has to come back with it

The parts worth keeping from the version that went, and the reason each one was worth having:

  • apply performs; it never returns material. The order inside was the point: resolve the operation, check policy, spend an approval if one is required, and only then read the contents -- so a refusal at any earlier step meant nothing was read.
  • The receipt is not traced. A receipt is the adapter's answer to the caller; an endpoint that echoed what it was sent would otherwise put the credential into the trace, which is the one place in the node that keeps everything.
  • An approval is spent. It admits one apply, not a standing permission, and the question it answers must be the caller's own.
  • Defaults are asymmetric. Sources default-deny, because a source shown to the wrong plugin cannot be unshown. Operations default-ask, because stopping to ask costs the principal a decision they were always entitled to make.

Whatever enforces these will need a way to gate a call it does not itself implement, which is the thing the old version could not do: the seam it registered adapters into is now each adapter's own service key, and a check has to sit somewhere a caller cannot go around.