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

curious-js

v3.0.2

Published

JavaScript consumer code for Curious APIs.

Downloads

461

Readme

curious-js

JavaScript consumer code for Curious APIs.

Build Status

v1 is available under the v1 branch

Usage

Installation

curious-js is available from npm:

npm install --save curious-js

If you're not using npm as a package manager, curious-js is also available in a UMD build at unpkg that you can use in a <script> tag in the browser. The UMD build makes curious available as a window.curious global variable.

Importing

curious-js is bundled with rollup.js for compatibility with AMD/require.js, CommonJS/node.js, direct loading in the browser, and ES6 module variants.

Using

There are two main parts to using Curious from JavaScript: CuriousClient and CuriousQuery.

First, create an instance of CuriousClient that points to your Curious server, providing a server URL and a request function.

The server URL provided to the client should point to the Curious root endpoint, not to the query endpoint (/q/) on the server. The code will not break if you make this mistake, but the behavior is deprecated.

You must also provide a request method. You are responsible for picking and using a request method/transport layer that works for you. CuriousClient provides convenience wrappers for common request methods, but you can make any asynchronous transport layer work by passing a custom function as the second parameter to the client constructor. The function must take the URL as its first parameter and an object payload as its second parameter, make a POST request to the curious server, and return a Promise (or any thenable) that resolves to the JSON data returned by the server. Note that if you're using jQuery, jQuery.post does not require any wrapping and can be passed as the second parameter directly.

// Example using Axios
var curiousClient = new curious.CuriousClient(CURIOUS_URL, curious.CuriousClient.wrappers.axios(axios), ...);

// Example using a custom request method
var curiousClient = new curious.CuriousClient(CURIOUS_URL, function (url, data) {
  return new Promise(function (resolve, reject) {
    var result;
    var error;

    // Perform some asynchronous access

    if (error) {
      reject(error);
    } else {
      resolve(result);
    }
  });
}, ...);

Then, construct a CuriousQuery and perform it on the server using the client. Attach any callbacks to the Promise object returned by the perform method, or directly to the query object. They will be executed in the order they were attached, before any callbacks attached later. The results of the query will be passed to the first callback.

Here's a trivial example. The results, of course, depend on the schema on the Curious server; the example uses a made up schema consiting of Document and Section entities in a 1:many relationship.

// A simple node.js use case; works similarly on the front end, minus module loading

const util = require('util');
const axios = require('axios');
const curious = require('curious');

// Define a client to connect to a curious server
const client = new curious.CuriousClient(
 'http://your-curious.com',
  curious.CuriousClient.wrappers.axios(axios),
  null, // serverArgs
  true, // quiet
  true  // camelCase
);

// The schema here is a simple 1:many relationship

// Make a query
const q = new curious.CuriousQuery('Document(id=12345)', 'documents')
  .follow('Document.section_set', 'sections');

// Perform that query with the client
q.perform(client).then((data) => {

  // In the callback, examine the resulting data
  try {
    console.log('data:');
    console.log(data);

    console.log('data.objects:');
    console.log(data.objects);

    console.log('data.objects.documents:');
    console.log(data.objects.documents);

    console.log('data.objects.documents[0].sections:');
    console.log(data.objects.documents[0].sections);

    console.log('data.objects.documents[0].sections[0].documents[0]:');
    console.log(data.objects.documents[0].sections[0].documents[0]);

    console.log('data.objects.sections:');
    console.log(data.objects.sections);

    console.log('data.objects.sections[0].documents:');
    console.log(data.objects.sections[0].documents);

    console.log('data.objects.sections[0].documents[0].sections[0]:');
    console.log(data.objects.sections[0].documents[0].sections[0]);
  } catch (e) {
    console.error(e);
  }

  return data;
}, console.error);

The output from the example code above would look something like this, depending on the data:

data:
{ objects: { documents: [ [Object] ], sections: [ [Object], [Object] ] },
  trees: [ null, null ] }

data.objects:
{ documents:
   [ CuriousObject {
       __url: 'http://your-curious.com/document/12345',
       __model: 'Document',
       id: 12345,
       ...
       sections: [Object] } ],
  sections:
   [ CuriousObject {
       __url: null,
       __model: 'Section',
       id: 12205,
       documentId: 12345,
       ...
       documents: [Object] },
     CuriousObject {
       __url: null,
       __model: 'Section',
       id: 112403,
       documentId: 12345,
       ...
       documents: [Object] } ] }

data.objects.documents:
[ CuriousObject {
    __url: 'http://your-curious.com/document/12345',
    __model: 'Document',
    id: 12345,
    ...
    sections: [ [Object], [Object] ] } ]

data.objects.documents[0].sections:
[ CuriousObject {
    __url: null,
    __model: 'Section',
    id: 12205,
    documentId: 12345,
    ...
    documents: [ [Object] ] },
  CuriousObject {
    __url: null,
    __model: 'Section',
    id: 112403,
    documentId: 12345,
    ...
    documents: [ [Object] ] } ]

data.objects.documents[0].sections[0].documents[0]:
CuriousObject {
  __url: 'http://your-curious.com/document/12345',
  __model: 'Document',
  id: 12345,
  ...
  sections:
   [ CuriousObject {
       __url: null,
       __model: 'Section',
       id: 12205,
       documentId: 12345,
       ...
       documents: [Object] },
     CuriousObject {
       __url: null,
       __model: 'Section',
       id: 112403,
       documentId: 12345,
       ...
       documents: [Object] } ] }

data.objects.sections:
[ CuriousObject {
    __url: null,
    __model: 'Section',
    id: 12205,
    documentId: 12345,
    ...
    documents: [ [Object] ] },
  CuriousObject {
    __url: null,
    __model: 'Section',
    id: 112403,
    documentId: 12345,
    ...
    documents: [ [Object] ] } ]

data.objects.sections[0].documents:
[ CuriousObject {
    __url: 'http://your-curious.com/document/12345',
    __model: 'Document',
    id: 12345,
    ...
    sections: [ [Object], [Object] ] } ]

data.objects.sections[0].documents[0].sections[0]:
CuriousObject {
  __url: null,
  __model: 'Section',
  id: 12205,
  documentId: 12345,
  ...
  documents:
   [ CuriousObject {
       __url: 'http://your-curious.com/document/12345',
       __model: 'Document',
       id: 12345,
       ...
       sections: [Object] } ] }

The API is explained in detail in the documentation.

Development

Development is carried out through an included Docker environment and Travis CI.

CI build and deployment

Continuous integration is performed with Travis CI. Any tagged commits on the master branch are automatically deployed to NPM through the CI deploy task.

To deploy the code:

  1. Get on the default branch git checkout master
  2. Bump the version: npm version [type]
  3. Push to the origin with tags: git push && git push --tags

Docker

The project also provides a Dockerfile that builds a container capable of running the unit tests and scripts. To run the tests, bring up the container with docker-compose up. Any of the scripts shown to be run below from a shell with npm run can be executed in an instance of the container with docker-compose run --rm [script name].

REPL

A script that opens up a node.js REPL and loads curious.js as curious is available via npm run repl.

Test framework

The tests are written in mocha, with chai expect-style assertions. Tests can be run with npm test.

Coding conventions and linting are enforced at the unit test level but can also be run independently with npm run lint.

Documentation

Any new code added to curious.js must be documented in a manner consistent with existing documentation.

JSDoc documentation can be generated into the doc/ subdirectory from the source code and README with npm run make_doc. It can be updated on the project website automatically with npm run release_doc.