ag-common 0.0.902 → 0.0.903

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,8 @@
1
+ import { type BatchWriteCommandInput } from "@aws-sdk/lib-dynamodb";
2
+ export type DynamoWriteRequest = NonNullable<NonNullable<BatchWriteCommandInput["RequestItems"]>[string]>[number];
3
+ export declare const sendAllBatchRequests: ({ maxRetries, operationName, requests, tableName, }: {
4
+ maxRetries?: number | null;
5
+ operationName: string;
6
+ requests: DynamoWriteRequest[];
7
+ tableName: string;
8
+ }) => Promise<void>;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendAllBatchRequests = void 0;
4
+ const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
5
+ const _1 = require(".");
6
+ const sleep_1 = require("../../../common/helpers/sleep");
7
+ const withRetry_1 = require("../../../common/helpers/withRetry");
8
+ const sendAllBatchRequests = async ({ maxRetries = 3, operationName, requests, tableName, }) => {
9
+ let pending = requests;
10
+ let unprocessedRetries = 0;
11
+ while (pending.length > 0) {
12
+ // oxlint-disable-next-line no-await-in-loop -- each request depends on DynamoDB's unprocessed set
13
+ const result = await (0, withRetry_1.withRetry)(() => _1.dynamoDb.send(new lib_dynamodb_1.BatchWriteCommand({
14
+ RequestItems: { [tableName]: pending },
15
+ })), operationName, { maxRetries });
16
+ pending = result.UnprocessedItems?.[tableName] ?? [];
17
+ if (pending.length === 0) {
18
+ return;
19
+ }
20
+ if (maxRetries !== null && unprocessedRetries >= maxRetries) {
21
+ throw new Error(`${operationName}: ${pending.length} items remained unprocessed`);
22
+ }
23
+ unprocessedRetries += 1;
24
+ // oxlint-disable-next-line no-await-in-loop -- unprocessed writes require backoff before retrying
25
+ await (0, sleep_1.sleep)(Math.min(2 ** unprocessedRetries * 25, 2000));
26
+ }
27
+ };
28
+ exports.sendAllBatchRequests = sendAllBatchRequests;
@@ -1,11 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.wipeTable = exports.batchDelete = void 0;
4
- const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
5
- const _1 = require(".");
6
4
  const array_1 = require("../../../common/helpers/array");
7
5
  const async_1 = require("../../../common/helpers/async");
8
- const withRetry_1 = require("../../../common/helpers/withRetry");
6
+ const batch_1 = require("./batch");
9
7
  const get_1 = require("./get");
10
8
  const batchDelete = async (params) => {
11
9
  try {
@@ -13,15 +11,13 @@ const batchDelete = async (params) => {
13
11
  const chunked = (0, array_1.chunk)(params.keys, batchSize);
14
12
  let processed = 0;
15
13
  await (0, async_1.asyncForEach)(chunked, async (chunk) => {
16
- const batchDeleteParams = {
17
- RequestItems: {
18
- [params.tableName]: chunk.map((key) => ({
19
- DeleteRequest: { Key: { [params.pkName]: key } },
20
- })),
21
- },
22
- };
23
- await (0, withRetry_1.withRetry)(() => _1.dynamoDb.send(new lib_dynamodb_1.BatchWriteCommand(batchDeleteParams)), `batchdelete ${processed}/${params.keys.length}. size=${batchSize}`, {
24
- maxRetries: maxRetries === undefined ? 3 : maxRetries,
14
+ await (0, batch_1.sendAllBatchRequests)({
15
+ tableName: params.tableName,
16
+ requests: chunk.map((key) => ({
17
+ DeleteRequest: { Key: { [params.pkName]: key } },
18
+ })),
19
+ operationName: `batchdelete ${processed}/${params.keys.length}. size=${batchSize}`,
20
+ maxRetries,
25
21
  });
26
22
  processed += chunk.length;
27
23
  });
@@ -38,11 +38,16 @@ const executeQuery = async (params, exclusiveStartKey) => {
38
38
  eav[`:${skName.toLowerCase()}`] = skValue;
39
39
  }
40
40
  }
41
+ const projectionAttrs = params.requiredAttributeList?.reduce((acc, attr, index) => {
42
+ acc[`#proj${index}`] = attr;
43
+ return acc;
44
+ }, {});
41
45
  const queryParams = {
42
46
  TableName: params.tableName,
43
47
  KeyConditionExpression: kce,
44
48
  ExpressionAttributeNames: {
45
49
  ...ean,
50
+ ...projectionAttrs,
46
51
  ...params.filter?.attrNames,
47
52
  },
48
53
  ExpressionAttributeValues: {
@@ -53,6 +58,11 @@ const executeQuery = async (params, exclusiveStartKey) => {
53
58
  Limit: params.limit === -1 ? undefined : params.limit,
54
59
  IndexName: params.indexName,
55
60
  ExclusiveStartKey: exclusiveStartKey,
61
+ ...(params.requiredAttributeList && {
62
+ ProjectionExpression: params.requiredAttributeList
63
+ .map((_, index) => `#proj${index}`)
64
+ .join(", "),
65
+ }),
56
66
  ...(params.filter && {
57
67
  FilterExpression: params.filter.filterExpression,
58
68
  ...(params.filter.attrValues && {
@@ -6,6 +6,7 @@ const _1 = require(".");
6
6
  const array_1 = require("../../../common/helpers/array");
7
7
  const async_1 = require("../../../common/helpers/async");
8
8
  const withRetry_1 = require("../../../common/helpers/withRetry");
9
+ const batch_1 = require("./batch");
9
10
  const putDynamo = async (item, tableName, opt) => {
10
11
  const putParams = {
11
12
  TableName: tableName,
@@ -32,13 +33,11 @@ const batchWrite = async (tableName, items, opt) => {
32
33
  let processed = 0;
33
34
  const chunked = (0, array_1.chunk)(items, batchSize);
34
35
  await (0, async_1.asyncForEach)(chunked, async (chunk) => {
35
- const batchWriteParams = {
36
- RequestItems: {
37
- [tableName]: chunk.map((Item) => ({ PutRequest: { Item } })),
38
- },
39
- };
40
- await (0, withRetry_1.withRetry)(() => _1.dynamoDb.send(new lib_dynamodb_1.BatchWriteCommand(batchWriteParams)), `batchwrite ${processed}/${items.length}. size=${batchSize}`, {
41
- maxRetries: opt?.maxRetries === undefined ? 3 : opt.maxRetries,
36
+ await (0, batch_1.sendAllBatchRequests)({
37
+ tableName,
38
+ requests: chunk.map((Item) => ({ PutRequest: { Item } })),
39
+ operationName: `batchwrite ${processed}/${items.length}. size=${batchSize}`,
40
+ maxRetries: opt?.maxRetries,
42
41
  });
43
42
  processed += chunk.length;
44
43
  });
@@ -53,6 +53,8 @@ export interface DynamoQueryParams {
53
53
  */
54
54
  limit?: number;
55
55
  filter?: DynamoFilter;
56
+ /** Return only these attributes. */
57
+ requiredAttributeList?: string[];
56
58
  sortAscending?: boolean;
57
59
  /** default 3, set to null to disable retries */
58
60
  maxRetries?: number | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ag-common",
3
- "version": "0.0.902",
3
+ "version": "0.0.903",
4
4
  "license": "ISC",
5
5
  "author": "admin@gec.dev",
6
6
  "repository": {