or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-pnpm--create-cafs-store

Create a CAFS store controller for pnpm's content addressable file system

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@pnpm/create-cafs-store@1000.0.x

To install, run

npx @tessl/cli install tessl/npm-pnpm--create-cafs-store@1000.0.0

0

# PNPM Create CAFS Store

1

2

PNPM 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.

3

4

## Package Information

5

6

- **Package Name**: @pnpm/create-cafs-store

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `pnpm add @pnpm/create-cafs-store`

10

11

## Core Imports

12

13

```typescript

14

import { createCafsStore, createPackageImporterAsync, type CafsLocker } from "@pnpm/create-cafs-store";

15

```

16

17

For CommonJS:

18

19

```javascript

20

const { createCafsStore, createPackageImporterAsync } = require("@pnpm/create-cafs-store");

21

```

22

23

## Basic Usage

24

25

```typescript

26

import { createCafsStore } from "@pnpm/create-cafs-store";

27

28

// Create a CAFS store controller

29

const cafsStore = createCafsStore("/path/to/pnpm-store", {

30

packageImportMethod: "hardlink",

31

ignoreFile: (filename) => filename.startsWith("."),

32

});

33

34

// The store provides CAFS operations and package importing

35

const tempDir = await cafsStore.tempDir();

36

const result = cafsStore.addFilesFromDir("/path/to/package");

37

38

// Import a package using the built-in importer

39

const importResult = cafsStore.importPackage("/target/path", {

40

filesResponse: packageFilesResponse,

41

force: false,

42

requiresBuild: false,

43

});

44

```

45

46

## Capabilities

47

48

### Create CAFS Store

49

50

Creates a complete CAFS store controller with package importing capabilities.

51

52

```typescript { .api }

53

function createCafsStore(

54

storeDir: string,

55

opts?: {

56

ignoreFile?: (filename: string) => boolean;

57

importPackage?: ImportIndexedPackage;

58

packageImportMethod?: 'auto' | 'hardlink' | 'copy' | 'clone' | 'clone-or-copy';

59

cafsLocker?: CafsLocker;

60

}

61

): Cafs;

62

```

63

64

**Parameters:**

65

- `storeDir` (string): Directory path for the CAFS store

66

- `opts` (optional object): Configuration options

67

- `ignoreFile`: Function to determine if a file should be ignored during operations

68

- `importPackage`: Custom package importer function for indexed packages

69

- `packageImportMethod`: Strategy for importing package files (defaults to 'auto')

70

- `cafsLocker`: CAFS locking mechanism to prevent concurrent access issues

71

72

**Returns:** `Cafs` interface providing complete store operations including file operations, package importing, and temporary directory creation

73

74

### Create Package Importer (Async)

75

76

Creates an asynchronous package importer function with configurable import strategies.

77

78

```typescript { .api }

79

function createPackageImporterAsync(

80

opts: {

81

importIndexedPackage?: ImportIndexedPackageAsync;

82

packageImportMethod?: 'auto' | 'hardlink' | 'copy' | 'clone' | 'clone-or-copy';

83

storeDir: string;

84

}

85

): ImportPackageFunctionAsync;

86

```

87

88

**Parameters:**

89

- `opts` (object): Configuration options

90

- `importIndexedPackage`: Custom async package importer for indexed packages

91

- `packageImportMethod`: Strategy for importing package files

92

- `storeDir`: Directory path for the store

93

94

**Returns:** `ImportPackageFunctionAsync` function that can import packages asynchronously

95

96

## Types

97

98

### CafsLocker

99

100

Type for CAFS locking mechanism to prevent concurrent access to the same files.

101

102

```typescript { .api }

103

type CafsLocker = Map<string, number>;

104

```

105

106

A map that tracks file paths to lock counts, ensuring thread-safe operations on the CAFS store.

107

108

### Cafs Interface

109

110

Complete interface returned by `createCafsStore` providing all CAFS operations.

111

112

```typescript { .api }

113

interface Cafs {

114

/** Directory path of the CAFS store */

115

storeDir: string;

116

117

/** Add files from a directory to the store */

118

addFilesFromDir: (dir: string) => AddToStoreResult;

119

120

/** Add files from a tarball buffer to the store */

121

addFilesFromTarball: (buffer: Buffer) => AddToStoreResult;

122

123

/** Get the file path for an index file in CAFS */

124

getIndexFilePathInCafs: (integrity: string | IntegrityLike, fileType: FileType) => string;

125

126

/** Get the file path based on file mode in CAFS */

127

getFilePathByModeInCafs: (integrity: string | IntegrityLike, mode: number) => string;

128

129

/** Import a package using the configured strategy */

130

importPackage: ImportPackageFunction;

131

132

/** Create a temporary directory within the store */

133

tempDir: () => Promise<string>;

134

}

135

```

136

137

### Import Function Types

138

139

Types for package import operations with different synchronization models.

140

141

```typescript { .api }

142

type ImportPackageFunction = (

143

to: string,

144

opts: ImportPackageOpts

145

) => { isBuilt: boolean; importMethod: string | undefined };

146

147

type ImportPackageFunctionAsync = (

148

to: string,

149

opts: ImportPackageOpts

150

) => Promise<{ isBuilt: boolean; importMethod: string | undefined }>;

151

152

type ImportIndexedPackage = (

153

to: string,

154

opts: ImportOptions

155

) => string | undefined;

156

157

type ImportIndexedPackageAsync = (

158

to: string,

159

opts: ImportOptions

160

) => Promise<string | undefined>;

161

```

162

163

### Import Options

164

165

Configuration options for package import operations.

166

167

```typescript { .api }

168

interface ImportPackageOpts {

169

/** Disable relinking of local directory dependencies */

170

disableRelinkLocalDirDeps?: boolean;

171

172

/** Whether the package requires building */

173

requiresBuild?: boolean;

174

175

/** Cache key for side effects */

176

sideEffectsCacheKey?: string;

177

178

/** Package files response containing file metadata */

179

filesResponse: PackageFilesResponse;

180

181

/** Force import even if files exist */

182

force: boolean;

183

184

/** Keep existing modules directory */

185

keepModulesDir?: boolean;

186

}

187

188

interface ImportOptions {

189

/** Disable relinking of local directory dependencies */

190

disableRelinkLocalDirDeps?: boolean;

191

192

/** Map of file paths to their locations in CAFS */

193

filesMap: Record<string, string>;

194

195

/** Force import operation */

196

force: boolean;

197

198

/** Source location of the resolved package */

199

resolvedFrom: ResolvedFrom;

200

201

/** Keep existing modules directory */

202

keepModulesDir?: boolean;

203

}

204

```

205

206

### Package Files Types

207

208

Types for package file metadata and responses.

209

210

```typescript { .api }

211

type PackageFiles = Record<string, PackageFileInfo>;

212

213

interface PackageFileInfo {

214

/** Last check timestamp (nullable for backward compatibility) */

215

checkedAt?: number;

216

217

/** File integrity hash */

218

integrity: string;

219

220

/** File permission mode */

221

mode: number;

222

223

/** File size in bytes */

224

size: number;

225

}

226

227

type PackageFilesResponse = {

228

/** Source location of resolved package */

229

resolvedFrom: ResolvedFrom;

230

231

/** Import method to use for this package */

232

packageImportMethod?: 'auto' | 'hardlink' | 'copy' | 'clone' | 'clone-or-copy';

233

234

/** Side effects applied to package files */

235

sideEffects?: SideEffects;

236

237

/** Whether package requires building */

238

requiresBuild: boolean;

239

} & (

240

| { unprocessed?: false; filesIndex: Record<string, string> }

241

| { unprocessed: true; filesIndex: PackageFiles }

242

);

243

244

type ResolvedFrom = 'store' | 'local-dir' | 'remote';

245

246

type SideEffects = Record<string, SideEffectsDiff>;

247

248

interface SideEffectsDiff {

249

/** Files deleted by side effects */

250

deleted?: string[];

251

252

/** Files added by side effects */

253

added?: PackageFiles;

254

}

255

```

256

257

### File and Store Types

258

259

Additional types for file operations and store results.

260

261

```typescript { .api }

262

type FileType = 'exec' | 'nonexec' | 'index';

263

264

interface FilesIndex {

265

/** File metadata mapped by filename */

266

[filename: string]: {

267

/** File permission mode */

268

mode: number;

269

/** File size in bytes */

270

size: number;

271

} & FileWriteResult;

272

}

273

274

interface FileWriteResult {

275

/** Timestamp when file integrity was checked */

276

checkedAt: number;

277

/** Full path to the file in CAFS */

278

filePath: string;

279

/** File integrity hash */

280

integrity: IntegrityLike;

281

}

282

283

type IntegrityLike = string | {

284

algorithm: string;

285

digest: string;

286

options?: any[];

287

};

288

289

interface AddToStoreResult {

290

/** File integrity mappings with metadata */

291

filesIndex: FilesIndex;

292

293

/** Package manifest if available */

294

manifest?: DependencyManifest;

295

}

296

297

type DependencyManifest = {

298

/** Package name */

299

name?: string;

300

/** Package version */

301

version?: string;

302

/** Package dependencies */

303

dependencies?: Record<string, string>;

304

/** Other manifest properties */

305

[key: string]: any;

306

};

307

```

308

309

## Package Import Methods

310

311

The package supports multiple import strategies optimized for different use cases:

312

313

- **`'auto'`**: Automatically choose the best method based on package and system characteristics

314

- **`'hardlink'`**: Use hard links for maximum efficiency when filesystem supports it

315

- **`'copy'`**: Copy files, ensuring complete independence but using more disk space

316

- **`'clone'`**: Clone files with copy-on-write semantics when available

317

- **`'clone-or-copy'`**: Attempt cloning, fall back to copying if not supported

318

319

The system automatically selects `'clone-or-copy'` for packages that require building to ensure build outputs don't affect the original store files.

320

321

## Usage Patterns

322

323

### Custom Import Strategy

324

325

```typescript

326

import { createPackageImporterAsync } from "@pnpm/create-cafs-store";

327

328

// Create a custom async importer

329

const packageImporter = createPackageImporterAsync({

330

storeDir: "/path/to/store",

331

packageImportMethod: "clone-or-copy",

332

});

333

334

// Use in package installation

335

const result = await packageImporter("/target/path", {

336

filesResponse: packageFilesResponse,

337

force: false,

338

requiresBuild: true,

339

});

340

341

console.log(`Package imported using: ${result.importMethod}`);

342

console.log(`Package was pre-built: ${result.isBuilt}`);

343

```

344

345

### Store with Custom File Filtering

346

347

```typescript

348

import { createCafsStore } from "@pnpm/create-cafs-store";

349

350

const store = createCafsStore("/pnpm-store", {

351

ignoreFile: (filename) => {

352

// Ignore dotfiles and temporary files

353

return filename.startsWith(".") || filename.endsWith(".tmp");

354

},

355

packageImportMethod: "hardlink",

356

});

357

358

// Add files with filtering applied

359

const result = store.addFilesFromDir("/package/source");

360

```

361

362

## Error Handling

363

364

The package integrates with pnpm's error handling system. Common error scenarios include:

365

366

- **Store Directory Access**: Ensure the store directory exists and is writable

367

- **File System Permissions**: Import methods may fail if target directories aren't writable

368

- **Concurrent Access**: Use `CafsLocker` to prevent concurrent modifications to the same files

369

- **Invalid Package Data**: `PackageFilesResponse` must contain valid integrity hashes and file metadata