Functionality for storing data in the cache with automatic integrity hash generation, metadata support, and streaming capabilities.
Stores data in the cache with a human-readable key, automatically generating a content integrity hash.
/**
* Stores data in cache with key
* @param {string} cache - Path to cache directory
* @param {string} key - Cache key for the data
* @param {Buffer|string} data - Data to store
* @param {object} opts - Options object
* @param {string[]} [opts.algorithms=['sha512']] - Hash algorithms to use
* @param {object} [opts.metadata] - User-defined metadata to store with entry
* @param {boolean|object} [opts.memoize] - Enable memoization of stored data
* @param {number} [opts.size] - Expected data size for verification
* @param {number} [opts.time] - Custom timestamp (default: Date.now())
* @returns {Promise<string>} Promise resolving to content integrity hash
*/
function put(cache, key, data, opts = {});Usage Examples:
const cacache = require('cacache');
// Basic storage
const integrity = await cacache.put('./cache', 'my-key', 'Hello World');
console.log('Stored with integrity:', integrity);
// With metadata
const integrity = await cacache.put('./cache', 'user-data', userData, {
metadata: {
version: '1.0',
source: 'api',
timestamp: Date.now()
}
});
// With custom algorithms
const integrity = await cacache.put('./cache', 'secure-data', sensitiveData, {
algorithms: ['sha256', 'sha512']
});
// With memoization
const integrity = await cacache.put('./cache', 'frequent-data', data, {
memoize: true
});
// With size verification
const integrity = await cacache.put('./cache', 'verified-data', data, {
size: data.length
});Returns a writable stream for storing data in the cache, useful for large files or streaming data sources.
/**
* Returns writable stream for storing data
* @param {string} cache - Path to cache directory
* @param {string} key - Cache key for the data
* @param {object} opts - Options object
* @param {string[]} [opts.algorithms=['sha512']] - Hash algorithms to use
* @param {object} [opts.metadata] - User-defined metadata to store with entry
* @param {boolean|object} [opts.memoize] - Enable memoization of stored data
* @param {number} [opts.size] - Expected data size for verification
* @param {number} [opts.time] - Custom timestamp (default: Date.now())
* @returns {WritableStream} Writable stream with events: integrity, size
*/
function put.stream(cache, key, opts = {});The returned stream emits the following events:
integrity - Content integrity hash when storage completessize - Final content size in byteserror - Error if storage failsUsage Examples:
const fs = require('fs');
// Stream file to cache
const writeStream = cacache.put.stream('./cache', 'large-file');
writeStream.on('integrity', (integrity) => {
console.log('File stored with integrity:', integrity);
});
writeStream.on('size', (size) => {
console.log('File size:', size);
});
fs.createReadStream('./input.txt').pipe(writeStream);
// Stream with metadata
const writeStream = cacache.put.stream('./cache', 'api-response', {
metadata: {
url: 'https://api.example.com/data',
timestamp: Date.now()
}
});
// Stream with promise-based completion
const writeStream = cacache.put.stream('./cache', 'streaming-data');
await new Promise((resolve, reject) => {
writeStream.on('integrity', resolve);
writeStream.on('error', reject);
// Write data chunks
writeStream.write('chunk 1\n');
writeStream.write('chunk 2\n');
writeStream.end('final chunk');
});
// Stream HTTP response to cache
const https = require('https');
https.get('https://example.com/data', (response) => {
const writeStream = cacache.put.stream('./cache', 'http-data', {
metadata: {
statusCode: response.statusCode,
headers: response.headers,
url: 'https://example.com/data'
}
});
response.pipe(writeStream);
writeStream.on('integrity', (integrity) => {
console.log('HTTP response cached with integrity:', integrity);
});
});Check if content already exists before storing to avoid duplicate writes:
// Check if we already have this content
const existingIntegrity = 'sha512-abc123...'; // from previous operation
const hasContent = await cacache.get.hasContent('./cache', existingIntegrity);
if (!hasContent) {
const integrity = await cacache.put('./cache', 'my-key', newData);
console.log('Stored new content:', integrity);
} else {
console.log('Content already exists, skipping storage');
}Update cache entries atomically by writing to a new key first:
// Store updated data with temporary key
const tempKey = `${originalKey}.tmp.${Date.now()}`;
const integrity = await cacache.put('./cache', tempKey, newData, {
metadata: { ...originalMetadata, updated: Date.now() }
});
// Remove old entry and update key atomically
await cacache.rm.entry('./cache', originalKey);
await cacache.put('./cache', originalKey, newData, {
metadata: { ...originalMetadata, updated: Date.now() }
});
await cacache.rm.entry('./cache', tempKey);Store multiple related items efficiently:
// Store multiple files concurrently
const files = ['file1.txt', 'file2.txt', 'file3.txt'];
const results = await Promise.all(
files.map(async (filename) => {
const data = await fs.readFile(filename);
const integrity = await cacache.put('./cache', filename, data, {
metadata: {
originalPath: filename,
mtime: (await fs.stat(filename)).mtime
}
});
return { filename, integrity };
})
);
console.log('Stored files:', results);Use custom memoization objects for fine-grained control:
// Create custom memoization cache
const customMemo = new Map();
// Store with custom memoization
const integrity = await cacache.put('./cache', 'memo-data', data, {
memoize: customMemo
});
// Check memoization
const memoKey = `key:./cache:memo-data`;
if (customMemo.has(memoKey)) {
console.log('Data is memoized');
}Writing operations may encounter various errors:
try {
const integrity = await cacache.put('./cache', 'my-key', data);
console.log('Success:', integrity);
} catch (error) {
switch (error.code) {
case 'ENOSPC':
console.error('Insufficient disk space');
break;
case 'EACCES':
console.error('Permission denied');
break;
case 'EMFILE':
console.error('Too many open files');
break;
default:
console.error('Unexpected error:', error);
}
}put() for small data (< 1MB) that fits in memoryput.stream() for large files or streaming data sources// Single algorithm (fastest)
await cacache.put('./cache', 'key', data, {
algorithms: ['sha512']
});
// Multiple algorithms (more secure, slower)
await cacache.put('./cache', 'key', data, {
algorithms: ['sha256', 'sha512', 'sha1']
});