4.3.0 • Published 3 years ago

@typemon/dynamon v4.3.0

Weekly downloads
120
License
MIT
Repository
gitlab
Last release
3 years ago

Dynamon - version license typescript-version gitlab-pipeline coverage

Starting from version 4.0.0, AWS SDK version 3 is supported, and version 2 is no longer supported.

Please check the link for more information on version 3.

If you are using AWS SDK version 2, use version 3.x.x.

Version 3.x.x can be found at the link below.

Features

Usage

Install the package.

$ npm install @typemon/dynamon

Import and instantiate Dynamon.

import { Dynamon } from '@typemon/dynamon';

const dynamon: Dynamon = new Dynamon();

You can configure the client yourself.

import { Dynamon } from '@typemon/dynamon';
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';

const client: DynamoDBClient = new DynamoDBClient(configuration);
const dynamon: Dynamon = new Dynamon(client);

The expression specification can be used immediately without any further action.

dynamon.update({
    tableName: 'example',
    primaryKey: {
        foo: 'bar',
    },
    updateExpressionSpec: update(
        set(path, value),
        set(path, plus(path, value)),
        set(path, minus(path, value)),
        set(path, listAppend(path, value)),
        set(path, ifNotExists(path, value)),
        remove(path),
        add(path, value),
        del(path, value),
    ),
});

If you use multiple expression specifications for an operation, you must use a scope. But Dynamon handles it automatically. See the Scope section for more information.

dynamon.query({
    tableName: 'example',
    keyConditionExpressionSpec: and(
        equal(path, value),
        notEqual(path, value),
        less(path, value),
        lessOrEqual(path, value),
        greater(path, value),
        greaterOrEqual(path, value),
    ),
    filterExpressionSpec: or(
        parenthesize(
            inList(path, value),
        ),
        not(
            between(path, value, value),
        ),
        attributeExists(path),
        attributeNotExists(path),
        attributeType(path, value),
        beginsWith(path, value),
        contains(path, value),
    ),
    projectionExpressionSpec: project(
        path,
        path,
        path,
    ),
});

Pagination

There are many methods and options for pagination. Check it out.

  • Using the skipEmptyPage option skips empty pages.
  • The index of the page represents the page number, starting at 0. May not be sequential when using the

Paginator

Pagination can be easily handled without implementing recursion using asynchronous iterators. Paginator is disposable. Do not reuse.

const paginator: Dynamon.Paginator<Item> = dynamon.query$({
    tableName: 'example',
    keyConditionExpressionSpec: equal('foo', 'bar'),
});

for await (const page of paginator) {
    ...
}

You can check the total scanned count, count, and index through the paginator. The index represents the last page number, starting at -1.

paginator.scannedCount;
paginator.count;
paginator.index;

Page Concatenation

You can concatenate pages by conditionally continuing pagination. In this example code, pagination continues until the count reaches 100 or the index reaches 4. When used with the skipEmptyPage option, empty pages are skipped and the predicate is not called. Therefore, be careful as pagination may continue unintentionally.

  • The index passed to the predicate represents the number of concatenated pages, starting at 0.
  • Indexes may not be sequential when used with the skipEmptyPage option.
dynamon.scan({
    tableName: 'example',
    filterExpressionSpec: equal('foo', 'bar'),
    limit: 100,
    concatenateWhile: (page: Dynamon.Page, index: number): boolean => Check.less(page.count, 100) && Check.less(index, 4),
});

Batch Operations

Batch operations have a limit on the number of items, but don't worry. Dynamon automatically splits the provided operations. However, operations returned due to an internal processing failure or exceeding the provisioned throughput of the table are not retried and must be retried manually. For more information on unprocessed items, please refer to the official documentation.

Special Functions

Here are some special functions. The parse and substitute functions are rarely used directly, but it is important to understand how they work as other functions use these functions internally. More details can be found in the Operand Conversion section.

size

This function can be used with almost any conditional expression.

equal(size(path), size(path));
notEqual(size(path), size(path));

less(size(path), size(path));
lessOrEqual(size(path), size(path));

greater(size(path), size(path));
greaterOrEqual(size(path), size(path));

inList(size(path), [size(path)]);
between(size(path), size(path), size(path));

contains(path, size(path));

parse

This function parses the path and returns an expression specification representing the path.

parse('typemon.dynamon');
{
    expression: '#0.#1',
    names: {
        '#0': 'typemon',
        '#1': 'dynamon'
    }
}

If the path contains characters in the following list, they must be escaped.

  • .
  • [
  • ]
  • \
parse('\\\\\\.\\[\\]');
{
    expression: '#0',
    names: {
        '#0': '\\.[]'
    }
}

If the path is invalid during parsing, it throws a related error.

  • PathSyntaxError
  • InvalidIndexError

substitute

This function replaces the value with a placeholder and returns an expression specification representing the value.

substitute(value);
{
    expression: ':0',
    values: {
        ':0': value
    }
}

Scope

If you use Dynamon, it is handled automatically, so you do not need to use it yourself.

Placeholder conflicts occur when using multiple expression specifications in an operation. This occurs because the expression specification is lazy-evaluated and the alias is generated with auto increment. Therefore, when using multiple expression specifications in an operation, you must use a scope. The scope is disposable. Do not reuse.

const scope: ExpressionSpec.Scope = new ExpressionSpec.Scope();
const conditionExpressionSpec: ExpressionSpec = equal('b', false);
const updateExpressionSpec: ExpressionSpec = update(
    set('a', true),
    remove('b'),
);

scope.evaluate(conditionExpressionSpec);
scope.evaluate(updateExpressionSpec);
scope.names;
scope.values;
#0 = :0
SET #1 = :1 REMOVE #0
{
    '#0': 'b',
    '#1': 'a'
}
{
    ':0': false,
    ':1': true
}

Lazy Evaluation

All expression specifications are lazily evaluated to eliminate duplicate names or values ​​and increase reusability. When accessing the properties of an expression specification, the expression specification is created and cached. Therefore, it may appear as an empty object when logging.

const expressionSpec: ExpressionSpec = equal('foo', 'bar');

expressionSpec;
expressionSpec.expression;
expressionSpec;
{}
#0 = :0
{
    expression: '#0 = :0',
    names: {
        '#0': 'foo'
    },
    values: {
        ':0': 'bar'
    }
}

Operand Conversion

If the operand is not an expression specification, the parse function or the substitute function is used to convert the operand to an expression specification, and it is already determined which function will be used. In most expressions, you can use both paths and values ​​as operands, but the conversion can create unintended expression specifications. If necessary, use conversion functions directly to ensure that the expression specification is created as intended. What functions are used in the conversion is in the comments of the expression functions.

equal(substitute('foo'), parse('bar'));
{
    expression: ':0 = #0',
    names: {
        '#0': 'bar'
    },
    values: {
        ':0': 'foo'
    }
}
4.3.0

3 years ago

4.2.0

3 years ago

4.1.0

3 years ago

4.0.0

3 years ago

3.0.0

4 years ago

3.0.0-rc.0

4 years ago

3.0.0-next.7

4 years ago

3.0.0-next.6

4 years ago

3.0.0-next.5

4 years ago

3.0.0-next.4

4 years ago

3.0.0-next.3

4 years ago

3.0.0-next.2

4 years ago

3.0.0-next.1

4 years ago

3.0.0-next.0

4 years ago

2.0.1

4 years ago

2.0.0

4 years ago

1.3.0

4 years ago

1.2.0

4 years ago

1.1.0

4 years ago

1.0.0

4 years ago