Create a CAFS store controller for pnpm's content addressable file system
npx @tessl/cli install tessl/npm-pnpm--create-cafs-store@1000.0.0PNPM Create CAFS Store provides functionality for creating Content Addressable File System (CAFS) store controllers within the pnpm package manager ecosystem. It implements package importing mechanisms with multiple strategies for efficiently managing package files in the pnpm global store.
pnpm add @pnpm/create-cafs-storeimport { createCafsStore, createPackageImporterAsync, type CafsLocker } from "@pnpm/create-cafs-store";For CommonJS:
const { createCafsStore, createPackageImporterAsync } = require("@pnpm/create-cafs-store");import { createCafsStore } from "@pnpm/create-cafs-store";
// Create a CAFS store controller
const cafsStore = createCafsStore("/path/to/pnpm-store", {
packageImportMethod: "hardlink",
ignoreFile: (filename) => filename.startsWith("."),
});
// The store provides CAFS operations and package importing
const tempDir = await cafsStore.tempDir();
const result = cafsStore.addFilesFromDir("/path/to/package");
// Import a package using the built-in importer
const importResult = cafsStore.importPackage("/target/path", {
filesResponse: packageFilesResponse,
force: false,
requiresBuild: false,
});Creates a complete CAFS store controller with package importing capabilities.
function createCafsStore(
storeDir: string,
opts?: {
ignoreFile?: (filename: string) => boolean;
importPackage?: ImportIndexedPackage;
packageImportMethod?: 'auto' | 'hardlink' | 'copy' | 'clone' | 'clone-or-copy';
cafsLocker?: CafsLocker;
}
): Cafs;Parameters:
storeDir (string): Directory path for the CAFS storeopts (optional object): Configuration options
ignoreFile: Function to determine if a file should be ignored during operationsimportPackage: Custom package importer function for indexed packagespackageImportMethod: Strategy for importing package files (defaults to 'auto')cafsLocker: CAFS locking mechanism to prevent concurrent access issuesReturns: Cafs interface providing complete store operations including file operations, package importing, and temporary directory creation
Creates an asynchronous package importer function with configurable import strategies.
function createPackageImporterAsync(
opts: {
importIndexedPackage?: ImportIndexedPackageAsync;
packageImportMethod?: 'auto' | 'hardlink' | 'copy' | 'clone' | 'clone-or-copy';
storeDir: string;
}
): ImportPackageFunctionAsync;Parameters:
opts (object): Configuration options
importIndexedPackage: Custom async package importer for indexed packagespackageImportMethod: Strategy for importing package filesstoreDir: Directory path for the storeReturns: ImportPackageFunctionAsync function that can import packages asynchronously
Type for CAFS locking mechanism to prevent concurrent access to the same files.
type CafsLocker = Map<string, number>;A map that tracks file paths to lock counts, ensuring thread-safe operations on the CAFS store.
Complete interface returned by createCafsStore providing all CAFS operations.
interface Cafs {
/** Directory path of the CAFS store */
storeDir: string;
/** Add files from a directory to the store */
addFilesFromDir: (dir: string) => AddToStoreResult;
/** Add files from a tarball buffer to the store */
addFilesFromTarball: (buffer: Buffer) => AddToStoreResult;
/** Get the file path for an index file in CAFS */
getIndexFilePathInCafs: (integrity: string | IntegrityLike, fileType: FileType) => string;
/** Get the file path based on file mode in CAFS */
getFilePathByModeInCafs: (integrity: string | IntegrityLike, mode: number) => string;
/** Import a package using the configured strategy */
importPackage: ImportPackageFunction;
/** Create a temporary directory within the store */
tempDir: () => Promise<string>;
}Types for package import operations with different synchronization models.
type ImportPackageFunction = (
to: string,
opts: ImportPackageOpts
) => { isBuilt: boolean; importMethod: string | undefined };
type ImportPackageFunctionAsync = (
to: string,
opts: ImportPackageOpts
) => Promise<{ isBuilt: boolean; importMethod: string | undefined }>;
type ImportIndexedPackage = (
to: string,
opts: ImportOptions
) => string | undefined;
type ImportIndexedPackageAsync = (
to: string,
opts: ImportOptions
) => Promise<string | undefined>;Configuration options for package import operations.
interface ImportPackageOpts {
/** Disable relinking of local directory dependencies */
disableRelinkLocalDirDeps?: boolean;
/** Whether the package requires building */
requiresBuild?: boolean;
/** Cache key for side effects */
sideEffectsCacheKey?: string;
/** Package files response containing file metadata */
filesResponse: PackageFilesResponse;
/** Force import even if files exist */
force: boolean;
/** Keep existing modules directory */
keepModulesDir?: boolean;
}
interface ImportOptions {
/** Disable relinking of local directory dependencies */
disableRelinkLocalDirDeps?: boolean;
/** Map of file paths to their locations in CAFS */
filesMap: Record<string, string>;
/** Force import operation */
force: boolean;
/** Source location of the resolved package */
resolvedFrom: ResolvedFrom;
/** Keep existing modules directory */
keepModulesDir?: boolean;
}Types for package file metadata and responses.
type PackageFiles = Record<string, PackageFileInfo>;
interface PackageFileInfo {
/** Last check timestamp (nullable for backward compatibility) */
checkedAt?: number;
/** File integrity hash */
integrity: string;
/** File permission mode */
mode: number;
/** File size in bytes */
size: number;
}
type PackageFilesResponse = {
/** Source location of resolved package */
resolvedFrom: ResolvedFrom;
/** Import method to use for this package */
packageImportMethod?: 'auto' | 'hardlink' | 'copy' | 'clone' | 'clone-or-copy';
/** Side effects applied to package files */
sideEffects?: SideEffects;
/** Whether package requires building */
requiresBuild: boolean;
} & (
| { unprocessed?: false; filesIndex: Record<string, string> }
| { unprocessed: true; filesIndex: PackageFiles }
);
type ResolvedFrom = 'store' | 'local-dir' | 'remote';
type SideEffects = Record<string, SideEffectsDiff>;
interface SideEffectsDiff {
/** Files deleted by side effects */
deleted?: string[];
/** Files added by side effects */
added?: PackageFiles;
}Additional types for file operations and store results.
type FileType = 'exec' | 'nonexec' | 'index';
interface FilesIndex {
/** File metadata mapped by filename */
[filename: string]: {
/** File permission mode */
mode: number;
/** File size in bytes */
size: number;
} & FileWriteResult;
}
interface FileWriteResult {
/** Timestamp when file integrity was checked */
checkedAt: number;
/** Full path to the file in CAFS */
filePath: string;
/** File integrity hash */
integrity: IntegrityLike;
}
type IntegrityLike = string | {
algorithm: string;
digest: string;
options?: any[];
};
interface AddToStoreResult {
/** File integrity mappings with metadata */
filesIndex: FilesIndex;
/** Package manifest if available */
manifest?: DependencyManifest;
}
type DependencyManifest = {
/** Package name */
name?: string;
/** Package version */
version?: string;
/** Package dependencies */
dependencies?: Record<string, string>;
/** Other manifest properties */
[key: string]: any;
};The package supports multiple import strategies optimized for different use cases:
'auto': Automatically choose the best method based on package and system characteristics'hardlink': Use hard links for maximum efficiency when filesystem supports it'copy': Copy files, ensuring complete independence but using more disk space'clone': Clone files with copy-on-write semantics when available'clone-or-copy': Attempt cloning, fall back to copying if not supportedThe system automatically selects 'clone-or-copy' for packages that require building to ensure build outputs don't affect the original store files.
import { createPackageImporterAsync } from "@pnpm/create-cafs-store";
// Create a custom async importer
const packageImporter = createPackageImporterAsync({
storeDir: "/path/to/store",
packageImportMethod: "clone-or-copy",
});
// Use in package installation
const result = await packageImporter("/target/path", {
filesResponse: packageFilesResponse,
force: false,
requiresBuild: true,
});
console.log(`Package imported using: ${result.importMethod}`);
console.log(`Package was pre-built: ${result.isBuilt}`);import { createCafsStore } from "@pnpm/create-cafs-store";
const store = createCafsStore("/pnpm-store", {
ignoreFile: (filename) => {
// Ignore dotfiles and temporary files
return filename.startsWith(".") || filename.endsWith(".tmp");
},
packageImportMethod: "hardlink",
});
// Add files with filtering applied
const result = store.addFilesFromDir("/package/source");The package integrates with pnpm's error handling system. Common error scenarios include:
CafsLocker to prevent concurrent modifications to the same filesPackageFilesResponse must contain valid integrity hashes and file metadata