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

@wonderlandlabs/carpentr

v1.0.5

Published

A data registry system

Downloads

1

Readme

CARPENTR

Carpenter is an attempt to create a homogenous record system for information transfer, based on (loosely) the REST paradigm. Records are kept in stores, which are grouped in baseFactory. Applications can subscribe to individual records, or entire stores, for updates to record content, or can submit requests to get, delete or change data.

Carpentr is based on the Looking Glass engine which in turn is RxJS based, so all (nearly) elements are Observable. (records being the most numerous content are not themselves directly observable, but are contained in an observable field called records, which can be subscribed/filtered).

Stores also contain requests which can be watched for and responded to. By seperating the request and response into obserable actions you can switch on one set of watchers for production and a second mock set of watchers for testing the system.

The Name

Carpentr is named after the character in Alice in Wonderland:

The Walrus and the Carpenter
Were walking close at hand
The beach was wide
From side to side
But much too full of sand
Mr. Walrus!
Said the Carpenter
My brain begins to perk
We'll sweep this clear
In 'alf a year
If you don't mind the work

Carpentr Classes

Store

Stores are produced by the storeFactory function; they are a LGE ValueMapStream. Stores are NOT intended to directly make REST requests; its not even an assumption that the store IS REST baseed. To interact with a remote system, intercept requests and satisfy them externally.

A note on Records

Records are a minimal glob of data. There are only three requirements for records:

  1. They must have a distinct identity (id) value -- a primary key of some sort -- in order for them to be referenced by the system. If for some reason you cannot or do not want them to have an identity, manage them outside of the Store until they do. (i.e., you can create a record on your own with identity === null but don't try submitting it into the store until it has a unique identity)

  2. They must have a props Object describing their value; a standard key/value javascript object. if your data is complex or in another form, nest it into an object; i.e., if you want the data to be a plain text blurb define it as {text: 'This is my value'}

  3. They must have a status that is one of the Record statuses in Constants. Any record that comes to' the store should be marked as RECORD_STATUS_PERSISTED.

  4. Any data that is not stored in the remote system should be kept in the meta property. For instance if you have a list of items in a select field, you might mark one (or more) of them as "selected"

Records are Immer drafts; they are not directly mutable. If you want to modify a record you must set it with immer produce (exposed by this module) or define a new record with different props and call myStore.do.setRecord(identity, newRecord).

For those not up to what Immer is, assume the records to be under Object.freeze; all its values are read-only

fields

fields are accessed off the store.my proxy. (store.my.records)

  • records: records is itself a ValueMapStream of records, mapped by identity.
  • requests: requests is a ValueMapStream as well, of Request streams. (note: request streams DO NOT update the storeFactory directly as they change;
  • schema (optional) schema exists as a utility to store whatever system you use to enforce consistent value in records.
  • transport (optional) transport exists to store whatever function/class you use to send requests back and forth to your backend.
  • name the identifier for the store, for convenience. also stored as the .name property of the store.

methods

methods are called from the store.do proxy (eg, mystore.do.request('get', 2)) note- this code intentionally makes it difficult to change the identity of a record from the one that it is keyed by.

  • request(action: string, params: any?, options?)): Request: injects a request into the request collection and triggers an ACTION_NEW_REQUEST event
  • onRequest(handler: function): Observer: registers a listener to respond to any new requests. As it returns an observer, the watcher can be cancelled by calling observer.complete() at any time. This method is how you translate a request into a network call.
  • getRequest(uuid: string): Request gets a request by its UUID.
  • hasRequest(uuid:string): boolean: determines if a request is registered by an ID
  • ** upsertRecord(identity, props: object, status: Symbol?, meta: object?)**: creates or updates a record. If the record exists, it updates its props -- only.
  • ** createRecord(identity, props: object, status: Symbol?, meta: object?)**: creates or updates a record. If the record exists, it updates its props -- only.
  • ** createRecords(records: Map)**: create a series of records in one action; transactionally locked.
  • ** updateRecord(identity, dataOrFn)**: updates a record by setting a number of fields with a pojo, or a mutataor function
  • mutateRecord(identity, fn): event: replaces a record with a new draft, based on the identity function. (see Immer)
  • hasRecord(identity): boolean: tests if an identity is registered locally in the store.
  • removeRecord(identity) Record deletes a record locally; returns it (if it were present).
  • ** record | r(identity)**: returns a record (if present) from the local store.