npm package: @node-tree/explorer
Description: File explorer service layer with VSCode-like architecture for virtual file systems
Author: Anderson D. Rosa
Latest version: 0.0.2

# @node-tree/explorer

A **VSCode-inspired file explorer service layer** that provides comprehensive file operations, navigation, and state management for tree-based file explorers. Built with TypeScript and designed for high-performance applications with large directory structures.

## 🎯 **Purpose & Philosophy**

This package implements the **service layer** of a file explorer following VSCode's architecture patterns. It orchestrates between:

- **[@firesystem/core](https://npmjs.com/package/@firesystem/core)**: Virtual file system abstraction
- **[@node-tree/viewport](https://npmjs.com/package/@node-tree/viewport)**: High-performance tree virtualization
- **[@node-tree/react](https://npmjs.com/package/@node-tree/react)**: React hooks for UI integration

> **🔧 Note**: This is a **service-only package** - it contains no UI components. Use `@node-tree/react` for React integration.

## 🚀 **Features**

### **📁 Complete File Operations**

- ✅ Create files/directories with smart naming
- ✅ Delete with confirmation and bulk support
- ✅ Rename with validation and conflict resolution
- ✅ Move/Copy with overwrite handling
- ✅ Duplicate with intelligent naming (`file-copy.ext`)

### **🔄 Full Undo/Redo System**

- ✅ Bounded operation history (configurable stack size)
- ✅ Complete operation reversal (files, directories, content)
- ✅ Branch handling - new operations clear future history
- ✅ Metadata tracking with affected paths

### **⌨️ VSCode-like Navigation**

- ✅ Arrow key navigation (Up/Down, Left/Right)
- ✅ Page navigation (PageUp/PageDown)
- ✅ Jump navigation (Home/End, Parent/Child)
- ✅ Smart expansion (Right arrow expands directories)
- ✅ **OPTIMIZED:** High-performance End navigation (O(1) complexity)

### **🎯 Advanced Selection Management**

- ✅ Single-click selection (VSCode behavior)
- ✅ Multi-select with Ctrl+Click (maintains previous selection)
- ✅ Range selection with Shift+Click
- ✅ Select all/clear/invert operations
- ✅ Type-specific selection (files only, directories only)
- ✅ **NEW:** `selectSingle()` method for exclusive selection

### **📋 Clipboard Operations**

- ✅ Cut/Copy/Paste with proper semantics
- ✅ Multi-paste support (copy once, paste multiple times)
- ✅ Auto-clear on cut operations
- ✅ Cross-operation clipboard persistence
- ✅ **NEW:** Memory-safe clipboard with 10,000 item limit
- ✅ **NEW:** Auto-expiring clipboard (30-minute TTL)

### **📡 Event-Driven Reactivity**

- ✅ Typed event system for all state changes
- ✅ Progress tracking for long operations
- ✅ User confirmation hooks (delete, overwrite)
- ✅ Real-time UI synchronization
- ✅ **ENHANCED:** Comprehensive error events with detailed context
- ✅ **NEW:** Operation success events for better UX feedback

## 📦 **Installation**

```bash
npm install @node-tree/explorer @firesystem/core @node-tree/viewport
# or
yarn add @node-tree/explorer @firesystem/core @node-tree/viewport
# or
pnpm add @node-tree/explorer @firesystem/core @node-tree/viewport
```

## 🏗️ **Architecture Overview**

```
┌─────────────────────────────────────────────────────────┐
│                    @node-tree/react                    │
│                 (React Hooks & UI)                     │
└─────────────────────┬───────────────────────────────────┘
                      │
┌─────────────────────▼───────────────────────────────────┐
│                @node-tree/explorer                     │
│              (Service Layer & Logic)                   │
│  ┌─────────────────┬─────────────────┬─────────────────┐ │
│  │ ExplorerService │ NavigationSvc   │ SelectionSvc    │ │
│  │ FileOpService   │ ClipboardSvc    │ HistoryManager  │ │
│  └─────────────────┴─────────────────┴─────────────────┘ │
└─────────────────────┬───────────────────────────────────┘
                      │
┌─────────────────────▼───────────────────────────────────┐
│  @firesystem/core   │    @node-tree/viewport            │
│  (Virtual FS)       │    (Tree Virtualization)         │
└─────────────────────┴───────────────────────────────────┘
```

## 🎮 **VSCode Behavior Compatibility**

### **Mouse Interactions**

- **Single Click on File** → Selects file exclusively (clears previous selection)
- **Single Click on Directory** → Selects directory and toggles expansion
- **Double Click on File** → Opens file in permanent mode
- **Double Click on Directory** → No action (VSCode ignores double-click on directories)
- **Ctrl+Click** → Toggles selection of clicked item (maintains previous selection)
- **Shift+Click** → Selects range from cursor to clicked item

### **Selection Behavior Updates (v0.0.2)**

- ✅ **Fixed:** Single click now properly selects the clicked item
- ✅ **Fixed:** Ctrl+Click maintains previous selection instead of clearing it
- ✅ **Added:** `selectSingle()` method for exclusive selection (VSCode behavior)
- ✅ **Fixed:** Double-click on directories is now properly ignored

## 🛠️ **Core Services**

### **ExplorerService** - Main Orchestrator

Central service that coordinates all explorer functionality:

```typescript
import { ExplorerService } from "@node-tree/explorer";
import { MemoryFileSystem } from "@firesystem/memory";
import { TreeViewport } from "@node-tree/viewport";

const fs = new MemoryFileSystem();
const viewport = new TreeViewport(provider, { itemHeight: 24 });
const explorer = new ExplorerService(fs, viewport, {
  confirmDelete: true,
  confirmOverwrite: true,
  maxHistorySize: 50,
});
```

### **FileOperationService** - File Operations Engine

Handles all file system operations with undo/redo support:

```typescript
// All operations return promises and emit events
await explorer.createFile("/src", "component.tsx");
await explorer.createDirectory("/src", "components");
await explorer.rename("/old-name.txt", "new-name.txt");
await explorer.delete(["/file1.txt", "/file2.txt"]);
await explorer.move(["/source.txt"], "/target-folder");
await explorer.copy(["/template.txt"], "/new-folder");
await explorer.duplicate(["/important.txt"]); // Creates important-copy.txt
```

### **NavigationService** - Tree Navigation

VSCode-like keyboard navigation:

```typescript
// Navigate tree structure
await explorer.navigateUp(); // Move cursor up
await explorer.navigateDown(); // Move cursor down
await explorer.navigateLeft(); // Collapse or go to parent
await explorer.navigateRight(); // Expand or enter directory
await explorer.navigateToFirst(); // Jump to first item
await explorer.navigateToLast(); // Jump to last item
```

### **SelectionService** - Multi-Selection

Advanced selection management:

```typescript
// Selection operations
await explorer.selectAll(); // Select all visible items
explorer.clearSelection(); // Clear all selections
explorer.selectSingle("/file.txt"); // Select only this item (clear others)
explorer.toggleSelection("/file.txt"); // Toggle single item (keep others)
await explorer.selectRange("/start", "/end"); // Select range
await explorer.invertSelection(); // Invert current selection
```

### **ClipboardService** - Cut/Copy/Paste

Full clipboard operations with memory management:

```typescript
// Clipboard operations
explorer.cut(["/file1.txt", "/file2.txt"]); // Cut files
explorer.copy(["/template.tsx"]); // Copy files
await explorer.paste("/destination"); // Paste to destination

// Check clipboard state
const clipboardState = explorer.getClipboardState();
console.log(clipboardState.hasItems); // boolean
console.log(clipboardState.operation); // 'cut' | 'copy'

// Memory-safe operations
try {
  explorer.copy(largeFileList); // Automatically limited to 10,000 items
} catch (error) {
  // Handle excessive clipboard usage
}

// Auto-expiring clipboard (30-minute TTL)
explorer.copy(["/file1.txt"]);
// ... 31 minutes later ...
console.log(explorer.canPaste()); // false (auto-cleared)
```

### **HistoryManager** - Undo/Redo System

Complete operation history:

```typescript
// History operations
await explorer.undo(); // Undo last operation
await explorer.redo(); // Redo next operation

// Check history state
const historyState = explorer.getHistoryState();
console.log(historyState.canUndo); // boolean
console.log(historyState.canRedo); // boolean
console.log(historyState.operations); // IOperation[]
```

## 🎮 **Command System**

The explorer provides a **VSCode-like command system** with categories, keybindings, and context awareness:

```typescript
// Execute commands by ID
await explorer.executeCommand("explorer.newFile");
await explorer.executeCommand("explorer.delete");
await explorer.executeCommand("explorer.selectAll");

// Get all available commands
const commands = explorer.getCommands();
commands.forEach((cmd) => {
  console.log(`${cmd.metadata.id}: ${cmd.metadata.label}`);
  console.log(`  Category: ${cmd.metadata.category}`);
  console.log(`  Keybinding: ${cmd.metadata.keybinding}`);
});

// Register custom commands
explorer.registerCommand({
  metadata: {
    id: "custom.myCommand",
    label: "My Custom Command",
    category: "Custom",
    keybinding: "Ctrl+Alt+M",
  },
  handler: async (context) => {
    // Custom logic here
  },
  enabled: (context) => context.explorer.hasSelection(),
});
```

### **Built-in Commands**

#### **File Operations**

- `explorer.newFile` - Create new file
- `explorer.newFolder` - Create new directory
- `explorer.delete` - Delete selected items
- `explorer.rename` - Rename current item
- `explorer.refresh` - Refresh tree view
- `explorer.reveal` - Reveal file in tree

#### **Navigation**

- `explorer.navigateUp/Down` - Arrow navigation
- `explorer.navigateLeft/Right` - Horizontal navigation
- `explorer.navigateToFirst/Last` - Jump navigation
- `explorer.pageUp/Down` - Page navigation

#### **Edit Operations**

- `explorer.cut` - Cut selected items
- `explorer.copy` - Copy selected items
- `explorer.paste` - Paste clipboard items
- `explorer.duplicate` - Duplicate selected items
- `explorer.undo/redo` - History operations

#### **Selection**

- `explorer.selectAll` - Select all visible
- `explorer.clearSelection` - Clear selection
- `explorer.toggleSelection` - Toggle current item
- `explorer.invertSelection` - Invert selection

## 📡 **Event System**

The explorer emits **typed events** for all state changes, enabling reactive UI updates:

```typescript
// Listen to all explorer events
explorer.on("operation:start", (event) => {
  console.log(`Starting ${event.type} on:`, event.paths);
});

explorer.on("operation:complete", (event) => {
  console.log(`Completed ${event.type} on:`, event.paths);
});

explorer.on("operation:error", (event) => {
  console.error(`Error in ${event.type}:`, event.error);
});

// Progress tracking for long operations
explorer.on("progress:start", (event) => {
  console.log(`Starting operation (${event.total} items)`);
});

explorer.on("progress:update", (event) => {
  const percent = (event.current / event.total) * 100;
  console.log(`Progress: ${percent.toFixed(1)}%`);
});

// State change notifications
explorer.on("clipboard:change", (state) => {
  updateClipboardUI(state);
});

explorer.on("history:change", (state) => {
  updateUndoRedoButtons(state);
});

// User confirmation hooks
explorer.on("confirm:delete", (event) => {
  const result = window.confirm(`Delete ${event.paths.length} items?`);
  event.confirm(result);
});

explorer.on("confirm:overwrite", (event) => {
  const result = window.confirm(`Overwrite ${event.path}?`);
  event.confirm(result);
});
```

### **Event Types**

```typescript
interface IExplorerEvents {
  // Operation lifecycle
  "operation:start": { type: OperationType; paths: string[] };
  "operation:complete": { type: OperationType; paths: string[] };
  "operation:error": { type: OperationType; error: Error };

  // Progress tracking
  "progress:start": { total: number };
  "progress:update": { current: number; total: number };
  "progress:complete": void;

  // State changes
  "clipboard:change": IClipboardState;
  "history:change": { canUndo: boolean; canRedo: boolean };

  // User confirmations
  "confirm:delete": { paths: string[]; confirm: (result: boolean) => void };
  "confirm:overwrite": { path: string; confirm: (result: boolean) => void };
}
```

## ⚡ **Performance & Memory Management**

### **Optimized Navigation**

```typescript
// High-performance End navigation - O(1) complexity
await explorer.navigateToLast(); // Uses viewport.scrollToIndex() for efficiency

// Smart fallback for large trees
// If scrollToIndex fails, gracefully falls back to visible window
```

### **Memory-Safe Clipboard**

```typescript
// Automatic limits prevent memory issues
const MAX_CLIPBOARD_ITEMS = 10000; // Built-in limit
const CLIPBOARD_TTL_MS = 30 * 60 * 1000; // 30-minute auto-expire

// Error handling for large selections
explorer.on("operation:error", (event) => {
  if (event.error.message.includes("Maximum allowed")) {
    showToast("Selection too large. Maximum 10,000 items allowed.");
  }
});
```

### **Event-Driven Error Handling**

```typescript
// Enhanced error events with detailed context
explorer.on("operation:error", (event) => {
  console.log(`Operation: ${event.type}`);
  console.log(`Error: ${event.error.message}`);
  // Handle specific error types
});

// Success events for better UX
explorer.on("operation:complete", (event) => {
  console.log(`${event.type} completed on ${event.paths.length} items`);
});
```

### **Performance Best Practices**

```typescript
// 1. Use bulk operations instead of loops
await explorer.delete(["/file1", "/file2", "/file3"]); // ✅ Good
// NOT: for (const file of files) await explorer.delete([file]); // ❌ Bad

// 2. Configure appropriate history size
const explorer = new ExplorerService(fs, viewport, {
  maxHistorySize: 100, // Adjust based on memory constraints
});

// 3. Listen to progress events for long operations
explorer.on("progress:update", (event) => {
  const percent = (event.current / event.total) * 100;
  updateProgressBar(percent);
});
```

## ⚙️ **Configuration**

```typescript
interface IExplorerConfig {
  // User confirmations
  confirmDelete?: boolean; // Default: false
  confirmOverwrite?: boolean; // Default: false

  // History settings
  maxHistorySize?: number; // Default: 50

  // File operation settings
  autoExpandOnCreate?: boolean; // Default: true
  autoSelectOnCreate?: boolean; // Default: true

  // Navigation settings
  pageNavigationSize?: number; // Default: 10
  wrapNavigation?: boolean; // Default: false
}
```

## 🔗 **Integration with React**

For React applications, use `@node-tree/react` which provides hooks that integrate seamlessly with this service layer:

```typescript
import { useExplorerService, useKeyboardShortcuts, useExplorerEvents } from '@node-tree/react';

function FileExplorer() {
  // Create explorer service
  const explorer = useExplorerService(fs, viewport, config);

  // Setup keyboard shortcuts
  const shortcuts = useKeyboardShortcuts(explorer);

  // Listen to events
  useExplorerEvents(explorer, {
    'operation:complete': (event) => {
      toast.success(`${event.type} completed successfully`);
    },
    'operation:error': (event) => {
      toast.error(`Error: ${event.error.message}`);
    }
  });

  return <YourTreeComponent />;
}
```

## 🧪 **Testing**

The package includes comprehensive tests with **90.34% coverage** and **387 test cases**:

```bash
npm test                # Run all tests
npm run test:coverage   # Run with coverage report
npm run test:watch      # Watch mode for development
```

### **Test Categories**

- **Unit Tests**: Individual service testing with mocks
- **Integration Tests**: Full FileSystem + Viewport + Explorer integration
- **Performance Tests**: Memory limits, TTL expiration, large datasets
- **Error Handling**: Comprehensive error scenarios and edge cases

### **New Test Coverage**

- ✅ Clipboard TTL and auto-expiration
- ✅ Memory limits and large selection handling
- ✅ Optimized navigation performance
- ✅ Enhanced error event handling
- ✅ Success event emissions

## 📋 **Requirements**

- **Node.js**: >=16.0.0
- **TypeScript**: >=4.8.0
- **@firesystem/core**: ^1.0.0
- **@node-tree/viewport**: workspace:\*

## 📄 **License**

MIT © Anderson D. Rosa

## 🤝 **Contributing**

This package follows VSCode architecture patterns and maintains high code quality standards:

- **🔧 TypeScript**: Fully typed with strict mode
- **🧪 Testing**: Comprehensive test suite with high coverage
- **📋 Linting**: ESLint + Prettier configuration
- **🏗️ Architecture**: Service-oriented with clear separation of concerns
- **📡 Events**: Reactive architecture with typed events
- **♻️ Operations**: Full undo/redo support for all operations

## 📝 **Changelog**

### **v0.0.2** (Latest)

- ✅ Added `selectSingle()` method for exclusive selection
- ✅ Fixed single-click selection behavior to match VSCode
- ✅ Fixed Ctrl+Click to maintain previous selection
- ✅ Fixed double-click on directories (now properly ignored)
- ✅ Improved VSCode behavior compatibility

### **v0.0.1** (Initial Release)

- Core explorer service implementation
- File operations with undo/redo
- Navigation and selection services
- Clipboard operations
- Event system
- Command registry

---

**Built for high-performance applications** that need VSCode-level file explorer functionality with complete TypeScript support and reactive architecture.