or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

archive-control.mdarchive-creation.mdcontent-operations.mdformat-options.mdindex.md
tile.json

archive-control.mddocs/

Archive Finalization and Control

Methods for controlling the archiving process including finalization, abortion, progress tracking, and utility functions.

Capabilities

Finalize Archive

Finalizes the archive and prevents further appending. This method must be called to complete archive creation.

/**
 * Finalizes archive and prevents further appending
 * @returns {Promise} Promise that resolves when archive is complete
 * @throws {Error} If archive is already finalizing or finalized
 */
finalize();

Usage Examples:

const archiver = require('archiver');
const fs = require('fs');

const archive = archiver('zip');
const output = fs.createWriteStream('archive.zip');

archive.pipe(output);

// Add content to archive
archive
  .append('Hello World', { name: 'hello.txt' })
  .file('/path/to/file.pdf', { name: 'document.pdf' });

// Finalize archive - required to complete
archive.finalize().then(() => {
  console.log('Archive finalized successfully');
}).catch(err => {
  console.error('Error finalizing archive:', err);
});

// Alternative: using async/await
async function createArchive() {
  try {
    await archive.finalize();
    console.log('Archive created successfully');
  } catch (err) {
    console.error('Archive creation failed:', err);
  }
}

Abort Archive Process

Aborts the archiving process with best-effort cleanup, removing pending tasks and ending streams.

/**
 * Aborts archiving process with best-effort cleanup
 * @returns {Archiver} This instance for chaining
 */
abort();

Usage Examples:

const archive = archiver('zip');
const output = fs.createWriteStream('archive.zip');

archive.pipe(output);

// Start adding content
archive.append('Some content', { name: 'file.txt' });

// Abort if needed (e.g., on error or user cancellation)
archive.on('error', (err) => {
  console.error('Archive error:', err);
  archive.abort(); // Clean up and stop processing
});

// Or abort programmatically
setTimeout(() => {
  archive.abort(); // Cancel after timeout
}, 5000);

Get Archive Progress

Returns the current byte length emitted by the archive, useful for progress tracking.

/**
 * Returns current byte length emitted by archive
 * @returns {number} Current byte length of archive data
 */
pointer();

Usage Examples:

const archive = archiver('zip');

// Track progress during archiving
archive.on('progress', (progressData) => {
  const bytesProcessed = archive.pointer();
  console.log(`Archive size: ${bytesProcessed} bytes`);
  console.log(`Entries processed: ${progressData.entries.processed}/${progressData.entries.total}`);
});

// Check final size after finalization
archive.finalize().then(() => {
  const finalSize = archive.pointer();
  console.log(`Final archive size: ${finalSize} bytes`);
});

Event-Driven Progress Tracking

The archiver emits various events to track progress and handle errors during the archiving process.

Progress Event

/**
 * Progress event data structure
 */
interface ProgressData {
  entries: {
    /** Total entries appended to archive */
    total: number;
    /** Entries processed so far */
    processed: number;
  };
  fs: {
    /** Total bytes from filesystem entries */
    totalBytes: number;
    /** Processed bytes from filesystem entries */
    processedBytes: number;
  };
}

// Event: 'progress' - Fired with processing progress information
archive.on('progress', (progressData) => {
  // Handle progress updates
});

Usage Examples:

archive.on('progress', (progressData) => {
  const entryPercent = (progressData.entries.processed / progressData.entries.total * 100).toFixed(1);
  const bytesPercent = (progressData.fs.processedBytes / progressData.fs.totalBytes * 100).toFixed(1);
  
  console.log(`Entries: ${entryPercent}% (${progressData.entries.processed}/${progressData.entries.total})`);
  console.log(`Bytes: ${bytesPercent}% (${progressData.fs.processedBytes}/${progressData.fs.totalBytes})`);
});

Entry Event

// Event: 'entry' - Fired when entry is processed and appended
archive.on('entry', (entryData) => {
  // Handle individual entry completion
});

Usage Examples:

archive.on('entry', (entryData) => {
  console.log(`Added entry: ${entryData.name}`);
  console.log(`Entry size: ${entryData.stats ? entryData.stats.size : 'unknown'} bytes`);
});

Warning Event

// Event: 'warning' - Fired for non-blocking errors (e.g., file not found)
archive.on('warning', (err) => {
  // Handle non-critical warnings
});

Usage Examples:

archive.on('warning', (err) => {
  if (err.code === 'ENOENT') {
    console.warn(`Warning: File not found: ${err.path}`);
    // Continue processing despite missing file
  } else {
    console.warn('Archive warning:', err.message);
  }
});

Error Event

// Event: 'error' - Fired for blocking errors that stop processing
archive.on('error', (err) => {
  // Handle critical errors
});

Usage Examples:

archive.on('error', (err) => {
  console.error('Archive error:', err.message);
  console.error('Error code:', err.code);
  
  // Clean up on error
  archive.abort();
  
  // Handle specific error types
  switch (err.code) {
    case 'ENOENT':
      console.error('File or directory not found');
      break;
    case 'EACCES':
      console.error('Permission denied');
      break;
    default:
      console.error('Unknown error occurred');
  }
});

Complete Workflow Example

const archiver = require('archiver');
const fs = require('fs');

async function createArchiveWithFullControl() {
  const archive = archiver('zip', { zlib: { level: 9 } });
  const output = fs.createWriteStream('complete-archive.zip');
  
  // Set up event handlers
  archive.on('progress', (progressData) => {
    const percent = (progressData.entries.processed / progressData.entries.total * 100).toFixed(1);
    console.log(`Progress: ${percent}%`);
  });
  
  archive.on('entry', (entryData) => {
    console.log(`Added: ${entryData.name}`);
  });
  
  archive.on('warning', (err) => {
    console.warn('Warning:', err.message);
  });
  
  archive.on('error', (err) => {
    console.error('Error:', err.message);
    throw err;
  });
  
  // Pipe archive to output
  archive.pipe(output);
  
  try {
    // Add content
    archive
      .append('Hello World', { name: 'hello.txt' })
      .file('/path/to/file.pdf', { name: 'document.pdf' })
      .directory('/path/to/dir', 'archived-dir');
    
    // Finalize and wait for completion
    await archive.finalize();
    
    console.log(`Archive created successfully: ${archive.pointer()} bytes`);
    
  } catch (err) {
    console.error('Failed to create archive:', err);
    archive.abort();
    throw err;
  }
}

Error Handling

Archive control errors that may be thrown:

  • FINALIZING - Archive is already finalizing, cannot perform operation
  • ABORTED - Archive was aborted, cannot perform operation
  • QUEUECLOSED - Queue is closed, cannot append more entries
  • NOENDMETHOD - Format module missing finalize/end method