npm package: @keylog-parser/core
Description: Modular, plugin-based keylog parser library with infinite extensibility
Latest version: 1.0.0

# 🔐 Keylog Parser

[![npm version](https://img.shields.io/npm/v/@keylog-parser/core.svg)](https://www.npmjs.com/package/@keylog-parser/core)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue.svg)](https://www.typescriptlang.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Tests](https://img.shields.io/badge/tests-371%20passing-brightgreen.svg)](./tests)

A powerful, extensible keylog parser with plugin architecture for desktop and mobile platforms. Parse keystroke logs from any format into readable text with full TypeScript support.

## Features

✅ **Zero Configuration** - Works immediately with sensible defaults
✅ **Cross-Platform** - Desktop (US QWERTY) & Mobile (Android) support
✅ **Plugin Architecture** - 5 plugin types for infinite extensibility
✅ **International Input** - IME, dead keys, accents (é, ñ, ä, ç)
✅ **Full TypeScript** - Complete type safety and IntelliSense
✅ **Event-Driven** - Real-time parsing events
✅ **Cursor Tracking** - Optional position and selection tracking
✅ **High Performance** - Built-in metrics and optimization

## Installation

```bash
npm install @keylog-parser/core
```

## Quick Start

```typescript
import { parseKeylog } from '@keylog-parser/core';

// Parse keystroke logs to text - one line!
const text = parseKeylog("[SHIFT]hello[SHIFT][Space]world[Enter]");
// Returns: "Hello world\n"
```

**No configuration needed!** Ready to use out of the box.

## API

### Simple API

```typescript
import { parseKeylog, parseKeylogFull, getKeylogStats } from '@keylog-parser/core';

// Get text only
const text = parseKeylog("[A][B][C]");
// "abc"

// Get statistics only
const stats = getKeylogStats("[SHIFT]hello[SHIFT][Enter]");
// { totalKeys: 7, characters: 5, words: 1, lines: 2, ... }

// Get full result with text, stats, state, and performance
const result = parseKeylogFull("[SHIFT]hello[SHIFT][Enter]");
// {
//   text: "Hello\n",
//   stats: { totalKeys: 7, characters: 5, ... },
//   state: { modifiers: {...}, cursor: {...}, ... },
//   performance: { duration: 2.5, tokensProcessed: 7, ... }
// }
```

### Advanced Configuration

```typescript
import { KeylogParser } from '@keylog-parser/core';
import {
  bracketFormat,
  usQwertyLayout,
  androidQwertyLayout,
  modifierHandler,
  clipboardHandler,
  basicKeysHandler
} from '@keylog-parser/core';

const parser = new KeylogParser()
  .use(bracketFormat)
  .use(usQwertyLayout)        // Desktop keyboard
  // .use(androidQwertyLayout)  // Or mobile keyboard
  .use(modifierHandler)
  .use(clipboardHandler)
  .use(basicKeysHandler)
  .configure({
    trackCursor: true,
    extractMetadata: true,
    enableDeadKeys: true,
    debug: false,
  });

const result = parser.parse(keylogData);
```

## Platform Support

### Desktop (US QWERTY)

```typescript
import { usQwertyLayout } from '@keylog-parser/core';

const parser = new KeylogParser().use(usQwertyLayout);
const text = parseKeylog("[SHIFT]h[SHIFT]ello");
// "Hello"
```

### Mobile (Android)

```typescript
import { androidQwertyLayout } from '@keylog-parser/core';

const parser = new KeylogParser().use(androidQwertyLayout);
const text = parseKeylog("[SHIFT]h[SHIFT]ello[Space]world");
// "Hello world"
```

Android virtual keyboard fully supported with identical shift mapping and special character handling.

## Plugin System

### Plugin Types

| Type | Purpose | Examples |
|------|---------|----------|
| **Format** | Tokenize raw input | `[KEY]`, `<KEY>`, JSON |
| **Layout** | Map keys to characters | QWERTY, AZERTY, Android |
| **Handler** | Process special keys | Modifiers, clipboard, IME |
| **Metadata** | Extract metadata | Timestamps, window titles |
| **Transform** | Post-process output | Trim, uppercase, cleanup |

### Built-in Plugins

**Formats:**
- `bracketFormat` - Parse `[KEY]` format (default)

**Layouts:**
- `usQwertyLayout` - US QWERTY desktop keyboard
- `androidQwertyLayout` - Android virtual keyboard

**Handlers:**
- `modifierHandler` - Shift, Ctrl, Alt, Meta/Win
- `clipboardHandler` - Copy, Cut, Paste operations
- `basicKeysHandler` - Space, Enter, Backspace, Tab, navigation keys
- `letterKeyHandler` - Single-letter key processing
- `cursorTrackingHandler` - Arrow keys and cursor position
- `deadKeyHandler` - Accent composition (é, ñ, ä)

### Creating Custom Plugins

#### Format Plugin

```typescript
import { FormatPlugin } from '@keylog-parser/core';

const angleFormat: FormatPlugin = {
  name: 'angle-format',
  version: '1.0.0',
  type: 'format',
  priority: 10,

  tokenize(input: string, state: ParserState): Token[] {
    // Parse <KEY> format
    const regex = /<([^>]+)>/g;
    const tokens: Token[] = [];
    let match;

    while ((match = regex.exec(input)) !== null) {
      tokens.push({
        type: 'key',
        value: match[1],
        raw: match[0]
      });
    }
    return tokens;
  },

  canHandle(input: string): number {
    // Return confidence 0-1
    return input.includes('<') && input.includes('>') ? 0.9 : 0;
  }
};

parser.use(angleFormat);
```

#### Layout Plugin

```typescript
import { LayoutPlugin } from '@keylog-parser/core';

const azertyLayout: LayoutPlugin = {
  name: 'fr-azerty',
  version: '1.0.0',
  type: 'layout',
  locale: 'fr-FR',
  priority: 10,

  mapKey(key: string, modifiers: ModifierState): string | null {
    if (key.length === 1) {
      if (modifiers.shift && key === '1') return '&';
      if (modifiers.shift && key === 'a') return 'A';
      return key;
    }
    return null;
  },

  getShiftChar(key: string): string | null {
    const map: Record<string, string> = {
      '1': '&', '2': 'é', '3': '"', '4': "'", '5': '(',
      '6': '-', '7': 'è', '8': '_', '9': 'ç', '0': 'à'
    };
    return map[key] || null;
  }
};

parser.use(azertyLayout);
```

#### Handler Plugin

```typescript
import { HandlerPlugin } from '@keylog-parser/core';

const emojiHandler: HandlerPlugin = {
  name: 'emoji-handler',
  version: '1.0.0',
  type: 'handler',
  priority: 60,

  process(token: Token, state: ParserState): Token | null {
    if (token.type === 'key' && token.value === 'Heart') {
      return { ...token, type: 'text', value: '❤️' };
    }
    return token;
  },

  canProcess(token: Token): boolean {
    return token.type === 'key' && token.value === 'Heart';
  }
};

parser.use(emojiHandler);
```

#### Transform Plugin

```typescript
import { TransformPlugin } from '@keylog-parser/core';

const cleanupTransform: TransformPlugin = {
  name: 'cleanup',
  version: '1.0.0',
  type: 'transform',
  priority: 100,

  transform(output: string, state: ParserState): string {
    return output.trim().replace(/\s+/g, ' ');
  }
};

parser.use(cleanupTransform);
```

## Advanced Features

### Event System

```typescript
parser
  .on('parse:start', (data) => console.log('Parsing started'))
  .on('parse:end', (result) => console.log('Parsing complete'))
  .on('token:processed', ({ token, index }) => console.log('Token:', token))
  .on('error', (error) => console.error('Error:', error));

const result = parser.parse(keylog);
```

### Clipboard Operations

```typescript
const input = 'hello[Ctrl+C][Ctrl+V][Space]world';
const result = parseKeylog(input);
console.log(result);
// "hellohello world"
```

### Cursor Tracking

```typescript
const result = parseKeylogFull('[A][B][C][Left][Left]', {
  trackCursor: true
});

console.log(result.cursor);
// { line: 0, column: 1, absolute: 1 }
```

### Dead Key Composition

```typescript
const input = "[´][e][~][n]"; // Accent + letter
const result = parseKeylog(input, { enableDeadKeys: true });
console.log(result);
// "éñ"
```

### Metadata Extraction

```typescript
import { MetadataPlugin } from '@keylog-parser/core';

const timestampPlugin: MetadataPlugin = {
  name: 'timestamp-parser',
  version: '1.0.0',
  type: 'metadata',
  priority: 1,

  extract(token: Token): Record<string, any> | null {
    if (token.type === 'metadata' && token.value.startsWith('Timestamp:')) {
      return {
        timestamp: new Date(token.value.split(':')[1])
      };
    }
    return null;
  }
};

parser.use(timestampPlugin);
const result = parser.parse('[Timestamp:2024-01-01T12:00:00Z][A][B]', {
  extractMetadata: true
});

console.log(result.metadata);
// { timestamp: Date(...) }
```

### Performance Metrics

```typescript
const result = parseKeylogFull(largeKeylog);

console.log(result.performance);
// {
//   duration: 42.5,          // ms
//   tokensProcessed: 15234,
//   pluginsExecuted: 5
// }
```

## Configuration Options

```typescript
interface ParserConfig {
  trackCursor?: boolean;       // Track cursor position
  trackSelection?: boolean;    // Track text selection
  extractMetadata?: boolean;   // Extract metadata
  enableIME?: boolean;         // IME composition support
  enableDeadKeys?: boolean;    // Dead key composition
  strict?: boolean;            // Strict error mode
  debug?: boolean;             // Debug logging
}
```

## Architecture

```
Parser Pipeline:
┌─────────┐    ┌────────────────┐    ┌──────────────────┐    ┌──────────────┐
│  Input  │ -> │ Format Plugins │ -> │ Layout + Handler │ -> │   Transform  │ -> Result
└─────────┘    └────────────────┘    └──────────────────┘    └──────────────┘
                                              ↓
                                      ┌──────────────────┐
                                      │ Metadata Plugins │
                                      └──────────────────┘
```

1. **Format plugins** tokenize raw input into structured tokens
2. **Layout plugins** map keys to characters based on keyboard layout
3. **Handler plugins** process special keys (modifiers, clipboard, etc.)
4. **Metadata plugins** extract metadata in parallel
5. **Transform plugins** post-process the final output

## Plugin Priority Guidelines

- **Format:** 1-50 (lower runs first)
- **Modifier handlers:** 1-10
- **Clipboard handlers:** 10-20
- **Letter/Basic handlers:** 40-50
- **Complex handlers (IME, Dead Keys):** 80-100
- **Transforms:** 100+

## Examples

### Parse Real-World Keylog

```typescript
const keylog = `
[SHIFT]h[SHIFT]ello[Space][SHIFT]w[SHIFT]orld[Enter]
[SHIFT]t[SHIFT]his[Space]is[Space]a[Space]test[Enter]
[Ctrl+C][Ctrl+V]
`;

const result = parseKeylogFull(keylog);

console.log(result.text);
// "Hello World\nThis is a test\nThis is a test"

console.log(result.stats);
// {
//   totalKeys: 45,
//   characters: 35,
//   words: 8,
//   lines: 3,
//   ...
// }
```

### Multi-Platform Support

```typescript
// Desktop parser
const desktopParser = new KeylogParser()
  .use(bracketFormat)
  .use(usQwertyLayout)
  .use(modifierHandler)
  .use(basicKeysHandler);

// Mobile parser
const mobileParser = new KeylogParser()
  .use(bracketFormat)
  .use(androidQwertyLayout)  // Android keyboard
  .use(modifierHandler)
  .use(basicKeysHandler);

// Use appropriate parser
const platform = detectPlatform();
const parser = platform === 'android' ? mobileParser : desktopParser;
const result = parser.parse(keylog);
```

## Testing

This library includes 371 comprehensive tests covering:

- Core parser functionality
- All plugin types
- Format tokenization
- Layout mappings
- Handler processing
- Integration scenarios
- Real-world edge cases

```bash
npm test              # Run all tests
npm run test:watch   # Watch mode
npm run test:coverage # Coverage report
```

## Contributing

Contributions are welcome! Please follow these guidelines:

1. **Creating Plugins:**
   - Implement the appropriate plugin interface
   - Set proper priority (lower = earlier execution)
   - Handle errors gracefully
   - Document your plugin with examples

2. **Code Quality:**
   - Write TypeScript with strict mode
   - Add tests for new features
   - Follow existing code style
   - Update documentation

3. **Pull Requests:**
   - Describe changes clearly
   - Include test coverage
   - Update README if needed

## License

MIT © [Your Name]

## Support

- 📝 [Documentation](https://github.com/natnaelbelayneh/keylog-parser)
- 🐛 [Issue Tracker](https://github.com/natnaelbelayneh/keylog-parser/issues)
- 💬 [Discussions](https://github.com/natnaelbelayneh/keylog-parser/discussions)

## Changelog

### 1.0.0 (2025-01-18)

- Initial release
- Desktop (US QWERTY) support
- Android virtual keyboard support
- 5 plugin types (format, layout, handler, metadata, transform)
- 371 comprehensive tests
- Full TypeScript support
- Event-driven architecture
- Cursor tracking
- Dead key composition
- Clipboard operations