npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@byronzeet/amava-crypto

v0.3.0

Published

High-performance SOC2-compliant encryption library with AWS KMS integration, batch processing, and intelligent caching

Downloads

630

Readme

@byronzeet/amava-crypto

High-performance SOC2-compliant encryption library with AWS KMS integration, batch processing, and intelligent caching.

Features

  • 🔐 SOC2 Compliant Encryption: AES-GCM envelope encryption with AWS KMS
  • Batch Processing: Up to 70% performance improvement with batch decryption
  • 🚀 Intelligent Caching: Multi-tier data key caching with automatic warming
  • 📊 Performance Monitoring: Built-in benchmarking and metrics collection
  • 🔄 Deterministic Hashing: Consistent hash generation for encrypted data
  • 🛡️ Type Safety: Full TypeScript support with comprehensive type definitions

Performance Improvements

Based on comprehensive benchmarking, this library delivers:

  • 37.6% average speed improvement with batch processing
  • 67.3% reduction in AWS KMS calls through intelligent caching
  • 60.9% efficiency gain in high-volume operations

Installation

npm install @byronzeet/amava-crypto

Quick Start

Basic Usage

import { AmavaCrypto } from '@byronzeet/amava-crypto';

const crypto = new AmavaCrypto({
  region: 'us-east-1',
  keyId: 'your-kms-key-id'
});

// Encrypt text
const encrypted = await crypto.encryptText('sensitive data', {
  tenantId: 'property-uuid',
  table: 'users',
  column: 'email',
  rowId: '123'
});

// Decrypt text
const decrypted = await crypto.decryptText(encrypted.ciphertext, {
  tenantId: 'property-uuid',
  table: 'users',
  column: 'email',
  rowId: '123'
});

The canonical encryption context

Every encryption call MUST pass the full canonical context — {tenantId, table, column, rowId} with non-empty values. Encryption throws if any of the four is missing, undefined, null, or empty; there is no way to mint ciphertext with an incomplete binding.

Key order in your object literal does not matter: the library serializes the context in a fixed canonical order before using it as AAD, so {rowId, table, column, tenantId} and {tenantId, table, column, rowId} produce identical envelopes. Decryption applies the same normalization and has no completeness guard — it accepts whatever context shape reproduces the stored AAD, which keeps envelopes written by older library versions readable.

There is deliberately no API that decrypts without a caller-supplied context. The AAD binding is the integrity guarantee; see docs/adr/0001 for rationale.

Batch Processing (Recommended for High Performance)

import { BatchDecryptItem } from '@byronzeet/amava-crypto';

const items: BatchDecryptItem[] = [
  {
    ciphertext: 'encrypted_data_1',
    context: { tenantId: 'property-uuid', table: 'users', column: 'email', rowId: '1' }
  },
  {
    ciphertext: 'encrypted_data_2', 
    context: { tenantId: 'property-uuid', table: 'users', column: 'email', rowId: '2' }
  }
  // ... more items
];

const result = await crypto.decryptBatch(items, {
  concurrencyPerGroup: 10,
  collectMetrics: true
});

console.log(`Processed ${result.metrics.successCount} items`);
console.log(`KMS calls: ${result.metrics.kmsCallCount}`);
console.log(`Cache hits: ${result.metrics.cacheHitCount}`);

Cache Management

// Warm cache with frequently used keys
await crypto.warmCache(['key1', 'key2', 'key3'], {
  concurrency: 5,
  priority: 'frequency'
});

// Configure tiered TTL for optimal performance
crypto.configureTieredTtl({
  frequentAccessTtl: 600000,    // 10 minutes for frequent keys
  recentAccessTtl: 300000,      // 5 minutes for recent keys
  standardTtl: 180000,          // 3 minutes for standard keys
  frequentAccessThreshold: 5,   // 5+ hits = frequent
  recentAccessThreshold: 60000  // 1 minute = recent
});

// Get cache statistics
const stats = crypto.getCacheStats();
console.log(`Local cache: ${stats.local.size}/${stats.local.maxSize}`);
console.log(`Shared cache: ${stats.shared.size}/${stats.shared.maxSize}`);

Configuration Options

AmavaCrypto Constructor

interface AmavaCryptoConfig {
  region: string;                    // AWS region
  keyId: string;                     // KMS key ID
  kmsClient?: KMSClient;            // Optional custom KMS client
  useSharedCache?: boolean;         // Enable shared caching (default: true)
  dataKeyCacheTtlMs?: number;       // Cache TTL in ms (default: 300000)
  hooks?: CryptoHooks;              // Event hooks for monitoring
}

Batch Processing Options

interface BatchDecryptOptions {
  concurrencyPerGroup?: number;     // Parallel operations per key group
  failFast?: boolean;               // Stop on first error
  collectMetrics?: boolean;         // Gather performance metrics
}

Performance Benchmarking

Run performance benchmarks to measure improvements:

npm run benchmark

This generates a detailed report showing:

  • Speed improvements vs individual operations
  • KMS call reduction percentages
  • Cache hit rates and efficiency gains
  • Scaling benefits with larger datasets

API Reference

Core Methods

encryptText(plaintext: string, context: EncryptionContext): Promise<EncryptionResult>

Encrypts text with the provided context.

decryptText(ciphertext: string, context: EncryptionContext): Promise<string>

Decrypts text with the provided context.

decryptBatch(items: BatchDecryptItem[], options?: BatchDecryptOptions): Promise<BatchDecryptResult>

Efficiently decrypts multiple items in batches.

generateDeterministicHash(data: string): string

Generates a consistent hash for the given data.

Cache Management

warmCache(keys: string[], options?: CacheWarmingOptions): Promise<CacheWarmResult>

Proactively loads data keys into cache.

intelligentCacheWarmup(tierConfig?: CacheTierConfig): Promise<IntelligentWarmupResult>

Automatically warms cache based on usage patterns.

getCacheStats(): CacheStats

Returns current cache statistics.

clearCache(): void

Clears all cached data keys.

Configuration

configureTieredTtl(config: CacheTierConfig): void

Sets up tiered TTL for different access patterns.

Types

Core Types

interface EncryptionContext {
  tenantId?: string; // REQUIRED for encryption (guard-enforced); optional in the type only so decryption can reproduce legacy stored AADs
  table: string;
  column: string;
  rowId?: string;    // REQUIRED for encryption (guard-enforced), same caveat
}

interface EncryptionResult {
  ciphertext: string;
  hash: string;
}

interface BatchDecryptItem {
  ciphertext: string;
  context: EncryptionContext;
}

interface BatchDecryptResult {
  results: Map<number, string>;
  errors: Map<number, Error>;
  metrics: BatchDecryptMetrics;
}

Performance Types

interface BatchDecryptMetrics {
  totalDuration: number;
  successCount: number;
  errorCount: number;
  keyGroupCount: number;
  kmsCallCount: number;
  cacheHitCount: number;
}

interface CacheStats {
  local: {
    size: number;
    maxSize: number;
    hitRate: number;
  };
  shared: {
    size: number;
    maxSize: number;
    hitRate: number;
  };
}

Best Practices

1. Use Batch Processing for Multiple Items

// ❌ Inefficient - individual calls
for (const item of items) {
  await crypto.decryptText(item.ciphertext, item.context);
}

// ✅ Efficient - batch processing
const result = await crypto.decryptBatch(items);

2. Enable Shared Caching

// ✅ Recommended configuration
const crypto = new AmavaCrypto({
  region: 'us-east-1',
  keyId: 'your-key-id',
  useSharedCache: true,        // Share cache across instances
  dataKeyCacheTtlMs: 300000    // 5 minute TTL
});

3. Warm Cache for Predictable Workloads

// ✅ Warm cache during application startup
const frequentKeys = await getFrequentlyUsedKeys();
await crypto.warmCache(frequentKeys, {
  concurrency: 10,
  priority: 'frequency'
});

4. Monitor Performance

// ✅ Collect metrics for optimization
const result = await crypto.decryptBatch(items, {
  collectMetrics: true
});

if (result.metrics.cacheHitCount / items.length < 0.5) {
  console.warn('Low cache hit rate - consider cache warming');
}

Migration from v0.1.x

Breaking Changes

  • decryptBatch now returns a BatchDecryptResult object instead of an array
  • Cache configuration moved to constructor options
  • Some internal method signatures changed

Migration Steps

  1. Update batch processing calls:
// v0.1.x
const results = await crypto.decryptBatch(items);

// v0.2.0
const { results, metrics } = await crypto.decryptBatch(items);
  1. Update cache configuration:
// v0.1.x
crypto.setCacheTtl(300000);

// v0.2.0
const crypto = new AmavaCrypto({
  // ... other options
  dataKeyCacheTtlMs: 300000
});

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Run npm test and npm run benchmark
  5. Submit a pull request

License

MIT License - see LICENSE file for details.

Support

For issues and questions:


Performance tested and optimized for production workloads 🚀