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

chainclient

v0.3.0

Published

JavaScript Chain API Client

Downloads

1

Readme

node-chainclient

node-chainclient is a JavaScript client for Chain API, analogous in function to chainclient.py.

Basic usage

const {ChainClient} = require('chainclient');

let client = new ChainClient();
let site = await client.get('https://chain-api.media.mit.edu/sites/1');

Retrieving Resources

Any object (not limited to sites) may be retrieved directly by its URL using the .get() method of the client:

let device = await client.get('http://chain-api.media.mit.edu/devices/25143');
let temperature = await client.get('http://chain-api.media.mit.edu/scalar_sensors/7571');

Following links

Links to other resources may be followed using the .rel() method on the resource, which will resolve with the resource referred to by the relation:

let devices = await site.rel('ch:devices');

It is also possible to get just the link object without resolving it by using the .link() method, allowing the properties of the link itself to be inspected:

let devicesLink = site.link('ch:devices');
console.log(devicesLink.title);

If one then wants to actually retrieve the resource that a link obtained through the .link() method points to, the .fetch() method on the link object may be called:

let devices = await devicesLink.fetch();

Resource objects also have a .links() method that will return an array of link relation names for the object.

Accessing resource properties

Any properties on a resource may be accessed with the .prop() method:

let name = device.prop('name');
console.log("Device name: ", name);

If a resource has an editForm link, properties may be modified by passing a second argument to .prop().

The changes will not be pushed to the API until the .save() method on the resource is called.

device.prop('name', 'fooDevice');
await device.save();

Collections

Resources with an items link that is an array of links to other resources support iteration over these links:

let devices = await site.rel('ch:devices');
for(let link of devices) {
    console.log("Link title: ", link.title);
}

Note that this iterates over the links, not the resources themselves (avoiding expensive fetching of every resource in the collection during iteration). Remember that links may be resolved into resources with the .fetch() method when desired:

for(let link of devices) {
    if(link.title == '0x8123') {
        let device = await link.fetch();
        console.log('Description of 0x8123: ', device.prop('description'));
        return device;
    }
}

Resource creation

If a resource has a createForm link, it may be used via the .create() method:

let devices = await site.rel('ch:devices');
let device = await devices.create({
    name: "fooDevice",
    description: "A test device"
});

// devices.create() resolved to the newly created resource, so we can now use it
// to do further things, like adding a new sensor metric to it:
let sensors = await device.rel('ch:sensors');
let sensor = await sensors.create({
    "sensor-type": "scalar",
    metric: "temperature",
    unit: "°C"
});

let history = await sensor.rel('ch:dataHistory');
let sample = await history.create({
    timestamp: new Date(),
    value: 25.3
});

Authentication

Options may be passed to the underlying HTTP library when the ChainClient instance is created:

let client = new ChainClient({
    auth: {
        username: "someone",
        password: "password"
    }
});

Additionally, most methods that perform HTTP requests (e.g. .save(), .create(), .get(), .fetch()) take an optional config argument that can be used to pass in credentials or other options to the HTTP library.

Caveats

This is still a work in progress and there are likely some rough edges. In particular:

  • There is currently no cache invalidation strategy; resources may get stale if they were modified elsewhere after they were retrieved.
  • Collections of links are fetched in their entirety (all pages are loaded until there are no more 'next' link rels). This allows simpler (and synchronous) iteration and reduces some issues with caching paginated resources, but is not ideal for large collections.
  • Embedded resources may not work entirely as expected; however the current implementation of Chain API apperas not to make much use of them.
  • Relation names are currently not expanded.
  • Reltaive URLs are currently not handled correctly.