npm package: @seawingai/wingdb
Description: A json, csv, file, folder based database for fast MVP & SaaS development
Author: Rafey Husain Syed
Latest version: 1.0.0

# WingDb

[![npm version](https://badge.fury.io/js/@seawingai%2Fwingdb.svg)](https://badge.fury.io/js/@seawingai%2Fwingdb)
[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

A lightweight, file-based database library for fast MVP and SaaS development. WingDb provides multiple storage providers (JSON, CSV, files, folders) with a simple, unified API for rapid prototyping and small to medium-scale applications.

## Features

- 📁 **Multiple Storage Providers**: JSON, CSV, files, and folder-based storage
- ⚡ **Lightweight & Fast**: No external database dependencies
- 🔧 **TypeScript Support**: Full type definitions and IntelliSense
- 🎯 **Simple API**: Easy-to-use interface for common database operations
- 🧪 **Comprehensive Testing**: Well-tested with Jest
- 📊 **Flexible Data Models**: Support for structured and unstructured data
- 🔄 **Auto-backup**: Built-in backup functionality
- 📝 **Logging**: Integrated logging with WingLog

## Installation

```bash
npm install @seawingai/wingdb
# or
pnpm add @seawingai/wingdb
# or
yarn add @seawingai/wingdb
```

## Quick Start

```typescript
import { WingDb, JsonTable, FileTable } from '@seawingai/wingdb';

// Create a custom database class
class MyDatabase extends WingDb {
  get tables() {
    return {
      users: { ctor: JsonTable, file: 'users.json' },
      config: { ctor: FileTable, file: 'config' }
    };
  }
}

// Initialize database
const db = new MyDatabase('./data');

// Load all tables
await db.load();

// Save user data
await db.setItem('users', 'user1', JSON.stringify({
  id: 'user1',
  name: 'John Doe',
  email: 'john@example.com'
}));

// Get user data
const userData = await db.get('users');
console.log(userData);
```

## Storage Providers

### 1. JsonTable - JSON-based Storage

Perfect for structured data with IDs.

```typescript
import { JsonTable } from '@seawingai/wingdb';

// Define your data type
interface User {
  id: string;
  name: string;
  email: string;
  age?: number;
}

// Create table instance
const usersTable = new JsonTable<User>(db, 'users.json');

// Load data
await usersTable.load();

// Add user
usersTable.set({
  id: 'user1',
  name: 'John Doe',
  email: 'john@example.com',
  age: 30
});

// Get user by ID
const user = usersTable.get('user1');

// Filter users
const youngUsers = usersTable.filter({ age: 30 });

// Save to file
await usersTable.save();
```

### 2. DelimitedTable - CSV-based Storage

Ideal for tabular data and spreadsheet-like operations.

```typescript
import { DelimitedTable } from '@seawingai/wingdb';

// Create CSV table
const csvTable = new DelimitedTable('./data/employees.csv', ',', [
  'id', 'name', 'department', 'salary'
]);

// Load CSV data
await csvTable.load();

// Add employee
csvTable.set({
  id: 'emp1',
  name: 'Jane Smith',
  department: 'Engineering',
  salary: '75000'
});

// Save as CSV
await csvTable.save();
```

### 3. FileTable - File-based Storage

Store individual files with metadata.

```typescript
import { FileTable } from '@seawingai/wingdb';

// Create file table for text files
const textFiles = new FileTable(db, 'documents', '.txt');

// Load all .txt files
await textFiles.load();

// Set file content
textFiles.set('readme', 'This is the README content');

// Get file content
const content = textFiles.get('readme');

// Save all files
await textFiles.save();
```

### 4. FolderTable - Folder-based Storage

Manage folder structures and paths.

```typescript
import { FolderTable } from '@seawingai/wingdb';

// Create folder table
const projects = new FolderTable(db, 'projects');

// Load folder structure
await projects.load();

// Add project folder
projects.set('project1', '/path/to/project1');

// Get project path
const projectPath = projects.get('project1');

// Save folder structure
await projects.save();
```

## Advanced Usage

### Custom Database Implementation

```typescript
import { WingDb, JsonTable, FileTable } from '@seawingai/wingdb';

class BlogDatabase extends WingDb {
  get tables() {
    return {
      posts: { ctor: JsonTable, file: 'posts.json' },
      users: { ctor: JsonTable, file: 'users.json' },
      assets: { ctor: FileTable, file: 'assets' },
      uploads: { ctor: FolderTable, file: 'uploads' }
    };
  }

  // Custom methods
  async getPost(id: string) {
    const postsTable = this.getJsonTable('posts');
    await postsTable.load();
    return postsTable.get(id);
  }

  async createPost(post: any) {
    const postsTable = this.getJsonTable('posts');
    await postsTable.load();
    postsTable.set(post);
    await postsTable.save();
  }

  async getPostsByAuthor(authorId: string) {
    const postsTable = this.getJsonTable('posts');
    await postsTable.load();
    return postsTable.filter({ authorId });
  }
}

// Usage
const blogDb = new BlogDatabase('./blog-data');
await blogDb.load();

// Create post
await blogDb.createPost({
  id: 'post1',
  title: 'My First Post',
  content: 'Hello World!',
  authorId: 'user1',
  createdAt: new Date().toISOString()
});

// Get post
const post = await blogDb.getPost('post1');
```

### Data Filtering and Queries

```typescript
// Filter by multiple criteria
const activeUsers = usersTable.filter({
  status: 'active',
  age: 25
});

// Get all items
const allUsers = usersTable.filter({});

// Complex filtering (custom implementation)
const premiumUsers = Array.from(usersTable).filter(user => 
  user.subscription === 'premium' && user.lastLogin > '2024-01-01'
);
```

### Backup and Recovery

```typescript
// Automatic backup on save
await usersTable.save(true);

// Manual backup
await usersTable.backup('./backups/users-backup.json');

// Load from backup
const backupTable = new JsonTable(db, 'backup-users.json');
await backupTable.load();
```

### Error Handling

```typescript
try {
  await db.load();
  await db.setItem('users', 'user1', userData);
} catch (error) {
  console.error('Database operation failed:', error);
  // Handle error appropriately
}
```

## API Reference

### WingDb (Abstract Base Class)

#### Constructor
```typescript
constructor(dbPath: string)
```

#### Methods
- `load(): Promise<void>` - Load all tables
- `loadTable(tableName: string): Promise<void>` - Load specific table
- `get(tableName: string): Promise<any>` - Get table data as JSON
- `set(tableName: string, json: string): Promise<void>` - Set table data from JSON
- `setItem(tableName: string, id: string, json: string): Promise<void>` - Set individual item

#### Protected Methods
- `getTable(tableName: string): any` - Get table instance
- `getJsonTable<T>(tableName: string): JsonTable<T>` - Get JSON table
- `getFileTable(tableName: string): FileTable` - Get file table

### JsonTable

#### Methods
- `load(create?: boolean): Promise<T[]>` - Load data from file
- `save(backup?: boolean): Promise<void>` - Save data to file
- `get(id: string): T | undefined` - Get item by ID
- `set(row: T, unique?: boolean): boolean` - Set item
- `filter(filters: Record<string, any>): T[]` - Filter items
- `clear(): Promise<void>` - Clear all data
- `backup(path: string): Promise<void>` - Create backup

### DelimitedTable

#### Methods
- `load(create?: boolean): Promise<T[]>` - Load CSV data
- `save(): Promise<void>` - Save as CSV
- `set(row: T, unique?: boolean): boolean` - Add row
- `get(id: string): T | undefined` - Get row by ID

### FileTable

#### Methods
- `load(): Promise<void>` - Load files
- `save(): Promise<void>` - Save files
- `get(key: string): string | undefined` - Get file content
- `set(key: string, value: string): void` - Set file content
- `toJson(): Promise<string>` - Export as JSON

### FolderTable

#### Methods
- `load(create?: boolean): Promise<void>` - Load folder structure
- `save(): Promise<void>` - Save folder structure
- `get(id: string): T | undefined` - Get folder path
- `set(key: string, value: string): void` - Set folder path
- `toJson(): Promise<string>` - Export as JSON

## Examples

### E-commerce Application

```typescript
class EcommerceDB extends WingDb {
  get tables() {
    return {
      products: { ctor: JsonTable, file: 'products.json' },
      orders: { ctor: JsonTable, file: 'orders.json' },
      customers: { ctor: JsonTable, file: 'customers.json' },
      images: { ctor: FileTable, file: 'images' }
    };
  }

  async addProduct(product: any) {
    const productsTable = this.getJsonTable('products');
    await productsTable.load();
    productsTable.set(product);
    await productsTable.save();
  }

  async getProductsByCategory(category: string) {
    const productsTable = this.getJsonTable('products');
    await productsTable.load();
    return productsTable.filter({ category });
  }
}
```

### Task Management System

```typescript
class TaskDB extends WingDb {
  get tables() {
    return {
      tasks: { ctor: JsonTable, file: 'tasks.json' },
      projects: { ctor: JsonTable, file: 'projects.json' },
      attachments: { ctor: FileTable, file: 'attachments' }
    };
  }

  async getTasksByStatus(status: string) {
    const tasksTable = this.getJsonTable('tasks');
    await tasksTable.load();
    return tasksTable.filter({ status });
  }

  async addTaskAttachment(taskId: string, filename: string, content: string) {
    const attachmentsTable = this.getFileTable('attachments');
    attachmentsTable.set(`${taskId}_${filename}`, content);
    await attachmentsTable.save();
  }
}
```

## Best Practices

1. **Always load tables before use**: Call `load()` or `loadTable()` before accessing data
2. **Handle errors gracefully**: Wrap database operations in try-catch blocks
3. **Use TypeScript interfaces**: Define proper types for your data structures
4. **Regular backups**: Enable automatic backups for critical data
5. **Organize your data**: Use meaningful table names and file structures
6. **Monitor performance**: For large datasets, consider data pagination

## Limitations

- **Not suitable for high-concurrency**: File-based storage has limitations for concurrent writes
- **No ACID transactions**: No built-in transaction support
- **Limited scalability**: Best for small to medium datasets
- **No built-in indexing**: Complex queries may be slower

## Contributing

We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.

## License

This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.

## Support

- 📖 [Documentation](https://seawingai.com/wingdb)
- 🐛 [Report Issues](https://github.com/seawingai/wingdb/issues)
- 💬 [Discussions](https://github.com/seawingai/wingdb/discussions)

---

Made with ❤️ by [SeaWingAI](https://seawingai.com)