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

theta

v0.0.0

Published

[![NPM version][npm-image]][npm-url] [![Build status][travis-image]][travis-url] [![Test coverage][codecov-image]][codecov-url] [![Dependency Status][david-image]][david-url] [![License][license-image]][license-url] [![Downloads][downloads-image]][downloa

Downloads

7

Readme

theta

NPM version Build status Test coverage Dependency Status License Downloads

Slowly modularize your app into AWS Lambda Functions.

Example

In our example, we create a lambda function around bcryptjs. Password hashing is a good use-case for lambda since it's CPU intensive, is a very simple function, and can be easily outsourced to Lambda.

Calling Lambdas

Suppose you have lambda functions bcrypt-compare and bcrypt-hash defined in your app:

lambdas/
  bcrypt-compare/
    index.js
    lambda.json
    package.json
  bcrypt-hash/
    index.js
    lambda.json
    package.json
server/
  index.js

From server/index.js, you can theta/require any lambda function:

import lambda from 'theta/require'

const bcryptCompare = lambda('bcrypt-compare')

bcryptCompare({
  password: 'mypassword',
  hash: '$some$bcrypt$hash',
}).then(valid => {
  console.log(valid)
})

By default, the local version of the lambda is used. In other words, in development, AWS Lambdas are not actually used. This makes development and testing both simpler and faster.

In production, lambdas are used by default. You can also enable lambdas using the environment variable THETA_ENABLED=1.

Creating Lambdas

Each lambda could have its own dependencies via package.json. For example, lambdas/bcrypt-compare might have:

{
  "dependencies": {
    "bcryptjs": "^2.0.0"
  }
}

However, you could also require other modules within your app and not define your explicitly require()d dependencies in each lambda.

import fn from '../../lib/fn'

export default function (event, context) {
  return fn(event).then(val => context.succeed(val), err => context.fail(err))
}

theta will:

  • Automatically transpile the code to node v0.12 code via babel - some configuration may be required.
  • Bundle your lambda into a single file (like webpack/browserify, but not).
  • Install dependencies in each lambda which may or may not be defined in the local package.json by crawling through the dependency tree.

Publishing

Each lambda is published with its package.json's name and the git repository's git commit as the version. This means that each commit of your app will have its own set of lambdas.

The publishing logic is as follows:

  • Create a temporary directory for each lambda
  • Copy over the package.json
  • Compile the lambda's index.js file and save it into the temporary directory as index.js
  • npm install --save all the crawled dependencies of the lambda
  • Package the folder into a zip
  • Publish the zip to AWS Lambda with the git commit as the version

Compiling is done with the theta push command.

Testing

Each lambda should have its own tests. theta test will run all of your lambdas' tests locally. theta will run the tests using lambdas after publishing.

You could test your app both with and without Lambdas. One way is to run parallel tests (one test with THETA_ENABLED=1, one without). Another is to run separate tests (i.e. Lambda functions only) in parallel to actual tests.

theta push takes a while to run. It's intended to be run in your CI, never locally. Here's what your test script could look like:

# run tests locally without remote lambdas
npm test
# create your lambda functions
./node_modules/theta push
# run the tests again with remote lambdas
THETA_ENABLED=1 npm test

API

theta(1)

theta push

Push all your lambda functions to AWS.

Options:

  • --test - run all the tests against the lambda functions as they are published

theta test

Run all your lambda tests locally.

node.js

import lambda from 'theta/require'

Acts kind of like require(). See below:

const fn = lambda(name, [options])

Require a lambda function. Depending on the configuration, this could just run the JS locally or it could be running the lambda remotely.

  • name - the name of the lambda

The first set of options are the Lambda Invoke options:

  • InvocationType
  • LogType
  • Qualifier

The second set of options are theta options:

  • remote - overriding THETA_ENABLED, whether to use a Lambda

fn(event, [context]).then(result => {})

Calls a lambda function. context is optional. The function always returns a Promise instance, even if the underlying lambda function is synchronous.

configuration

Environment Variables

theta environment variables:

  • THETA_ENABLED <optional> - whether theta/require uses lambdas or not.
  • THETA_PATH <optional> - the path of the lambdas/ folder defaulting to path.resolve('lambdas')

AWS environment variables (which can just be set in lambdas/config.js below):

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_REGION
  • AWS_LAMBDA_ROLE

lambdas/package.json

lambdas/.babelrc

The babel configuration to be used when bundling your lambda function. If not defined, the following configuration will be used:

{
  "presets": [
    "stage-0",
    "es2015",
  ]
}

Note that this will overwrite any other .babelrc.

lambdas/config.js

Configuration for all your lambdas.

lambdas//lambda.json

Optional options for each of your lambdas

Notes

  • Slowly split your code into separate files. This will allow your lambda functions to remain minimal as theta will include any require()d modules in the lambda. For example, refactor to do import fn from 'lib/fn' instead of import { fn } from 'lib'
  • Because modules are packaged together, certain node features such as __dirname and __filename are not supported. Do not use these when the module will be used in lambda functions.
  • If a dependency is not explicitly imported down the lambda's dependency tree, you should add it in the lambda's package.json or lambdas/package.json.