UNPKG

@aws-lambda-powertools/idempotency

Version:

The idempotency package for the Powertools for AWS Lambda (TypeScript) library. It provides options to make your Lambda functions idempotent and safe to retry.

85 lines (84 loc) 2.84 kB
import { IdempotencyConfig } from './IdempotencyConfig.js'; import { IdempotencyHandler } from './IdempotencyHandler.js'; const isContext = (arg) => { return (arg !== undefined && arg !== null && typeof arg === 'object' && 'getRemainingTimeInMillis' in arg); }; const isFnHandler = (fn, args) => { // get arguments of function return (fn !== undefined && fn !== null && typeof fn === 'function' && isContext(args[1])); }; const isOptionsWithDataIndexArgument = (options) => { return (options !== undefined && options !== null && typeof options === 'object' && 'dataIndexArgument' in options); }; /** * Use function wrapper to make your function idempotent. * @example * ```ts * // this is your processing function with an example record { transactionId: '123', foo: 'bar' } * const processRecord = (record: Record<string, unknown>): any => { * // you custom processing logic * return result; * }; * * // we use wrapper to make processing function idempotent with DynamoDBPersistenceLayer * const processIdempotently = makeIdempotent(processRecord, { * persistenceStore: new DynamoDBPersistenceLayer() * dataKeywordArgument: 'transactionId', // keyword argument to hash the payload and the result * }); * * export const handler = async ( * _event: EventRecords, * _context: Context * ): Promise<void> => { * for (const record of _event.records) { * const result = await processIdempotently(record); * // do something with the result * } * * return Promise.resolve(); * }; * * @param fn - the function to make idempotent * @param options - the options to configure the idempotency behavior * ``` */ function makeIdempotent(fn, options) { const { persistenceStore, config, keyPrefix } = options; const idempotencyConfig = config ? config : new IdempotencyConfig({}); if (!idempotencyConfig.isEnabled()) return fn; return function (...args) { let functionPayloadToBeHashed; if (isFnHandler(fn, args)) { idempotencyConfig.registerLambdaContext(args[1]); functionPayloadToBeHashed = args[0]; } else { if (isOptionsWithDataIndexArgument(options)) { functionPayloadToBeHashed = args[options.dataIndexArgument]; } else { functionPayloadToBeHashed = args[0]; } } return new IdempotencyHandler({ functionToMakeIdempotent: fn, idempotencyConfig: idempotencyConfig, persistenceStore: persistenceStore, keyPrefix: keyPrefix, functionArguments: args, functionPayloadToBeHashed, thisArg: this, }).handle(); }; } export { makeIdempotent };