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

dynamo-plus

v2.0.2

Published

dynamo-plus

Downloads

151

Readme

Dynamo Plus

npm version Types, Tests and Linting Issues

Extend and supercharge your DynamoDB DocumentClient with infinite batching.

Installation

npm i dynamo-plus
import { DynamoPlus } from 'dynamo-plus'
const dynamo = new DynamoPlus({
  region: 'eu-west-1',
})

const regularDynamoParams = {
  TableName: 'myTable',
  Key: {
    myKey: '1337'
  }
}
const data = await dynamo.get(regularDynamoParams)

Features

Optional return types

On methods that return documents you can have them explicitly typed from the get-go:

interface User {
  id: string
  name: string
  age: number
}
const user = await dynamo.get<User>({
  TableName: 'users',
  Key: { id: 'agent47' },
})
// user is now either User or undefined

const users = await dynamo.getAll<User>({
  TableName: 'users',
  Keys: [
    { id: 'eagle-1' },
    { id: 'pelican-1' }
  ],
})
// users is now Array<User>

const moreUsers = await dynamo.scanAll<User>({ TableName: 'users' })
// Array<User>

New method for performing batchGet requests in chunks

The built-in batchRead method can be used for fetching multiple documents by their primary keys, but it requires you to handle chunking and unprocessed items yourself. DynamoPlus adds a getAll method that does the heavy lifting for you.

getAll(params)

It's like batchGet, but with the simple syntax of get.

  • params Object
    • TableName
    • Keys - An array of key objects equivalent to Key in get().
    • BatchSize - Optional custom batch size. Defaults to 100 which the maximum permitted value by DynamoDB.

getAll() returns

const params = {
  TableName: 'users',
  Keys: [{ userId: '1' }, { userId: '2' }, /* ... */ { userId: '999' }]
}

const response = await dynamo.getAll(params)
// response now contains ALL documents, not just the first 100

New methods for performing batchWrite requests in chunks

batchWrite is neat for inserting multiple documents at once, but it requires you to handle chunking and unprocessed items yourself, while also using it's own somewhat unique syntax. We've added deleteAll() and putAll() to do the heavy lifting for you.

deleteAll(params)

batchWrite deletions, but with the simple syntax of delete.

  • params Object
    • TableName
    • Keys - An array of key objects equivalent to Key in delete().
    • BatchSize - Optional custom batch size. Defaults to 25 which the maximum permitted value by DynamoDB.

deleteAll() does not return any data once it resolves.

const params = {
  TableName: 'Woop woop!',
  Keys: [{ userId: '123' }, { userId: 'abc' }]
}
await dynamo.deleteAll(params)

putAll(params)

batchWrite upserts, but with the simple syntax of put.

  • params Object
    • TableName
    • Items - An array of documents equivalent to Item in put().
    • BatchSize - Optional custom batch size. Defaults to 25 which the maximum permitted value by DynamoDB.

putAll() does not return any data once it resolves.

const params = {
  TableName: 'Woop woop!',
  Items: [{ a: 'b' }, { c: 'd' }]
}
await dynamo.putAll(params)

New methods for query()

Query has new sibling methods that automatically paginate through resultsets for you.

queryAll(params[, pageSize])

Resolves with the entire array of matching items.

const params = {
  TableName : 'items',
  IndexName: 'articleNo-index',
  KeyConditionExpression: 'articleNo = :val',
  ExpressionAttributeValues: { ':val': articleNo }
}
const response = await dynamo.queryAll(params)
// response now contains ALL items with the articleNo, not just the first 1MB

queryIterator(params[, pageSize])

Like scanIterator, but for queries.


New methods for scan()

We've supercharged scan() for those times when you want to recurse through entire tables.

scanAll(params[, pageSize])

Resolves with the entire array of matching items.

const params = {
  TableName : 'MyTable',
  FilterExpression : 'Year = :this_year',
  ExpressionAttributeValues : {':this_year' : 2015}
}
const response = await documentClient.scanAll(params)
// response now contains ALL documents from 2015, not just the first 1MB

scanIterator(params[, pageSize[, parallelScanSegments]])

An async generator-driven approach to recursing your tables. This is a powerful tool when you have datasets that are too large to keep in memory all at once.

To spread out the workload across your table partitions you can define a number of parallelScanSegments. DynamoPlus will launch concurrent scans and yield results on the fly.

  • params - AWS.DynamoDB.DocumentClient.scan() parameters
  • pageSize - integer (Default: 100) How many items to retrieve per API call. (DynamoPlus automatically fetches all the pages regardless)
  • parallelScans - integer (Default: 1) Amount of segments to split the scan operation into. It also accepts an array of individual segment options such as LastEvaluatedKey, the length of the array then decides the amount of segments.
const usersIterator = dynamoPlus.scanIterator({ TableName: 'users' })
for await (const user of usersIterator) {
  await sendNewsletter(user.email)
}

FAQ

Can I interact with the DocumentClient directly?

Yes, its accessible via .client:

import { DescribeTableCommand } from '@aws-sdk/client-dynamodb'
import { DynamoPlus } from 'dynamo-plus'
const dynamo = new DynamoPlus()

const command = new DescribeTableCommand({ TableName: 'my-table' })
dynamo.client.send(command)

How do I upgrade from v1 to v2?

DynamoPlus 2.0.0 introduces a significant rewrite. Changes include:

  • Rewritten from the ground up using modern tools and syntax, natively producing correct type definitions

  • aws-sdk v2 has been replaced with @aws-sdk/* v3 and are now explicit dependencies

  • DynamoPlus is now a class that you instantiate with new, similar to the AWS clients

    const dynamo = new DynamoPlus({ region: 'eu-west-1' })
  • queryStream and queryStreamSync have been replaced with queryIterator

    const params = {
      TableName: 'users',
      IndexName: 'orgs-index',
      KeyConditionExpression: "organisationId = :val",
      ExpressionAttributeValues: { ":val": organisationId },
    }
    const queryResults = dynamo.queryIterator(params)
    for await (const user of queryResults) {
      console.log(user)
    }
  • scanStream and scanStreamSync have been replaced with scanIterator

    const params = {
      TableName: 'users',
    }
    const scanResults = dynamo.scanIterator(params)
    for await (const user of scanResults) {
      console.log(user)
    }