import { Store, SessionData } from 'express-session';
import { DynamoDBClient, CreateTableCommandInput } from '@aws-sdk/client-dynamodb';
/**
 * DynamoDBStoreOptions are the options for creating a { @link DynamoDBStore }
 */
export interface DynamoDBStoreOptions {
    /**
     * AWS v3 SDK DynamoDB client, optionally wrapped with XRay, etc.
     *
     * @default new DynamoDBClient({})
     */
    readonly dynamoDBClient?: DynamoDBClient;
    /**
     * Name of the DynamoDB table to use (and optionally create)
     *
     * @defaultValue 'sessions'
     */
    readonly tableName?: string;
    /**
     * Only update the session TTL on `touch` events if `touchAfter` seconds has passed
     * since the last time the session TTL was updated.
     *
     * Set to `0` to always update the session TTL. - This is not suggested.
     *
     * @remarks
     *
     * Writes on DynamoDB cost 5x as much as reads for sessions < 1 KB.
     *
     * Writes on DynamoDB cost 20x as much as reads for sessions >= 3 KB and < 4 KB
     * - Reading a 3.5 KB session takes 1 RCUs
     * - Writing that same 3.5 KB session takes 4 WCUs
     *
     * ### Calculating Write Capacity Units - from AWS Docs
     *
     * [Managing settings on DynamoDB provisioned capacity tables](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ProvisionedThroughput.html#ItemSizeCalculations.Writes)
     *
     * `UpdateItem` — Modifies a single item in the table. DynamoDB considers the size of the item as
     * it appears before and after the update. The provisioned throughput consumed reflects the
     * larger of these item sizes. Even if you update just a subset of the item's attributes,
     * `UpdateItem` will still consume the full amount of provisioned throughput (the larger of the
     * "before" and "after" item sizes).
     *
     * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ProvisionedThroughput.html#ItemSizeCalculations.Writes }
     *
     * @defaultValue 3600 (1 hour) or 10% of the `ttl` if `ttl` is less than 36,000 (10 hours)
     */
    readonly touchAfter?: number;
    /**
     * Hash key name of the existing DynamoDB table or name of the hash key
     * to create if the table does not exist and the `createTableOptions`
     * do not provide a hash key name.
     *
     * @defaultValue 'id'
     */
    readonly hashKey?: string;
    /**
     * Prefix to add to the `sid` in the `hashKey` written to the DynamoDB table.
     *
     * @defaultValue 'session#'
     */
    readonly prefix?: string;
    /**
     * Create the DynamoDB table if it does not exist with OnDemand capacity
     *
     * @remarks
     *
     * ⛔️ NOT SUGGESTED ⛔️: this can create the table in many accounts and regions
     * for any developer running the app locally with AWS credentials that
     * have permission to create tables. This is also a bad idea
     * because the least expensive option for relatively stable loads
     * is to use ProvisionedCapacity with Application Auto Scaling
     * configured to adjust the Read and Write capacity.
     *
     * Set to `{}` enable creation of the table with default parameters, or
     * specify additional parameters.
     *
     * @default undefined - table will not be created
     */
    readonly createTableOptions?: Partial<CreateTableCommandInput>;
    /**
     * Use Strongly Consistent Reads for session reads
     *
     * @remarks
     * Strongly Consistent Reads should rarely be needed for a session store unless
     * the values in the session are updated frequently and they must absolutely
     * be the most recent version (which is very unliley as the most recent
     * write could fail, in which case the session would not be the most
     * recent version...).
     *
     * Reasons not to use Strongly Consistent Reads:
     * - They cost 2x more than Eventually Consistent Reads
     * - They can return a 500 if there is a network error or outage
     * - They can have higher latency than Eventually Consistent Reads
     *
     * @see { @link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadConsistency.html }
     * @see { @link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html}
     *
     * @defaultValue false
     */
    readonly useStronglyConsistentReads?: boolean;
}
/**
 * DynamoDBStore is an [express-session](https://www.npmjs.com/package/express-session) store that uses
 * [DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html)
 * as the backing store.
 *
 * @remarks
 *
 * DynamoDB is an excellent choice for session stores because it is
 * a fully managed service that is highly available, durable, and
 * can scale automatically (to nearly unlimited levels) to meet demand.
 *
 * DynamoDB reads will typically return in 1-3 ms if capacity is set
 * correctly and the caller is located in the same region as the `Table`.
 *
 * ### Example of Pricing
 *
 * Disclaimer: perform your own pricing calculation, monitor your costs
 * while launching, and setup cost alerts to avoid unexpected charges.
 *
 * [Saved AWS Pricing Calculation](https://calculator.aws/#/estimate?id=fb2f0d461ab2acd6c98a107059f75a4325918bda)
 *
 * Assumptions:
 * - Using Provisioned Capacity with auto-scaling
 * - Using Eventually Consistent Reads
 * - 2 KB average session size
 * - 100k RPM (requests per minute) average load
 * - 1 million new sessions per month (~0.4 new sessions / second)
 * - 8 million existing sessions
 * - 2 million session updates / expirations per month (~0.8 updates / second)
 *
 * Pricing:
 * - Storage
 *   - 2 KB * 8 million = 16 GB of storage
 *   - 16 GB * $0.25 / GB / month = $4 / month for storage
 * - Reads
 *   - 100k RPM / 60 seconds = ~1,700 RPS (requests per second)
 *   - 1 RCU (read capacity unit) per item * 0.5 (eventually consistent reads) = 0.5 RCU per read
 *   - 1,700 RPS * 0.5 RCU per read = 850 RCUs
 *   - 850 RCUs / read * 720 hours / month * $0.00013 / RCU / hour = ~$80 / month for reads
 * - Writes
 *   - 0.4 new sessions / second + 0.8 updates / second = 1.2 WPS (writes per second)
 *   - 1.2 WPS * 2 WCU (write capacity unit) per item = 2.4 WCUs
 *   - Allocate more WCUs to handle bursts
 *   - 100 WCUs * 720 hours / month * $0.00065 / WCU / hour = ~$50 / month for writes
 * - Total
 *   - $4 / month for storage
 *   - $80 / month for reads
 *   - $50 / month for writes
 *   - $134 / month total
 */
export declare class DynamoDBStore extends Store {
    private _dynamoDBClient;
    private _ddbDocClient;
    private _createTableOptions?;
    private _tableName;
    /**
     * { @inheritDoc DynamoDBStoreOptions.tableName }
     */
    get tableName(): string;
    private _touchAfter;
    /**
     * { @inheritDoc DynamoDBStoreOptions.touchAfter }
     */
    get touchAfter(): number;
    private _useStronglyConsistentReads;
    /**
     * { @inheritDoc DynamoDBStoreOptions.useStronglyConsistentReads }
     */
    get useStronglyConsistentReads(): boolean;
    set useStronglyConsistentReads(value: boolean);
    private _hashKey;
    /**
     * { @inheritDoc DynamoDBStoreOptions.hashKey }
     */
    get hashKey(): string;
    private _prefix;
    /**
     * { @inheritDoc DynamoDBStoreOptions.prefix }
     */
    get prefix(): string;
    /**
     * Create the table if it does not exist
     * Enable TTL field on the table if configured
     *
     * @remarks
     * ⛔️ NOT SUGGESTED ⛔️: This is not recommended for production use.
     *
     * For production the table should be created with IaaC (infrastructure as code)
     * such as AWS CDK, SAM, CloudFormation, Terraform, etc.
     */
    private createTableIfNotExists;
    /**
     * Create a DynamoDB Table-based [express-session](https://www.npmjs.com/package/express-session) store.
     *
     * @remarks
     * ⛔️ NOT SUGGESTED ⛔️: `createTableOptions` is not recommended for production use.
     *
     * Note: This does not await creation of a table if `createTableOptions` is passed (which should only
     * be used in quick and dirty tests).  Use `DynamoDBStore.create()` instead to await
     * creation of the table in testing scenarios.
     */
    constructor(options: DynamoDBStoreOptions);
    /**
     * Create the store and optionally await creation of the table.
     *
     * Note: Store-created tables is not advised for production use.
     *
     * @param options DynamoDBStore options
     */
    static create(options: DynamoDBStoreOptions): Promise<DynamoDBStore>;
    get(
    /**
     * Session ID
     */
    sid: string, 
    /**
     * Callback to return the session data
     * @param err Error
     * @param session Session data
     * @returns void
     */
    callback: (err: unknown, session?: SessionData | null) => void): void;
    set(
    /**
     * Session ID
     */
    sid: string, 
    /**
     * Session data
     * @remarks
     * The `expires` field is set by the session middleware and is used
     * by DynamoDB to automatically expire the session.
     * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html}
     * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/howitworks-ttl.html}
     * @see {@link https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/time-to-live-ttl-how-to.html}
     */
    session: SessionData, 
    /**
     * Callback to return an error if the session was not saved
     * @param err Error
     * @returns void
     */
    callback?: (err?: unknown) => void): void;
    /**
     * Reset the TTL on the DynamoDB record to 100% of the original TTL
     *
     * @remarks
     * This is called by the session middleware on every single `get` request.
     */
    touch(
    /**
     * Session ID
     */
    sid: string, 
    /**
     * Session data
     */
    session: SessionData & {
        lastModified?: string;
    }, 
    /**
     * Callback to return an error if the session TTL was not updated
     */
    callback?: (err?: unknown) => void): void;
    /**
     * Destroy the session in DynamoDB
     */
    destroy(
    /**
     * Session ID
     */
    sid: string, 
    /**
     * Callback to return an error if the session was not destroyed
     * @param err Error
     * @returns void
     */
    callback?: (err?: unknown) => void): void;
    private newExpireSecondsSinceEpochUTC;
    private getTTLSeconds;
}
//# sourceMappingURL=dynamodb-store.d.ts.map