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

cubic-core

v2.0.4

Published

Core node for cubic.

Downloads

6

Readme

cubic API

npm build dependencies

Usage

const Cubic = require('cubic')
const Core = require('cubic-core')
const cubic = new Cubic()

cubic.use(new Core(options))

This will create a core node that connects to the API node on localhost:3003 and listen to any incoming requests. We'll being using this for our application logic.

How does it work?

Whenever a user requests a URL on the API node, that request is actually being processed at the core node.

The API checks every core node for an endpoint component that matches the desired URL and the first core node to respond affirmatively gets to process the request and return a response.

model

Should no core node find a matching endpoint, we return a '404, not found'. Should all core nodes fail to respond to the initial check within one second, we respond with a '503, All nodes currently busy'.

Endpoint components

To respond to requests, cubic-core looks for endpoint components in the /api folder in the current working directory. These components are automatically routed based on folder and file names.

An endpoint saved as /api/test/foo.js would automatically be exposed as localhost:3003/test/foo. Custom URLs can still be specified through the endpoint schema.

Endpoint components usually extend the default endpoint class which contains information on rate limiting, caching and more:

const Endpoint = cubic.nodes.core.Endpoint

class Foo extends Endpoint {
  /**
   * Set custom schema information (optional)
   */
  constructor(api, db, url) {
    super(api, db, url)
    this.schema = options
  }

  /**
   * Main method which will be called on a request
   */
  async main(req, res) {
    res.send('bar')   // Respond with a simple 'bar'
    this.cache('bar') // And cache the response for follow-up requests
  }
}

module.exports = Foo

Endpoint Parent Properties

The Endpoint class that we're extending in each endpoint comes with a few utilities that can be used within the class like this:

Caching

this.cache(data, exp, url)

Allows storing a value in redis, which will be sent as a response to requests within the given timeframe. The response is looked up on the api node directly, not on the core node.

| Param | Default | Description | |:------------- |:------------- |:------------- | | data | none | Value to store in the cache. | | exp | default value in cubic-api | (optional) Duration for which the cached value should persist. | | url | this.url | (optional) URL to store the cached value on.

Publish

this.publish(data, url)

Publishes data in cubic's Pub/Sub model. This is important for real-time data, as every subscribed client will receive the published changes immediately.

pub/sub model

| Param | Default | Description | |:------------- |:------------- |:------------- | | data | none | Data to publish to subscribed clients. | | url | this.url | (optional) URL to publish the data on. Useful when a POST endpoint changes the data of another GET endpoint.

Have a look at cubic-client for instructions on how to subscribe to endpoints.

Endpoint Schema

this.schema

Provides basic information about the endpoint, including rate limiting, custom URL and more. See options for all options.

Database client

this.db

Every endpoint gets passed the database client that is connected to the database specified in options.

API client

this.api

The cubic-client instance used to connect to our target API. Can be useful if we need to make requests on endpoints hosted by other core nodes. Under the hood, it's also used for this.publish and this.cache.

Options

Constructor

cubic.use(new Core(options))

| Option | Default | Description | |:------------- |:------------- |:------------- | | endpointPath | process.cwd()/api | Folder to read API endpoints from. | | endpointPathExclude | /a^/ | Sub-path to exclude from endpoints. Default regex matches nothing. | | endpointParent | internal | Parent class that API endpoints will extend. | | baseUrl | none | Path to prepend to each route found in endpoints folder. | | publicPath | process.cwd()/assets | Folder containing publically accessible files. | | apiUrl | 'http://localhost:3003' | API node to connect to | | authUrl | 'http://localhost:3030' | Auth node to authenticate at | | userKey | none | User key to authenticate with. These are registered and assigned automatically in dev mode. In production, you need to register them yourself. (see cubic-auth for reference) | | userSecret | none | User secret to authenticate with. Handled the same way as above. | | mongoUrl | 'mongodb://localhost' | Mongodb connection string. | | mongoDb | 'cubic-core' | Database to select by default. | | redisUrl | `'redis://localhost'`` | Redis connection string. |

Endpoint Schema

class Endpoint extends EndpointParent {
  constructor() {
    this.schema = options
  }
}

| Option | Default | Description | |:------------- |:------------- |:------------- | | method | 'GET' | RESTful method to listen for. | scope | '' | Authorization scope required to use this endpoint. E.g. 'read_contacts' | description | none | (optional) Description for the current endpoint. Useful for automatic API documentation. | query | [] | (optional) Array specifying rules for query params (see object format below) | limit | see below | Object describing rate limit specifications. See keys and default values below

Endpoint Query Object

this.schema.query = [{
  name: 'time',
  default: () => moment().endOf('day').valueOf() // Returns value at time of execution rather than construction
}]

| Option | Default | Description | |:------------- |:------------- |:------------- | | name | none | Name of the given query key. For example in /route?foo=value the query key name is 'foo' | default | none | (optional) Default value for query key. Can be raw value or a function returning a value. If a default value is given, its data type is automatically enforced on user input. E.g. you can't provide numbers if the default value is a string. | required | false | (optional) Whether the query key is required on user input. Will return a 400 error if no matching key is given. | description | '' | (optional) Description for the given key. Useful for automated API documentation.

Endpoint Rate Limits

this.schema.limit = {
  interval: 5000,
  maxInInterval: 20
}

| Option | Default | Description | |:------------- |:------------- |:------------- | | disable | false | (optional) Whether rate limits should be enforced on this endpoint. The default rate limit is applied on all endpoints and we recommend keeping it that way. If some API clients like your service workers need to bypass rate limits, you can add the ignore_rate_limit scope to their user account. | interval | 5000 | Interval in ms for the token bucket to refill. | maxInInterval | 20 | Maximum number of requests within a single interval.

License

MIT