# @begin/data

> Begin Data is a durable and fast key/value document store built on top of DynamoDB

Latest version **5.0.5** (published 2024-05-18) · Apache-2.0 license · 0 weekly downloads

## Install

```sh
npm install @begin/data
pnpm add @begin/data
yarn add @begin/data
bun add @begin/data
```

## Health

**Score 23/100 (F)** — status: abandoned.

Positive: has types package; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 5.0.5 |
| Published | 2024-05-18 |
| First published | 2018-09-16 |
| Weekly downloads | 0 |
| License | Apache-2.0 |
| TypeScript types | separate (@types/begin__data) |
| Module format | CommonJS |
| Node | >=12 |
| Dependencies | 6 |
| Unpacked size | 35.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 78 |
| Maintainers | ryanblock, dam, brianleroux, beginci |
| Keywords | serverless, database, AWS, dynamodb, keyvalue, infrastructure, infra |

## Links

- npm: https://www.npmjs.com/package/@begin/data
- Repository: https://github.com/beginner-corp/begin-data
- Homepage: https://begin.com
- Issues: https://github.com/beginner-corp/begin-issues/issues
- npm.io page: https://npm.io/package/@begin/data

## Dependencies (6)

- [run-parallel](https://npm.io/package/run-parallel.md) ^1.2.0
- [@aws-lite/ssm](https://npm.io/package/@aws-lite/ssm.md) ^0.2.3
- [@begin/hashid](https://npm.io/package/@begin/hashid.md) ^1.0.0
- [run-waterfall](https://npm.io/package/run-waterfall.md) ^1.1.7
- [@aws-lite/client](https://npm.io/package/@aws-lite/client.md) ^0.21.5
- [@aws-lite/dynamodb](https://npm.io/package/@aws-lite/dynamodb.md) ^0.3.4

## Alternatives

- [@opentelemetry/exporter-zipkin](https://npm.io/package/@opentelemetry/exporter-zipkin.md) — 14.8M weekly downloads
- [pusher-js](https://npm.io/package/pusher-js.md) — 2.0M weekly downloads
- [browserify](https://npm.io/package/browserify.md) — 1.7M weekly downloads
- [sqs-consumer](https://npm.io/package/sqs-consumer.md) — 1.7M weekly downloads
- [@sanity/eventsource](https://npm.io/package/@sanity/eventsource.md) — 930.8K weekly downloads

## Recent versions

- 5.0.5 (latest) — 2024-05-18
- 5.0.0-RC.2 (RC) — 2024-01-30
- 5.0.4 — 2024-05-07
- 5.0.3 — 2024-02-09
- 5.0.2 — 2024-02-08
- 5.0.1 — 2024-02-05
- 5.0.0 — 2024-02-03
- 5.0.0-RC.1 — 2024-01-30
- 5.0.0-RC.0 — 2024-01-29
- 4.0.2 — 2022-11-25
- 4.0.2-RC.0 — 2022-11-23
- 4.0.2-RC.1 — 2022-11-23
- 4.0.1 — 2022-09-22
- 4.0.1-RC.0 — 2022-09-22
- 4.0.0 — 2022-03-10
- … 34 more at https://npm.io/package/@begin/data/versions

## README

# Begin Data
## [`@begin/data`](https://www.npmjs.com/package/@begin/data)

[![GitHub CI status](https://github.com/smallwins/begin-data/workflows/Node%20CI/badge.svg)](https://github.com/smallwins/begin-data/actions?query=workflow%3A%22Node+CI%22)

Begin Data is an easy to use, fast, and durable key/value and document store built on top of DynamoDB. Originally built for [Begin serverless apps](https://begin.com), Begin Data’s core API has three simple methods: `get`, `set`, and `destroy`.

## Concepts

Begin Data organizes itself into `table`s. A `table` contain documents which are just collections of plain Objects. Documents stored in Begin Data always have the properties `table` and `key`.

Optionally a document can also have a `ttl` property with a UNIX epoch value representing the expiry time for the document.

## Usage

Begin Data operates on one DynamoDB table named `data` with a partition key `scopeID` and a sort key of `dataID` (and, optionally, a `ttl` for expiring documents).

Example `app.arc`:

```
@app
myapp

@tables
data
  scopeID *String
  dataID **String
  ttl TTL
```

Or equivalent CloudFormation YAML:

```yaml
AWSTemplateFormatVersion: "2010-09-09"
Resources:
    BeginData:
        Type: "AWS::DynamoDB::Table"
        Properties:
            TableName: "data"
            BillingMode: "PAY_PER_REQUEST"
            KeySchema:
              -
                AttributeName: "scopeID"
                KeyType: "HASH"
              -
                AttributeName: "dataID"
                KeyType: "RANGE"
            SSESpecification:
                Enabled: "false"
            TimeToLiveSpecification:
                AttributeName: "ttl"
                Enabled: "TRUE"
```

> Note: projects not based on [Architect](https://arc.codes) will need a `BEGIN_DATA_TABLE_NAME` environment variable. You can also use this env var to override and name the table anything you want. This also allows for multiple apps to share a single table.

### API

```javascript
let data = require('@begin/data')
```

The core API is three methods:

- `data.get(params[, callback])` → `[Promise]` for retreiving data
- `data.set(params[, callback])` → `[Promise]` for writing data
- `data.destroy(params[, callback])` → `[Promise]` for removing data

Additional helper methods are also made available:

- `data.incr(params[, callback])` → `[Promise]` increment an attribute on a document
- `data.decr(params[, callback])` → `[Promise]` decrement an attribute on a document
- `data.count(params[, callback])` → `[Promise]` get the number of documents for a given table

All methods accept a params object and, optionally, a Node-style errback. If no errback is supplied, a Promise is returned. All methods support `async`/`await`.

#### Writes

Save a document in a `table` by `key`. Remember: `table` is required; `key` is optional.

```javascript
let taco = await data.set({
  table: 'tacos',
  key: 'al-pastor'
})
```

All documents have a `key`. If no `key` is given, `set` will generate a unique `key`.

```javascript
let token = await data.set({
  table: 'tokens',
})
// {table:'tokens', key:'LCJkYX9jYWwidW50RhSU'}
```

Batch save multiple documents at once by passing an Array of Objects.

```javascript
let collection = await data.set([
  {table: 'ppl', name:'brian', email:'b@brian.io'},
  {table: 'ppl', name:'sutr0', email:'sutr0@brian.io'},
  {table: 'tacos', key:'pollo'},
  {table: 'tacos', key:'carnitas'},
])
```

#### Reads

Read a document by `key`:

```javascript
let yum = await data.get({
  table: 'tacos',
  key: 'baja'
})
```

Batch read by passing an Array of Objects. With these building blocks you can construct secondary indexes and joins, like one-to-many and many-to-many.

```javascript
await data.get([
  {table:'tacos', key:'carnitas'},
  {table:'tacos', key:'al-pastor'},
])
```

#### Destroy

Delete a document by `key`.

```javascript
await data.destroy({
  table: 'tacos',
  key: 'pollo'
})
```

Batch delete documents by passing an Array of Objects.

```javascript
await data.destroy([
  {table:'tacos', key:'carnitas'},
  {table:'tacos', key:'al-pastor'},
])
```

## Pagination

Large sets of data can not be retrieved in one call because the underlying `get` api paginates results.
In this case use the `for await` syntax with a limit set to get paginated data.

```javascript
let pages = data.page({ table:'ppl', limit:25 })
let count = 0  
for await (let page of pages) {
  console.log(page)
  count++
}
```

## Additional Superpowers

- Documents can be expired by setting `ttl` to an UNIX epoch in the future.
- Atomic counters: `data.incr` and `data.decr`

See the tests for more examples!

## Patterns

Coming soon! Detailed guides for various data persistence tasks:

- Denormalizing
- Pagination
- Counters
- Secondary indexes
- One to many
- Many to many

## More

- [Try out Begin Data on Begin!](https://begin.com)
- [Learn more about Begin Data](https://docs.begin.com/en/data/begin-data/)

---
_Source: https://npm.io/package/@begin/data · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
