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

@1mill/with-iota

v0.2.1

Published

Idempotently invoke and mutate state using AWS Lambda functions with Cloudevents

Downloads

53

Readme

with-iota

Getting started

  1. Run npm install @1mill/with-iota

  2. Configure your AWS Lambda handler

    import { CREATE, DELETE, INCREMENT, SET, withIota } from '@1mill/with-iota'
    
    const func = async ({ cloudevent, ctx, data, mutation, rapids }) => {
      const { companyId, name } = data
    
      if (!companyId) { throw new Error('companyId is required') }
      if (!name) { throw new Error('name is required') }
    
      // * Create some record
      const { id } = mutation.stage({
        action: CREATE,
        props: { companyId, name, comment: 'Hello world!' },
        type: 'myRecords',
      })
    
      // * Enqueue cloudevent that will be emitted after all staged mutations
      // * are comitted.
      rapids.stage({
        data: { id },
        type: 'fct.my-record-created.v0',
      })
    
      // * Increment some value on a different record
      mutation.stage({
        action: INCREMENT,
        id: companyId,
        props: { recordsCount: 1 },
        type: 'companies',
      })
    
      // * Set a value on the record we just created
      mutation.stage({
        action: SET,
        id,
        props: { comment: 'Update this comment!' },
        type: 'myRecords'
      })
    
      // * Selete the record we just created
      mutation.stage({
        action: DELETE,
        id,
        type: 'myRecords',
      })
    
      // * Enqueue another cloudevent that will be emitted after all
      // * staged mutations are committed.
      rapids.stage({
        data: { id },
        type: 'fct.my-record-deleted.v0',
      })
    
      // * Return some value for calls with InvocationType set to RequestResponse.
      return cloudevent.id
    }
    
    export const handler = async (event, ctx) => await withIota(event, ctx, { func })

Usage

Setup

If you ever change any of the values below once they are set, be sure to migrate any saved journal entries to the new settings. If you do not do this, then already processed cloudevents may run again.

| Environment | Required | Types | Default | Description | |-----------------------------------|----------|--------|----------------------|--------------------------------------------------------| | MILL_IOTA_AWS_ACCESS_KEY_ID | yes | string | | AWS Access Key with permissions to AWS EventBridge. | | MILL_IOTA_AWS_ENDPOINT | | string | Set by AWS | | | MILL_IOTA_AWS_REGION | yes | string | | Valid AWS Region. | | MILL_IOTA_AWS_SECRET_ACCESS_KEY | yes | string | | AWS Secret Key with permissions to AWS EventBridge. | | MILL_IOTA_AWS_SESSION_TOKEN | | string | Set by AWS | AWS Session Token with permissions to AWS EventBridge. | | MILL_IOTA_EVENTBUS_NAME | | string | default | Name of the AWS EventBridge. | | MILL_IOTA_JOURNAL_NAME | | string | iotaJournalEntries | Name of the MongoDB collection. | | MILL_IOTA_MONGO_DB | yes | string | | Name of the MongoDB Database. | | MILL_IOTA_MONGO_URI | yes | string | | URI of the MongoDB Cluster. | | MILL_IOTA_SERVICE_ID | yes | string | | Unique name of the service / application itself. |

During the AWS Lambda runtime, AWS automatically provides all the MILL_IOTA_AWS_ credentials.

Func

| Property | Type |Description | |----------------|-----------|------------| | cloudevent | object | The cloudevent payload from event. | | countDocuments(name, args) | function | Alias for db.collection(name).countDocuments(args) using mongo. | | ctx | object | AWS Lambda context. | | data | any | The cloudevent.data. If cloudevent.datacontenttype is application/json, then the JSON parsed data will be returned. | | distinct(name, args) | function | Alias for db.collection(name).distinct(args) using mongo. | | event | object | The event that invoked the AWS Lambda function. | | find(name, args) | function | Alias for db.collection(name).find(args) using mongo. | | findOne(name, args) | function | Alias for db.collection(name).findOne(args) using mongo. | | mutation.stage(args) | function | Stage a mutation to be committed after return. | | rapids.stage(args) | function | Stage a cloudevent to be sent to rapids after mutations are applied. |

Lifecycle

Despite the straggered nature of staged mutations and staged rapids cloudevents, all mutations are applied first in order. Then, all rapids cloudevents are emitted in order.

| Lifecycle | Commit order | | --- | --- | | Image communicating lifecycle | Image communicating that all mutations are applied first followed by all rapids cloudevents |

Development

  1. Run npm install
  2. Create .env file with with MILL_IOTA_AWS_ACCESS_KEY_ID, MILL_IOTA_AWS_REGION, and MILL_IOTA_AWS_SECRET_ACCESS_KEY.
  3. Run docker compose up -d mongo mongo-admin
  4. Run docker compose up test

Deploy

  1. Run npm version (major|minor|patch)
  2. Run git push
  3. Run npm run deploy